cutpointr/0000755000176200001440000000000014066536752012317 5ustar liggesuserscutpointr/NAMESPACE0000644000176200001440000000446014066411534013530 0ustar liggesusers# Generated by roxygen2: do not edit by hand S3method(add_metric,cutpointr) S3method(add_metric,multi_cutpointr) S3method(add_metric,roc_cutpointr) S3method(auc,cutpointr) S3method(auc,roc_cutpointr) S3method(cutpointr,default) S3method(cutpointr,numeric) S3method(plot,cutpointr) S3method(plot,multi_cutpointr) S3method(plot,roc_cutpointr) S3method(plot_roc,cutpointr) S3method(plot_roc,roc_cutpointr) S3method(predict,cutpointr) S3method(print,cutpointr) S3method(print,multi_cutpointr) S3method(print,summary_cutpointr) S3method(print,summary_multi_cutpointr) S3method(summary,cutpointr) S3method(summary,multi_cutpointr) export(F1_score) export(Jaccard) export(abs_d_ppv_npv) export(abs_d_sens_spec) export(acc_constrain) export(accuracy) export(add_metric) export(auc) export(boot_ci) export(boot_test) export(cohens_kappa) export(cutpoint) export(cutpoint_knots) export(cutpointr) export(cutpointr_) export(cutpoints) export(false_discovery_rate) export(false_omission_rate) export(fn) export(fnr) export(fp) export(fpr) export(maximize_boot_metric) export(maximize_gam_metric) export(maximize_loess_metric) export(maximize_metric) export(maximize_spline_metric) export(metric_constrain) export(minimize_boot_metric) export(minimize_gam_metric) export(minimize_loess_metric) export(minimize_metric) export(minimize_spline_metric) export(misclassification_cost) export(multi_cutpointr) export(nlr) export(npv) export(oc_manual) export(oc_mean) export(oc_median) export(oc_youden_kernel) export(oc_youden_normal) export(odds_ratio) export(p_chisquared) export(plot_cut_boot) export(plot_cutpointr) export(plot_metric) export(plot_metric_boot) export(plot_precision_recall) export(plot_roc) export(plot_sensitivity_specificity) export(plot_x) export(plr) export(ppv) export(precision) export(prod_ppv_npv) export(prod_sens_spec) export(recall) export(risk_ratio) export(roc) export(roc01) export(sens_constrain) export(sensitivity) export(spec_constrain) export(specificity) export(sum_ppv_npv) export(sum_sens_spec) export(tn) export(tnr) export(total_utility) export(tp) export(tpr) export(youden) importFrom(Rcpp,sourceCpp) importFrom(dplyr,"%>%") importFrom(foreach,"%do%") importFrom(purrr,"%>%") importFrom(rlang,"!!") importFrom(rlang,":=") importFrom(rlang,.data) importFrom(stats,median) importFrom(tidyselect,any_of) useDynLib(cutpointr) cutpointr/data/0000755000176200001440000000000014066407426013223 5ustar liggesuserscutpointr/data/suicide.rda0000644000176200001440000000212014066407426015333 0ustar liggesusersBZh91AY&SYq (\T]P?@@@[0 0n"*~Li0MA2zLM4hz$OҏSLSFڞ4 2h5 FA  @ 24hiL 24b40F@IML=OQ@bd@A׶ƸmVYP# @d$5fA=5:g&Jl换s#4>EXm|. F,ѯoAX3\I6  M uXo)p"ζs e;)hERdV:7l9 `XJ P"ݍGimjadK(ǰ\R %W |Ub7@"EF9(EVR@_ X5 Б 1L,`"{Cg3ssbK}r]~;,cs>\8p5߼):+$ qe Ãjih(7is7Z9D3chiN EITlX#R[Mfj4k1PlhXk QFX5DjLiD0F4L0̨$Gb;4Gg@_;;gM(Pm_NO ^ېYJ-VA-*Al6 n=i>?gtT׋#jtQ% J%WOW._q(f]w]BA3cutpointr/data/prostate_nodal.rda0000644000176200001440000000044413475240564016734 0ustar liggesusersBZh91AY&SYz*3hD݀H@=H(O$46jꁧ@2i * 4h̞= hF^f5D3ōTX;r=\G̒VdU WoYvI#M6M V$_sDo)W46CH3)5ms.-$]0!01 ZWXl݄OUS^єQ-2 1`J2I-ҕsxc@_(G8{1з,QܑN$6'cutpointr/man/0000755000176200001440000000000013766732727013100 5ustar liggesuserscutpointr/man/plot.cutpointr.Rd0000644000176200001440000000175413672457720016373 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/plot.cutpointr.R \name{plot.cutpointr} \alias{plot.cutpointr} \title{Plot cutpointr objects} \usage{ \method{plot}{cutpointr}(x, ...) } \arguments{ \item{x}{A cutpointr object.} \item{...}{Further arguments.} } \description{ The plot layout depends on whether subgroups were defined and whether bootstrapping was run. } \details{ The \code{...} argument can be used to apply \pkg{ggplot2} functions to every individual plot, for example for changing the theme. } \examples{ opt_cut <- cutpointr(suicide, dsi, suicide, gender) plot(opt_cut) plot(opt_cut, ggplot2::theme_bw()) } \seealso{ Other cutpointr plotting functions: \code{\link{plot_cut_boot}()}, \code{\link{plot_cutpointr}()}, \code{\link{plot_metric_boot}()}, \code{\link{plot_metric}()}, \code{\link{plot_precision_recall}()}, \code{\link{plot_roc}()}, \code{\link{plot_sensitivity_specificity}()}, \code{\link{plot_x}()} } \concept{cutpointr plotting functions} cutpointr/man/oc_manual.Rd0000644000176200001440000000223413672457720015317 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/oc_manual.R \name{oc_manual} \alias{oc_manual} \title{Set a manual cutpoint for use with cutpointr} \usage{ oc_manual(cutpoint, ...) } \arguments{ \item{cutpoint}{(numeric) The fixed cutpoint.} \item{...}{To capture further arguments that are always passed to the method function by cutpointr. The cutpointr function passes data, x, class, metric_func, direction, pos_class and neg_class to the method function.} } \description{ This function simply returns \code{cutpoint} as the optimal cutpoint. Mainly useful if bootstrap estimates of the out-of-bag performance of a given cutpoint are desired, e.g. taking a cutpoint value from the literature. } \examples{ cutpointr(suicide, dsi, suicide, method = oc_manual, cutpoint = 4) } \seealso{ Other method functions: \code{\link{maximize_boot_metric}()}, \code{\link{maximize_gam_metric}()}, \code{\link{maximize_loess_metric}()}, \code{\link{maximize_metric}()}, \code{\link{maximize_spline_metric}()}, \code{\link{oc_mean}()}, \code{\link{oc_median}()}, \code{\link{oc_youden_kernel}()}, \code{\link{oc_youden_normal}()} } \concept{method functions} cutpointr/man/maximize_spline_metric.Rd0000644000176200001440000001134413672457720020123 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/optimize_metric.R \name{maximize_spline_metric} \alias{maximize_spline_metric} \alias{minimize_spline_metric} \title{Optimize a metric function in binary classification after spline smoothing} \usage{ maximize_spline_metric( data, x, class, metric_func = youden, pos_class = NULL, neg_class = NULL, direction, w = NULL, df = NULL, spar = 1, nknots = cutpoint_knots, df_offset = NULL, penalty = 1, control_spar = list(), tol_metric, use_midpoints, ... ) minimize_spline_metric( data, x, class, metric_func = youden, pos_class = NULL, neg_class = NULL, direction, w = NULL, df = NULL, spar = 1, nknots = cutpoint_knots, df_offset = NULL, penalty = 1, control_spar = list(), tol_metric, use_midpoints, ... ) } \arguments{ \item{data}{A data frame or tibble in which the columns that are given in x and class can be found.} \item{x}{(character) The variable name to be used for classification, e.g. predictions or test values.} \item{class}{(character) The variable name indicating class membership.} \item{metric_func}{(function) A function that computes a metric to be optimized. See description.} \item{pos_class}{The value of class that indicates the positive class.} \item{neg_class}{The value of class that indicates the negative class.} \item{direction}{(character) Use ">=" or "<=" to select whether an x value >= or <= the cutoff predicts the positive class.} \item{w}{Optional vector of weights of the same length as x; defaults to all 1.} \item{df}{The desired equivalent number of degrees of freedom (trace of the smoother matrix). Must be in (1,nx], nx the number of unique x values.} \item{spar}{Smoothing parameter, typically (but not necessarily) in (0,1]. When spar is specified, the coefficient lambda of the integral of the squared second derivative in the fit (penalized log likelihood) criterion is a monotone function of spar.} \item{nknots}{Integer or function giving the number of knots. The function should accept data and x (the name of the predictor variable) as inputs. By default nknots = 0.1 * log(n_dat / n_cut) * n_cut where n_dat is the number of observations and n_cut the number of unique predictor values.} \item{df_offset}{Allows the degrees of freedom to be increased by df_offset in the GCV criterion.} \item{penalty}{The coefficient of the penalty for degrees of freedom in the GCV criterion.} \item{control_spar}{Optional list with named components controlling the root finding when the smoothing parameter spar is computed, i.e., NULL. See help("smooth.spline") for further information.} \item{tol_metric}{All cutpoints will be returned that lead to a metric value in the interval [m_max - tol_metric, m_max + tol_metric] where m_max is the maximum achievable metric value. This can be used to return multiple decent cutpoints and to avoid floating-point problems.} \item{use_midpoints}{(logical) If TRUE (default FALSE) the returned optimal cutpoint will be the mean of the optimal cutpoint and the next highest observation (for direction = ">") or the next lowest observation (for direction = "<") which avoids biasing the optimal cutpoint.} \item{...}{Further arguments that will be passed to metric_func.} } \value{ A tibble with the columns \code{optimal_cutpoint}, the corresponding metric value and \code{roc_curve}, a nested tibble that includes all possible cutoffs and the corresponding numbers of true and false positives / negatives and all corresponding metric values. } \description{ Given a function for computing a metric in \code{metric_func}, this function smoothes the function of metric value per cutpoint using smoothing splines. Then it optimizes the metric by selecting an optimal cutpoint. For further details on the smoothing spline see \code{?stats::smooth.spline}. The \code{metric} function should accept the following inputs: \itemize{ \item \code{tp}: vector of number of true positives \item \code{fp}: vector of number of false positives \item \code{tn}: vector of number of true negatives \item \code{fn}: vector of number of false negatives } } \details{ The above inputs are arrived at by using all unique values in \code{x}, Inf, and -Inf as possible cutpoints for classifying the variable in class. } \examples{ oc <- cutpointr(suicide, dsi, suicide, gender, method = maximize_spline_metric, df = 5, metric = accuracy) plot_metric(oc) } \seealso{ Other method functions: \code{\link{maximize_boot_metric}()}, \code{\link{maximize_gam_metric}()}, \code{\link{maximize_loess_metric}()}, \code{\link{maximize_metric}()}, \code{\link{oc_manual}()}, \code{\link{oc_mean}()}, \code{\link{oc_median}()}, \code{\link{oc_youden_kernel}()}, \code{\link{oc_youden_normal}()} } \concept{method functions} cutpointr/man/plot_precision_recall.Rd0000644000176200001440000000212013672457720017726 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/plot_precision_recall.R \name{plot_precision_recall} \alias{plot_precision_recall} \title{Precision recall plot from a cutpointr object} \usage{ plot_precision_recall(x, display_cutpoint = TRUE, ...) } \arguments{ \item{x}{A cutpointr object.} \item{display_cutpoint}{(logical) Whether or not to display the optimal cutpoint as a dot on the precision recall curve.} \item{...}{Additional arguments (unused).} } \description{ Given a \code{cutpointr} object this function plots the precision recall curve(s) per subgroup, if given. } \examples{ library(cutpointr) ## Optimal cutpoint for dsi data(suicide) opt_cut <- cutpointr(suicide, dsi, suicide) plot_precision_recall(opt_cut) } \seealso{ Other cutpointr plotting functions: \code{\link{plot.cutpointr}()}, \code{\link{plot_cut_boot}()}, \code{\link{plot_cutpointr}()}, \code{\link{plot_metric_boot}()}, \code{\link{plot_metric}()}, \code{\link{plot_roc}()}, \code{\link{plot_sensitivity_specificity}()}, \code{\link{plot_x}()} } \concept{cutpointr plotting functions} cutpointr/man/cutpoint_knots.Rd0000644000176200001440000000124513672457720016445 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/optimize_metric.R \name{cutpoint_knots} \alias{cutpoint_knots} \title{Calculate number of knots to use in spline smoothing} \usage{ cutpoint_knots(data, x) } \arguments{ \item{data}{A data frame} \item{x}{(character) The name of the predictor variable} } \description{ This function calculates the number of knots when using smoothing splines for smoothing a function of metric values per cutpoint value. The function for calculating the number of knots is equal to \code{stats::.nknots_smspl} but uses the number of unique cutpoints in the data as n. } \examples{ cutpoint_knots(suicide, "dsi") } cutpointr/man/prod_ppv_npv.Rd0000644000176200001440000000334713672457720016103 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{prod_ppv_npv} \alias{prod_ppv_npv} \title{Calculate the product of positive and negative predictive value} \usage{ prod_ppv_npv(tp, fp, tn, fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate the product of positive predictive value (PPV) and negative predictive value (NPV) from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. \cr \cr ppv = tp / (tp + fp) \cr npv = tn / (tn + fn) \cr prod_ppv_npv = ppv * npv \cr } \examples{ prod_ppv_npv(10, 5, 20, 10) prod_ppv_npv(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/roc01.Rd0000644000176200001440000000363713672457720014315 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{roc01} \alias{roc01} \title{Calculate the distance between points on the ROC curve and (0,1)} \usage{ roc01(tp, fp, tn, fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate the distance on the ROC space between points on the ROC curve and the point of perfect discrimination from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. To be used with \code{method = minimize_metric}. \cr \cr sensitivity = tp / (tp + fn) \cr specificity = tn / (tn + fp) \cr roc01 = sqrt((1 - sensitivity)^2 + (1 - specificity)^2) \cr } \examples{ roc01(10, 5, 20, 10) roc01(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) oc <- cutpointr(suicide, dsi, suicide, method = minimize_metric, metric = roc01) plot_roc(oc) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/plot_sensitivity_specificity.Rd0000644000176200001440000000222013672457720021377 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/plot_sensitivity_specificity.R \name{plot_sensitivity_specificity} \alias{plot_sensitivity_specificity} \title{Sensitivity and specificity plot from a cutpointr object} \usage{ plot_sensitivity_specificity(x, display_cutpoint = TRUE, ...) } \arguments{ \item{x}{A cutpointr object.} \item{display_cutpoint}{(logical) Whether or not to display the optimal cutpoint as a dot on the precision recall curve.} \item{...}{Additional arguments (unused).} } \description{ Given a \code{cutpointr} object this function plots the sensitivity and specificity curve(s) per subgroup, if the latter is given. } \examples{ library(cutpointr) ## Optimal cutpoint for dsi data(suicide) opt_cut <- cutpointr(suicide, dsi, suicide) plot_sensitivity_specificity(opt_cut) } \seealso{ Other cutpointr plotting functions: \code{\link{plot.cutpointr}()}, \code{\link{plot_cut_boot}()}, \code{\link{plot_cutpointr}()}, \code{\link{plot_metric_boot}()}, \code{\link{plot_metric}()}, \code{\link{plot_precision_recall}()}, \code{\link{plot_roc}()}, \code{\link{plot_x}()} } \concept{cutpointr plotting functions} cutpointr/man/sensitivity.Rd0000644000176200001440000000273313672457720015757 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{sensitivity} \alias{sensitivity} \title{Calculate sensitivity} \usage{ sensitivity(tp, fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fn}{(numeric) number of false negatives.} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate sensitivity from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. \cr \cr sensitivity = tp / (tp + fn) \cr } \examples{ sensitivity(10, 5, 20, 10) sensitivity(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/plot.roc_cutpointr.Rd0000644000176200001440000000237513672457720017236 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/plot_roc.R \name{plot.roc_cutpointr} \alias{plot.roc_cutpointr} \title{Plot ROC curve from a cutpointr or roc_cutpointr object} \usage{ \method{plot}{roc_cutpointr}(x, type = "line", ...) } \arguments{ \item{x}{A cutpointr or roc_cutpointr object.} \item{type}{"line" for line plot (default) or "step" for step plot.} \item{...}{Additional arguments (unused).} } \description{ Given a \code{cutpointr} object this function plots the ROC curve(s) per subgroup, if given. Also plots a ROC curve from the output of \code{roc()}. } \examples{ opt_cut <- cutpointr(suicide, dsi, suicide) plot_roc(opt_cut, display_cutpoint = FALSE) opt_cut_2groups <- cutpointr(suicide, dsi, suicide, gender) plot_roc(opt_cut_2groups, display_cutpoint = TRUE) roc_curve <- roc(suicide, x = dsi, class = suicide, pos_class = "yes", neg_class = "no", direction = ">=") plot(roc_curve) auc(roc_curve) } \seealso{ Other cutpointr plotting functions: \code{\link{plot.cutpointr}()}, \code{\link{plot_cut_boot}()}, \code{\link{plot_cutpointr}()}, \code{\link{plot_metric_boot}()}, \code{\link{plot_metric}()}, \code{\link{plot_precision_recall}()}, \code{\link{plot_sensitivity_specificity}()}, \code{\link{plot_x}()} } cutpointr/man/multi_cutpointr.Rd0000644000176200001440000000403613741611406016612 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cutpointr.R \name{multi_cutpointr} \alias{multi_cutpointr} \title{Calculate optimal cutpoints and further statistics for multiple predictors} \usage{ multi_cutpointr(data, x = NULL, class, subgroup = NULL, silent = FALSE, ...) } \arguments{ \item{data}{A data frame.} \item{x}{Character vector of predictor variables. If NULL all numeric columns.} \item{class}{The name of the outcome / independent variable.} \item{subgroup}{An additional covariate that identifies subgroups. Separate optimal cutpoints will be determined per group.} \item{silent}{Whether to suppress messages.} \item{...}{Further arguments to be passed to cutpointr_ (Use a quoted variable name for subgroup).} } \value{ A data frame. } \description{ Runs \code{cutpointr} over multiple predictor variables. Tidyeval via \code{!!} is supported for \code{class} and \code{subgroup}. If \code{x = NULL}, \code{cutpointr} will be run using all numeric columns in the data set as predictors except for the variable in \code{class} and, if given, \code{subgroup}. } \details{ The automatic determination of positive / negative classes and \code{direction} will be carried out separately for every predictor variable. That way, if \code{direction} and the classes are not specified, the reported AUC for every variable will be >= 0.5. AUC may be < 0.5 if subgroups are specified as \code{direction} is equal within every subgroup. } \examples{ library(cutpointr) multi_cutpointr(suicide, x = c("age", "dsi"), class = suicide, pos_class = "yes") mcp <- multi_cutpointr(suicide, x = c("age", "dsi"), class = suicide, subgroup = gender, pos_class = "yes") mcp (scp <- summary(mcp)) \dontrun{ ## The result is a data frame tibble:::print.tbl(scp) } } \seealso{ Other main cutpointr functions: \code{\link{add_metric}()}, \code{\link{boot_ci}()}, \code{\link{boot_test}()}, \code{\link{cutpointr}()}, \code{\link{predict.cutpointr}()}, \code{\link{roc}()} } \concept{main cutpointr functions} cutpointr/man/predict.cutpointr.Rd0000644000176200001440000000240113672457720017035 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/predict.cutpointr.R \name{predict.cutpointr} \alias{predict.cutpointr} \title{Predict using a cutpointr object} \usage{ \method{predict}{cutpointr}(object, newdata, cutpoint_nr = 1, ...) } \arguments{ \item{object}{a cutpointr object.} \item{newdata}{a data.frame with a column that contains the predictor variable.} \item{cutpoint_nr}{if multiple optimal cutpoints were found this parameter defines which one should be used for predictions. Can be a vector if different cutpoint numbers are desired for different subgroups.} \item{...}{further arguments.} } \description{ Predictions are made on the \code{data.frame} in \code{newdata} using either the variable name or by applying the same transformation to the data as in \code{cutpointr}. The class of the output will be identical to the class of the predictor. } \examples{ oc <- cutpointr(suicide, dsi, suicide) ## Return in-sample predictions predict(oc, newdata = data.frame(dsi = oc$data[[1]]$dsi)) } \seealso{ Other main cutpointr functions: \code{\link{add_metric}()}, \code{\link{boot_ci}()}, \code{\link{boot_test}()}, \code{\link{cutpointr}()}, \code{\link{multi_cutpointr}()}, \code{\link{roc}()} } \concept{main cutpointr functions} cutpointr/man/prod_sens_spec.Rd0000644000176200001440000000333613672457720016373 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{prod_sens_spec} \alias{prod_sens_spec} \title{Calculate the product of sensitivity and specificity} \usage{ prod_sens_spec(tp, fp, tn, fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate the product of sensitivity and specificity from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. \cr \cr sensitivity = tp / (tp + fn) \cr specificity = tn / (tn + fp) \cr prod_sens_spec = sensitivity * specificity \cr } \examples{ prod_sens_spec(10, 5, 20, 10) prod_sens_spec(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/npv.Rd0000644000176200001440000000310613672457720014163 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{npv} \alias{npv} \title{Calculate the negative predictive value} \usage{ npv(tp, fp, tn, fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate the negative predictive value (NPV) from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. \cr \cr npv = tn / (tn + fn) \cr } \examples{ npv(10, 5, 20, 10) npv(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/cutpointr.Rd0000644000176200001440000003316714066363377015423 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cutpointr.R \name{cutpointr} \alias{cutpointr} \alias{cutpointr.default} \alias{cutpointr.numeric} \title{Determine and evaluate optimal cutpoints} \usage{ cutpointr(...) \method{cutpointr}{default}( data, x, class, subgroup = NULL, method = maximize_metric, metric = sum_sens_spec, pos_class = NULL, neg_class = NULL, direction = NULL, boot_runs = 0, boot_stratify = FALSE, use_midpoints = FALSE, break_ties = median, na.rm = FALSE, allowParallel = FALSE, silent = FALSE, tol_metric = 1e-06, ... ) \method{cutpointr}{numeric}( x, class, subgroup = NULL, method = maximize_metric, metric = sum_sens_spec, pos_class = NULL, neg_class = NULL, direction = NULL, boot_runs = 0, boot_stratify = FALSE, use_midpoints = FALSE, break_ties = median, na.rm = FALSE, allowParallel = FALSE, silent = FALSE, tol_metric = 1e-06, ... ) } \arguments{ \item{...}{Further optional arguments that will be passed to method. minimize_metric and maximize_metric pass ... to metric.} \item{data}{A data.frame with the data needed for x, class and optionally subgroup.} \item{x}{The variable name to be used for classification, e.g. predictions. The raw vector of values if the data argument is unused.} \item{class}{The variable name indicating class membership. If the data argument is unused, the vector of raw numeric values.} \item{subgroup}{An additional covariate that identifies subgroups or the raw data if data = NULL. Separate optimal cutpoints will be determined per group. Numeric, character and factor are allowed.} \item{method}{(function) A function for determining cutpoints. Can be user supplied or use some of the built in methods. See details.} \item{metric}{(function) The function for computing a metric when using maximize_metric or minimize_metric as method and and for the out-of-bag values during bootstrapping. A way of internally validating the performance. User defined functions can be supplied, see details.} \item{pos_class}{(optional) The value of class that indicates the positive class.} \item{neg_class}{(optional) The value of class that indicates the negative class.} \item{direction}{(character, optional) Use ">=" or "<=" to indicate whether x is supposed to be larger or smaller for the positive class.} \item{boot_runs}{(numerical) If positive, this number of bootstrap samples will be used to assess the variability and the out-of-sample performance.} \item{boot_stratify}{(logical) If the bootstrap is stratified, bootstrap samples are drawn separately in both classes and then combined, keeping the proportion of positives and negatives constant in every resample.} \item{use_midpoints}{(logical) If TRUE (default FALSE) the returned optimal cutpoint will be the mean of the optimal cutpoint and the next highest observation (for direction = ">=") or the next lowest observation (for direction = "<=") which avoids biasing the optimal cutpoint.} \item{break_ties}{If multiple cutpoints are found, they can be summarized using this function, e.g. mean or median. To return all cutpoints use c as the function.} \item{na.rm}{(logical) Set to TRUE (default FALSE) to keep only complete cases of x, class and subgroup (if specified). Missing values with na.rm = FALSE will raise an error.} \item{allowParallel}{(logical) If TRUE, the bootstrapping will be parallelized using foreach. A local cluster, for example, should be started manually beforehand.} \item{silent}{(logical) If TRUE suppresses all messages.} \item{tol_metric}{All cutpoints will be returned that lead to a metric value in the interval [m_max - tol_metric, m_max + tol_metric] where m_max is the maximum achievable metric value. This can be used to return multiple decent cutpoints and to avoid floating-point problems. Not supported by all \code{method} functions, see details.} } \value{ A cutpointr object which is also a data.frame and tbl_df. } \description{ Using predictions (or e.g. biological marker values) and binary class labels, this function will determine "optimal" cutpoints using various selectable methods. The methods for cutpoint determination can be evaluated using bootstrapping. An estimate of the cutpoint variability and the out-of-sample performance can then be returned with \code{summary} or \code{plot}. For an introduction to the package please see \code{vignette("cutpointr", package = "cutpointr")}. } \details{ If \code{direction} and/or \code{pos_class} and \code{neg_class} are not given, the function will assume that higher values indicate the positive class and use the class with a higher median as the positive class. This function uses tidyeval to support unquoted arguments. For programming with \code{cutpointr} the operator \code{!!} can be used to unquote an argument, see the examples. Different methods can be selected for determining the optimal cutpoint via the method argument. The package includes the following method functions: \itemize{ \item \code{maximize_metric}: Maximize the metric function \item \code{minimize_metric}: Minimize the metric function \item \code{maximize_loess_metric}: Maximize the metric function after LOESS smoothing \item \code{minimize_loess_metric}: Minimize the metric function after LOESS smoothing \item \code{maximize_spline_metric}: Maximize the metric function after spline smoothing \item \code{minimize_spline_metric}: Minimize the metric function after spline smoothing \item \code{maximize_boot_metric}: Maximize the metric function as a summary of the optimal cutpoints in bootstrapped samples \item \code{minimize_boot_metric}: Minimize the metric function as a summary of the optimal cutpoints in bootstrapped samples \item \code{oc_youden_kernel}: Maximize the Youden-Index after kernel smoothing the distributions of the two classes \item \code{oc_youden_normal}: Maximize the Youden-Index parametrically assuming normally distributed data in both classes \item \code{oc_manual}: Specify the cutpoint manually } User-defined functions can be supplied to method, too. As a reference, the code of all included method functions can be accessed by simply typing their name. To define a new method function, create a function that may take as input(s): \itemize{ \item \code{data}: A \code{data.frame} or \code{tbl_df} \item \code{x}: (character) The name of the predictor or independent variable \item \code{class}: (character) The name of the class or dependent variable \item \code{metric_func}: A function for calculating a metric, e.g. accuracy \item \code{pos_class}: The positive class \item \code{neg_class}: The negative class \item \code{direction}: ">=" if the positive class has higher x values, "<=" otherwise \item \code{tol_metric}: (numeric) In the built-in methods a tolerance around the optimal metric value \item \code{use_midpoints}: (logical) In the built-in methods whether to use midpoints instead of exact optimal cutpoints \item \code{...} Further arguments } The \code{...} argument can be used to avoid an error if not all of the above arguments are needed or in order to pass additional arguments to method. The function should return a \code{data.frame} or \code{tbl_df} with one row, the column "optimal_cutpoint", and an optional column with an arbitrary name with the metric value at the optimal cutpoint. Built-in metric functions include: \itemize{ \item \code{accuracy}: Fraction correctly classified \item \code{youden}: Youden- or J-Index = sensitivity + specificity - 1 \item \code{sum_sens_spec}: sensitivity + specificity \item \code{sum_ppv_npv}: The sum of positive predictive value (PPV) and negative predictive value (NPV) \item \code{prod_sens_spec}: sensitivity * specificity \item \code{prod_ppv_npv}: The product of positive predictive value (PPV) and negative predictive value (NPV) \item \code{cohens_kappa}: Cohen's Kappa \item \code{abs_d_sens_spec}: The absolute difference between sensitivity and specificity \item \code{roc01}: Distance to the point (0,1) on ROC space \item \code{abs_d_ppv_npv}: The absolute difference between positive predictive value (PPV) and negative predictive value (NPV) \item \code{p_chisquared}: The p-value of a chi-squared test on the confusion matrix of predictions and observations \item \code{odds_ratio}: The odds ratio calculated as (TP / FP) / (FN / TN) \item \code{risk_ratio}: The risk ratio (relative risk) calculated as (TP / (TP + FN)) / (FP / (FP + TN)) \item positive and negative likelihood ratio calculated as \code{plr} = true positive rate / false positive rate and \code{nlr} = false negative rate / true negative rate \item \code{misclassification_cost}: The sum of the misclassification cost of false positives and false negatives fp * cost_fp + fn * cost_fn. Additional arguments to cutpointr: \code{cost_fp}, \code{cost_fn} \item \code{total_utility}: The total utility of true / false positives / negatives calculated as utility_tp * TP + utility_tn * TN - cost_fp * FP - cost_fn * FN. Additional arguments to cutpointr: \code{utility_tp}, \code{utility_tn}, \code{cost_fp}, \code{cost_fn} \item \code{F1_score}: The F1-score (2 * TP) / (2 * TP + FP + FN) \item \code{sens_constrain}: Maximize sensitivity given a minimal value of specificity \item \code{spec_constrain}: Maximize specificity given a minimal value of sensitivity \item \code{metric_constrain}: Maximize a selected metric given a minimal value of another selected metric } Furthermore, the following functions are included which can be used as metric functions but are more useful for plotting purposes, for example in plot_cutpointr, or for defining new metric functions: \code{tp}, \code{fp}, \code{tn}, \code{fn}, \code{tpr}, \code{fpr}, \code{tnr}, \code{fnr}, \code{false_omission_rate}, \code{false_discovery_rate}, \code{ppv}, \code{npv}, \code{precision}, \code{recall}, \code{sensitivity}, and \code{specificity}. User defined metric functions can be created as well which can accept the following inputs as vectors: \itemize{ \item \code{tp}: Vector of true positives \item \code{fp}: Vector of false positives \item \code{tn}: Vector of true negatives \item \code{fn}: Vector of false negatives \item \code{...} If the metric function is used in conjunction with any of the maximize / minimize methods, further arguments can be passed } The function should return a numeric vector or a matrix or a \code{data.frame} with one column. If the column is named, the name will be included in the output and plots. Avoid using names that are identical to the column names that are by default returned by \pkg{cutpointr}. If \code{boot_runs} is positive, that number of bootstrap samples will be drawn and the optimal cutpoint using \code{method} will be determined. Additionally, as a way of internal validation, the function in \code{metric} will be used to score the out-of-bag predictions using the cutpoints determined by \code{method}. Various default metrics are always included in the bootstrap results. If multiple optimal cutpoints are found, the column optimal_cutpoint becomes a list that contains the vector(s) of the optimal cutpoints. If \code{use_midpoints = TRUE} the mean of the optimal cutpoint and the next highest or lowest possible cutpoint is returned, depending on \code{direction}. The \code{tol_metric} argument can be used to avoid floating-point problems that may lead to exclusion of cutpoints that achieve the optimally achievable metric value. Additionally, by selecting a large tolerance multiple cutpoints can be returned that lead to decent metric values in the vicinity of the optimal metric value. \code{tol_metric} is passed to metric and is only supported by the maximization and minimization functions, i.e. \code{maximize_metric}, \code{minimize_metric}, \code{maximize_loess_metric}, \code{minimize_loess_metric}, \code{maximize_spline_metric}, and \code{minimize_spline_metric}. In \code{maximize_boot_metric} and \code{minimize_boot_metric} multiple optimal cutpoints will be passed to the \code{summary_func} of these two functions. } \examples{ library(cutpointr) ## Optimal cutpoint for dsi data(suicide) opt_cut <- cutpointr(suicide, dsi, suicide) opt_cut s_opt_cut <- summary(opt_cut) plot(opt_cut) \dontrun{ ## Predict class for new observations predict(opt_cut, newdata = data.frame(dsi = 0:5)) ## Supplying raw data, same result cutpointr(x = suicide$dsi, class = suicide$suicide) ## direction, class labels, method and metric can be defined manually ## Again, same result cutpointr(suicide, dsi, suicide, direction = ">=", pos_class = "yes", method = maximize_metric, metric = youden) ## Optimal cutpoint for dsi, as before, but for the separate subgroups opt_cut <- cutpointr(suicide, dsi, suicide, gender) opt_cut (s_opt_cut <- summary(opt_cut)) tibble:::print.tbl(s_opt_cut) ## Bootstrapping also works on individual subgroups set.seed(30) opt_cut <- cutpointr(suicide, dsi, suicide, gender, boot_runs = 1000, boot_stratify = TRUE) opt_cut summary(opt_cut) plot(opt_cut) ## Parallelized bootstrapping library(doParallel) library(doRNG) cl <- makeCluster(2) # 2 cores registerDoParallel(cl) registerDoRNG(12) # Reproducible parallel loops using doRNG opt_cut <- cutpointr(suicide, dsi, suicide, gender, boot_runs = 1000, allowParallel = TRUE) stopCluster(cl) opt_cut plot(opt_cut) ## Robust cutpoint method using kernel smoothing for optimizing Youden-Index opt_cut <- cutpointr(suicide, dsi, suicide, gender, method = oc_youden_kernel) opt_cut } } \seealso{ Other main cutpointr functions: \code{\link{add_metric}()}, \code{\link{boot_ci}()}, \code{\link{boot_test}()}, \code{\link{multi_cutpointr}()}, \code{\link{predict.cutpointr}()}, \code{\link{roc}()} } \concept{main cutpointr functions} cutpointr/man/abs_d_sens_spec.Rd0000644000176200001440000000337513672457720016502 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{abs_d_sens_spec} \alias{abs_d_sens_spec} \title{Calculate the absolute difference of sensitivity and specificity} \usage{ abs_d_sens_spec(tp, fp, tn, fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate the absolute difference of sensitivity and specificity from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. \cr \cr sensitivity = tp / (tp + fn) \cr specificity = tn / (tn + fp) \cr abs_d_sens_spec = |sensitivity - specificity| \cr } \examples{ abs_d_sens_spec(10, 5, 20, 10) abs_d_sens_spec(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/add_metric.Rd0000644000176200001440000000257613766732727015474 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/add_metric.R \name{add_metric} \alias{add_metric} \alias{add_metric.cutpointr} \alias{add_metric.multi_cutpointr} \alias{add_metric.roc_cutpointr} \title{Add metrics to a cutpointr or roc_cutpointr object} \usage{ add_metric(object, metric) \method{add_metric}{cutpointr}(object, metric) \method{add_metric}{multi_cutpointr}(object, metric) \method{add_metric}{roc_cutpointr}(object, metric) } \arguments{ \item{object}{A cutpointr or roc_cutpointr object.} \item{metric}{(list) A list of metric functions to be added.} } \value{ A cutpointr or roc_cutpointr object (a data.frame) with one or more added columns. } \description{ By default, the output of cutpointr includes the optimized metric and several other metrics. This function adds further metrics. Suitable metric functions are all metric functions that are included in the package or that comply with those standards. } \examples{ library(dplyr) library(cutpointr) cutpointr(suicide, dsi, suicide, gender) \%>\% add_metric(list(ppv, npv)) \%>\% select(optimal_cutpoint, subgroup, AUC, sum_sens_spec, ppv, npv) } \seealso{ Other main cutpointr functions: \code{\link{boot_ci}()}, \code{\link{boot_test}()}, \code{\link{cutpointr}()}, \code{\link{multi_cutpointr}()}, \code{\link{predict.cutpointr}()}, \code{\link{roc}()} } \concept{main cutpointr functions} cutpointr/man/precision.Rd0000644000176200001440000000313713672457720015357 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{precision} \alias{precision} \title{Calculate precision} \usage{ precision(tp, fp, tn, fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate precision (equal to the positive predictive value) from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. \cr \cr precision = tp / (tp + fp) \cr } \examples{ precision(10, 5, 20, 10) precision(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/recall.Rd0000644000176200001440000000307013672457720014622 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{recall} \alias{recall} \title{Calculate recall} \usage{ recall(tp, fp, tn, fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate recall (equal to sensitivity) from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. \cr \cr recall = tp / (tp + fn) \cr } \examples{ recall(10, 5, 20, 10) recall(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/F1_score.Rd0000644000176200001440000000310613672457720015021 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{F1_score} \alias{F1_score} \title{Calculate the F1-score} \usage{ F1_score(tp, fp, tn, fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate the F1-score from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. \cr \cr F1_score = (2 * tp) / (2 * tp + fp + fn) \cr } \examples{ F1_score(10, 5, 20, 10) F1_score(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) } \seealso{ Other metric functions: \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/youden.Rd0000644000176200001440000000322613672457720014666 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{youden} \alias{youden} \title{Calculate the Youden-Index} \usage{ youden(tp, fp, tn, fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate the Youden-Index (J-Index) from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. \cr \cr sensitivity = tp / (tp + fn) \cr specificity = tn / (tn + fp) \cr youden_index = sensitivity + specificity - 1 \cr } \examples{ youden(10, 5, 20, 10) youden(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()} } \concept{metric functions} cutpointr/man/plot_metric_boot.Rd0000644000176200001440000000220513672457720016723 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/plot_metric_boot.R \name{plot_metric_boot} \alias{plot_metric_boot} \title{Plot the bootstrapped metric distribution from a cutpointr object} \usage{ plot_metric_boot(x, ...) } \arguments{ \item{x}{A cutpointr object.} \item{...}{Additional arguments (unused)} } \description{ Given a \code{cutpointr} object this function plots the bootstrapped metric distribution, i.e. the distribution of out-of-bag metric values. The metric depends on the function that was supplied to \code{metric} in the call to \code{cutpointr}. The \code{cutpointr} function has to be run with \code{boot_runs}` > 0 to enable bootstrapping. } \examples{ set.seed(300) opt_cut <- cutpointr(suicide, dsi, suicide, boot_runs = 10) plot_metric_boot(opt_cut) } \seealso{ Other cutpointr plotting functions: \code{\link{plot.cutpointr}()}, \code{\link{plot_cut_boot}()}, \code{\link{plot_cutpointr}()}, \code{\link{plot_metric}()}, \code{\link{plot_precision_recall}()}, \code{\link{plot_roc}()}, \code{\link{plot_sensitivity_specificity}()}, \code{\link{plot_x}()} } \concept{cutpointr plotting functions} cutpointr/man/plot_metric.Rd0000644000176200001440000000312113672457720015676 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/plot_metric.R \name{plot_metric} \alias{plot_metric} \title{Plot a metric over all possible cutoffs from a cutpointr object} \usage{ plot_metric(x, conf_lvl = 0.95, add_unsmoothed = TRUE) } \arguments{ \item{x}{A cutpointr object.} \item{conf_lvl}{The confidence level of the bootstrap confidence interval. Set to 0 to draw no bootstrap confidence interval.} \item{add_unsmoothed}{Add the line of unsmoothed metric values to the plot. Applicable for some smoothing methods, e.g. maximize_gam_metric.} } \description{ If \code{maximize_metric} is used as \code{method} function in cutpointr the computed metric values over all possible cutoffs can be plotted. Generally, this works for method functions that return a ROC-curve including the metric value for every cutpoint along with the optimal cutpoint. } \examples{ opt_cut <- cutpointr(suicide, dsi, suicide) plot_metric(opt_cut) } \seealso{ Other cutpointr plotting functions: \code{\link{plot.cutpointr}()}, \code{\link{plot_cut_boot}()}, \code{\link{plot_cutpointr}()}, \code{\link{plot_metric_boot}()}, \code{\link{plot_precision_recall}()}, \code{\link{plot_roc}()}, \code{\link{plot_sensitivity_specificity}()}, \code{\link{plot_x}()} Other cutpointr plotting functions: \code{\link{plot.cutpointr}()}, \code{\link{plot_cut_boot}()}, \code{\link{plot_cutpointr}()}, \code{\link{plot_metric_boot}()}, \code{\link{plot_precision_recall}()}, \code{\link{plot_roc}()}, \code{\link{plot_sensitivity_specificity}()}, \code{\link{plot_x}()} } \concept{cutpointr plotting functions} cutpointr/man/maximize_metric.Rd0000644000176200001440000000627413672457720016557 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/optimize_metric.R \name{maximize_metric} \alias{maximize_metric} \alias{minimize_metric} \title{Optimize a metric function in binary classification} \usage{ maximize_metric( data, x, class, metric_func = youden, pos_class = NULL, neg_class = NULL, direction, tol_metric, use_midpoints, ... ) minimize_metric( data, x, class, metric_func = youden, pos_class = NULL, neg_class = NULL, direction, tol_metric, use_midpoints, ... ) } \arguments{ \item{data}{A data frame or tibble in which the columns that are given in x and class can be found.} \item{x}{(character) The variable name to be used for classification, e.g. predictions or test values.} \item{class}{(character) The variable name indicating class membership.} \item{metric_func}{(function) A function that computes a metric to be maximized. See description.} \item{pos_class}{The value of class that indicates the positive class.} \item{neg_class}{The value of class that indicates the negative class.} \item{direction}{(character) Use ">=" or "<=" to select whether an x value >= or <= the cutoff predicts the positive class.} \item{tol_metric}{All cutpoints will be returned that lead to a metric value in the interval [m_max - tol_metric, m_max + tol_metric] where m_max is the maximum achievable metric value. This can be used to return multiple decent cutpoints and to avoid floating-point problems.} \item{use_midpoints}{(logical) If TRUE (default FALSE) the returned optimal cutpoint will be the mean of the optimal cutpoint and the next highest observation (for direction = ">") or the next lowest observation (for direction = "<") which avoids biasing the optimal cutpoint.} \item{...}{Further arguments that will be passed to \code{metric_func}.} } \value{ A tibble with the columns \code{optimal_cutpoint}, the corresponding metric value and \code{roc_curve}, a nested tibble that includes all possible cutoffs and the corresponding numbers of true and false positives / negatives and all corresponding metric values. } \description{ Given a function for computing a metric in \code{metric_func}, these functions maximize or minimize that metric by selecting an optimal cutpoint. The metric function should accept the following inputs: \itemize{ \item \code{tp}: vector of number of true positives \item \code{fp}: vector of number of false positives \item \code{tn}: vector of number of true negatives \item \code{fn}: vector of number of false negatives } } \details{ The above inputs are arrived at by using all unique values in \code{x}, Inf, or -Inf as possible cutpoints for classifying the variable in class. } \examples{ cutpointr(suicide, dsi, suicide, method = maximize_metric, metric = accuracy) cutpointr(suicide, dsi, suicide, method = minimize_metric, metric = abs_d_sens_spec) } \seealso{ Other method functions: \code{\link{maximize_boot_metric}()}, \code{\link{maximize_gam_metric}()}, \code{\link{maximize_loess_metric}()}, \code{\link{maximize_spline_metric}()}, \code{\link{oc_manual}()}, \code{\link{oc_mean}()}, \code{\link{oc_median}()}, \code{\link{oc_youden_kernel}()}, \code{\link{oc_youden_normal}()} } \concept{method functions} cutpointr/man/roc.Rd0000644000176200001440000000437513672457720014154 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/roc.R \name{roc} \alias{roc} \title{Calculate a ROC curve} \source{ Forked from the \pkg{ROCR} package } \usage{ roc(data, x, class, pos_class, neg_class, direction = ">=", silent = FALSE) } \arguments{ \item{data}{A data.frame or matrix. Will be converted to a data.frame.} \item{x}{The name of the numeric predictor variable.} \item{class}{The name of the binary outcome variable.} \item{pos_class}{The value of 'class' that represents the positive cases.} \item{neg_class}{The value of 'class' that represents the negative cases.} \item{direction}{(character) One of ">=" or "<=". Specifies if the positive class is associated with higher values of x (default).} \item{silent}{If FALSE and the ROC curve contains no positives or negatives, a warning is generated.} } \value{ A data frame with the columns x.sorted, tp, fp, tn, fn, tpr, tnr, fpr, and fnr. } \description{ Given a \code{data.frame} with a numeric predictor variable and a binary outcome variable this function returns a \code{data.frame} that includes all elements of the confusion matrix (true positives, false positives, true negatives, and false negatives) for every unique value of the predictor variable. Additionally, the true positive rate (tpr), false positive rate (fpr), true negative rate (tnr) and false negative rate (fnr) are returned. } \details{ To enable classifying all observations as belonging to only one class the predictor values will be augmented by Inf or -Inf. The returned object can be plotted with plot_roc. This function uses tidyeval to support unquoted arguments. For programming with \code{roc} the operator \code{!!} can be used to unquote an argument, see the examples. } \examples{ roc_curve <- roc(data = suicide, x = dsi, class = suicide, pos_class = "yes", neg_class = "no", direction = ">=") roc_curve plot_roc(roc_curve) auc(roc_curve) ## Unquoting an argument myvar <- "dsi" roc(suicide, x = !!myvar, suicide, pos_class = "yes", neg_class = "no") } \seealso{ Other main cutpointr functions: \code{\link{add_metric}()}, \code{\link{boot_ci}()}, \code{\link{boot_test}()}, \code{\link{cutpointr}()}, \code{\link{multi_cutpointr}()}, \code{\link{predict.cutpointr}()} } \concept{main cutpointr functions} cutpointr/man/false_omission_rate.Rd0000644000176200001440000000345613672457720017415 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{false_omission_rate} \alias{false_omission_rate} \alias{false_discovery_rate} \title{Calculate the false omission and false discovery rate} \usage{ false_omission_rate(tp, fp, tn, fn, ...) false_discovery_rate(tp, fp, tn, fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate the false omission rate or false discovery rate from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. \cr \cr false_omission_rate = fn / (tn + fn) = 1 - npv false_discovery_rate = fp / (tp + fp) = 1 - ppv } \examples{ false_omission_rate(10, 5, 20, 10) false_omission_rate(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/cohens_kappa.Rd0000644000176200001440000000361313672457720016016 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{cohens_kappa} \alias{cohens_kappa} \title{Calculate Cohen's Kappa} \usage{ cohens_kappa(tp, fp, tn, fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{...}{for capturing additional arguments passed by method.} } \value{ A numeric matrix with the column name "cohens_kappa". } \description{ Calculate the Kappa metric from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. \cr \cr mrg_a = ((tp + fn) * (tp + fp)) / (tp + fn + fp + tn) \cr mrg_b = ((fp + tn) * (fn + tn)) / (tp + fn + fp + tn) \cr expec_agree = (mrg_a + mrg_b) / (tp + fn + fp + tn) \cr obs_agree = (tp + tn) / (tp + fn + fp + tn) \cr cohens_kappa = (obs_agree - expec_agree) / (1 - expec_agree) \cr } \examples{ cohens_kappa(10, 5, 20, 10) cohens_kappa(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/maximize_gam_metric.Rd0000644000176200001440000000766613672457720017411 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/optimize_metric.R \name{maximize_gam_metric} \alias{maximize_gam_metric} \alias{minimize_gam_metric} \title{Optimize a metric function in binary classification after smoothing via generalized additive models} \usage{ maximize_gam_metric( data, x, class, metric_func = youden, pos_class = NULL, neg_class = NULL, direction, formula = m ~ s(x.sorted), optimizer = c("outer", "newton"), tol_metric, use_midpoints, ... ) minimize_gam_metric( data, x, class, metric_func = youden, pos_class = NULL, neg_class = NULL, direction, formula = m ~ s(x.sorted), optimizer = c("outer", "newton"), tol_metric, use_midpoints, ... ) } \arguments{ \item{data}{A data frame or tibble in which the columns that are given in x and class can be found.} \item{x}{(character) The variable name to be used for classification, e.g. predictions or test values.} \item{class}{(character) The variable name indicating class membership.} \item{metric_func}{(function) A function that computes a metric to be maximized. See description.} \item{pos_class}{The value of class that indicates the positive class.} \item{neg_class}{The value of class that indicates the negative class.} \item{direction}{(character) Use ">=" or "<=" to select whether an x value >= or <= the cutoff predicts the positive class.} \item{formula}{A GAM formula. See \code{help("gam", package = "mgcv")} for details.} \item{optimizer}{An array specifying the numerical optimization method to use to optimize the smoothing parameter estimation criterion (given by method). See \code{help("gam", package = "mgcv")} for details.} \item{tol_metric}{All cutpoints will be returned that lead to a metric value in the interval [m_max - tol_metric, m_max + tol_metric] where m_max is the maximum achievable metric value. This can be used to return multiple decent cutpoints and to avoid floating-point problems.} \item{use_midpoints}{(logical) If TRUE (default FALSE) the returned optimal cutpoint will be the mean of the optimal cutpoint and the next highest observation (for direction = ">") or the next lowest observation (for direction = "<") which avoids biasing the optimal cutpoint.} \item{...}{Further arguments that will be passed to metric_func or the GAM smoother.} } \value{ A tibble with the columns \code{optimal_cutpoint}, the corresponding metric value and \code{roc_curve}, a nested tibble that includes all possible cutoffs and the corresponding numbers of true and false positives / negatives and all corresponding metric values. } \description{ Given a function for computing a metric in \code{metric_func}, these functions smooth the function of metric value per cutpoint using generalized additive models (as implemented in \pkg{mgcv}), then maximize or minimize the metric by selecting an optimal cutpoint. For further details on the GAM smoothing see \code{?mgcv::gam}. The \code{metric} function should accept the following inputs: \itemize{ \item \code{tp}: vector of number of true positives \item \code{fp}: vector of number of false positives \item \code{tn}: vector of number of true negatives \item \code{fn}: vector of number of false negatives } } \details{ The above inputs are arrived at by using all unique values in \code{x}, Inf, and -Inf as possible cutpoints for classifying the variable in class. } \examples{ oc <- cutpointr(suicide, dsi, suicide, gender, method = maximize_gam_metric, metric = accuracy) plot_metric(oc) oc <- cutpointr(suicide, dsi, suicide, gender, method = minimize_gam_metric, metric = abs_d_sens_spec) plot_metric(oc) } \seealso{ Other method functions: \code{\link{maximize_boot_metric}()}, \code{\link{maximize_loess_metric}()}, \code{\link{maximize_metric}()}, \code{\link{maximize_spline_metric}()}, \code{\link{oc_manual}()}, \code{\link{oc_mean}()}, \code{\link{oc_median}()}, \code{\link{oc_youden_kernel}()}, \code{\link{oc_youden_normal}()} } \concept{method functions} cutpointr/man/maximize_boot_metric.Rd0000644000176200001440000001043713764665004017574 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/optimize_metric.R \name{maximize_boot_metric} \alias{maximize_boot_metric} \alias{minimize_boot_metric} \title{Optimize a metric function in binary classification after bootstrapping} \usage{ maximize_boot_metric( data, x, class, metric_func = youden, pos_class = NULL, neg_class = NULL, direction, summary_func = mean, boot_cut = 50, boot_stratify, inf_rm = TRUE, tol_metric, use_midpoints, ... ) minimize_boot_metric( data, x, class, metric_func = youden, pos_class = NULL, neg_class = NULL, direction, summary_func = mean, boot_cut = 50, boot_stratify, inf_rm = TRUE, tol_metric, use_midpoints, ... ) } \arguments{ \item{data}{A data frame or tibble in which the columns that are given in x and class can be found.} \item{x}{(character) The variable name to be used for classification, e.g. predictions or test values.} \item{class}{(character) The variable name indicating class membership.} \item{metric_func}{(function) A function that computes a single number metric to be maximized. See description.} \item{pos_class}{The value of class that indicates the positive class.} \item{neg_class}{The value of class that indicates the negative class.} \item{direction}{(character) Use ">=" or "<=" to select whether an x value >= or <= the cutoff predicts the positive class.} \item{summary_func}{(function) After obtaining the bootstrapped optimal cutpoints this function, e.g. mean or median, is applied to arrive at a single cutpoint.} \item{boot_cut}{(numeric) Number of bootstrap repetitions over which the mean optimal cutpoint is calculated.} \item{boot_stratify}{(logical) If the bootstrap is stratified, bootstrap samples are drawn in both classes and then combined, keeping the number of positives and negatives constant in every resample.} \item{inf_rm}{(logical) whether to remove infinite cutpoints before calculating the summary.} \item{tol_metric}{All cutpoints will be passed to \code{summary_func} that lead to a metric value in the interval [m_max - tol_metric, m_max + tol_metric] where m_max is the maximum achievable metric value. This can be used to return multiple decent cutpoints and to avoid floating-point problems.} \item{use_midpoints}{(logical) If TRUE (default FALSE) the returned optimal cutpoint will be the mean of the optimal cutpoint and the next highest observation (for direction = ">") or the next lowest observation (for direction = "<") which avoids biasing the optimal cutpoint.} \item{...}{To capture further arguments that are always passed to the method function by cutpointr. The cutpointr function passes data, x, class, metric_func, direction, pos_class and neg_class to the method function.} } \value{ A tibble with the column \code{optimal_cutpoint} } \description{ Given a function for computing a metric in \code{metric_func}, these functions bootstrap the data \code{boot_cut} times and maximize or minimize the metric by selecting an optimal cutpoint. The returned optimal cutpoint is the result of applying \code{summary_func}, e.g. the mean, to all optimal cutpoints that were determined in the bootstrap samples. The \code{metric} function should accept the following inputs: \itemize{ \item \code{tp}: vector of number of true positives \item \code{fp}: vector of number of false positives \item \code{tn}: vector of number of true negatives \item \code{fn}: vector of number of false negatives } } \details{ The above inputs are arrived at by using all unique values in \code{x}, Inf, and -Inf as possible cutpoints for classifying the variable in class. The reported metric represents the usual in-sample performance of the determined cutpoint. } \examples{ set.seed(100) cutpointr(suicide, dsi, suicide, method = maximize_boot_metric, metric = accuracy, boot_cut = 30) set.seed(100) cutpointr(suicide, dsi, suicide, method = minimize_boot_metric, metric = abs_d_sens_spec, boot_cut = 30) } \seealso{ Other method functions: \code{\link{maximize_gam_metric}()}, \code{\link{maximize_loess_metric}()}, \code{\link{maximize_metric}()}, \code{\link{maximize_spline_metric}()}, \code{\link{oc_manual}()}, \code{\link{oc_mean}()}, \code{\link{oc_median}()}, \code{\link{oc_youden_kernel}()}, \code{\link{oc_youden_normal}()} } \concept{method functions} cutpointr/man/cutpointr_.Rd0000644000176200001440000000733414066363154015550 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cutpointr.R \name{cutpointr_} \alias{cutpointr_} \title{The standard evaluation version of cutpointr (deprecated)} \usage{ cutpointr_( data, x, class, subgroup = NULL, method = maximize_metric, metric = sum_sens_spec, pos_class = NULL, neg_class = NULL, direction = NULL, boot_runs = 0, boot_stratify = FALSE, use_midpoints = FALSE, break_ties = median, na.rm = FALSE, allowParallel = FALSE, silent = FALSE, tol_metric = 1e-06, ... ) } \arguments{ \item{data}{A data.frame with the data needed for x, class and optionally subgroup.} \item{x}{(character) The variable name to be used for classification, e.g. predictions or test values.} \item{class}{(character) The variable name indicating class membership.} \item{subgroup}{(character) The variable name of an additional covariate that identifies subgroups. Separate optimal cutpoints will be determined per group.} \item{method}{(function) A function for determining cutpoints. Can be user supplied or use some of the built in methods. See details.} \item{metric}{(function) The function for computing a metric when using maximize_metric or minimize_metric as method and and for the out-of-bag values during bootstrapping. A way of internally validating the performance. User defined functions can be supplied, see details.} \item{pos_class}{(optional) The value of class that indicates the positive class.} \item{neg_class}{(optional) The value of class that indicates the negative class.} \item{direction}{(character, optional) Use ">=" or "<=" to indicate whether x is supposed to be larger or smaller for the positive class.} \item{boot_runs}{(numerical) If positive, this number of bootstrap samples will be used to assess the variability and the out-of-sample performance.} \item{boot_stratify}{(logical) If the bootstrap is stratified, bootstrap samples are drawn separately in both classes and then combined, keeping the proportion of positives and negatives constant in every resample.} \item{use_midpoints}{(logical) If TRUE (default FALSE) the returned optimal cutpoint will be the mean of the optimal cutpoint and the next highest observation (for direction = ">=") or the next lowest observation (for direction = "<=") which avoids biasing the optimal cutpoint.} \item{break_ties}{If multiple cutpoints are found, they can be summarized using this function, e.g. mean or median. To return all cutpoints use c as the function.} \item{na.rm}{(logical) Set to TRUE (default FALSE) to keep only complete cases of x, class and subgroup (if specified). Missing values with na.rm = FALSE will raise an error.} \item{allowParallel}{(logical) If TRUE, the bootstrapping will be parallelized using foreach. A local cluster, for example, should be started manually beforehand.} \item{silent}{(logical) If TRUE suppresses all messages.} \item{tol_metric}{All cutpoints will be returned that lead to a metric value in the interval [m_max - tol_metric, m_max + tol_metric] where m_max is the maximum achievable metric value. This can be used to return multiple decent cutpoints and to avoid floating-point problems. Not supported by all \code{method} functions, see details.} \item{...}{Further optional arguments that will be passed to method. minimize_metric and maximize_metric pass ... to metric.} } \description{ This function is equivalent to \code{cutpointr} but takes only quoted arguments for \code{x}, \code{class} and \code{subgroup}. This was useful before \code{cutpointr} supported tidyeval. } \examples{ library(cutpointr) ## Optimal cutpoint for dsi data(suicide) opt_cut <- cutpointr_(suicide, "dsi", "suicide") opt_cut summary(opt_cut) plot(opt_cut) predict(opt_cut, newdata = data.frame(dsi = 0:5)) } cutpointr/man/total_utility.Rd0000644000176200001440000000411113672457720016263 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{total_utility} \alias{total_utility} \title{Calculate the total utility} \usage{ total_utility( tp, fp, tn, fn, utility_tp = 1, utility_tn = 1, cost_fp = 1, cost_fn = 1, ... ) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{utility_tp}{(numeric) the utility of a true positive} \item{utility_tn}{(numeric) the utility of a true negative} \item{cost_fp}{(numeric) the cost of a false positive} \item{cost_fn}{(numeric) the cost of a false negative} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate the total utility from true positives, false positives, true negatives and false negatives. \cr \cr total_utility = utility_tp * tp + utility_tn * tn - cost_fp * fp - cost_fn * fn \cr \cr The inputs must be vectors of equal length. } \examples{ total_utility(10, 5, 20, 10, utility_tp = 3, utility_tn = 3, cost_fp = 1, cost_fn = 5) total_utility(c(10, 8), c(5, 7), c(20, 12), c(10, 18), utility_tp = 3, utility_tn = 3, cost_fp = 1, cost_fn = 5) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/plot_roc.Rd0000644000176200001440000000306213672457720015202 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/plot_roc.R \name{plot_roc} \alias{plot_roc} \alias{plot_roc.cutpointr} \alias{plot_roc.roc_cutpointr} \title{Plot ROC curve from a cutpointr or roc_cutpointr object} \usage{ plot_roc(x, ...) \method{plot_roc}{cutpointr}(x, display_cutpoint = TRUE, type = "line", ...) \method{plot_roc}{roc_cutpointr}(x, type = "line", ...) } \arguments{ \item{x}{A cutpointr or roc_cutpointr object.} \item{...}{Additional arguments (unused).} \item{display_cutpoint}{(logical) Whether or not to display the optimal cutpoint as a dot on the ROC curve for cutpointr objects.} \item{type}{"line" for line plot (default) or "step" for step plot.} } \description{ Given a \code{cutpointr} object this function plots the ROC curve(s) per subgroup, if given. Also plots a ROC curve from the output of \code{roc()}. } \examples{ opt_cut <- cutpointr(suicide, dsi, suicide) plot_roc(opt_cut, display_cutpoint = FALSE) opt_cut_2groups <- cutpointr(suicide, dsi, suicide, gender) plot_roc(opt_cut_2groups, display_cutpoint = TRUE) roc_curve <- roc(suicide, x = dsi, class = suicide, pos_class = "yes", neg_class = "no", direction = ">=") plot(roc_curve) auc(roc_curve) } \seealso{ Other cutpointr plotting functions: \code{\link{plot.cutpointr}()}, \code{\link{plot_cut_boot}()}, \code{\link{plot_cutpointr}()}, \code{\link{plot_metric_boot}()}, \code{\link{plot_metric}()}, \code{\link{plot_precision_recall}()}, \code{\link{plot_sensitivity_specificity}()}, \code{\link{plot_x}()} } \concept{cutpointr plotting functions} cutpointr/man/Jaccard.Rd0000644000176200001440000000310313672457720014704 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{Jaccard} \alias{Jaccard} \title{Calculate the Jaccard Index} \usage{ Jaccard(tp, fp, tn, fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate the Jaccard Index from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. \cr \cr Jaccard = (tp) / (tp + fp + fn) \cr } \examples{ Jaccard(10, 5, 20, 10) Jaccard(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/plot.multi_cutpointr.Rd0000644000176200001440000000064513672457720017603 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/plot.multi_cutpointr.R \name{plot.multi_cutpointr} \alias{plot.multi_cutpointr} \title{Plotting multi_cutpointr objects is currently not supported} \usage{ \method{plot}{multi_cutpointr}(x, ...) } \arguments{ \item{x}{A multi_cutpointr object.} \item{...}{Further arguments.} } \description{ You can try plotting the data manually instead. } cutpointr/man/auc.Rd0000644000176200001440000000104113672457720014124 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{auc} \alias{auc} \alias{auc.roc_cutpointr} \alias{auc.cutpointr} \title{Calculate AUC from a roc_cutpointr or cutpointr object} \source{ Forked from the AUC package } \usage{ auc(x) \method{auc}{roc_cutpointr}(x) \method{auc}{cutpointr}(x) } \arguments{ \item{x}{Data frame resulting from the roc() or cutpointr() function.} } \value{ Numeric vector of AUC values } \description{ Calculate the area under the ROC curve using the trapezoidal rule. } cutpointr/man/boot_test.Rd0000644000176200001440000000665613717555442015377 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/boot_test.R \name{boot_test} \alias{boot_test} \title{Test for equivalence of a metric} \source{ Robin, X., Turck, N., Hainard, A., Tiberti, N., Lisacek, F., Sanchez, J.-C., & Müller, M. (2011). pROC: An open-source package for R and S+ to analyze and compare ROC curves. BMC Bioinformatics, 12(1), 77. https://doi.org/10.1186/1471-2105-12-77 } \usage{ boot_test(x, y = NULL, variable = "AUC", in_bag = TRUE, correction = "holm") } \arguments{ \item{x}{A cutpointr object with bootstrap results} \item{y}{If x does not contain subgroups another cutpointr object} \item{variable}{The variable for testing} \item{in_bag}{Whether the in-bag or out-of-bag results should be used for testing} \item{correction}{The type of correction for multiple testing. Possible values are as in p.adjust.methods} } \value{ A data.frame (a tibble) with the columns test_var, p, d, sd_d, z and in_bag. If a grouped cutpointr object was tested, the additional columns subgroup1, subgroup2 and p_adj are returned. } \description{ This function performs a significance test based on the bootstrap results of cutpointr to test whether a chosen metric is equal between subgroups or between two cutpointr objects. The test statistic is calculated as the standardized difference of the metric between groups. If \code{x} contains subgroups, the test is run on all possible pairings of subgroups. An additional adjusted p-value is returned in that case. } \details{ The variable name is looked up in the columns of the bootstrap results where the suffixes _b and _oob indicate in-bag and out-of-bag estimates, respectively (controlled via the \code{in_bag} argument). Possible values are optimal_cutpoint, AUC, acc, sensitivity, specificity, and the metric that was selected in \code{cutpointr}. Note that there is no "out-of-bag optimal cutpoint", so when selecting \code{variable = optimal_cutpoint} the test will be based on the in-bag data. The test statistic is calculated as z = (t1 - t2) / sd(t1 - t2) where t1 and t2 are the metric values on the full sample and sd(t1 - t2) is the standard deviation of the differences of the metric values per bootstrap repetition. The test is two-sided. If two cutpointr objects are compared and the numbers of bootstrap repetitions differ, the smaller number will be used. Since pairwise differences are calculated for this test, the test function does not support multiple optimal cutpoints, because it is unclear how the differences should be calculated in that case. } \examples{ \dontrun{ library(cutpointr) library(dplyr) set.seed(734) cp_f <- cutpointr(suicide \%>\% filter(gender == "female"), dsi, suicide, boot_runs = 1000, boot_stratify = TRUE) set.seed(928) cp_m <- cutpointr(suicide \%>\% filter(gender == "male"), dsi, suicide, boot_runs = 1000, boot_stratify = TRUE) # No significant differences: boot_test(cp_f, cp_m, AUC, in_bag = TRUE) boot_test(cp_f, cp_m, sum_sens_spec, in_bag = FALSE) set.seed(135) cp <- cutpointr(suicide, dsi, suicide, gender, boot_runs = 1000, boot_stratify = TRUE) # Roughly same result as above: boot_test(cp, variable = AUC, in_bag = TRUE) boot_test(cp, variable = sum_sens_spec, in_bag = FALSE) } } \seealso{ Other main cutpointr functions: \code{\link{add_metric}()}, \code{\link{boot_ci}()}, \code{\link{cutpointr}()}, \code{\link{multi_cutpointr}()}, \code{\link{predict.cutpointr}()}, \code{\link{roc}()} } \concept{main cutpointr functions} cutpointr/man/accuracy.Rd0000644000176200001440000000307413672457720015156 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{accuracy} \alias{accuracy} \title{Calculate accuracy} \usage{ accuracy(tp, fp, tn, fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate accuracy from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. \cr \cr accuracy = (tp + tn) / (tp + fp + tn + fn) } \examples{ accuracy(10, 5, 20, 10) accuracy(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/figures/0000755000176200001440000000000014066443560014530 5ustar liggesuserscutpointr/man/figures/README-unnamed-chunk-38-1.png0000644000176200001440000001164614066443524021324 0ustar liggesusersPNG  IHDR Tc PLTE:f:::f:f 333::::f:::::::f:::ff:f:f::MMMMMnMMMnMff:fff:f:ffffffnMMnMnnMnnnnnnMMMnMnMn:ff::fې۶nMnnMȫf:۶ȎMې:ېf۶f۶۶nfȎې۶t#,k pHYsod,IDATx흋{7M{ټ4u :P-\[kmR/_ i}1z;%΍tiW+("tv]2 d%,@`K6W/oO߹]pHͯ235bE!nO'zvrr5+޽੖EKqt'Cdye* Czjյ=-o.u}*5^>R6P?G*:;9cX&4es|jTb'VuA=լRקRTʳX^&ŇK|gRWwS1(ϋIs9FZ_o",腎4~Qi :Z-mhC8,&_Cۮժ(GO=Wm}Ol6ߤTڊ!3A? 4{{ 0g1h8H}mXt,ꪊ/$G6{Y;1PTgZkY+ƫ_1}_JL ku]-^a7?BqhUm |&%MA(}Fk-m?B_y5齉Ԫi+æ3o7G%0ImѪkGTc7RŸMzEsҜNfuyoOڤ=oZ:n7tCaOLo*xW4kZtZ'mVo[YZv]yPLYl݈` NJ"t4fإdyN;zv~l.Լ @C_]ݼ!Y$,@`KX2  I<}3TX)4ANS2bfh9,k o`:p> TPvB6;GɢXϰ'Xuvh`IU]OR$'%f īa ^O2My=KOVs1ygoޥ4>zYD$`Z3tP-{$SgFR9f~|<щXD\T3Y7^wf;~@/I}x_ с%,@`KX2+^1N@`@`@`@`@`@`@`@`@`a,ھh d]kے#2#z+9* ׿{ߺpE~g N97ͽWpuy ZaIAM R9S<93i.vy:7g{V)hX>+t4d @W0:}+@+@^m~2 u WCRЯR@ϯ@ ΟYd_{XdB~%~1hk Z pw)PqT. 5*HFap#Ŵ0*4wln0RL@U2[H10į'_؂ad. z,C#DRڢ wA/lw @W15L@f8==l6:@BޤrBXo˹AHJX*36-3WѻLo_ T oݩ>4/M;c  H D``΃SKU7)& d`)zl#E΋\;2zf*Em7)zx75pM F>.*@2=X _)H}NA6I/t'hh"0HFn4`8}]~0;BQkmKً.:%+ 'j7ПJ#{fh O>GuK% dJ@Mъl8[kEhZkl `86AcS^^ \T@o&Mx6k<\i j "qDr3 ) ƚ|"Gx0@cv@`p:Anj&G4N,N(l9 [pU&PN`S?@Rp4jǦrЙ4ܞ;E)TJ xGIaodwC %"/m=B'!K9K!dk]0 d 9*YGk?LJf.yAΚJ( p9!t @KQ8z?DY֝bǢ9J|<HFKp*9Bfp3v$xx/)9~p6#)w7TXtRrRT%sQx/_9Jt(j@A>( L%{_c@p[0Q@o*}SPor!j?XkF^5b^ 'jPc '0Kf[G"GG֤t 6@i 'YqpP #,G @ #@pЀ_7MԆ6#!M*9aH 4:JXdX:*ؿ$nF'0&^rؿ B~/H @@x B5ݍJpKC }O, Rb, kB%@"r6kdx8tJ pП$N$ą H "2G?nKm֊ZJ:kD R`F8!=U,"S.i#;5Ǒ6 p[zLA|xuqjȍ 71Ptm8(((@֊3)2PZ,a#!sH9O8 reU|{5My^ltHH x@SP=Ql)`QB^ |h^m&l% t9ޠ ,UA2P, KBtא` 5' @wcNƎko*57ꭤ֐ ?I-UMe*zxKJПG'jWK{AhIz).+'{# NS6QA`i-$=eDGĮ$V4yln![@A :HnDHxF|=caAIU5t @iPO/g֩a0$[ZK ά @@*NWvR~A]C#N ްeJ=cM!r&n #D7ظNGe `L8*9CKKw arb$bpI;LI =0jO @Ϡ怌:rmP@M!4BЏa(dfu5)ToLƗ~(dM48oz s`RP[0TPPpVSl+< [Jw`m6/^zP\#l͓31| DOmX ӽ%~Y>e3bu483@df:B^P`HƬu%+!kG@3%7f;f0l0l0l , d%,v:O\v%?|qtK׏ @wށGN 5ǯ\^#7OOvi @wƑ85kT `qRrw"׏S3gBR*N !jC^SˆŲ۔>}:9ɑ:rmG5t{cT|'X2 d%,[\v:mg(@`IiQLgϊpYQpsՙ5>ACW'mO9w={>34QEF U,td#:;DNHG $`u(,ȖձrASdKȎmǗTS  KA]OZs$Uś_ޞIi)|MtT&[>`tC'eZUgH$YHX2M d%,@`KXꂏ,IENDB`cutpointr/man/figures/README-unnamed-chunk-7-1.png0000644000176200001440000001552214066443364021237 0ustar liggesusersPNG  IHDRMR/,PLTE:f:::f:f333::::f:::::::f:::ff:f:f::MMMMMnMMMnMff:f:f::f:fff:ffffffffnMMnMnnMnnnnnnMMMnMnMn:ff:ff:fې۶nMnnMf:۶ې۶۶ȎMې:ېf۶f۶۶nfȎې۶J@ pHYsodIDATx {uR^MLdZ6UWl7TLXuYʋbp%.39gfylvXAQ P (":ED"Aс8zWy^>rc4pa\YSO̼(,.z=,hSO̼(,.}Xxy~{#Q ~_䂾{ԏڿ>Y[WwKrBܶ>Tj  N&1eqW({׈Us5QY?|n1uQO]6YN+Ao/՝*^3.عsB) Re~1*⪞|GПoV$%U( auWb z}Yv\Rq([U{J?7z/v\h8G/ \zy{Wnk|K']@6>+%#d[hm-B$smt]^׾^z mv]h8_"ꡮiN.,5/ʾM +~-6Ղ*=7\hq?-wJ#+V AJЭɬBx&lTuVl ΎLTiQKjEP _lkwgpQUZ_ʣBbR lkn;, _$}ټ˃a}Zqbc{PdϢYeGEߗV6e?$?Hʦz,k5vAѸIMF(>V.Gr3]Ч*A!([S1}B>я,ZrQȹjT Sk.~q>Q_ 'uu5Jj}`4$hk3AJ@fG2OAJ@")"Aс@PDt (":W̤})_S~_zWJk/7J@neM߯Hqt9WSx<<<*bR{WoTF|H`qjwOWŝhp`W{qğv+TqD~^jJ-=%`GІ$I]*}鶽;/mo{XH$xAu2WڷoiV(%%@tA]R򆠭$}Co!eqFw/jEtU>&gM3S~IVg3VoT}^OrZo#)gi@PDtp":ED"Aѱ@?O¤ `Q (-,a,*/ EXAP`0  R`AAPZX , (XT0J K_ J)0/,\Ag6$a9) VPA X*VSi({c[#_Xx0FQ~/,4A;m4W߁ J"SELQ~/,A4Q߁ CP3;0a!j~ 4:%{c&_P#S;0aUʖ5({c&Z|Ӟ5({c&X3V_XAkX=;0a2mVreu*XIt[-wV_2oo8Ki9a\XIg=} KO&&_Xz+sUXaI j|oH˾X%5 r p"A9YtTJ؂2 XI_Pv(`t<A3C g~0 eAo{@㙧 e6~CXkP (-͚j(0J ,5Pv(`͚f(5YÂX eAia){@0JX eAia7Y{@0JbhogC=APZXPv(`A)X/Pv(`r3 AP f2~; XJ; FP`(0J ,A wPBp%oKC=APZ0Pv(`6²2 l eAia,C%v(`f26 L e뎾 n؍D*8Ŝ=Ab*T0lia,G߰ ,oa (schXk&.AYN{lG ٱ Y ٲ Y ٳ=%(ϕh[lH`Yn(`^p`\ru0WVסfAPZ;˨kfM`Xz!u IP[rwR׬0J Sל0J jAPZTV AiaY&k.Mg5]ULzS* kya)7YAPfz_f)7YAPvz_g9}qMjlowgW  LT 3u ^o=T,7S' ,l{fR hL#輂}%Y a]nV{t힩CC5Ad24uFq/v hLT ˓q5[s$,5Sgw?<φ^=9ɂZ=ch\ H -嵓>.?zuAcAЎF't>혩k7^oxbA=S{f5+}s~-ea݂ӌ+:/ˇq5l\fՁ㉂ڮ=‚7f=gO7GFP:`h\ AϵEwyb3 Lj\Z dM74APa,3&~O:kq5S~ hkA˃9A! kq5l`[)ԄA DCjX[> ( 3u :"Ԍ5и%茗9=~ h5r74u :& h9S$APcq5[P8AY eAbA/G~ A)XհL׺ mL?6,GCjXCgB]J6,_s×AXnհNAOʻ~R bAоiڱ a#QJA-Yh&fAP* lYf~8T6+YAP, Ae~w:m* oYfu.AXfY.AXf. L`AP*A!lEj A!lyj A!lqjx`DYa4Y-a4Yf=aT< (͂T6˨q5 ĂT6ˤq5 ł3 gd2hd\ a (d\ (me\ (e\ t BP٬n0 BP, AeW h,Y)~Fo?0" BP٬0Axxpp A hO7>MAPհqA|Ej(zgA:^cgk,3w}{%L@#kk\ =^=xkh\ ͎⏛KYުG[~BPJ< t! ,gwcj=1/l\ #t3k3W hଛݍa4t֍0y?=ٳsPN 1A,-r$[R 'Ebaa"$TbFzw27֤?A1&*%p8wA\M%2J,Lnò$rKn <,rWOǷR7YĬ΃:y05Lƭ=&$Dt (":ED"A}\)wz77Y=;/G;m;21>s -ЁA:swTj}+'J-ϊOcΊCxX z\/o=>YlL[1z喠GխUneT6+/k zKz)/{s|Oxj/yo{zP:H*m#=>sV&IAE~i>T?.Yz v|R ܁AED"Aс@PDt (":y;mIENDB`cutpointr/man/figures/README-unnamed-chunk-26-1.png0000644000176200001440000003606414066443433021321 0ustar liggesusersPNG  IHDRMR/PLTE:f:::f:ff?b?b333::::f:::::::f:::ff:f:f:::????b??b???MMMMM^MMnMMMnMMS^Mo^Mbb?bbb?b?bdMff:fff:f::f:ff:ff:fffffffffnMMnMnnMonMnnn???bَMMM^MnM:::ff:ff:fې۶b٥nMnnnȫff:ff:f۶ې۶۶?ĚȎMٟbٽٟٽې:ېf۶f۶۶YnvmafȎې۶Ѝ pHYsod IDATx흍F}ߟ;|]%)o͒4l E-k.mN1mnxl4%.g3ocz?Gz$={hyffQP#bP1!Q EZ(jB@QPԨF =[P}ͲsAS~X/HWwb'׍\S"` wQ!nu|q\'Ecdܵf=@Ϣa g!rkp]BlW?y ^wb];1]7H0dMHJxx>׾Nl|Czbԛ!A5%z/>7Yq@|"⩿>0O:_|JfM\Nc!0msydtgFlk1b/Jf4xs,![t#"4@5&~`[DSeugI]C?Q\QܿT]GU2n"pyǨs I܅nPB!XZADVqMH=t$731B%^߇+^34E<\(⊗G~1$>9-OW$n{@T^G ]ʎރ《.xlJk1i(dq7ɪ]7_),㿔xj;uPt2|cB2A᦮ȼB ɑ'+*7*P~ tuԙD]=d3!@ɥx H:Z!nEiD*,O ͈ @_*!`P$" ;aӯcR3NTW*eiAu=oNRటS#n^̈g&0@E|N!Cn~MW}*j NI n6T\g[ՠY^8"^Zj񲤖a/r?H S Zڪ )0n'&uХ\@UHfF>F<6-U{ "VKElOnq) D>Ah)_qat3.m@6Х\@ՉGeͤULWs*E@vIks@?y?‡vFVVW$7(=c`[)yE=s„t +D hWyP o7l wmSKwޡ`PT ,j+B@[ ݮАx䢢GݮАQEZ(jB@QPԨF-5j!Qk^G/wʿ! 8D3k]4 u>3 ǻHZ|X[&"atyTogPc7MÈTs@/nc1@?jhOdyP +⩟ z -vir`h(l\=U ^C)u/( wHY<7-nɎ [~A3EMX >R9.gCֆGRi>+vű8UN)eǡJž54r1*At20t\>׹?5:.vQ EZ(jB@QPԨZ-1! Vu aLhC@BPhPƄ6Z-1! Vu aLhC@BPhPƄ6Z-1 ~n󹧟@PeVA([[~KDc`@1A軿/!|HAO%0y~AN&ջb"ޫa,ˏkYcԯa,~y8>ǒ-ԯa,վp 3:[O{P0]Ju~ϡ[WxA$d,g+^Y>`F n! m([cB@ ˜ІB+0& n! m([cjh[sˊ5sZn?1+xrQRz ɫ/Ÿ(Ş0c˔O-n|>I c>VAVVA$M,XAA=a =M#)ɱ c>VA؊o/ 6նxtj& E@֯:nShx$jBB@o&QzPk#VAhxP?jB*\yľ~m YPPyF F40c޳?f9М@@EmBVAu/(wmZE=Y{Z>#;ba =V# $롾H<#OXBB@+bQzP@a'V@@DmBVAgeC{I-{M(iba =oQzPWs3%u51+ aV Y! BM =Pgw6kЃ6ׄF9y~6mY׃:^D.PK[J tBI#4 3|݃^CD! V|24 mFn5*FͼE<<<[u(C2JF;KjNo>mȭЃh.>qҦM܏v;i3`~= "MP1~I5AT#TT{Ih#9fiM&4aMB)jzqvb'^]L 5e6r+XP5eC>]4enjcAi7 NN@@L6-@} nk*k' AY3n'F`LT; 5G6mVP5mU,ij jJL <0GԓP8ghzMP57)i&j-@褿C(We}nOEKM'0)-W&~UK'λxUEiڰBjUv(iba5- mMEFuA/;!yݫCvaD2lhΫvϪC'/ͤQLTǶ Fn:()as0*x@RTEi!#Ť*:V_mt׊'',JuZT 4tk^m u"~d`!+4Vh*ʨ܃D3h4w(iba[wAi0!@(a d!P'):a<ɴF?~Vh hhMt:VK_.$ɔ,I3Q xPqm$ʉ$5rʩ6vPvWfh+}{ű}|[F pp4, \d |Ri-nQE4.ȐV=Y|Sx_Vp]9ݧC>ȏccs'g }Njxi/5OQ/;Ic ]۳^Nwc sЕNů݅/aOȑ]E񠪝d\-%dmg"J3P/|"]7# EIc@WsP.BV*fעT.L)hA7r)%MDu`Ut6TAM@'q@bMjeJ [-#lԞ+%-mȌm 7|&ܛ 2әkYlZV.Gr+Âe2+xc*9uHVsỖQa)Yz[[VXf!@sޗ)Q-@_F6Xcʯ6ԕl8 V:[eefKLܘeKU ѨmYcJ.GHR(-K4 $ͪXAhe:{caX?iH̩zX8%s[қ3&|3GTrM40c}We<"QeF9t"~5A(_ jj@BLKG&rL EuՒPTgDl""Ws@[hІTג /)6ZT ojuP@Zd"i_zIDATډ ML;ꇶB+hlPqo1iPa>4 LOh0֛nh ,h@>U4iz[OЀ*+pEbo%O4+5zȻր_ i ?s&W^[qEVPPlc5j;~ &Qz}2峧Վk\qOsFVPSGbT;X!z/jǣK% zx=Վǖ45h.vI$y &|:# mVzn|>Ichb7>HBzaO8g~7 a@䠵$szePB&Fnhx!t; hb0[kߧ SӇ"#B2[4qxp~.t__ ^(堉ōpN^ 5<hX!xoȭ4تƔS:X/W iM !@L8@4fs@QACG``}:|Uˣ=>XsІZ! Y|UPks@hx!t{@x[І[! Y{eCm60^VH6!+XB@9D\(Yh#%Cm/?h#Q݅6r+XB@9D\Ж򣁀6rn<,!"hx@@9D\ hn4]+XB@9D\Ж򣁀6rnP{ZR9a/lM m5v(G@=^}7H`g{O^{Cs8cM @\[T_>+&" >%%w}P:eC@a'c7۶9h树&df~@Ϡ\6~>+!P_t|$ҐWc7ԫ؍<&d0~PVQǥ9&^+$FRڀn&aVpIyp6 Y!⊀ Cĵs@ BAtw%Cĵ'@M F E@9 w6 Yz f t,z#O /&dKc4p>4#O^@=M hCnL0x{f,P)x;V~[h8UAÉ7L{6 YM#Oe^Cw Ѐ)6IfZ,)@ůaIuixn[8^-XquXҹm*xf 'H=hZ8N`3whNM4YxZ`Iו-08.B6a ~MjHʡr5{@ASϯk$]|.,i;&ygP+Lhŧjx Cy/P_PQc9oN m+4Alxq>hg' I?j!tmfC hR1BCzugZ~ˀ*B 45ݶB#@7S7cP&J(b/~$({PhJm(PB|Hm,)Jrl$Q#Fm+Z$ըҦ 5|BW_jŃ9廞:6&q.ZZDLb3@}T8L^{B 0:+0joRL4J1C(7}:c NxZ.{2>];Ӱk?4(1BcuPYAd=4vr>!|xXѨ'0ےx++";tBC@Ydz6zSf(?,\Ob#M}fkŋzn&m(5aT_B;Wee۞>A!}xx,c7nOS;sTfP=oqu@ݸO\4NSy&Ԁϐ/7j;D\PYNX#@$CVHmZW`fhP&@wm0TtCe $~h y*+uq@)i:T>+*g i褉P6\)˼͝ԚFPqWTsNR`;Y,& oK1Kc.؍GUWFAf(+vCXs\~BӉN">6!⊀{fhRZOe9Zh)͂9'X7*vISyH}fny!<-(.j̅?BqE@}&;x34*:հ6ixTf(U$ # }5TBc]DU4f~U ;⊀L@yXïOh5Xgh.|>;J喪qE@&h ߒV}"ͯG<esZQvDD0;3v(0@$st1a -҅R*wA"SP9(btrbM'H!|Q362W>èsz^v8vǨqAc7^;iD ŔҚQLƩkJ2OދƱue$Gb8^lfo&O=|aG\w PTLAyeQS4d&O{TA@J$su5u@r\TJOsxu aL#}9U= .d]/FZ҈nZ@m VUS淍W4&@C̓5Xf* sCc8^xKTvJ-dίPfn!i<i Rk+3 É,bȜM*Ffb%n!iR\bN[M Mh;S,d'0|n!i7-m٩M1uPof褣9(!L{噘-1n0`, jgiҶp ԻNRa6+MdmuQyM[t>,i ôCUכjBk|RM̮&~X3c<*e!ʂB.r|WA9(_d>ҁI}y46ol S%{3X6+F7쑇zdEV% BzX\=Մ3\<U+ҙW0+ohApTXi]Nx߈cT6fC&Sm"i" r j8Wss~rGμOKyY˂_j5`4PoV[&| PPSZpMu&5nqUZPՒ[ v9+rJ+ WRKKU,uck d GJrNUQZ}4-W#{2xG C|97u Z(A=7ȵ+w4khgVo Դ⫯s +Gf6Zn&a t7! V۽ m/M&\<>s>6h- qm|΄86tgB@kB@_3 4- UO(jB@QPԨ)~mk@ԇ9<-|ѯOz(|p`tV߹r.Vغ6,KրdCn|XN"ׂ(^x"4o*Npr@+l_-x<`]O^c1س?Ov(rRnCʼnO#q=kq#qDOXh88C̉syiԾ=!>Z=ki=wxdx6Tu$ԨF-5j!Q EZ(jB@QPԨ6/CGc>B@bƃݡ1!t fl" m&g!̈́,О6ڳPԨF-5j!Q EZ(jB@QPԨFS-t:IENDB`cutpointr/man/figures/README-unnamed-chunk-24-1.png0000644000176200001440000001425614066443433021316 0ustar liggesusersPNG  IHDRMR/hPLTE:f:::f:f?b?b?bb333::::f::::f:::ff:f::??b???MMMMMnMMMnMYYYbb?bbb??bb?bff:f:f:fffffffffnMMnMnnMnnn???b?َMMMnM:ff:fې۶b٫nMnnnȫf:۶ې۶۶?ȎMٟbٽٟٽې:۶f۶nfȎې۶vI`e pHYsodIDATx݉yl1iVڴL:nLG,aIdڦ-TFQMڊe/,x{wqk%ޖ_Vnix[8jIlfȥ!<jʏCl˯_fr",t[VD&COS@?[nF/vW̶Lm^w򯽿@{Y_>$ )GB(uJz:%@IP:%@IP4GѫAx$3d.l* MM<'c~i;,Mv_:Z]TYؽ7 wZ+}ng8)qo˳}FTY2G~ԓ҇ʨ|]o7}rƭth 8/o$#i95ay9zoeY I)wѻ"wb.[˓!dxTh܎7VQ#+'g|u+w?)~ꁾ)΅HIA*y zC\}O|zꟚ $dۮddPN^wEmCe7هx۩T7VD(D轿g:VE\(_{z]CdSsY}FOu ?~IGrZzV(9@uA]zt xI2T&?TO'M%sV_ze_)S,th>BC<#i1$Ew@ag%;%7&)9F(ھIZod5AFw>3fn@&o" C1օ׻#hԉt<-ڇd/<(zЩHz^^' nGz^(uJz^2Ч$?_~ж @W+m;_~ж @W+m;_~ж0~vͧO~ީ(~Ok YП??{??|@?Z'o|eEo>s`[ @os [dX@_v-sz|OL0z/3,~PFՍF}@ݟ h~ZgYN U @j+(@P P2Tm* U @j+(@P P2Tm* U @j+(@P P2Tm* U @j+(@P P2Tm* U @j+{ANdNz"p-賬_{AZPVP PjT(@meU P[@6@VP PjT(@meU P[@6@VP PjTipp1@-*нQ>ZPƀ&GrhA@}j @ $Уhc5 l'@KԧA\69$@}z O@K R}iڈƆO@MhA@} P[ih>ZPƁWsk -K ²<`#ؿ-;6/YCŝ~}菠wϷ'7D_;7􋖳~n5σ{4od6fyʼnT_1_V]fnh#hA_МtLGzG6CM -~">V}{)5l B^ 螻?YBG7tn%_{@/ӿlVw<:@&?:h}t)$Љ$+O@ hA@} P[=\-cԧIhA@}LM PV@y!$A>5}(@meU P[@6@VP PjT(@meU P[@6@VP PjT(@meU P[@6@VP P岀Ndtf(' A ,鞽 GPjT(@meU P[@6@VP PjT(@meU P[@6@VP PjT(@meU P[@6@VP PjT(@meU P[@6@VP PjT(@mezzw|ZA?_he~P?oimn;A@eYNl(@O/[ZϷj.cugCzs;utWLug/}(@meU P[@6@VP PjT(@meU P[@6@VP PjT(@meU P[@6@VP PjT(@meU P[@6@VP PjT(@meU P[`|mZ7w L+} = -7oV0sZb"e X?Kx=V:N-clU,shyR]@-נwZb]kڳUsů 跙 R]@|wZb^F*4?-諱~h#{ZCVuH٪ Pv2[! Nf:$@lU(@;h'UdCTƅ(bX/eM qeb!. 5B,-T ^(uJz;9?k(jv '}e6WMgMo*+xX>3y?k M;'fs9c-TYp{w^܊>|i'f G$Xf۹{ee?_;g:'erx%J'[gvMi=+|8kc@\v'!_5hx( lY2q68kc*YCE;6Ͽ({o<4[z0ͦQ|U_YC^YseaFSu$c-BehrׯHP:%@IPuٻh'hjJ6Wÿ<>ZF6G+/{%m'{W9'kw&ev8̷3@SpIs)~) to^.HR14zu>8dG_oe Vdm5ă/_@0+ (aeA*P(iP(iP(iP(iP(iP(iP(iYz~_ox+(=ɂ' "[@ ~u> (Oғ,~ 軌; Z A0l}sZ?~A_,;?_mMʈAAiw觌Ci)2TɮE}K@yW%1ӯK`Ɖ<"hї:}g=T]gF 0ͨ,02JcAygîtWǸk^mZAX"<'|ڗޟk?ۡ^_RY_>?;R </i_*[Q noDP_eRRzYju"+BtơI{Ԧ ,,xw~(%M]7J $Poq'Hh T?QvE=YO˺A(\Yۊ={Z\W]wP]UN0DAe(rUJ.].{pV?xv\{b T \U3]"~v7f- |O>IC}=̑}ASrOOViwձ)Vn jM\dYUfB7 6rtq}x4|ەƬ=m=ӄ. roKErɳ8j~I5r8%հ{{ʥ"d@TY(2.P.ET("4=RdƲ\,#KaKEr@P.uh{5E[BT(*#fIKaKEr@#P.UkkBT(Ph{5Er eF\Y#tI5r)h?KZR \,8KżkC &~Rw\^& @P,K#6.P.,KEYҒjؽ=RgF\,{{j8=@P.,K'4=ʢ9KaK+4=Ȣ4~I5r d1|x*" p(dO*1Cs4=" j@4hJjؽ=" i@4@CP,ZNT(Pާ"ro@ 7''?zQwkҎ>v3]P^PTvY$/zCœ?5%!v[C3ت̤E^=4'IAZT1z^f2[G *Sg|xpڷt>h-:^n:`4@}>@xrgh@UJj Ⱦ|w1E>!@9IvoO82ua4"UۋILl@s?(U: %ɹ.$xx_*[ ܂Pc4_$C®P$77d_5%-Њ96ހj9=_Ī"_*2{'dG*)6?y9?kՖI} Iۜ5m$'~M;fe,/PiG!@_@%O:@Ϫ4:54NT9%)Z {3DgtZSBU"ڵ_Ofqw@7tjbѢes oUba^}Gf]c t4 ۋ̑I$0YOx IEQ\,N^tuGl A,3}QZTLu:JtH)+tj~e&U39Rx!Ni/P*ȹ7q% (}\C֋kcJIRoЏ3PхJkh G>ܻwi Cxk怶;v=U Ƚ}XlN)^l+ěhO-ĕ++@eEU!I> ,O@}.3VWϏƽK]<p-pJ!_'PSS΂{>.$g_d>A8 'eNNݧ'O^7v uXWTt/ ,4?P<&уE6+r @rsOлϾ*nϟ+je>OPE Zx]k _7>\zX]sTd/ T6ߦ]t$_{*@AV׭ڻ3U&hU lJб.$R}xY}T7m7A'ۤ^`;@[!9ӽUw>-JZP6S?hdw>8Ao>zF(u2'&~` @$_e|n⟎Kjwy}_:!zozjfe"rm57x@Ci߀&|iy\GJd/ Po,l]Dfqzܒ={>ϛ-"3L/P/ocZ(5253 5G@8G@ ^~\U h}MuYjgrWCaǥ|E` TP/UTUskv}3^=eKԌ䒯 tnZ5xX wuji% Z?lPj-6vR ,T݂j?l,d@]O Pac ~^&|XܛT*9*|Gڏν-$_3p@塈f%'tr} {mLԞ$8iA3t)$_?p(69chښ|]xOz8u*z )i3@1Irn Q3 2q}(TIsdš ,\3X0 JA'Is4oA_'IN>b .MAaVDSj;TonE]|A;SaG(*4q3{O'p(:6M=?8RtfyPPG%v[xӁP"Uzs|EvTͳZ鵠zh~ zPjAhxsJ5Ik2P :@EP  ho@=(:I=)uP_v)N4AT6Ai^' 0A."J범PrzC$)a@ teg[.1ayuA4 IeHe3e&-@k5_YR/^cBװoA.~KxV?$yG:/ԝ$+8~zPrnuO w\j0'EPSBw^P$27I"x $Zo$xOv#=׌Po5cA^( hx?Hλx&;B곆5@=$ivzǎMPdP\P & vP@ xG(3@  >]<7 } @}OnB'(KCT$OR? *z GT8<hF6R@O>1Oe.AꅄZbon=7I"BmΎѡtXIw\xvy?@Eeޘ6xP/ }BCAŞPBC"Xeen=ť{*Л_ݧ'O^7LY%tm^ɏ^o?+^WT2bP#}=C^[ق}GuK3*8C]kl]" v7.>(/[J3'(l=FYi7O(GuCop-j{\|ql=9r-P-(nCmoP@njA; TҹE^ӳow&A HT櫚E»{ʕeϮ+`@‘1Vc(WJF^>I@ǃi1r%h!,a~Q»w\}3X F/G܋}¡=Rģo$#뵬 ^8tD7?/@~ p(5I>m >ӀOڒ"$t*{q#彈y/zcc)}9PDkD]paPw@QUtH!5,o8! = E7惘5=ww i-*NIDAT;?Ϳ@fQRq}{SB԰ר )ckؔ-!Q`EdV6c"E>FzN8 Թk kP`; D tYy֤G A ZKºцD)!@n%{]u#Fd޹= RDBX iQk"#@EJPUe/;@ RҀ*T_x栾MZ=P(8&5JV j!h]{ʕBhB&5Js4+":H>c'4'@'U(W E7J4Jc ɸTc(MCh2'|@q?;P.I%1rdO*1 &~Rw\4Jc ɸTc(MCh2'|lw]F6=vI@>iE=@@@@лOOvޜE{rϊW﹊\7gśxw}%g}BSG'" (b zɿS(}?r(G1 $hs MjA#rw@Ja Jf*t>#=,iYt!q21Kߟ$Bd oN▾7$(iP(iP(iP(iP(iP(iPY].|0G(P$5W0 4p2UY>hhPnO&ˎ2y=vlOnL @jsypu*M ZPr_5?v=?wu.*%?tZ6TTz z%P5}.Վ,V]<%_==.; hTښCn@I"+HQ^XeU]fb۱<3Pc)j,RX4(((((((t]IENDB`cutpointr/man/figures/README-unnamed-chunk-46-1.png0000644000176200001440000003010114066443560021306 0ustar liggesusersPNG  IHDRMR/tPLTE:f:f:f}?b?b?b333::::f::f::::????b??b????MMMMMnMMMnMbb?bbb?bb?bff:fff:ffff:ffnMMnMnnMnnnnn???b?bَMMMnMnMn:::f:f۶bٟ٣nMnnnMȫfې?ٟٽȎMٟbٽٟٽې:ېnkvmfȎې۶ pHYsod IDATx흋qfd%GҎcG҉'˹[ e{$3V/9,[> T5FS8SӍF͇UG% Kr4wXX\€d- (K€d- (K€d-a}\\^,@ݦM- 040^€K€z ZP/a@S %K[n}Ͼk[~}^1$괿*͛3r:v,h #aw;; }?*NϿFrUA1ڲO/[ޭ+=C\g?[#~*?nQ}5o:d %տ~S[NO p_d^FVe}_$4ڲ>>лo-]M}(PD:TGťyBOڄ|+5iLc?7_X}c@jW?_XU5uҍA+^}csQlLcqB- :o˹t=@kU?W~ [XC^J]ɀ4 W OI?_*iߙmkP"@|XyKY/߮*B/+;zɂ mXȀ>$|Ҿ3_DR.|K CE@sfcH20P*2ЗュKYZ6~ve@5`uPaypH :TPoa@ka@8 `@ h4(Tŀ e/\ h4gJRb@4StdHcM t j.q=(IثOԀbw<5 hT{ԥ`@740EQn:4j*3tM؀Ɓ2b_sC (Q wuzg@bא}O{1(UH@.ޚTNH yN|ʷ:).7d@PxQI/z=OyW'68Qv瑨u?PRhV4t$'Zu (A9փ~y||!1d@m? jt (Aa8P4ELʀ*Lʀ&h':d@40:xtPav hPk-Àe@7EO4v:<Vt:x4v<Vt(u*z|mLa{<T -JR\!Vf 8PWfH"+T8ʅh-À r'^f< (\%[An;;Pπ _)@Â<*@F@ePOQ|8r=PL1gwk2/n<@ <a3 (@[Z0]@b|2s,ez3-q-IRwPābl@YūuHߋfGs8 ($)=yq&z!InYa@gwOʫWCt#4 h_R@Z9CJ^.,եd@{g@hi7RBAd@{RE,.|4[>|(n'“/}gJo<5^p ȻP0x@=Ic3Pe@t8`π"|[ v:@ 2T$@Jt@|&v (QS`9c#3M ;ϔeXGHK=-\Ml/n\lIжlL!=p/|ȁ&p v2Ip<;_fJtsEˬPod@)/3"bS١:kIz<%4%0Fkuw v-.!KOԖ|] hXMPT3. rq#=|dkʀ5VAЍ |]ksq-c@)4HedM3$ %_jE wkPT+[iqÁ2 {k(-_t@F'<^p U>-/Edgt3fkV 1FHu+u2.j: ELD@x~}T.q"ʁt3g5@cLCSyѪC=}d3-.7b]*.$#:F$|E&#uk<M:<m4m2y352SCoOӎA"hZ@uihZ39b:Pͧ_~Idr)1X (hx@|O1=^Z('irAbe~4!8`r~.e@a gh[I (' k::bV85͓ tU&tSuc$uڄr!VVx*/ j=d@?A+:=(bXt]OK\v/RPP9~^$IRb@+>+c' k\25vC`@PWIf#5{C_ΐSa3\COP&==n=gwttFɀR5E̺x+ S(PZb413IJ %j4C!']oL.)Ok9D]RDC.24Ub?oܝPWDRDI h'J>92lTPbJ.v|l,q;);!V$DU_ihOC?uxPV 3W\@ASAQ>6ƀkZPbO_A:]v)m;x1LSmt<JN 1 h!ɧ%"Kr zoU&>&t@c9PKCL:1P$|\ ܚDԭ&_.>AԜ~>G X> 9ĤIs kpԭЩ)RD@@뙞tb ΀4ԕ/$ tߏ€:4e |4 bq ΀:4}\,3i>Q~>Oԡt:K4t C_^YQ&:/ 28j>5|l-G@ʀz <2J@+$ tJҀ #=@PHq)UkSCOj*xw[mDžW(9zPg|*S&veߌ  tπR5.@CяjitPO㳼\րnEFi$7%\χnТl6wSH@ -Zͅ.~D`?R'wT @SDX|+NR4|2ips5 C@˝tyi8ڑ| P?%Tt'Pi}A{ l ΀R4.smʤPe>}m.^P"s9FtJT&V",cN,ʀ4.sT 󲌸̴Pe.wHtF@jO;}6~,ТHxg :a]OKTSsG'J֨[HYqȇ0hPJѸ硄 qìZ}Z"EPOih68I45 (H'Pf0l{ǧe-[v\;X|td@52CLǠ?BK+I;eH #tTO/n<*WOƠ χ&Uh%gjX|َc ɀ:5]>2sMUwvlOԥvt@2uh|Ze gX>-P"*CMxȀ5 (AjiE5Frõ*ڴ tXj;@A>3"e ȇ ɀ":<(=a@D:){;}-u[4mx$<~s2WׁCo9Dd@a s;5uq ŋlc'svq03c% ,Sv[񃀚 ^*}ƁW:uWU,3ESjPB np |Bp-6pC@ ΀vLд >QZpr4m(|2tEQ0M(Ӳ,/1>ЎZL>܀&n '?ЎZgPfI@VOB:MqNv)&tB]v80|<JR i P$IorՉ9)P.veD]lcڍn9  @PIa2RR!Plo≌,:xi(d(MmDQߐٵO!y>n7]%)b4@ۘvcmp#;yqwT A 2TfX+ 萢bEƦ뚹4* T@zt@a  )EKZ"plcڍn:E;ffT~nUωSsP(2!̌d^@݁I9$@;|L\@JwZ.>PgȤ\1=%L[ ’Ր*aTI=-c @]1sj$@nZ3xgDn&C7e]Nݼխ\r<t5rz{P\hr$4EtHiɑ PdD4=2|}(s|EQ>0@}CqiV(EBQ^$ ߻N@70M ajP< DPpw_|OP@ ́EQhaހIf@msa#@aj*~G>L~Θ!mna5RXπRXɃ=Ɠ|:m"E3'E㮂r+HqƠa/߯w![>:tPhM ,b,:3Ú\ 8RO}ܮEvakoĻ,|#ߋ7̅lL[fCEm햦Nw5),z=hm/G Ńz"ێmw8^3 d@iF8ͺl["c.$ 47JE9RĈ@1hv1xabpU"Ju ګ.hRi4IhQ hD+]@5;IooƮKX%:(b0d.j ;44~G+=hm0tHd)H۾uOyLJC@eLEmE K@5А=bH+1G Aσ bSbċal@ :ai&Jcl[@ &>u>4 PHrs2@Y7HA|ƿH ϏeVtB0@}QHg X~_ ֲ4bHh?2<hʦi,ek\x@=AaZ|Z7PcY/f$itvw7- r$ݖqWH]+hgZ,ˁ26xrl.^ܼrT4ީׁ y6/Pm7J>y4Zwۍ_(W@xV2:tKTmJzC (]$f ΝK. _]qM@7ؓfRk)nD'Qwueg))Kt^!'z~CA]ci%/ŐtYR12tsfPĨ=(шǐK1dxj-)nfF?}x) Pᖔ Npc@5]ı}YR PX84-]!I"Fqv5/R 9+\]q PZ&I~wޖb+h+! QcW=bȸ"֫?`@;sL?& :F@vd@1]Mm-+'[х4ÝKqM;IA$ l M⚐n< ɀn@(@U1€ e@k& sņd@S7`)Wl,Ůf<#:r"Cv"w&>L,Ůf$Q.,ߐ563f uu0 v3(8do<5`Vיn;^8nuwOfjf.2 vzQA{s#QByP)854@ {^瑨ƠRPhiK1Y|Xt/?ea$)ࡣU-zT8/4}=kP"|')uP" h0^E Y! `@0z/:YlaA0za@S7*€nUMԫ W4uP" h0^E"ʂ Kj?Mf-1 X0k9eR2]PeZPeZBjrEi8yybu$QaX#iE^g촦G`]c/rQDA|=U-(sDE)ȩMY؋dpP\% +!rCB(#.rW 2>TD,#Ch1+xA: E^]}T I.r⑳̺5^sT^D݆iќ<\O .ۮAXI+rTlĭ\cE1Wp@%&,e_߁ *H8vx`:!e1+8Rȷ?m<2{QwX%ka@Y%ka@Y%ka@Y&GGG7 |7:ߨK^%) (I.^yTWG'ouY.uqwWOE Jщ : >p"/߮>}oWCGGJU YN|ByaYэxQ{56q.%ɕ`Cȳ'~ZƅRʣeo-^$wV)$X?{_+<}D}~<]0D󝊋/ȒDcQ~Kd | U hH5́cZ0tyvWx+93WN#_+X ّݶK)$z@7T^Qyzz8zUPxvƃI•\2THW4n`@Y~fAe^m)Nk/4.u5q Y &D$I35AMRi~$IN q $h?jvhBb puJq&Ǎ7/\LJ߅uƁ*ڄ tcmYH2iu%M=9uz4)QaeZPeZPeZPeZPeZPeZPeZPeZPeZPeZPeZPeZPeZ ' & v^B&f3kG[J6nj WeP@w(qX3W26{ʐ#B%(j(m đ-T%YmهCՕ>"(O[%?O( kI%("l=P\^ik PYZ4i\iU=ٕ;=;P Evemmk )xG |oQȼ*_x&+uQ[eoރ-ytx( mԇ 7(XOU>}ϥIՙd5x{vB?8]|bN`$nFrq%;\D"muX|Z:-"FE\AWz6p[7hPJ4\`~QAwXGUμ:K}ZњC;:!Xx+N,m@m/TQz{L-W]uTH7RKЀ. l"Gݸ+w fQE)tv\YVgOV+ZswrBկSTt\OP&3y]6HMTxЦ.gw߃- )]թdJuCzU_(]| ]NP:6Az>pATx5'6cЁlP51iT}Mj@jН:A'P#1Ρj3{d/ΣTtXoC!i7Rf[y>D| hӆRI֍0iU=>j<%PڤX3&I/PȘ$9D@?U_^3wVT \3OUzҒGg,u:cT3q#Az UW =@OA˜ſo 'NȷLr_覵 _,* ܒμ’DPeZPeZPeZPeZPeZPeZPeZPeZPeZ4}IENDB`cutpointr/man/figures/README-unnamed-chunk-38-2.png0000644000176200001440000000615314066443524021322 0ustar liggesusersPNG  IHDR TcPLTE:f:::f:f333::::f::::::ff:f:f::MMMMMnMMMnMff:f:f:fffnMMnMnnMnnnMMMnM::f۶nMnnnȫff::ȎMې:nfȎې۶έ pHYsod 3IDATx w5N -م@h`RBʒ.17|$>9gH{iFq( z C`( 0 l>.f5'IfomI& !x':۝/^Kkb3mP^'opP C`( 0(`slTԎ=<(mξ'uFhӋ̼WzHeT=QdolοIԽIS`W.ky Evq[ͅ]l *z8lB-.Ne;[dF++ G؅qpY*s\],*#r|G@ ٤yA`^{^ MnOvd[nPӛe|d ţd*b݃ 0SpP C`(  E>XypY R@@V) '?/L k{|bdܽoY vbzl zǯۯ~sḥ/~EOtIrp @V[zr.CsP}we΂FqTw:m9dM<=U}9?&ze"]\Xs^;U՜J{m~왪F ^2=dTUyr|,LAk) $S =ea<VO9) $v<㧀2B*`eG@-'O]>\((DsohQ@OC4Ji 5U (*ħ1T OcP8Y"MR4UZ@(H}0?E! 5U (R*CH⥞~^S Kw/ kB`JU5R@0JeC!kTC6Up$OC 82>xgPGJ(wWy){$#G|J1ze/Dj0o0P)`8RpBMvB U ( * /T OmdS@H~w|U[ZmSTnkuU׬ּ5_i[W`( 0UrDo> qh6gNf$٫$y&ݜޢ7zMgi0\z:vRx9H :N4Ail"&@1P s&0P ;REġ .IENDB`cutpointr/man/figures/README-unnamed-chunk-38-3.png0000644000176200001440000000771614066443524021331 0ustar liggesusersPNG  IHDR TcPLTE:f:::f:f 333::::f::::::::ff:f:f::MMMMMnMMMnMff:f:f:fffffnMMnMnnMnnnnnnMMMnMnMn::f۶nMnnMȫf:ȎMې:ېf۶fnfȎې۶Pq pHYsodoIDATx wq8]oڬvnm$qדI=v?\ 99Ys$BP`W`"""""""j `Kuhgs-Gh6R4FHtA<'Ir=:X/ϖra}}?k.{?|-%%{7Fn~ߓG?_E[X+։X\Pl^,|mc`G៉y_/Xq!,e,g*[]gf$"C|!$>g_YT@PoYp{K[h ەjdįdT@űPo.@6`u'uD懡:y^]謊eDGSLl_@bްh_$rn;E!Wk8w{<_λGgf͕: mY2?ٛ|?*{Dl+ߙ,XٮIPӵq2y g{.( @6:,PQ{l>IьZwNf#B:AwAoIqys.Trf/|,G((w`4q[oLXf3)uFLo*29eχsL >-@ "_vٮ|14\F;CSocA7:tA0ӫSGAM " HotPR fnb08Lh&Vn9Cqu6Cqu6 Cqu6H$ *Hl>Y n0 @#| p`5Zc `wdc@MkPT_{NQNq 7:vAR͡y?Ds0g \ơ0 \X)GepDb.x0/h.x#p/z Sc =&$p` `eK n.왯E_g60J }0|Ju4XYS>`oztۣo >U`{w5m3O:z5bhB{ѣQA\8xSi- #ptF L} 9H39bp[b0ԁ`\,h$ H39 -$uN Lyc:@v&i*C+Lչ`YwymL]g'Q_;>[4Wi*C*)J$jlӘ57Ss^,}Z@l4._WХyMpwr(D0 Ԁ \&; _5h@i.xyAZjL4"e0[#ڙqLC`lZmr5t2Z4A8jsm&G:@j#4o\33&/ul\7_c$D:׍A6uԭ FϪĮqYo6:|F1 :֍ 6j:F@{5JFwioN7X;!a4 0fUu3C⫹ 0c3hl`QD*0ߖ͹-:@|>W&6Z=ۧZ@\ 퍚 PœQ 2)2+:=^=0Xn?ZntB"Kht!*|P2:L'uJ@؄N9=Vas&@%>f({@!`x;ll@t74% Fa 2Ǩ f:˨ +oΏ,%έ*rbn|\h06u䄡#ȐgyME2`7!7ʭ`~QV`4U=In @@ &qZ`䨌*)Z@%`} `JTt{<>4Vj2>Fױ>>hWF; nl `cSp1Pex5hPo*ל\Hc]λv_ i` ׌ǀ'E.+$Eit0$h ct0$<@Eu  #E'f+ HK$%NDEEE@*>GBӫç;cwziӷg|JN/_ Ybwՙ(! po]PD0;xYZl ¿6 ~6l^vȑQ)pS{ eQBgu>U@5 # kD>-/Mcx~5 ka Qj"YZ= j4`DE5.@@@@@@v( ÛpIENDB`cutpointr/man/figures/README-unnamed-chunk-36-5.png0000644000176200001440000001435314066443500021316 0ustar liggesusersPNG  IHDR TcSPLTE:f:::f:ff333::::f:::::::f:::ff:f:f::MMMMMnMMMnMff:fff:f::f:ff:ffff:fffffffffnMMnMnnMnnnnMMMnMn::::fff:ff:fې۶nMnnnMȫff::f۶ې۶۶ȎMې:۶f۶ې۶nvmfȎې۶m pHYsod>IDATxFio^[MUq@6-l -%M֎f43\HּO6g,K7ӛ,OU0vI"KYȒD $%,vV=M_;=|o~tNHg;8?˾q sBswSrɇ Y^RTMw'^/~@ͫl^ûy]q kTH}u g=5 */R 3sn.yJR K0~]6O=ynFN\^:Zx\k{x;[6A&6 ;ĵbą^hߝ^/mO3O=A_}MK@:tFۀ9=1*4A:lŧglfY^j̞G*6`? @y4Z( 2t Rey ].S'f0:t >!œ;7PV"RH@Dž!ކ䗈溡剉%+KTʼn)ڐ\@50"lꀋ>ٔ/O{N̫yhxHnnq௠5N_*KzP]'&Z`lzo`_nކ9Et@+ŒV+pGۜB-/~ 5q,UFk B#\'K-;TxjFoi7vC8ZP̢(Kkʝx{ 9軹XTUE74g_nI|c \L@~M"%b^u &?#%^r\ 1Uq*{[>̆ Lh>q8Gd8q8,upjv_p>׉Itc $%, @dI"3 &廪968#!:ĒĒĒĒĒĒZ)~}K_BĦ ^<|{wn{bS@/5}N}.yx~Unɚnܷf轐*%i(cŦY/TK+c$DBs)&4!o5`s d 2'ꁠrҝ# QYdA[-Wm `'%CP# (fְevGgkfN4s zJA)횠?Qif2Pm4iu\9LHV<gӘq"z M(=_?Ekš +1ϦdVV+gpi9ϲ@&{ @3!qp&bUш 2s  'b/hjo,&7 wZ7L:+U{=+Iܵ&3ufRS/hhb SǬbNkJѤ@*L51V<qyK֫&\F@WO6 #/@9}Xñf<b,NʛR<ߗ@n5GK(h V*7?`57W>FwyA9R"uܻek +12^'MJŦ|Iv{Z>ؾ|?Q35BuM"& O}0S9>|VBP ^Fk1yn,1!8 TdxAUQ8́^ gl[f1g}FnC ǯTy=@c8jRs0pK'L$C n)`~AFA8\l_~ːF/^B(?Zp4A= o䖲=9|vxNbIQ!qF0uKAhwNR n)K[S!ڀȉ[ x-;+X-0 fF@)?FlySn)Ԁ;ESjR+B3[SMS0=-e{2GFsn)p?g斲S;u{>6Z?bocU)qFg#a j un)PUrAv@[ $avPuaL-1/:( N P&P0Nv.L6@2]rԅU`.LF‚wn߲ S+\фuO烱2]rBJz`VcLЈPfk=;/mZQ&Ǭ&/!!rѮ(]" S @I 0Ahl(&q8 y&2uGrH|10֨Tb`wENHZp؞>"eTho}xcbfc0YlAk_ `ra6A{~w2NHo}̲ѳRaa@&5I=TX),t;ǯ]9[/"Z5A l\JW#Dx@:^¦|5ޙ6 H&aFG@POY)))ҥ[faADRYwCLP糡XxBDjA.[T,׀uFjWIT 7)vC/Y@;A5':Z 7]PfETJ,5_e5}wVC@}1Qm">'lj,`h @~n~AӂjD,{Abv q bMEQf䪅@s8Epq.b۟< 2gR.d|" 4Bv]lRЩ[J<"zr@]!ՀLq y|dХc֐3u!; O>"XԚ2: 'x$j͐`ww"tZL0ܻED`9fNnQkrU<_ w̲5vyNinN@fwH($k۾pwF57ijQB[`TZl3Atm·lhHl3bui(ah>پP'< 8h `댢P7wh)&Evq'-Lz@Y l,Qj 5<턫7AADo+r2s !5X7vqR:=Y@0= Ta [)/]7 G0JAHZ>pY)S+KM' `o" {@ @7r-CVJ{@^PZa(weB>$F+Z'ze L).}$K4e  E4]'VILS.ΐ By$tl8b&zo/,zA7I/親xI8q@%6r)fĒĒA՘n^ȒD drD $%, RCyd(O⶛g"~DG 3mcuteF .1p3=?Ŵ_  QT߰[XMmCc\N_\qWΉCѽnZh\={`{eQ$8@،4z4B/4cKYȒD $/hJeS`w aҖ\.^ i SLn3[,;edweGr>x/89rd{?XQB?̸ &9h&8CX_SVZ%#aaz %Lp7YPc_r 쏝 $F! @dI"KYȒD GbDkIENDB`cutpointr/man/figures/README-unnamed-chunk-36-3.png0000644000176200001440000001221114066443500021303 0ustar liggesusersPNG  IHDR TcPLTE:f:::f:f0333::::f::::f:ff:f:f:::<==>>>>>>>>?MMMMMnMMMnM^aacdff:fff:f:fffffffnMMnMnnMnnnnnuyz{|||||||}MMMnMnMn:::ff:ff:fې۶nMnnnMff::۶۶ȎMې:۶f۶۶n|vmwnypzq}t~vfȎې۶lE pHYsod@IDATx흍E7\kRm}kKj VkU@h/6P1m@ Aξinw۽wewn=T 8p,XcizD_xS|{]+/o\lWte@1 U5\9f J*#4\FycOѵr덿9񻾿37[W|ݪ%1d _bZnizj#6i6Pm*ߧh4@.$Q! w a:,h;R!0 %W6-I>RKV ^yX˙@σs ]H 5Qb寂oFQk @cwV'6PYxr7B, %q 8Zp{t-MťU^'  vN&{h#X{Kߠ fŻ  89p,Xc07պt}p$ǀ ziFRE$lۙkK"yE36B @6<Ҡ o *QzGVȘL0"c珮 zG~xX,}߽t ?BkCNqZv;K_5 Z0ñxz.>v"X' rd$#d9<"Nñx6RP|EN>.]6n-O/ӏ̍wd A`W mdDZX BEY&fUK TA|)o#j膴 8%#wr|DzVn(>*B++AJTo6&Е:V8M#|x'KQed@AiP!+܎v,Xc `3Ш H"$[-IĖ$bK@% DlR^l,4j:j\A@- ؒ Vt%ǮF "h|,9\tӿUa$m!:"sKB*(y*W/VX@)ڀ"P/A;YU)/z4i5(ꮄ $bK@:X4j:/ Dl H"$[-IĖ* H"$[-U@A^+FM$[-U H"$[-U[d^b GP$[2@N^+FMU?+ Dl H"$[-IĖLʠQyIĖ$bKy$[-IĖ$bK@JD-IDK<]H"Zr ʠ+.z{}}P?<_yMDܼ$wgۇGG~I"D0G%+'C#o3z@>5M~@;سCocTAi?[㦁rBGz(yWQm`K@-x˪ V#Uvo?}U{{=ntcF{(~#zF qqw'f+OD;y-]ں P/A_ %}}Z @.Q2tIiYK5H&er-mxR*{A CG *@r$bK܎JkMģ(W` HWUTZ襫Ǘ`Xm4U CQ`:@P ^ G Xknf7 }!8`r4֐polAT d]x 2aՠ3|uZ}2&@jH7T @B ( x)?0SJ Ã-E+ܱ`"8^Y\ @L"8`l}+a)")ڍ5Wyퟂwl[ ٔ *  2at^%/@MpǶ?@$P9+FMU @) >DfceШH_mK) ;-i@ @NpǶ(%Hۖ$wl[ ܱ wl[ H'DRxzj1uڨ HV *p4<f2$N'(Β-sw|r*PT DE,:"~r* cmz)p}vۘ@$͞Mۘ j퍌is@PIsޢ/5q?Q_ 3j:/KR~̨鼜w{FM@0@cȌΫ}̨-6t&U @ j[8k˨vV 5s!Pl>Ir(|x$RiҩǮќ8ossoDr7/,Wgkf!8=3?m*?[ei)5[^P*O_MD[<7Ф|J>`IjUevJK3\jN8g{Ͻ+?|w>{w{?ms_mcSnL;|gر:?Ng ܿtPͩfgs v:)"^Ђq'9;m5TP \ *ȩ_> =_8O>}/,޶С{8/,\^8yxqÅ'^\}hiz}џFta1^P$b1Ͷ(ݕӎc*TcK@tg. rg#g3bT >sWF8dOɛհ1I'xi_iU:hU>id5>  8p,Xc08* Z8\ 8p,#MZ胯x]oG9oleCG7z<]ߗ' nl(viAsbcA[qZ;|l}_iYzJIb?;ZOɆ"ףbmCj.v,[g0}!e 裪b,0kb %.w=Vp?|lOqQfG~Rwi=c!D>xHV5Pe!|l=R MFDhG ؙk09\<[ } SFcq%&!ǻ,AG鵺5W kmRH, ױ\_'~n,#%XcUIENDB`cutpointr/man/figures/README-unnamed-chunk-18-1.png0000644000176200001440000002053114066443432021311 0ustar liggesusersPNG  IHDRMR/5PLTE:f:::f:f333::::f:::::::f:::ff:f:f::MMMMMnMMMnMff:fff:f::f:fff:ffffffffnMMnMnnMnnnnnMMMnMnMn:ff:ff:fې۶nMnnnMȫfff:۶ې۶۶ȎMې:ېf۶f۶۶nfȎې۶4 . pHYsodIDATx {ݶ})9um8ʲKb'Y[9&]ڭFw@| !y^A0) XPT(-JAR"(-JARв~_Twly/{}oWڑt05hTݏj^>235n[-jP E;&(:;Y]F~//f_J(iBC'}1&Io#9 4d&?pwyÌ_m@NDaUZ % /^N|+.B<@0wVY\Wp$ǯP(=Ki2TAQ5炒#6m*F(GMJ[?}VuE _* >>lpg6~PֹEYjҚ6S@Ӌ+=~+=(5wX?~9Jz!Vʎώ3A jW byZ_O],1DE@[ &AQ~5PQJ.Z6U 2ͽ])j?R z}RKZ]6 UPà(foN/{eOuŰvo4|quIs9l^Q|J $gEYVY; T5;I%eunQ+gXV 0Sh(+3A?xUɎΆRD.¾Lo7J@vPo 4)djv7GJ@Hz1O6zK9#1GԿ]mu/,Dik[vPgr6&m5G@F9 D4ij4 h IOh ԢD@)hP ZE@)hP Z5ۇwM$Ճ :ݺΚ=r5FZfQ"-ۈא*~TdYA<#S% }H̽L7doyɋU'O[GĐK哤YiFteRrƾf)R @'{+tsx]k3J Wt2{:_NN<7%EWy(؝Z|?i_fS] E%ѕ*R澮fla{A0@zj(^VwfG?nbD^U9ߐ4}y޺eg_3/9yYVɿ"ft$Vn}=g$1TaUi!uV<{2?<<#72oq_K/(*?ˢ @VG؛GOJCreIJq{uzV*r4hm}QZ?ě;uo{jam[s_Y[DrW :LDTVcTV?2j>`EҥO*/*}/h*7Vۖ7*hLpY*3=Nx7rw!7[]6ݚ%v$}Ĝ",4dRêr澮f U] DkWMb&_Y~7ߐO>:Mۗ|s:vKl|a&_mim'P{vڶܭu@C3P_kzA 4@7.Q?xet; ZE@)hP Z5Wܩ/76PF׆چچچچچچچچچچچچچF .ۧǯ6fqG?Qxbx_^4 \EyƳIGDߒvRt}X!D؅6mL)A-۠!% 1԰ S`@=I{Ozm|`m@?W9h%뀫eiwJ@l3t:4pƵ4 .ڦqAm'kvEWOQMzgh=6JZhS9@ՈPmF6h3h6; FIN1J@C1CzUfs{*L ɦ&,Mʥ mlސX\ u0#Q0I/ei[pup4Q0iɇL-$ZgS^U.M|~Q0Qٔ ~Rք]l"'xPVxM*c| t-1YʨOԾs-ó[]cD37@KBMŸau,9e9hS95*s{m !6U}& f6jbܑ@iB@"شMS";"S،NfP^Y>jetO$*:S$lP:)ܶ_Sp?ZM"%F_iH=F@%P6:M-FE@]uS:?$pl4hzt ( hנP6 P#Ly79L@U9:+$lr&LP6-U|86dP FwmceI6|P-E_ FX%@@+9K@mlY"R  Aʁ!6/-첱Ue00P6c%  ,:,]·!NG  ,%&jNmE9ل hPT$l6I@3qd@ Df[dPc^: ʋAq8jP`pmܿdӑMv yT$hhˀ-;I".hZt-%&`(i@e)A@U\d@U (MNl>]?~-~y:??,AG8 aMyhc~y___l9גK)Q&U{`-Q**Pj)/jKYb q""7 QZ-AߤDE;wC\\f&"F4-6V۠/[g BdoSMægO^|Zb 3e.;JPiivh6* Ѭ^_t}<Ѕ l @;.z!<ԅ^л*H@Wn3w@WR-B}<p!6jRzsx$~l<ae(TKP76MP'.J"R_ 4o4%CJ8QJ@hDk9C@ 8Qj@ ;`7.X/ il'j⼬ʫ^r2.~I@ f*ޅRAQBha&10ӕl- N5p mW*M6mR_*>qP!{BdhZk'J h㠩h-4D5] &C@[ EjC(TLKP'6:EGjA(T l:-4"joBo_D |]&KBD@ԘP4-xw|o[B P6WF Q;w1$*M6=7v,AM;`.fBIצopK#p"{ &ԍMzCCIӦ7}RzV|I*'Tv(Tl@r5_&-'JɁ h614d@uR(v?Z!?4WX6J@M;Q\Bn 8Q݀ew2[%T@(j8k*M6zN Pݕ&E@JSJ h*($-4DSKI'V40 |h!"*M[tiAe5 |BҴP@vP+>t!Ҍuac'3ytiPiڱ9QEF bZCnc\.:JS&Ek)n\J]Bi.A6 PZ7Q|.Ck &Et .fm 9Qfta R]Bj3OD;Pi"KTM(T*6Fi$ۅNnC@;{T 5QFۧǯWʆݹPi*lP~qCű!x@w J"BY}m^{46LT hM/Iվ^W6@4]!ơ?4'a|83Q|EvCnUghn%ԋ{w󉘨C/&gڠ;R@iU|'Y]\hs;4I|&4}.>_f9exI3tM3#vBI8/Q.VU%~Aw\ ګ[T t м6GJ5W4P*tE@-T)ODq\FPx6UTHiZ, _T!H@IZ )Z$+@@EH";I\tWŒ8iZ.\T#ȍPx*I%UBQZ{䃀J /Cs4Xx4ǎ h*(@EA RHj͘6*@S4oh&73w`,@w#6DХ oH6T_iW-л#vv2Ήsx5[wS`_@/9ayWԿ P14%hSa_NױФG{|P;YFZk%&.l (nhH>;strN2۠GѴi[P3P6L.5w/ $;)3*[Xj)EOf~P9YxZm, pqU4B?@9fN$^d f3CvҦK6vxO՛d@Of' %Yf @[N$A}JPiNR¦_6*@#vl<)5 |0vZl'V^}m-ڡeq'銀ڷA^|="6Z=g|:3e{xNMfdiABTQ#;]TTN˘EacE(մ!mIјA0pQ8${A0p!mWxs'&.nrtiF@5m;U+ (k@z!mMx`Y;0l[]bm :PMF߆+BcG3{FwX9L@\tlt#6Խ.a e^1bʁ:M߻{NCQR(O hz 'Nmzмawtޕ]43!toӧmH6F&6= ߆eBhVCe F7^ F*6V Fhjбl\Uދײ!@F Tf6ԏ !~l d1Ae ͭxD] mZ9$6tT6#A!ڨ نkC@P@P@P@P@msنn>Be &R|d: `C@imC@imC@imC@imC@,W 56ԋ΋نi 56ԏ !!!!!!oJmv[fl~@o?(+7Pڌm/ $jE9T;oUb_Uq5#z3tz ٱ|Et\\ @`ڡtWK{xa& LFU(Y#/ԗ9P * *MJ-6(`Ype[ 5IE@)hP ZE@)hPǺhﴲow>*w'Q=G[{€E@]RfNVqOlO|%hKm=/~z$:%nD@*ZF fU<ur w* UU')T"uI#H|tlXaU\fJ']ԃXۋz j/JAR"(-JAR"$Ü'm[IENDB`cutpointr/man/figures/README-unnamed-chunk-19-1.png0000644000176200001440000002302114066443432021307 0ustar liggesusersPNG  IHDRMR/8PLTE:f:::f:f333::::f:::::::f:::ff:f:f::MMMMMnMMMnMff:fff:f::f:fff:ffffffffnMMnMnnMnnnnMMMnMn:::ff:ff:fې۶nMnnMȫfff:۶ې۶۶ȎMې:ېf۶f۶۶nvmfȎې۶E pHYsod IDATx {ݶu)7QdN2ۚEkvvklkfz17@<J$@@QHUD2%JB-Z( Pj$"@I şq$e×ױJTޞ#=E"_@sz 1"']2HQ wk.9jx:$#@?xş(U෼X|1EqӚH\V&:mqo(wo[̲2u2H o= j+sX<>^]tB{X2|9u鶽K>{Mr{(%iZJ:EJ o@jWz*? *Sj].j/yۓ_Xq꿦 ./үU(KeJj"%7ۓS~e^JnՁ! :w~NQ]Uu] ]~PNv*w#ϠA*$-Cnif.\lU=m[=\7~ -J3CtդoRl[@{ɜ"ŗ?U(;tQ7㉉?T=H@u ]RUuq8WdՂ>ϕ M/nŇ]^\vGa1(R\Mt{WM'e-JS7I7;1*~t]l^Qy֪* $UiK4mjI :(L@Y_ŚfZ@]Tx7,D`%]Iѐ Ո\W|6`IZt߀YEJ Vi'wظ(I˲iFvX:, Լ]<] |`b-,KנHLbQneQNGZ=Z< QfV="@%-M( Pj$"@IEP%JB-?@wLcoϙC5ЫVW;8;Tjj@~!Mg6hOF>挵]rm2X{9W'RO@5(kxE4Ay3VZ4| @{f5|Ѱz铮ϕMoF}ZM;>T Ι&hY`7ϻ=@N[?h/l;nW:-݆5.$;mw=Hj[7xVdjs&}@CT6^nܦ]۶ ?/Wz(h 8sv{f/R$k68gT1$Y{)@ [.T%BEۑP%JB-Z( PjzScE>1ԋE>1ԋE>1ԋE>1ԋE>1ԋE>1ԋE>1ԋE>1ԋE>1ԋE>1ԋE>1ԋE>1ԋE>1ԋE>1ԋE>1ԋE>1ԋE>1 M[oO:$%P/P/gЉ. P! ޞwHK(Y^(Y^(Y^IB>1ԋE>1ԋE>1 tK*ax{T-}Vc}Vc}Vcˑ/ţqUEqU :%0=*ScE>1ԋE>1ԋE>1 )%0=*d"ʞ2dMeO H'@0"x{ !q,hg>0zhg>0zhg>0z:'@LY$@B, P!S D[oO;$%P/P/PT1h{TȘE4=*d"ƞp)|ıDqUEqUEqUP^ҒJޞ2gMbO H&'@FKJޞp)|ıDqUEqU fC&'@1o6-IJaO )c&@Bʘ д:h IJޞEM.j4=*MhO iHɦ'@YlNR{THE4}s|eyG-m tKʷϟIYDJ~i2U}Bh8_"UyػHK Л~U 'hMfTTe2dLeD@˯9>N%-hӨ}?hzu%@/PLYJޞ2e6JdO H&?'crʔE4=*d"Q~^VV,TsA-d"~˜M_[oO:$Uz{R?Ūzpy5VXNc?@ l5O_'G9k4E4-wŪxrj$%0H X7ht%ʿ<"~^;ȏi,H 65Ğ"-}\_~@x4}0 I%R8Fo|!@9h\{ lAώJ>ӨoW1ۏm5BdzH 7D7T~@ZsT. P^m.W6?h|{yG㧻`@oAJ8'e> 5$@vct2 CmHF4CTH@ RYwcG`!XT*(Ao}ր`<@Ψ5~hzR(5h4!XTE~=<'H@Ǿf3,*P"K}^c"~# -!_ek6udz]e.,7I{<@֨&>jD~ޟYwߵqRUZY$@C$91 (Hl8D%Hྗ8fՂkoQ d߿ӆq_&q@=O]?ӎkQ nu i{i7${<(x'ɑP,ſq_aA PO{UU96$B gW8z'ghW-o̽aް?r":m^!s&g\s}8"O;?;iH57,)h zqTnr"ҧ(tWd_C@VLRc{z,U7@NsWTW',=]G~X yQ_)Pcs6",=ގ.h@EKts!ZT%B5G_{b=)||{r/8q .Fhi× (6pU/DYudϗiZe1Rw?yoh o31Ejq0.W:Y|`i?گ7#.ShTOR hiǵP!lrKWZo[-kkj`q"@ǵ+|5Ċ9Vݟwm'I$$Y).Pkz$flXltPt/!GCO;&@Gb@cInY&t MWn.5h9IP.`1/4?w@M;nom7:?rFG340:f|1ybW-@E T1PiCZ=@fbGY,.PiCЋ{ ZI'SZU SF#E  sT(Vq숽vr[h({tU^|CnCw=?ְa+,e ЪBZ:_@71Gi0Ͼ(-&~r@CqЛݧO^w~r-t~ zqV ؑ 8g_7WeoU _ؽmqK*_s@o_?Eymf@uϠ}$q `Eo>y-}TޭoL?h7u )^Bړ8Nfќp%͵:jP `Hr8ݧOҰ%@?d(5(jN9}|Q ECb@7tJ/~ɀ}i13qЅj'uSd9Y4ƌh9IaQ=(&Nh$-P.@;qY=8-0;q-H L/PkgqEA'@ܳP@怶ބYݮu_uw p P!,|] .|cbb7kQ:n/|C$LM/ivmn.|Sb@M<۫i:n-|c@u9Z&90X hd,y꼹6Gk]I~PZ  ,Ps j=X&dq9 P3d㄀\= U *#z5\2S㉧:6Xh%m(l46 hP>oP/%X|z'|) 8x?@?@-KvjiY v|?*4-ԏO$[&V*$w;jހz9?@(b :ލ|:q,4^Jx·OKL'Rb:_GuX) Yx,fm$_FTWY!@C j-|Y1ԋUNe63cM$ 4 &]CTNY衖gg ꃨyY?ME7=uu;m7[@7= .5cfqf6Y)/tyLRqsz%@*n%$CT2@UfY"YiEЉR6r >J$qa KO9mE&@UZ{Uh~UPo9P>WEqj7ڨŸ`=}z1ygqc-ğ[S9򋧡_?> }%4*ho9ɼŸfɾ$&>>IUhV%iVOPI+^dY?>J9t33"C/Jx>cWyB|59ۇ#r1핬| H'@Ux,UM!XT*amc~` bE/fB3)ym{K['L:}@2۰FmCcW} PfJIkPU3ܸ71 еE4{T%/Zy7v"y%ڇRl? ^#aCT~4.͵yzcެ΢6۸ÇS>g):X> <9m P)-inz29TmMh?)O@mVF>}0 R4>jȢ/7DoaU*m 펀6P.i{CcW&"4y^PU`,aM1>C $Lua"vGvϟS> } &~n  b?@7w 9'BLBs&@㠶s PxQmn߸'@U&i u D_urI{$h%YYİ@=!@(CM9 X>a]wiP( ďj\h`%@aA^%,z@PN_W'} @(T/ދPz'@/'ZY!41!FT%o|YM=M8@d[U}դGs*k=#kh'zL=h໕쮽^l̆#i3IQ@-GSYDH6#@UuO) X%@U3iΒо}ih'@U4ӎnP{` J2K_9,"_$@R,@U>L:$(Մ ;R8j: tkL Pı?N螽rv%"@RaѯmMCXڋ#tގD]A'cWa& j!螴cWqPsނPۑvfkt(iہaX=Po$P'mIگKt=73NĞ>'TҺ:q,ETKf΅+>:ocfnL\30F5ҰG/<@JaXJ(mBY,xI{t5-&X*5.xP-g>:_ #9iwTr{JQ^ZShޕ:E:{Sצ7B*L>)aGb2; ;my$@ՊӦgt q%}B{WAVPa$tnld%}7Y 2>6dԞd P*ѡf=H:YYne8^ 9CRګD5# FdžF%r^Uۼ,nw#.G{y({` 뻌6N+ ⋠ ık:`*(){8{}Xīi׺2{CX(D'|ԁGNR@b"P`mߜ t >a"#T(-9gkn])x;6f-T(-(t Uj5)jsIDATU(4&Z( Pj$Ԃ'7?z?*>}Y=I|'B л_pHR*uyY<p֠7k&#0@Y|qJ7)iV5hB_u_P0YD,@%g4zGѺ*!B" D,Y @d!B""fu$+MZk7ml#lODȳrMdfQ!&E`!̌L{Ig [뱉X$} .xfOc%T)Wx'IP8]C,mJO(q+%9&$]^aD/P90uLw#ؔlNvԥ`pǀ0*N*'Km\~ =4k<3ж$ufX,{SDT"oXZvX?+ft_(=dUY:$oT(mm;M3 { zUOZ-*^&l^W|-wݍdQ.YViC~*UKg0mDV?"읨%;S8'ʒR`0~G ^iX. o\t!h{* ,MG.W s+)#AVZ.j:a[aS.s:<::a~āh¶wN+;aBqpѳj4:aJU6iD.v>a(Xu6ŶV u-.(ݝGȃvX-P+O#7@^7(/g,jjǗ>&~Xdh++LZ؞Hp|ba(%> ơnR`iy7se> !n> <&ɢU@6}h5@n 52 ҊNA*2ܹuΝ"-afU?G^yT6% k4DkFX!afVkFX!afVkFX!aUgd3pg\VyKTDfVkFX!afVkFX!afVkFX!afVkFXëxsCϾ#\@8Ǘ!Ȕ<,pq}U5@-@*j ~G T\u!~:jBX 菟{3}=^ wylZK$I:/Y5nCo${jCXa 07䖠p[ɴb9L& 8M:WGW IL厂``j$mohvХѴN]3ĜG3# wo-'9};l7w@M8p)0dwHv{a}@%*g.<0}U ˆ[dԙ\TB^3L ӝt;3 Le:a@hKg#Lp- C"sB^3k1;[k)I"I SLafIa 0%Bͺ,@rBUupVƕV*"F^3 v+N-W- TgP);ܪCń@Fm!Wu--IFYyWθ|/sB yi. A7w&%oa]\p}gik?m0'd,nua Dt]EYrtB}Q_$wh4{y@_tNl0r}c3H¸RYE[CJPwQm]ӵ7y:4Fq #OL`۹ PlpP:,䮈V(*hpJhh'jXHdT@Iy-!J XC[nCfںXx:4&>TBBk 9E[ƃBՌ'XQjʖ0%ahQyI k3V- jnFV<3!ߌЊg5@Qʵ& f-/ E όk(ZKXc7h-q&uΝC.E  A%fBkvR~A@JJQPSI׎ ~L%];P׭oߺe\9kjr+ᕪ%RTZy-Z@*~L%-P(!R#@䏩|&@a!afV'̻rg`P׌B^3 x+5#׌B^3ª3C}_T(n\vim4Z8ԡ}S?pan*$[>+`F`Y!J T!D i'('5 >.A%( k`^8a{A<9O~,YG{ 8g{Vf^C^&dιP|k̸o-q둞3b<96#{M3bgƑ5T]u"3ª\ uH]u3H]uy TMJV\Y<U@d!B" D,Y :DׯYr6+;z`k쪫VyYb&ߵ>YZvfFr!rlάfFr#rǗpƁb5Dr%_t|\x!|b[,^`k+W:ggxUW0}#|>x)iAZ EQ8bՕkQk8;>Ȉ4+nÏe9!bՕ+ygG0vwFƮjpd!B" DZP/5={-W5NoP dh~0IhnBߊdڣjO-!ARѕKl"MIpE0<PO7=pUA!O{{x>Jk+a;*(WFql&C5?ITg,V,Ve(V PgRn$C1TK2bGHHʣjvUpHdp }b&CRGir#@dcd]I`:`/Iɍ쐖Ҫ5d#˪Q3\aЮH&Ij-@fׂV*C!!B D,Y @d!?giIENDB`cutpointr/man/figures/README-unnamed-chunk-36-6.png0000644000176200001440000001067014066443500021315 0ustar liggesusersPNG  IHDR TcPLTE:f:::f:f333::::f::::f:f:f:MMMMMnMMMnMff:fff:fffffffffnMMnMnnMnnnMMMnM:::f::fې۶nMnnnȫff:f۶ȎMې:ېf۶f۶ېnvmfȎې۶E pHYsodPIDATx ۶W4ޢwOIݏ7F# 1l<{W̍yvDq] z׿hmofNvi<7#Z|aP@==j\>oǰm8ۙ{ &:7=΂8 rEkem u`ͺ,ȧ BQ/fkI8fP>{P}W 8 Rϫ]Oʢ?7|W m8\A1 ˩ULP<[1jLýǓ+YDv5T[#jX(.hϓ+YcP>@%y}ϓ+YL~hp\>Od[Bx3rơ-=;!ϓ+YqȰo'W`}ɕ>4͵P'W"|yr%+&ożyr%+vyr%G a:ϓ+Yq Wϓ+Y=ȧ~Z+<]>OdWϓ+YӏJV?n'~.'W0,P'WG.'W+{y|\@fT ?O3 hϓ+Y0=)yr%@=IoS^㮫 @uy Xٓ֊ TE:֊ 5,MAwI%tSU@_[-`^+k@Bƀg@ 泠|yf/P `O\~i[DH z"}^~"dQW DnQ:J>Od J>Od@kwɕ,}\ɕ,}\4tϓ+YuwgW* ek+oh/UTlЏR]ݥRsk@FE O˭g{׍/U@`DwE@hvZdf>R>^Ae\Pl2-lg7D? $7IBd6ה; .K Ezk0G @=O Nj =~t=Wŭɳ'HG=#H/k2BGPl]о%l @H֙ [a|? AB8^Fw gW/>0!Z8 }j$4V@p j1[އhOu \r `a@e@?0|AȪVty+jF$gY.hͪV@9: -ND!`6$^]R0oj{.η"@ q^|+` 3|{E8?-$o`|"V0\÷5+['$_(0/0zA@#4o>J'M$*5ߤSkE {bDJeSp[SLM*? @ZY(0zAIAG5!Aw?}|<OR)Cw@[΅(n (N1@h(qX6mbPrYC+:85Hi+-Zv3PX|@Kq] iyr%K`'Wyr%K`'WA>Od J>Od J>Od,WWV~՚Ln jPNz٪5Fn /W0<{bV1w[}gVIr5S V"TVu"̪5R!-Gn ,(~ςӘͪ5|@Kt#~ͪ5-%Wɕ,}\ɕ,}\ɕ,}\ɕ,}\ɕ,}\ɕ,}\ɕ,}\ɕ,}\ɕ,}\Z/HJ>Od J>Od J>Od J>Od J>Od J>Od J>Od J>Od J>Od J>OddF"^W|@K׊0JG$諥{QY/V} sPb9b\~ρcuh8?8.{Qp\~qE_/?8.߼k1q<%ϓ+Y<%ϓ+Y\ߐyQghWM]y6 v@R @d  Ƅ|MAK+lu0cSL y Կ}]/2Oy/2yʛ''<+N^@Ş/257CGr /aƄ|bE&OyS0`mm{Q`E&o`_䃩w8~ "|V0` xx z h1)oE&OyS}4l?1\fLx[ɷ}S}GҰ }\ G,Y @d Ȋ ëVJ\W٧/{ulK٘eP-lW7ms-Sn4 L߁VJM֓+Q ˁQf] Bߣ_/hJ Ḟ-+/[@Nz1H 9*К 2@sh=h@937^zdvAכJYgZ4>٥ q+:h4͌9(9*K#~/ŵtL3Ԉ@d %"KDSV ÍIENDB`cutpointr/man/figures/README-unnamed-chunk-39-1.png0000644000176200001440000000547614066443560021331 0ustar liggesusersPNG  IHDR Tc2PLTE:f:f?b?b?b333444666::::f:>>>????b????BBBDDDIIIKKKMMMMMnMMMnM```bb?bbb?bdddff:ffnMMnMnnMnnnnn???bَMMMnMn:fb٫nMnnnMȫf?ȎMȎnٟbٽٟٽې:nfȎې pHYsod IDATx _Eŗ *5ŢRm@苵 R((4 ^ Wf3{{<ϯ%4<3vK6RUM.P( e"e@Y,P(d~_wn\F%6oߛOp_K/fD^5ֹM}|i0\z~>Χ 7l~=o.z 55:`᫻[gmBM kgF nDkA=ѽۄ&:t9'ۼq;eUV^4*?_|׉̕/?&԰6|i ; &>F>4*@9V( #^UZEX+UZEX+UZ)zh9+h9+h9+h9+h9+h9*˝0XѤ05gEY5gEY5gEY5gEY@GpNV0VVZ҉:Y`CZP(G8 *h9+h9+h9+h9+h9+h9+h9+h9h6pxo!ٹ % =  yZb 3..*VpGYz 07{Ī <5/V%P l= )VĪ }XѤ Zh@M-)V6J ¦X Vh.Oo%m>hSSr2/85E '5Z F+Sy)J9y)J9y)J9S5] `}!wڴO4|SfM̦DC3YJО{ҝ--3p)V3`L-誹=I*FG뾡5@@k6n]k@g@QTL<KGWǺC^Iw@o-%{vTLMTf&Zs'FDe՚_\%νj PZOQ"\^mX#Z= 58 -V &U=p}C>ZIM1RWmG1 X+mQ3#jPh6S>4̮4&&y  0' LAyl\BQqV4y)J9y)J9Z%mA hHvߞn bN6 4:#!jLMM5Zھǝ vM/g{t54PBUgts_'}hiBTB0tz 'SɅ{#K,/!.G#v6kǺp:B/d/G:G e@Y,P( eF6IENDB`cutpointr/man/figures/README-unnamed-chunk-11-1.png0000644000176200001440000003075714066443404021314 0ustar liggesusersPNG  IHDRMR/PLTE:f:::f:f?b?b333::::f:::::::f:::ff:f:f::????b??????b?MMMMMnMMMnMYYYbb?bbb?bbbbff:f:f:ffffffffffnMMnMnnMnnnnnnuuu???bbَMMMnMnMn:ff:ff:fې۶bb?٫nMnnnMȫff::f۶ې۶۶?ȎMٟbٽٟٽې:ېf۶f۶ې۶nfȎې۶ pHYsod IDATx흉u8̬-c7I6^۠d1s넑%ub6C9ڤ8x>_Y~3]ǫߩr*aeCBJZ(*i!JZ(*ilEt*xey|Ze\>x?e/OkXI:B%͘Ϟ^f/F Y}u-~of ;k/V;UP6B?^!Í~iks&sX8:KQoHcEWٹ21fT&9/3q8NtTڏ5nw7S]@y+o-dO %cK_+lev7KK9ɦt^ W2:3$W|dAHo/9{}X8>xȃsS^Y-iU],kc<3zI6qX$xq^ 37I?F}PQ5w];X8>k:7 [Ք3@DfN .櫏j@ݒ (K?X};&%nm?jA3szkP.BhVW pJ{{g!]P}t?Qh _J]ji/,?6%<_c8E߷c& |'7Pne:[ &ƴH@vV%9ֆ _T_t-%@_^{w|yG 07/2w<?~[=X '5P/$0֯~ͥ퉏/FA]Wʷ(T !JZ8PTB@QI E%-PTB@ǭ\P@eY[IK͠Jkc6yF21|* (Ph*3Qy'Z1z"hiTiX@&t0]!C:aNb[2SܶVQRyG73,EMOt'x6+`i,vٹIuf"\#?V~I'{}~ ajVbmAW d)?t.N++=v%.*9WT2-F.OUvky4%t&J"2q/y?|=Pf(kWbA8 [ΪU$q6ɇ/]pP#ş~#6?~}#=PfO)~^U,tBҗ_i2Oi +;0+@@k(ϱ]f˃sZ!hb}_ȗD͚͒cY4ga# m$=Kԁa?=֕\xd Ԭk֕\x Kd{|hE4]5g&=0N;G@ Yjگ<Є9HְڲvU)iiC{0JJOY\ FjXmL`'_7kQ-X&AՖYU?lK!>{ Ԭh‚}GwQ4,]sae<37}]0'Af(Fl %!ۦ.P+?-m=@͜({T{HT+(i%[PmVTY{/9 nIP"cA3׀*h#OQ0mA@ pyT9t  7 .R/{A'6@W)3=f(kPap-nXW*؂nA@EO:DOUn7miMgB@ mK5}kPo PNw`D#. \#.; l |#oۂZn+t\ĝМg-{eRXW@r2qg"#]<jeX@Be⾢JÇtiրHm2(r)s3Ԡ=5t@Ah̯K-8(!Y42Y*nӜfjŰ$s䣈^DґQZnX+ҀѦ x.sF@AE1PI]wkx(0]z/)I> @gKwqP!4=@Y剀rat80^>@/Iһ4=Yt |"tL DP'unJN;ꐻLiZ3r&"V_'P[X\P[--( Ԭ(qfD@Ў5+`Z|A@JuE@E@;Ԭh67hA<8Z{6!B@Ë"9('R҆a){#r)RҮa wlB4aA n*RҮa  lB4T ԬP@^f3T k]jX@z՜ے]?Ḭ"mɮ8pՠIֺCMPgWlWo־CB{[7JJ*--Cj]D\^IŰa=@jzk{=sf:׽@Rh(U \bJs5!JZ(*i53Ftd<$O)7ES?{bR aR q6zKbP{-#9`#4×pаVUH-2"ᔨ) gmR@yex8$S9c4UUL+ڏ//g)vWJaP5Vbo% @i֪*2 ]ʔ])P{pQ'6wK%DEab1H10~|y18[{u+glR5 #]?q,֪kPm`+RAUJ^$TV/<]]+(ny֪"">zP}tG-uNԞ+l+X? $NA @@@l8%ѰRʭǦ(u6j=%;yMS<|5a*,_$S_p'ٷ5lS$TB@QI E%-PTB@QIk܀? #eO,8zwmL<{}B@硃2syvCNwv9:ʳ=ǁe#!m$sseN@^⾤:~aQN y!ljы4_?ϲr=[(ߚ~ٹC>BJ=,+kYEܹFp'{P4G l] eX hcujdvUkvjJ:Uxs1;G.\p6=c4_ atgcPbtUKR@ =QO-=}-ҶY%jՠЈ{;N]ȚC&4d_5QW/;[_OEJ}r4lh$Byd$#zj(Y> =зyw8} >|ꃮD 3Q ՠ8kVj]5G@Q]6Z=^7dJZ(*i!JZ(*i!JZ(*i!JZ(*i!UP|3]Ύ %^>ލV։z:2go>t-DEj/©geLwtj}36&>-Vٹ>E~b^f/z0z5 513IgkW~zi,Z]O/+vЋ05n_}sς_r&_vt'[<>~oS("L cwµ/}<4sBlK5xU>GBBR9]\ɶEΘkuXMu S}@Wv-i>w띹6,"LM4NLIW^{nB/Ԥ7;fw}1Ek0ǤaajpD$ f3$ӝQf!"L-AbVNo:c7{E4{"W3,^iL{jyxEtj^JZ(*i!JZ(*it}|>31cxryQf+ʯ@Tg.CS2锨nCI?'<9W[Re)16XJZ2pn:hNwg v߭Ϳ3m)ǯΙOGD s.8Qe"<rKx΍[`=RFrnNQ%gK<uy!eUzE3@wU’\XHϳ0?=/Ś<1 sP)[0 FYF2W\3]SrPYr8_y!+]Z꘸0ݻJǹyAeTPHJq35VM@N)\_&Z"b(kn6x;+&-APKsKS?$(Ϛ-1 FrY̊ЀKʒKs+;}!+:Df9;F: _]l'PYr PJɼ^QHl6HT @ٚEݤcg8m:ͮZՠ&~HTOFzS-8TrX6=V WiMB$17/qqC+ДnDTݴ:X*@e+7MMvsit^pT8TܾI"Ihpz+j6̴ 2˾ƾ5e )e_ËaЖG@ۍ=nv# -gm9h?@B@[ʾ HPD)w]`}L,˟"q'TY`4wCc/kˉ"MS2heWDtf<$P^2넁Ih!hVF@뇌ɝA+)נvk25@Ox|R <'B}MugT5B@>:PKh}Z˸q)߉-vhhГ??@@CA'hsz$|8 nRiP^N{׿kヌV'j'M|L6a(,;aR1aA':4<;L nGJBz4b <m̽o@q]3 ŻJ@'ۯ B ݃} ׵ r싀N ZI(Z/BeJMsg<$6LېwP.+IDATtm@n:U"" q! zt@@ʠՎ;2% YHMޞ7/"@ډ|f$b^[j]^u5"@a c. WcAx L- mU-f:;1:ϓ$kP㳎LVdhN_/̅3hPϲ-4>[ZR4;ܥԿpju נ^w'*i 4QV MPßu 4r8^7@ nD 3pzIӝPӎ:<g(͒D@}Ai(@+fhhD;f-i5Lju-)PNCv-e7i.+!BS4PNQ) @ae7dbRMPuCTIA h?C9 hQ3kՠrv_  5OP[ӇSSmV4ML̻m#U+ ,Im/?(LmW 4q@mZ  ظ#jЃE:wR"r74nV|;OC/zCyiJg{ c`ԞSܰ֠%& gb YVP]"ޠn@m h6@a>( В?wu_]a{csβ'T7{.*Bπd5hȟz4ڡ3hMc)4PN)FqZ4_a01u?!o 49@,*q >hI h؋Yđ[2c4]gYG/l.*ZPNfc.)JtXmŸt,j<l` =8r\UmV6oQpPhz4!r v>WMbs* Q3J@ iGGX"}0h؋JhDѱ9}4<<yȱ =W@Ӝ oLwyeA]44PcGũ X" #vzg28'jW/!huu踿RTo[Kz1Q$F[SuS߀w_v7Cע0@c gA'F}f u#D ;yxՀ#A!T 2%SToMmin鱺Pe_4b~loz}cWETT=O@#׿ P` q062>Lv5h~LPb`XuhquBA@LM`-%śup@|lhр{T/" s4sxI,tx B[4(,d`]#"t(dA܀TYD' ڟc0@ ] RJ*BWV/&ӯd)هA S""f Y? QE0r\#BӬ|rJπfI)]m ,ݮ:Jw}*2{Z : m/8(M;Pr[k!ك+=S@ޱ:xk;ؐ2^-yv7r%[  <ЧFcq te2: в}_…+zE{#FXv*BEpu\DLQQ8%To`^%4R.{kj@]5h Ph{4 @|r{ӻE >5#vWg7T/_~ ⟋xz7>J^q7?/]LDB\p#]qҵ w/fUx^]&' s!HBdap6F4իywIvK7.] \zӋW}]ՀV@\C@VZ"Pc p8(U?:H3Ep{Ld|v/n޼RG\+7ɧݼv{kWݼN@.ܤ޼IG`&BN^/zJb\'\yv1ɜϮ]r Ě+.]/^]!_D7@MsDH6:BYM-QZ/GA(*i!JZ5ҒNnoo?m9NAnWڟe'"/1 @s]q&9#4N|8X.VO*"(8mymIX0"6+uJ3Z&W3@i3 VW,@=Q?)}R~;Q[~Wɺc] #`aE{ (W81@;83DKQc:bxXuZKE~+@O#ehd_qj܋_PI E%-PTB@QI E%}~~8 8jC\ *\s܅!ieقa|̲-RWbȟ]rd[!*>9~f8p;sɮA_@)vRbIxL%پf.!@!{%_hWOw3ɫWUr2 kZe_**Wox/%f82̯ӾtMI0IڨwɇOTubʃd*ִt1Ԁ*bN!)l3H<'[f/%@i!1N5i6$jsãFr7V!;Њ>-q >g,Ant#tgc@ e:dkTZ~qw&FPƾ\leYoT7*[[a;L/%f:1/'%k8yM|&I؀ tQNw>IRo_*7V8'2u yN;W7LBI,hYEF }u]vёϣ<,rw *Qlx!DjߦPÖbxJlj(ʡtNYwB# q"4 (JZ(*i!JZ(*i ZDAIENDB`cutpointr/man/figures/README-unnamed-chunk-15-1.png0000644000176200001440000002037714066443431021315 0ustar liggesusersPNG  IHDRMR/5PLTE:f:::f:f333::::f:::::::f:::ff:f:f::MMMMMnMMMnMff:fff:f::f:fff:ffffffffnMMnMnnMnnnnMMMnMn:::ff:ff:fې۶nMnnMȫf:۶ې۶۶ȎMې:ېf۶f۶۶nvmfȎې۶& pHYsodpIDATx ܶur<4Iwyڕj6nUZo$]k.Ѹ{O(ˀ!@<}{+0&: (` 5@P X(w~^y`WW}1F83'U3@\͎.?lYG h{R53O UУoW^^TjD8A-APF J?q)7fw~W5˲uj2ETIQogV.T>Ar9_hwu`)SVߛw(>4%Ⱥ_[[5N Y<7BbC_pt2{OborW]g%}Tee~5n%nvn>,[MfI8 b_.brQ H?iơbKV僫+~\ve۳/^*[Mn-DEEվHXuVRmۢH DY+aJCJk_n ].owqgUbbmw?4R,R 'X5OpTlg7BjK[m+A+]fyBk9{_mdҦϐ-6fI *\6.Mw?xsőIV[KHI ]PqTjj>/pjUB=꣤Jj>_vr`#eR ,#u yuL]$mvӊTXCbs^N,ZGEQ܊Nʃ͟2"j I *Dܾ*0cz7'1ZjŠ5^?UkFpZNݢ66Τ*E\L40@FZ 2f3-f?IALn=ϫ)z܎h_{*w)'_WLnEXNWXD}#h֌Iw6F*l~INo>N-{ v!tHLHí tHLP07 (` 5@P X&ٻ6A7A-uGqol)OE./8[կ'yɶl}ey0N\o}L{YQ/rr\qtY8\Sy\ݞ꫆ŇYb.Dd|fRrm&)AWr}T/-v/6Օh2Fݼ,`_Gh_v+/겉ևMK!Ë=ۻ7 * fhAkn2qE=A[gW7 Z=H.D#pp#|쏠&oӺAqZ=Aw`ZJn=DW h)~!ºd3ܛmh >\eؽ Jz XAkp` 5@P7A_zߔHߢq( (JXC5MIOʦ'P e}Rk>5TAtTlO*}b @P6'>j (JXC5MIOʦ'P e}Rk>5TAtTlO*}b P ^~EԢq(]:5LA%9CиTқ3A%Ic4j<(0}<1JTYCЈTFU4b<!D5A%!hx*Q_CPD/J%BxT,Ƌe4^<5`M80{0>5TC}(C紆!D]"A%!hx*QACPD-J%BhT)qsZT)ƊM4V<hJ!DS"A%!hx*єAcCPi CPD)Jt%BHT+F]4R<J!DW"A% m4N<hKq!D["A%!hx*іACPD'J%::5LA%!hx*їACPD%J%B(T/F}4J< j0}< AcCP@4F< AcCP@4F< AcCP@4F< h0}< A#CPP4B< A#CPP4B< A#CP`ni N7?|w>~{,7<_}R3X" ?7Aw_~_?uu3tNk>~nϞTGOl!h <=-AA!h aD<JK!dD<JK!ĠDC紆!ĠD:J J!ĠD:J J!ĠD:J J!ĤDC紆!ĤD8JLJ!ĤD8JLJ!ĤD8JLJ!ĨD{C紆!ĨD6JJa!ĨD6JJa!ĨD6<|[7tj^:;A Me 󌟾g+yp5eAРF놑ʦ{Ls:kX F}E4h.\1hwQ.=#f%BРp7b?8HbӽMXC5A!,5Pk8oBN OGE~z1eٔlOGP]q}Q< :D Jv&ѽG%??] %BpޛtAl_b0ʰD,~iݽ7!9Aŗjs A؉{b t-<2-o 3Z!LK^[ J}6 A%%BP_=GDD M}pĦ{xt5ŸD;C! N*1.Rg I.gcMS;jo#(QA駙 (ITb\"o|c-NQxP 9jy59 z#ny-c*1/:ĻA%%BPxK7 ļDj>\u>7*(D ^96އ@P ;SJ߇@P׃gJptiO)}b F@xRܣ{aETqQJ{P/(JePtGЕaMDP' ɩ6%B}TwJL$ۇBgIji&zGT/AIネ~ h9Q,}e;v磟=>i}?/fx@P[ >rnڹ|׹ݞ=.lO6.Lh5=@~ݸ_GW-Q{<CpٱuѺe({ou-_7_ĦB*!hfkp&vkM|U:?R hͷBƽ"ΉA I8$FIXALZGtGT3HB=1e-h^O34 xO(:;Ag{P{xK7QU7 !W?Vc;B񙹠 dACv&اn )uְ+6@Pk_"i $ctk`~q/'+ eTyy5%~ @б'v^cQq3T<<CcY"58иT55z:ߋx[ٖA< 5.w @P: }|iԞⲏ'_fɦM|*>3ӧy~W?AtG1^Xd~pQ^L#hϿoϞ/oV?ۏ?E.gvtvFӻ/7<_ SU탖]t'ϴS7jW cm1%fS(^HX-A~eVзϞof/ !l0V#Bd&9'*.;Iq?BP@?%!hy(AťFp%?3Ao>~*,g/tug/⟌8x/OOIA!h'.hc_,h[SM]P Bs CNn?qA=NA?qA/q|.ؗA?AͼeK6~2L_8 q9y5R Z LRgԿr5l'u# *VdTq9Jo'c*_Zwft@Pu}P [CPxjX/qSz qfkOf4Vz|@KPzg!~5ظ_PO^5 ڻjqRPw;ظ_PsOV6'zOIСRuSÍu"oi CPz\ŜuQcIsoۓ*f$|7iKP/O~ޞ4W1AdQPy\ 5ƭDOS岆䒾YP@P!(![]LuIC{J O6EV@P@Po~H߸q(N0IAM)ޟ{tAQ%NQ]MiA~zΨ7 *KJ2}x*AWQ%j Mq J1}x*5½ĉ ڙO/}x. ibvI.cd('%^1?&އ>H$x*$RJ\?_½zXIR鏌b/ME􆦴{H){g:鏏'P u /" 5TA5>E>lJH$}xb  z|lbh*+H#}xb @PpuIOO Ma '>UK!5TEP/tKA5TC(5'kF+'ǯv/f%)<oN<iưDuEY{1}\Ka :O"`p L~xmbH&6[}4~?07BcOf*0.k/C>ȂA>}Iu(Pc A9*HFut hޟ4o(;Aqt{x*)PfvOA%6%Z :nDTbUb7T EPTqK8kxhϋ?42j8SFt cCPe'V CPeu /h=h 3B ݖԢq( 7-}-AM5%=JK\?GrrR=Tb]ٝ Rmzbk&zCG38k)$Bx %P A6;~'hP֖C}Ḧq(xm7bgP닂'!.^9jv֗U8auUh :nqdL6GT2D7PKr d\ jhQxg)k&JC Rdl B hT._߯b m~A{"P6n;ullwJƖYPk ')Aku!h ʌ+X A((H/I'Pc)}(g;>j (JXC5MIOʦ'P e}Rk>5TAtTlO*}b @P6'>j (JXC5fzra?=A=k (g EsP 5@P:A>;}li9=xݿ}vuqA&gOS-͞OGx@>+/y)IL"/ʏͧ# Wqbn9|~ Tl~E74㧥%(7114b/T}Pq3n'D=uM|Qyoә}yu"(?DӸ߾7K` 5@P:˲c0 B= | 쁠.Ջ=[5,>2N2y-ϪOV[q|' UkA/v|70Al]tUyxSZټAɁjT#s߈|^c@ U~pAcA5ԇegj#&HM< AoN]A uhZ._ G\o,iEޝfGwz@Pk ZACAk (` 5@PpKi4JIENDB`cutpointr/man/figures/README-unnamed-chunk-36-2.png0000644000176200001440000001517014066443500021311 0ustar liggesusersPNG  IHDR TcSPLTE:f:::f:f(333::::f:::::::f:::ff:f:f::MMMMMnMMMnMff:fff:f::f:fff:ffffffffnMMnMnnMnnnnMMMnMn:::ff:ff:fې۶nMnnnMȫf:۶ې۶۶ƅ~ȎMې:ېf۶f۶۶nvmfȎې۶;b{ pHYsodIDATxܶ});>j'e])m4{9۬nV^6tϷdKړYix~ AJ^~3E/ժVd l@f+2[,?=v|>>^'Ng1p4Hse7$;8vRXb7w^6&Χ(g?D^}XUYUlS5z/;"H/߭ϊ\'p_ %[pp|[-:=߅wW_wiJn]>WȈSwսo#lq|nՃn*d Y}BR{;qZ;n o۹p kD*ugp}_֯3B;fʳ=E' :/Gv{A.p 𯀿fO_3! TzTtp9 Oa/y^ﳛuW p[^-}Я-aℿ#bHEeN`>xsL1y`!^]T=p%xT f|rƖN TrCCKE|_S׳~J$iY!Jm<΂*) tF-סh GR cAq>bu ~,K͂ #Ժ9 a $ޝjn8T$ U g}_u? apwߞ݂SV aޑVjy I2=  `x"\>ɳp&܇Aȑj%`Sq)-6zTC9#޺/ɂf;c߅7l)~uT'׼7bVX!dg5pbygru|{'j]C얗z;No01JcZ.py˂^7s0zs$0 w$~^~)O>H}U./'N ?>2p@j%Vإ$>x}\ oM S_࿖vL/?b.:~@0CQޥ,L ^z2zl(K`d5yM Y^)5vM`hØ/0@0Ud4̤?ةRc% #/.cCYV X{d¯ ee3&Q?~\\a E Pip\`>!/d:"ql)NqV/:)5{7@c#0,/mkد eidqۥ7^?0pR'H35њ._m #W\ձzм -EW ʡ 0YS[akԌ@ZdM#l@JN&Uz 4 {R2z -.]^2#M#ljT[/` s% \(*B` R~Ez<Ak8Y-[)ڃ;;za0 =>tL-;SXJZhُ@}Q8LhT.]$ @-eŦ}@hc`|mj%(7彯O1 C Cj(sjCp ^Әp /? ̂@DڝV$}hEz% t`D|"/h JԶ@43\$<2(F @Z υt o uZ,~i]6L K^vU@ H5HzF>Amԏa83|b*?X)gؑvS-l}0+4FPr oA# s`H㎎;YfAgd_7̸N+j0vrUs".Fj2UIs)>&KL@627s4@>#&b<vhJEf^N鎶4kOQuQhV\2. J QxQoMl%y5/c'TIbI1MIc5(1pbWX]a'gǏvǟVpXstRLgLK"{ +ruzn>޽^`u{6>{!o M [z`*S{0R?F#Xx6!1h-ܧ@Z:D%}A}G@/FLX>/BO.{ϳ Q- :(: @}BjN a~R/f43#L<i6Z 9a=jھq =j'-.JjPL 0(0 @^iG(ݭdyxcd0۷2 @YՁ]}E( 38&?NR8!/Vaf">%?$ZRr:d7@;d^KSYy w(C~(KY j-+i$i(=U@+8hqgAt^bXjsԕ tI &+ ?! 6$ ki>Z8pƘdp}ڤ8 1 h2ШхC ʼ*>@mIAfv*P;u*C6@m<$%A|T*i Ǥ h}i"{ HwII@(7Ӗڿ 8,yNl.`] _JVgv @Cf,@m !~C&gh jU2T 2GQf9P2j@?qa-@]`Kj)ԑ^Oxg30q׼R` +<@$9| =udY@sEo)8 2tWh#+ +qEVT`>TI8wU@| Og" )Vp\yAUQ04h+p[z񴄻 zfz- #8/!=e+12/ }pצ.޳8/= :51 @NCYt4Ђ@``?@myP[,V}2@4AMM P[h# -xl.ҩޯM A^7Vx<ѕ@vu![\8kϿE斃3q## Wۢpm5O 2h<>t]PǶ b0GZa>X`q.ЬׇtgElN]FOFf;[.BR1\j(ƴ}=7j5ߠV[׵ ba?a'zlkJshݩǴ'ZPd "'0i) kثw=XXw'Х.o(tCyɜ@@"u X\?8 9N'Ru_ǽ&@<<[2aMkÎ OK cA+Peh3ZnaK<y5GcsT {Msj REc,:nd4ߘ@5hB1 ќ2Ic6ֹ䍰1 `e^TclF䚕Fv`g'g05SM^ږV_9uP֔JSXJN @54 j#@MX23 ,y@!_:'Ssǿ*E)%Єs#u+[ ,,N G9[/9O9%UF_t9&y=1/nT1U` շ$tH1;OZQ'dVCsn5映]ak X5mLb̷L7;vh;F*yYJvA3\y5 "_x+0b{L .PHde)5vZo.h J=;?thDix ˑJF^RcN}4UJ(<>UA@cb9RRj^ob^CgA$yYJ J"ԗhS/<-*%yZT3¾ x"? un@qc`4@*rcLe)5vZOw#-bP[Oe)5vZo՘3s wU@j|61T:9%#/]xj6OS.deHgGm}GmdziǪu{?tUP,|\ou-)RH[$S 7~Z.n[; ZrU˥VYd %1m@f+2[XQ, Vd +^ CL{q `{".C{_ e{2u Yeb~JJubR[Lt㸼R3P{XsYρBov#t(-i<y[Z<:zt `'ЃfHk% Vd lc*y/svGiٸ\A훊o!!m ظ\&잂}6êLϪjpnzs3mT8Gpu ;J Hjcy `UHuzHj .ӶQe@#KY-l ,x;n+}}vp& m nl@f+2[ UU]{*IENDB`cutpointr/man/figures/README-unnamed-chunk-22-1.png0000644000176200001440000000711114066443433021304 0ustar liggesusersPNG  IHDR TcPLTE:f:::f:f333::::f::::f:f:f:MMMMMnMMMnMff:f:ffffffffnMMnMnnMnnnMMMnM:f:fې۶nMnnnȫff:f۶ȎMې:ېf۶f۶ېnfȎې۶F^ pHYsod IDATx {۶a7lv^v.eܭUv( >E$(HG5 Xrad_7 kA6\;, 76!56A=}9dON?)ր-@ ٸ=⻡"e@Y,P(E"e [BBBBBBw:}ٓOo2 (X>V<$w?8 (X>V|7OF-ݸG\,)oO:,w)XPIOݍ{l@`TTk !нi CcZx (j/˿aV6 t<߇6EX; j-+DMhkMa@g, dlA|,1T@M;A|,=2lEW?h2h .2`Z'VX {ȯ(~> dHc @A|,},!|,~Eiԡ8` dxz(1BB28!!!>>> ,B2,7U|,A%> dHL@`׀|,0}! _@ȿыߔ'HJ7/J{;FT) !E:>Uao *Qd()I&^/Jo< |,;|:o":Ry yu @#_x>˫^P6󀧯z:F}1K@_jiX@@@@`5!|>>>>`}qr޺c#)Kb1gm:FLZ6u"H^o10NEQCc]Ǣ`33R,@C"d٪i}OtE^<}4> 0TЫ D/`#c WEpj Xr$| ہXzq1vwDӝG矤`wV([X z|>>'b|J]  *j~Z'vJT : F^=$(U ih{Z rvF@ӏ5迢bz,N0R1KցQD: o |.̏\RjlfɕLDzAP<9v};zd?@@LA}"FIE8L@v4$qFr 3{Y $< cc0rq[<;!*whoG_sa$%=B+Y$qᥜ~Wԁ>!(Ex ,NZIBrp"L"f6.X(TWGg 8SХP8 R@G6]kJ |:#,ZD ccccccccccctYݯVĶjMR@@QFHjS \pUq*v9za$jxYP1THW=\n8Ru:ܹ:P6p GAK>upNwUkn@ Y~]՚Ln@*3aHEBBBBBBBBBBBBBBBBwu JX X X X X X X X X X X X X X X X j< C},},},},.{@M r C6dVW*@MVKq Z/Ja wR@(ixircX^}рcy:h@:~\,Krvp|,},},},zN<>@O}"D=UT(E"e M5 ~{P\1ҾZڻg۷mQ|ZҾZڻO2{<2k!ϋ[ڋ*ȴkx啼gI>z犉I/2w ~zgI lC4LӆlMǯ>kxpxZKލz sDK_djioM<{?D+&Z7"S]o'=x&,P(E"e 'W5oa9۹Vl^_ujlI4mO[_>z؂G Rlg-OMhy^m3{0F8lfȰs?;Ԋ3ۻNT5./ܥ2{lrz'/Yʭ=94oYZJnVay]O.m[qRD>M i ")qdQ @RVx?գ+@HzyrUi띂3N dy-a;,\], tLGa*wйPrynjltĹ1нoӭ5դ^tR,P(E"eLsQ_stIENDB`cutpointr/man/figures/README-unnamed-chunk-36-1.png0000644000176200001440000000733214066443500021311 0ustar liggesusersPNG  IHDR TcAPLTE:f:::f:f333::::f::::f:ff:f:f::MMMMMnMMMnM^aacdff:fff:f:fffffffnMMnMnnMnnnnnMMMnMnM:::ff:ff:fې۶nMnnnȫff::۶ې۶ȎMې:۶f۶۶nvmfȎې۶Lw pHYsod ?IDATx {۶)'hZ)nUmnMV/vK䨻9%F$AC2ylI%H6x%x<@g 3⻏-W?[_zKf jir0% \ F;Ap]uFH4QMӯ6GEp8"0\OFAp}V=^ '((0)W4~um8}Txmuch"~&~#]bZY4\Oˠ[8axқϴk?k鷃@ ]_Lj ^JhI| P _^J P] ;]@;ёj*@t<@@ Kŀ Ec|tLnd ,$,7΢%*?7D[xpAXaԡ^E{|ɵAΩtg';_%'bɳy)O^?^+թE%eRgm;x<1@g 3 x<!`y0_L/߫ĶXX_~G}vPOʬvfcea.(,넀$G]>G'_dt.Ĩn>Pn~{|Pobʩ%L}c~WE9Xj֓Qj ]ׁ>ُS?2}PI,If<-&wj@r5ʼ.nl>~Wo POT0ꈢjOi:TBg/i$aoBsfDlqؚ+,JIy;"vmTEn)~7)~-եga%@76g.?t /@ fn\zқe~jS 2:4S;])@9K3cka e ΍o ^.U~<+j4A=˱zsԋe\cuѬH݈A8i?0\YAХ$;ٱ޻g1dDT4;"wФt?iwA5wv.@g 3m 3 x^ks'+A@qwAK˱~бrݾqGjSWY@Lp MuIH#v[@u@B a:Ɯf; Itm* C%c@\6G<M@B@$ ?!*ct5lC X.٨JmQ0e%Iۅ(`MrY* %gꦉpql-+pP…1nЗ٣Ve9 PYLY(x*"Tm7Lp"+e- Ψ w˒C)pQ!@MѲ<uc*u(dS_3Mm)޿| [+Uj $@z7|Q>MR[wjnA@÷',%--C<T&w4 N琁boж.YD3!2mƇ>2h(NןC()c/I9d7 n=bCoF)#|3 170 :'fhX@(аQ @@@'4{Qޝ hڀrkB l%(C@@@y (QM@.kF!SbMwo-h{ (6  <@5~4'yM(6  <@ب- a -kZ$!&ls싀Pwq`?`o,Ym'krgWً>I+-ً`{ԟCf/PX@V$ ژA}}YI 3L@ 3 x_@uz<tftڅmvWw^~xEe4&ROVknpk2ipnV?&/ uAah\,±\<[صlU6M~pӻc < xu1k[y3AXҊqQP;%KڌZ-=[ plr_PW-P5~M &6q&j%ZF)>Vގj+qՈ)UHio ăËՏW}:;OF9K(|0dDbMTlSLt co~/# m[3'# OlHZAUegRS [>T۶UtݞY#@а(T0Uft]\PS{ֺN@tlqoɴAtkHx _Tuy^}A~ N4-NF?05@=%y:z$,%h0PSOA#[AN{d:E,>;$K(|ѕ(z;Nmq2NfiA{QdWWO3w!($Z- D B@!hPH($Z- ֜}Q|rp'.:̉&'Զ+W8qe>V4@LԚ-I6E3 MPj(=,Lob\uE{nNЫ@I u=\ˠ\.mǦ>I2Pj(T7]j&+U$"\2-}lRڳ'Kf }>n5NMbgIgsb{NRRڂ,޿$q'IʍH|rgtCHO?[Dk6jck4{&MfJRR?%LhY8x-ANìI^[#K!Ѕ 5|$@҃$q;H($Z- D B )TǠ851h?A @q j(ڏcPC~ PǠ851?k׾y놃9}ا֧Ϯ5uQZ 蟼?  ?|_G85T{?Q_,;>WchWPb=]U!OvP(A|7/ݪaQZ 6T-*JC*xO,P.z„qEA @?i+1h?k=kVzg詿3o>Ix8V/LrE㪗QzYDZzٕ!.؍Sh>yCs=qK DZzYyש8@qfT2Qte@6L٠v5S?[d je66o:V/ XK4m7|0L=vw/Jx*`MkUu;T.ZT²qФIkmяГhTJ6,:V/ϘΜwƕ)VV ~U* PE{O?E+Fs_mt1Ǔ qJr PT(- @E PT 2wP@ZsAKaP*qT@H3Pf "J?P4VO.h)*!9.4s\(i=}y~woi@2@xN@f-G7?4%Saj? @zO_&>پP;VjtFf Q~Uz&~x@Rkg- )IA@Tvf P瀼ڙ9.4\@~"S3(,)vf о^qT@H3y3 h&uf Lt~@ZsA(A= @ +M$qT(7H;y8& q Pұhy@log渄 =cLhHfKɉr]_VOew\栀gJѪLPd q:{vZɢIaS3%X@3Pԡ9.T^~LL7Cjd㍍yܙ,:5s\B2а @E9.4s\*=6˗E V \Њ;1:PR&ki^XsiqP1s\Uefaq7_|PB Ш\:$3ǥ ;7@"~䢉߱Hs|ט}3EgZժ<贎vc*9UTmIR/m^6zX$Ԙcs46פhm4c!uF;RWVL@H3hҊKz hi#)ym+dQF:F9./@s(D3.@44,{%K޶CAӗ}]k L^F?g@8(/ym7Pm@46W@H3Pf "90ԩ@H3Pf "SzHaS3Pf " @E9.T>+IaS3Pf˂Z` )ЪLPdP7Pf " @E9.4s\t@ |aS3Pf "g+{3ԑ3m,X 1A]}-봋,VgQbTL!ש@n!- @@Gњ+h<hcQE"$gbq]=To[.->c:mP*q]GVk!ŧ:5s\h%,!m(PU|=EP%O1 ujP*q]vm+a J#Mygv\DSˮ|aS3v=h܋Wv wi3vh[%|aS3v%h @%1E *qA? @c @9.+@[?Q_Ƨ:5s\h%,! @INݍ[766n3{Nv3ӟ'2E3׾Fh}cc'i>PSQWMw=9b N͡jq\ՐZ<^=a:( @3@Uz&5mP2QU (77^KZ45gPψ㺮FFv|>Y٣}Vdj/mL ) ujv]8_f%h|2|fWEsYr@zS>:Tb.<Zŧ:5E?*~˾Cb|NڎNRW$Uz&oE|(A݀@+;]:9P &!(%( x=hysz6BM1ϐra&*qTqP*q}5yPo&\^@(mP*qT@H3Pf " @E9.4s\(i, fZ h@2s\(iP*qT@H3Pf " @E9.4s\(iP*qT@H3Pf "PǥhN~1Q$q\6OqhB z j')VS @6s\*ճڹ%$J2mVSQh~Ra+O @=?] 氀tJe U j]L*t9 , iMf&)9.ڹsK _|S @6{Z(AEj')&K)a4l7vt 4߱Z0Z}hfKw/3 qT@H3Pf " @E9.4s\(iP*qYH@ąh5bqT@H3Pf " @E9.4s\ho|?n@hS_T̅a@hVh@h/nW̅M h:E\ Z 3TТ mP) i}N}Q1+炖 @{jA@2箜 Z 3Pf " @E9.4s\(iP*qBͪݓ#Pѩ( J5@ssP@؟d! 2P6+k ~,]4@Zڼ;;f5[kRSdmWPqZwP!ּ6r:}u?]|6YsUYέRXݿ %tmv.߯KJm5f:w|tC@k^NMR[5m禲osIT5{KyT{dijL@ݿ{-mί=mNuIfv(JWT4|!:N6m4mPрּ6IEmL@ݿ yԙț6Yss<ӹ Jr PT(- @E PTrz^a8D'1+o]yQ's@s6:$WxmU%;ۜ6\@elXT^j>HXkVbwn\3Ӌ(b>h[#AIs{f<^u : BFk1>OUJ3QsХ\m;␏MڣYq؋tǫMAG*kP,S{z渚(Q7$R='7>bNW7'+{cKxaO5<]Z@(uN*Baw32:zk{0GIZ;ĀfIJ Pz13z2?:W*(@VN]O PT(!]X U P47ĘcT|ͯ0851#_@hr|u /O+#V*.1hjʾ^f)!1hΚ% ΁4giAut@Ǡ9˿],AaM )AsVq!9(!1hjs'I b PT(- @E PT(- @E Pjd}=cL=ؠ=ؠ=ؠ‹:hPH($Z- V+@sMxc彍%;˛ʾcЬjh~Z蚕=߂KwUn1BZtǠ+E(]i< YPwLlՔTbfV@˯Qi!֤Uy2WU4iZwJ}]5iIBMc--pҩ߿_Z :ͬ.۠eM᧤)h;wQhor5BZȲt7#8 PE HYgsudg5Q)|uz'."wN䃲@{ON~Www:5od@qwU L,R-)]@_p"ڨY.b^jw`V`[Y(?ϲy&_.๰왈'`|4feu1Xhaj:]^tA0y6Cۅ 0=Y2'ʵ4jXpPPVt}Su%/FuTpziDM0ϝb$H,X @b1bT48h1=N+Z @48h!~W GfY?*)M8xDMϊ_@cPԫ2*]Ћ_/ Oe?=^#;D#mR@ z10''8l^}=2 bV{DgszB48h1=N+Z @t(`4x!J#H-i|Eq_bzW07Ekp qqФZhDlpm3xp<6bW/(1qq_њwߒZ]N" KKͻEoV*<H , B'w9N`.1Cwo-oi ,\b u`LG:]8h B s`YČ9tB `81"i|Ek@=ukؕƣ@SǍ9wFG 5loHw< hmMAtIngu{e@_6[>}C8ڤcr>*x>o!T:dMój{foi(5ƒ~AEO$ީ&Bj<|JmdPb~4Z{4睬~7[ @Y@M **$]1?7@+Z h|EkOD\N+Z1/)dX&@ 4t thE ֲu\/Ü+"-[%vNޓXPg:ηv3$GH{Li,۾qݿ(NEn!'w˽cմbYy 9.fŹ ?u!`>Z i"@U ۥz sDO/f_/ڵdK b =x"@b2 lWA4Nxd=*[ċv{,[ޖ]PlN. ]Ѓ35'* 8y9ׅ|a1@t?h׌Z2ON./f`-LC?Vr5 r>-]^2\Yps![b7L斸 hpm%@z!s^Ȝvgʷ " 'l91ǀ"嫁J[/dNtL.&@9^_Ả]; %YTnT d>tފhTO@'p=<miYv&Íɥs]+Bm@ v/ln;jYV 3ܽ)TywKQ~AtBXH W.sB"Rf@Cۜ~AjBSn|e-+װ@Ic@' \/ 8z~3Mv/`:T=ܿnZX/Hm@h Sf {.אU~AjiY/ @YUnx0,= p?aNtL_7"{DG ߏ[z$BD@H= _C:Я `"<p^ UAu &%@iEQ|(5@)|b+}R(v&tS 1!RR_cߒ\jQ~*/3h-PJ< c`(V" :.D[rn"bp B-Fa7[>:+as|\Nt0PT{D pIQ)q`j' Mh7Gč @3nL 4fVi'_?7 D2=eAqh8} }q57'>)S/~{Ej%ZTOwŘn4ޝ'"]kZ4o*?yjVbPQcԮ5aѾP -ĺ=; vQ/ά/A.-减TZ11 _@YP;_Z^n%69sy}n0]k }!Mq_cLJnajh!`i}(q `DR-kL_yB+ZGFbc 0r\'p 2E& `ԸFo`[!"&JYEC x[@ o h$j Q$R+ Q\``:F[@q@s8>.h2q_bzW-i|Eq_bzW-*'`kW-ԣ:3p R:l)^Qc [zT:!zMʓ'+O&OI$H,XAWL7}#S_yU[cc(od) EwQ`nYOy72W|V_SFKp&ԟW](zʫGQ`FCϫw?|Qa x^0bzʫU3P^\VL7~#S_ #?+b$H,XAًl_wH5Ibi-bJW3kSM^v!&S &[k}w?T9 7p KDl4IRDUA O.ĖVIrlUu0pl iZ7a@VPNCW_X$b$H,X @b1bP EVIENDB`cutpointr/man/oc_youden_kernel.Rd0000644000176200001440000000541113672457720016705 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/oc_youden_kernel.R \name{oc_youden_kernel} \alias{oc_youden_kernel} \title{Determine an optimal cutpoint maximizing the Youden-Index based on kernel smoothed densities} \source{ Fluss, R., Faraggi, D., & Reiser, B. (2005). Estimation of the Youden Index and its associated cutoff point. Biometrical Journal, 47(4), 458–472. Matt Wand (2015). KernSmooth: Functions for Kernel Smoothing Supporting Wand & Jones (1995). R package version 2.23-15. https://CRAN.R-project.org/package=KernSmooth } \usage{ oc_youden_kernel(data, x, class, pos_class, neg_class, direction, ...) } \arguments{ \item{data}{A data frame or tibble in which the columns that are given in x and class can be found.} \item{x}{(character) The variable name to be used for classification, e.g. predictions or test values.} \item{class}{(character) The variable name indicating class membership.} \item{pos_class}{The value of class that indicates the positive class.} \item{neg_class}{The value of class that indicates the negative class.} \item{direction}{(character) Use ">=" or "<=" to select whether an x value >= or <= the cutoff predicts the positive class.} \item{...}{To capture further arguments that are always passed to the method function by cutpointr. The cutpointr function passes data, x, class, metric_func, direction, pos_class and neg_class to the method function.} } \description{ Instead of searching for an optimal cutpoint to maximize (sensitivity + specificity - 1) on the ROC curve, this function first smoothes the empirical distributions of \code{x} per class. The smoothing is done using a binned kernel density estimate. The bandwidth is automatically selected using the direct plug-in method. } \details{ The functions for calculating the kernel density estimate and the bandwidth are both from \pkg{KernSmooth} with default parameters, except for the bandwidth selection, which uses the standard deviation as scale estimate. The cutpoint is estimated as the cutpoint that maximizes the Youden-Index given by \eqn{J = max_c {F_N(c) - G_N(c) }} where \eqn{J} and \eqn{G} are the smoothed distribution functions. } \examples{ data(suicide) if (require(KernSmooth)) { oc_youden_kernel(suicide, "dsi", "suicide", oc_metric = "Youden", pos_class = "yes", neg_class = "no", direction = ">=") ## Within cutpointr cutpointr(suicide, dsi, suicide, method = oc_youden_kernel) } } \seealso{ Other method functions: \code{\link{maximize_boot_metric}()}, \code{\link{maximize_gam_metric}()}, \code{\link{maximize_loess_metric}()}, \code{\link{maximize_metric}()}, \code{\link{maximize_spline_metric}()}, \code{\link{oc_manual}()}, \code{\link{oc_mean}()}, \code{\link{oc_median}()}, \code{\link{oc_youden_normal}()} } \concept{method functions} cutpointr/man/specificity.Rd0000644000176200001440000000273313672457720015700 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{specificity} \alias{specificity} \title{Calculate specificity} \usage{ specificity(fp, tn, ...) } \arguments{ \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate specificity from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. \cr \cr specificity = tn / (tn + fp) \cr } \examples{ specificity(10, 5, 20, 10) specificity(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/abs_d_ppv_npv.Rd0000644000176200001440000000341113672457720016177 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{abs_d_ppv_npv} \alias{abs_d_ppv_npv} \title{Calculate the absolute difference of positive and negative predictive value} \usage{ abs_d_ppv_npv(tp, fp, tn, fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate the absolute difference of positive predictive value (PPV) and negative predictive value (NPV) from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. \cr \cr ppv = tp / (tp + fp) \cr npv = tn / (tn + fn) \cr abs\_d\_ppv\_npv = |ppv - npv| \cr } \examples{ abs_d_ppv_npv(10, 5, 20, 10) abs_d_ppv_npv(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/print.cutpointr.Rd0000644000176200001440000000131113672457720016536 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/print.cutpointr.R \name{print.cutpointr} \alias{print.cutpointr} \title{Print cutpointr objects} \source{ Kirill Müller and Hadley Wickham (2017). tibble: Simple Data Frames. https://CRAN.R-project.org/package=tibble } \usage{ \method{print}{cutpointr}(x, width = 1000, n = 50, sigfig = 6, ...) } \arguments{ \item{x}{a cutpointr object.} \item{width}{width of output.} \item{n}{number of rows to print.} \item{sigfig}{Number of significant digits to print. Temporarily overrides options("pillar.sigfig").} \item{...}{further arguments.} } \description{ Prints the \code{cutpointr} object with full width like a \code{tbl_df}. } cutpointr/man/user_span_cutpointr.Rd0000644000176200001440000000145613672457720017474 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/optimize_metric.R \name{user_span_cutpointr} \alias{user_span_cutpointr} \title{Calculate bandwidth for LOESS smoothing of metric functions by rule of thumb} \usage{ user_span_cutpointr(data, x) } \arguments{ \item{data}{A data frame} \item{x}{The predictor variable} } \description{ This function implements a rule of thumb for selecting the bandwidth when smoothing a function of metric values per cutpoint value, particularly in \code{maximize_loess_metric} and \code{minimize_loess_metric}. } \details{ The function used for calculating the bandwidth is 0.1 * xsd / sqrt(xn), where xsd is the standard deviation of the unique values of the predictor variable (i.e. all cutpoints) and xn is the number of unique predictor values. } cutpointr/man/odds_ratio.Rd0000644000176200001440000000313113672457720015505 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{odds_ratio} \alias{odds_ratio} \title{Calculate the odds ratio} \usage{ odds_ratio(tp, fp, tn, fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate the (diagnostic) odds ratio from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. \cr \cr odds_ratio = (tp / fp) / (fn / tn) \cr } \examples{ odds_ratio(10, 5, 20, 10) odds_ratio(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/oc_youden_normal.Rd0000644000176200001440000000347713672457720016727 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/oc_youden_normal.R \name{oc_youden_normal} \alias{oc_youden_normal} \title{Determine an optimal cutpoint for the Youden-Index assuming normal distributions} \usage{ oc_youden_normal( data, x, class, pos_class = NULL, neg_class = NULL, direction, ... ) } \arguments{ \item{data}{A data frame or tibble in which the columns that are given in x and class can be found.} \item{x}{(character) The variable name to be used for classification, e.g. predictions or test values.} \item{class}{(character) The variable name indicating class membership.} \item{pos_class}{The value of class that indicates the positive class.} \item{neg_class}{The value of class that indicates the negative class.} \item{direction}{(character) Use ">=" or "<=" to select whether an x value >= or <= the cutoff predicts the positive class.} \item{...}{To capture further arguments that are always passed to the method function by cutpointr. The cutpointr function passes data, x, class, metric_func, direction, pos_class and neg_class to the method function.} } \description{ An optimal cutpoint maximizing the Youden- or J-Index (sensitivity + specificity - 1) is calculated parametrically assuming normal distributions per class. } \examples{ data(suicide) oc_youden_normal(suicide, "dsi", "suicide", pos_class = "yes", neg_class = "no", direction = ">=") cutpointr(suicide, dsi, suicide, method = oc_youden_normal) } \seealso{ Other method functions: \code{\link{maximize_boot_metric}()}, \code{\link{maximize_gam_metric}()}, \code{\link{maximize_loess_metric}()}, \code{\link{maximize_metric}()}, \code{\link{maximize_spline_metric}()}, \code{\link{oc_manual}()}, \code{\link{oc_mean}()}, \code{\link{oc_median}()}, \code{\link{oc_youden_kernel}()} } \concept{method functions} cutpointr/man/boot_ci.Rd0000644000176200001440000000355513717555442015006 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/boot_ci.R \name{boot_ci} \alias{boot_ci} \title{Calculate bootstrap confidence intervals from a cutpointr object} \usage{ boot_ci(x, variable, in_bag = TRUE, alpha = 0.05) } \arguments{ \item{x}{(character) The numeric independent (predictor) variable.} \item{variable}{Variable to calculate CI for} \item{in_bag}{Whether the in-bag or out-of-bag results should be used for testing} \item{alpha}{Alpha level. Quantiles of the bootstrapped values are returned for (alpha / 2) and 1 - (alpha / 2).} } \value{ A data frame with the columns quantile and value } \description{ Given a \code{cutpointr} object that includes bootstrap results this function calculates a bootstrap confidence interval for a selected variable. Missing values are removed before calculating the quantiles. In the case of multiple optimal cutpoints all cutpoints / metric values are included in the calculation. Values of the selected variable are returned for the percentiles alpha / 2 and 1 - alpha / 2. The metrics in the bootstrap data frames of \code{cutpointr} are suffixed with \code{_b} and \code{_oob} to indicate in-bag and out-of-bag, respectively. For example, to calculate quantiles of the in-bag AUC \code{variable = AUC_b} should be set. } \examples{ \dontrun{ opt_cut <- cutpointr(suicide, dsi, suicide, gender, metric = youden, boot_runs = 1000) boot_ci(opt_cut, optimal_cutpoint, in_bag = FALSE, alpha = 0.05) boot_ci(opt_cut, acc, in_bag = FALSE, alpha = 0.05) boot_ci(opt_cut, cohens_kappa, in_bag = FALSE, alpha = 0.05) boot_ci(opt_cut, AUC, in_bag = TRUE, alpha = 0.05) } } \seealso{ Other main cutpointr functions: \code{\link{add_metric}()}, \code{\link{boot_test}()}, \code{\link{cutpointr}()}, \code{\link{multi_cutpointr}()}, \code{\link{predict.cutpointr}()}, \code{\link{roc}()} } \concept{main cutpointr functions} cutpointr/man/ppv.Rd0000644000176200001440000000310613672457720014165 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{ppv} \alias{ppv} \title{Calculate the positive predictive value} \usage{ ppv(tp, fp, tn, fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate the positive predictive value (PPV) from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. \cr \cr ppv = tp / (tp + fp) \cr } \examples{ ppv(10, 5, 20, 10) ppv(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/plot_x.Rd0000644000176200001440000000216313672457720014667 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/plot_x.R \name{plot_x} \alias{plot_x} \title{Plot the distribution of the independent variable per class from a cutpointr object} \usage{ plot_x(x, display_cutpoint = TRUE, ...) } \arguments{ \item{x}{A cutpointr object.} \item{display_cutpoint}{(logical) Whether or not to display the optimal cutpoint as a vertical line.} \item{...}{Additional arguments (unused).} } \description{ Given a \code{cutpointr} object this function plots the distribution(s) of the independent variable(s) and the respective cutpoints per class. } \examples{ opt_cut <- cutpointr(suicide, dsi, suicide) plot_x(opt_cut) ## With subgroup opt_cut_2groups <- cutpointr(suicide, dsi, suicide, gender) plot_x(opt_cut_2groups) } \seealso{ Other cutpointr plotting functions: \code{\link{plot.cutpointr}()}, \code{\link{plot_cut_boot}()}, \code{\link{plot_cutpointr}()}, \code{\link{plot_metric_boot}()}, \code{\link{plot_metric}()}, \code{\link{plot_precision_recall}()}, \code{\link{plot_roc}()}, \code{\link{plot_sensitivity_specificity}()} } \concept{cutpointr plotting functions} cutpointr/man/plot_cutpointr.Rd0000644000176200001440000000534013672457720016447 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/plot_cutpointr.R \name{plot_cutpointr} \alias{plot_cutpointr} \title{General purpose plotting function for cutpointr or roc_cutpointr objects} \usage{ plot_cutpointr( x, xvar = cutpoint, yvar = sum_sens_spec, conf_lvl = 0.95, aspect_ratio = NULL ) } \arguments{ \item{x}{A \code{cutpointr} or \code{roc_cutpointr} object.} \item{xvar}{A function, typically \code{cutpoint} or a metric function.} \item{yvar}{A function, typically a metric function.} \item{conf_lvl}{(numeric) If bootstrapping was run and x is a cutpointr object, a confidence interval at the level of conf_lvl can be plotted. To plot no confidence interval set conf_lvl = 0.} \item{aspect_ratio}{(numeric) Set to 1 to obtain a quadratic plot, e.g. for plotting a ROC curve.} } \description{ Flexibly plot various metrics against all cutpoints or any other metric. The function can plot any metric based on a \code{cutpointr} or \code{roc_cutpointr} object. If \code{cutpointr} was run with bootstrapping, bootstrapped confidence intervals can be plotted. These represent the quantiles of the distribution of the y-variable grouped by x-variable over all bootstrap repetitions. } \details{ The arguments to \code{xvar} and \code{yvar} should be metric functions. Any metric function that is suitable for \code{cutpointr} can also be used in \code{plot_cutpointr}. Anonymous functions are also allowed. To plot all possible cutpoints, the utility function \code{cutpoint} can be used. The functions for \code{xvar} and \code{yvar} may accept any or all of the arguments \code{tp}, \code{fp}, \code{tn}, or \code{fn} and return a numeric vector, a matrix or a \code{data.frame}. For more details on metric functions see \code{vignette("cutpointr")}. Note that confidence intervals can only be correctly plotted if the values of \code{xvar} are constant across bootstrap samples. For example, confidence intervals for \code{tpr} by \code{fpr} (a ROC curve) cannot be plotted, as the values of the false positive rate vary per bootstrap sample. } \examples{ set.seed(1) oc <- cutpointr(suicide, dsi, suicide, boot_runs = 10) plot_cutpointr(oc, cutpoint, F1_score) ## ROC curve plot_cutpointr(oc, fpr, tpr, aspect_ratio = 1) ## Custom function plot_cutpointr(oc, cutpoint, function(tp, tn, fp, fn, ...) tp / fp) + ggplot2::ggtitle("Custom metric") + ggplot2::ylab("value") } \seealso{ Other cutpointr plotting functions: \code{\link{plot.cutpointr}()}, \code{\link{plot_cut_boot}()}, \code{\link{plot_metric_boot}()}, \code{\link{plot_metric}()}, \code{\link{plot_precision_recall}()}, \code{\link{plot_roc}()}, \code{\link{plot_sensitivity_specificity}()}, \code{\link{plot_x}()} } \concept{cutpointr plotting functions} cutpointr/man/plr.Rd0000644000176200001440000000321513672457720014156 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{plr} \alias{plr} \alias{nlr} \title{Calculate the positive or negative likelihood ratio} \usage{ plr(tp, fp, tn, fn, ...) nlr(tp, fp, tn, fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate the positive or negative likelihood ratio from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. \cr \cr plr = tpr / fpr \cr nlr = fnr / tnr \cr } \examples{ plr(10, 5, 20, 10) plr(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/tpr.Rd0000644000176200001440000000361513672457720014172 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{tpr} \alias{tpr} \alias{fpr} \alias{tnr} \alias{fnr} \title{Calculate true / false positive / negative rate} \usage{ tpr(tp, fn, ...) fpr(fp, tn, ...) tnr(fp, tn, ...) fnr(tp, fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fn}{(numeric) number of false negatives.} \item{...}{for capturing additional arguments passed by method.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} } \description{ Calculate the true positive rate (tpr, equal to sensitivity and recall), the false positive rate (fpr, equal to fall-out), the true negative rate (tnr, equal to specificity), or the false negative rate (fnr) from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. \cr \cr tpr = tp / (tp + fn) \cr fpr = fp / (fp + tn) \cr tnr = tn / (tn + fp) \cr fnr = fn / (fn + tp) \cr } \examples{ tpr(10, 5, 20, 10) tpr(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/risk_ratio.Rd0000644000176200001440000000317513672457720015534 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{risk_ratio} \alias{risk_ratio} \title{Calculate the risk ratio (relative risk)} \usage{ risk_ratio(tp, fp, tn, fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate the risk ratio (or relative risk) from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. \cr \cr risk_ratio = (tp / (tp + fn)) / (fp / (fp + tn)) \cr } \examples{ risk_ratio(10, 5, 20, 10) risk_ratio(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/sum_ppv_npv.Rd0000644000176200001440000000333213672457720015735 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{sum_ppv_npv} \alias{sum_ppv_npv} \title{Calculate the sum of positive and negative predictive value} \usage{ sum_ppv_npv(tp, fp, tn, fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate the sum of positive predictive value (PPV) and negative predictive value (NPV) from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. \cr \cr ppv = tp / (tp + fp) \cr npv = tn / (tn + fn) \cr sum_ppv_npv = ppv + npv \cr } \examples{ sum_ppv_npv(10, 5, 20, 10) sum_ppv_npv(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/prostate_nodal.Rd0000644000176200001440000000167713672457720016411 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/data.R \docType{data} \name{prostate_nodal} \alias{prostate_nodal} \title{Nodal involvement and acid phosphatase levels in 53 prostate cancer patients} \format{ A data frame with 53 rows and 2 variables: \describe{ \item{acid_phosphatase}{(numeric) Blood serum level of acid phosphatase} \item{nodal_involvement}{(logical) Whether neighboring lymph nodes were involved} } } \source{ Le CT (2006). A solution for the most basic optimization problem associated with an ROC curve. Statistical methods in medical research 15: 571–584 } \usage{ prostate_nodal } \description{ Prostatic acid phosphatase (PAP) emerged as the first clinically useful tumor marker in the 1940s and 1950s. This data set contains the serum levels of acid phosphatase of 53 patients that were confirmed to have prostate cancer and whether the neighboring lymph nodes were involved. } \keyword{datasets} cutpointr/man/cutpoint.Rd0000644000176200001440000000273613672457720015235 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{cutpoint} \alias{cutpoint} \alias{cutpoints} \title{Extract the cutpoints from a ROC curve generated by cutpointr} \usage{ cutpoint(x, ...) cutpoints(x, ...) } \arguments{ \item{x}{A roc_cutpointr object.} \item{...}{Further arguments.} } \description{ This is a utility function for extracting the cutpoints from a \code{roc_cutpointr} object. Mainly useful in conjunction with the \code{plot_cutpointr} function if cutpoints are to be plotted on the x-axis. } \examples{ oc <- cutpointr(suicide, dsi, suicide, gender) plot_cutpointr(oc, cutpoint, accuracy) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/metric_constrain.Rd0000644000176200001440000000742114066364276016730 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{metric_constrain} \alias{metric_constrain} \alias{sens_constrain} \alias{spec_constrain} \alias{acc_constrain} \title{Metrics that are constrained by another metric} \usage{ metric_constrain( tp, fp, tn, fn, main_metric = sensitivity, constrain_metric = specificity, min_constrain = 0.5, suffix = "_constrain", ... ) sens_constrain( tp, fp, tn, fn, constrain_metric = specificity, min_constrain = 0.5, ... ) spec_constrain( tp, fp, tn, fn, constrain_metric = sensitivity, min_constrain = 0.5, ... ) acc_constrain( tp, fp, tn, fn, constrain_metric = sensitivity, min_constrain = 0.5, ... ) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{main_metric}{Metric to be optimized.} \item{constrain_metric}{Metric for constraint.} \item{min_constrain}{Minimum desired value of constrain_metric.} \item{suffix}{Character string to be added to the name of main_metric.} \item{...}{for capturing additional arguments passed by method.} } \description{ For example, calculate sensitivity where a lower bound (minimal desired value) for specificty can be defined. All returned metric values for cutpoints that lead to values of the constraining metric below the specified minimum will be zero. The inputs must be vectors of equal length. } \examples{ ## Maximum sensitivity when Positive Predictive Value (PPV) is at least 75\% library(dplyr) library(purrr) library(cutpointr) cp <- cutpointr(data = suicide, x = dsi, class = suicide, method = maximize_metric, metric = sens_constrain, constrain_metric = ppv, min_constrain = 0.75) ## All metric values (m) where PPV < 0.75 are zero plot_metric(cp) cp$roc_curve ## We can confirm that PPV is indeed >= 0.75 cp \%>\% add_metric(list(ppv)) ## We can also do so for the complete ROC curve(s) cp \%>\% pull(roc_curve) \%>\% map(~ add_metric(., list(sensitivity, ppv))) ## Use the metric_constrain function for a combination of any two metrics ## Estimate optimal cutpoint for precision given a recall of at least 70\% cp <- cutpointr(data = suicide, x = dsi, class = suicide, subgroup = gender, method = maximize_metric, metric = metric_constrain, main_metric = precision, suffix = "_constrained", constrain_metric = recall, min_constrain = 0.70) ## All metric values (m) where recall < 0.7 are zero plot_metric(cp) ## We can confirm that recall is indeed >= 0.70 and that precision_constrain ## is identical to precision for the estimated cutpoint cp \%>\% add_metric(list(recall, precision)) ## We can also do so for the complete ROC curve(s) cp \%>\% pull(roc_curve) \%>\% map(~ add_metric(., list(recall, precision))) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/maximize_loess_metric.Rd0000644000176200001440000001117113672457720017754 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/optimize_metric.R \name{maximize_loess_metric} \alias{maximize_loess_metric} \alias{minimize_loess_metric} \title{Optimize a metric function in binary classification after LOESS smoothing} \source{ Xiao-Feng Wang (2010). fANCOVA: Nonparametric Analysis of Covariance. https://CRAN.R-project.org/package=fANCOVA Leeflang, M. M., Moons, K. G., Reitsma, J. B., & Zwinderman, A. H. (2008). Bias in sensitivity and specificity caused by data-driven selection of optimal cutoff values: mechanisms, magnitude, and solutions. Clinical Chemistry, (4), 729–738. } \usage{ maximize_loess_metric( data, x, class, metric_func = youden, pos_class = NULL, neg_class = NULL, direction, criterion = "aicc", degree = 1, family = "symmetric", user.span = NULL, tol_metric, use_midpoints, ... ) minimize_loess_metric( data, x, class, metric_func = youden, pos_class = NULL, neg_class = NULL, direction, criterion = "aicc", degree = 1, family = "symmetric", user.span = NULL, tol_metric, use_midpoints, ... ) } \arguments{ \item{data}{A data frame or tibble in which the columns that are given in x and class can be found.} \item{x}{(character) The variable name to be used for classification, e.g. predictions or test values.} \item{class}{(character) The variable name indicating class membership.} \item{metric_func}{(function) A function that computes a metric to be maximized. See description.} \item{pos_class}{The value of class that indicates the positive class.} \item{neg_class}{The value of class that indicates the negative class.} \item{direction}{(character) Use ">=" or "<=" to select whether an x value >= or <= the cutoff predicts the positive class.} \item{criterion}{the criterion for automatic smoothing parameter selection: "aicc" denotes bias-corrected AIC criterion, "gcv" denotes generalized cross-validation.} \item{degree}{the degree of the local polynomials to be used. It can be 0, 1 or 2.} \item{family}{if "gaussian" fitting is by least-squares, and if "symmetric" a re-descending M estimator is used with Tukey's biweight function.} \item{user.span}{The user-defined parameter which controls the degree of smoothing} \item{tol_metric}{All cutpoints will be returned that lead to a metric value in the interval [m_max - tol_metric, m_max + tol_metric] where m_max is the maximum achievable metric value. This can be used to return multiple decent cutpoints and to avoid floating-point problems.} \item{use_midpoints}{(logical) If TRUE (default FALSE) the returned optimal cutpoint will be the mean of the optimal cutpoint and the next highest observation (for direction = ">") or the next lowest observation (for direction = "<") which avoids biasing the optimal cutpoint.} \item{...}{Further arguments that will be passed to metric_func or the loess smoother.} } \value{ A tibble with the columns \code{optimal_cutpoint}, the corresponding metric value and \code{roc_curve}, a nested tibble that includes all possible cutoffs and the corresponding numbers of true and false positives / negatives and all corresponding metric values. } \description{ Given a function for computing a metric in \code{metric_func}, these functions smooth the function of metric value per cutpoint using LOESS, then maximize or minimize the metric by selecting an optimal cutpoint. For further details on the LOESS smoothing see \code{?fANCOVA::loess.as}. The \code{metric} function should accept the following inputs: \itemize{ \item \code{tp}: vector of number of true positives \item \code{fp}: vector of number of false positives \item \code{tn}: vector of number of true negatives \item \code{fn}: vector of number of false negatives } } \details{ The above inputs are arrived at by using all unique values in \code{x}, Inf, and -Inf as possible cutpoints for classifying the variable in class. } \examples{ oc <- cutpointr(suicide, dsi, suicide, gender, method = maximize_loess_metric, criterion = "aicc", family = "symmetric", degree = 2, user.span = 0.7, metric = accuracy) plot_metric(oc) oc <- cutpointr(suicide, dsi, suicide, gender, method = minimize_loess_metric, criterion = "aicc", family = "symmetric", degree = 2, user.span = 0.7, metric = misclassification_cost, cost_fp = 1, cost_fn = 10) plot_metric(oc) } \seealso{ Other method functions: \code{\link{maximize_boot_metric}()}, \code{\link{maximize_gam_metric}()}, \code{\link{maximize_metric}()}, \code{\link{maximize_spline_metric}()}, \code{\link{oc_manual}()}, \code{\link{oc_mean}()}, \code{\link{oc_median}()}, \code{\link{oc_youden_kernel}()}, \code{\link{oc_youden_normal}()} } \concept{method functions} cutpointr/man/print.multi_cutpointr.Rd0000644000176200001440000000112713672457720017755 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/print.multi_cutpointr.R \name{print.multi_cutpointr} \alias{print.multi_cutpointr} \title{Print multi_cutpointr objects} \source{ Kirill Müller and Hadley Wickham (2017). tibble: Simple Data Frames. https://CRAN.R-project.org/package=tibble } \usage{ \method{print}{multi_cutpointr}(x, n = Inf, ...) } \arguments{ \item{x}{a multi_cutpointr object.} \item{n}{number of rows to print.} \item{...}{further arguments.} } \description{ Prints the \code{multi_cutpointr} object with infinite width like a \code{tbl_df}. } cutpointr/man/tp.Rd0000644000176200001440000000327513672457720014012 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{tp} \alias{tp} \alias{tn} \alias{fp} \alias{fn} \title{Extract number true / false positives / negatives} \usage{ tp(tp, ...) tn(tn, ...) fp(fp, ...) fn(fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{...}{for capturing additional arguments passed by method.} \item{tn}{(numeric) number of true negatives.} \item{fp}{(numeric) number of false positives.} \item{fn}{(numeric) number of false negatives.} } \description{ Extract the number of true positives (tp), false positives (fp), true negatives (tn), or false negatives (fn). The inputs must be vectors of equal length. Mainly useful for \code{plot_cutpointr}. } \examples{ tp(10, 5, 20, 10) tp(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) fp(10, 5, 20, 10) tn(10, 5, 20, 10) fn(10, 5, 20, 10) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/oc_mean.Rd0000644000176200001440000000255013672457720014763 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/oc_mean.R \name{oc_mean} \alias{oc_mean} \title{Use the sample mean as cutpoint} \usage{ oc_mean(data, x, trim = 0, ...) } \arguments{ \item{data}{A data frame or tibble in which the columns that are given in x and class can be found.} \item{x}{(character) The variable name to be used for classification, e.g. predictions or test values.} \item{trim}{The fraction (0 to 0.5) of observations to be trimmed from each end of x before the mean is computed. Values of trim outside that range are taken as the nearest endpoint.} \item{...}{To capture further arguments that are always passed to the method function by cutpointr. The cutpointr function passes data, x, class, metric_func, direction, pos_class and neg_class to the method function.} } \description{ The sample mean is calculated and returned as the optimal cutpoint. } \examples{ data(suicide) oc_mean(suicide, "dsi") cutpointr(suicide, dsi, suicide, method = oc_mean) } \seealso{ Other method functions: \code{\link{maximize_boot_metric}()}, \code{\link{maximize_gam_metric}()}, \code{\link{maximize_loess_metric}()}, \code{\link{maximize_metric}()}, \code{\link{maximize_spline_metric}()}, \code{\link{oc_manual}()}, \code{\link{oc_median}()}, \code{\link{oc_youden_kernel}()}, \code{\link{oc_youden_normal}()} } \concept{method functions} cutpointr/man/plot_cut_boot.Rd0000644000176200001440000000175013672457720016237 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/plot_cut_boot.R \name{plot_cut_boot} \alias{plot_cut_boot} \title{Plot the bootstrapped distribution of optimal cutpoints from a cutpointr object} \usage{ plot_cut_boot(x, ...) } \arguments{ \item{x}{A cutpointr object.} \item{...}{Additional arguments (unused).} } \description{ Given a cutpointr object this function plots the bootstrapped distribution of optimal cutpoints. \code{cutpointr} has to be run with \code{boot_runs}` > 0 to enable bootstrapping. } \examples{ set.seed(100) opt_cut <- cutpointr(suicide, dsi, suicide, boot_runs = 10) plot_cut_boot(opt_cut) } \seealso{ Other cutpointr plotting functions: \code{\link{plot.cutpointr}()}, \code{\link{plot_cutpointr}()}, \code{\link{plot_metric_boot}()}, \code{\link{plot_metric}()}, \code{\link{plot_precision_recall}()}, \code{\link{plot_roc}()}, \code{\link{plot_sensitivity_specificity}()}, \code{\link{plot_x}()} } \concept{cutpointr plotting functions} cutpointr/man/sum_sens_spec.Rd0000644000176200001440000000332113672457720016225 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{sum_sens_spec} \alias{sum_sens_spec} \title{Calculate the sum of sensitivity and specificity} \usage{ sum_sens_spec(tp, fp, tn, fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate the sum of sensitivity and specificity from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. \cr \cr sensitivity = tp / (tp + fn) \cr specificity = tn / (tn + fp) \cr sum_sens_spec = sensitivity + specificity \cr } \examples{ sum_sens_spec(10, 5, 20, 10) sum_sens_spec(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/oc_median.Rd0000644000176200001440000000226313672457720015301 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/oc_median.R \name{oc_median} \alias{oc_median} \title{Use the sample median as cutpoint} \usage{ oc_median(data, x, ...) } \arguments{ \item{data}{A data frame or tibble in which the columns that are given in x and class can be found.} \item{x}{(character) The variable name to be used for classification, e.g. predictions or test values.} \item{...}{To capture further arguments that are always passed to the method function by cutpointr. The cutpointr function passes data, x, class, metric_func, direction, pos_class and neg_class to the method function.} } \description{ The sample median is calculated and returned as the optimal cutpoint. } \examples{ data(suicide) oc_median(suicide, "dsi") cutpointr(suicide, dsi, suicide, method = oc_median) } \seealso{ Other method functions: \code{\link{maximize_boot_metric}()}, \code{\link{maximize_gam_metric}()}, \code{\link{maximize_loess_metric}()}, \code{\link{maximize_metric}()}, \code{\link{maximize_spline_metric}()}, \code{\link{oc_manual}()}, \code{\link{oc_mean}()}, \code{\link{oc_youden_kernel}()}, \code{\link{oc_youden_normal}()} } \concept{method functions} cutpointr/man/misclassification_cost.Rd0000644000176200001440000000357313672457720020124 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{misclassification_cost} \alias{misclassification_cost} \title{Calculate the misclassification cost} \usage{ misclassification_cost(tp, fp, tn, fn, cost_fp = 1, cost_fn = 1, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{cost_fp}{(numeric) the cost of a false positive} \item{cost_fn}{(numeric) the cost of a false negative} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate the misclassification cost from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. \cr \cr misclassification_cost = cost_fp * fp + cost_fn * fn \cr } \examples{ misclassification_cost(10, 5, 20, 10, cost_fp = 1, cost_fn = 5) misclassification_cost(c(10, 8), c(5, 7), c(20, 12), c(10, 18), cost_fp = 1, cost_fn = 5) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{p_chisquared}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/man/suicide.Rd0000644000176200001440000000247113672457720015011 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/data.R \docType{data} \name{suicide} \alias{suicide} \title{Suicide attempts and DSI sum scores of 532 subjects} \format{ A data frame with 532 rows and 4 variables: \describe{ \item{age}{(numeric) Age of participants in years} \item{gender}{(factor) Gender} \item{dsi}{(numeric) Sum-score (0 = low suicidality, 12 = high suicidality)} \item{suicide}{(factor) Past suicide attempt (no = no attempt, yes = at least one attempt)} } } \source{ von Glischinski, M., Teisman, T., Prinz, S., Gebauer, J., and Hirschfeld, G. (2017). Depressive Symptom Inventory- Suicidality Subscale: Optimal cut points for clinical and non-clinical samples. Clinical Psychology & Psychotherapy } \usage{ suicide } \description{ Various personality and clinical psychological characteristics were assessed as part of an online-study preventing suicide. To identify persons at risk for attempting suicide, various demographic and clinical characteristics were assessed. Depressive Symptom Inventory - Suicidality Subscale (DSA-SS) sum scores and past suicide attempts from 532 subjects are included as a demonstration set to calculate optimal cutpoints. Two additional demographic variables (age, gender) are also included to test for group differences. } \keyword{datasets} cutpointr/man/p_chisquared.Rd0000644000176200001440000000311313672457720016025 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/metrics.R \name{p_chisquared} \alias{p_chisquared} \title{Calculate the p-value of a chi-squared test} \usage{ p_chisquared(tp, fp, tn, fn, ...) } \arguments{ \item{tp}{(numeric) number of true positives.} \item{fp}{(numeric) number of false positives.} \item{tn}{(numeric) number of true negatives.} \item{fn}{(numeric) number of false negatives.} \item{...}{for capturing additional arguments passed by method.} } \description{ Calculate the p-value of a chi-squared test from true positives, false positives, true negatives and false negatives. The inputs must be vectors of equal length. } \examples{ p_chisquared(10, 5, 20, 10) p_chisquared(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) } \seealso{ Other metric functions: \code{\link{F1_score}()}, \code{\link{Jaccard}()}, \code{\link{abs_d_ppv_npv}()}, \code{\link{abs_d_sens_spec}()}, \code{\link{accuracy}()}, \code{\link{cohens_kappa}()}, \code{\link{cutpoint}()}, \code{\link{false_omission_rate}()}, \code{\link{metric_constrain}()}, \code{\link{misclassification_cost}()}, \code{\link{npv}()}, \code{\link{odds_ratio}()}, \code{\link{plr}()}, \code{\link{ppv}()}, \code{\link{precision}()}, \code{\link{prod_ppv_npv}()}, \code{\link{prod_sens_spec}()}, \code{\link{recall}()}, \code{\link{risk_ratio}()}, \code{\link{roc01}()}, \code{\link{sensitivity}()}, \code{\link{specificity}()}, \code{\link{sum_ppv_npv}()}, \code{\link{sum_sens_spec}()}, \code{\link{total_utility}()}, \code{\link{tpr}()}, \code{\link{tp}()}, \code{\link{youden}()} } \concept{metric functions} cutpointr/DESCRIPTION0000644000176200001440000000347614066536752014037 0ustar liggesusersPackage: cutpointr Type: Package Title: Determine and Evaluate Optimal Cutpoints in Binary Classification Tasks Version: 1.1.1 Date: 2021-06-28 Authors@R: person(given = "Christian", family = "Thiele", role = c("cre", "aut"), email = "c.thiele@gmx-topmail.de", comment = c(ORCID = "0000-0002-1156-5117")) Description: Estimate cutpoints that optimize a specified metric in binary classification tasks and validate performance using bootstrapping. Some methods for more robust cutpoint estimation are supported, e.g. a parametric method assuming normal distributions, bootstrapped cutpoints, and smoothing of the metric values per cutpoint using Generalized Additive Models. Various plotting functions are included. For an overview of the package see Thiele and Hirschfeld (2021) . License: GPL-3 URL: https://github.com/thie1e/cutpointr BugReports: https://github.com/thie1e/cutpointr/issues Encoding: UTF-8 LazyData: true Depends: R (>= 3.5.0) LinkingTo: Rcpp Imports: gridExtra (>= 2.2.1), foreach (>= 1.4.3), dplyr (>= 0.8.0), tidyselect (>= 1.1.0), tidyr (>= 1.0.0), purrr (>= 0.3.0), tibble (>= 3.0.0), ggplot2 (>= 3.0.0), Rcpp (>= 0.12.12), stats, utils, rlang (>= 0.4.0) RoxygenNote: 7.1.1 Suggests: KernSmooth (>= 2.23-15), fANCOVA (>= 0.5-1), testthat (>= 1.0.2), doRNG (>= 1.6), doParallel (>= 1.0.11), knitr, rmarkdown, mgcv (>= 1.8), crayon (>= 1.3.4), registry (>= 0.5-1), pkgmaker(>= 0.31.1), vctrs (>= 0.2.4) VignetteBuilder: knitr NeedsCompilation: yes Packaged: 2021-06-28 22:17:51 UTC; Khl4v Author: Christian Thiele [cre, aut] () Maintainer: Christian Thiele Repository: CRAN Date/Publication: 2021-06-29 06:30:02 UTC cutpointr/build/0000755000176200001440000000000014066445216013410 5ustar liggesuserscutpointr/build/vignette.rds0000644000176200001440000000030414066445216015744 0ustar liggesusersb```b`a@&0`b fd`aҼɥ%y%EzA)hpI4 >4Yn$3v J I)k^bnj1~vԂԼ?iN,/AQU▙ 7$apq2݀a>9`~wMI,F(WJbI^ZP?Fcutpointr/tests/0000755000176200001440000000000014066445217013454 5ustar liggesuserscutpointr/tests/testthat/0000755000176200001440000000000014066536752015321 5ustar liggesuserscutpointr/tests/testthat/Rplots.pdf0000644000176200001440000114725213770654577017322 0ustar liggesusers%PDF-1.4 %ρ\r 1 0 obj << /CreationDate (D:20201223155104) /ModDate (D:20201223155104) /Title (R Graphics Output) /Producer (R 4.0.3) /Creator (R) >> endobj 2 0 obj << /Type /Catalog /Pages 3 0 R >> endobj 7 0 obj << /Type /Page /Parent 3 0 R /Contents 8 0 R /Resources 4 0 R >> endobj 8 0 obj << /Length 21 /Filter /FlateDecode >> stream x3TR0TR( ćendstream endobj 9 0 obj << /Type /Page /Parent 3 0 R /Contents 10 0 R /Resources 4 0 R >> endobj 10 0 obj << /Length 1930 /Filter /FlateDecode >> stream xYn[7+ta~lEEk]Y (4S;cHd9]%9!;GJxrKl?]hx.m.J\,x uzo m. e"pl8̯Zގ OkVb0r _/N! UFlBCBŨX޺"Lc!w1!&IfńX% `W2k^K3w옻3wAxE)b Q,BLbUq7rdd". uB~ acB?uYXIN˴xYxAWYRi.R:J7'&*ğXZAB \%N{k /G포mn\4\24\Cba]b4$?XAJ=B`"l reQN&snTPaX=%7 h.a4tf,B ?1 >,#5bP<,="hڐe}/mS1c)083μ}^{)EK!%ɐےdpoöy ֳ k n`7':t46k62CxbyspG6pʞwn>O7͝8\W0QXo'V7QW>=!yM0il..?]bv^smlh7s"=u=Ҷl|ߕ_8ҩ}\rTE¥[" c!fhT58aaMv^4U>#K ( atŮQ1׀)Aiao w9%Dv\"ަA{Xws ;R;)sx0( Akdx4s9y`#5X+fIgmv*B!037ek TxD&VѲhgL.7fKݴsL춀T&D4vיV[>͖ݼE[Ы`%!ѱ^ w\adq猷KxQTNb!E`Mki]\ǂcYf3]h#> endobj 12 0 obj << /Length 1929 /Filter /FlateDecode >> stream xYn[7+ta~lEEk]Y (4S;cHd9] G3sIpHiNhQcPR)zo+_/_bϟ߈BÏJߞn Bqp.^ghtIX-H^f)>f~v,@=XZ+-녆AkzqZ Px(Xe$̶+T<P|[W\q2.&9ɬk6]^!WLJ&c-kisa.!;.]+^3wFe}tCj8$!Xq \*2%˂?1CAؘ%A]1p!,dA2m0E,r,BuD.30^4FvUzTIIJ9'VPP}%5W^BQ#뿾[++7 ШiX_רi8 FhD=ָn'fR)B\zFmT )*hPy0$FJs炯s#\4P&'JBt|B+' 0|O"VOɍb%Kz5]#ˤ>PuOLde$A ORVvQ]tnǤ2„CIvRK)*BKu_&ъJ0Jh\_-ޜVHuYZٕȽ+cMTl-N67ŏg/˞TzG?IKO'>w]/}U)`x~k?ܪ2Ie=I/jR%Iyĺ&$u9Pޖb%\dМT(Llap'fh5nza5@@C2mi|eԆ˞s}]ηU6]6.{ n~<#t*]3&>'19=#ŝHc=lw+}lk%6dفC⋱?xd`Te θƌ3o-/3?3/3/|ռ߿wB;')vZhk6Rc\ /vhP{߻OmGdut{2d<'m®F*Di@;%o Gg#Xov1ѫ 1|[ϯjs'7bu{LFTU,ooq|eL{f/OX\#>Wq.^\6?1n6ТTM/A_]9=#/n%gNe[$\%0oF\if֔QqaEC_a3tрpifNgQs ؝aPqx0_;SBdk'5| mwUy0׀#(U\ 2wsr oFL0?\yűbt_(f"3ySfX{ D*Z팉gl ѻv݄Hn:j\ٲ(|z$7:+K: ,:nv OS+nep,x9qx+?([8 #Ou"endstream endobj 13 0 obj << /Type /Page /Parent 3 0 R /Contents 14 0 R /Resources 4 0 R >> endobj 14 0 obj << /Length 7574 /Filter /FlateDecode >> stream xK$qW\ǖ-XmXC A cE {9'z8VUYQo۟otOIJ/?o>??evq/po uۗO{ߟ2_>῟?=^;v|kS%.vK|_ { n@=k^=skS9> –$72,"3%g $wwy) [(KD^zyLIi$alI)&AY˴VNE7Gj焻y%M#+]w̥-xyhNI) !"/ da5ےǢXCwJnFn~3nɳ[&=4 L$|ˁqrP20IՒGABI;ƑJgu&AU*' d[23 -KtyA~ 6֩ D4M MiwϓShf |.ɟr K|w9}=䠏l4[~^䗢 ivh[ZC_A_~JӪ |DaO~K&%{z#Wu}&A?}$\ ޡ_C7/!^:4gw];M;VC?"o~s9]/oݵxԦHZ@}y'?C},~W &s(}S|OA_"~֪;=Q?5vxz,ϾxvBEצk= M'rzzަ/sgp| 'ϻ@fv ~hzs%iD So`vi&| AŹy3ƯicA/&g"&-SBC"~j؃oRqE%f|Nig?x[Ƞ n DG]MM?¥?zl;'Skk@Nu3W*M ;+Q* -Y5,4Lh{/kCe.UAc xۇ-a~>xP|c))j:{V:+|kUZ!+|'% ~t_o'::sΪwxܬfqz\Ʈo~"~3<v{!.?GyӍRѩNvy=r4rGS^ 7@ڶZ|m+y5H^ _ s]Q̐'lm3EFMܙ#{m>r%S)k}_o_gN ^G_W5_|ŏ}_C|۷+}Vh?hց@W35M~ {'F?2۵LAk>=}g]&=wUbp{.GaVZݨG|>ទmʮ/P6X_<h!A})~5ŏИ7e.m fm*H_=11Y[#g?zr,S\/mk${\ؐ&UYŏx6s^?M|-:os- ~|dFrmt ~h|:t~C}[g#}EG~t} ]e/j5V m?Z-yvՂ'u?=ʿ|>&yɵz{h{k~]#?5/w9^lx?Sk_2= 1?[pM~{K?k?J^hG-~- F>&߮-R] %}:oj_m۠վ6;Zgfÿ.G>jg@ߦw 72I"YӑpY\ev]5_*Ur8ƚ&~s=xM|'j?J$ٳ |U>mxk=C-,8xCuŗxH3ܶF7]Wޟ&ߨx M #.K=afaٮ-~o?_Bqp6Bkgvֻh?0>u}^?2/.t+7oɟjo.a_p64~|a] 1\\-.a}a_LL$}Ɋx0R?xԞ45Z**>,دO5~"4Qd MnJ\| ~Wqo]5m?Ay|e|𻯧_ ~(4xᠹ_ъWv Z@ׇy / 8X,Q]?hcy{rMqs 4oY\JM=qkF}= x4/૎J|6>n;د^|kshHjC/w]@&5`L'ﱖ/}Chsgސ ^Ȯ64 s/U4t_^/4ES}WiFoLۗ3`Eu ]xyUߠoMp7ǻsu?/?5g627Qs*Y >߹B?hGbtEX^# K?=8J,mTU/]t 8U?˿f&~?N)I045Kš_UYhWՃ߅ ?ORw@A #h _>&?sXz=W.Y{,3>X?q?+wbWOch>Va k~'&?%:49\||7^0?!~S> h :&DhWOW7 Xr<n,@+^S!4?*Qk>T}R鮋ꓼ=4Ol46C8U/{[ߣoL{[/`~Ki}^R}cХbOk͠_jV]Tߦxf= m7z^C[% \tB_kվ_;^5G>P e?6Nm{zaWH_.~GvgzzO:ď\5輻&Z9ړoC˿)~4y? ,5&xL^*e?S=,c}W5o/_9?E{u{{%ߊ8l|.*2qNM~=5ů%G-Jyg_]_[D^=}QB=߃^ڜo(Jn?U}<˿O#!UGq<_ro*Kj?QQrыc¦eϛA_?}مwQuwo<P..Z??gF_+z;glo%v8׆07o_ 5\Gb%@a~׃ǃί뷃. |+8~tG#<{\7{}Ͱ6tVi>k?~oo}#x߽'kN>_~/O_Ͽ}o}헷/_~_?x_,~xoo.qϿ4S]j\b)/_ᄇ?v񬎫ܯ?_E`/~LJy+ʟ>^!zw/}V-T.?nϰ>Q+ʫUB&hXE:,J|봘[ŢâƋ櫊JtB#n1YtZH_,lyXZxa!}x:]t8|tܻ?]j"uNr:WSN i>p N f:_cl?髅k./1 aXe$lX-D- Zs8"[_.]ˏl*Y/u7D\/D:~{?7/Z7Ky.};㣿Z}?>˫EG.ÄY59?8xp-3a7W}СRdz? ~kLΏg?еŭot*c]n^|/~V:ru K,* w/z,~K{Dj wcUYendstream endobj 15 0 obj << /Type /Page /Parent 3 0 R /Contents 16 0 R /Resources 4 0 R >> endobj 16 0 obj << /Length 7551 /Filter /FlateDecode >> stream xŜMqﯸKiHH0P()!ʊ);OsfRERTKMsgzk&~˷?tOIJ/?n=wJzWo_=e;n׿47=<᏷t)~oSg7_5~V}ۮo-otߥܮqo}󮷔^%o/r]~臭]e{Ӡz4p yMtڼãmJyn-.szwy5xjvXҗƲҥ]_{ƒ> Z޸5 ƽ)unl.<,um}gkI]+{ՠ{ tb}l^5`}l٤d_{Jֶ_02N J}fI햛$) 2$-$7Ut ?@ 2}$yӐRPD"EI"]lwI]dټ a3:%&ld*I-Iw70^]}/SHlrQGٜ >H^$ѰC!$yG$y f $'hdj o33(3:$yF;/MꪖlAJ$Ԕ$Ź1j)l 27&e \I:xo ķO֡@6$S$ٺH$ٞB$k$PI2ۗdk&IRÚ$(K )m,;i,`6;oRPpen oLlrQLVР V-I='I7]yE6nyt6pMB @){4!90ʩm$j,$i$1.r1DH&IiI<0`lǍE%էK0EQ-i.A6rE9k^0 r6Ǹ$A6DG&Iڜl$]Τ$GI-0%JKH1ITo7I6ItLISI'h-k7gH^ɑ)9idu xs\C䢁cրϔ%jD(9 @ru*?$/lQ$wo&r4$ⳁHdCMcJ푱SɢȏSI7{y.Ĝ&cz~H&If&I~yk|h5xTߘ$5OMeKa+1EV&I6fE3,NY\\4;2Ur˘aM6*BD$W [*drXWEUQL"c4IrIorȘ`jR$-v "Mt&h@)Ē$]I=0䡡auK6w72n$' [z[(kT"7u&%5`-b%c)JYeLkqd䡦S 9\|;2$gXX"$mQAܓRWUD^g-c}ܓK&AIn@2d}n-e&AV(LIrLg"/!̄.In'P q4$Izj"wMvI`yj$yj*_]\%تdMZ,\n$oE&Aؘrydv[Qm.eA$,IrӪmMw%/ZM(yxgX"{L/r14q ^JmQN ۴T] ۲Mg`cpO4AԸ{|<9ef8hkYh&) `}wSYO8~I@_u/9)%J~)4o ɷNwh=p^}?ڻ?yuG_'Jh4S'[M͵ 1_~R%K:~v_ٵt|3[g?#7Ο~];ߟGm4;io~*{QpO1Mk~:=<4_wE=_i=M~ ^7544{.gʡ޿ss / ^]}a ~^WǢqla't^wm&Ӝ{8+mi0.~vǺp ~ 4Hof'fW?TF ?Nf眖kgNNat^w9k6>&z4bXk~*rhK?E,4$́视=+%XZo_vFm~[ oSMŏ rM=OtT4)\3 ήf |=m`oT7{ګaqےE_ZGin˄B7QRO>> 4=W-ͽ}8rG 7昒,ꯦgk#o+VGz[O@gv 3笺j]xe~߸kI5 3t9n:N-Dԕpq>8y<*er"#ʼje7}'[ZŸ<{X`{p}R'iD9,$uƎzj@bP4nju1({:KkiMٴ6# bq>-L?|kl|/- yh:ɇWh|ʫFH^Vϣm%pCɫA083CV,5sgAkkNX|Ϳ}9)&{}__|W?|}_mg_-ZϾ^[7 Y]e4+v瓟|I;:lƇzl0y` :' >̟Aw"RWUVYRhw{F)&UOF?3sM󹪆M{4}{7vwyep}׿Z fPXi0`b@`b 8+c?^KM~7=?Ccߔ M~|Ęx\(gmH=>KɱOqLq*NjsEcCBd-ϛٶ<#[`l#_3or/O |L{HVXfmf=݇C~{ồkoI6>n$4,w_Mv{Vf?򓳊_*~{Mn6"dݶ4=E6NɵulNC575'u9oGe3ď|˜h)~vISs͜{c85-d-M.5_L۠s~׿şq}[o??[,ՁβOo_33W?4]e|4şmq_||bYUď 9{zY-txX5߫_hOV \[ǧ+zx'3ukZC?XC|mD,{5*ZSO)~DC+xlB*5-#ZK'%+y?3x"Ku-j輩oNoVn6 hMGH]\y~گ7߽"3pܜ/F$i#f3MGeEs > u|xxW&y>kV|n5+q|((qRd736mwBWC̷1~cW{Z\?y i?_z#pޟ&:lv]{/z&)43+J\h>.z=;֣fM>Lc M~쯙6>ןZp\'U{\˼Эp&0Vsu/sQ{sa{p}}C [g/3Q{_0`%+eKQRC_<DC_hR{B_Î_jת`Z/?G%4;ڻ)q14_~tQs4) ~[񩗕゙FG~4ףㅃ|UK^4ZF+^-5j}]_408c)~Gunv W"h"5^́eq *џ6ox"_i04+rп@:*im|=cz#Ư ϡ_# m|Jwmox1y> ZrkџQXSvC.zSr*.دz"_ۀ/̅TW7Q`zA\On_庫 ^^2qo_&PCQǫ*v >V5W‘z 5UHbVwߟ-ȯ?Gͩ}f:/Sh7~ H9ѹ:\zc9z|4c/cK|[(SUtk=4_ DT,4;$ߚ&d//Ug_?W.?]K{Eد+oϏpM/{D?b|_=Xl[PgCh h`q{މ?_=YX5* h>|&{Bԗ+ozhsYXzM,h=( a[@_a?_>(`=`h<xMl'«DSI.OX fW?XVTm[<-~1Cmk-ͿKzIa\Av֋A?=>I|7I[~tQ}❚18){m-Nϗz>hk|(p}5{3 |W|ZC;_x^+TBz'hT<ش;Zгy?_#?|S={.~?_?s׸_vkhO!-^I2Û`]2z#|DO]xK׳ď]]׸%qLD?zo[ukS+~WIJ麨ȼqS;5+w1)n|u~mQ{9rF |zise(T(.N?E$7"w A"[[${N$Oo*l"/&Cl7lCυ\Si Cr^al=$S4IrX0Ir82Irc]}cՑLlj$y}aƏI$KO&Soa [\lr; 䜽.sּ`lqIlRt\5L\%M99,I|I3HP$w[!ar7JN0bn%m阒䥧0[O|-[>$%o *#Sr4 r*&A6|mL$E$E)Krդ0QrUd %I_FHVM7hHg%ֽ$Û14-ǔ$#cu&/Er$/o.]%9M6ML!<Ќk<1I6k$W9&90Wc5LEm2-,fXÝ$hv69e<1rmU.IU.䐱j\oDvh&=M1]Բz'4IrW[@rE$L6 *ЀS0%Iz${(45Ir1h&|HN@&@ PDEnL/?Jr?%kZJrRʘ.$C$CMhr$Ovd0*euIϰ&E4GIۢ$y)2'$[>$0'-Lܓ|Ádk182Z `!9LP䢙$EiU_dC 9\4BOJhH>}$wDX3"+$.Ԁ5IT ,J=αU1Xv&Iފ6M<<1iv "Y %ȣ(\ʂ(UEI)YUۚ"7*Kd_$Q%ΰDp-_b.iDlֽ$o=&ۢ.AiyF7JܽK$&yU& Ա qG2IrSgId6j"͡&I&GdKK=זz 1 2ĔcKlMQH6ɇ\B2QEda"=x rITKO3Q)I8d<- 9$;kݪ Hp7/r$ib .o")/S#eW[2DC%,4fv`[XkNmV\o-yv䀱&WIdp90XJF&IٿZ(^(rv8[0"{$ȶJD!lTF}&Ae).#0Ϡ:54h&q< 4yrpֲLzA%4Sz~B9"糞q x@_r/SKR4x7.mqz+Uksh"6hk}ZiZUA4ABo(r){dO`w⏸.OO;hOd?ksA;4+c3K]O#t쮝k|g hG-o?%!v?|)Sh}}v>U]8cu<'zxh򻏿v{_{"oj@i2h\ZC"9*}_|?BE38NtM9$pVNZ4E`]uћyḫO@~3ة?hA~ 9-wSϜ49$87еs&5m|L?hŰQC,T%~YhH7/O {-VJ=αL1A/|Dz訋igsSg]z{j-rȩnO)bWaG:8|%J%ڿ0o#\= ~q|oH=̥||>h{Z{p2?o#o1%%X_Mg uW_GBwV~J+d$/ډ#][GgYu,>q;73j`grs=8,uZQ+d|.qxTEG(y+#o,Oؕ>܅?yp0p}nL2ƅbN>-\rYH^0̍2`˝Šdi#b 5~SQZtD*^;6ⷳimF}Z,ɟ?t;*-9_Z|tW0GJ^ .Wa qrgXsRM? +~;۾Ͼ^[|ϵB}ַ1n@ʞhW='?|5ɯw0u5خ` ZtNc}6?E43~﹫hs9* ЊF? lSvM~9*~gF4_FLShg%Wqᕸ>|]D{wG7;v n{}_3m|?5E^O yq[|MT{sa … - ^oq Ϟ_f`"KVăٗx<;4&)UɯUa~^~5"KhwwSch𛿊~&DhoS S/+}=~"hG 5&<hdύVZTkG.>ϓ%hxa(qR ;~x#gB? \T]_REv /^ ~/͟oR|!.ڟuܿJuW-6X=xKe޾L;.>WU0|5* ~kگ#A>ޝky1a?[_1S:t_wo@@?rs?u.orhnj_;Qb m }צ{h@rY53iwJI⇿5M燡Ȯ_^* BدoW.\q?~&?旒34 *_=XWߞDX_ P941"3`zPpcA\Yt-4`zC kXU8]xU=y}4^?MAb*zx[{c"xK[Mﻗø.&z|X^o=e/R線6;5chqSZd~/|Pkg>::^5vW]ӣ!~:įqxG=,4:ў|CZN?qe` 7ǻ{e"5G|U.+柺<=g뻺įq}K~1޶)ړv৘++VeuQyvj/~-?m1Wc>SJڢD'rt,|GQqz'Q]~ xT:<3-~Sq\UK݈j2^.6o,lZo_\Hx'5Q_~-߾涏O)ⲭu/^>I޾?|nR~蝛_nYppf;Y?*nCn W{чX P_AqAqAq G7. :_?!O9*gmV.g)Gv.fMzXrg&NϲzvO:WZ{w;_K.vkݥ.?] ׺KqZvt^n,}YS?rߠXFf ۇu[¥^'<{-~ɋNy2_N~r{ϓ[kO?]>tJ~RXUɏUWJ~RXUɏU*Jh~}<5WnoWvI}{2E=ȺekggDO~_}˓<|yg(g'B.뿇n5ᥳ2xLYᓿ}z'_~ׯ?_>\vrp^?5o|{vחwx/?|pn_x_>x,_xn.~{헯^}fKK]?w_}Ǯ2q_}gKodo_ 3t~Chvyw~ގ_wV^>2iFò(aQ\z$,/U/>5^6_UTʧ}Fv͢Bbf  cGuyW uR֑Z4rZHu酳uXlpZH_-6ѧ3gI_-𰐾X\38otQo} /#a _>nrl$jWim8?xlYѻtq.?{d#<^o&F_u&~o^>oxj=m}ѝ >{/>bJ(144Ug3yAby%BvQ|[ֈ>ķ,B_sc"FX_^-?>'grǗ9gŃs~pnqX<8_'uWJe=wt wtmq+rݯzļgg7/a1WWp?˫{WXĸ{\([[mabn,:qendstream endobj 19 0 obj << /Type /Page /Parent 3 0 R /Contents 20 0 R /Resources 4 0 R >> endobj 20 0 obj << /Length 7551 /Filter /FlateDecode >> stream xŜMqﯸKiHH0P()!ʊ);OsfRERTKMsgzk&~˷?tOIJ/?n=wJzWo_=e;n׿47=<᏷t)~oSg7_5~V}ۮo-otߥܮqo}󮷔^%o/r]~臭]e{Ӡz4p yMtڼãmJyn-.szwy5xjvXҗƲҥ]_{ƒ> Z޸5 ƽ)unl.<,um}gkI]+{ՠ{ tb}l^5`}l٤d_{Jֶ_02N J}fI햛$) 2$-$7Ut ?@ 2}$yӐRPD"EI"]lwI]dټ a3:%&ld*I-Iw70^]}/SHlrQGٜ >H^$ѰC!$yG$y f $'hdj o33(3:$yF;/MꪖlAJ$Ԕ$Ź1j)l 27&e \I:xo ķO֡@6$S$ٺH$ٞB$k$PI2ۗdk&IRÚ$(K )m,;i,`6;oRPpen oLlrQLVР V-I='I7]yE6nyt6pMB @){4!90ʩm$j,$i$1.r1DH&IiI<0`lǍE%էK0EQ-i.A6rE9k^0 r6Ǹ$A6DG&Iڜl$]Τ$GI-0%JKH1ITo7I6ItLISI'h-k7gH^ɑ)9idu xs\C䢁cրϔ%jD(9 @ru*?$/lQ$wo&r4$ⳁHdCMcJ푱SɢȏSI7{y.Ĝ&cz~H&If&I~yk|h5xTߘ$5OMeKa+1EV&I6fE3,NY\\4;2Ur˘aM6*BD$W [*drXWEUQL"c4IrIorȘ`jR$-v "Mt&h@)Ē$]I=0䡡auK6w72n$' [z[(kT"7u&%5`-b%c)JYeLkqd䡦S 9\|;2$gXX"$mQAܓRWUD^g-c}ܓK&AIn@2d}n-e&AV(LIrLg"/!̄.In'P q4$Izj"wMvI`yj$yj*_]\%تdMZ,\n$oE&Aؘrydv[Qm.eA$,IrӪmMw%/ZM(yxgX"{L/r14q ^JmQN ۴T] ۲Mg`cpO4AԸ{|<9ef8hkYh&) `}wSYO8~I@_u/9)%J~)4o ɷNwh=p^}?ڻ?yuG_'Jh4S'[M͵ 1_~R%K:~v_ٵt|3[g?#7Ο~];ߟGm4;io~*{QpO1Mk~:=<4_wE=_i=M~ ^7544{.gʡ޿ss / ^]}a ~^WǢqla't^wm&Ӝ{8+mi0.~vǺp ~ 4Hof'fW?TF ?Nf眖kgNNat^w9k6>&z4bXk~*rhK?E,4$́视=+%XZo_vFm~[ oSMŏ rM=OtT4)\3 ήf |=m`oT7{ګaqےE_ZGin˄B7QRO>> 4=W-ͽ}8rG 7昒,ꯦgk#o+VGz[O@gv 3笺j]xe~߸kI5 3t9n:N-Dԕpq>8y<*er"#ʼje7}'[ZŸ<{X`{p}R'iD9,$uƎzj@bP4nju1({:KkiMٴ6# bq>-L?|kl|/- yh:ɇWh|ʫFH^Vϣm%pCɫA083CV,5sgAkkNX|Ϳ}9)&{}__|W?|}_mg_-ZϾ^[7 Y]e4+v瓟|I;:lƇzl0y` :' >̟Aw"RWUVYRhw{F)&UOF?3sM󹪆M{4}{7vwyep}׿Z fPXi0`b@`b 8+c?^KM~7=?Ccߔ M~|Ęx\(gmH=>KɱOqLq*NjsEcCBd-ϛٶ<#[`l#_3or/O |L{HVXfmf=݇C~{ồkoI6>n$4,w_Mv{Vf?򓳊_*~{Mn6"dݶ4=E6NɵulNC575'u9oGe3ď|˜h)~vISs͜{c85-d-M.5_L۠s~׿şq}[o??[,ՁβOo_33W?4]e|4şmq_||bYUď 9{zY-txX5߫_hOV \[ǧ+zx'3ukZC?XC|mD,{5*ZSO)~DC+xlB*5-#ZK'%+y?3x"Ku-j輩oNoVn6 hMGH]\y~گ7߽"3pܜ/F$i#f3MGeEs > u|xxW&y>kV|n5+q|((qRd736mwBWC̷1~cW{Z\?y i?_z#pޟ&:lv]{/z&)43+J\h>.z=;֣fM>Lc M~쯙6>ןZp\'U{\˼Эp&0Vsu/sQ{sa{p}}C [g/3Q{_0`%+eKQRC_<DC_hR{B_Î_jת`Z/?G%4;ڻ)q14_~tQs4) ~[񩗕゙FG~4ףㅃ|UK^4ZF+^-5j}]_408c)~Gunv W"h"5^́eq *џ6ox"_i04+rп@:*im|=cz#Ư ϡ_# m|Jwmox1y> ZrkџQXSvC.zSr*.دz"_ۀ/̅TW7Q`zA\On_庫 ^^2qo_&PCQǫ*v >V5W‘z 5UHbVwߟ-ȯ?Gͩ}f:/Sh7~ H9ѹ:\zc9z|4c/cK|[(SUtk=4_ DT,4;$ߚ&d//Ug_?W.?]K{Eد+oϏpM/{D?b|_=Xl[PgCh h`q{މ?_=YX5* h>|&{Bԗ+ozhsYXzM,h=( a[@_a?_>(`=`h<xMl'«DSI.OX fW?XVTm[<-~1Cmk-ͿKzIa\Av֋A?=>I|7I[~tQ}❚18){m-Nϗz>hk|(p}5{3 |W|ZC;_x^+TBz'hT<ش;Zгy?_#?|S={.~?_?s׸_vkhO!-^I2Û`]2z#|DO]xK׳ď]]׸%qLD?zo[ukS+~WIJ麨ȼqS;5+w1)n|u~mQ{9rF |zise(T(.N?E$7"w A"[[${N$Oo*l"/&Cl7lCυ\Si Cr^al=$S4IrX0Ir82Irc]}cՑLlj$y}aƏI$KO&Soa [\lr; 䜽.sּ`lqIlRt\5L\%M99,I|I3HP$w[!ar7JN0bn%m阒䥧0[O|-[>$%o *#Sr4 r*&A6|mL$E$E)Krդ0QrUd %I_FHVM7hHg%ֽ$Û14-ǔ$#cu&/Er$/o.]%9M6ML!<Ќk<1I6k$W9&90Wc5LEm2-,fXÝ$hv69e<1rmU.IU.䐱j\oDvh&=M1]Բz'4IrW[@rE$L6 *ЀS0%Iz${(45Ir1h&|HN@&@ PDEnL/?Jr?%kZJrRʘ.$C$CMhr$Ovd0*euIϰ&E4GIۢ$y)2'$[>$0'-Lܓ|Ádk182Z `!9LP䢙$EiU_dC 9\4BOJhH>}$wDX3"+$.Ԁ5IT ,J=αU1Xv&Iފ6M<<1iv "Y %ȣ(\ʂ(UEI)YUۚ"7*Kd_$Q%ΰDp-_b.iDlֽ$o=&ۢ.AiyF7JܽK$&yU& Ա qG2IrSgId6j"͡&I&GdKK=זz 1 2ĔcKlMQH6ɇ\B2QEda"=x rITKO3Q)I8d<- 9$;kݪ Hp7/r$ib .o")/S#eW[2DC%,4fv`[XkNmV\o-yv䀱&WIdp90XJF&IٿZ(^(rv8[0"{$ȶJD!lTF}&Ae).#0Ϡ:54h&q< 4yrpֲLzA%4Sz~B9"糞q x@_r/SKR4x7.mqz+Uksh"6hk}ZiZUA4ABo(r){dO`w⏸.OO;hOd?ksA;4+c3K]O#t쮝k|g hG-o?%!v?|)Sh}}v>U]8cu<'zxh򻏿v{_{"oj@i2h\ZC"9*}_|?BE38NtM9$pVNZ4E`]uћyḫO@~3ة?hA~ 9-wSϜ49$87еs&5m|L?hŰQC,T%~YhH7/O {-VJ=αL1A/|Dz訋igsSg]z{j-rȩnO)bWaG:8|%J%ڿ0o#\= ~q|oH=̥||>h{Z{p2?o#o1%%X_Mg uW_GBwV~J+d$/ډ#][GgYu,>q;73j`grs=8,uZQ+d|.qxTEG(y+#o,Oؕ>܅?yp0p}nL2ƅbN>-\rYH^0̍2`˝Šdi#b 5~SQZtD*^;6ⷳimF}Z,ɟ?t;*-9_Z|tW0GJ^ .Wa qrgXsRM? +~;۾Ͼ^[|ϵB}ַ1n@ʞhW='?|5ɯw0u5خ` ZtNc}6?E43~﹫hs9* ЊF? lSvM~9*~gF4_FLShg%Wqᕸ>|]D{wG7;v n{}_3m|?5E^O yq[|MT{sa … - ^oq Ϟ_f`"KVăٗx<;4&)UɯUa~^~5"KhwwSch𛿊~&DhoS S/+}=~"hG 5&<hdύVZTkG.>ϓ%hxa(qR ;~x#gB? \T]_REv /^ ~/͟oR|!.ڟuܿJuW-6X=xKe޾L;.>WU0|5* ~kگ#A>ޝky1a?[_1S:t_wo@@?rs?u.orhnj_;Qb m }צ{h@rY53iwJI⇿5M燡Ȯ_^* BدoW.\q?~&?旒34 *_=XWߞDX_ P941"3`zPpcA\Yt-4`zC kXU8]xU=y}4^?MAb*zx[{c"xK[Mﻗø.&z|X^o=e/R線6;5chqSZd~/|Pkg>::^5vW]ӣ!~:įqxG=,4:ў|CZN?qe` 7ǻ{e"5G|U.+柺<=g뻺įq}K~1޶)ړv৘++VeuQyvj/~-?m1Wc>SJڢD'rt,|GQqz'Q]~ xT:<3-~Sq\UK݈j2^.6o,lZo_\Hx'5Q_~-߾涏O)ⲭu/^>I޾?|nR~蝛_nYppf;Y?*nCn W{чX P_AqAqAq G7. :_?!O9*gmV.g)Gv.fMzXrg&NϲzvO:WZ{w;_K.vkݥ.?] ׺KqZvt^n,}YS?rߠXFf ۇu[¥^'<{-~ɋNy2_N~r{ϓ[kO?]>tJ~RXUɏUWJ~RXUɏU*Jh~}<5WnoWvI}{2E=ȺekggDO~_}˓<|yg(g'B.뿇n5ᥳ2xLYᓿ}z'_~ׯ?_>\vrp^?5o|{vחwx/?|pn_x_>x,_xn.~{헯^}fKK]?w_}Ǯ2q_}gKodo_ 3t~Chvyw~ގ_wV^>2iFò(aQ\z$,/U/>5^6_UTʧ}Fv͢Bbf  cGuyW uR֑Z4rZHu酳uXlpZH_-6ѧ3gI_-𰐾X\38otQo} /#a _>nrl$jWim8?xlYѻtq.?{d#<^o&F_u&~o^>oxj=m}ѝ >{/>bJ(144Ug3yAby%BvQ|[ֈ>ķ,B_sc"FX_^-?>'grǗ9gŃs~pnqX<8_'uWJe=wt wtmq+rݯzļgg7/a1WWp?˫{WXĸ{\([[mabn,:qendstream endobj 23 0 obj << /Type /Page /Parent 3 0 R /Contents 24 0 R /Resources 4 0 R >> endobj 24 0 obj << /Length 7554 /Filter /FlateDecode >> stream xŜMqﯸKiHH0P()!ʊ);OsfRERTéyLOwuuuo?ۻwKG_Y_~l2<~ f~/y?n_=?=e^??}ƿ?{|~\sn5wz_ֲS}E.v67zKyK[Oq_)}Op^yiPVq> N0hKWj<</]]taqXr8qqW{.!yif/%}i,+]Zʼzi,Ӡ< \`ٚR[撺RqԵҼKkJ^ JqH^ K'o-K-BsrOtZԉDI,Ir?0%Aіٞ{㹅f=Jn(AF${S`Ud!I]K. rl UU!0,{FQU%I%IJ<=IMn? } ]Qɣk$9vܝE&wT  c)&I&I^&I^)I^z #גcM\ɫ292%'M bdvΔkH\4pL\r$WM%_Hn\EQr$eT8mD~D|6Pl{H<C~LI=26]yj2Yq*7If"/yE^rdLos[$[$"o̓͸OdIrucɘ s)}%0Y$Y^f,ch<)KfgSƣJn3,IF[EOa\L몶՟* Idw&In3ML-[wB$w5$w]Id1 H>X27IǓ<44Lb`n&CӍ<\EzFp6Ud MO72^nl \-D^Nn 뚛Ka6"oyQ$o &G2~:C'V d ZaP$9 dLZ[֪$Yc\)"X)rQa$Ks.BS$W)I&m‡drXteM[䦸$\E$w,E)rM<4LHl/í$ )I.L\VE6%M#!7IrW[M5.P2I"O X$OM嫋ˢ$[UIkmh$6An n+P<ͥ,RU$ۜ%InZ)rDEIZ" Kd yE.F4yaKIVc-dKgtݛK$KlWe)@ 27y$$7uDn39-,j)krtJ;4`ԃmJj ALI1$6td|([ !-IneXDfJ&IZ*S@P.$OE7UHؒ oSLiݭڝnj? wb!KF(V09[L[&!Мb<5R6=q.C=D^rABxkf7i%E&l%fXݒgL{hrʙ$IxdDaᏛ%p텒.kw/# cϞ-LlTN d[23 -KtyA~ 6֩ D4M MiwϓShf |.ɟr K|w9}=䠏l4[~^䗢 ivh[ZC_A_~JӪ |DaO~K&%{z#Wu}&A?}$\ ޡ_C7/!^:4gw];M;VC?"o~s9]/oݵxHZ@y'?C},~W &s(}S|OA_"~֪;=Q?5vxz,ϾxvBEצk= M'rzzަ/sgp| 'ϻ@fv ~hzsN%iD Sodvi&| AŹy3ƯicA/&g"&-SBC"~j؃oRqE%f|ig?x[Ƞ n DG]MM?¥?zl;'Skk@Nu3W*M ;+Q* -Y5,4Lh{/kCe.UAc xۇ-a~>xP|c))j:{V:+|kUZ!+|'5 ~tN_o'::sΪ{xܬfمq~\vIT=N<aBԏJ]'s9SǣR&w.>B[IVcg|®.Yσ[vg:-\_,1.  .uiHLBZanh![< $/%+O.Yɟ&VٴMk3 \_-byNl÷WiҲ狦|h|<Ƨ,om竑O~vm|hgZfϠsr`t./%ɟ{E|]e@+ܞQi-V|7ngdk?QŏdTc=3>?į>jZįG߷/cwwξWۧ| M`V jZ&  &֠kh$׍dUm&f}f3ߝͰ]?|K?4̷Vv#9>~fzor'7޳_=7UsV&~kgw O'm/̷qHcs ~Pǀq>ׯs}!~5o޿?-s!~[D{NϰKҨSoըɨ o&mEnrb2|ϸ-[ŏxNOft} M~鞩_5-џW߷m/*{Vw$/WhSȪ5x\E"~WqU|ӃβoW êW^5~-G?/|Z:>_Ճ;?v_~|o|ͯk_Gn;'b˟WКG~jMk_&G_#?g RQ=~oZG>y-G^ Mŏş۵_kADWCM3v|w3X@l:B|G,3~Yo|1x7_&I]_748o:.+kLخKû*5Q^Xo?v5]DCG${!Q|oc*gp=oͰӾ{}cN /x4f$31Oɟߗ^aąW@v=߱865mwgKX(Fhcʹ̮zz=.B^Ņne 4Sͅ1 fƏ/K0x!fڛ s{Ņ;컞/K\>{~/Y/f_O\ @_|vRKW%VŇz&WO?,MKo*M'h:Ot~4:/4_? ђ=7ZjQݮU?OᅡK4E>skgU ~A?v^2n.kW7"Nsܨ_1||QIomgՋ/0@5~M^xmImh㥔\Pk|ӤƛQ=֒㥏T\= ~š·34rћSw~uK5xa.4*4K]< hus*-]Ub-{2q8^Uk/O෪4ixw@lF~=A8jN3бB=;WhGR XhkC3~G^G%- ^'g/)%4#y84*? j>azp]p_Jo.(PT~`}^!{~mb}#B|PϠbC…:BcaFs'gNz *aUtMO@UA{4ğ_'?^y?gC@F &?ogA?AaX'?ܲM )FC_hk*dC=^%jGpO*uQ}_0&zǷꥺ~oo{o?_,oi5M^"Kz ^ aM{KM/j,珡Y?W\O٫hkv}A;_C;Xx ڷz>xK_Hէ;ALǦީM|ׂ]3*]aߣȟ.~v[\OZџ_?G{ yh:O?oǕ%[` WU廬'X%~-e"?xhOC]b~|['OEE=کɯ&$~v0_4;Lw+5kˡϗ5JH{K-EgꝼGPtw)Qu"H< K^MqW-GXt#5\.zһؼiٳy~͠o>B;ᨉ:䗏on\\N7'z/>ڍVvs-k\._~'Gmȭj?<~!(V_>|FnP~ElP~DjP~CѠ8 7Ox4tʇze^3l#o;_Iw=wprnz],[9MxsgYe}=r'֫qǯwRRi .vkݥ8~-U:/7^y,ũo?#Uۇu`:{f-NR}Gey{\T'ɇQǏO>|<~|w3㳓_|sC7Y<>ي/ן﯏~c]A;9L8|w^7>={;?Ë_~{{~}W^/E[sOkt?w7=W>N3ڥ˥.֟R黯kî2q_}g y|{h/_ :!\Y DP}\Q?HoGů;+/V 4aY}(mbnF/B**ݾ X#fi!}kaj#D w:qzswB:GH_-O9-::k,68-B~ó^BxXH_,7Ăzc/a1[4ZsZs8"[/z.u6s|u? D< ѿ_ď͋ Og>M/v<_gO3GL %w_l&"H,D;_{6"0xK?Z Eaw>Ky.};㣿Z}?>˫EG>Y59?8xp-3a7WСRdz}\{?a39?-n^~Ӡ5WC~p7t> X^UǟqyooYb zϑ _k-,\lލEG]O 7 endstream endobj 25 0 obj << /Type /Page /Parent 3 0 R /Contents 26 0 R /Resources 4 0 R >> endobj 26 0 obj << /Length 22994 /Filter /FlateDecode >> stream xͮ&q$Bْ+\ h!hisI(69¼Gz)VW>Uf~_?}o^1WSy^?/_WÏo?uVx~~'N'kLJWxC|tQ>|i~9׏sZkƏ933+՗QXFFELcIo>?iWsh0٘?z;A{琎:bϫ;SNY֕ا<^_{sclIa}Yp]a2ລhV:}p&5V}<p?&WX”ܷʛ(r"S8侙7Z]')Lr40}W+h]-:+3 q}'iX1J}~p(ۺjJ>ncg2c^Q׷ u\>X}Q\}s`њ hkCӵճ\/6W#Ŕv1DOպoHq#;FFaYCg>y1& 2Gx!up5p juuCF `_ tCF {5oHsƙ7PXџ ڳK*Z]b6չBosʭ+YfR44EQ~mَрVӈ%I@) hu1Z6l0Fz-U:МН׀Yg*AѺbDiX6\h5XV%.T{. f\FoTxlBx?&C}"c!+ &OVI.xlu-"zTeYb+fUlQ'&^_-geR{ײC  53 wY(K<6~% z? ErF]Yi_b{Y"P~jw*CߏkqC/ť=в9h8A,m@ތ(* h9Zh! -[RN@ &3;[܀֗[\[bh5:jZ6f#-[/P+@ǀ-XhBf -t,Gƻ5/Y6hYB$%ɲڗ,hY0d>3EYHKUmEː>hyeкE2֠V]Ŧ6 Wbdx,N#x,̌ MY,V?5 1Y T .+n0ndirTu?~ SS_]cPOI6]8e{ZTtA0'L p0 㤵μvY>w)Z፪4>K_#QI4.WUq$KmY~\f* Zɦ]՞/kRXy jEUNn+vi$.,oCvI_aD2_U`8!JN톴c iikWWMMt} zݷsVRC!.Wo/tŪVEbxt+9hѯqI] )VL xL}e:rm)N $YDeĸ{bM.#m&8/㙵zBop<*\g[m\b[Y{8pBqmŵRGe}_&Li.8 `9Ƣ6YwNdN0cl ն/(9h>/(mY~G kK-(ؽ$AȂST׶zlYHSs[י,5ѧۓY$.Ru-(& :K8Uly8} #rX{>vt<X%Վa5ߩq c?`,pNw#c9`,-NwߨG8`)lွp&16zX{9UÔk=`Ojk>`U\q0p8oSO`,〭pNn`,-Nߡ^X<`WqjXZ۫5!)+=z{]a<#JmUJJmÜPZ#p^w?u1ny{oqnMwk[}u[Ww[u[>:mh8aut!y p~7of(nf027@͸L_< a6՛ɽ䛹;7qs"7ss@{9wnn4zsY\Ӏ$6M?ncrؼ&E)mBi&rimx"65M\oc{6MoSc~ƿߖmp,.`oZL߷ZLl逥۫kv- z{z׶W{Ѻwm{W{ak K kpث:лv+,ϸsl\*O..rv 98υb|BΙ1t!gsdc]&ƿ.frv 񶍪w`9l{9煸F#r qH-Br9;xCa!κQ6YB\!g(zG8C sR[oA!*wr yA!@ 8l S ᐳ3 0rhP9!7y␳/ jrCξrJ9B!g_@e9H0}}s= rCs09q I鐳/C7ՀHuP97v h_a쐳/ v09!e; vS/{/ӻ2{һ/{/ӻ2{tACξ E!e\ᐳ/Hpy$t8 RAr^I$9T+94294}ACξ !g_2H'r$"9 RrO9/)}A•!dc9 r^`91A֙Cξ _!e搳/HRsyd9 #e琳/Hܨz/C}ArC q "r^9LACξ !e+ꐳ/1uy: rZr^9ZACξ g!e됳/vb[쐳/Ivb쐳/́/̝/̹/6Խa}anaN s/ s/ s Ue3!g_k!eQ9/}A-F{ 8 jr^5%o_P+2pflAMCξ!ePC␳/=qyԬ8 j]r^529AUCξ!eP 䐳/!ryT9 r^O9Z)ACξ>!7-{}9 r^f9"5AyCξ0!ePR琳/(sy9 r^9CACξ!eP"鐳/(tye: :r^weC?]?ԋ>OS/ԋ>OS/ԋ>OS/ԋ>OS/ԋ>OS/ԋ>OOS/`E|E=|E=^ܾWI| {u Jjt,8M B(˵2ؚ0:6cotl&E:6c btl!+L:%[ [6: ltlcYc_&W>Fck!/:֣ck!:2H:ꒋt)бIޗi}tcktletlRtF|m:LIJK*[ &ck kӱ†9:2G:f>ؚN#{j2(ؚcckҖtlMӓ ұ;צc+IMұQLұfб5/4£=*4VX;] Ԑ'kpA7*)+AAVe` / [yT\7 !);+tƕ6~V`% +Ia, E1d Z /.AJeei֋մ2V:vrGN{UHJCJBV`kH$o5Ą J}xYY X /}"4^Rp;RV YhAMP+HpDZW }12VH' p"#}@H)G+б#_MI|3f 7Hq+i_qm &r}Q=”I ]b/ct[+| ,*x+0ז+Cu1u5?䭸4[+0ZWbl^%F@ dpŵ%#ٔXxr ZZm@P}uIlr;)ߚ6,-5J TW zFBqmӛ*|(^ᵙdf1N.WUbL@b@2k3"]V^[R %3F7U8/2vXe0ӛ*h0k3M2 8`zwӁM 2ӛ%ӛCW y|TѽF* Lo{ӫ6Dx_՘=ڈ\f2W{{~ӫc<}'8 aE+1WG(asځ $o;.W-e7@+ӫfP 1X`hs ,&^5BګN8p_0՘I`'a$L2W`!`zAӫeL~1j˘^\n}u~@# y"O.`"iWPpF]2W :2 ˘^Vӫ0][%[q_u`zӫbz1 ˘ zu-`zo^dk L^}2W!܊Aӫbzw`z՗1}˘^$;sj^uVBa ӛ8$ӛȲM:^tv Ư~_2^Y3Wb/ ,5?1^Pi_ܮ+Sثh,2_ %{| _`c5Ae_.Xq1+]qm>2 tHy - 4-@Q *8Zf ` /#Oi% @ ݅ґtYٯV^-VV.f<1`A <*JʋV:Ge*"h(WnXIVbcA`HjW ICO~xrJD~X4.s5V 䇧c%K¤$d #%󿡕K084WLÓÓ2g1^ZY}upd̘ U F|W˜~3~x2M~xlJbJ7R~xF^:~xF{Hg$ Fqktx20,Óaߌ΀[F6Ã~$itW<}niPU}_G%[Ʈf?w?3~X}&̚i*$TKRP~xT{A4NãZV~x0H~xT{Hd'.&S![1AO~x>aIȬRÖC~Xfspj>ÖD~rL[X(Ø?<$|Ãe Ób@85hy0~3~x0F~xD6,1 #?l5䇭t``T#s Rr`p1 E &ZRaK"?lu<"䇧3a.-af?<O,faN XJ?<ǂY*d ~xZkL1 sc`'$?l^'?U~$Ik;c߼OOs'}OOs'?O^|+ps 37[9 g=̓8s(qz0/c|Q@Õ?BW r;AsR !_e#F.c};y;rrLRȫ ):\W2gxz>8˜d2bĄ9E*7b(Hi;.خfY[xFJ7Nlj:ep^UvwEvǠiٝ7gCgԱOmʂ683 @RMFU!# [$[$,,H̹ILmn۩IRʢHJěD:y-LIS u \CnH~Adb5 en($iڤnV6I uG?I]8&[7OKRlI~nI]f$u~uQ1ԕJ$I:#uu@ڸ+cǖ%FWb;9A,D,e#٬K#;rF%e3UE BTx\ѸZx`qm צpMsƾhT-ԻXwezWv&TUVr?Älm;(v$&kk-pe;v笄y1|`kg\ xzICP ƇLPV̭ہݝD je ZYuQz#jOKq+B!>r@J Dm@,Z 8RDm-1Dm#}L1oDmg|Dm8$Q+D)MԎd2Q;"Q;iHNQ+1_ +IJv @_*J̌ H@ /#jEwZQTl Ilj(}YڄR +W*6F +J*~_(DaW%jMV@Pڜ(Qsު}n-7 Os ʮm}+6sQi- WDm aA[b޲EK#..VDb1LJ jf9-mTlN١>w%[lMT >$,CxQ%HVw >yi£YQ]XΌ¥ĔBYBYP@oF163+ OFԪ. \8T-"즀MqOyH FRA 4 ] Qqez>$5 $[^I![9!%Qk+ZII$jcdk $js&AN*($ҴZUYy@78Jю ]-5rAëN8v},krXE1t}fM.5qc"bRHE$_` zq pA:E۩eS$T'{{G}I{{{SνU{{}^=`Ü{ǜc͹W}ss7<`md$Al։54{֭k+ub+!ubADmI>m|D1D{zbKym4m;a$e)FDΌgm5BD M'pyqEm+D%VXL':">6MbX1b."ڮ'ΓXmtFَ%7uҬZ2dKbHҘG5"fdklL!IJ*DX4iDx ڌ-5`[3#4qU~rW KjLd~Q٘DUf}(S Ic3jOMUʝ{JjP @:)Xy)z_ axVC&GhֈRȪq\V drV$c5ͨ7DY:ծh&5(.fME"dh)cǰ|hMcG(֢9RǎlTHMhacGؤsZ4 #1>ٵcc7Śz>Vcc+cutEKn>6q';6GƸb5qNf}r;{a?5޻nHNלX58/yr?7c! xAgg`=|>g`=|~v>г}g`C =zzг}g`C =z6ll>г}g`Ek`>OySЧ<)}CS>OyS>OySn>OyS=OyS~<s=ÿ+~!~1æLb)xM.{?5 dW~OqSފ΋㗾J\R46e?Ա5(h}t@:ڕ%@->Ղ~墽=뙣̊SF@zO}!Z7r (Te*w֫-8jmiow׿ΖyS2Z|Ko<+;_O=d|CTvu͇T 7`>c 'g3r> vg b=oІ qzNHI>v?(O8m3l˻$[]K:Z.q}1ǼΘ5miڶ1x7&3tH' iП5Ot'} aBYl!l!] dNDͥƐK|63 +͎·:WkdrlԜa O-3OsoS0Wl~#tS Q?{+&&:gaşfy`òH.;7B%!1x̷/4;2Ɇ'ٰ°T/{z" &8¶'ަ6,G?Ԉ#K]pzF;dě/O}hzI`A45 bCق,x";฾z!NX\ϯPX5ӑJ3u:şw ,3:*|D'j|g aW|},4q/XiR()8B雿=cbՐ'['XE,TH;>p}|JpFIJHU}䃵O|4=Xi esG"4~'Oܟ[kWN\y~t!7 ,z%!j%Jij3W{F xa\{H +U&?xD<ւ#?oA\Hډ5>Q;w^B<%&xiou;.O&~Y҂jEQ{`1dX3Y*#XijX`ςQ3[pA{hOEbڿn'+"\ 8\B^brAQve U'_dbGD%QN>(%ɞOrW=Wֈ՟f('Ş{Gv>(4Y͞G dיXĻ&NQVkm|!,|v8Qsu>Sş|'O)`hŰ ̧"' cOb:kbUY{cHb2,%XsSB|n%{u>ۈ3`SB|ɱ;cb(8f'X#X1s1gb]OdU [dO:~b=oSzh S!4Jg= S*b8O&)Sk|~%1Yxe uLB W#ihO1{QJє#)L93 Έ xzŃ?m6^s2\&9\(O(l*}^.^0)x eKpv봤S\/\O xdv+3>+̂\qgrE|s N Έv7/!>װ<Ou/aOrG|e%J4]iXsվOG|hxxAs@<44_;eD|٪ ic7FJw '_؏}#:}K@(g"!llI c qE< Di?_#kaKBDACo{][8U@{襏橒5O, x襏橒5O,(x襏橒5O,G\GHЫd!5C/}Ď *YH K!C C -z,xULsS% 8zU?$xUt|!C5O,d(yU橒5O,dGyU橒5O,df]0~TɚJ<~TɚJ2<~TɚJ6D^oI0C< W0 CB2/U?/zUWCAy顷WЫc&^j0CoWǎ,L۫qlL[B^o;0 CoB|CQ z{e/{i= i<ԵWHлqHl1CodwB޵Cjyz{-&{U][WPbq^4C!ź ^jCPᡷW!zB޵Wл6xt<z\,۫~HrCoPwmb铇^CuUz{,k>K6DE޵Cfz{b :],u+y].{"=kC킇^rCP^衷W(Nлvw`=U;XV顷W],+z][;DXmz|ثvxCoPwmb^Cϋ%z{`kk= <㡷Wл6TU{j= :{uJA|rw;v<5OS3Ԍ?5OS3Ԍ?5OS3Ԍ?5O͸fjƟf{jƟfjƟf]OS3Ԍ?w|]dͧRn Ĉ[-rq$d5%sR=n 4#b.喞rK^/wI3[-HֹKݒn)DG-]r-utK{:n)SnVd[8Ȏ4wI`[-|vޥݒn)q#l.wK%[[r-x-ޒߥ<"o钷d#.MyK%顷w[Z-iz$a%Rio4#I.{KgX|K;~|KY%4ҝd[D[- }$pһ%Ro㷴q&)od[*-Q޻[[-} ޕ ܊ n%\VVq+Q%w[iǭ( +)Qn*G)˭]̭HVBs+gQtVs+J[ѻb[ҭVtAJPʫnWҬpVVv+yv+E{_v+cJ[ܻ[ݭ0VwJoń'_O x@+pN'x^:*C+O{؝X.E {8q6RVJۊTPKX7 Fz_ʹcpmq睡!+dwr#(' zFr_BxXJsYHl)C,36M^!JDyXǠL0:]eْX=/n\\۴TUϋI_j&N( 'MiK>Jу#!6P#1B|9 ~J QlG!S=+L5BfޕUŧrgfToJ}T(exE̟)u`jx}A㘣ȇd$m+8n\۠ >ʳ++Ϯ>{+Ϯ|vEvEwgWt]=|vEgWt]=|vE}gWgWt]=|vEgWt]=|vEgWtO^ᬻ?O4%OSSSSSSSSSST8?Λz*_; p~* gp~* p~* p{YxQ{3l{Cն7j,6{C(m 4n(Nl 4oզIq#Feqc7cPn$=IIdǥɝf*Ņp)a`-E{jޝhp[ W7۔tp[ 7;1dpS` 7KpC1܃d/a &z 0ʰūjԞnV m!oը dapS%m"di~ցp*a {md-G,pOkv0#=)\H{ZӁV`5i{4n~ឦ Yp2#2 &'-Щsk BAi32$ý`78ԹV{D_0c<+=~+-J(02#2eBB[2E#P=_+ 2}(j!)M[n!2D`ʷ2pj$͕^3hk@ =L/ (pC& [bp=DzѬ_)ý ,RW{4v M}pn_A9FWPC=2kf^d up=u$aR`)b=t ǓcpOZ4u@IN^fdg6ke'Cdg>i} , =i/zTЛ1t5&cd1l&C  OM p- :(&c;d}ipoC4oihzwL=m2R\67c(K=P/mLO[2-K= iMO7Rü~_`z1AO;{~i[hce)gjzEBO;f7ӖЇe. =Њi#"f x vl,QSO{a@iG9QO;{_ii%37vӴOD"1dZJv*~nliKɑ_Inzڦkzک =dRiaNq0_ihz6IFrїĤz!HĢMzy]CO[ݡLBzڙTin|.el $Pi[v0}ni;}liϩsяv\=POd:@iBO=B=N.zڢs72<@O =ҭAOزzŖ.Ӿ7˴煞v FCOE~ؿ-GzuCO{a'>ؿjXi'kłk;Uǡ][azڢh }^OSO[ƚ'E HMBO{-c'>ӖըeQ#ַ#u6HcyuYN;&ZֱzԺvzҠֻ_ZQO{Zkj] F͋?z/~ֻSZj75^Owqe?r$nNm5hzşӋLz ޛQ6*]ֿ=EşiS=Lzڣ:,|2-qԺN; gK: 6=m盞E=mڛY5*]쟸D,tSO{ҩmSxӞWK=YMzڳ =M5PO[2eL?[dֳzӞ4zsXCO{nzsSӞZI}s վ쟚A쟚Y—SZP1FEZW3iԻPKa/NIhyiߌZW3hT4.fԿN\ u.R0jԺAG v(OңܿuԺE;L[v:QM?;#׉b O}zgu׃ZWoOFO?ʈԢJ j]ik:=mmnQL;4=A6-UJj}Zjo j]e=1=Qsmj}jZ[ZèwPcsǸe=1,uzڣ[*QO[L8a>6-јB=m.azc^iXZ{BOۂܦ=,Uzzڣ^8e;e=1ʥ-Q.]ִ'l/il=JF=.F^#7G6boF|kn=F=muz'f3-4/O=magi(x%'ddX_C=~ީ}G=^-?zBq۸n>_mmgq=|vmgq=|vmg >?;6۸n>{6۸n>{6~ggqs6~>wjb{Cb?O-Sb?O-Sb?oO-Sb?O-Sb+~jZ~jZ췧~jZV{w~LJWxCxTWC7a)ؕp!%Fq]? e+/n4\,r:ywЄHR%65ahMWJ7,=+;.$b 1>؟!|otg3D. bwF)__oʧ=˭Fx G~kBwmn`ĵ]7_^ G5:LxOM?v:.:N%]໺B`ߣ+x6,p6 W}Էucws= Lo__)4]k?~o^?/^߮^%E?__of=p/ןSO$_O{Ե#rﲏkݻAr)P@]q<]럛4Cؿd!R34GH'dz ZCv mE_Ifp.h4<ޅ16渺=mT]dz0Ù:DBYWƍdpUS~~_}kE'3 qK9qV43Ϋ~%(x$cvr.Qo®nwQ$9,=c:Y?9 qgY9 g_=g!ߧW0eh7)1ű3)1ű3)1ǔJ$?&t2_.Ki]A\7dx__"~C,$z%A )A_. Q',O^_QyX/7&!f Qw&oݧƧWEe_]g502^o6v~2%ִlm.(kZ6E-_9NI]hXA~4+GkʞiOwkͦI߻5,h4Zs /hͩeFk5?[sj nXkQR޵_di>+ʼ'o;g9tu6})- endstream endobj 27 0 obj << /Type /Page /Parent 3 0 R /Contents 28 0 R /Resources 4 0 R >> endobj 28 0 obj << /Length 22994 /Filter /FlateDecode >> stream xͮ&q$Bْ+\ h!hisI(69¼Gz)VW>Uf~_?}o^1WSy^?/_WÏo?uVx~~'N'kLJWxC|tQ>|i~9׏sZkƏ933+՗QXFFELcIo>?iWsh0٘?z;A{琎:bϫ;SNY֕ا<^_{sclIa}Yp]a2ລhV:}p&5V}<p?&WX”ܷʛ(r"S8侙7Z]')Lr40}W+h]-:+3 q}'iX1J}~p(ۺjJ>ncg2c^Q׷ u\>X}Q\}s`њ hkCӵճ\/6W#Ŕv1DOպoHq#;FFaYCg>y1& 2Gx!up5p juuCF `_ tCF {5oHsƙ7PXџ ڳK*Z]b6չBosʭ+YfR44EQ~mَрVӈ%I@) hu1Z6l0Fz-U:МН׀Yg*AѺbDiX6\h5XV%.T{. f\FoTxlBx?&C}"c!+ &OVI.xlu-"zTeYb+fUlQ'&^_-geR{ײC  53 wY(K<6~% z? ErF]Yi_b{Y"P~jw*CߏkqC/ť=в9h8A,m@ތ(* h9Zh! -[RN@ &3;[܀֗[\[bh5:jZ6f#-[/P+@ǀ-XhBf -t,Gƻ5/Y6hYB$%ɲڗ,hY0d>3EYHKUmEː>hyeкE2֠V]Ŧ6 Wbdx,N#x,̌ MY,V?5 1Y T .+n0ndirTu?~ SS_]cPOI6]8e{ZTtA0'L p0 㤵μvY>w)Z፪4>K_#QI4.WUq$KmY~\f* Zɦ]՞/kRXy jEUNn+vi$.,oCvI_aD2_U`8!JN톴c iikWWMMt} zݷsVRC!.Wo/tŪVEbxt+9hѯqI] )VL xL}e:rm)N $YDeĸ{bM.#m&8/㙵zBop<*\g[m\b[Y{8pBqmŵRGe}_&Li.8 `9Ƣ6YwNdN0cl ն/(9h>/(mY~G kK-(ؽ$AȂST׶zlYHSs[י,5ѧۓY$.Ru-(& :K8Uly8} #rX{>vt<X%Վa5ߩq c?`,pNw#c9`,-NwߨG8`)lွp&16zX{9UÔk=`Ojk>`U\q0p8oSO`,〭pNn`,-Nߡ^X<`WqjXZ۫5!)+=z{]a<#JmUJJmÜPZ#p^w?u1ny{oqnMwk[}u[Ww[u[>:mh8aut!y p~7of(nf027@͸L_< a6՛ɽ䛹;7qs"7ss@{9wnn4zsY\Ӏ$6M?ncrؼ&E)mBi&rimx"65M\oc{6MoSc~ƿߖmp,.`oZL߷ZLl逥۫kv- z{z׶W{Ѻwm{W{ak K kpث:лv+,ϸsl\*O..rv 98υb|BΙ1t!gsdc]&ƿ.frv 񶍪w`9l{9煸F#r qH-Br9;xCa!κQ6YB\!g(zG8C sR[oA!*wr yA!@ 8l S ᐳ3 0rhP9!7y␳/ jrCξrJ9B!g_@e9H0}}s= rCs09q I鐳/C7ՀHuP97v h_a쐳/ v09!e; vS/{/ӻ2{һ/{/ӻ2{tACξ E!e\ᐳ/Hpy$t8 RAr^I$9T+94294}ACξ !g_2H'r$"9 RrO9/)}A•!dc9 r^`91A֙Cξ _!e搳/HRsyd9 #e琳/Hܨz/C}ArC q "r^9LACξ !e+ꐳ/1uy: rZr^9ZACξ g!e됳/vb[쐳/Ivb쐳/́/̝/̹/6Խa}anaN s/ s/ s Ue3!g_k!eQ9/}A-F{ 8 jr^5%o_P+2pflAMCξ!ePC␳/=qyԬ8 j]r^529AUCξ!eP 䐳/!ryT9 r^O9Z)ACξ>!7-{}9 r^f9"5AyCξ0!ePR琳/(sy9 r^9CACξ!eP"鐳/(tye: :r^weC?]?ԋ>OS/ԋ>OS/ԋ>OS/ԋ>OS/ԋ>OS/ԋ>OOS/`E|E=|E=^ܾWI| {u Jjt,8M B(˵2ؚ0:6cotl&E:6c btl!+L:%[ [6: ltlcYc_&W>Fck!/:֣ck!:2H:ꒋt)бIޗi}tcktletlRtF|m:LIJK*[ &ck kӱ†9:2G:f>ؚN#{j2(ؚcckҖtlMӓ ұ;צc+IMұQLұfб5/4£=*4VX;] Ԑ'kpA7*)+AAVe` / [yT\7 !);+tƕ6~V`% +Ia, E1d Z /.AJeei֋մ2V:vrGN{UHJCJBV`kH$o5Ą J}xYY X /}"4^Rp;RV YhAMP+HpDZW }12VH' p"#}@H)G+б#_MI|3f 7Hq+i_qm &r}Q=”I ]b/ct[+| ,*x+0ז+Cu1u5?䭸4[+0ZWbl^%F@ dpŵ%#ٔXxr ZZm@P}uIlr;)ߚ6,-5J TW zFBqmӛ*|(^ᵙdf1N.WUbL@b@2k3"]V^[R %3F7U8/2vXe0ӛ*h0k3M2 8`zwӁM 2ӛ%ӛCW y|TѽF* Lo{ӫ6Dx_՘=ڈ\f2W{{~ӫc<}'8 aE+1WG(asځ $o;.W-e7@+ӫfP 1X`hs ,&^5BګN8p_0՘I`'a$L2W`!`zAӫeL~1j˘^\n}u~@# y"O.`"iWPpF]2W :2 ˘^Vӫ0][%[q_u`zӫbz1 ˘ zu-`zo^dk L^}2W!܊Aӫbzw`z՗1}˘^$;sj^uVBa ӛ8$ӛȲM:^tv Ư~_2^Y3Wb/ ,5?1^Pi_ܮ+Sثh,2_ %{| _`c5Ae_.Xq1+]qm>2 tHy - 4-@Q *8Zf ` /#Oi% @ ݅ґtYٯV^-VV.f<1`A <*JʋV:Ge*"h(WnXIVbcA`HjW ICO~xrJD~X4.s5V 䇧c%K¤$d #%󿡕K084WLÓÓ2g1^ZY}upd̘ U F|W˜~3~x2M~xlJbJ7R~xF^:~xF{Hg$ Fqktx20,Óaߌ΀[F6Ã~$itW<}niPU}_G%[Ʈf?w?3~X}&̚i*$TKRP~xT{A4NãZV~x0H~xT{Hd'.&S![1AO~x>aIȬRÖC~Xfspj>ÖD~rL[X(Ø?<$|Ãe Ób@85hy0~3~x0F~xD6,1 #?l5䇭t``T#s Rr`p1 E &ZRaK"?lu<"䇧3a.-af?<O,faN XJ?<ǂY*d ~xZkL1 sc`'$?l^'?U~$Ik;c߼OOs'}OOs'?O^|+ps 37[9 g=̓8s(qz0/c|Q@Õ?BW r;AsR !_e#F.c};y;rrLRȫ ):\W2gxz>8˜d2bĄ9E*7b(Hi;.خfY[xFJ7Nlj:ep^UvwEvǠiٝ7gCgԱOmʂ683 @RMFU!# [$[$,,H̹ILmn۩IRʢHJěD:y-LIS u \CnH~Adb5 en($iڤnV6I uG?I]8&[7OKRlI~nI]f$u~uQ1ԕJ$I:#uu@ڸ+cǖ%FWb;9A,D,e#٬K#;rF%e3UE BTx\ѸZx`qm צpMsƾhT-ԻXwezWv&TUVr?Älm;(v$&kk-pe;v笄y1|`kg\ xzICP ƇLPV̭ہݝD je ZYuQz#jOKq+B!>r@J Dm@,Z 8RDm-1Dm#}L1oDmg|Dm8$Q+D)MԎd2Q;"Q;iHNQ+1_ +IJv @_*J̌ H@ /#jEwZQTl Ilj(}YڄR +W*6F +J*~_(DaW%jMV@Pڜ(Qsު}n-7 Os ʮm}+6sQi- WDm aA[b޲EK#..VDb1LJ jf9-mTlN١>w%[lMT >$,CxQ%HVw >yi£YQ]XΌ¥ĔBYBYP@oF163+ OFԪ. \8T-"즀MqOyH FRA 4 ] Qqez>$5 $[^I![9!%Qk+ZII$jcdk $js&AN*($ҴZUYy@78Jю ]-5rAëN8v},krXE1t}fM.5qc"bRHE$_` zq pA:E۩eS$T'{{G}I{{{SνU{{}^=`Ü{ǜc͹W}ss7<`md$Al։54{֭k+ub+!ubADmI>m|D1D{zbKym4m;a$e)FDΌgm5BD M'pyqEm+D%VXL':">6MbX1b."ڮ'ΓXmtFَ%7uҬZ2dKbHҘG5"fdklL!IJ*DX4iDx ڌ-5`[3#4qU~rW KjLd~Q٘DUf}(S Ic3jOMUʝ{JjP @:)Xy)z_ axVC&GhֈRȪq\V drV$c5ͨ7DY:ծh&5(.fME"dh)cǰ|hMcG(֢9RǎlTHMhacGؤsZ4 #1>ٵcc7Śz>Vcc+cutEKn>6q';6GƸb5qNf}r;{a?5޻nHNלX58/yr?7c! xAgg`=|>g`=|~v>г}g`C =zzг}g`C =z6ll>г}g`Ek`>OySЧ<)}CS>OyS>OySn>OyS=OyS~<s=ÿ+~!~1æLb)xM.{?5 dW~OqSފ΋㗾J\R46e?Ա5(h}t@:ڕ%@->Ղ~墽=뙣̊SF@zO}!Z7r (Te*w֫-8jmiow׿ΖyS2Z|Ko<+;_O=d|CTvu͇T 7`>c 'g3r> vg b=oІ qzNHI>v?(O8m3l˻$[]K:Z.q}1ǼΘ5miڶ1x7&3tH' iП5Ot'} aBYl!l!] dNDͥƐK|63 +͎·:WkdrlԜa O-3OsoS0Wl~#tS Q?{+&&:gaşfy`òH.;7B%!1x̷/4;2Ɇ'ٰ°T/{z" &8¶'ަ6,G?Ԉ#K]pzF;dě/O}hzI`A45 bCق,x";฾z!NX\ϯPX5ӑJ3u:şw ,3:*|D'j|g aW|},4q/XiR()8B雿=cbՐ'['XE,TH;>p}|JpFIJHU}䃵O|4=Xi esG"4~'Oܟ[kWN\y~t!7 ,z%!j%Jij3W{F xa\{H +U&?xD<ւ#?oA\Hډ5>Q;w^B<%&xiou;.O&~Y҂jEQ{`1dX3Y*#XijX`ςQ3[pA{hOEbڿn'+"\ 8\B^brAQve U'_dbGD%QN>(%ɞOrW=Wֈ՟f('Ş{Gv>(4Y͞G dיXĻ&NQVkm|!,|v8Qsu>Sş|'O)`hŰ ̧"' cOb:kbUY{cHb2,%XsSB|n%{u>ۈ3`SB|ɱ;cb(8f'X#X1s1gb]OdU [dO:~b=oSzh S!4Jg= S*b8O&)Sk|~%1Yxe uLB W#ihO1{QJє#)L93 Έ xzŃ?m6^s2\&9\(O(l*}^.^0)x eKpv봤S\/\O xdv+3>+̂\qgrE|s N Έv7/!>װ<Ou/aOrG|e%J4]iXsվOG|hxxAs@<44_;eD|٪ ic7FJw '_؏}#:}K@(g"!llI c qE< Di?_#kaKBDACo{][8U@{襏橒5O, x襏橒5O,(x襏橒5O,G\GHЫd!5C/}Ď *YH K!C C -z,xULsS% 8zU?$xUt|!C5O,d(yU橒5O,dGyU橒5O,df]0~TɚJ<~TɚJ2<~TɚJ6D^oI0C< W0 CB2/U?/zUWCAy顷WЫc&^j0CoWǎ,L۫qlL[B^o;0 CoB|CQ z{e/{i= i<ԵWHлqHl1CodwB޵Cjyz{-&{U][WPbq^4C!ź ^jCPᡷW!zB޵Wл6xt<z\,۫~HrCoPwmb铇^CuUz{,k>K6DE޵Cfz{b :],u+y].{"=kC킇^rCP^衷W(Nлvw`=U;XV顷W],+z][;DXmz|ثvxCoPwmb^Cϋ%z{`kk= <㡷Wл6TU{j= :{uJA|rw;v<5OS3Ԍ?5OS3Ԍ?5OS3Ԍ?5O͸fjƟf{jƟfjƟf]OS3Ԍ?w|]dͧRn Ĉ[-rq$d5%sR=n 4#b.喞rK^/wI3[-HֹKݒn)DG-]r-utK{:n)SnVd[8Ȏ4wI`[-|vޥݒn)q#l.wK%[[r-x-ޒߥ<"o钷d#.MyK%顷w[Z-iz$a%Rio4#I.{KgX|K;~|KY%4ҝd[D[- }$pһ%Ro㷴q&)od[*-Q޻[[-} ޕ ܊ n%\VVq+Q%w[iǭ( +)Qn*G)˭]̭HVBs+gQtVs+J[ѻb[ҭVtAJPʫnWҬpVVv+yv+E{_v+cJ[ܻ[ݭ0VwJoń'_O x@+pN'x^:*C+O{؝X.E {8q6RVJۊTPKX7 Fz_ʹcpmq睡!+dwr#(' zFr_BxXJsYHl)C,36M^!JDyXǠL0:]eْX=/n\\۴TUϋI_j&N( 'MiK>Jу#!6P#1B|9 ~J QlG!S=+L5BfޕUŧrgfToJ}T(exE̟)u`jx}A㘣ȇd$m+8n\۠ >ʳ++Ϯ>{+Ϯ|vEvEwgWt]=|vEgWt]=|vE}gWgWt]=|vEgWt]=|vEgWtO^ᬻ?O4%OSSSSSSSSSST8?Λz*_; p~* gp~* p~* p{YxQ{3l{Cն7j,6{C(m 4n(Nl 4oզIq#Feqc7cPn$=IIdǥɝf*Ņp)a`-E{jޝhp[ W7۔tp[ 7;1dpS` 7KpC1܃d/a &z 0ʰūjԞnV m!oը dapS%m"di~ցp*a {md-G,pOkv0#=)\H{ZӁV`5i{4n~ឦ Yp2#2 &'-Щsk BAi32$ý`78ԹV{D_0c<+=~+-J(02#2eBB[2E#P=_+ 2}(j!)M[n!2D`ʷ2pj$͕^3hk@ =L/ (pC& [bp=DzѬ_)ý ,RW{4v M}pn_A9FWPC=2kf^d up=u$aR`)b=t ǓcpOZ4u@IN^fdg6ke'Cdg>i} , =i/zTЛ1t5&cd1l&C  OM p- :(&c;d}ipoC4oihzwL=m2R\67c(K=P/mLO[2-K= iMO7Rü~_`z1AO;{~i[hce)gjzEBO;f7ӖЇe. =Њi#"f x vl,QSO{a@iG9QO;{_ii%37vӴOD"1dZJv*~nliKɑ_Inzڦkzک =dRiaNq0_ihz6IFrїĤz!HĢMzy]CO[ݡLBzڙTin|.el $Pi[v0}ni;}liϩsяv\=POd:@iBO=B=N.zڢs72<@O =ҭAOزzŖ.Ӿ7˴煞v FCOE~ؿ-GzuCO{a'>ؿjXi'kłk;Uǡ][azڢh }^OSO[ƚ'E HMBO{-c'>ӖըeQ#ַ#u6HcyuYN;&ZֱzԺvzҠֻ_ZQO{Zkj] F͋?z/~ֻSZj75^Owqe?r$nNm5hzşӋLz ޛQ6*]ֿ=EşiS=Lzڣ:,|2-qԺN; gK: 6=m盞E=mڛY5*]쟸D,tSO{ҩmSxӞWK=YMzڳ =M5PO[2eL?[dֳzӞ4zsXCO{nzsSӞZI}s վ쟚A쟚Y—SZP1FEZW3iԻPKa/NIhyiߌZW3hT4.fԿN\ u.R0jԺAG v(OңܿuԺE;L[v:QM?;#׉b O}zgu׃ZWoOFO?ʈԢJ j]ik:=mmnQL;4=A6-UJj}Zjo j]e=1=Qsmj}jZ[ZèwPcsǸe=1,uzڣ[*QO[L8a>6-јB=m.azc^iXZ{BOۂܦ=,Uzzڣ^8e;e=1ʥ-Q.]ִ'l/il=JF=.F^#7G6boF|kn=F=muz'f3-4/O=magi(x%'ddX_C=~ީ}G=^-?zBq۸n>_mmgq=|vmgq=|vmg >?;6۸n>{6۸n>{6~ggqs6~>wjb{Cb?O-Sb?O-Sb?oO-Sb?O-Sb+~jZ~jZ췧~jZV{w~LJWxCxTWC7a)ؕp!%Fq]? e+/n4\,r:ywЄHR%65ahMWJ7,=+;.$b 1>؟!|otg3D. bwF)__oʧ=˭Fx G~kBwmn`ĵ]7_^ G5:LxOM?v:.:N%]໺B`ߣ+x6,p6 W}Էucws= Lo__)4]k?~o^?/^߮^%E?__of=p/ןSO$_O{Ե#rﲏkݻAr)P@]q<]럛4Cؿd!R34GH'dz ZCv mE_Ifp.h4<ޅ16渺=mT]dz0Ù:DBYWƍdpUS~~_}kE'3 qK9qV43Ϋ~%(x$cvr.Qo®nwQ$9,=c:Y?9 qgY9 g_=g!ߧW0eh7)1ű3)1ű3)1ǔJ$?&t2_.Ki]A\7dx__"~C,$z%A )A_. Q',O^_QyX/7&!f Qw&oݧƧWEe_]g502^o6v~2%ִlm.(kZ6E-_9NI]hXA~4+GkʞiOwkͦI߻5,h4Zs /hͩeFk5?[sj nXkQR޵_di>+ʼ'o;g9tu6})- endstream endobj 29 0 obj << /Type /Page /Parent 3 0 R /Contents 30 0 R /Resources 4 0 R >> endobj 30 0 obj << /Length 22993 /Filter /FlateDecode >> stream xͮ&q$Bْ+\ h!hisI(69¼Gz)VW>Uf~_?}o^1WSy^?/_WÏo?uVx~~'N'kLJWxC|tQ>|i~9׏sZkƏ933+՗QXFFELcIo>?iWsh0٘?z;A{琎:bϫ;SNY֕ا<^_{sclIa}Yp]a2ລhV:}p&5V}<p?&WX”ܷʛ(r"S8侙7Z]')Lr40}W+h]-:+3 q}'iX1J}~p(ۺjJ>ncg2c^Q׷ u\>X}Q\}s`њ hkCӵճ\/6W#Ŕv1DOպoHq#;FFaYCg>y1& 2Gx!up5p juuCF `_ tCF {5oHsƙ7PXџ ڳK*Z]b6չBosʭ+YfR44EQ~mَрVӈ%I@) hu1Z6l0Fz-U:МН׀Yg*AѺbDiX6\h5XV%.T{. f\FoTxlBx?&C}"c!+ &OVI.xlu-"zTeYb+fUlQ'&^_-geR{ײC  53 wY(K<6~% z? ErF]Yi_b{Y"P~jw*CߏkqC/ť=в9h8A,m@ތ(* h9Zh! -[RN@ &3;[܀֗[\[bh5:jZ6f#-[/P+@ǀ-XhBf -t,Gƻ5/Y6hYB$%ɲڗ,hY0d>3EYHKUmEː>hyeкE2֠V]Ŧ6 Wbdx,N#x,̌ MY,V?5 1Y T .+n0ndirTu?~ SS_]cPOI6]8e{ZTtA0'L p0 㤵μvY>w)Z፪4>K_#QI4.WUq$KmY~\f* Zɦ]՞/kRXy jEUNn+vi$.,oCvI_aD2_U`8!JN톴c iikWWMMt} zݷsVRC!.Wo/tŪVEbxt+9hѯqI] )VL xL}e:rm)N $YDeĸ{bM.#m&8/㙵zBop<*\g[m\b[Y{8pBqmŵRGe}_&Li.8 `9Ƣ6YwNdN0cl ն/(9h>/(mY~G kK-(ؽ$AȂST׶zlYHSs[י,5ѧۓY$.Ru-(& :K8Uly8} #rX{>vt<X%Վa5ߩq c?`,pNw#c9`,-NwߨG8`)lွp&16zX{9UÔk=`Ojk>`U\q0p8oSO`,〭pNn`,-Nߡ^X<`WqjXZ۫5!)+=z{]a<#JmUJJmÜPZ#p^w?u1ny{oqnMwk[}u[Ww[u[>:mh8aut!y p~7of(nf027@͸L_< a6՛ɽ䛹;7qs"7ss@{9wnn4zsY\Ӏ$6M?ncrؼ&E)mBi&rimx"65M\oc{6MoSc~ƿߖmp,.`oZL߷ZLl逥۫kv- z{z׶W{Ѻwm{W{ak K kpث:лv+,ϸsl\*O..rv 98υb|BΙ1t!gsdc]&ƿ.frv 񶍪w`9l{9煸F#r qH-Br9;xCa!κQ6YB\!g(zG8C sR[oA!*wr yA!@ 8l S ᐳ3 0rhP9!7y␳/ jrCξrJ9B!g_@e9H0}}s= rCs09q I鐳/C7ՀHuP97v h_a쐳/ v09!e; vS/{/ӻ2{һ/{/ӻ2{tACξ E!e\ᐳ/Hpy$t8 RAr^I$9T+94294}ACξ !g_2H'r$"9 RrO9/)}A•!dc9 r^`91A֙Cξ _!e搳/HRsyd9 #e琳/Hܨz/C}ArC q "r^9LACξ !e+ꐳ/1uy: rZr^9ZACξ g!e됳/vb[쐳/Ivb쐳/́/̝/̹/6Խa}anaN s/ s/ s Ue3!g_k!eQ9/}A-F{ 8 jr^5%o_P+2pflAMCξ!ePC␳/=qyԬ8 j]r^529AUCξ!eP 䐳/!ryT9 r^O9Z)ACξ>!7-{}9 r^f9"5AyCξ0!ePR琳/(sy9 r^9CACξ!eP"鐳/(tye: :r^weC?]?ԋ>OS/ԋ>OS/ԋ>OS/ԋ>OS/ԋ>OS/ԋ>OOS/`E|E=|E=^ܾWI| {u Jjt,8M B(˵2ؚ0:6cotl&E:6c btl!+L:%[ [6: ltlcYc_&W>Fck!/:֣ck!:2H:ꒋt)бIޗi}tcktletlRtF|m:LIJK*[ &ck kӱ†9:2G:f>ؚN#{j2(ؚcckҖtlMӓ ұ;צc+IMұQLұfб5/4£=*4VX;] Ԑ'kpA7*)+AAVe` / [yT\7 !);+tƕ6~V`% +Ia, E1d Z /.AJeei֋մ2V:vrGN{UHJCJBV`kH$o5Ą J}xYY X /}"4^Rp;RV YhAMP+HpDZW }12VH' p"#}@H)G+б#_MI|3f 7Hq+i_qm &r}Q=”I ]b/ct[+| ,*x+0ז+Cu1u5?䭸4[+0ZWbl^%F@ dpŵ%#ٔXxr ZZm@P}uIlr;)ߚ6,-5J TW zFBqmӛ*|(^ᵙdf1N.WUbL@b@2k3"]V^[R %3F7U8/2vXe0ӛ*h0k3M2 8`zwӁM 2ӛ%ӛCW y|TѽF* Lo{ӫ6Dx_՘=ڈ\f2W{{~ӫc<}'8 aE+1WG(asځ $o;.W-e7@+ӫfP 1X`hs ,&^5BګN8p_0՘I`'a$L2W`!`zAӫeL~1j˘^\n}u~@# y"O.`"iWPpF]2W :2 ˘^Vӫ0][%[q_u`zӫbz1 ˘ zu-`zo^dk L^}2W!܊Aӫbzw`z՗1}˘^$;sj^uVBa ӛ8$ӛȲM:^tv Ư~_2^Y3Wb/ ,5?1^Pi_ܮ+Sثh,2_ %{| _`c5Ae_.Xq1+]qm>2 tHy - 4-@Q *8Zf ` /#Oi% @ ݅ґtYٯV^-VV.f<1`A <*JʋV:Ge*"h(WnXIVbcA`HjW ICO~xrJD~X4.s5V 䇧c%K¤$d #%󿡕K084WLÓÓ2g1^ZY}upd̘ U F|W˜~3~x2M~xlJbJ7R~xF^:~xF{Hg$ Fqktx20,Óaߌ΀[F6Ã~$itW<}niPU}_G%[Ʈf?w?3~X}&̚i*$TKRP~xT{A4NãZV~x0H~xT{Hd'.&S![1AO~x>aIȬRÖC~Xfspj>ÖD~rL[X(Ø?<$|Ãe Ób@85hy0~3~x0F~xD6,1 #?l5䇭t``T#s Rr`p1 E &ZRaK"?lu<"䇧3a.-af?<O,faN XJ?<ǂY*d ~xZkL1 sc`'$?l^'?U~$Ik;c߼OOs'}OOs'?O^|+ps 37[9 g=̓8s(qz0/c|Q@Õ?BW r;AsR !_e#F.c};y;rrLRȫ ):\W2gxz>8˜d2bĄ9E*7b(Hi;.خfY[xFJ7Nlj:ep^UvwEvǠiٝ7gCgԱOmʂ683 @RMFU!# [$[$,,H̹ILmn۩IRʢHJěD:y-LIS u \CnH~Adb5 en($iڤnV6I uG?I]8&[7OKRlI~nI]f$u~uQ1ԕJ$I:#uu@ڸ+cǖ%FWb;9A,D,e#٬K#;rF%e3UE BTx\ѸZx`qm צpMsƾhT-ԻXwezWv&TUVr?Älm;(v$&kk-pe;v笄y1|`kg\ xzICP ƇLPV̭ہݝD je ZYuQz#jOKq+B!>r@J Dm@,Z 8RDm-1Dm#}L1oDmg|Dm8$Q+D)MԎd2Q;"Q;iHNQ+1_ +IJv @_*J̌ H@ /#jEwZQTl Ilj(}YڄR +W*6F +J*~_(DaW%jMV@Pڜ(Qsު}n-7 Os ʮm}+6sQi- WDm aA[b޲EK#..VDb1LJ jf9-mTlN١>w%[lMT >$,CxQ%HVw >yi£YQ]XΌ¥ĔBYBYP@oF163+ OFԪ. \8T-"즀MqOyH FRA 4 ] Qqez>$5 $[^I![9!%Qk+ZII$jcdk $js&AN*($ҴZUYy@78Jю ]-5rAëN8v},krXE1t}fM.5qc"bRHE$_` zq pA:E۩eS$T'{{G}I{{{SνU{{}^=`Ü{ǜc͹W}ss7<`md$Al։54{֭k+ub+!ubADmI>m|D1D{zbKym4m;a$e)FDΌgm5BD M'pyqEm+D%VXL':">6MbX1b."ڮ'ΓXmtFَ%7uҬZ2dKbHҘG5"fdklL!IJ*DX4iDx ڌ-5`[3#4qU~rW KjLd~Q٘DUf}(S Ic3jOMUʝ{JjP @:)Xy)z_ axVC&GhֈRȪq\V drV$c5ͨ7DY:ծh&5(.fME"dh)cǰ|hMcG(֢9RǎlTHMhacGؤsZ4 #1>ٵcc7Śz>Vcc+cutEKn>6q';6GƸb5qNf}r;{a?5޻nHNלX58/yr?7c! xAgg`=|>g`=|~v>г}g`C =zzг}g`C =z6ll>г}g`Ek`>OySЧ<)}CS>OyS>OySn>OyS=OyS~<s=ÿ+~!~1æLb)xM.{?5 dW~OqSފ΋㗾J\R46e?Ա5(h}t@:ڕ%@->Ղ~墽=뙣̊SF@zO}!Z7r (Te*w֫-8jmiow׿ΖyS2Z|Ko<+;_O=d|CTvu͇T 7`>c 'g3r> vg b=oІ qzNHI>v?(O8m3l˻$[]K:Z.q}1ǼΘ5miڶ1x7&3tH' iП5Ot'} aBYl!l!] dNDͥƐK|63 +͎·:WkdrlԜa O-3OsoS0Wl~#tS Q?{+&&:gaşfy`òH.;7B%!1x̷/4;2Ɇ'ٰ°T/{z" &8¶'ަ6,G?Ԉ#K]pzF;dě/O}hzI`A45 bCق,x";฾z!NX\ϯPX5ӑJ3u:şw ,3:*|D'j|g aW|},4q/XiR()8B雿=cbՐ'['XE,TH;>p}|JpFIJHU}䃵O|4=Xi esG"4~'Oܟ[kWN\y~t!7 ,z%!j%Jij3W{F xa\{H +U&?xD<ւ#?oA\Hډ5>Q;w^B<%&xiou;.O&~Y҂jEQ{`1dX3Y*#XijX`ςQ3[pA{hOEbڿn'+"\ 8\B^brAQve U'_dbGD%QN>(%ɞOrW=Wֈ՟f('Ş{Gv>(4Y͞G dיXĻ&NQVkm|!,|v8Qsu>Sş|'O)`hŰ ̧"' cOb:kbUY{cHb2,%XsSB|n%{u>ۈ3`SB|ɱ;cb(8f'X#X1s1gb]OdU [dO:~b=oSzh S!4Jg= S*b8O&)Sk|~%1Yxe uLB W#ihO1{QJє#)L93 Έ xzŃ?m6^s2\&9\(O(l*}^.^0)x eKpv봤S\/\O xdv+3>+̂\qgrE|s N Έv7/!>װ<Ou/aOrG|e%J4]iXsվOG|hxxAs@<44_;eD|٪ ic7FJw '_؏}#:}K@(g"!llI c qE< Di?_#kaKBDACo{][8U@{襏橒5O, x襏橒5O,(x襏橒5O,G\GHЫd!5C/}Ď *YH K!C C -z,xULsS% 8zU?$xUt|!C5O,d(yU橒5O,dGyU橒5O,df]0~TɚJ<~TɚJ2<~TɚJ6D^oI0C< W0 CB2/U?/zUWCAy顷WЫc&^j0CoWǎ,L۫qlL[B^o;0 CoB|CQ z{e/{i= i<ԵWHлqHl1CodwB޵Cjyz{-&{U][WPbq^4C!ź ^jCPᡷW!zB޵Wл6xt<z\,۫~HrCoPwmb铇^CuUz{,k>K6DE޵Cfz{b :],u+y].{"=kC킇^rCP^衷W(Nлvw`=U;XV顷W],+z][;DXmz|ثvxCoPwmb^Cϋ%z{`kk= <㡷Wл6TU{j= :{uJA|rw;v<5OS3Ԍ?5OS3Ԍ?5OS3Ԍ?5O͸fjƟf{jƟfjƟf]OS3Ԍ?w|]dͧRn Ĉ[-rq$d5%sR=n 4#b.喞rK^/wI3[-HֹKݒn)DG-]r-utK{:n)SnVd[8Ȏ4wI`[-|vޥݒn)q#l.wK%[[r-x-ޒߥ<"o钷d#.MyK%顷w[Z-iz$a%Rio4#I.{KgX|K;~|KY%4ҝd[D[- }$pһ%Ro㷴q&)od[*-Q޻[[-} ޕ ܊ n%\VVq+Q%w[iǭ( +)Qn*G)˭]̭HVBs+gQtVs+J[ѻb[ҭVtAJPʫnWҬpVVv+yv+E{_v+cJ[ܻ[ݭ0VwJoń'_O x@+pN'x^:*C+O{؝X.E {8q6RVJۊTPKX7 Fz_ʹcpmq睡!+dwr#(' zFr_BxXJsYHl)C,36M^!JDyXǠL0:]eْX=/n\\۴TUϋI_j&N( 'MiK>Jу#!6P#1B|9 ~J QlG!S=+L5BfޕUŧrgfToJ}T(exE̟)u`jx}A㘣ȇd$m+8n\۠ >ʳ++Ϯ>{+Ϯ|vEvEwgWt]=|vEgWt]=|vE}gWgWt]=|vEgWt]=|vEgWtO^ᬻ?O4%OSSSSSSSSSST8?Λz*_; p~* gp~* p~* p{YxQ{3l{Cն7j,6{C(m 4n(Nl 4oզIq#Feqc7cPn$=IIdǥɝf*Ņp)a`-E{jޝhp[ W7۔tp[ 7;1dpS` 7KpC1܃d/a &z 0ʰūjԞnV m!oը dapS%m"di~ցp*a {md-G,pOkv0#=)\H{ZӁV`5i{4n~ឦ Yp2#2 &'-Щsk BAi32$ý`78ԹV{D_0c<+=~+-J(02#2eBB[2E#P=_+ 2}(j!)M[n!2D`ʷ2pj$͕^3hk@ =L/ (pC& [bp=DzѬ_)ý ,RW{4v M}pn_A9FWPC=2kf^d up=u$aR`)b=t ǓcpOZ4u@IN^fdg6ke'Cdg>i} , =i/zTЛ1t5&cd1l&C  OM p- :(&c;d}ipoC4oihzwL=m2R\67c(K=P/mLO[2-K= iMO7Rü~_`z1AO;{~i[hce)gjzEBO;f7ӖЇe. =Њi#"f x vl,QSO{a@iG9QO;{_ii%37vӴOD"1dZJv*~nliKɑ_Inzڦkzک =dRiaNq0_ihz6IFrїĤz!HĢMzy]CO[ݡLBzڙTin|.el $Pi[v0}ni;}liϩsяv\=POd:@iBO=B=N.zڢs72<@O =ҭAOزzŖ.Ӿ7˴煞v FCOE~ؿ-GzuCO{a'>ؿjXi'kłk;Uǡ][azڢh }^OSO[ƚ'E HMBO{-c'>ӖըeQ#ַ#u6HcyuYN;&ZֱzԺvzҠֻ_ZQO{Zkj] F͋?z/~ֻSZj75^Owqe?r$nNm5hzşӋLz ޛQ6*]ֿ=EşiS=Lzڣ:,|2-qԺN; gK: 6=m盞E=mڛY5*]쟸D,tSO{ҩmSxӞWK=YMzڳ =M5PO[2eL?[dֳzӞ4zsXCO{nzsSӞZI}s վ쟚A쟚Y—SZP1FEZW3iԻPKa/NIhyiߌZW3hT4.fԿN\ u.R0jԺAG v(OңܿuԺE;L[v:QM?;#׉b O}zgu׃ZWoOFO?ʈԢJ j]ik:=mmnQL;4=A6-UJj}Zjo j]e=1=Qsmj}jZ[ZèwPcsǸe=1,uzڣ[*QO[L8a>6-јB=m.azc^iXZ{BOۂܦ=,Uzzڣ^8e;e=1ʥ-Q.]ִ'l/il=JF=.F^#7G6boF|kn=F=muz'f3-4/O=magi(x%'ddX_C=~ީ}G=^-?zBq۸n>_mmgq=|vmgq=|vmg >?;6۸n>{6۸n>{6~ggqs6~>wjb{Cb?O-Sb?O-Sb?oO-Sb?O-Sb+~jZ~jZ췧~jZV{w~LJWxCxTWC7a)ؕp!%Fq]? e+/n4\,r:ywЄHR%65ahMWJ7,=+;.$b 1>؟!|otg3D. bwF)__oʧ=˭Fx G~kBwmn`ĵ]7_^ G5:LxOM?v:.:N%]໺B`ߣ+x6,p6 W}Էucws= Lo__)4]k?~o^?/^߮^%E?__of=p/ןSO$_O{Ե#rﲏkݻAr)P@]q<]럛4Cؿd!R34GH'dz ZCv mE_Ifp.h4<ޅ16渺=mT]dz0Ù:DBYWƍdpUS~~_}kE'3 qK9qV43Ϋ~%(x$cvr.Qo®nwQ$9,=c:Y?9 qgY9 g_=g!ߧW0eh7)1ű3)1ű3)1ǔJ$?&t2_.Ki]A\7dx__"~C,$z%A )A_. Q',O^_QyX/7&!f Qw&oݧƧWEe_]g502^o6v~2%ִlm.(kZ6E-_9NI]hXA~4+GkʞiOwkͦI߻5,h4Zs /hͩeFk5?[sj nXkQR޵_di>+ʼ'o;g9tu6})E}_c[endstream endobj 31 0 obj << /Type /Page /Parent 3 0 R /Contents 32 0 R /Resources 4 0 R >> endobj 32 0 obj << /Length 15558 /Filter /FlateDecode >> stream x}KǕ䞿[ ckc1 e!rC܃'"NV%M]JH+|W?=a=ST׏y|T߼7~|U\Wlx5hokWoëߟ^E<|{s}F~1ӈy4Szc/}TV[y߾i>/AOm S^ %է֠R=,?=?:q}Pfb=S;[-ncC_fƧܮW>:e{G ںA8SHG J޸[RBމx5ѭѭgT·n O֭G  YʷKL) agZ 'wwe1`^R) >Dة&O%=@*`)`nO]W+o5O)뾙@0`Q&x)B0Of 2O1c!w#3=H!SGOfcOiy%sLO6ɬ/ip1sPY_̒seb[\̃ '‚`(08y}; sYn+҂9@/My'%IfIkI3 @0 yr@ yI}Y5f#-6+ÂK/94mqD2) g^+ \nu@ָrZ-JQ|A0kLfm Q(Z̍CԖ@k9s92;"gS,YeA0sM Q,s0 )JZ<.BѨd\l̯ߜy  s \74fp1VB^1h)ݙݙٓݙ L86s'1͜Ŝ̃!XcܽQdjg~nϓp1vM`fc 46C.(f|<k[ >(7@,l` \p1‚bƤ[%;`5;Gݤk$88!3't{Ǔpqcd2W.Pkӎl/hfՂ`uk28',AS̙jڬd^Ϛ 3cA^̉zʂ`NFI3d\g#skA061Dd71d:RidAc sMf)f0Kb jY:݂`EMޙ8,é 2g 9ۧmb9&#FqF?is^17V5ۻ~;}6ppTQ|bxRxc\9CS0u#C>¨1 @)Gaa% fq$7~/92/#Ip *LH ,%^&&~h‹pA@݁d0 Gag%䏔 _] R^ۄi z!a㷽-:6Qam= ?sp" D0#>MfP?K MUl"j<@7xpc2 }p07n0,t(3D4ZDooT "0.U`MM/eH;ǃMDr_2 tã\h;<Ղpmur6*pɅlkaOO1?j~B_wY 7lC8&9m+0dr|FL<1 C0Ɵ-6U? ?i=^>J߷?h}\1j%rù–}>iX㯓P4 ɟh7 ;#e&?fWCN3;la7~ڳ՟IO\cH8*׾mQ0?$d@7DDOAmpex{C"t@2'0Dž?6) Wz"}=I\_-qJYia')׏H~pT l_r0hQ^Hظ s=9wj?+f&18b 塅/1z0É,hpCV9p~q~O,QZ[/nf_p`bb\O swwop{<6ZD:w W?{:M=qhq'ͪ''X`U@s|Y/ O8 dru]z/\ oǭߚkeV~ch0(pT)rR7T̾}J(!|[?gPnHZEwaxÝ-)+9>[~ق/PG JDC;n/ZA|hr:_Pw_Pբ2p( o=΅lG G?EEjA )cZT+Tx:LpBp+p1Z ^ܥA.-:8 @ )UOY*UƟ ukUSկ` <RhPݖ-_@íWo,-"_5HjUZIWI9gw-%wYeZ"e-]?d%lg{PhMP&A^6~sp()bV"`{?љj+kO6&漿o%*3 _ Zek/4hI_"1 ~jN&-uՠu7Y f5 0QE ao߽m ? 䟲R5xL*F+L$9  >~41[aw0f6\ڃ?iX0Wg=O# }XV_d5 D~Ŗ ޾) d3/߭=߭t=*3ݪa7+^i-qf^kRw|ÃJuzMj`>lEz+MQפv'^^NI5nmu߶ޏ^UݭqfD%^gƘJΟ~?zMZkbQMX^Z+1eX^ O]^)I^yM&EVNI;ҮB _Ԇ޾2^AIg&#Ȫ<5Y&#i~zM, (&CM/XH6P̂aOd 7E:6k2?ܙ551bAt/ߠcN=:upS_^<} $lflOc91տ z8& z$ 1ѽ35p:4_OxM[ f B׉ ב Ù!4/f$3ۃ1&W&b<9ݫ ],9[S`f~23?̓.?OxMVBgl G3>as|N*t|VίU^֙gɎ+GoW4Okvk' 0&}?I‰# : <4? /i bI=?&+CW(W}DB~Ɵ4 az\ ~cS<pb039 CnEF&^? _dž ?p}6\ p(e3lQiml%6~6(6XX(m?I8ZY?H4ܹUb :b44 ~5\%OdapLá EjMµ@Y쇳uWfb '[- ? 'Au?pJ3?d/1%/C&v~0>|p }p]X&/b$ްw_/"j8:;“·_ϓ#aaQ>iH)?j~Lp>?jMٟ)e~ \}=Oş_S_l)Ο<9^S߂^\??Ԝ&ao#k}p/zF~0/``ۗ!,~5d{·ԝy{SUXc _;_a&䑅S;r|a?.l?ۋA+G=9o쫆'cbu\r"|}_&{9?hmUW O&9)ef9){|1I`xzNL'%z3I({fxҿ=#QP.5aϝÝQ?3sd2&}Ҏ_Fy-3I.>oQ;ޏ'pWԳB"0IVTN%â'T) [Q .y(1`x2e ( ywLb\hs"vdqp k@8Qn%"P"pp|rZwiu׻8Z{]=v㋣CV=z]y h}h!|Kw9>z=ݢ7>VͣO`ɍVx;C>88rp0i,4,">་]s2m1v {l|18z1&|c6o糷y[޾g_8>m-`x.#Q^o#?AuugG D->EJOs997ZܳfjQ&ly|IwƇWbwկ{0Y -DB?>ZHyo_=~WE̾'͆ g}}iڷBM|[y"8T=!癁So 9 ~Ky ░Z ߾12>O~F"S þ?}??/᥿8q~3|4|K8[\)|K8O2L$?gYW)?o<~8K?|z~uKx|=z7b~xT3L>_c=_^~& ˚?@WQ $BI1_z'>JGl(L/ S-~q >ZBlQz jn%e(wjixv|xxb >[h>0h?w@w2.\uj1Z 9I8xNREjA VCnF3gpw|1y&o oc.LM:1C:8%U\8C6V/qyt;!n1cFL81oc%s\0m\՜6V*U*`ҡX/txǤV`Y||⇯|KǴ~ƴ<`o7o=&O`_y&W6R^@jU6a`6 (rg&qgؔ,JG<5_rLׅ#U i,"0t]lP :<1GE>%Ox2ܭH,/;zj9ܿ/QqDꏪ 1s+pڪDOKtBEU&*$%ed&[i*TJw4KL`"8nT#'XU DhlյxL. G|l,چ6?וꄨVT"Qג}/4q?VS,Qb=P|@(toڅXB%h<^Bt9/ăBnTˉfK ]Cqq"ԎJ:ѸޙZBuh^p_UucG`XlBm{xv܏[.T‰LrN4 &٨o;5SpqݏU)ԮGP)'F7jOt'5WFaj=Ѽ O_ss<8Q[}Ўiժ &3`/:%rSZfhQjrDĢ!!{d3iUj\iU V(JY4Zg&rT/Sx%+ đˢXB8,YtVUKV Xپ,KE'}2CP:B2dL(F͟hKhezHU5< Q\pBf3/?v:x"Փd +T E* L\ukFS3ÙV=T@:5&jҤG^"aD0 &* EMU"Q \OqjzRT9"rT/,q6eYw j*11tY\vvv]DֳZ e L-N:]{EkDܗ_!"iVՉHvu_4dt,Ѣ׌"wΤRiURk\LQnٻ#GD,><0ޔ*Z-S 7Bj =Upװ=465];|53O6A мo;'蝊惧",-ɂM盧]nm>$hGju8=)t9#^jRPg1 ` Etd׋Ω]41d`mRoݚ:fkHX5:]3%O]|,sw܉K;owMk~DZkʶ1^?\ X˟쿅~ӤEwU3s+I>$b,hv O5|1,b{]]Q2u$߳3.S#Bs Ew%y^?|hwX:T,[FIω)bg@CF5&k{~QjT^6sܷx*Uo7-oRǕ :gyN@ CX}'!Fxd.1m$r48g"?M"VnR$׺|G&5JjEf}_#Z~8CS{5:l#߮|8|9 te=1M_HX? I?0"a9$h/*/\[ "Jpu4+b _3g_?8SQGWH#4/"uȜ} 9s-ND&7O/l̗w$2JqxaǏ?1~[ATG>?w)CNy:_&4"/IOX,Ӧ`?8>I̫J^^8gkxhAB_Z-c\ ~4 D֑ aL_P2ytq?v̍CwK cWCu . e Y̰10p}q@99h'j\Z0{2\o:?DSr@m V",p*he fefa䀂SSh C0O9EA5 77Ңy1Ab  rdىss|x 86cr}Q3z̚$R(QxCṽ(ŠCqG >GԸ5I65},gH% MT>Pb G vGbh2{cG p`GD`@2rs `xKFbs'ٽ-9ƒf c,ɕDtLqp$0Ū`)1(Ε$Km,aUxI1O4`G](6{+! C]c!?p G$[ǘcp8?j0Ӂ'm |A"uQ ft3_FR zF?>&\2y6GqS(;$.]x fsk"1Dc k^8NrdFidpO-Z,R]]okF(:v͇2HTŰ5aswkDrD6E9 GP-ÍB(V O`W+S NC5P\vE!lғ(} }$W0Xʑs'@VD&MՔ<҇q 9ge`{0Gl [`iÃmD,\;0wAF%|X2_G+ِHz|߳b75,ƁRx$fi = –0)|batN{1u{%LRQ eqM)E'bbvJG#;'B)0KE [Q&dG"XQ,_e )k $R`S'Ö/|~}ߖiY X,7Ԇ|Ӑ.n!*NŒ. 7XAmya5>X< BA3pm 0@_ N܉X pNռD2ڟ,(qb"_!1~s gѝXpzퟣi=@:ΖQhl=OwZyAϿxLaZ|p>&Ov3lgڟOң0O-X1BJgaGH?䭑ōbIxp>VD=+m0XΎm>40d~(ÔtK/8Ka?[t ٪t=4iNl󡩦Ӹ5 S2/i Ҕ'F_#1Mga قmXF|elaȓS̔' A z6p"r wbr=u˓Mx8K =NOa/z' nLR)a ̬Mu#asgΎ3~[c-dx<V0l6SˁƌP ga~,O6%B`j:#^Yxr<01UY{ Y9+kg4a}&OVVϪ߰韖46` ]2\=Ϧފ |hhϦ_+Flg93T g$XO(y 7>O_ -p){e0N{I'J#xaf[?g.?Mlu}he꟞HaݏgW#M`.Ma:XQgWK?0Ϯ Pg' c"هsD@Ua?'+o_= *|/O88 1|$lΜgq<{я%Oޯ< y01C|(?}0C~lhb8cǨ5j o3vPZ[?!80mty^qjr<9>Sf?F߇f~CF*OW(OJ?.IRGYTc0:ZO5ud w,zݨW W,ӨO12`5ƣ,۫ W,~IK^֯Fs'l?Y5W| 7lg~o6;O3;ga[/o^f,LlgrSLZRg{?C~eKxSLsPL~tIYgD_?CG" =_~Ϩ㩖. \6FsuVJ~i+ICTyÓ%S3ꠚe"ɳcogqbFoe23On<DӦB?8ن 1y1x/ tr+s]S߬5r V]IvtϹ_.&Mba͂~9u$ZϦ*TIQGj(}] vxRuz ^Ρ3 ^;}]xr{>G8s]'xD<^[E` ^ϽOt${8BCa+Co[{ N=ir"/qм}X~ ' 'JVB;kuرUXA4#vuq8¸-Ϡ#k_?c>M(A<_p"k6{gI߾x&<♃u~؁2߽ݛwO =jX_(o"'~eeendstream endobj 33 0 obj << /Type /Page /Parent 3 0 R /Contents 34 0 R /Resources 4 0 R >> endobj 34 0 obj << /Length 1645 /Filter /FlateDecode >> stream xYo[7 BPUԏ'b+V`6ء!sEdӡ'JRDZg;I")"UᷗJ*?)|L;/Z oW?8hfhw_gI(q9>0 0yY*U2a@F!‚lgh-7ɼm]5RҙzQ"@G#aFno‰ )%d!Gbu8#6 %:N8%ndԵN͘k ^J F+p"*'t6e8#R2Bs>%ύ!IMA>ⓣ#|ѣ \LdT=pٺґ((fD5"5BQb,Ovr@n A'lnG8"J D-%-%-%-Q, 9w\o0<kx"G@; .B3ǴSC "H@Tu@%vl@o6/t=w&B}G48^gA'Τoʼn:矇ΏL}gI;mJ/(G pQvܫm﫱ǹ7ߍx7evQQ~m{ wf/vVgh&÷1k*%d|]v61ڔDDVyP晘e2%bx8ïrB)CHH 8qRcSe7Sug˓tc9[Qf}6!ywo*Cq#Y}:x˘i]'hGW<1Fr}eo3Aj[7humѺ~W76^vw|q@oAYSyxTh'N.nN?ڗmɀ7AQD^wō?˵X^jEFc,D(q^-ob~sZHh^TD x,O˫+太$'GFzdѥyh|F֘ R;Jx!}KYH/&."қ.x2C œ12f 1}c279lGʅcF3Fƌaa@awb)u22m=ca#cnWY'㉁ sMn:xi`GӬ1gDl5ua&353o7&/(*@] 4KIHLC:`AR-|biEFKhZ;)u׹*7u e6M$rχ B9Q1snLwM= ІTts^Vej?eV> endobj 36 0 obj << /Length 1644 /Filter /FlateDecode >> stream xYo[7 BPUԏ'b+V`6ء!sEdӡ'JRDZg;IHA| >v%trʦ/W޾i_gb<lm ? %.yIfiΪVA  NFEf$󶅮wHIgFF1H:J 3mp#%F &}#NI-!k y>ca-qmh)t&Cu8nL]e`"5VZf0`uHX aeTU>ѧ)quzlȐ)il|n Il t9 -&md""祇c֕?@ڎi@4^#,QC,%bpלm!w FȐtrv#I]""]BB]bb5 izgAN' { #.t1~L+=5=  AEY'P PbjƸ ckByg2P)ds:DSk?=&trLZVSqyh>D{ٶrArp wew˽JI{{و(zRPhe&;'pwl"hguf2|{>k RJ &FrBhwJ?#ʵ<[ƻDoyUv<sii=$6Nj,}|cy2XN<[=gk3l zH}Nz!ଌuve4ڎxbwtcƣ+u]#].y4P&o>ݲ ޴yZh]ƫunNus | |`p<@R&du7>eڦ{Ɯ82F:ɯN&܄uY'cΈj5s` l œMfdkf oL@[oPT0h(*jt'OJ'[&Ӯ6дvf/SsUolz7\4=6T e_G%U1U7u'$CS~4yi>>Z[3wodk&9;9bF1499 +T:,=9O\Rsg\ƨ}<8JSyOt<Fxb.V}㉭2D*_jލ]S7{.:ٻ^hi{K6{Sq%Vd1/cYم(!ط ]-W+XDE*/I%A@% _Eưendstream endobj 37 0 obj << /Type /Page /Parent 3 0 R /Contents 38 0 R /Resources 4 0 R >> endobj 38 0 obj << /Length 8458 /Filter /FlateDecode >> stream xŝM&u+ޥpMne$A $A"YY(#9C#;>sn{D2Ze") 299]aNNW>"[V"+Om@+w˫I0n,W}4"{SYȖtEr_,}K5B(fPVB([mzV Bj7ؖ\yZD(zeeUeTBzQB`}ƀ%BڂaEƼB~#&땡+[xhrQє5 r0B"فCzouem B\]9v]sVWN' "ȍ #sbceke K輪Xernl݆P㌣+OxlMXѼ,6X`8zNoBƿ$r.ѕ٠da-ƕID(C2]@%BfUj˕*]9 Y&;mQyrx2tjXJ2@&B9 C(.*2Q e 6Qq3t6FvǞ -'a ]yqDcI2ʈP]#]"_r?8ʝc4Ynʃ+Oe]bEg@~bfP1+p*6+[&ٽ2+;sCWl7*7%QۇrGCuteʃ]+[-׳cpe뮙ʆ,,> Bp(2gVNWYTѕUN*WW8Ml^U';2CWޅݵ+dsbwDʚ}b0t4 Op0slWVel37ϨPhxNEn+ni2"{5t1td*W ]"re>"3mpmЕ^TXj_>[l]Y1s]y(͕ʃQCR\2'ACWȮQyJSyr"7:Pl(|遆CB;j, +#{'c(eoRi-Ff<Q̍OKVe)P-(;6 VFf-(;&d$)){ĮhG)r&ʆ|#(_"͝i.Dk1rc#7*~}fygFʰ2O ed(e3WYBYBٻC){;2gC)$Z>3QʾL3򱈝Evepg*Ӯ<ʓ &mTQ>5fg5rVd)e89)b,Aei0z v#C8<ʃ98J9CR rUs2?w}52{01rBdn +0Fa(eoeR]G({n(P6t FE-+a>0rmcNl eoe002W`,@Ux9M8Xh<*DW,A ˌ\WK(|o e`lʋ+CWVeX2z1tCm2->hbHgdo9 E#}A"rf F䢪2:"GzTee7\r؅4m,#LJz9szFwVwvq#1ؿ]}q|:Y`觃Q~Jm` pö x~e f`o0˒]qFv}YQUl3&[1'I`<+qY&0s[2oB9U%#7C>VaW6R(FƅNB;_<_ZS]_܇ =lp*+7/B5Ok+ [AgKb&>dsBKGĆVygG G}5VoM0m@y`/ۧW>)=EIJԗI)Yv}-BT]ͮlC?G0h +{pkl3FO3[]a-?bsI0,?1l u6Fp&賕$n&_ xĉV/:œ H7\(p8v;!~NJ>AoCaYn,eJ#n}kr#ICL~i/mafz[vC#_c[{*Bɇڳ\ >_c߸͜,Oc>? *;KQTkƲe['C1)M߷n7Dl>&0₍1x?DaKВ~?T?wxc VO2G<߹#>kz Tߍ_:"`R=w u6~w^QBTi{ux^Vp܉i>vܞcʑ kxP0J鞮Voji4q{&xi M#iKg-"Ih;qvC٩tVN[Y{I[YдeᴥET泲jcyP_H4moz3G[m-$)#m%ɽ(I]탗㞶9ߕ6{JuKOyn`{y[yZm5Wl_U~l |iq/q/i\[{o2׽]3up}g9ݿk(*K#4޶g/C J'9Wybݷ؇.ƀCObpUh!bT+1j/X>vg3-e"LG(y7U=9ˁ/r~[sYr\-+纶,.=Mg˭QKN_p@3'8W NjP{ ;A[]CƗi\ehnHXC &\7_(`>Usc:滜/IOՃۛ"t$ N10Wb qӪl( ƤmP0 >N:M iWg8ghgyT;륇 %ֻ">M(;mpb̘]_?M跬XwZ4ܹlY<츞贵Lc{YN$K\mbsן r}z>r.& >Å6hny}@wT^VCiWdn{WӞ]]<"\}OڳK䏬a2÷2w)~Ey+)ҷž]%ٿ -`W=˞6iϞg7gėpx^_o#9^ {9sUO{S!=>Bi9=WY;`s`gBi?;iϱWƧ}s}!YB,nWks59ߛ5"v}a~~Ns "n>zx4{3ƿ٩_՟N}yρcf<\q`|s㠾"I6EEsPDLKvaR_[`ϑI3#?h11r"7|)?ECx)=>^&/G^ _{<r{G?Q?J[ӥKSoq|C.>n\:\? *?4>BCc='OO='j?ǪԗW:)"uD{X%ʫQ?Ë];5'<_NrLBMWaM[C 7G~]D25|//o?Xz~G(?#v2h d]7]TouEObX_pGc7f^A~}U>~Me/`-M:2ԟ;@b>QxA0(1^ Ft`wR<4ԃ4[g_yFΚ#FSyFZ_*H:X I`c;ĸ#i3p>Zyơc?ǏwC†+ GdnS 7o9p^>kww;nkכp>Q?>c\zy={(p˳pOpop5wÏAXxo5oqqW^ k[8o=y{[!wsn u w 7[Mlnq}K}w/I?(wNiŹ|_}Ŧz16??yݦpn0Y_||W'gNHmUx|~˸gܧK1f sc5mݯB:yP"<>Vf[/?l[u"Ib~+D-7z$flf,ޝgCMz)N3]|ׯ>{l"5jr!7žwqb?ߺG| -u%[p܁|{Jܢ?YGqvx΋"gƅWD]\xdd]S\bW sa{ruڮW7Oi$_/_o=&j_hB<^b CZ^/Eendstream endobj 39 0 obj << /Type /Page /Parent 3 0 R /Contents 40 0 R /Resources 4 0 R >> endobj 40 0 obj << /Length 8457 /Filter /FlateDecode >> stream xŝM&u+ޥpMne$A $A"YY(#9C#;>sn{k>E _O3PV{ F/g:f8I[02-8Yu "gb- su=[[n[nܨm."ڞ-ňPl"mSog0i %=7>~eqqp|wZy7T6fI8y=JTEHD( YP"+:fʽ@dK"C/ÚD!ByV3C(+f!O= emllKcY lm ԰"rc^!܉P^Е-S<@XӨhŚqMXO @!rLyl i vÎ{+'PNWTF^912otP% ekt^U2B97nC(qѕ'Gf[N4Eǃ1h>JŽBf9!ZRFPV#{02C){Ʈ#al7r`(bor:|#"ذlhQRTYg2[Udi+0*} Po`nuX4+O eFzv櫥`fdH eBt+X2,l!6 MDv@4137 鈜 rˢȾ _nU]9E#rQUTr Fva#|=j۲Dz.IrewBWjʶNIDWɑC=Ԝ9Wq;b;丑X8wC>,0(YB?%6~p~W8a[O}K?S]_f37eɮ8`﬇(Wv*SM$ku^E ,{`-g7^٪!vi 0+)kO~B'J/ʯN}) y6dGV}pa]Fԗe!њ 'N?U~ W{[?#ubӸǸ۴O.Yi@v.t:8r3ǜߵUX쥑^yo[᳗!%ޫ_aWE[Ccn1[ *yo1*5,Fp2][o&# |J9?-x9\9Gsŕs][wFዦ3q[(%ݯQG+{'5wln(=i܆o{!ׇy 4G47g_?x߄QU/01]ۤMyQC }vo+1ȇVk~iUz6aMr{c6(XCOOi&~r+33Ӽ^ÝCN {M&Z6v8U1fLuЁ 쮯a&[za N-\tqD\O,lv\Otv'%Z61OZcG>b=isN{^TqsEC? YeB~v>u;*N!G4+|S`2 Zԏ=U+iOB]. h.'%GVt[ kyb[iO[aϮSxk_I`770hOE9C/ٛG {3ק,A{|,{Ƞ=>g7C'ЍM,{37n_$;v' aF]?x?=.{=~Dװ7y }OlLhaN^h~ {0ǫ܂ef}gOqسX3KFg[,sg7k+59~GV`?b?d[7~ Jbs<=UԯOg}n1S_8q0>9B_qP_K$?A9_xVi%~0-sH~ϑ 䘿E_9isgYc[<ڔžLOK/ؗrw=~a=3?4_#ޟa%w-Rť)8q>b!_7?L}O{yB؟_IsW҈''5OkbCXNgp|cU+`:=FըEۮq~z'9a&q&+ư#\A׵5_ZbnqI}9$&:y|pVVsPGzП-;a}Y/Z×;s= Bw*vi<Be v0r !.0Gg1~ D}ǁ]_i_`OχY] su :rC },ȅ +_9~a]BD?K/3f-9x(O'GC!7H_~ww`oשS/N xNA> ǃL,נ~=<?d|Ǥ~fvpc:ŃKd|9Y"Ѿr >~z-<? ,~,zɅy M߃?9!Ι*_?_"}OU7C,}Pr~ ygadH: ΌߪpbkЛioQ~ 㳾KƯE,}Wo.^_bn,}Sg_H?w WM 8?*/QjH~?X{}>.˟gg{Vav}yЂ]?|P?>ße930ά9Q_'p>~a0Ӓn!psG؏Wp=_`?6Y/Ҝ B4v ZET8x)+{1CZd.Gp~hD3-_t?sa h %,to| ak} v}p#<{[C?/g6hLbs/p~/Xy=G1~i(~ !{5k/Lq;wx,'E?7pI14`Uc{/1D.:nQLE엱$GYG&W3;fM|D,Ow?П:v{CCt'fo #k3Fo IQ2`wׂG߯z /U/}^ѣ}ޟg~|x2..*7',دXWߣ1f3 C*ZhC&2xަQbYxFO 1(P wH/#:Kb}XyFOKЭW#gWpY#-/Wk$,tr$O01b\?[]8`1`ǻ!aC?#2s)Aas;Qr4ncxw~#\OܞOmwܴ>71 wְ2u:\'g~Xx-x|ޟwoLkU?hC N/9q׿/?q E8q/;s ݎgMJϨl?{.={ڼ½|i8qOYoO[?g; ,ߚo׿{t+q^5ǭ}NXWvCgsܿ7➿_ǽǭ廹[ a~]k{U6>%w;{n—qMnn;y^D[>bSE V~n8N7U,/_>ë}3'`ζ*|K<>e\3|ޥ{3H1vudP^NF~ vdnn\>|̇G>u<>MSy ~›CC[P쏫 hխ[u\halgFF-o{=Jv~ޤ}X ?/Ҿݫ}h߮C=VRg<9qGbKk_|͟=^?~;Ӿj~~7 GO߿y7O|/՛_Z-;eşo<^w}lJYR˖T[-&?}m?,QVg*TʾyYv?8??3y_=] - Gѿ=EZeْfKg{O!c ݻb ]|F53ڷ} o1C+ ]1!r{۽r;oʹ=bn>b|p_CcT?owŨrWM]C󯺡QLuXv W?.W c(zL$5G\mˁR~#.@1I̯xVr7XϞڌߌŻsuu(I=%:©pgMDF |t :vt Nr1}~~AKɺشpouW<\_=1dKVb\8YGk/B']ådn]W\9k;Ɠ./xr >xd }~Os=seO _>v荹~2]*_r9åg'76y\Dڸ lkJ+]^ApN x/Y.'h؉qD[ȟs)?qb.K7Vxn8YGf żRkHN1]T/֕aL?!z.|/n2[|PO돶i_j$x>c|v|vq_=F_ُ,e?^6Ym1ndY1d9b&?w}J~2cf?yޟFsYkݟF3otu?g1Nuz~o^)_埻3ؗ^ 70 MH?ðT dhVW xendstream endobj 41 0 obj << /Type /Page /Parent 3 0 R /Contents 42 0 R /Resources 4 0 R >> endobj 42 0 obj << /Length 8456 /Filter /FlateDecode >> stream xŝM&u+ޥpMne$A $A"YY(#9C#;>sn{D2Ze") 299]aNNW>"[V"+Om@+w˫I0n,W}4"{SYȖtEr_,}K5B(fPVB([mzV Bj7ؖ\yZD(zeeUeTBzQB`}ƀ%BڂaEƼB~#&땡+[xhrQє5 r0B"فCzouem B\]9v]sVWN' "ȍ #sbceke K輪Xernl݆P㌣+OxlMXѼ,6X`8zNoBƿ$r.ѕ٠da-ƕID(C2]@%BfUj˕*]9 Y&;mQyrx2tjXJ2@&B9 C(.*2Q e 6Qq3t6FvǞ -'a ]yqDcI2ʈP]#]"_r?8ʝc4Ynʃ+Oe]bEg@~bfP1+p*6+[&ٽ2+;sCWl7*7%QۇrGCuteʃ]+[-׳cpe뮙ʆ,,> Bp(2gVNWYTѕUN*WW8Ml^U';2CWޅݵ+dsbwDʚ}b0t4 Op0slWVel37ϨPhxNEn+ni2"{5t1td*W ]"re>"3mpmЕ^TXj_>[l]Y1s]y(͕ʃQCR\2'ACWȮQyJSyr"7:Pl(|遆CB;j, +#{'c(eoRi-Ff<Q̍OKVe)P-(;6 VFf-(;&d$)){ĮhG)r&ʆ|#(_"͝i.Dk1rc#7*~}fygFʰ2O ed(e3WYBYBٻC){;2gC)$Z>3QʾL3򱈝Evepg*Ӯ<ʓ &mTQ>5fg5rVd)e89)b,Aei0z v#C8<ʃ98J9CR rUs2?w}52{01rBdn +0Fa(eoeR]G({n(P6t FE-+a>0rmcNl eoe002W`,@Ux9M8Xh<*DW,A ˌ\WK(|o e`lʋ+CWVeX2z1tCm2->hbHgdo9 E#}A"rf F䢪2:"GzTee7\r؅4m,#LJz9szFwVwvq#1ؿ]}q|:Y`觃Q~Jm` pö x~e f`o0˒]qFv}YQUl3&[1'I`<+qY&0s[2oB9U%#7C>VaW6R(FƅNB;_<_ZS]_܇ =lp*+7/B5Ok+ [AgKb&>dsBKGĆVygG G}5VoM0m@y`/ۧW>)=EIJԗI)Yv}-BT]ͮlC?G0h +{pkl3FO3[]a-?bsI0,?1l u6Fp&賕$n&_ xĉV/:œ H7\(p8v;!~NJ>AoCaYn,eJ#n}kr#ICL~i/mafz[vC#_c[{*Bɇڳ\ >_c߸͜,Oc>? *;KQTkƲe['C1)M߷n7Dl>&0₍1x?DaKВ~?T?wxc VO2G<߹#>kz Tߍ_:"`R=w O{N+Rȑ*ms.o+ ;4ӎ?=}ljF)W9-]m^<#=B:&nO$O;m[x:mL7{3e_$)tW9nn(;i+cO5i+ V,tJqӾ|VVml9 3ƶ>^oz˱-[=e$w%k}vӶ0x_ni)6[y[yZm5Wl_U~l |iq/q/i\[{o2׽]3up}g9ݿk(*K#4޶g/C J'9Wybݷ؇.ƀCObpUh!bT+1j/X>vg3-e"LG(y7U=9ˁ/r~[sYr\-+纶,.=Mg˭QKN_p@3'8W NjP{ ;A[]CƗi\ehnHXC &\7_(`>Usc:滜/IOՃۛ"t$ N10Wb qӪl( ƤmP0 >N:M iWg8ghgyT;륇 %ֻ">M(;mpb̘]_?M跬XwZ4ܹlY<츞贵Lc{YN$K\mbsן ir{}=/˹?p ?[aPWUw)0[-*{'w.vOu_#+|{-wv-]Fd_Q޴ŧ w{sg)v{yG{G/$kۛeo'"!{T #A{|oXf=>G~s=d͡s& {/ `~ؓWFx}zA{<s=a?"k؛٧G {6ha}q/OK=hang~ڳ8M,?#\3>Wc>}c=䰗<^xx\/}i~8G:N{<8*zxag=hg6پA{6cӔ=~(Qѿqe:ekЯ'}g}}O~>X9>g2zO`NsՄiߜgF-msg9K賿5f }f ]_n`AEn2Gws_%9vovWS_s>٩/W88HM~~/Qc4Ӓ]?G}ז9swR?GLr_~4ō9_G 3sQP1-mJaOIQW;C?EJϯDOԏt)C8`/?WNa߽*啎sJHV~jԏm8GeIo?=OW聓0ecXzb c֠~auZ/eC178|OG菉<>8+9(tb[ =ǝP,ҝaw~|b̿L2~;9`CG\~4`/K,ɀ.~9Ӻbbldt>mB`ׯ]~_~|"ß v}헁]J M.˟gg{Vav}yЂ]?|P?>ße930ά9Q_'p>~a0Ӓn!psG؏Wp=_`?6Y/Ҝ B4v ZET8x)+{1CZd.Gp~hD3-_t?sa h %,to| ak} v}p#<{[C?/g6hLbs/p~/Xy=G1~i(~ !{5k/Lq;wx,'E?7pI14`Uc{/1D.:nQLE엱$GYG&W3;fM|D,Ow?П:v{CCt'fo #k3Fo IQ2`wׂG߯z /U/}^ѣ}ޟg~|x2..*7',دXWߣ1f3 C*ZhC&2xަQbYxFO 1(P wH/#:Kb}XyFOKЭW#gWpY#-/Wk$,tr$O01b\?[]8`1`ǻ!|C M!(ܼ}헣p{_Cq"wܟo7}|j#p鏹_xv=Ǖ1 >8#xϿ6nƳ{{eZAmNp½|xqY>~ [/‰{ݙSxv< ^oíWxFe{s!UKY{o.=}c=ܭW4j︇~kߚ׿^ӝpǽ~{u:a]qoqqq߈{^3Cn)҇AiwoW{˗nߥﱻ _-~> 4Q.ӊsyn߿M %[cm~M8Wa&8o8~OϜp/>8ޫ-qiϸOz c ϗnǼk2=œ_Cy;-۵|ru /Dx|̶/^l,<=x2J/y߳؟C̹?>˯؟^~<?\r>xw\݃z>wa:oӛO,U,UwoATxScy~bqb(*W߇qM=?2UcV>Z{m0,Ո٨E~ϵWin־ϛok_Eڷ{۵R~=gݪYJ''H iM/׿݋Gw{ٯ4pg7XM|~oVA?7oo_=zKKeǛl9oCoOMc`ӚC}Uvd}b bM!cCӽ^C޿7\WR]1Zg71Z~>rK!1bT]Pfë!WPŨrb,^biwyA+y[EP{qcelq&W;Fl^Ctg\K=IVǎw+\⳷t~;fQQO 7.-'<],k`%7ni+ق܃Wɺ]Bk-q{]p\aE_2s.6-[ݸ19WGjOn~oƾ=\#/YU~%wXW-2N֑DZċIpiYהWؽ`U@X^\0O]Ѱɍ?RXjn]>Y WMO2P=糜Yzsz1bzn1}>Lj}>1Әebk><&6yM#m|,+}|,Gg1SIO|l'p.k0`&?፮Nw=۞u??fiN_=>ׯwX> 0s7~R{ޫ ~xg MhUzJendstream endobj 43 0 obj << /Type /Page /Parent 3 0 R /Contents 44 0 R /Resources 4 0 R >> endobj 44 0 obj << /Length 8455 /Filter /FlateDecode >> stream xŝM&u+ޥpMne$A $A"YY(#9C#;>sn{k>E _O3PV{ F/g:f8I[02-8Yu "gb- su=[[n[nܨm."ڞ-ňPl"mSog0i %=7>~eqqp|wZy7T6fI8y=JTEHD( YP"+:fʽ@dK"C/ÚD!ByV3C(+f!O= emllKcY lm ԰"rc^!܉P^Е-S<@XӨhŚqMXO @!rLyl i vÎ{+'PNWTF^912otP% ekt^U2B97nC(qѕ'Gf[N4Eǃ1h>JŽBf9!ZRFPV#{02C){Ʈ#al7r`(bor:|#"ذlhQRTYg2[Udi+0*} Po`nuX4+O eFzv櫥`fdH eBt+X2,l!6 MDv@4137 鈜 rˢȾ _nU]9E#rQUTr Fva#|=j۲Dz.IrewBWjʶNIDWɑC=Ԝ9Wq;b;丑X8wC>,0(YB?%6~p~W8a[O}K?S]_f37eɮ8`﬇(Wv*SM$ku^E ,{`-g7^٪!vi 0+)kO~B'J/ʯN}) y6dGV}pa]Fԗe!њ 'N?U~ W{[?#ub6)к6 뫜jk/oLڞf!Oi-+66Ϝi JcfN7stؖ-O2V;tڵ>xi;i[]ist _Lӭ֭nysڿ}*?i{c~>ӸǸ۴O.Yi@v.t:8r3ǜߵUX쥑^yo[᳗!%ޫ_aWE[Ccn1[ *yo1*5,Fp2][o&# |J9?-x9\9Gsŕs][wFዦ3q[(%ݯQG+{'5wln(=i܆o{!ׇy 4G47g_?x߄QU/01]ۤMyQC }vo+1ȇVk~iUz6aMr{c6(XCOOi&~r+33Ӽ^ÝCN {M&Z6v8U1fLuЁ 쮯a&[za N-\tqD\O,lv\Otv'%Z61OZvNGq4XvSU\ПCVgІ-|ʫӪ; _-cp@~ʽtړлk'wZ˺/I{v>=]f;Z^X?#}2ů(oq9EVسD=#A{|5MA{|7 vno{=~K=>7,{3#92hY9 tcrsͅɅNy0]?Ix+#>y=O~˞0d5z^xy{ӣ=aӾ8Z؃Sڧj`ٳYF?S&ҟ.K1B c>ǿ1ž}r˃^za/gzN{ix<.{|ė>sgx#ig{=sxig?N{| =s۳4|Xl_\i?_S?Sg {8IJs|G5SГ>3'J?k,}l3_='|'9joN#䖶9K%J }_>{QĮ/U0 "in#;aVčGwB﯒Xf}wF~7;٩/9p~ԗ+xW}R$&wsPhhꗨ?ޱUiɮ>Lk9;#&sm9sQ?WND||/#(A6'$ܫk硟Xno%W'G{X]avqqi!NOX~+S_0S^P?W~R\U~,c4"r{|=bgDӚ`!9cXJ9%XhQDy5|xѶk#~F+|INI\1ikh=|g1ckP?惰:uFy ֡x'A#wR_leU{:g1-g@X_|e\ݻ]?E}Z{1_PGChc?Cȁ ?pk_C?Q_q`qgӥgd@Cki]z162rDC6r~cvCW_X~`?P?s>R}u~o Y f&: Bv{p=qDn=ר#/[u#ԋSr>ӹ2|Prv / 5_hϡ7_1_]?s|~zN`<_w~Nb|VoC,}wm ǩ=ρK?Gx)Kb}r~cӦe`rusf$OH_S`oMK_/ԯ߂GYX?>R3*ܻX3b`z[_ogaŃkK_C5[K{ė:7Ʃ[3/q;C_s~p+&u\O߿_5~$?=]_>QXO3=q}Tϲ?wg眨`?8C0 UJiIw8 +/p ԗi΅Qs~U~~ Nxu*x啽!v}w2# ?Z"z/:0s|4~7q>0׎x{8fY we{ý`p4x&1?X?|O8x,!v}cfΗ~?8t ψ`bj>ZxFl|gv<iM`]uѓuh+јj z_c~_xF-O_s~GK<~ o(,N 'eO^j;$Je%>T#'%MuWޫQ8Tެʫ5qF:yF'1.H.V^q0]t!ݦn>kwy GH=ߏͯ!ssv;Ϸ>q{>Psw/_G[ÞyֿrD[cN_kq{޽2W v'8^>8,]V{sS-|rĽ|)vw;r 7+}<|Vk*zQ,_=7gើ?+q5wÏAXxo5oqqW^ k[8o=y{[!wsn u w 7[Mlnq}K}w/I?(wNiŹ|_}Ŧz16??yݦpn0Y_||W'gNHmUx|~˸gܧK1f sc5mݯB:yP"<>Vf[/{l"5jr!7žwqb?ߺG| -u%[p܁|{Jܢxd }GoLytQXW3:CdF<;lP7ixl@=˯?ȧ}> IJ|3Kq_=F_-9g1g?V~LLxgd9b&ϷrĸMoeŸOoq<,&wa*ɀmtyeuFd?gbwVg:m߿yKԧ~C/^|7`_v{5/4!o R1'Z^/B\endstream endobj 45 0 obj << /Type /Page /Parent 3 0 R /Contents 46 0 R /Resources 4 0 R >> endobj 46 0 obj << /Length 8453 /Filter /FlateDecode >> stream xŝM&u+ޥpMne$F $A"Y^(#9CKv{9=Hd=M)yyN<~o?t[?_>ͫ_㿾}oן<^*Y~h->տ?~Uzë W|r5%=XiGMDO+~VO:}_)_ էaͧ޷+B^R}F_jOc^Ĉ̯EY=x2`)g0i Ncy=­șXK>F]Oe&-7jj[cp1"T+HLڂgAF0i ϭ_E#t\%"D<?r}VM=dz2YmD^O-k{y:ʽ>-Bw!Dus0Ńemʣⷎv4FG(jD(8,ePMi.A9'ˣErʩ?Fr!Z5j5(gO#Ir\8B䧮g\*;*5ҟ$B̧PF6Z+L22EP<'+?gBrJtV ӕ}X#BMrny5fՍVFro*#6ْPo&QPÊYeSBj{D([mے+Ok0YX l _PS/Jh^yp1dV3C([[5ܘWoD4w"d2te-P.4"rqDS.FhCv>;yH@SﭮlmD([a+®ݰkI!SUc?>QysrNs l!}"CWP΍y`qtЕ5ik4w Pѩ# C(P.8P5T7Ÿ5zP+cD(׬?]]"C;?pS]+'$Kd-*OOB Wua`rQPFD(GaeEE2B:&*7t{ؓB]Y#+/{,2R3Pb#B]kᯋu_^dkWnѕg^Ps,"+ ]yp6t婬T^H /Vl1fZNBf>Ycbu$=@sregnʚFD6*wV~PWhl]y7tez֕{`wcBl5<\ِ2PeD(E3+{:r9C]IЕy}R-2rXfC߻06t^TlVEȬu3"J1C1Cy)Ԫ5zʺeFp,eD$%e(P]0bkV#ͅhm Fn bF%گϬ>O<>ZVF 5vPj6K({3K({W`(eoGR1tPl(e$X_kݧc&JٗiR>3ȮTV~ڕ>Qyrd>8J碆R~]c"lRΊ,e '#'EX9?,; Fnd]y>pPyp;'G)@?g(PUR u\tPPѰ2RfqP1FNlѭ#a^7 Pʞeot ʃۦ4H3%#{6,Fn-`,U)4ٟ- tFZF hJ/ǣ)k]"Gʓ%aj)m=lB]yq~e7VK[1n9MCS2%M MC:"'2õ耾xD3/8#"cUdWc\TU&\B}X_lƀKRܸCЕƢSѕerP5g@U=9n$q=7/O? t#JO l܃}ySavԯl`ח fY7Ψ5;a: ]ʃmTd+2 g%n݀WC?~>Xzn YF30WA?gdus]pv* vF vӨ߸ItGS_kJrp .YtU\E|ןQeYH&I}m%`+hlbC,}ćlB.V`Hذ*lCoȟ!v`-⻾(e4vܒ''Q?I2)%kخE(ꗱ-`'з蓵|WbE{/0v}mmƈiF|?{? e] s. >%GQ}4T-NqY}-qK"c}ž08T1# 2#[gx,3m 1[y-/>`MU__{rZ8CW|/MW-L1aˎp[{k }kO3[E(P{~ $ZagkSR0i }tۇGQ{ACE#3}}<jXLp˾dc3&%֍WCfC\U=Cw8lIZ2u\g oߪ_ ZF;7rć~=~\/_1KZl\ p"~b{C{EU 9RmAׅuMx[|%iviq{zܟ>6)к6 뫜jk/oLڞf!OiдiKg-"Ih;qvC٩tlxk;˂( -].Eܴoe5Ug΃B m{כ9rln'yOi+IFI:n-9W[|{V^V^Vۼ9sc_?Wo=۱B?uڿicm'V4^ [uoyLlw_9cN*JJm/KQN{TH^{zWE[Ccn1[ *yo1*5,Fp2][o&# |J9?-x9\9Gsŕs][wFዦ3q[(%ݯQG#+{'5wln(=i܆o{!ׇy 4G47g_?x߄QU/01]ۤMyQC }vo+1ȇVk~iUz6aMr{c6(XCOOi&~r+33Ӽ^ÝCN {M&Z6v8U1fLuЁ 쮯a&[za N-\tqD\O,lv\Otv'%Z61OZcG>b=isN{^TqsEC? YeB~v>u;*N!G4+|S`2 Zԏ=U+iOB]. h.'%GVt[ kyb[iO[aϮSxk_I`770hOE9C/ٛG {3ק,A{|,{Ƞ=>g7C'ЍM,{37n_$;v' aF]?x?=.{=~Dװ7y }OlLhaN^h~ {0ǫ܂ef}gOqسX3KFg[,sg7k+59~GV`?b?d[7~ Jbs<=UԯOg}n1S_8q0>9B_qP_K$?A9_xVi%~0-sH~ϑ 䘿E_9isgYc[<ڔžLOK/ؗrw=~a=3?4_#ޟa%w-Rť)8q>b!_7?L}O{yB؟_IsW҈''5OkbCXNgp|cU+`:=FըEۮq~z'9a&q&+ư#\A׵5_ZbnqI}9$&:y|pVVsPGzП-;a}Y/Z×;s= Bw*vi<Be v0r !.0Gg1~ D}ǁ]_i_`OχY] su :rC },ȅ +_9~a]BD?K/3f-9x(O'GC!7H_~ww`oשS/N xNA> ǃL,נ~=<?d|Ǥ~fvpc:ŃKd|9Y"Ѿr >~z-<? ,~,zɅy M߃?9!Ι*_?_"}OU7C,}Pr~ ygadH: ΌߪpbkЛioQ~ 㳾KƯE,}Wo.^_b_X!n}O8ӿđ~ }9¥qpG(?#v2h d]7]TouEObX_pGc7f^A~}U>~Me/`-M:2ԟ;@b>QxA0(1^ Ft`wR<4ԃ4[g_yFΚ#FSyFZ_*H:X I`c;ĸ#i3p>Zyơc?ǏCF;JGdnS 7o9p^>kww;nkכp>Q?>c\zy={(p˳pOpw?g; ,ߚo׿{t+q^5ǭ}NXWvCgsܿ7➿_ǽǭ廹[ a~]k{U6>%w;{n—qMnn;y^D]>lSE V~n8N7U,׏?|WGgNHmTx|~˸gK1f sc5m=œ_Cy;-۵|ru /Dx|̶/^l-<=x2J/y׳؟}̹?˯؟^~<?\r>xw\݃z>wa:oӛO$U,UwoATxScy~bqb(*W߇aM=?2UCVZ{m0$Ո٨E~ϵWin־ϛok_Eڷ{۵S=gݪYJ''H ?&_˟o"A^- ܙ 4V/7i?ןx7|/_?m?-[ݛ?~ϿdS*ϒZj1_Ka:SR˲1@Xg2ߓd^a!7(G#^9[,w1|)_1{{Ww{_5Y_uze1o~_1[ t1x芡HW{Ev!Λro+G?s%W]1.(USWnbT9S]1o]1{UǠK- oy(= n 6dGm~p6F&7mI{5[g;ϊ\fs![fxK7!~ꓷ&\,}o\[z'NL/#9/x$X*Kn>YW'n-ʓu>‹[b ;'W>lchc%ed]lZq+cs.t遯Ԟ}{dc-G\_f%x}KtZd#w!~ɓ.xz+mc<d~o\b𜧮s/'uwdR?./YGЂed@T^ugmXI.~vjm\xEŅGO5%.v/X 8'V,̓uW48{r-Ϲ֟ڸ~1wO~%+bwxU7F#3uЅb^5WQ}tz ;g ?vьy5vؠnpqt+ z_OB}]G?f,g㜿{[sz1bz~H8f,񚯟Moq<&6yM>yM#mqׇ'>aot8otY0ݟ~FWmOcZ}]/o~[,QIx ^&jiB_=^b C{Z^/xzendstream endobj 47 0 obj << /Type /Page /Parent 3 0 R /Contents 48 0 R /Resources 4 0 R >> endobj 48 0 obj << /Length 8452 /Filter /FlateDecode >> stream xŝM&u+ޥpMne$F $A"Y^(#9CKv{9=Hd=M)yyN<~ox:-vT//in_߾O},x?}͈W_}h_Wx|*=~cU_x{r>9\ӚVz4ӣ&UyGcDKIS+'>HׯR^OcӈS[!d>#e1bDhb}עZӬR+OUc֞J2=fެ6 "T]Ƚ<^B;}9ByA6bvQ[ ;#I5"灂tٲD(Ϧ4W)e"}BK VAPW+2єa lX r>"&DžKߠ"B9U}QsԟR#B9Mߐflۚ'V$B9OtiP.^E\S׳P.UbO}\HD(z Z\&BP(}ӕte3z!Be%rr>ܦ tr reG#B7ulIWd(ҷAyX(D(jfa,gl "{mɕ5J,WP_PF/D(ϩ%4g X2!-xVDn+7"[;k^e(kuMX8) #!r;<\\VW6"0ՕSan5W}ouq)ܨЋ9B9'9PVپDlΫUF(m<08gV45Io;b֋CZwY!mKB(]y *Ob\ٚAr=T(ӕ1T"kV埮Vl\Rܕ j''CW^l:0}U0D( d"02"CIPFgG:CWl=Qy`dwrRЕGI=D(CHeȮ5ź//2+7ʍ3^9A톮<8XTU*/Vyyk+6{ofeBBl1źMo Q37teFzrS";+}+w4TGW_<r=ʋ=0;ͱy WilB(2" "Cyfp噕Ie=]\reeʍӼ>Tu]urQs,3t]]Pq/*O6g+vWL8ٗ+/ CW^,AC( 3yeU6s 5Td(/솾Bʬ톮(S(w@^CW.CGrzЕN*+W3*2#Іj ]Eʍ%ZKQl峕Vq;ѕ53<ѕ\<8*Ѩ<$՞!Qyr4teQ;''rS9J،—h;d,ϯ2w2Rk(e֢`dֺcܘ䘡jUQϚr=e݂c#Zi8bedقc"NFNwAvr`(gl1Ҍ~+܉Bx#71rgY|iaad +#P^FR;s({5%ϙ%+0#C):K({}6O14C)PdW wV*[?Sߨ<9bFesQC){?.1mw6XC)gE^"Kk,T`72,rGUq[6Xvc%)Wn\]]McQ)29r|3GZ*ntGlug`מ7`ȧ~:%XO CHϖP?hc'm>[I▸^n%PaOMh^hh`Qy٭3]d`藦+heG8=r5"|=@?M05))R4>C "Ӿ {UMf,[&e^Qz2}+{CFc3!.ʪOӈ߻Cd -:.C3{G[7oU/-~o9C\f/Ks- ~.sNLVn~?H!{߽*6º&­Z?M;==OOPgh]tZQUNtzKW۵7&mOΧ4 N[hڋ3Ж}PU4ӝ_ivB[BI[YҝeAjӖcrQ"nڷʪ3AB}!qضه]o9ep˓$$vm^ڎ{|W+-m>=t+u+[mtvߟOڞX:416퓋{}V}/]溷˼?}}λ1wm%V%{i䶗FV%xD(w*}$=W+X-1S-\ڼb g L{d-Bl7J̈́Oi>%rAv~#9}ʹ- KpOEGrk(#@zý;G67䞴jnCwPV|ĽfS 7̕FC{`G|owC5ﴪc=0&91i },seӴirC?wZ9Zbi^/UNzG{nO{-N;3:vWO-k=0o: 8"w'[O6;':mt;~imWo'Cdg܃#{hr{}=/˹?p ?[aPWUw)0[-*{'w.vOu_#+|{-wv-]Fd_Q޴ŧ w{sg)v{yG{G/$kۛeo'"!{T #A{|oXf=>G~s=d͡s& {/ `~ؓWFx}zA{<s=a?"k؛٧G {6ha}q/OK=hang~ڳ8M,?#\3>Wc>}c=䰗<^xx\/}i~8G:N{<8*zxag=hg6پA{6cӔ=~(Qѿqe:ekЯ'}g}}O~>X9>g2zO`NsՄiߜgF-msg9K賿5f }f ]_n`AEn2Gws_%9vovWS_s>٩/W88HM~~/Qc4Ӓ]?G}ז9swR?GLr_~4ō9_G 3sQP1-mJaOIQW;C?EJϯDOԏt)C8`/?WNa߽*啎sJHV~jԏm8GeIo?=OW聓0ecXzb c֠~auZ/eC178|OG菉<>8+9(tb[ =ǝP,ҝaw~|b̿L2~;9`CG\~4`/K,ɀ.~9Ӻbbldt>mB`ׯ]~_~|"ß v}헁]J M.˟gg{Vav}yЂ]?|P?>ße930ά9Q_'p>~a0Ӓn!psG؏Wp=_`?6Y/Ҝ B4v ZET8x)+{1CZd.Gp~hD3-_t?sa h %,to| ak} v}p#<{[C?/g6hLbs/p~/Xy=G1~i(~ !{5k/Lq;wx,'E?7pI14`Uc{/1D.:nQLE엱$GYG&W3;fM|D,Ow?П:v{CCt'fo #k3Fo IQ2`wׂG߯z /U/}^ѣ}ޟg~|x2..*7',دXWߣ1f3 C*ZhC&2xަQbYxFO 1(P wH/#:Kb}XyFOKЭW#gWpY#-/Wk$,tr$O01b\?[]8`1`!a#?#2s)Aas;Qr4ncxw~#\OܞOmwܴ>71 wְ2u:\'g~Xx-x|ޟwoLkU?hC N/9q׿/?q E8q/;s ݎgMJϨl?{.={ڼ½|i8qOYoO wF3cwoͷ[w߽~sc{־C'~;o!9?nq_kp^V-[0H]]?{MVӽ*[Cxo{w}=v7pKҸBz&77ʝ}tZq?{".W|)x^?v̏u^?*dώ?>ë}3'w}oζw*|K<>e\3|ޥ{3H1ݯB:yP"<>Vf[/h}s+gK.b2=+x1|w1tb﫲&k>],+y?ؔ=]1tq;;ySq%uv#wy+Fe;j W*g++yϿvWtbE];e'>ru߆ȿ7Ï-5bOf wYk3~یYz.c t&=ݯ_}DkBo}Kĉ~$gcuD X%|ɍ['J-EyG[xqK\잡cA$cj؇mwmd̜M V7.~es΅.=ړ[olK,0d~ɝ.Uu$./ye08\OVu•Vûm'U: 2v힋_1] u@%Wշ㎌ޘ['ӥ%Zp,+3\Z| ]c㬿;8EN ɺ$?ŠyGtOn9Sw/Ϻcq_./ƈud^+^F;O1]T/֕aL?!z.|/n2[|POi_k(x>c|v|vq_=F_,e?^m1nd9b&Ϸɲb'ϷrĸM;0Td6:~?ֺ?# ft׳L+Pcv?}߼~%cZ! />?uכؗ^ 70;MHT dhVW > endobj 50 0 obj << /Length 5230 /Filter /FlateDecode >> stream xŝM7r+([H$pް"lac2E9 )yIc@}S=;!fN4 D /,e?D%K_}u˻?E?|9^|oWݟrY.?݅_(}3~sq˜%k 5\rJz/!Ϗ}*xH%²\k ]m݋ aՇ!?|V}rCðj3H>U:ʲ]]!\SدЦ4ҟ/(lhcjWҩV! [ry/T^r^ò_?lk6t,Y z8%bzcRzmhjRy^$rC:JZCZ=ӔlݢWzMM.lfNeBeR4r6t4ru2V9/{#2e'[wiNT\uSu7vlZ6jAPY\Wc*M%u]xd0ū pzfY,`0 jMg*z8NϬ`V0+ fٮx8NvLSp g0f3U3;%p*L`&0 f3ײxpzۓS)` Y,`0 }W`9,p*Y`V0+ fgY<+*YT8=3 `k ^)!xf3L`&0 fUpz)` )`0 fdnW N3+ fY(z >T8S1p8N `0g]yf3̩ gSf3L`&*k*p*)` )` f}%d\i9I$G#ɑDr"9]e,4g g3əL,$ B,$L4 ͅfd%YIVd%\IqRh.4Won$7ɍFryx]&B3cK*4A$G#ɑHr$9HN$'E9-reYh.4,$ B,$1(N } ,4AVd%YIVJr%`,4J;$ڈ(((sȧR?SmdBo5YTaAϽ#K;C葲eR[P:gR=Hz\5ۧXP4ѾñjH;VO[9s=hJ$d253ا~G*aNZ1}*#cA䨘}{U*fq0;J!MzCaȮZ e,JXG7^3ea2SLPa,O]d\iK3#ز1}H-3ktX#mLLp2LV313Ö^8RL|ҵeL/ǔ_lĮ"{ek839M({8E`MЦI34YinތpI#ɑh%ȉ8_I$'ɉLr&9I$gD㊐,$ |EHBr!\H.$d%YIVD㊒$WJ%\I$WɍFr#2ܥ).)2.+2.+]h2.kBO]VFeetY]VFeetY]VFeetْ 2,4AftY]VFeetY]VFeUDeetYq>etY]VFeetY]VFeetY]VF W].w)4Aft2\].WF+˕eK?f 25ret2\].WF+˕貥#Oret2h 3\].WF+˕ret2ܥUF+˵"W].WF+˕ret2\]\ɍe7D\hrct1]n.7F˖P B6Fˍrct1]n.7Ft1`fvx 2MHBr!\H.$d^&fJr%\I$WɍFr#,ɸ,lґM&f@r 9H$O9<^* 'ɉDr"9I$g3M ,3DЬ4\H.$ Ʌb۱$+jQs/fJr%\I$WɍFr J'[S =2hfɁ@r 9?/A$G f{hfɉDr"9H$gGKYi,$ B,$ ɅBr!\H.$y r%\I$W+ɍfqO/BɖP =2hfɁ@r 9›DR[?o'dDyZoq^q@vw]Źa׷@MYm4ύ6 hjn qg|놠o-tkX>nבWKi})o9*c$~RXKJx:D(Qgڼellޜxs>o.Oy$ /\w3HH-4c{9ϝcO6gsL>CwiaXxjg> endobj 52 0 obj << /Length 5232 /Filter /FlateDecode >> stream xŝM7v+ji/|qxȭdI,pd9!H`}x8O-v\?=<[ۺQ5ۯ\sy{?~E~wwˋww_^݋i;+n妷)a5 ,_iaX^^ohz"򐣎V+Vc4e'[hU^d&mF#UCFc) !]ble %#ވLr{#+ `qg3#f3L`&0 d fGѫ g)` Y,`qԼ*pV8s* `* fYxU>Wl`60gZAM:Ls r i.4WA$G#ɑHr$9HN7Y! ?%șLr&9,$ B,$ ɅbaG/Bsd%YIVd%YI$WE\ ՛ɍFr#@k*^zrf Xm@r ͅf#ɑHr$9IN$'ɉd{/A$g{h B,$ } Br4 ͅfd%YIVd%\I$1! 5/An$7 丂ܥ'whK9`L4 ͅf#ɑHr$9IN$',Bszs&9I$g3B,$]^zb7D˂2DÓDeܟ ڶ_]^[ĽV[pUqUT7ޠR)Juk#^j#YW½!{Zj2? cF랷\ڨuY-@{׍ͿnW*IBRONJ틞S3[ӥ6De&T/M)\7}ysFq2RL.,pUڥ&FGG獗EC 9_j#r}}}cz+|xY*E]]2^7G=*؂~W*Ճgʥ^þ}%EKOY<vocΑtӱ179rIBIp)SS:C}w(mTmEGܧV12DΊW-Nڴ[MbG=jJ_h S{ݥ7 qU[!E +kƲL;l[g*K>sLיTvmws~fzD}[7=#2i#uutkzd NYfiԝj;?yFt Gʘ鑏7>ZYhLF&-,_fJ -pJ(_r}m'~[^o~_"K}ھ\g|kS? ?|aJ\?OZ6Soa']Wh$+27_7_,_\lxmߕo- 7ã _Y>DˑL~ ߮ٿq-_޿O|z=ӵ+?j~XȗYk #6%>$*a?> (8Zq1dal'tϛg{KZð]m~٢e|=>{~՟率/cs]m7f9~q?7ڠO+w#ٜq$3Ɗߧqkc㩝ayj_3oyxx_~}Wo/?qջWǫղ._/oM}ywB5ZYE?eKQv~228B96#:ΎD -c _a=ӖUO}Fnc5cq$M{1s$[ӱ^G~ov,,9t6p:6s9)q3yS{G SYgLyl.:Sڙ͜3N=`Os;wPӽv}+v/?0[8۳Zi$::n;}-tCouϞ$ e[tCL@Z~]Vu'9=$eN,呗t =< &2v;=1V[g9w_<~)n7Ϸ<|tz_b84zO?gz{w;g3T_9}sWgcr>^zW3 ;8^zB`!y0ioXJ]lg*}!ݲendstream endobj 53 0 obj << /Type /Page /Parent 3 0 R /Contents 54 0 R /Resources 4 0 R >> endobj 54 0 obj << /Length 18273 /Filter /FlateDecode >> stream xM.u$xׅo`+njcᙰ/:z9.I=~p2T\)S^Ԃ/STp2QH>߾>Gn@W_6>o_㗿*_2 #?*}矿J/r~v_tiק>V4GS_sק.疮/n?R7_>W_{' } ~JRyk=ZS9|#TpO1}#tSD>|&:kXQq3`_gOovO(-£M.SGq_S?0ۧ~LtVWן$<xNv\j}fe3ZlX۰Yu JO΂`n BԐ!.*0O3Q:ep^`".*a0 kCcΗ=C@cp(ؘ~FИ7ИsCWf`̀JjO̕upe`6sT!U N^VSy}j1]&1o8Zd]Fs)a\ 7sSV*;`dB0[d^*kvBclK 5f{f+L]wy/2O ^v~˸Ƽ}1.2ObИ{SИИwИ@pJH]Иǥmpھ1~cCczN@cٰyL]d!Rp,ֹysE\^iN]UT+ZENKm^!И`O#Y_d3|%v6}7s*~G~^eCc2E݋Ah̻':ww yfCGywPhݻsXur9 0lmsS4~Bw3` 4>\O0F{CcfhU=ƼUFXmhYT;17u}. ^,I{e4F&4pUn xmh}"74NfCcZ޵1Иwm*~yvyv< yvP& W5yqQ74=$ƼvƼ5j|tOCcÍ)u1kwp3K Ǻ n6^aƜ. 9e֫ Tmh̻c{̰1RaVv[@UИ3sVO1Wl-%yqpj&lv 2ݎolhCjUw4\ 2g1&h﷐YoXK U'LLPmn-eEh6Qca5W%f" >pkCcEh̻n`3^@O2D`pmBsra=ۢ1wʆlE 9ov9ԹƼ{B Y̻c9O0'e6^ca`:ywn?2ܙ WcИʷ0ĦmEfe]6&5Tצ+7w{2ʇL`xfZ^'g^bćcX?'`kggHNL60\9~Ób]JVˠ3l{+Vt=64?i?%^l@D`0_O%0/aqmwWɱa3߆'aek ﱊawWNʖkdtpSN91 ~tO࿜!&emyow i5;m&{@ó"1x|_=94 c{{\D%9ˋb0fM1ƍ,_uߟW;p[‰l?n1_4 N7NK0Íş0nJ2 ,1 }*,~g{`+~]Opr,1G% 2RčQNS055g)u=͆S/u_^:5t0\'HtϰW Upc<;cW_o2A,'?^B6\pbՄ߽>-wo"[ljo#vcWd`2Ɇ55]S. L?^(>m ˉJԔ  AƔ(Ob8Oa/S_&c 3dфRExw ~ s!Sxv`G dhp|^d۰ʯ?sur'Or#|ƟɴȵROVk9a_\bpDKd.DOsdF:a9ESdN9E|E+2_'3{`%gdyFgdFGdF~S =2#s=2"s-2{3' 52\#s%2\"s00Ȍ! [ .18"s)2Ȝ"sWd"3F',18'3',18<#32<#̘00Ȍ S =2#s=2"3&'l1s52\#s52\"s%2Ȍ sb"s)2Ȝ"sWdF=\b̬ԁ^TCd ' 3p9 Hh8+

YB9 3p ?ŁN8ǹL`9#pg=pZlCYg 5pYg %pY'I!@'g9pg )p'a:9 فz!2ȃη"O8g@5D8Gs8G쁳8an:kZ( 1ؽR3t5FtntKdHPueR.!$]כ)])]e%]߂+2tm28:C$?WTEbm)kqI]%I:qKյ%Ro/qژee]k{?>, !5U[nKuwu)]~"%ۘ24f~ YSI}yHP(]X}hJף$)]ɎKPWLl撮FgMҵA$]Wkc-]K#'UXW= k6C@)]/I}m%?CҵM``gk].b@blxSipQcNzRλYtmm.(]g{IH6fF!]Kڲ*SAQ0̎ҵic.It]\cNnEz3ڮۧt]';dIV'-]| k+>I׭WtfŶ gN{cW +u.ڦt=t=*0n%ۘ *zj+zϷyGw+3lS t$Q^JI^B},풒 օϋbmeKڒ-M4Μҵetm"bmtmuJșb uqkw)k$BJD:˔k|JyH[Jצ݂uquфI~kqt]]C tCAI6rHHI6fMII !]A̔AM*mSʐ뙙tmqKHK!$]mPʷm̫Jt4ttDt$zifNu*{QJXudUp^ $YLe&ĥ](*IH68YƜtm.as%lOP6K~!1k J+ {`JXIkk-]/q$]/e%]'Hz)%zj(zN ̔K3۔t=}Jt|k-]KS&OG&zh4"z(SҵF_.]C뮷w$=pqҵKt٬\LҵC &eҵl .]+uk¥ku}kO^}t=]Vҵ4 Wt- ".].]wݠʷK\tnu]V7ueHְGTۧ ̗J`N: x`_r(]|%lC-tmɐ`ӖP]˥ظm9!&(]إjӥiJCKJ\Mzp\ʣt#uCz.StN+uwIu̥ݮtݔu麩ͺtݪK&.][ɥ?Jז4I*;um.URvKR\ t]4s (].}t]nu?Υr'"wKyK:˻u^w[Ltv=st]:tM-]˭|u64~(].FҵLs:UMRNңkS]6~t}M/uu.][1lv}!]_ե=J-%SKWvtm@nci/- k چlc{֫P^%LLVuU\G׸\)j$m̗kЪץMzÕͼav!z3:4&fU9M"mY@Xf{]Mԧg\JyzVWQ62\\[6=lZ%ef9 ]&&.;7_bf`gz4gcNfJEzJ* =/УÒmNGf^`5ۇEGX٢OШjim_^bN.2֜nGg0`Tl~ݺF•TՄ?;U]ySOPAwv?; ҧ˓ .1_Xrz"/u}X1uW9?\槎$?t̷ ͏7r~|['||['||['||[﷜~-gG﷜o9?[Ύo9;z3-[B﷜rv~-g[z̷\jr~_׏w].}_w].}_w].}_wU_Q_7Dվ!K? Yۮa>(~6}&9lh.GL7Q(}X9>ˈ!]޿Ls[խ 8wLtk t}.AN<.wy>-0t\W.I`ϹDǹh]@UC ^wun ;w;&|?5.zŽQ9A =ϹD=ay0gi_nQ/[לy)K| t<pOxr3 <|Q8Zy-=نϞLF*{ =S=J>óy|\:cϲl,˖ѳ^_R߭oig&4\u2vw$fYof_;:zqP;j5$GXBKFWU=Gΰ=[ Wp0_x>k[|/c#_}mJa߹цy8[ ;ꛯ`>$mH1jz"#,`wa]Zw0!y"&(Lߡ$,`qxu4oG\i5 Uiw>eo^({36z"f3O)SGD-pˆ0#sァaz  X;,Ԏ73`"_6zX/xAVC*jQ- vsӠzX .79hLm(k`suKhѠzLO4̭f5ܪ+Eӳ~ +fbaS4ynCjlz:}czCr !mlN/"X0rԵCX&u)ӡz, CXڢf^Dݡ1W:{u=rXݯ ڸCXyOF# t!_–|SGGaLS–ܾTJ酆ősA@ro~~C9UMz;$ &CɿT:dLy8BqUPB,ٚCU7,Epe]nԡ ܄{C,m:K>SLK#$;yzU'w@٦Si2wH<_0Қy*#ͷ˓˱mHGmR3( ;O`[|#KALfӒ1%\%,aH;Aqdmő] 9;?\lo#324 ZvcOڳܰ|Grn{G|Ja@1Տ9qLd#(24 q@1S){M6I lmQH)ok7{9[ay"=k0`23 hw}6<'#}VzfjsbZ=s MP<~V4U(Xez!K}j9y'~5`1( #} g8%u'3 N#,~Yo8C09ߤ{iB1s qļ/l(pTcַ uB1  }Bof+l X?&$~f x8!%?g&vX7ّ8ܚJPRr Z_Zy~K)ZRkƟYaO6I'>(&f*0!KWno {1|]/ߗaˡbS䗩0V3SY 6~7֡Ϗ_w8?$aէm*oww}^>J"YM"o: םe}^Sw0в`\?-H*0mƟca\YPU8]xq/qa+ L̜:-H+ȣ޷Ӣ'o L^T$}z0ղO1Cc.c~}U~XQ@dt 2K0tr ?Bn[CoAkW ղ3u6~[5X ]_9)@GY_h4%lٷ_xa7GJ>T}Kޗl s᩼/߆ٔ ƻǍrycK"N3-?4>q|T3m>Ξs2l6cvlӷ5v:6y.l`ޟ3Cq}nÃo.?n]9j, k74Z i}[ku]{ }ga=x,lU.y_&&qin:'VB~1 ?=xpIW@ 5h96H0l9~7lqZx7ᜀ/?/Sakn[ Lϯ37_끡,\&01 ~w1>eak~oo{}$<_"sEրUދͯo}iZ7.k> EJ3akK/./1AfVΌL \d|_/c",1&0_ Z6~7wtLsjq\ T_?+e3<7zE[f2U5+ghU՟G#F 9˲?L˯_'࿼a jՔ_< %#L@k&Nh֗%;>M7 z}/^_&I~' OfhN$W>pbcxMWM\ɥ̼ S ~mdg^9pƅ_bkI*:UD'ߌa|6)SU۬/d/RL1Ŧeod<1-L97 2< 0lZoKF!6z Gx\N_ȕZ~i.ax#W_~}!9۠㿐jXt6~_o'|!g?0 IzH~k^f>Ѵװ7f-oU<_OgIu_6Sz0ǧ=WL6l_Ψ4]IY? ?SR}|[4(p[EJaq̷l`eׅ+)/,a|gJÆ}d}YX7387E,z}=n4ϖT$ g|E>-߉eLVe.~(IS<~亯19̉0*L.oeo\M1ާ3|U?o~Қ%4^(HD/yk njޖDXë \Cؠ9N?:9f?טQ[[sBETɺs'O,k}C3J6xnl<^~Ի8%ٜo3O9Q *B И) {8n '(KvAcu\н ~`:w:a5|RѝOzk 180<#ޱ+ޱ+ޱ+ޱ+ޱ+K O!-|<:ޱ3;ޱ3;ޱ3K7ޱ3K K N1tƽcg;vƽcg;vƽcg;vƽcg;vƽcD[EGao"^I2`f7JerQ"+o&ųd+ݤ%@qᆪLMN2˯&%`*7~joId˓&=)E~2&0Dz߈S&M&h%>C"}Q `y#O? L.ꛈ~%0@z2&`$6n_&K'\ !@r]&h_n2a2z5v@6~K&M) D\i@EU.Y&k'_py *~>M} /%e~&%M&{,&rM&"`"}0W`b;L(B&{?&5EuPRP&x~wnL 0 M&Jg!B:`!~hȷɌ&3&onB C&KrqoY1MuyPh&nv{4XD"&P4vI-`ea1ixD_t&<8pp7|,8\ } M77$Oj`iHhH25 inHwn\ G_t R&HL"LwP&+)S'Y0PͺmnSLx}0Y6 ju|B)_[nx?wQ&MxM4@?]4 ˏ9AcW%iE}~vDa% ~hE}t*  @rLVdaL2`S10n&0-+oj4`&73oQ\&LC=1i`0^&B~;dױU0$7Mwё&L]??]/EMa妀uQ"䢿G"MM2| ˤ2X*I~i@}qSEZ&ϸ .wQ&K;)Zg7Kt `td4/~ K$ ` }*8Dܮm0ڣLL[|MBMp,~4 Ie7LoDknZ&"|q~p[0L0]ߦi8qwSW}EX4Lc `+04h ` iM4;P9 ` 7yL秈.n {G~h> `$`", ~o2X&Wg?w]EA&cin `xA&&&Fz/F&qdJExrM}>*q| @wSL&;Ta2Lr<&o\7.ꃿ? Kr0#?q,_>X6n?MF&ML&ҷD@@.c 0@кCZM@ v|r OgOh0?H+-n>7 Du?aZ!Ka 0GS=^&[ Imf5LB4`vNQ67g7Nz~>'|'|'|'|'|'|'|'|'|'|'|'|'E/W wB]!W + wBB]!W+ mW+ą wB\]!W+ą +ĿQ;_͇` >C txzQ;w͇h=3ȸ|8 qȨ<ǹ j8oS]u#<ǎa=C[s|at'7x>i$7+s3 x* <xu?g`h`/Ws>y>Rt2|S?O{:"9k|:9>/~O?Pҥ9ԮSE89xgwZӻt^Q{ +},_ DUBp/jx>.?G9oχ { ?|`7au/_Z{xmQ蟾&K_?p"Vh3?FlG-O~p}/ܬgcYp?ͪ?>a_Yۮã_%~U1ɴwF-^ʝ%zNG ?J߇~=࣫se/?9;!Or~t=g^?D*ω?TZϋG&sZS%Nx_hq8ROu<|VX?axQ G+(XS,S~.x!nqN͓m޲g{?}e2LAOUY[O{Mؚsg;[yE=Io4~*R |[y7sܬXKMS+OpCRPL> 8Q(Pv?_ǟs>?ꇏ_"}y\cw?zq7ȖRM˿/_w?~}ѻ8~?v\_~!?~OSL:TpoWg_?*+gn|2lmY=<↿lG;aX+[_+\Co үXZ/T *DTYڟd#JZwGp8nq\FaG;3 *!|FhA|DĊ`@>[ ,G1. xpёz"l$t.,lyJ,JA|F,kA|_~ʏ!A8E}<Y)4!o7Mo/(E+,_~#p#ZO^՜m?sW?uSl r__~G FQ$7o>>1L?[m=]~p̬Gܙ[9E0Fx ]O㻳i'?M06|fo/پ~gVLrkd݄e{foُohMX VGqҜL?(}iN\ѥ[9KsqJ?6ѴYKԟgmmgUS|N endstream endobj 55 0 obj << /Type /Page /Parent 3 0 R /Contents 56 0 R /Resources 4 0 R >> endobj 56 0 obj << /Length 18271 /Filter /FlateDecode >> stream xM.u$xׅo`+njcᙰ/:z9.I=~p2T\R)S^Ԃ/STp2QH>߿>Gn@ˏW_6>o_*_0 #?*}_J/r~v_tiק>V4GS_sק.疮/n?R7_>W_{' } ~JRyk=ZS9|#TpO1}#tSD>|&:kXQq3`_gOovO(-£M.SGq_S?0ۧ~LtVWן$<xNv\j}fe3ZlX۰Yu JO΂`n BԐ!.*0O3Q:ep^`".*a0 kCcΗ=C@cp(ؘ~FИ7ИsCWf`̀JjO̕upe`6sT!U N^VSy}j1]&1o8Zd]Fs)a\ 7sSV*;`dB0[d^*kvBclK 5f{f+L]wy/2O ^v~˸Ƽ}1.2ObИ{SИИwИ@pJH]Иǥmpھ1~cCczN@cٰyL]d!Rp,ֹysE\^iN]UT+ZENKm^!И`O#Y_d3|%v6}7s*~G~^eCc2E݋Ah̻':ww yfCGywPhݻsXur9 0lmsS4~Bw3` 4>\O0F{CcfhU=ƼUFXmhYT;17u}. ^,I{e4F&4pUn xmh}"74NfCcZ޵1Иwm*~yvyv< yvP& W5yqQ74=$ƼvƼ5j|tOCcÍ)u1kwp3K Ǻ n6^aƜ. 9e֫ Tmh̻c{̰1RaVv[@UИ3sVO1Wl-%yqpj&lv 2ݎolhCjUw4\ 2g1&h﷐YoXK U'LLPmn-eEh6Qca5W%f" >pkCcEh̻n`3^@O2D`pmBsra=ۢ1wʆlE 9ov9ԹƼ{B Y̻c9O0'e6^ca`:ywn?2ܙ WcИʷ0ĦmEfe]6&5Tצ+7w{2ʇL`xfZ^'g^bćcX?'`kggHNL60\9~Ób]JVˠ3l{+Vt=64?i?%^l@D`0_O%0/aqmwWɱa3߆'aek ﱊawWNʖkdtpSN91 ~tO࿜!&emyow i5;m&{@ó"1x|_=94 c{{\D%9ˋb0fM1ƍ,_uߟW;p[‰l?n1_4 N7NK0Íş0nJ2 ,1 }*,~g{`+~]Opr,1G% 2RčQNS055g)u=͆S/u_^:5t0\'HtϰW Upc<;cW_o2A,'?^B6\pbՄ߽>-wo"[ljo#vcWd`2Ɇ55]S. L?^(>m ˉJԔ  AƔ(Ob8Oa/S_&c 3dфRExw ~ s!Sxv`G dhp|^d۰ʯ?sur'Or#|ƟɴȵROVk9a_\bpDKd.DOsdF:a9ESdN9E|E+2_'3{`%gdyFgdFGdF~S =2#s=2"s-2{3' 52\#s%2\"s00Ȍ! [ .18"s)2Ȝ"sWd"3F',18'3',18<#32<#̘00Ȍ S =2#s=2"3&'l1s52\#s52\"s%2Ȍ sb"s)2Ȝ"sWdF=\b̬ԁ^TCd ' 3p9 Hh8+

YB9 3p ?ŁN8ǹL`9#pg=pZlCYg 5pYg %pY'I!@'g9pg )p'a:9 فz!2ȃη"O8g@5D8Gs8G쁳8an:kZ( 1ؽR3t5FtntKdHPueR.!$]כ)])]e%]߂+2tm28:C$?WTEbm)kqI]%I:qKյ%Ro/qژee]k{?>, !5U[nKuwu)]~"%ۘ24f~ YSI}yHP(]X}hJף$)]ɎKPWLl撮FgMҵA$]Wkc-]K#'UXW= k6C@)]/I}m%?CҵM``gk].b@blxSipQcNzRλYtmm.(]g{IH6fF!]Kڲ*SAQ0̎ҵic.It]\cNnEz3ڮۧt]';dIV'-]| k+>I׭WtfŶ gN{cW +u.ڦt=t=*0n%ۘ *zj+zϷyGw+3lS t$Q^JI^B},풒 օϋbmeKڒ-M4Μҵetm"bmtmuJșb uqkw)k$BJD:˔k|JyH[Jצ݂uquфI~kqt]]C tCAI6rHHI6fMII !]A̔AM*mSʐ뙙tmqKHK!$]mPʷm̫Jt4ttDt$zifNu*{QJXudUp^ $YLe&ĥ](*IH68YƜtm.as%lOP6K~!1k J+ {`JXIkk-]/q$]/e%]'Hz)%zj(zN ̔K3۔t=}Jt|k-]KS&OG&zh4"z(SҵF_.]C뮷w$=pqҵKt٬\LҵC &eҵl .]+uk¥ku}kO^}t=]Vҵ4 Wt- ".].]wݠʷK\tnu]V7ueHְGTۧ ̗J`N: x`_r(]|%lC-tmɐ`ӖP]˥ظm9!&(]إjӥiJCKJ\Mzp\ʣt#uCz.StN+uwIu̥ݮtݔu麩ͺtݪK&.][ɥ?Jז4I*;um.URvKR\ t]4s (].}t]nu?Υr'"wKyK:˻u^w[Ltv=st]:tM-]˭|u64~(].FҵLs:UMRNңkS]6~t}M/uu.][1lv}!]_ե=J-%SKWvtm@nci/- k چlc{֫P^%LLVuU\G׸\)j$m̗kЪץMzÕͼav!z3:4&fU9M"mY@Xf{]Mԧg\JyzVWQ62\\[6=lZ%ef9 ]&&.;7_bf`gz4gcNfJEzJ* =/УÒmNGf^`5ۇEGX٢OШjim_^bN.2֜nGg0`Tl~ݺF•TՄ?;U]ySOPAwv?; ҧ˓ .1_Xrz"/u}X1uW9?\槎$?t̷ ͏7r~|['||['||['||[﷜~-gG﷜o9?[Ύo9;z3-[B﷜rv~-g[z̷\jr~_׏w].}_w].}_w].}_wU_Q_βX}|!X+-0t\W>.稉`ϹDǹh_@UC nwun pfSL mk)-Yy:9х@t8Q`>kOt9zJkN^bw\ [|oСxGy-'sg#:zraw{<5F:{ =S=JNóy|\zcϲl,˖ѳ^_R߭oig&4\u2vw$f$Zof:`;:zqP;j5$f GXBKVWU=Gα=2\ kq0_x>k|/c#_}mJc߹ǿ|oaV|eV!iK _1)ai=#K7Һ#ψ)4E2T} a#=3`y;<,π\ J "jFYQ Sgg٦v;8wrz U ݵQS*ƇoRo#s]pa9GCgjKY3N;[Eӈczav5f]_aА1k=3X13t17tcS4,{tPǔOfp"=x!'Ǻ4AKcQ&7ζp%*/}CX9w~U=Mǒ~:FydF::ei C@Vu [zjJoJWS?b+G֍!l) T5A`-Ɵ^'RUBƿgvH!6UqB tkr>rY^ҕwR/pFzAt27jD,L9O/5“xUuLoߍygNa]u*#3}Hk^積4ߘ/O/߳M#*~Pٷņ>. KΠ<2C;XlGł!,es2MS.p\!\Ø0|cAydixå@gblz]?pϟl #v-7l9;䑜RnGLcw@1)SiL #6<`{GVʞxD3Q;#$]_Ւ/O~Eąw|Ys, ~85_&O l~'n/at;s^~wx`AZN_ y-+0e[»c,ӟ5IkߺLS7PGX߃b_TT>YqAg)Rh6 f/,H-cбg:Vc[P[n_&@݅Vu a./H.foWymxu6pҳ},ln#Z|da7h %-}͓bU%@|x*7b6nq\|^Xp`L =vpg;?4La ͘{͇]फt0 v7Ps\ sx6ˏ|ߵ 8>ڰ792ACy6~ڰ7ledٰnrls= OްW\aկ_v O\T0/67"˿a/ 6=jtz [t i?V1M8'ˏx6Voǖ)|0D4S*4?ny- a=kuY33OL phO.3~&(,B~ yx6~Qt8WLJc?r%f~iK>ȕ_FHsNa6/+o2>]5_Dag ?}omyo2e4-5l߇>u[,w?y}W /A6:<">$i})lUk ۷3< D`"RĀa֏T~, |ĖogQ|a}-XuJKYŒa_zE,Yz_$MWK/E-j(M%U?JX GKmaf.Y0>jk$_Kb}Y b!& b~$%/F~o2L.}P%s" -K|k&Wxs&~s iM.oAϛ4j0/ KZ~hweiy6>$>*6hӏh5fmxVV\PQ+;>j* &K=0ZЌ nqy*[cp3ϥ_Ŋ90NI6S^TʻCD6x94f} ?ή[%kF6R]Иet/^Nbp9+2_GTt'18/遞s 32p?t K 1: N!4#2<"#2#s\&r3[dnEkdFfq' %2C$9a%sdΑ9GsdΑ9EӹC|Wd"|Edh}ƒY B8a`aQ'l1#2<"#24Hs-2cW=vcy`=vciJ9a){{슻Ǯ{슻Ǯ{슻swO){슻Ǯ{슻Ǯ{슻Ǯ{슻Ǯ{슻Һu“yci:a%{θ{쌻θ{쌻θ{쌻M{쌻ҪwS >wqwqwqwqwqX'Obp`9;3;3;3;3KC s=n\bp9;3;3;3;ZzS >G=vcG=vcG=vcG=vcG=vcG=vcLjqw#2cG=vcG=vcG=vcG=vc-bp`ǎ{숻ǎ{숻ǎ{숻ǎ{숻ǎ{숻r#)',180cG=vcG=vcG=vc=\bZtk .180<#32<##2<"a?YG;a`[j K -2"s-2\#s52e9l1ō'1s92Ȝ#slVKA"soVLOXcpWd"|rj K Ng32<#32<"a'Z->a`s~اzw"y{zw]=zw{zw6qzow]~{?zohw_sV粟]7 ([%.wI] ?I!e~lw?%%=Q|.?yb5uBYDҡ['$.뤪;?g%ac+7N[uD4ϞӝDo8~g*iD^A꿽Tck"^R3E\MMϧ ()@$L `t44T&;i)Unљ&~I$ iGL6s~>4">MC" `h&Q4 `t%d0- د `j&j1oMu `y2,R&UD `uE>v½n]{k3 r)<(Bk _0wS6g7ܓn2&%HzE~iDWd$LxqQ؛G"hȭWL؅MR,)\ԇ{B D,Oo)@aCE1@Ϊ4xm2 LIdh> ~[xL&vE@]^4m ]&zM'p,z: hf7`r6r46sYX"DLї&<] /&&7d#-?&K*a'aiHjnHMɓ2XxRs>LnHZ&$.d%luo']eԟ .p+ Jpy&T.l/۔D-^LhM8'ZE20d&d&2%O]ԥ )l|}v^n"0,MOhao?}cUIb0,sQE"+Q0`Xz E0,vQ2ag7@DoD$Ym6/Lt ~/̮&Lˊ0?M湉EL[..2{} Poonɠ_0u,~?LM2@dt]t l/O7dO/ax|.;v),~CXs)`~]Կ"H>|n@Ӣg7&2:wsP_c 3n4~`]T .gM]i]?, _i&00"k2(oPt1_+MERME Z&[ `_/7ܢ|uLS&<7L),vNC|Uxi~_9Mcj&|i.0_2& ƧnEzpMc?TdM)0Fhޅ'e1 k7 ۻL?IUY&{~`aQ{ `Effd>^ `I&xˤ& `\.0n&@@_2t7g'U&bL&&G Meү`&% ~&˗Oa)V&Om G7~96Ц4z4P&y|D!??Y gOz? `=| `8Ÿ'<0Q7qE}`zLd`t`&v`r>i 0MwfAsDԄ E/¿_" /Ÿ" /Ÿ" /Ÿ" /Ÿ" /Ÿ" /Ÿ" /Ÿ" /Ÿ" /Ÿ" /Ÿ" /Ÿ" /Ÿ" "B]!W+ wB]!W+ wBvۼ+ qwǻB]!~W+ qwB Ԏ߰^p0dtxzQ;w͇h}9k9.D<Χbm}0߈7!c~aza׶E>g??,M?οF~~? ~_Z#o>WBQ|? LruIKg47 EW_eowǿ|pSU$ӆ!xu(w~9:o%z.L(s~|M'v5ck25lER'GҾ0J6(~X9nqbv' [@d~}$,&Ͽ/~Oh~\>}qe뫟v`{(QBu+q"*,ODX0=<K&;Tuw0: e&wȾ8#gGD {{qq$򑀗gO'FK–tNgĒgl3]zyBCj3) 3;Tg k-~aщ"^ۖl\Gf>77u\su⫟z!j T NS<]|f# X|\Gf\@@q. e^99^vlJ- BX#L+0z6^* 5¾o,_mcVƏm0Ŕq?ijƚ##}qH}>Ǒ?MʧŴ"L#<"L+4#´"L#aaZ'OljVR?T6xot ?U3uxotqw5?e~cMys/>_W_|G FQ$7o>>1L?Ym=]~p̬Gܙ[9E0Fx ?w]O㻳i'?M06|fo/پ~gVLrkd݄e{foُohMX VGqҜLwz뾿4'VÿҜ\C㥹[jox4c`)Yq'C?_endstream endobj 57 0 obj << /Type /Page /Parent 3 0 R /Contents 58 0 R /Resources 4 0 R >> endobj 58 0 obj << /Length 18269 /Filter /FlateDecode >> stream xM.u$xׅo`+njcᙰ/:z9.I=~p2T\R)S^Ԃ/STp2QH>߿>Gn@ˏW_6>o_*_0 #?*}_J/r~v_tiק>V4GS_sק.疮/n?R7_>W_{' } ~JRyk=ZS9|#TpO1}#tSD>|&:kXQq3`_gOovO(-£M.SGq_S?0ۧ~LtVWן$<xNv\j}fe3ZlX۰Yu JO΂`n BԐ!.*0O3Q:ep^`".*a0 kCcΗ=C@cp(ؘ~FИ7ИsCWf`̀JjO̕upe`6sT!U N^VSy}j1]&1o8Zd]Fs)a\ 7sSV*;`dB0[d^*kvBclK 5f{f+L]wy/2O ^v~˸Ƽ}1.2ObИ{SИИwИ@pJH]Иǥmpھ1~cCczN@cٰyL]d!Rp,ֹysE\^iN]UT+ZENKm^!И`O#Y_d3|%v6}7s*~G~^eCc2E݋Ah̻':ww yfCGywPhݻsXur9 0lmsS4~Bw3` 4>\O0F{CcfhU=ƼUFXmhYT;17u}. ^,I{e4F&4pUn xmh}"74NfCcZ޵1Иwm*~yvyv< yvP& W5yqQ74=$ƼvƼ5j|tOCcÍ)u1kwp3K Ǻ n6^aƜ. 9e֫ Tmh̻c{̰1RaVv[@UИ3sVO1Wl-%yqpj&lv 2ݎolhCjUw4\ 2g1&h﷐YoXK U'LLPmn-eEh6Qca5W%f" >pkCcEh̻n`3^@O2D`pmBsra=ۢ1wʆlE 9ov9ԹƼ{B Y̻c9O0'e6^ca`:ywn?2ܙ WcИʷ0ĦmEfe]6&5Tצ+7w{2ʇL`xfZ^'g^bćcX?'`kggHNL60\9~Ób]JVˠ3l{+Vt=64?i?%^l@D`0_O%0/aqmwWɱa3߆'aek ﱊawWNʖkdtpSN91 ~tO࿜!&emyow i5;m&{@ó"1x|_=94 c{{\D%9ˋb0fM1ƍ,_uߟW;p[‰l?n1_4 N7NK0Íş0nJ2 ,1 }*,~g{`+~]Opr,1G% 2RčQNS055g)u=͆S/u_^:5t0\'HtϰW Upc<;cW_o2A,'?^B6\pbՄ߽>-wo"[ljo#vcWd`2Ɇ55]S. L?^(>m ˉJԔ  AƔ(Ob8Oa/S_&c 3dфRExw ~ s!Sxv`G dhp|^d۰ʯ?sur'Or#|ƟɴȵROVk9a_\bpDKd.DOsdF:a9ESdN9E|E+2_'3{`%gdyFgdFGdF~S =2#s=2"s-2{3' 52\#s%2\"s00Ȍ! [ .18"s)2Ȝ"sWd"3F',18'3',18<#32<#̘00Ȍ S =2#s=2"3&'l1s52\#s52\"s%2Ȍ sb"s)2Ȝ"sWdF=\b̬ԁ^TCd ' 3p9 Hh8+

6;k@#.h='O_c9pC ]Qg >|lN+z4wc5|1^ #̶,̓Ej0~?Տ=w#A{gA`cPӯ'/uV3 cHVu\\?kϞݗϹsIW_@hd)H3_hؿ_<+~ͻӝ}^̢/mgo^_Q9a / N:lzs!i!1tS {6ͺc q^CDw\1j7>^}_rdfU.6Y9\}# ΃p7v ʪY2qAPsa:Pm}n7/1{~M^n @J޻='Cka qUh=dn mN >pN  o5 zG'C7ΕHt-[^TvXH>3bW5AzQ[; @"Ÿؤ?oo/w0K#.Bڤ!5e!7v[< ?S>no)dƏ'+Nc⃹%k@fƉ[!㜞kUou4襐@ 3°zL'ܺ [^ u|c^Xrvo_hi@XPɎwo,, evɛ;Ǵ:#lHfYb-w >Bl\C!dmŐr:D]&\ Ye72x+\O |2 ^"S}wǏ5!q& :^м;}ؤ$>cF>Й5.{ yXZ;%$I{ !e͝10nE}p|q 5<Ր=˽pH{3b5 ̣h{_^|I ߤ7gwT191;dyw™8cYד7tS{`HqiE3H38by\7g{APM9 L3j d37af% 2tSO 3y㦃2^҄y/J:$>h *LvGtA;$}m}ڵ ?fxHvyl8]^~d=t[eO0dכna7d@xL`CXԜG6TyR3-b{c4iXȖZXTRvuOb/zAM~OGgyn{=H13hAO8& ɇV,{KtIt3'!gGU6yAÝ XzuDh崵\8c<$w^i4HB1rk˙!izm+ة SgEݟ7n_쭮~q=0sF쀌q>ZC|Vay [@ڢYBȟu3MkBB>;~oߟ v+ *@lc6Bew#ߌK\ck\ANЙ+@+c7Ln>\bҚޱ̂/;"~ܟ  lh)&ed |\Y~4a=OԮW9kYm ZZ$݋̂yyՓ#z 靛[ ).2f>|-Hw{L|h0;h#y&_*yKiKNLx=Rf$.qdE~m}3BѬKG2v1oB?76 " Hiq,dH3*\YGϮۆƣڴѱ̥;So˭:zwoi<>ǟ;6, p8c0fuHȾ$s-kuݳt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0LCagT^SlmHkMZG rnǫ|〴HkK^9;& ֭Ժ^8G<5 :Z[e~˫|ݑC(܁C >EZZē;hO3:} #N*eOwrIZZi-O'N?x OK;8?OCA!͍Azp? zG'O%g?*-'=/_:ߴ\#?q^T\׶9|C*C/mm(99!~Z?qB#_Cq^ _C'xğ~QN(|:ikۧAԸ8cOEµ ۻUƇ@?woūh;cC8ZNEI=&״~=~4>8It\^G 8:ݗ\BӋ(GC? ċ~~]]9y$]H-џ[|#>F޴_/n4>Av~ip]?G|[uKt@MLj^X?օqQQ>pA!I|99 < Vog1@ayI[Ls&u[h8y%P99 pė偓O\=*G9yȹ9EC9o#n[;;LDҢG#?}Bzx'O>ΈtLǶrE:ΞRtzyh;xg ޸[~8@p?M?#=>kϧ ]8Gr?C|(woh8;F7Qh~ 8 ''qrCZ?=~ץ|g[>za;S~!8'z5ۢ2E>P*ønm~H?3A1 ~srH̓~CڑT\}LoGynZ:UG;q҅q0Ǥ̋q'Ca?q^r-E7 '9`~7D'C:q_p<5G;tc<| mP~_=lJуq!sq[~1}䍜~#tރOhp>z= .ZNol+Ai.F< E b1GOQ~rN_Q"Pgu1.Dz8\7YRޭ򺴜z\EC:P0ߞVCrFiNO2Tr},r??Pt ݢs}t!#ѿ#8!Ou*O':8#_INt]sl ??Ю`GIcKOg2'd<3qy2Gǵ.:uuNs|$]my<Ǒ똿svWNmq7҅qv\H;G>u8:nNNl+c)d>s Qi{x*5WA@N_ϸ>:K:]W/ҋQtrt|n\MH?Nl+ӅqTOIzter_rrLe_N.H1:GMq9o"2o~>øҏ 8Z<8 M9\Ǚ\G>qv\hJ\n[O@EOr8>i:q^oSne:?F|&1ꏟџݢ`rFN6j9} ^qv$=n|"U'-~2<-59/csa8&c3Gs2eHx9.69ΓkAd&8C2;f? k<gg:, 5]{[d|Y9O6jk7H(r]&Y'G~]'x!H,qdP iA`A˳mvZY>6WYyjL [~1d#2g<FZ넖${6ˋD#>O[ ΏBc21[n.s<"٧d_پoxmBsҗF@]`&}AbOmn"CKcfoY<8Z7n=&kzPOؿm <;'+{o_\N^BABh$x~ۖsd#r\&k%p7vUovM4޳}PΑdOY|1.a oIMxⷓeY4K/}u|?Y>)ٷ<= #x^YZgn/6#MwL $"Du+﷜Gkcp27aL'Bײx&&8cSǂhɘwv{M>"{mLCS5uLWfMlW1eX?yh^ה-s;4(3rwhh:5u*7M08P ~* OmK4mAf4ҡ)857ǚ|u~}Bi≸k(zﵦ=4诉ƹNk΁8kO!5h5CuPh;KBM:+-򣉳>4pCy}.-xǫ|mߴдǨE_c~͵5C|&ͽN*Ӣ88M;kjӣMiУiq^6SˍۿɣiŘתk`>#҇v:OƹNii/5cMVy{hz:1VSn4ZN 1ƹ&.F}hhV(DkXeUhүki5yK':ıۑ^iZִ]FS.jќGNiDˢ1&#cޟ:#|iҦG&>JSiִ_S0ќOVj:д!Dǔ{7ך);ksMkUWYy}5c>c3M~i1xCS4eyGq.M.։ms Ҷ#m_zIxlkS8_+j|; նq֏_8K-t6ulRm\CӂtuжO4iE]q8ď8Vu?zT?J:>4i!KӃp/4hh5=?-G4ƛ_Zw籤tߔN6sċ'ߴBoA>tiEZh@8ݧ3_4f -i97*?m6׃=4nNZ/4Um~f;gNZGě6-~M=q]~YR-mw'ΫxbKǛ8em -fߵ)8h~-~n~b;uOtz-卶;mroq6y_k}jSz]ڿBo!u3iҖ7j״kztjG4]R N˟6;K뇅~6[P׵ e~:kO,_j%7OjIZxnIͿ[Rz4=DrM4=m?A˴C66k'i hnm>z~Tt\GG:I{ViiSTͿpm_i}ץοiͩ봼j˧h/mhcOz>^j[muTKͮumxkCighKeI3MA?fyp=/ZhYGumroh,쓶EY,q6{E_VVF?}][^ϒ׋@ͯxi~T]@8o8jKՇmmraNV卮vzx]#>8^[\o_KO=jh?Q͟rA6-nz,q4>4t|-O&xy59B{eCZo?oVޛoMp?x%PpoV~}qE|}#C*,)P-qzxatQxwZ+?|gx#P+vw< Zls/?lqT<$m;:ow$-އĚzF3%@j<|@uh~tzp| Dh;1ԭ91mh9_G27|#nhG?GgCoZ.,qqXh>kw~R78xr0G5Κ@ZK^^Fnu{Zh+7*z-EG4h{T?[:7FQiFnKO@Ꜷ3cIK3O!h}i/rH?nJϣNGG-Z}Nvw(5 gq'iy85뫈7-4~^pǡ\<?:]uxi%-~q?CyAyom4Kџs }H'G99%~u :?yS7sa_q918G5iIC%s0cK ̟9ϐ6Ϯu9.N|ٹqHd WcnPB{m?ϮB_t%>>@7{!d<{ݓ9nص"Hd ^"%~74Jzz/6p}FH?DNpe$} M+d oEM'.5{VsdX](82wq#ȣ.'3 !}q͓d>%E2GOjsSB/3IpC'4^$GbE_'e6>O_'oB?|ܫ˄>eY=@c?:wYyj "zrM!BMNԺ:S'/7H?29?S'Ҟ -~\#s 6y2qq2] wC"Y,9Po.8+nd=l}0>;3KvP28鿃 GOm+5hme7D5?u2ʉ?ًd T!m! |ڗ1ͮ5G9KO|yP{42cDyhҠ9u5qk}&.&*Bk:㛾򣉳QkFӫe^VFf/Q4h&Ss~M>\4W0X+C;:N4>Oc,xZiH\CӦкɫf"4khUO+4}4ИSs1|2@|h|s\Uxi_4yG#{7@_zc1Ƶ*Zhg~5=kkKOZ>W4^hx@1moyq5?oh-67_Mˎ5Sj·6{C˄6_A78x7}4oZhMzC^eZ:ƁU59RӼCK(Fͦоoih|i:4mm4grI+=7>͇Ѻ73eJ]Q}ii[<^ ñtNix#ޟid|um[U 4#I딦l4>oSUVa`skJچ5'mm ? %G-<׭!oh2aSHԫuy41#crejz ՘xS֬[0sſr[*\p\.CM !B?| 7@ ȀkV͛5o:UKVY]>kBnѹɟ&笛m9+0g(e1H&4Y//-Ώ 4wٿ۝8U}c2r&{PȰGaᬣؿ|B OEUV y~w$UJM%q-fC&>i5(6F A>+q5fȋ(pB' * qwvSn0Ur77^+7l]xXׄY!T+g2\L&mv^~4TҏQuc=ز͙SEngX:$"zxn\EA p9?VTKү?"71AwP4G)s(#Tј;hH`y@iFq1Il~.gV6s\[\Z#[L2E]_g5l 8rY]ӫR o|OZ̴?'vlwj=W~Cj$'!^tRIV| ))pt!$uY xܟk64j J&;>ɂ_-_$&dCExgmk۱C\ڽ{F_7,H?c z=I[-DS!ZO{pޑ 7(*Rq|`ǟGTc㟎5`9bFJt@ ';3 ?@P`Cȹ,W(Uw;L)bu\lQCkZ E=Bw/gbXQOKxsZ͌ܭcٙnp~s3Tp9f PϿ !P]vg*vM'|Up[u bmvP2Ws?tŰ̄WuͺGO|GM]_rM;l;xV'/SD-pŕ?R^H@˖nOLIА%lgnwpa)" $MK*e6hmX~?=|:<^'m|`U2򽋑N)g0?ߚk92((czV6aʏPu:]^AwLG mjE_n7lĤ,V>9M!=(j7x(|K0hZʮ$TLg*L6'8Dl16D:#9TkmX[0G `9gYdq`p.1%F⾭&$Mh:P_NS+ji803E¤ fbA< _4⧱%Gng%7Ysym!KȠ1eapWjKQ_Bk{ByGkA͇v#jH1 hTj}'O Uy0 }Wl~/n~4q"1۝q(jJ4IXCZ~$"3OTBë Qe~KkƼ6'7d:yC.9{mm!GMo _q[¼s#߯\~}R(ֱw|Pnf ăUT/ݲ|ߍnv5X_jܾ\tAT}[8λ!@51ğk|V|bބ>)dg'īՔ$\W['J ?͜{πW .{wOcD^`a ܮ-O6|?nƖ:qXҷR<:q3҉mF֙gv+N7'?_5pCr2$,~x?/?Zso{[}̘?!'|ػpP$mUsm!NӰݾݫ̟ͫZԆ&?㶃!pkr*ȗt:2GOo~p,mpt>m'C_OGr X:>q{4GrF-[}E&ÈrDjkq]@v8iӨrcirxG>zL>\y*ұNXc*3r̀: n}}xH"=S(Vrtc*A | p(QJU_lO*@ٍ{PF-"|SɉV#McKҢaWE1ݹxѤvȪFdULEx3Sru$,n㷏zߋXS#.4dAwI` #l9]Tw6h=-F^6V即lU^-t{?7~]F|e$b櫊fCġ5mNxԛo!06ތzĂZ\*r*7FX fU[v' L|of3kB|[AS'2cCgZacQ6~<)0XundCQ{Gzcą ȫ= GCHZH;+w3 įdGb:sđՎcTVƟE,z-TlrJ6ic"-FtMJ!Kh(<Tc@' ި S-ZnX^tk5;.'_:;\|߷23||]`adh`{8cQܖjຘ:r"19kP[$ &9caq\~ P:MS|;j y''n-Er-iTpŰpY6<}-$$pJGZ H$D@F@9Izv7Yk-*q zo&9mۈ?9'aK0T:9ψd[(ڊ [BEo?E qHdFMȧxl%?(K1!㩿*碿Q"]z@~.oޫ~5v)H?%3hv&ڪ~d E`KP34{h (֞tف)K[4ǫGl/myb[|͇v`M,XoöA|jAz~- &  u R1iNP:1jWiScni`TՋS&o>CԂ9 nKӣsIʅR2)٧ϭ4ʤ= >]N_TgR- K0U*nɱEr,RBZ N}{-֚trEb-ߐ/ZQ5'`O,zDHVWCI{ܞ^k gȧnY`[H>}¶E[3A瓗:^gc3˘Y\dzhl74>/ʏȆq=kD^!Fu}/3Wo]_HTJ?t"Oor[>5IdWBO2¯o?h~V٢t&B/KY]l6|_eF=UjTkLo@'(:ZSE\גܧ}dޱSƩ1+sTʷ`cM([ ytpfJڨjlv H+8yaX> #㔛U"U\L{`k?{(jh( ]MrEW'bG}mLf sǫGloWM{)+3}QGNȫFۨ+Hl^^7.u±,cjr#?eI*mo&Mӣy;N4>Pc~y-ˠPgѲӎ5P1*qQmDefC(8lߎp=,2@yn&EGpXKï+pũ1#Ge>ƒԹأ+:3K9ϳN'SB[|b׏]INnXr=)$2o `PU0ȫ_Wzk﯎T6 qǀˍ}{-A '=4LR'>ga \Z|Ʒ"8ߡTi^#3ox9&Fn!/7Q5>T}Mӧ40 y˅Cɣ1zʪxZ_l WrbT\oxCd Ozc?xz?oDb9aL)ܓɧz_ouqf8 ;-idP_*eV ~=ె6 [?5_O~Ⱦݰ6''UĹu [rj?V/|9} [sv$Wk7D?H9,o='Ώz>o|ؒrӻnp%" GgN*; ِEJ#|C>(9 { `S7N3ALr#},lŖO/նԃbv6u&kC ]~r2|j)vw+:o ?D?| |ըַ:CG wqݷ3]u6A Iv!r_ngw]͆S]BVUyg[C|7RH{28ddjba[W(0HȿiWo~cL/!] iG&'<!Eoē:XWqS:oO.w J Q/-MoH{'a/}B\;t2tۜ pcPC($ '!Eoę!+;>D?`ęI We^􃴲)!g<@kl -86r[VY%h> ?C N'G}-K &<m]E6 C2tI'QȌ4̟))M*hь (X.ޣ@BXjQEu~Ʊ ~Y \ބrʃCdUrmadG'+S9UÅ^^-= > ^W wA2%-+gJNY ռxA&M<$'i-Zl:z2jؕHH/0' &77vynb]١$jqG?_'ɠQԔi _E@[ωx52h,@lF̴XQ0@\22BȕX%:ͩ*Ipe[2$ЦT=}^F;@P&WWHҫܦ D5-?=AG*,pì Npے/[6͗$_C[့lx 7A=@1 Z'΢:˧>8 RֽGo 2tjse}to.6v=2RKJd[%âhhS"v%2Xl!)瑶DC[HiJd: ՔU*h'N`M-_>~Kuynԙl.ŭ=O[C)ȭ8}iM 9ss"ke)Kto.L|4FV,+m@#fin Bq(>DMz*R"G:E<naG*\plʅ Qу(1IC 3x/H7qM,_ Hv)NݜmGt:]T&wJf6߶\vH ='Ԙ xiE/ Afb82C]͟BTv͖i<ַBT:XѰA~U[!2~zJOF1Dn=\D_j-m/lwAW|w{NO9V|J!#qkbVg( [K-BꂅGsTyu / {r]f_^hUkm5:r2/3$=/ 坺%EKa}zA~Yt)K e(TO]{'|d!r[!J]9E 1D]ZwEӲ[! ( {զfނ!"kNL^E #ctJO~nKv/zB軒[LURDl92e]3]*Rbcw )&.+N?'h/U-oV~z]I 3ѥG#ͨ@6$l8}r/9yINF?Ȍ&+̟X1C_Xw.TPd> fhC+2^ٸ>놜tnSwpPmX=9(cN"Yyhg)Vyٷj2ƕ;v{K.QG\a7CV vԪqyߣ>N[ SW&֋̈́-'~y Q!GP0,H[.zVݍ],V!Sqմ/V ?yxpbf'Z'F" .M^#nxRx^eKc6iܙS`|hBP_--F$d&zy>[-֐:y!-pA.w&@s@zޭ6]awNɨ)v Ylh-ЗӤ<),.RFdz]deUh.ahB?~kF(fSżIxsZ!Q=8+$Szx$'MLUV,9mIP5(ߎjS,`os1ޖRMn܄ut{7=P7-‚l\Q$|_(C+r=6E\9Q}<+'KZ_k Hjӻ}Xz]!$ Aڜcw[ Y;h=vv|)h%%%ʨdyARo Xd;m" ۙI'Ւ3VV)ĕB+ 6o-ld=HK\q. j#FܷVIl%LXaIKZy S^5.xx(3yDI 9;DŒ{ . ޟ Hb ·xI|^"%}JGV={tXH:ulѹf+1jڧh+G>&}aꄒr(/35U, ͟ #w9eK %GIQPFrrbQEY7tɸ3Ev8qBWnIM9feBD.)4y2?GXz+"}r 1r|U Rw- {ɣ(2f1TNrs' ) z.)9f׳3rEyo9si:$Wn?r 1t&ƕCa"2!cF'fJ1lu^ %sARIp}A4p:YJCRg\,y;]1zkP[jlPFL\f"d9}R#`y)GKŵǵW•b+=w^roҕFrz EɱatG,!BlLBR`˜rT~[tV5޼n:4:8g>1bE)"s>#I١$|6u;J-bnksf"S`N{>eR#2e䴗t֓W%\qSJ_kBdLfޏ8)g= tSJЙ?rK%᷎|J m)wJZCNѫ? ;LZ}عՐrv?{o>)vf9_)h_vߓ=芞.5)1SoOo/'_m2SI8鰗4? AꆲNA(;S8 w=Zzƙ(7ﴏb+ aK0=ڋ>3kǏRowEͽ >w6D466$ۣϪ͐ʵ@Wimlj!>/zй=2߿@}w_hyjCɧjtg$mQJ 4'3ftD(p$m KfΟd1O1۟k!NY$UX;f/i΢ ]G sTɵTk (ׁj7f)Wfi䅙K L<嗢e \[[{Mwɧ!Ok!Jg [@ v@0G,$=G ~~F}Pde'Z8m 6rgHl=f4ۮ7*=74ܮ -ryh@-#}#C[FRNdt *JIaBzVb+g̘KωT0^܏e1/1Q3ˆQGL~C&↊g╘ fo[?êeXxPn>gb;˅]>H'6^,?L((d[OԺ|ߖꮂȳ q*RtpA.Veat1^qZ-$H>fłQ}X,| ΐ"/U]/I"4] ۆm/4r%o{g5Iv}292*Ű͟ð-L+ĘFzډ Q^G*' "8X*ThX`)Ls\m ?Gq)٫ جA)|= "N]{/Lf޾8~4{JZuF<:12̼}qRЕbWnxpv71UƇW!?}߻_?Cy^HOV|Iax5pB=i}\r 66 V'tʼ/1Nݰ|Olڧq74Ǣ?^rF9Ta $mR45:jRțnᛈO9)ũmRG[egR|'*>) R-%) !PrЧ@2Vpe\O_˙9@9Y&'@u$|2P.^F>gb z'ŧ\ G|?? 2->f?ﻉ\4Ŝ<#c$Cw(Hgb;:]. hvtP +!ҕ{vvK̆[|r[cB6P8J<q5눒PbѮ2s(]C;o~bQ-f@LYINrѫ(#2YM. l{.݃tg 0PTWi4{Y I?`%.ZP<@dVu!qկ9vxcٱŊZC.u2$Nk9SdAV@뚰vh_l]#h/Cl-!Mm.d/H:omQk+7H},|js`_XL)bMo3oKnr^,傋w}q]_>%)a9ވJ$R,vD~\7ۡd/|4},3w=į2m?!s_4_s;:wҮ~¯6hM1tSOǒY- pkb ͣD_OR%EGqQ[1g1[0 ! J((c~="EbPgi{hRzK7+oyTcڞyE"E Qc&C7OҒJ;P葷WѤφ{gG>7*s]2ێ W ? k'$ܘÎѦO o\hf5YaAUAmOJikE(,Deh BRE Ɨc@yf7 2ԇYdR Q ڂyxY'_wˤCK>7 [THI-gLG {xi)'δt/gxh:ukHW2ء7h9~dzڿ@}'0VdD䲹ۗ:ڡ$IJ}Q$fjT*q5glƌ۞QjڜhEMEHRFDUK5xڼqޥ@l K*H %rODӀ{!rˑ{or J6كtְ#nꭅ4S[3g 'JP4Q?}G58^2ƒ)$Rt+hb{ih'^1tᣲν2aN࿩*ސHv-Z<$N`3Z43h~a'K\2s>D&Pzϧ0z I}e8_ qM$n[TLUxeJ5UoMfg\\*C59iA)|DX!a}|!5mH=7}W`1u9V쏣8 ·p? #CA8r0q;Ez :$}54~Ji({dOg;jB 39R櫮?~0`߳wcY2:9V7{S6 Psk3mlۋx 5vFY}q ega^zUXq=!㞰@gFR!*OQm4y%ߓç +`K9UAF>ᢾ+W՚\ 00/O8%_8LQ+2A!}5Y {wkx.<ބQo8ՄB%揆㻻"^,kS,z ϛ/G͕ ?[ Jm]5m\ء33(UKVv(ǴOF87-|PJW{̩2|MQ0Q2g~8o*i($L#\A (mEiY`z?w!5_C|6 c 1 f˶r0MxQ1koG\Qִj1 t=CT*|̿p *m=[|?;5p G m[ 1|OH13,4A0@dwZ=(%x!)-4P,j)^5ͻvz#1=@%X"ۊJG#$^iۋ0 e Fʚ- f>} >( *x] !(=(_1 ۉ1ߡK WP^w|pR|}XHjAA{rˍ@Wǿk'! x mQ:G?_@IdDP3G\e*+3O'X:/pZP B/k!  * Nsj N(PznCT] {%5q^U=8nRr%wϚHP˖ ;|{; V%I>pF;0R8עǧZ'N4ԼS'fsxzhkm9Ns=xvuv  o hv(%tb OF8/s|P=Pن%j|'7yZҟ͟1`3c)f*۩ ż`K(QƎjp@Fvl!JnvUsߝ+>H]'~} TNʐ?j}~ȁ㢎,ns{v9 \-tn{XI{:,9>1 ѨGx o C=|ʱÖQ?=.8A# 6rNC|*F14'yiC@׽S:$ndԎVL[֊/-X;K|Q2]Q4FsgF ~s11CDaDDaT>H:׌h5<63GgAz(㹢$Z?_hkq!u]TsvU7=UR"(]9x.774zf\{y\A3"0<`Wr4O0#tCo!!mFHG~}m Ӗ?ݸ[9y'6|ł%oef}+@JV82}< e#0TEe5knQ+m fXdzw2z=mOݝPV7e2v:gNa\+5dHmuf`?La>AE\+)O[v]"?hGw K)HZ̹]U@WDhf6,ߗ9FJvlQV Kk(~48<2l)M8ᆑ;o&g0>oNS.Bbtf!οc jA$Q^Fye0x |(>ʕ<e vxpÀ93Y qU;׌9 1+l!VU Pg sLߋXqlVrS`=nj`grOr絢vC*-=R X'QW.>K DP_ xz}ajN49|XvThǃ!~AB-}e;GYc/5.+mˮN~[ t*Oмh#SJ-[X~/~CءBXo?~gCgAq+ԓ&B 2=93[]|f['k,Hf6,̭s( Ht_8x'-0H_:a̟D M̴̌OAG1lQL^8, RanA!+T&|js}y:(EU`nYbUn&p3|ο- i;F5P.{/ԵkD,s Ɗ:~>~>ƕ $iN=h6-U}hw{ݠ}xK;!y#f[l{P`Q(peh2萤@%IE*aĢiȗȝDv}9gE1e3m)te+#'%'i&3f#`\a&%排*vRoIC LSZ)xM^NL*%7!oeZZd,xo~?Q+~5+~~mvo _x <hH2H} 1H+ȳ{[@ۭkV5 RMb־^} ;hy2\롭T j"E|P9"OɊ9_c4Ff/fȩVS«|,ǽRup!"/ =e#.nd=>@쓏tp/8@Q}}k&9^]bKo0x=~rH~!GNVs]ltvǠ=y, t?U< jsغJf6yV>ԎԖ IcNV>#GȉLrvmiZ$੖Y2j70uʇY 6O,gPC$*!?Ž'SG82^t{YjV+8wӃ TY3( 7@d+iߛ2+UswH+O])0!Q<'#ܞap<~Vې E=pHbӠ_wQn[;}: CA=N z ~O~ IǞm)[ qH}xKGdpo@sd-+3+[t9:jI IvC'C5@aցtb+P/iAblH:I-&{~"Џ$22t?qvO 1- ;_>ճ:=zXP縉*:ڵtoYWsIUKFn}NwF;M༢HI8k4M1/%k@R֙_#Al :uY7Sڂ:R!=ӄU3+-_?: 3o9)B̑o_y|9]AxFR,6­"g  qr! lbJ-%,(i~j(J^ w~קxiݸm7Xꚾ3]/ՠ{95xzv&U| &*ٺ~R)`+mBEkcQJWG[zEPm8HS0Vx%c5 M7' jR 5ֆx^ շ 6[+7{5r7wݿz Zi=Ӊ'r4EF ?VW"M9ɯLZX>#IC)'JБhW !(Eͽ >w6ʧ7PilmH-q:GH}XŠD󠫴׊{Az[ ~ )) ?Za 9oyD>fI|~h>D&əbh(:V?,P%XN3F"φ!yl1(G W Y%|P6ד12q{OȽZ<T P"hއOzcrlqq}84ް pqVۚكWMn\oؐ?ح@MV(z ͟p> HJԛ( c^7#OfkuyyN3nQ]MۀʆS{u;YhX{lX'8gBw&HC SgR RQr&J*܊A:?g?k̴M;3 ZĬoDx"o1ِ\{J|zb<I&]]ꇌY׽Ui"|q>Zco{l86t3,xov|*58G:Q_"<+ P4 e3 DZ'ǓWHW4ԛ%ωm?] %4Wg*ffC!GeZh^>K}PGi-3Oշ*iݒXk ga;%!w(C[q:RRmɘʠbGHU1M̼]q|'r0:x9E­7!/5^HE ɏBria'_|v}H[Q#xϠMё[ۣ*E.ZloY[χG<ʃZ+|>I;$>(B Һχ?|Sf0w4V8LqlUc-\P~vDã Um\zeKtq:[/G8׳G8iK;"g4/{=;BP.Oa >)]S]BoRƒ)Ov])O=ڣz sw t)ۓtn3GV,b8hka+~$9M>!B2[OɶX:a|sB E˜Yq 3#E02T\muàPR*Eawӕu! q>OQbW.bab F~̼q>B v\){+xԨ-s*\ϊS0[VåB=D5b3oW\{J2z ?Osc!A>+Q%@W1u@'Ԍo_Ͽ@}{ :*b-hƜm |4Ο ˷pJ[[avBG"˝o_0`ęL+B,Q2,i|:,=" LTfۛf[=@ݱpJ2(]Hnw ?\Oozע\ fmbþZ,@阳o}!2[zC6p>N,f vto:zT ݺf it0vӎ <]rC^)]^Oz!=fZVԟA$!oij %C0CHVfoCWfSAX@mȶGv|v;>xĜrtvIҸ]ЊN \FMXkb7Ù"D'pȡ[8pCnLd X^e"c+c sxmx?jpD@)B¦{֣y0%n*Fvt: tiOStI9?Zג9Ԇ[3Y6x h^AAぅ]} SryՆ2NL~.3>99rq0:s&m3\ ߡ!x! P5NԏXvTq o9 ;Um?LDLڰOZʱ!}+O:`-Tq ׅχnf*LF} C%Io! -#cU]FB|pSלVuHZSL~nCj7 D/kM@ %(  ڽE!R+< ԿGLH`+2s+1"Ut>c?,\iZEK/, ??+Ve'3bTASɀIv#jV>eXNH2/\VVb/eoT/>'-(WK>YW&avq` G OOmqp߫Hx1;RR>H?TYKGk\1'; ^$f}p[$H8şNA=rOquв*7;@w#aZ_.*3ofmwE*L^!a/%27TV\QR>|{$:??#RUU̝|ֻ\$R9 QT!ekp׊JV՚.'حMTSP!! Mjwd3r@ժ]*ݸ .s-m:"QKUl 4O>G3lE}.y`_H9R}R{SF#eu|teJ t|uÓܛ̆FSxVp9)AϷ/u\()+ \Bap'e<¨Y+Q3>a ('|*QÖ7=6r^#G&)A,&e\7[}B\9KtԯrdWPtQi<([p2DD\D_5sx0Yܛ_8 x n6Q7T=y+|rf Ǩ?҄c~-AϺٻ>q=$; i iGtiZ ښ)FRaa~Hi)NhzIdkm $͓v|V|/A6<\Ц@DQҌ|\h2fƇdjxqX"'kw#`\G 8P cXv@>P>=Z 7Xi$D (Wb=I!p9=NhP߻eF oy9c CHqBp9Nh "ԅQoD_Ha*@sqAO.o?+#^s1y\3HoT!M-|TP̜S9x4@[xm| T2ce+2r:l|Lôbe#aFfx/tH 72Hd#&?L_A t%(NxcznPbS*0!!']*1կǭ}VoaρdTz/1A? T8ՠGԯF'&d$QM$dL~{qquH{(Q)xmw9)Eh?=Nƃ! b`#3x@ѹCs>7x9W{EXQVv b&]Ue󘞪g@{b2#Bٚ/Ѧӳxpv74ӾJ҃mvdKdE fwrլ䬙'mw,}t= ~cLu? tx 7N(4< tBzJmvhg _ڰ6ۗ̆ܶ"Ng•K1FV۷4^ZJ4n ݨISF>O x2͟pL3Ҋi0ti{Id \gY["S c*GiJf)1W O:C:~IY~Gfo,/Q`b[Hbh)6.:̸۵|G[xUױpG&Fbj$pb $k!pi~_:NNе~$t4\ޭHV;)mhuhcaKhO|^If6,.ra|>!%hA:BzxVNfuC1DD̰ͣB{SjXQ{'dK3PqxPV"ϮN=:͈_l/'6cW] !6}QS{CL;oU9/>vek;r@Ĕ[=zǤ+xW&luykxDs҂\{ϋ{t?٦ #U/9/qs~[ree{Njm! %Hu.QCH[}]x4oNQ}$hRrm9vh"V$ $M+g SSN>'\KbӢ!)gMdhGi#BhXX!Ex3]ۋdtH&3 "Nբ 0hNyba?矀aQɠj< (G !bBo/8:홳\d>/"?!JQm;PdX'dg:?Ϙ| nbb=vWrg 4 7 _L[ZDG*!"2l {ƮeTZ߫pLd@ڵ?__ w?;w8-I GםEXJ ) ?o~ e/K:_L^q 3r.L/[gM>e~!_l;%"4߳ZVWQTPlo>>g-[AGz?:|ę !yئʻJY SHp}VpؾU6,I$HoeW~V+ߊWefXPd\;>OJO*2\!iD(\N8.(ɀљ,Rqg|s\fNNnaomh*Obo+Ղ'orl[`Vy9S_1jH'G]0t?n0qph({u!Ud[Wд}|f6ty47lt#|b93b$$k4_3Y񆎁_ 9QϚJY3rYLNƓBZJ=[wMĶ|C i}f ԅJi?.)dސ&מoZWJHY\+nή;D[8vQP#xtSw$*Ǎ\=l$KΏ (,% z,^Z_əӰ;8ЭQnJI~:WU{{ ,L.&p'fmtKK;ةo%K %OE[uiQ|\ >!r&a~Ԓ8\M-s/6N4`d(줬~y5IF@_#`& U%1vO"޷k 1AC+yXv7HE?a=s [J9-~˺MuH?\T6%}p|@25#?\b0*E~>F 8 Ps_<<B>}8$ Ufm]0aHJms7.}Tm3ho{JfJe3>oIP<-O'})0^J>8CeOA5<HS~A_Qq#H2R,V[B P#0 2"RC5-}G^o-\~_b&0t7P-SMy(Pd -o;+1R}oU2؃}jUvgmc:oOo>3#U A@kLxPwn84_?pĨ󢝐މ 3+B98ْMu7@t W9y]=ٸ7hoy.n? V̓>0jO%CE햜MΥ%-!~.&mѿJ΍E|{!/cD@ uWPﲞGϠO\? E))wrcTf/u T/?ylBly~̝ś bk޵y~/Gn˧W!E;$]b|~ kgɺO_.;M@EQ2Kz+$h[Qf$h5&G'`Rf?#otO]k[{qЌ *[,ZhG?_[} 32&@Qm TnXy#We!H$wd,%$±@Z n*LPhV[J$pu?ٞ!):+Wm{pPIlD,xr`m,%a74'(ްS?uqOM[Nzn$.B(o|Q9%"v>m7|yI6;AB5;+:Եw꭬ iBJU9׋PbKKl Zš%fjk&dE(K%g8OFEdlsOz T3R̒!dџlYCf0Z%Lڼ`띕6#(W=ӵ(P>σ{]94f|db+`e0D/ѠnF|<,,\҇N6q3t^n/Rr9;r!ǯd䚐3lM]xtSJ9Du۾ }b9zg@F MAP|1d>md7 AG;+Sϝ^)(,:ǃʟ[֯w}Ae A2 ܢF=8+20Kch~(~n-3oC_MܪDolMcƅhsی9y6岑Ss,kՓ$'vlZߣM&BLCZn{!e?ѧLc\bJ/,:]P^r:oK,]X_{X|i^rI׹k&zY-:[z ͑ǃf]v-Au kW0[t[Ufa> ~r> &Nsx&J2Pj^;Ymr*qtW$,d3 idf9Ӝәd|3-JNW5hY#Nn1Ƙ}&]P*lSZ,9G̼}qL%eX2L9Y!6P9RM @7$&Za>qT&gSeopےsMh`ЯkA|6uY i)6=]ty;4B~lXQ%JCɇ(=(`K7my(N@Iib Ȱ4[7ys1 1 p +!(9Rm.e8(5)d";-XiEPwN{]1GI x)q47pQ \j(B :^('7f{cX1(GuKHnI{N?4GruuA&)ʱ!0MQqmD )A3߽a~atZE p>R%E:쎒RK+ R E ̶>0 0:$ߊuxX㝶D\K]Bbjnv@c!ս+uU)}eMF D *5q^%;\lÕ7q"~˺\:+v goLmH{ ESAm-Gܑh x`Ęp-a# a:MAJ{5XsOfۂUj]Y@"ll%tWFW"Odbja"my5櫁 dOd YV#mUAX2nQѯcJouA([SGB9U% %:#w6_YՀanwT[}Y DMz\}K! ؂UD.4=cQPgOc Rb敜T5b Or Իv)Q]Xߔ7{i+N!s]#υ'tN坙 ?R°%y|O쏜b4=,C+15fCP2Fv 2̿Vc̸Q)m=So A0,??Z,~6ןPoMRbǂ>RT7P}ߓ"]@@ K U0\7^!g[x q.8QxJ xS!G~p=N Лzܲ<1G@݁~! Ӳ(j 'a6JX4hSAwp쮪v.-,diHNn zu{dtXQ{bY$A,rz T@{r DH˴ [qȤe_c5<+ ZQŭ`AxEf Q)VȈXW/L ?}bi8V>>8t ; =Dܙ땉.ay28,(cz;Gd͇&6U3߼;B8\/ Gz{- !UD1窠pG='`I"rSP=/I KזEہZڇ:n`-wSA۽Ql.gPzE[DhEC_Ad[scc-!DFM0  or*W2y~~D!H^o@Bn/KK'b 6pQռ<ѥ _Ȳ7|$IIn@W+Zg ب j.6g:b4ek^2CKE ğ Ydf=FٶQQY_:@LOrI: >dn _OHXb ]\Ғ`]] ]^PW:jF5x܍Oµ_ri dž|>tf \|W5#B8*b(-ꏀO+&ϨO' sxH@(9$h|tKP i~C@3p6h8 A~+9)Gt'2]Ds4's] w(zGZ4gŢ2C(ZȾ'$:_hE i%G ?p+>zh=jhh%& A#, Y,w4DfM^uC$,T\hWۄ܅nlSh?|qt@aeZr~ B⣉υkwhI\Zg@H`5LHzrg i,:|T6HkЭp۠.5N?v藳GZ{n[Ŋ-#I R"#՟/͋|qrR) YAMӞ2&g8:}iϸg?'T&3Vlaa13*ZIى2$/`фH?bj  X $k Pbc&6kDP _Oֻp1d!,\'S3]൯Ν7.ר&@$ $?Av1PblELZ N8g-H~`!y\6AS&O*0zۚ}ԶMlɀ=@a .r!i;DK[J2P#y&yfh{Ix& %]|񄈿Ĥ$YBƋ0DRZT`<==1XLbAŏ7RLK=00oҥC'!O'D<1aR2u0W`T c&'}O;Ȅ8^Cjl/潰s=o`wH4+KRޮsT:Vc>1Hy0wD@0R> \Bs8D>nEez2VnjYA+,* Z1Z)]ujwОplVף_bt"^o Dg>JZy Ei%VfGdYϘcQKb3&>ӒąGܒVGS92R}=w͸[~W"٧9{_=|Z s>]Y]r|}=7$<.G^]׋O9umTHjWrTm e`i A!g>隹] ݲ-lXOE`[.$SJɞtr|pJ;^F9LaB/:</;pT[SPV wh " t-&K=^/X5BRl8BJIgNh =i㺟)_9\\6h;ZI\ܭ)ωļHGhv(y1ّoǼX@>bhrhxg,ۯYԀ]T$"_|^i#y? zC3!DrDU?Fho}b:Oq>Pɷu뚥,(h7D9&E~aJhf l\:?vqDvbpm+/n_ձ40>@W D Ɗ G=!(^{XL:pZTE B">jhOX uۆ!m@E6m!l z_؟ 5x)hJT=3 Ew#e\?1qL|?RYDh' |NC #_@MJRX> ] hsְ,Llw@Xq9w07EpE$% 6ןؙ9߷>W\lA\!#6@Skۢ^Z\}q#F:BIQ)XJ9sK zYrk9%Ã5N~+qyˎw>‘3p2ZP|z[ɎUZ'sF+Ze6$=q*@˿ i镕k#;rМJlm[s'V 1n ȅߥ4^;D"r+ M+k2#DŐ;72\5_s6ɠyh|~$:P1^}js}Hmbczui^ V7OP^lW[=DE2tA<q!/cAlTb^6;k 뇰 e.0;hoK>ZJGGvi?i SUU8qήA~%G"S vxg$mQVJvQ5(;DULf,Mןc̟D=B!? s&[O9=oILNѨ"%+dr❯>,@Z3U}WNOrW ?"#Ǒ9L>3Yi5xNѷ n}:k)/ DVv`ɡ%'=ԓ?/!: W1a՚߸ YCC DG;@ŠgZ^t )c? 4'/< h%qZo]l>hk=3!dVJv"(-J2xb Giŀ* t 0>LyIa$,PN $UM&Ծ5j&BUZL SR5 Bdޞ9 ǟQCΗ?<"6O! ! \ӏ_z\" U1\+UL8`UfPՒOO8 gAwlhҖ{lƻ'2aeʇO%/n,񺍹O|)=/Hʇ_ Xe+psXN6N̷2(9,Z.P5[iSM!rl%,P 3b N23q+7n7:wI"] -_uCg'_cK'{_=Dwm뽀FV$^Q!L6Q >[+CS6"^'R wQ* >m&WR&tRmȋlfEgf}q>g+DV@hq~2:qSzdh6Ha(VNR+2M#; + ̷tLfNS*["@cFftXo:>>rjC rm!rn۱؎\V$O+ZQbS,_ *͛le,U;ASWqrk+Wf=Jqr\ʚQ>H6~[6+ +EM+>Y"iVn349O؏hli~ENcE d|'gj9b$Gi'ֹiGSh%GUTX- B+^- ]P6EZҊ:]jŴ'A^үo ʖV^JWf9MJҊJ gك_z5앴͇ 4r@VH?Tu%;i ส+5 u|d;!SDFB⅞{̻\bxCHTy9}D]ܐ)h=0&/U6h]dĂfQEϢ Bf)jm.3܊RZhx+ ސWc&'[D|h͟eleV&hъvZ΃r"o$?hG[j* NrɠDVKӖk6lz{8u7>sկ [>q>@}ۨ7=}+ AUKm~2:,VD| IOs'=JꓕS-3GEnGx˰V,_FfRb2(7@y=ȶ~ev$ J44js}yTL~oCl^blT*F-~>Vlk&RVKgotc]\ NajP@$Ҳ|D_Z( A> A+h#Kl }xIRlbSR'XS9]gpxdJ6мjFwo;uzĴ@9AENn2PM8I M$KPRd~71eD:TK6"*Ejb^&EDlr(G_Jo"H~Ы~ͱ"3fM9աIVLWVr& J .GIdYw#$|Ӛ֎w2_&Dk#K{:>pJUHMXzv7H:8gH=9+A㸬`A[3P2C :"T7GK H(Qx0^m$AfYm$xXqYd` TRfUh׸*%H!2%2Uk'òC íy[ #i]&3GT'rsKX $!y6q7ӜE d;?㿯Q/$Bj^(!>@ : dcG7[7p4Tu.lpלw/Ŀ@}3l óH$GINi  9l(E"85ImS~%g^hXg*0+!ɿd9FW$ H7jH_3dCF7A_ oC1K][8(=j|Y kH)>xb PEfypm&cOS9:tбq~j|{h/ ٰSfd.+|h!On-7Hx@0VV= `$V?k͟ $4:|Sf2t )M@N(/{C~/F wiG1 |[0AE+pH+^d66O9>Ҿϻ@w㙚w$_r\+?WbC ņބ'(nMfwd+3"g4)̣gF}CQ@%e6#!&l%6xfJ$0/,HC^*+p RdP>CJ!qzdJ"O0~#+Bp.cA(6b"h!7oAoݑ`K[%)ߟT?>EE:tSh3;q uEǚ?+вrؖdؖ4Ψ!y 9̪F_ xBԵ r! 5v?T3b *eCĉ[9_A*lzo$wz%-T#ew9 ?}~sݤ+ŭ/Ʊo&FE={*AC!\% ̠@x~1'{~]jPH-q)pxʘQiO1ՁOIT!gݚV-Ak]){MĬܖQ<-E*&bMndtX,{) 2Xi㲿NQU!vƔs:r[ ?G W7kI6a0w (xkP|iJFXRU. az𾟐ST Z'T:nJ >OUOOyZh*bh6=1ҨXвjms3tLt[֜[2*Q9i(%F#n)E?kQJM)*YdRxRPR)WUnIQRhjQR+ KS[ ,qWY]b}/[-3olP5a_apb_+M^Ċli?H˥ݯ` ۅ_)OT|Z{= m$Ji+uKia`'] %??>Y3"$({u($ lqHv:0}!݊m.}n0zXxn”[B/;viv(&AzQ g*q%3T= -dV\RQ:"} ^>+Ҋ*? ΈN$&M;.0?m:X-+^!#[zCAiM@UhysÜuhrF>CTf6RGA&j>%yb-+R CPe_Z h^ڢeZocM%9mOH៵ڼ4vSi|]Z@͝/ }:  C?[H|>=O++>ʆ Jo_)e# AYCg :{3f+/*,3ҥPru&L"mɈh興ZTqU'剟_<;Y>`VP%f;5ސ jwʟ^MTETwN{QpѲԫq1՞ TF»{NO+ܚxNu@^a"m ~;D9 I~F}ᜠ֐u9_4:kQ 1NotG,tW]QKlĔ2a9k7$L虸u"r9 aibXMw̐eAI;lud83>lB!e6/8~~}A{# sl R7Kk8bWhu#Pf+@(~>brXOO>~s2ZGg)\9=F?jo1@I'+JN CٕQo׃ &]U:=xA^]kBrLڲPHձQsrxC`|2)!(iHx'6G?B>?h9)g!js5I*O>%u|H9ω"MD 'L{8[NtooNap%>u/9nޠd O[ xŭ)2u_^1EiJxNPj_ջC R:{-\Yc-x +@an =gWr>4XWz$=UNpp??Pꇝu\H<-Kca[4H;+ 4z%f4HeZlivDr x~$ڗ)~3|F.#g&'~O4@r3URHbH FY翊ѳ xB7QtHm'/*&ZHBQ t) U):C!j&/ym`?! 3':b1GI (DmѰumt+dw> l]!o^qyOoYcЬQw6ww)92a[3֠X:yQ'6E?q( rdž9UR 5ۖ/:ˌiK';"Zt$nm Wl䙑 \ꁊ9q@4۸ɘq xא?_K_}v !6M@qumLA뵁t}9r+[*k{>:mEV0Lh R <hD}QЍ8nj]i_̹qO ?^{ώC q̌|?NN(GC+XO>O ƭY5,h왟&̸NK$T*L)2'I僨ZTW`L }~XVhRPݫqPP:7'PhĜmbCܷ~4Qץ`lb) 0&^9ZwCrQK\? HQDB>NZ!O['Ar ?,)eo-hrOi3v>hI{h⼙@e[w85jIQF9bّ7Ur8J1S%?g?'lXc8ԉ׾ HIRNQgW#A/f"%lL5+)r""0}W"᫑ _{gxH{3g؉az{ (CaRT7"7OP`}Rr^vQ$O\m 5BʛݿN<4^shϝ=+h 6@[* XDgǣqd0AהІ-5CsWA{ ~ffcF4?bpՓ B{vsbk NzojB}͟A5Okrҥ>Vޱ!o;2g=\S8:=x*שN̓;B+8DzKB=R^⵷pmieHD?T;4~Xr uۦVaҲϴl3.\$i-͋2t`AJSQg )e+9wʅ?:XK }7x\_B'ft}*!3b(s%2FMTu[B  %4B*F \!RK7%׃|!3w<|hݺ"L V94Nu}Z!ӡhl2ǖ[s}B/&w[*}^|iDb ʖT,Y-|q99qKN<`++-Oq %U h{-We#-UuKZ.9beӠb;U6Zm#㙐[mv#+8ϴ+vbu Z]vl[[*vCUJvVѠe5 JmХm`,HZ߃!}%!}s HaPsG76`!p1W㙍ɴOI#[4y8 q0,MмE.iL|8{yd@fDcAVkPnҰrUlxٛ Q?&cy\+p@+Ev>P5p p=B8?&l~e &g iЯͼ$ ^V fg5Alۄ~ v.:ݫxnƹRzG3aoa{\3A(wd/Oy F> AcʍrvGɰ(3W7,OfPw2,iXN[/hQO|7LBa}1Pr; P/Hyx0fWl)!#߶>__Tk< "u;s2Nyv`o?>*ga#Ì]wσU;jsL #|IeKB2+< ɭTdKP%k6z}7@rLM\Aj-ʂ,kߣAZhU.Z>R ZnaAݹT[gS${b?̈QCi61#QWel9~ 2s > e4,ÑQ!OoA5diHx; q,pQcrT}'l-KPG>e>hx^P5g4$_(eea:!Vz K棧?w{r38/|8q;$p;hqöPG-;y ̓%r? Ң!Js/wJ@t-JZ)J>JA|eGfY'}G5y ݳ1֎J|γZ΃_AQZ1Qv:_~WNN.ɨu;S*6 ^13*sT(c+۹zzL>/{@PKS[hDY|^ l9/"١:iF<-;+%y?땱g3ޢȝ%ڥ?G?'cClcfayhqs9pxٓMeŏ 6σٟ!#엕!:Od]%\[0ԢJ/{~^!}+TZve|IW'k5Ǹl v }N$]EEA'~ &96GߝP^B  (ՠo'ήsѼxA!zH:: #HWs(;HS}{ >,[+hn 6L/[-3op>yr2o'&sbֹaư;^/TУp֙fOt`ILCfp?y¨Ÿ-!9[5~IjWڀtlFp?>ykMP/Z׀R >H%9/΍)W; \8~n0~4~]$ IGA+B0ocl@OzO۷in~)bdꜬt :g |c̴HR e7 P|%dW`0Lg 3;lDgomX:99\x NXo{ZDup˳>? g;gr\2J]X ;x;ܜA3>Ni[Ni:~})9J4gh ΢F ͣcJ33whH)ZQ15 ( [a!y( b\fjH43 r b,,U\Ҡb1 @%Sf\ّI9hx @@@g1~I?o,l]?T9eR@%I@찜zh{@k(Z> qJ+^ zVs8jT,X9b(g,hH'E^; LbKް oxL(R9H^N$HԜ{dDUN5g>Oy, =TAJy ʨ񚀓,XBĹB][4Q912+LJVQM =g9p#C1c{bٱ;w5oQ}D@L_wxM!_U-/#D@mX{!NK-r\ϱdQDVK'jVUa5_q}7ˈ]%H|A l7x$ϳm2,z& 貦67w2h5 uݽ3^|[w@}?'9Ɍ4.Pq%?~$'E^x ݨirkL$"Έg-bqƱwUd.N u'g^eIxySE}~"-z a;'{!r~~F'9{*#Ŀr$V+$ }1iHvno/Hr+`0RFsZw-{_? h"mR=w ]mh{tFXf6tH'aK#gxsNbG2tbl Jb3q?'ĈRP ɌvJSȺʀV`uC%ĕ K I $X\]W8_ ql T{@#ؒWoz~Hb$g+ߥҳ\z_]gwS|'XB\]?'X{яH$,W`%CẺ( VdoA B7DŽCÑfzA}|oS@guzAsv[c<ǫΠ;cGЖnf6P蕘Ŗϡq4FIQ;{N)',WK%&Ȇ'^\̓zɗboiExI[I^a,c3@PX$!6׫JL,yr4Nh,cpWAsʇAU6O|%YG@$7A,tR+ځ+ZgCeLr$Q,xg( JwsϨOrAGޯk2$5+Hxb@W׿eM 鷜z48q~#Wb>1&'S 'ՏAء`oD]; J |B0x +.ssf @+vU2(|(-EgJl:IKAdش@E9rԠ2rփ>ݛBD)/2y?|Fv{BZ)/ou=E9*[*Cz>(#P} N.2|b^[Q )I(3>b6A+zW!h :mQ]g/mIʭ!Dڳ0HqFy\2Nf"3iKQEg2=M!\wx"WuxI}6P8_a(he BwPt M&zv |O)_h j)%knNiG^ ( 6k<[B|"ӢP${hgqRk-7H?]*Уdl;o:??'c=2#Ex @u֨0#Y vX^BM3'b!I M[@$^n *^m/7P޶z[qUR,bNnC}1_}Xij Z񬁉@/TU٫5\{<ΎȾBp߫Hx1;i\0j *y?%g6OPAM#!@Ы(QǨ/ۍG}'a_3$v:S4kLɬ i9/&lޏ256b(EA;w<.i]n r\T32C.[ 5_1͎e39M&Ѱ|p𚪁~6 bNsP.Ω ڬ8ڈ H{+ҫ] "[x,+L28xMKxi0/؅*%cN^`@-i/H  Go3"1O=|I<@Stn˭OoKx(IM>PQS$$qa6WXf?#Ғ0-7Y?_MĒ 2d$"ZW$t#2P*%!N L{*ezSn#tPݣjr%''O(8=On'Z7ђPE] -Hv͌#?~~-a{ڙEZm>!@;Y{lZ~)GfC&#C2aGQZ8]-7H$ތ xM%Ci K2c0fc\融%Җmw(&딶ۑG?"6*Ҏ|-_dSJU*2,0`ΌkFsBz {1BkPxzEPg h̶[MT.aXd[\׫JpX4piqh{Ԧ)kêkƜ?%.f<Ĥ[ы%7S-?~~yG;\ ?W0-> j+2H/[,]d{ ثY͂Y; }?cG"9~2:qм+%V3@Ar ^Bdk62a߳_RkX&zå;}ĺ`Q=mar rg ڝ!# ɫ&X `,5E!rk_g +ẵym3!W 1o -?~N&2mH8?WyiE^4N?ilN`z}"ZZ[{)ɯ.('3wv&@mIQ*&36NVG;r33 ~ zY4n}W| _؟>Al0{ b7GwgrR.4ZⲞbjYDP|k,}QI pRW6y%V8>jۯ>K֐=_m_Jky]+jE#6`JʶO nꅀBb g^ABbµ c?킢 `TK!Cc7 -h^ڝB/@ӻgf 9dwn}XnyUAөͲgP߽,G $*ee#bOR,(vd> Q*>,3gq> mF/DT|5iJg(ߡD'!| ~Բ3P(Dx݁{?-dVB$#IS9USJxذ/\Aq>7vy/hVP'C8P( Cx*?r^orG|O<^ji =qf@W]hBn @|Rv(_#2UۧTZY|ObF{tf3 +k""82^|qMPWP"- ~js~VXn ~1跒hRΗ(Q,K(:&#F9#(d͟LіE+PUM-Ȁyj9&}RllEMXmƊ mSrvJ|n68Pk@7vWUǂWsԙ} 7_tkIh߾!y:ѣ$rg2b:/DF!<1Ys)y$%R)IJFU)cC$14/TmOӀ*G*NA&yuկ+. uοlIÁʮ-WTޯnsk%;ytJyS;.Gmd炢!)[jz] iiW_4u>vm߷8'Lf6,o剨jA[<&" (v3H~x ؍NbpP͟)vi TdiHG)WPDK/"P\|5R"I>E(ʥUh}e{GDݘKJe{U5C؍p>z+/7 .Q}=6ЏHb%G P}h ]CTUm2Dݢ*uv gqLt6!dR3.67oՊm,I:#n NĔۮ~yb9.Oͨ$qp~i(Jg7jVP̕jzb 8:&B9_i\uɤVP\zTJ]HR(A-D f25 -nuKru5rc;ʚ/b ]{ޕwwŲ+**`@tQ7TB It$w}Gv8v\LX[XĽIp% ՚ZSm^z7J{Kq~37[9)Ovi Kq:)R`(%R9!Ә:s3C %Ek)S\D*[ zuK97`(r1:O݌,XA[*)\=kbA2wFJ' Cj WGf8.WLy(wEs#:ffa-]9׃6aK k{MټPqbDJj j]E4K~> a}{\չCJA}뒫3 &NpM8o^ 9oMN鹴p&ÙD.@8޿&jۘ*Aa?UA~K%\!\~ƽcIU}Bθ3A灁k27K1|xƀUc _zAG0<'7Dna ydUXPԼc(DwP [%cymvmE<1Nh_ bxG|xtV4ĶMt)aڑC贪[j>ts0^Tj/SN!B9l4 uD)j,ynw@9>.rkO~.UP( GFlSR?/iV=wh]<hOX( :dwq~TBFG9qd#kǕg>o<e'{sG$}2 X)JSG&q#\1f@ \ݬvZX+L+(-p$O]4o6<\]1(HOЭbjˮhS,/֧bUpAb; [- :|c~;W[vOt>~=zߛ~ex?뀔49. 2q֘Rqy#-.Adqf`̧ $(#2$PQ)\ G)rj.x(D 5!FٝdV<ɧºAc3+PlI49QW~sJv< &c?X^8<t(r /|N (s~ΪdmQ8EۀFLj9).m)7RkZyC,Ue_лu#]}Y@}۲Sm=qxM(_ku8p@"AH7ڿGMw}El_3Si2ړ(XOi2Vm_[bؕ'|@-_jA;AIRf,2z4ֻs;\pՒgs<\pOg:,9~ c=0>]=/>٣W:;CJʆ?mITayj;dz]vtwkv 9R=oj˷M:/SsV+" mn;C[.H{ȍt0PN]`Q,AX +-+3žXTfyTIe~cwm#8x[Wx=  zvkξRi-Vb LCtmo ]帼nv>3zv:v;& ָSgC0+4T"S]e;~7X.3MTՔ iAjs Hܟ)E-Z=q`ȓqT/oql#'Ey 9Y"Q7:TYJ^3D VfyZŜRk&ccIpM԰S:'0f \ppG(^h< XlgzL8း~ɭ Llg4w=pVjjuAꤾ}m=Ҁve u}n]\%'T3H+T&"Tb/3Ue64.h S.yJ J) ߗ{S_Pv ף"J~Y" a/кy4Jy![ .JaϯGCS],_)X\7\ |@h z,+K}.2भUQHG*F㹥Mo42Ӗnq服( 5O#ҽP-|W6d/3`&Tgwpf! DQ mِxX߱oeΖ_ a72CؠY}2 gS)a~lJnpl-Eo_  LZ%G %C1 ͉q#?Ѷ>s=Frwy:?ڒщN]֏kVWݡ-uz߲%x,aFtJsV[D>`J-)?Nz8o>RRkhrWI{gɌxlxжˬK3k[- T],l$vVFԻtU"dK<?c!rɞk?] K"?FͿN8PEV(ooTNscP<Ǥ֓sߧtgfz-Ϩzn~n^q|qҚy!Ufx-įv č>c6}U!N@ qDɣ= Z>:W!M}j/g_װ?gvaYY@}ۭ.I@)WX$ fSZ (h eO]@cy{ih1P;gX'c`s!Ŵ.fDg=ϱYۊg1 Alqy1މж;+²Pƒf(s{ ?s+6ݮuT6ƴnd뙳plcgg=-_ʷ=x)Xӧ(\x;ztxPÏzVb6ׯ`W+'C8&() fTI6MhJ-On8]Jԁ n hz 쁔?NY3i Ӵ~7ݼV5 m}@NvSR@ȸ$KSœ(R`ţyRVa\<2Sl 轻ۺsya G dFOK[9k~C W ~ͶjLDz+zLE DrP @xmY٩EYLtЍH碷Mk* aئ%J"/y> o|q/ܭ~n HC_Iv!`;xU@l494Vq*<哉I#sAj,bqt̵ѫDX̔KNV#pׯ0b5FPֶ&b#^;Lt}FB8?uT{UAyOkYgrB9Mtֱ 9m.x8P ׳w5^43>QN(+|!{Q0򱷄a̮q=+£Y|\ 9ԹW.'5YxHvkK@WuQI6[r,XX<~$`$r_I&̈́X֧Łx]kfȫ@E2<_4e^3s@9U BfRr QylBDO61UA{fIl't3h6\3Lj=y8WWk/zlY{4}9n %]TS/\Ξ O/>s:x)-%5&ɜe baazJ/Er4=6-6 i [f=5cbk(*t 3kEJ OTm>?-!2byMpw; g7sC|&2[Nw\7v|tl28YwCm]S8s 7hS>NFZzŀFt‘C#$J#7kS^= N`<֡$/7Iб45/ f_F,lx>iKaGC_y?KF^1ڊsi]$@b9d] ]OdoBvn>GÇu)َ+厗А J}*AQ fL/)ut]+ب=w0~{&)0ޒ5%ϑРlـ% *+!M*R5\šA~e@_goo@?aAcרvfdA}mQ<%iL$3m8x+ $w< Hɍtaw꒶xTY 3G2#pӬlb^2# 3bi#̾8¾3FSfպ۫m V?۹m]I:oC DqP}5ޏ./-^ ܬ驵aC'ev ?4W[ŸMM~nI$xɚ./ctD V9mQ]/( >s:\sv갣ݤ]^u`Id온YyO%^;#ᆝ`p#߉_o=zW\a4UjuHz?BZkŎp6Y_Dfq<@&i%U3G%SJh<>VedYqңN(OEQ$b#fޘz6(R -Ye'˚Gy+8W϶+pqj5Ayቃ#\ƒ_7O>'UU7P=[ӵ:ʛx _?UdqEn>i_ :ߤ&vO֚Bg=רRKp*&)!ΏC|3Ow'zqηoKu3XnQHruriĢy} m0p :+{^[? B2_lPI5(/$_Mm )^SK=swp;bX'd;yܤ-!ZB[w\ E4gI/$ݭɩ J[?NjI[>2SUB*饖ziǧ֙ (ٰM-mD#9'?Y o5{Ċp%A'w+o86Ԓ!zi\_ĀڑћI{ I0⋜܌t#uIuo0"36؈,32a FxG;R9@PD{J2&/$cƒ6xrn-6š w 1q'Zlk*#fes_eY4u/4oH#e>N[uy3Yݹ*6LOTmZz'0" ̛_KpۋO.LY^bO\=+!ۮgۢ qN[.BJiɐlڞU!-bAX {@wMLY} c{Mqp2j7( r'G8%[f^?&xtN3,u+LSʅ 릭E!J^)M( fKwPNac2cM>[}O&)]zO3IΏ`.@}[U͏[.~~"n,R2HvV!mta]f 5^ȿ)H?;8*f;2} 5~DR4lvrٰDw6je$љi!eehdw$F/mm;HM†#RB XW%$aBlp̀$l70 =x *Dme%8H@ !m6&KvFf> wt}9hAbXNp?:HҨQ_M"БR;yиd+"A$&e JxJQ+1u[ O #W=36S:Ŝ HbX̮v OsH@E uh|_kD Gc͉7Ga 7Q;fG}a{FY%a~[uy^ZӉwǑ@͠˾mn.}=w_mQF9ߚ@D}n{zN/Һ(p gݩcǒҸn|_\p"t@5Bo܄o ~o5 [=+ԫ5ZtRt-G ]tv&- MU/5KNY@}ٷv^4d!MMKʏ!Οm!y,mܝ^%ŗ;JB!#@!= ([P.}ui#-X 06H *!9Ri?8_Yh~Uy5N@8oWYj#@i|N.Sf֓.cܦp}O| ]fC\.U9$[r +Oy]Z@UتjD~D )< 9{qhSpDL-3hXz߽p\ ~."uf_>8ZMu_6&+fF%U 1iJڬhH)EEY!#ݨk*BdטzDrZfY5",b3?Ju\Fxp'R_SxB8 aFq ikD0"K/Vpic?۸xSA}܊;BLf 3ҙ']O0WnH/}<'S#9眪}h1?p TD~-\7mc)L5: &e qo[m)HRoVȁ=# խpY5 2AA={]ml)Y} ?5%!͇M8J׭p2ދHI@*idEP(D^a2yѠ~)Vmr,HZ#Ĝ8|Nxr4֔P5򲡦@q< ،gX'e\!  F4mNl!Q fXn|Y EH]#BD(hE%hy-殉x[}j#T2.mȽΧHIQ(`lGSBKښ}f,5δ|OW# 42!0BnzY . 쟫Hh.Q>pC bL)!՗^( +DbvDKneƾ{6|5es6|V{ nFP.9 2[5#V[+R Sg*)%IZ&I ,tWI@)m40(Y?7m['n3v30DIV=#X F.Ua.kD|́%Vo u Zw*+߿quP4wSJ5cَ.S緇KbڼfO1vZn!P~Z?C1XkbHOmۑ}-M 8m=ԯ~u7k|R7o֡23#>58|j.bcb'Wg{na3i`Oܪ]'V: !}3ϋUC{W6aeh1G t~]Ulo!t9]?_f@G 8 [gUb;Mj<.j`1ܝ51sC8moL)$-NbEtF V%eH3{~l&ʗֈ*S,[x)y2I|u#AUΠDbqsʓfDbO^Ta˜v=I4O<ifqQy$*aN+ͯ7]X h:WW"eVn>c[z8R?3hl-m~']4tn.2# UGP`H#naJq< %=9:94ĮySȌ&7(~Jf]͂qP.t9$B Hs#/)qV#cXF]2+ѸiRIW4A#e!A4a$zI"EK?)ڨ.7qbaJL`/&u{ccoUec8+R8~b=Hhϳmnw $tAQGHrXH%KAW末烅 yro~8Rt 왯sFt'~鿭`?_o$%wXQd:idMr- #@xMqڼ(71/ms]W8MGh>Ge_)t#BbY-tSuY TĎu_y-(X&x䰿5q.bϷo, {\H `؈&F: J4W5&D嫞9佋Go` [Ƃj(T+3> PFƮI/3GyJPd$w@Q.Lrq$# .FJ(q 6PN]Ra6k:2K6?B A8M2Sbm# ܊ ܒ<-m8J[XFOZos列lY">n}T8<1(j:p+(fD"c\貐2]24(!U[vD>s*w;C%J|P"> hh܂R#jU?ĭJ(j@R͚rBR};G|VSʃ6JSsh;theFUs¨fPVxMHɋFr$()XzbI%~Ddiwb8Awꒌ|7ӐX˅E,YD1қ B24 $RʛX 4Pqp%nOm$ V'tӠ.*Tզ,[ bڎ%/UrPR0F.mi]N]1!XnMmHΟ tRhâ W ,tBw{45ݿlHXbaxڹ- k3h䩲LA3ם/l[ ]^AmNgd іq ɒ50٢Ĕ0lPMSqM@CGd|D,/=-2pfxFoPDV rLW &<!{=9O6"]} ^U<&u׊JdߝU?'nW֙B,{q|ҺhF~8CԾ)DkŇz RoR{i([J!O֊|rg-qL/?IRӡ(rGC޶/7Jz(HF:H-lͼli80<34,X|12bTֺDYc]{޶0|#'ɛߗ n,xsTw$CzȋF^Eu h$=4"%oyXy4Cf v@fgen/oiᣳ+) l%.ͯF!teC[n |l̽/V'AH# GT~TTc'/ Dw{dSeP|@5~aګ@vŨO@e2eL6~;:pcM;cp}6\Ѩ H|uҺ#}!L\4~ĵ~_ Hn{$^c3mi6Ơ'0 zCZayfdsFf>eD7: ǣ#ݸ#8D:8Dž.5|"rٞLUjw4R7iIlVd& %qGǰjBC^^ E:@P>?kH|NUP!0uEaOG~}&~^4hIX1?ć:]|HHa)fO )O^~-M)c!mvϑ,']ɽ?Ȃd%Xx͊\4(ѝN8)w7M:<ѬQD특7Z'&kXT$ 6JAZF )EPb1QrgXZbc5Tx)!HUذsM/7^>QSXpO"ww};]g˻m~}}5i}<[#މķW'?&ecFkf׸Vh?G WA3y9Y3_ & @R9w;gd}xH۰$>\I^6˜l/uXKEdcm#DU鸦AMy:IC[jE C4@&>FJBEgDH rO1(*S6NT bT${<ʛ6BCIv'h/W^Z){%wAW< |Ur)"Kz#)2|'??&$I/iykA6]{q܂=u6^ 2/!o?DRP4rhAr9?ŏG{<q-5%Kbq S3= =qזۍ!jJ! KB`9cy }'vZkvYSb;$7zKmŴTyn ojbIl'u.mM]nXo=\hC":ȦVR Hh["ۊƒ_nSZョ!6KAbZ%ޏF[SCd6u-i=-93ˆ+ty+hl2؛I?+pidK"َ#bn цț ɚoq$4fhCJ}a}5ZOCAZk[4nBꐽ AwܱG@WPQ>O@!zGx1/dbs+>HŔzFˆl/C;p>g t Ӟَ~YM-70 ڎ"ֈ[#>V>+w_@v[jD|exϪMZCl6y&Wj½KWȆotŘ{&\:zn 쯤3Web^sp >}IN .ZԔmiSiAW`|^"? EEKDwB7-!}ݥHuزlxnПz=erѠo_C9i=AwϟsHplҜ(nlD|OG^9vTdRK#v.3#6'zpn`han1;3L_d;:/aO)pKȆD%K>غrcx!dT}R+S:B= FYٌ嶿B7<6Ypk.> Kvڤtx7NSY8@0%dC:o,<ߏ|oY\|\} @rbO-ڠ'力iM;4t@9[kW#PL9V7ϾL w`a-7KKOb{9[u{myG;t5< +Xݩڃ({5<({g?K{p^z%dnSIN~aSV=֘]5'H+FsH=U!naH׮{{<}wSů΅OU|>t]r[h>TzN|`%QIh:ҥi"D-R2R-hRK '-MMyQa[+&`kyۏ)54?F4:1bRK|T%7܎ Jf (:~w3V%a٨OI~aWX7:j,7V}Z3z+d~v>:C@| ͅ(JsoM[ ),a{*h[)8kOv'ǎ Iqvf8,tK,m*76&[FeFq^0~(@I>YU"RפZ (և}ghrC[d="4 T8j]tAXCT>'L(1=O,l9$dGEP^/@do7Lu9Kӳ?}6sn{7Q:FA]j@r@:ڨ R熷,i/MM5 vZ@287&* >IkB7LW aiU~5O#心$4+ OBBYɧ@r»=NO } :B]{8>ej*>&EFPG)G޸[9`ǣ1=Jpr#t3uM5 3]B-، L[.vَ6[o[xNTb?60>}p:PQ]#P"YH9^wb_y9Z._y"~ܑZjJv<^fvĵ}퓦u7w}<\\"eoO5eC{|\#ƈoD-3K_7T  l8$u ;$nޡ`kt顠}YNq.GqܦH[otI_h7f?Lޚ}/x#5G h@j.F*7ZbdS\Z}s3H[9ʹlL1yomIS#Gidc_\Q f M/H-qĝtwQZN[ݤz4eAu9X@G?~Aj 4) -OruJg>YܺGC+~̆/KSKĸ*2#H&G0ٞNpTv]\c1[Bn{~8F\R6>vG&]To@"A[M]ǦvC|:H.Ul) <T2Hc슴?^_NSJ4&3" \Grw9>yd&k5:DuWPt+T2 ht?͇F(|0'ŏGcz)Hl`~9@GtwdF\oe>]Q1GP*G0*Lq'G@8o®,A]\@0e[ta+`p/%t/MXߥ2jPtܿequBNpX}.&o;N am+.V( '~JB`$n*Uv~H2gHن ^;m 7z-C ?[.辿Axm*RIus1AHmLq0[-|Os`O0̜ bȉfQq`X f2%8f[ѣ_#M2u!F;P-rLC-"zu (Y9'Aq%%է)M]~R`$yܷUNйR%'YΤVDކ^_ _ tn.+͈ sIs|8͇Ӏ$4\VUCGƓvey@?t@7Apr*䏅5`Ȃ,l%hxc9mx$L58t8JQ:)8BX|U-߳Ia`+ϏHc.+2Γ")~L?S &e}FBLVŚKLZ gx9C^" R%N2[QߺU ŗm,)&Q||aRdkʆn2OH$H>ϛD':ªY˝=Ln;K x': mQ|@q^$H6#8[䔙 bfP9m@ ?bP} C+jT/ S첷QYvU&W0UwͲyU+mv.Jr*%,P&Cp⺉A״L$ C+C7p>w- =;:e m}ۑ·Fio&c4l8Jph]?Rhh4x+ GfpMdeZ@-jL),&Ep3H}Dp|chhјjbRa˜+$Mֈ6zZx`aP=]Pao@ܤifL" HeBpcayitU_[ &QOP9|j =~{~}&~bQMxȃ_Toc_)P$H3e.UȂV-!| PڂQ m(lbԟiٱ'u1E*i>1(H -ŭw Nxy +>oG(}}9m @v߇eb UvîkϤc՟1;/Y/Ηʴv*P٪f0Dgiǘ5=eY 9{WUDyxk&'x?${sՑ|p= #[m_7z,o'+?_ x&o< Iy,:ǘ,A'y!ADߌ,.2?aR[&%j8$J5$Q$k,%nNa ͆)JL_W/E2 U+Twh,gɬ{]v3xb̨;%MP&84c6P:M=DǾɿ"SnMԆ̼TۥJmB9v??S?2i3hT^HU/Q5xU}j%wAT-cƹiFqe2( ^RKY TG!pfAƾԏ fⵘv^AW˂g?.g|u edHuT4._Մ&2mѐqI!,x.ɍtuM[lRQ -hkVLfɬc fBRG  eE 85i_x6U4Wc!fw ի-r?=w_mʟ""_ ZN) M]u\{*7Qv g|K!CXmG[3ј6m^xqoo_wEuXfG Ɓ&Q1 .,߸ @BUrC+ [)\0 t5c>>4}m;Χ9N2\ʝ,oq{-]> +Igk"5?RCTp &RMA=/3Ml{bd7ٙ\hdL)*~_"jPB3i(f@lI53, i^#4FU{(ٟ#A$ ˉ/Y#p6XUB5{'B0=EmIfW|S2.4|/'BI1eI{~=&qR W:BH9?~f_ji k +='o#]g,^3Q |"_DG%lGVOt1RrHmێU!ڏ*EӔ 421zd;lGh#"Jdrݦ׃(T"Xlr/QMG'AlvC#@}d.7lHd4>(4dK:v,ԡCPQ&H9Bх>ޯ2ِ%>%? LvLdu[%;<;h;BayeOB|+vħ;7^imcBګU?:$CZ[?YiO殡[؎_!ۊ8#Un(}H F[-n)7!H-mDdjŢB?C0c2˔ 6's㤝@hZM~xDZ-HtF"hGI2P*KK6}eV/@Qq/-;OCOe,\[nlg*:HroPb-|{gAj~;!T9 ]s c9GO˨Ψ zȂi~(Gv䨥뱲iohs-]2]{}:knn`L P[znMX˞Fdͷ[3:|OPoˠZTaK^ަAgu9{}W`ġnpƳsv!{rty5iݼ[=yO\](+wX8k ̙_$yWIu4;>"v q/~*.6)2gK%41 H gv( S q; Tq<򞑀ZhG ј &feh-ߓoƬR Aܲzl Ͼ jH#*&,i&vl6x[Tx,={5,ߏ:_dw\1P R2XfAv.@Q_Xuja\`uCkmv\l̞apsH#K'o5Pa[TԠ<=58q숀ԣ::_>tK}*x˙ ={#+{} (d7&JдUd|)uNm Dɧ.FJу."Ei fM*m֔ob؟vM_*wXQe 282]Ɲ.Hn°@l*ZBجP%>D! Gi ̹q)/ S8 4ehJ4gڠb) ]!`]@ҠmGtb99 KgqFn{+۔ ҞH}K7}.Sʄ*G_K}Na=fDBwQ t( r~o7Gv<^P4/ݱ@h s~=&QVZlivqCffh/eV a#T ?(wHU]xOvD.ĖꗽhWJ~6AUwuG!:^P9Nf,9lTzjrbjJe@kwtqαvY |?@z#?dhGIХ(i*d+dОHE* $}E~ʆ@ xRM0,k.)FbA3oc$}CڼtxI5o;^ձv 2đ"䨲YEz?\ӌ-bCV*]kݲe}C>at$0Bqg@[.UƍG |y @D`(H[f;3^%aQ<YLfڲI&nJ¤w#_e^ !Y%atJ{ 15sIP{rݦ|M˚Yh]I6r$-7={='8o\SǂpCH43J$[R Q< 㖁e"5lS&dIɕic׍x5h G:NiVx>tAuooֵXIW/0# d<7|./,_GJX*HI` BjimhMXga31ˡBT޶"c!}*gB@*DHITcɿDΛ7OVhݏ@u$gA-wok* ⌴D]j/k/ 쟫X 0h%>(^p "%#-QEѦ֌oh Y9+H8QS i1stYgbߨ"5}{Cq) s!G]\T7_Kq]8HNH{!H6yfZkQ!@"TI`&ls28!ѭMnlrD5|cg ݈>0h0-:LuaM;}Yfo}GX0cyDZ`vC0}$]ķ;{ wwpBp}q'`9$6\琶b;K Q"յqNЀcYmiR2r߿ET Ҹȶ4꒼T Mot7hKK ϭwO,l6('5jE>Df) O9Y?98tAfKϵ.O6mH04C mˬO=گr5! {/Ȃ[;k7і9G?k!vWyrl|Qrde`&̄l7^HɛEIoB/D5|J_# 'e7A6WA<ЏlH7c`dS+gCc7mA\w'9K\g+\RYm ~|Ȅ?E,edsrnwS5 Kku"A〔4:ur#)8@/.ϋ̾_f1OԴ-8%X s z_W-b±1Et҉Y66+CE8l̀bbUK?{-&_qwb~yc;Epa3A`*|T!e^\5̺h?  h>>e[0̠P/3@w_%o\(#msASVxIn!*?*N|W>/a^cq\G)73&8\HoFs+mʶ)^wAF<\%bm3+w_b ߍ'力 򕽳z&qPU+g_P~} 瞽'{٪sl#׽[7{՝ڬ=\?}w3;ic2Th䣑_Zca㲹~Ĝ,#K( 'jϯ/|?N辥X[]EHh_wÖ[4'$2M! q+OqY}[c2oOsV4F%oo/uXL/N'koʹ|Gx~1ϗy-kSm $0N|D5å*~gz6 {p!7Z+P "Aya;!}c|}*!Nv >Xo5sAH7jISmt Tpo0j5uYv IoHR&_ :E\tl{wW?5tq_4(GRx:|Vt ZSinTCrztt7R邀\cF0j1W9[+jNㄹ`9I& WG*RB˯  Q!@%^ꂀoPUvtR/b"Ln9Ơ eWs);ll~Gp-vBbH+`8s\[HzB@ A2)>QRSFi/.-:мuWzA܍O el1=$ܼ;#"f>.ߩS?wޡ>F<*2|IFt߶ u'MR%c5֘sƈ)[NE8cSAԕy*9;3wQIr!k#s O)'Jcɧy*YHf,2uJɥ,l0x/ƮIґҘé J0=sM)!NDJ/SuLͰNǃnͤA?%-NgMX!yW]VCJ@v ~͊MmIӟjLV0# t #O-[C6nK8z7:lD䝢Tx]F&7Ff]<̎Ff7CgEv]b3*(jX{HMAxj#B8m*|^cWk$U(zb0FhB3dwt4dntD *w7B <ant QN5OT#k߯٬nOO(gW+j視]y#Hvmo =Ji}{FƸme*M_ior?_;,辅 : A3).c/Sm@cr:Õ<CZ\ i: -_t{47;tk]SwYU>qyւu7J%6@2)^i֐ayˌHd֥)pL &]Xq:b~SG4R)mg_=֚ XDiuX.ƠwNHxs>k*@4Yܕ|vΠqa i6M ?`8xCy#+|KfL YhE|Ӫ| ܶa@Zרj'YHC 1m(`ɂ:Dg@]yWNjN~0 "ˌ_f&h٭!pO#s4l -) fCr>^C"HY, RjBT`6RL[VMZ4AvTH;gwAڥת%A݈̽ @nszqxC| kbAq4m %k'PC]C =t374*RP$UаZ>V;N!󾿩sI@ w.a?Dn@P}2igZkvY=^|KU-eP1SjHtIj=⺜֝8c5]EpobavThNtiAfx&!=?*BZ)Aa@=&hEDTY:cE>_~y[ͰzRfjPI~qYNd- ])L3n-?nnзt|0hBO =*# Wǻ526aB[Hik68ӿؚ7&"4"5[d53w3.~ҌȤhkv)!Gx[Hn "!X㎨ SO_T燛fQ%ئʌ_wDe iapQ(zTqk@mR롭mILRHC}ښ!c5`T6lP3V Y l͝ŭe\WvaIxExȗ-CD#9wG:7oJ^Lk.yR-ڱoƴM6 {8/5#~&%f$-; "pW56+loT_{7>2]|&'H}fA?@;'G6e=qU_74U^pم,њ=g Gw4/ҸD9fZ xdKLFj) .a'Bzblw&wI8 -gmn@w1%׵>~A7@kedAm5omlbqX.Fj614>J! oZ`Z̘$3,J'LF{Y*楯M&pB1Rb":QJ%\pUqNERTn1JK}&^HqmX08(EFnrh匤cU H?'< ʄpRfGͦ/$ 3Q,̪IM)~+. c-o*rh@+=# ^=GY摠QVq ; ("^[qI@HZ+XfJ淊dT\âDap+ 9)ȽUN!f y53">۝ySiz}ļ է9 u台?APaY@ys&UHvP R>u-SYU R7Fhgp7k -kh:pmw GD<4%k ۛMpA8H$iVzD&66+4g6mΆxOpό,XTz䀴GyfǡCRHjb%!r#]L]擂-٬iP 혡ͷ|OL!퇷/dH=o[c^Gy;+>?,ӯov7cu_O~ > #˿D?&y}Ap Ty7oQE5dK@Qf} #yAGYu.-*Trp#owd`V6 ylt,i~H)`N|[pr,1}p4y4ِ sd!FC6I¶/,}Ĥ>pr 7i3eOׅu{1(nʿ3- )#]Ϭ2 ֏5!8wHΗl0.B6663>ͅP n_tN<[z͚W,ޘ2j^z,7 sVɬH @H+)mZb?dNr#M+oV谡|G$B,G)8ж$ /1-A |6V>\2aef2(YŮ#LQef,dʮXT@λ <0y3 #}g ,.qce#)0CZ9 #8HSkV_ [ vA*hGm.g˷w 4m}(FRd/'[ (@ [&Y'|vHgeb̷ٜ:,E/B qpж!x l19)4 Ucɧ |<65@"caH3`qAB.`ihOR#ah*(5JNu61!A"_APܚד0m52cwuC'9Xp v$-ϥ>o,֍98i$pkDn~r#]J%FKS*f,y\M!{ 9@p)esv D_x$xBDߗXP&9 b6}jTuۙk8U)f:K[Wֶyb./KAm/UpȣW\q9Am`ZD~fOEd3Q~=& 0,O6vJyj߮NAS򩕚-}ٕ?2*B't9UIj:+7^Hm#0SĶ[T]Ըɤ(`>ؖp+挿~hd$#%1 H|f 86`i:!O [jeooϼ`6J+&M7kQ}~78)*zqt(nYT(NFsR{FGTKkXͧ!&?v/AAerRQS)Q?ZҎ%{nւeJ*nO@![Io+7ҖH[!MHQZaT34ZYcH-߳|gA5(R#[E_9PBb,䟵'e֔Ry @OUGu볏;ATLCt1$,k+y =7HZ@zis|hX1o k;^0sHcpi#"A׶Qڂ.fEw+>nr7ǷR~<2[iPU^+ 0~q(MBdKkPL8=7ӠlgkPÌLH1nڲ- ag&!Vc fk,g&,^I-M1+;%GY*t v]`vJ/c$0CEչ EڗnV;iNFm2@~I4߁_I@|:3 Q?p$2RT_?]%hZ0 @O\ϿS@}{6os- (G.6:h~wyHC"$&:ЫdܶOɬK]hEz9ɌLv!0t<۝}9vgN@կk@n?uyQ(ayL^mMO0&P o( =5^T NK t-G ]tF\1mR t7ҏ<?۸͗ښah[N |q;h14+>IDž*i>lp9 6?&JYgld8ϸlGT~H:it뇰c6BVuFV>Ϻa/sT5/iD|qM9w^u|Ú{"^tM~oQ]JYɌ_gvNRk/Vpgfz-׼^7.]-UoUCy^)ziďH xi$m@>)G~=& $XHdݮԢO:\;|ʼ#WAoZn!d,ONIlF$ =EqaeqfC.rWIIK59)La=v2K Ҁ 5;kx_,? *vi4|J_zr譊5ցSՆqL9|ց"{:.3[guepY9x*ST ?v;KAvP]>45^%$fF>>?8@ynm;HP]WHkp6wG\.6_oCjHx;k}2~lt>;׀8M4FFďÏSq| yhA 8.t.I¦0kkeltwevGib.~:a^̶l<jς+x~OIJ_Z +6D4YS׈0JB9ӯ[{9&i Y.**Us<+> PTm_y2(v%ٳ'VmaM:DlS\۞< ji>8nNZa\("[ΆbQ0(eT]_ {qFakvĭ^sV]!ye݅.}xꖠULbmЭt.o6揌,쿄#)xz*۹]%#قɍrz+3\ŭc'ӎzkنZEeU lRW'M[3Ru?ۥes:4J]AU(`fۚQ}47m63~xOPT޵3 ~[rSy̍+ D)˺N7 sZRgiHӮ uvHe][!LWr7HK[4~N.mӟ']qH0 *]H&8ԟ(_6۶yc46/̱Bʸ`^ylێx,ho N+kF%eߗ [S@ ɧM8S{W?߻;9 3lFкp |ⰠEzkFޜwe{~=&pXq1MXiGVK=S@loP,u)I@r1Җ.6%|OtH-5&Ķk,탒OY&d/3/#tnN@Fx,vrF^A)rvHon!bTL_TYP/ 뒫3 _b٣++VRAL ŠR%4 L$ =o:$*?_+ 4 ^ÎBZ)1l^ ~cJWЭ+),QɧV)?E%Ar[x7&HM$ DZvrvCe2dwDNQhU넙D6cHmd![Q hЈ,Bc_1Q ~~H:$(5>ر/D&LY2F31y`qT//M΃vc}+v#$O o+BPR> c-߿!CLp4N`Qrz#3avs2k@H0/ DQiHBmu-G. =&|npT_j٠uT|/{u7" < k›ɖbqsJI"u˹ZSk䰻b;KuG N.{[T!-XbNXZ!`vyen< 7 O3vw<syROڐٹyTtn..X2N,A^&>l)b qE#[ i0$hzȍ QdYCiѻOUlO˯ ?0~dNNWTJSȫWCl |#Ln9n\tҨBqC ?S-##+sBf#қkzx%+Є6d2_FJ(Si*7Det}͖J(Kn5o`g;!5 -2's( TԘA%j#nedO^ kgݷР[5)+ #H6ǡQsPn%GF]s. t3#!5"y0#`'CD8R9žfqkCF(4lkZ\Ts=1nTojvTյKABsL9p6;_Ϛ2Wn&WݷKw_Fb' mo*AERV=jZr E]lk`f|\{avw@ӏuC!ia) vXAp-ck\\OPg>'nFAr)ґ4 Zꇯ>eJENu*Ӛ0ٝƱyP*T-]gMU2(u(Uv_D8SDm%uP]Bon?e2c_R" @bap^RU C܎=YfAB:Cb|5 JåBN0@c}Zl uV \wr * e02@kF[ rKI|GL+ 7k*4Rb-Fב!Fx0`.MCfBratUO5x oRqX3]!(Y/_V:&#pFlyw_mX+0{KQ.(u:g2~7ӢN'\LkLJ-{3z(xc*]QM{5vXRu rU\%3`G InxACV@AAr/HV4.H;&nBk m)2$B̦sЦZ'ꙖB1C34\,dOtϟDe6 '7653ux[4d‚o òq1ځA`R1@Um@9fbRifԩprq=覗[ot8{WͳoS{(׮_xn)p?vx" 3PW(!1 $;0<oϯ$4~STKGG^q[Hu uNϽV]&E}jA3O\2>eEYiAi j`P3.4MDB\~CgO;"D5cp'""b|p)l?4Mav!-YeA{kR[~̺7OIB|*Ri4孶xIBD-/Qb4vzt,63n3DVL6eUdt E3gd3QP-{C-:LunGg.2 Ee+$֓~d \nGت?+\.DZŕt&#=wTʙu q 'ZV9 RZ^})йFxz*Rh(GIc8HEXE975G 'dezcX,0gSl1ZU\? Q\eSLJvmg?yKQ ӣ:PVR2 J8F[ӽ3c (W!>H,|Grd?;Oo] Mӥ?$beS ͛ob3D6'%-NDc.,TBf* C| !GL@KH/5FvʃBJ?F8bE(?T^%#W:U04 hSJ3Rz{ ӿdPn=Ȓ3֍О+ 2jKDI|S> ڢl; s³6HPtmt I<9K8DBeg4؏Ʋ/,1B5 ~.P ~A9.ONsQBH_!Aɗ'sI~X|yH͟ P,d|'@ Eb,[dgcjX^yjCrs]NVS/=jO}fO YR/im4.oW,HPR1kށ^5D+Xg<[,= 8_rK s@x1qw&q(V,^`ؽ|b.6$ɯW"jJ.7/uKWD1 Z5E Ǒ?"z)5_ Z@V,դ ++ e3u$Ҩa r7א:2Ժ`netv$b J>9Y" T"Rum5L9lh,rnI(i 0xrr43n_#Z)Ŝ,59X rі s2cP1' VJ\sv8b.&0w,<&b 1Ξ_4: &e V*Rɐi7!>8eY :z ӽzk,ud\?_jQ&љHJƧg=CAYg9vxl9eRnHݑʑ" C~!⨚Y*imJ՛NuQ/Vu6~aګr!.e2qdΆNZSW&]t gO~ߙ .R Dho/qӒ1i 58HS4Pcܑqi7M= i#]uO@!;+N8#ۏj{/֠DFfjt^F#MɍN)Sf:9d6>̞&7:`NXL6yU Vp_OOoUJ-J4(:fV+smHeـr#qU>lW_:N OxWe,շ/p9{rnρcoƹi [<ŕʠ$iǯ@ZIC_t+ :և[lݟmyVWw 5(N-]T!E?RoȖKnNF;uIwf-=qFZ'%3EIr>̒Uն#H/! \U;C qИQϜ@]P ֮ߛ/ utױjkϾActDjRۧA}`=!rA.>>ۯK>9\Z@|[+a<{x1 k#J \G᏶:qQBphsKTItp0 &<4{6p91#w 9aNM!KYρfoA%A_sQKxuƭ (d7D_4(J% _ )-A:i1ϩ X0#q?,-|ODc@yfaOr0A/0B FDS$0[PV>;x:ʛI @sAU*kC~!1+`>Dp< V>d.w9퇰A/nXAya܇N~S6̦Ʈpj"!O) oB2   İ3p|1rZ(z*xx k @P: fF9k#czd-52SeEXl'L4 uhzsT#kD/2iX'@ ;ə n P3#w!Biܲy[8OqvO*$3EHgڢCB0")99v=^ɬi-ߵm=Ҁ~|yNnp+2`޷o5y|$hhqC8xVƳ|+fS$aK4k̸g/9bdئhYrq\nȑұ#(xڞHxҙ AEo^ gK]~z"}bI5#>_7tk:鞁io A5? Pn?WD2O"q:ӚnU}K#\.Oxf)oO!~b aw˅CĢ^ԁO@Zm_4ξa?l/ u);h20# ""=g AGT&vaUʙRyo`-ƒҚ &umLIZ9|<(_ Ѐ:X|UTzX2IޓB 0 [vLQu%K[%ZED`~nC`Sk1|Fȿ$\wX/@'"·@Da%o /뀔eہѼ?p {0< ,!3!Ơ6Yq;CyU|ڃ<)lo B\%Oc>Lc@3GNի-r?v_tBxRlm3ђ#eGdWnxUnto\Sǂn^)xQX^W@>B"!a$"shS@>ƭiCP#hJG*yc (XA5i2e\T}^2p*3]E{ *?N PvSD|3iZ^9)pd_. N),)j<_{> ⳗ$}l d #3`G@YOO_ZHƺ8< G0SW$XԼC()f;PaqqSK5։^ǚ⏱k-_-ү=d&z/pMc={{gr+a;V@boرI )Iy63I{}aݧL.L<2dkթ4}r-i?eKf^7TNذD6x3mάDgfQ0%R3 =SvJ;,w҂ATeU>b/0 pZ?/髆Xee΅s+e Qi٠w8_PStA]^|=u+t~Ĥ)E!Cy'mmϓ!)Xfĩ'R1ř%g'' E')Cf8GX>'䰰>*W`̴ɇqvPrb-E%L&t"%xHC #Rc1o 13+h/-#Q(}eO.\S5Xq~R;m]"C@5Uk-򂠶;uVAYd2R'tu}ƈ'|,04u _s:{@G,L!.KC0H)EHy\ AkЗ:B)[mA{̪%?_ݨ+^Էpk47VGy pJiH]qr# ߧhuK0Ŝ6{ " 2 ,a2![v z)0rZfZ5|!QIbM C ujJ*Ea4 Nf_\$4Ed[^BKraV$_x= vO[-=83/K q¯:UVtWXe;4͸&O^-t/ O{6m4KςnG[!amfCHń=L&7R1lLC&F2S_汗"@j?$Ь%`0HB\p!$䟵C+:wS6eoZ8 ΋ֽhV6*sbD\W|mvz`ԽudOp. > † xR㊆51 8{@"2QA7$o>QKK]Pgw!nc o ?/jwk _g_>k7UḑW y1= 䁞y(+ ҚQ$E1)ESikbn*y`FY>'!LEAy 07G*yRi {ƻaq%&Õt(v^ĶrnVt+&$dU֗^c0Sza.S2u#A3!5[VA\X\+܅]r󥭦0:h:l$PNr CwDJ _e¾K!ӏxbw㊜#AC\g 4h!iF{ԅ=9i?YYߦ^ U? +}J]c'N;3+M}.\1+NVy] eFx2d^ "hbxˌNruK 6Q7e{oeHV|bO]pS \b3A5&0vȧxM{a,:!nEvl9GOUj[8$vt˞ 7$}|H8}[{鸍 'Mς(bOlҮdu7)ű55B c:*bslk>S @_do)-|$|Jc/8{@T%xZ3L^DB%!)B[pU5a|[pWHu6p2I&L* q+K1bzrN|sDi|HD^&tH:kDCt+ E3j>[>#YHfJ373MOsHcg5Md{>éHi^O*7 Tc'υ D0w4q_9>u2=GwPu6P];ؗƂ\Bin&tgJoqI? Pl?2g+wwOHoSf7b۳ "5s+Q~qu:=Zִ?Ys$uOϕ=\"k8芌:D;>`Rm4ձdH0n,Xo͇(&M4 'nF)%&"?/w3^;{1w+t奱=jՃ耳2-;3宍o }zGIEg,凗jnMt/_u7z̵A^wa3 `)7ڴg~]j{PSQsH/|q8eH B-|`ə&pͅ2b /ea}Q琠[Z }fh 5uYFٴkJ"h+E/tzP?S槼%HTE;T*Amϓac={7|jң$8CdFSm8],1;Lc ,#*3!gdP2nc[c;M /  1._K\/m!DYtҤzĒAKޕW:" yӌ/io3'eӾ WC!l߈Au^KKmpT#C|uoNg~?&i2Nk6߫CJ<]u|AJwe`&xg /s= B,k%~|yŌmF:и<̺!232O~!vrp(L|js>X-MƪMbU ~ښۿL4˅b^DˠyA5OA9=C.XYRW3: Y,׀߮[ovA_p I;qDiTEn&VwƯӚ?fv]^!ya]4]VA?}5SA#9~x/ۥg}fR4&[U{A=W庠 ޹% x_4=X?vG hh_ n [g9:B__^shDIF>E ȧ*µׁ_80KXH(!<I8OJ Г>UtL*Q@7g6ӳ`4G`40|x; J%4 9=扈 Q̈X<,`Mz~VH:qE@-1\O çP؝ VrFO-UP1,0IGܗ~'Y_{ i;=aȔFuD" %4}Ej{@ [CtT_~zo9hX]'|Yex{ʆ#= fѼHI3}@ԌjR;hPtWW|q圦[BS5%bpe2)ZԪ1P>Q~:>EA",=| RҤ_iPU / Af]9CacL\Z5T[UƟ'od8Mji=` ˻ֹBLr^38 ,v~}oriZҸ40AS5/KF +KyixD+j`q{6Zh1$U ~&G>G(d|)R$hХ<<Эgztߢf۷fq| !U)A+ǧÉoD%@Q7bkfq2~a 37̰|ƪW 33TaI@:qfgP:b8gZ>#h@LɌ#:m&4!dūH qZ3T%|\JI<)3DUNųŠԽr"⢢z;%-{ E[ppuA)z3elL:cCԚ(H+Fʯߊ?7|mY<֝K%vWBcY2,+;;B`AC҂Qt#NiK_QꂅCJ-wr(d EƦ[>#H|Cv2STJ6!@xP:TCdCc'Ê `a8Zbi~\E͖ vw^kꎾ+|ډ%4vK5/~^#ߨ$C4_43P+<@ ˙7φ [~ )w@'=%dJou>TsBo5 M5\-j8GJ8+Ӓ:z:q? I;qDg EX`|U:w~?& Alg*) qxXԾm5H{fÀ@{'YwA+L]H/n{B@hÉgcdJŬ|x7(\/jDn6L]*vCJՖ\ff̲5L@1Y1͈$x?Lk|a-bYURBy[К_SfSUoW<2T7^Fwe}uځVԠ+EL}BTQZ 6 Nf8SvPc 쾨P{E$;ɩHZ 389X;ÂZ* -qW;$) R֜{K&_/ê- @ۮOк?W0 z}VP4?h<Q1ZyR JԜRXҴ|D).Bh7[;1Gm s ap~xŞD׻ƁAwqc MA5+@yMήU*Bk+ةLf9|z]Z=ojWc} OB@U=4֠p8 *nx >>)zh(h&{ ./p|vS~e %GW{ ]X۟WF-%śU= ZR Կ֧h|e`/3D͇,{[CjZ b>R^e^3p><>9Y|uPb?r, ^ǯ `!^|(>WcsBab)GzHcB{Mqx{#ZowiM@GݡA1z]C̾2ߣ3KJ 9  qwwC<$G=BwȟHƽ!ɸ𞱱x|)"/ ϹwKdCs&c7{Bɻ;t. ,_t5{גzdCд$RqqyL|RZS^@lKd.-GE[>+9Lب[ d_c"9CR>$t&%ջmrTiS4)7i%"Y LBIDW MIߦ̖MUh5෋?u-%<&25?`Tw|&<&qBM!o7#O ITu]]NM݈9C^n#KCDM%G>2nFJeMOԤy7'"L"r#-n*@'2fe>Y+[-0Ӕq\M|H֎:+Q9wI!!Fu_wo.պ"o3մJ2%RKB 3j4p]F{]<¦¥ZHᲞXGd,Q; ~$.°q?XX$uUTZ5A lv=O|N-'NOLTRT{QtTC)esIЅʝ yέ2Pdb2)X\f5;mg=Y`H =.K !A2wgOSUV40@یft۳ٞ/q@MPWmWݦ6AY ".qv1ʹ\jjy.E@ 6\ K#-pm8tm#oMt5@"F>_v674uxjLn'զܾMs}Hjρ=dvfBF9&? /+}UнSaW@'s]r: % y uXD튴qNsiT3eh<]hFNXgyy%xPxM-QH4KvpCAu JPe>B/f[,ET@G;#4/piF?Q.ZݑߏF1PdP͟ _1\HrXbz`:OßY@;HPD@G|MDFHtq^QT7HnQJ@Urg$f3hsh:N|FОXkph)"3 R1odJƎN!~k_}}X(slY`;1o-"T,]:P\XfPx<(?_wqP4sU%SuUS{rp(C! |>qn@$ hWծر%~Ƽ1c;M0A,vE~'V3yH^U݈dHٳ1E )Kӏfz ڪ]-= ﲓ4>y,p 7#APTBݸS'_ v2Q+F$͇閬^3ᤢ֚KLm .4/jSqH i 0Ov̚We*)iӺvA&lئp?-4r@H9ds|GE͂8>x`z4q\ A&5L$=)lTa슔3ď5K^:D dW=g4& YQGz"aLPgڷ<״ 2dsqzfn vGp0x+d` 8zcǽ3Cp=e [Ej䗝%q|@~66Ar.fc>ݓ9 }Wz7{}1zY $NigWS(};ê/ nЄ6 >JNiĩ4u&<ƴJ5I!s9_ބDXOQPma| (S1DUm+4aJb?J.u2\vL[aDFͷ=~/ Ru :Ƞ;AgAָ t'@2Qk[ ^=aUbCEWLuG;c$-PfD38)Fdb%27kBPO2 j~9KCHb3&)dz&@!P^mP>{wgQ b {kt|E{i[Pu{(~wv5DZ}>3yE`S^ţNp,xWq-?rdؤ'yv9 2|E` ?qaܭ4Xvd|>zD ɘIIdv)GmAsq}Rڙ}||%O<%lJڋi~)?-S'O bA%Yȱ$L˾J4SԔ6w.RUyDJ"]>wU6Қ޿ ˴R˄{ր2hnu[@Eʎ4Jl|\N3< yG\wUy<:g6½UwLr !8#­YIFpJx|&vX#}Blhc۽^N tXγ-/ ( О<``@7uk3Aul^ҳѮnEҤ#H/)e;IQ_#Fc\1Sİv~r|FBdLp;IQ}D8~pЈ %pY 0'DP`KGA53n^ϗ̫ )Y/_Jи#Kxyx^Wߥs\ܛkť׏|!KLw$`Xv͜z>4EqL4~bvHSn6O_UxMW>j;ll^my@XY|ߚ{#@N^h>.t&͇JQ,Lm!퇜єHZվRTUkxcb FKAf[L{;ڷ~}I˹!~bTVm]tv( x-^ i>/PP>n%RkGo(5l*MߨXEKFA 9)m/|=qtN3 tUV>(' @4ȉ|)<((B%љyrԮiE,Y F3@-aHElo!K8HAI@)$@] }4p4TC,ld (X:frq?R8PD#^byy9!LY] ,E9=!Sz?ڿ qfp}W[!'ڑߎAz〯EZxEw@J|}k] z5i赛O4ߙ",O֠ivM3l`3" ;&'I$L8W8DJtW'#87xS:`[Mtw!WDŽQjPؕih݋fAy`2'U?Xn{[1峆7à;v.ox?^vPPx=X{J8 pa5Վ_8~,=Vvefo vE {G iRz;HH سs>7Oӳ`wLljxL&CDD 㧽) H!dCJg2?Ka5^P{&b'KsT{(`Mm(޿QA؁Wm7Eo4c+ hCB[&/pO+Xφ]e^}z5?UtmMcT@9&i ⓪̾ ߑt"C>kUyr|cC\{}ٳ:N\ ח4TWs^)]& "߂(wc\-7.z}bU ~D3jlI}Af@7A۫O_}9|2iPG$HiQҠ҈%.ui3Լ?zoφńg1ɹm^*-|-|>H |HbΣ& q)k2'#(JwX 5}GGD3f1Pnia2ȗF>&u!sDX.bq8/O<BE }E qm[w/5 2>zNִ¥E>%ҜȴCsX5\̈vi8і `3%ψuhacyGؕBۀ[jюr5i>?Uwxߙ+lQ FdA36me+vЃ*j>}@Uuվ oڝke\S[-,sNΖW8o:t=7;B   9֜]hOj_~&~s6ZbZb{]z@ʚ,!qrݱ@@_^u=K=Y|q`rjӸPt9G[),M M ӆͯ[pqM& jVz2^St#(5r m"SkY)kEϧ1A3K_5u` p.1Kn;\8G>ROwʔ&CҢ ԲI)iڟ Fj$̺ˉc1DgDsb aMT2k`2>vc $igN,Z +, \ ڨ)e'X`XFŶo& iFqTzʍT̈!I,;2Sj,0iq L![v@/ÆG \my FkXS<9fՠ'CTR1A,>e0\P"n\{xru[s |?|ƂuFx$B Vj/k1XlQwPVw} Wˍ!yˎB{C~=trf='?‚EP}q,F,f]d!MJ.jz|I!=eq`$Xdrx2[2c\fEK $C<>0(3Dzu_bFIr[v<;O)Dy|0L!lȯgh8lt}u{ӿ@J.7> zys'];[Ыy]]|`kO݌TIe)J$Faq* xm"ef7j3.ksBJ]YKlCAx̓DjO R *Tc?(S^AΩ}OtM9CW*Lf9>]V?Pض 3hN"X=},3!ai R|u)A"4-)UeޤruCo!^IŮN)eTxc#} aGYwUe8TE&C2RzG7#%ܞ~ )jVatIѥs3bȚgȌȆIuYM}9b6kJA?4])ldB_.5D'5!f,KOPM`7 Jw)f,=X̮5h>B s[|$f6`Ӽp%ʫn!R-*E|4|zJv5}2u" TA^'<ڧ}^"W8? /CjRJdz؀_epfJߗsMcl-&n .!BFcr= =gU X6|Dq4h'Iϭ5a̠80voH .%? o,"v-Mj(g:A$p笠OE8 ;z4q\JcP2c9!nk2,3}M]'o0KЍbX葉,+-(NlPsiTge^_@6AF\Q6wêz֮@4Ot^vV+ChR?C;BS.e[}Qfo"TpSAy!aK! Oa{|M:ςXA戀t u,|tQ:Vl̚!h麸ϑ2%BŖŢ`AM_%"jBr#{+=J%;6Pfl]adbpa*EeYl,x!`\q:7"$VW|4J3r OceHy^e(P9\ȁBR}aHE4]b~c{9o(h2h 6D{uټ,Ȁo%S(kߴ^G #n܁# EoA?"YWR ;'Y Vl[wu vjB]"n+-N"}\S冦P0 /C ]cp63gMMiBE(%"mf!PɑCwtSߋ`m[n.Jؿf>0:Ox/Y+e.zbԏ.XOjxSyR;0)XnF:OCR;&p0=9rndF3j2ʤvO)p1!=pN!S1;YZ#q=E*nK"-EcN8w>DϸI$Ng0CS?Qw23c`g=8:﫻FMpywW=]et"cUuPgsD]MC~Ez̒~LagU8 at2[!yʍ?CJ'gW9t _2h8>]W2nˏU@S !JarJ;RR2(Ϧq`^3^[XYMĚ +#Zl}$lX؜qq /~nޠ϶X]G\H "sD|pBGl*ߟJ+7יZ".=ycJurq?R0Dݱj߂wpb( |[ )X~ګ($oȷ-|Kr$_F= - )Zҿ6srRu,#C0V;T[nhtBzP%D:) &P4i\{Ov3n4$ d<8t6z,VqDf]8J, 8-F^`p9^Q ohƒ6|C5Eʓ@uN3w ܤws!Jn /D"3YϚ.K28нuCG  /n|r~ȗ(ƎOrb^%;Q~?&!cQC{ܹu!~~$ -jTz\;O^jt~~t4(Q@/>NGt) *C!﨧Hmvşf0 O|΢R̘LIe˖D+jNsҘ$sXL QϝbzU bzjzǷWJyw5/W; |{/.b{P2 ^OC$4BAg95G$].7=p-.hOeg;Wk4Rp\˖AQנ{ryGP~BTOiPN]%F5)R?Nh(R%(Ԉ&{ͪx3~J U!> a,Ǣ2w3ltO: e#A+7Mς&4~U|6R~|:`:h| &!8i(rGIٯeFxh 2mk3b5e^3?=$[4%AH`|2QmGߨitsBY@RBV̀{ z.u:m#W9? K0EF`|#?!q8?NRE| ZNN4;cz`8oȌ3-3v7D tGH $P9+b0Vc'V\U3V?T\.FR tJt^anpNp6apyAS;CNU0>? ^?3/|Ʀsښ? C:ѓ }3}ssZtf`1Rߪ~$8V"/a Iph>`4.V4)d^Ų_b? ż 3/B ƛ@o|Yx!h==Q95=A~uۉPkd`13\~_~|jx^ _{P0Ge>3enu=o]TgB<SJ~h^3S5bS/ l:pA3_a[SzZy⻩NZk=ڷT>Hv 2Ѕtt_~Z}oRp mZy^ d7/q imh=K(E%z~(=J+w&9,,BaN`chn7P2KC,ҋ|J/ FjƒOBCK: ( Dxnji36`;.{pUx i}A/* jQ~&~\8#A跍{lJoO3*ؤ틚s@WD?|<1%"N8*FZ\³NR##V#tc{es6;yy>e2Iωә9`LP/}.g@Bc?k\+YSD A*Y J/H;y>Snj E. ㆂ n!8i|'E'_}5eF́ߏoh:2K{ak7C!KI$/4v䝐٫}V;Vs$>N)5)'0.lR;ut8i> 6Nff1{籗dlh)~婷+wEi$ҿ&5]g Zh73 Xbq}ϤYݰ[f:U͘Nn0 6\*ѹrTjΆK|Cٸi,xIHS\/ z'ֿf-==S$? o9k1o9|=DYmztYԳb|084" s$|@/xCzc[kޭի_UmþD(!f_D~O -fQr8;8L++:vrO͹V9oH'0lN>#~VasRih[?QY|GY; \_?t? {)o~9fml4nY}onlHģ(hu3Rig%hA1}Si^' oLfn &3d&AFfVm\ػ@橇:)80(@5!%ƚ5'}S/uAԽd·E"%ZDЂ.y |SLqW;ܵ&ΔzDy+txBF> y477npaC\mA|wq' IENܿ(ϕ[@yе̼ѱ}K2ýAWB#*}u&&S褉9u3HzR`Y n5/Oi$()l{ b|\Wwh% "ϔf«B_MD&v`DK.ShJ?L^:5|:EY4~AP@0Rfma+2|Ut=/JZJ5@}?n=seLi?Q:@ GZBߋ?? Ax?jX -/ŵP>꼙y]ЁW~]'3qWeʬ>SNv[MլɸPHRTr9Sj5kxEg# MX̺ib2P99Ap2&8@ $̬EQ,\{F7(Elj!8UXZsyWe/'[ ˴`:2B 1end B9kl閚+Iэl>r?ȃ[vdm# _ r?J]D #vxobTٌnNJoz>b =w( tXa nIJϧw^SR짴U?5 WP ~ Mr}V |AJzǗ:u: %_Aѣl̝xՠ=g ohgOaE"PFBBH(sHcɧԝ1sW<]ՉK\Avb9>1cq f,9=&MuC֬3./5~I B6~khA " tfŠ8nb,s+]2[{&;.Z G&9: t%2|t咯wwd8|+?Oj8?{aEˍt3=JO3̴ٖ  5Ƣ|Q>i{;LΫKٱT&DpĤ)Hј9Q+ϯuiթ_|nLw@QNQvY^BsKV7Zo\pu T4/_|"b v~LA~<ϦU+ ߣf}j{Yt'r~<+7{1ac'Эz3V3ҳϷJq9 % L1L8wT} Wd¸vGIIBQ9'FzCU R5!R[K>.pN~(9fV>#gPgٰk[q+8"|(ͿRc3MY&yo/epao?K2̭4dNx0>CcX~ID|4!oDÄMZZg5? t[g^_)n_'!f;Pz,7x>"gQ7#KDR)bOܤN8.aY!K8J1͆!X1Mi&\s(>"V5B>JHLUIR$fj4-T,mCOPbe!dY$yM% ϻ7|pY22v`!db\$EbxC P ?ok|H;3ofŭzM~t/dRof|Dʼnc{>~^p?)դ,;<7fķ bh!2#>9[>+6J,3ٷL0JEY̶/4:A/ӔJL`C8| ,PUAqlzkZV.̵xPרm_P~{ 祠H'4yR|kbWt}禺pm0 ( .R@ r,s?>fojH |_ | ᾁ`=''{F _;zYWDs6L,~zaߐw/DPm]<1G:yECീX,s Dţ ?w""!,&b d\s@:vw⵸'okz7 8*v3RK.]BxEix-M\f\8&?1!,|N4(qi_dQo½E=j~Nƒi7 Y!yA,fԽHi0hIT[!NK?αn0(d rۂvWz?d!xS-CDPD 0PάIcDKr]=~-)ZF{ _3%on ZÍUU~t4)AEpZHSvJ:p">R( M>(ҬT`c5^'eDkWd Aa_4,&QzẌ́uMքLiK~`4-/CBEu_{nTgZ:p(_z1fPԆW);2mAru첧.:šP {fK%yFQc ߋ?k L> o5l jRP}B"1 L!R¾ݷAA'ơyRo:QS+6y:B)Spgi ,t dvddJJ('nKd"&%m6gKAiI`!Vl}P5yf_mA7MH)J&&L0;A?-CpWC]4 2O$;lj:ojmjt ?KM?V7)c>OG2q jlV$ vhɠgb<>(Ǐ.%tUwҠ~nh"R KIEt2Yɤ살?R0\f,fNp,):8KyQv2"}ЁH "D^^DԈCqjğL; є+Eꊭ@5}AANZb>lğ;Cz`0[=+\-K(!u:=@"%"ZЯ@܂#޽Oݺtan xщ[zC!e<)/HhZR_0G,Xkg;/C4JW39M'C8dzbt=J,3:ܙ70G9Oe4۶KK'XbnSK-" hb)j, p,AI0=#PjP@͢ _7nN_^8p|ATt}٠2 *$G^&N-¹ҔBIxpTsZ|[{9Q~?&|g#K)Ga_@Еw?^{[Щfl9 oNgmyH0@J;M&yp<|qnwNΡF:/$E@s3#LSӓKA`cvll%Wžs3j_Ez S&lw 0 qg9>lY% |G5E!z.] AgQ *y5Ad|@DE&60w:tju3|@WӧI@%RݚS+r|pxt{yh^3g;%zG Tތ1sE~nxK0^w"7|N0uA vÜ_C} MY;m{m}&um=K- T N? *u@O (DOlxS͉IB$Mn=8|;z(љzM|΢Y$ӤHb&9 m@]M5S+OLaPxQȒA}UFp|m "ӎodGRfJ'"6 ]0^?>5HG8EYdI)6A4å+څLY TWfI:~φ\{ #pW}zE˳ ^cHx7"Cmڞ ޓ'w&ܟQ[@3sx?9:KyʨCf uw%ľ]-hҾ,lϺ'3vja,7Dc8g+a9YkDMa%}X)|B_!_ƒ]2W>4S@|@=1Bt?aDBp9u0J$LEYt5tp}WlW BVU_) q;6:Z WX#CEH&?|`@?8oY@ۦk.#@Sij֎~ys,k_d)gsof{:(fT+^;{4܊y3xtL#pωvv۽2Vh.GLr&h,gC@1֔VtY~w_(eD,ٙi!]oIz^ǚvWԸ\-c\SNv# Qno<؛OԨ~ߏoQO~WJh/ߙsC/^[z|04nF.lߦa;H/;`rt (d&dd"]͂H'KDRTw" < IPO3:eVz391WFvϜTvã&xJ"=4(uó9+ߌ~U qMSx_LU!P1{uZݚ͝n,DVNPRgAP9.g+ "t/sXj?⾜W;;u5]y<`i9S>:[tds%6d>]¹—޽z /cV? }8<`#CCR@yXTi7|^KkP 1(ȌXQěaK&ӠMӨ1РHc)iKP']UkM44EǙ_Ar{Hr5&3xyAcRʞ3ȅ33!m!Q):#"c)Z,?⊤Po9[䕼xလs}!9 bNh`(nS'Hyqk;E]@}V4%8O݌{w|Q4%ju2-!,ZKIjD}sh>tX*7!6R)),DDQOҍ;Mu&j;Zz8V&_\Tk= w=u!+ 9yL?\i 19_ c~[)݀0oDi_~&\`[eӍk@~aȉ] io\b@[#ǥvK~r@_zGE/f+Aw:%aɳYR2y7:ٜ/8(㉂W4ϋ(_B'sz(fY>+dS12J9Ȍx<<)_3'3BבKw<7\nI!4)-(\;=we:CL]Jl~' Jžy?v*9i7#..0!\u#(uMzm b{K4Fs vX]8zM`k>03~aÇބXIM5A݁ fRr6IigZqh[7. |q#{$9= &EH+94h5,%(&Oo8uܙ$3x>}.|NZ MPQ'i!!M:.G4%,a>#:?NIʼ/zizjYUlNJ|D0;lHOP͈}㏒4Ɍ8Pm$GJ2<~d,MWf e5xz]]frof}V>?,$'Lv&ӎ-ߠF-}ލ(_S&1F}5vxN\?K>A{1(h#\;|iXuAw0q!cҳ1L< ŗNrPb|I_Oy8y>_L<Ι߱wǴ?cC1!Ģt7n}50jF޿DuztMwO_?UZ"g<(֑|E}Xs%[GGl 72!|pEhKyU=Y`VX;sHr#%:8o:k^b!M:WaL'/6 :'ӳ`!L<4H&ju 7Ik4"Dv喈ʱ3a >hh9iNu{!fNG.q9cTiuPgs(E(JG).Z'2$tDwM *ڬܓ:JF0b}eGh3qVO57!b3Plp0%GT,y/ct Q@1zG1EO2z{fEIZ1zbT?Hԩ!Ine| @6y"Te93oPR^;= F3M;I[!z?UE(qt`InY<\'r8K% _7L` IN5{!XGYԮ.|4 B _cZ=s r͵;;,菋GGm jt^ASY_~R9 Jp[ Zt;x҇ Iv8/VAPY/x"g3o3<"]g͟AWG]@;=驂fT NPb@J /(V y@.>r̼,Xk Jԅy-4.#kPhf ܩARI.;tGi+ ~Y8YjP|fM Gv@LD- P!kVJӓzzΔ1޽ً |@5OA9=C.64(!>M.febikon~µ'ZgqqB >Q=5f_74+uqVϨ-5jR-ob^ agc N'/˟IKJW@?-]pztWk؛wY"鋢9NU=-)l 47_^7'#,7Ҵ0_fY>'$ИÜv2c&9; j_"l /Ш$% d~Dy%R[=;^T 8.&ʠ(wod+?Rc ^t̅f{|G 0{s@J .* *R| Ò ]3sTfCorSuN^Ϳ^fFVf_zPߕ&2(@"cKGH{w׬2 1w@fP)YNfҢ jVi0+1 ՔN Ո,m"4fLJ=>M'$j!)`!NV3{YoTm3Ltrf/1} pa}lt Ar|@v+7cF2Q~&~piq=$q6H:2` 5F%pymor'g9 JTQ8I|m;Xtza<$?'cD~(jeN !mv;lpSO7wl՝ vF:.ڣeM[9A[g7}zm)iN]= NdR;nv+w┳ Y}>Z<>aQTQ7kFR1ꇴOyS$tZd1,3s;tf7_`>+&=̄+esHdBǔxR$=%Pd:jp\|iUt!àcہ!1A k:A:@kѰMkK/cFދeFw4aMeKfe6\+M<2CR4/J ԭN>ahD(~6LL@R A<[Ͱw/+A^\ LY ,m. KT+T%+%x"6f,N/`Xvok.ps';5o~BQq6xѬ~~a >U',C5}F>Yѽ6MEx,NNbkc I/F/2v}<ިk#е~o9"^h1GIHɮ.4 N]vTy&y,jD2# Y|B0sg|l, ?~`D釧I e;z4oF?y7X/DʐAZ?@dn@&_\?7t/efWDŽnpôknvYwn'>*xk ?ث:|*өM%|v3Ie )7q1?ežoon*|lQ95=T%ܞO쇦YF<ȹBϫzҡYn :vUu+NAǭhz`߷=B79sj}dܽ|g tF~P߷vp0@>,՘-?bBv6aHrT\t$=q/讴umqi>w9ԤtG_/˷5=H5w@X)*2(|DROy'sDAGzK ӃE#ϰ|FsLsf~Gl4S*x~8eP6puz7Wn"5|J&.,<1FdAZ}U6bV;9俹ў뻔Q{E>3cq˘;geq'8W~JzCgnn5Gt~iv=mHl5_ǟ9|}^z۶8`[];;jASQ#!зzlЭo֧Bʔ]CEODanMB6B@4rb}6BwX>+h8"BL@`Yk<O1v庎P A4>YFX ߼[bAt[w5M.vQxW\5iWE\n"n1tBD١psBu~9_Q>aEJ]G"F6|*ǃߟ_89k8|?iW>R+0b]{[ 􈗤^oM ɪ kӳQVGq[FC|.dQ0GŪ 6aYetEP~1/`Ʉ<̇ONYa*p 9cdi{iA4:E+Pʳ\+Bχ% 0B'셸OOu\|!Q@ח\/EJ t L{m*[X<ѪzH9a&S[-2`SA?f Ax?kt&N|5V~4R$+ѤrRNrҒχ4x=i&3ocs.|F4Nf7wZC4N!}LQ5VS\ *(%Gc9~+̨H͎DPݩ̵GP~e^^+x5%DjR3Un]0Bp |] [s\ܭRNcIfvh&!R!VpDmgciM*M00ć? y ~) )Wep]fܱ|j_kZv@?3XTgcT_N381?flqnx-hh2bp }<0o9[>+Q2Svyj!j4)uG-b-P؁Ubb;?k[P1Өʜݥ&{HuAf_wݵv jܤWtR.޾4by7;3Y?&\l }A M*HKyi$6$; w5|/ Rc'>ic{pĝ__ݽ!qo)H6 n=?苔QxtnS o.cdR9 /TtU9kJ\?uIWk2ңdRE, ZxpYf ay49CX&Լݫ=t\0\Rc@p7?h 'xJÝ-Mn< >qLU GԪ}~Gf?SLSfqCҚykն ~!1N>SL |7Sͼ% 9wI! |4Dh39Įs U6H[v4^t_%ΗO^wmRYnh\L2H3a+A+U\2C(K>$1C) Ar#m;(X|/'qW孰% ay9 ,]_` `~m!,s\Wb)rT?b0O@" z^|:'5C"nj798k`.WfT܋Tmj$ ҄~hI=z cIнZ~e-*˫<藕f\t/qXztwA`iQ~|:4($0"M.1sؙҠV>6K Hb&P>J x 91AQT)R55+LKڍ7(Tqx4(nRS]IPĀנ(G9AKU#[ǝ5@r#ZAVv#[rᝃlr'5.= v~`q@TXUw#%M%̴^2h$a ^s!I(02#\f:l8Y>#c4!Yω'ӄl|hinkv+.X/Rl/C4 ^2SoW e\[ &s=cyiǕs#@ȧGkr|qη&v{iM{f&\b+.w}z,piӌj5eG!F^u0O4H`@Q/NH3 ;(ą:}H޺H Y eZ Mղf e$~4zܮsoH)|Ik,H>+7C>T44Hy@>_LeQDz\ [Za< L9H~^Ц{i,dCcysi5D~STmAoV%{X/%4r֕i:`71wǛpєLJA{a,ʚQZphԿ+ o~ǾC>^[-'$Vd xF򪠫..&0k\_t6>)% $/7Ri9%tBϳ|CY,θT.ɤ |&2pHpI$(fG#?L&C(#Џ@Uv۰/JP9S{!= gzx7|1'ExClj(rߟχ1N+L7 B";vXW쑠iO}2@74yiӳ1aм|1v‰KaUsFtTEAGebntFc6g}d}{R~ȹMڗ>F6LtdЭiuVneϦ=}ߦs\7Ov>8J 4?>N<@w Tv=qxQ`k?y3b5 -b(]Q/|'(RR S]-~DkLpYThܴ k75A>MEWub] ك 8<#]hH"QK7 cZ vNYJN0G 1,XkSҠkQKBИ^ٜO7>aWT|%UCC'_Lm-R|AfJLbK`kۦ"uBX# m}wԑ38G kJ޸mGy=$m+=Tе=rISoW}Wl z,kSQ2yI"cUFH۞/Z]Qtq󡘃չ2-3nUn[lZN"[vKpPvj4pM/>dk1_1 TQ.o-Xo-\%B>u*hgjè_b`qߟ{@=ʻ"gvpuju5˨g>1?# 9c@1C8 ;k_pD4{qgXqʎ Hiݤ ym\g}їN~ zj ߍ*]I;ݤ-tAJS< 2$>dav|'l\90bP G-3L_g !5j`ar%K5x*ODu-B*/ 1ÖL8B~fN8}>aOִ^W=>A5ەH3$YŲۋ7n=DUgA`Ǘّ@۩CQA"/0J[H1Y3IPHj:nFD>%k"MgRYGV,%M@3Z>'p̯OHak6&Hh6xO /,|a킱VET$#|<#&U$wQ &[UGjKC@2]}f_I8 8}NϵK*:\cB؝\cxűe_ג|1,+; CwXP0s#Ci3 ,_= .+SG~})R$hбOHvPgL1i8z#Rj~O_CGJ rQrn9`1ù3ؚ{*i5,'4ħ5(ҳX\({K|?;s|@kEȮ/@ޘ jv;U6Ocf-s{GN,zOAPD><$4DD䯷$p0܌i}׫C9Ru&55h8Y?9-(G_*ܮ /qR&lN٧!xtVw 쑟vM4KClcj)VVĜ*W@ۦb堭2vǣr_@EۤJ@Krҳ`w,ۙ|~ 2yk6DN)XDF&ղHS,Q&3P f> wlI(@ PkX[f[~BLmj^{G\ e2  tjͺI_gA`֬Z;Ϩ;Lyhς<Ռ (xOdrdkJ\XO4 lK?x|: /qWlGɑ\:?/=~ Z$Dz k |sDJD~ $V(8ȷ"֔ MBه?ۙV2~Ax0n1´WjЬ&Yx@H`0) Mֈ[cDEq>{IP;|~]f,g ;dudLb5GO.^4HPA(X4Vr\02?$$={ڳju~uR 2rޤixdzFD S2|U=yXfX[R=+K<,3sEF5U3`2[>gق0 , {KeRq1#3YX(eN[Uc eCF:􁈎"y*ߓ1WSŮV|~r#'GI@gXʢI^2K8W>SjSl ޖc6>Uio(l!v|BA-՚eB[FvX tg3=^_^byya>\pͷwEmu?뮴Fl_͛ lj@,8-|.WgUЅjq('o[dн8tG˗?mzd8%"M^ Ҩh:p6>/&vC:@nt V Df?) ,ȋ륐6HhT2w)7)e8+RFdA}5B"of1WA6ia*(#ƭji(>:7_QLf9, 2ؾsN2$Yµ |iu3e6S10e~S&8AH}f;9&uyQhYՌڙU~t2a%mCЎCY| _77$ !Mot y$ߴliR4Ia}@璙i69bW1Q>d֡K /D݆̈E&(HY$ASP ҚBL"_&Mwxm^3di8PE7~>ɽiw.; nBBropw~?U)4vJ b˲⯇U)Iz~=$T=au]?S ?lwz0h1i-7/ufЅWI/Eo(k'WeQ쾞u#탢RpbEYEhx}+* _$~TOxC3"֌pd~Ln姏aqC yGmBΈ [RD@zwݠ_{!ת_=]Y2,̕Կ}x!ā}ɸtԡhy|!Bvkť4 + B/+Ѱ&t!EO#è) e;o Vh*o|U밈{6HPkq!xmά|^]#8!ෛ5 .#~ڟcߧ+ ωfq4A3W,N2$ s!U|UrXOW t]~tUŝJz,"],A.M#@\88.Q<$-xUĊs5F˂a?k,s nZXeNYmtֈGSV !eo?yn+Xb*=Tͣ^Ur"NO ;Sj}:]W;;u 6 Eͯ/.zY![}FF ,>&*7M \Qy/+ -e6 t ;sB|1bHa?_2CNW~0:E xFϓ!K| | }KKf CA' BP{kX>'nRfϥjL#Xc<R`恿'^׽vfbd P7,@MXMlmz6Oj9,WДI,\RVL=[^18;FqKڄ} =#|`e9!E/Lqlʋ!G!eߪ iA)YA_ɳ.z~?O@}[nc%h\lvD;a¦Ǘ:UD& U (0IܩHQ0:d;PBY6<0YþC ޞ9Ox4 ߏV"U 5_ucTku8? Pl>*+:形)5 MC]/uja'>09}]sA~I|v}#l,: B1;7MGGm+7q#'IVkz'x|zhϭ6= F3ړ cdoھs8>Rn)gj{(v˷M 9R[2y(wr9i>i .HTZ6;0ce+qωyHL'!Z!T^!I>kd: nKB󉉙ܫy3Atn3WR*Q̣'8i@`Wwۍr ì# 8&h6j>uk>d)`D#ߏiR3+OrBCb*gwvn.ytvoW/ < 5<qٚԿSM3ƋJ(DkQ|̟Ex/7R\3Q$Ⱥ\P+eY2D%sx^32.A"$&AR Qʗ!P'@}Ebo7J "4WJ-?lb9y7 qBͼepQJy2'hRʋ!z*FoMY̏zBɝ&NYY%x]47eݥt{uAM Կ'_/ɉ$KϗCQL%z(%i$NFnLũ|27ت؏ڼ4>a'2Iϋ o@~NarG5x?Gi4\6b:xrPhxP oE ť{76l6LF|Z=&\wIla҉/%s5@01)kjK5&x7?[r9Aqh [m}YzƆlC[EHMC|@Z56=G$bHnYL"Ӑ2{!ck3"*J= RP%TTr`BV#DT9cNn{>kwɠR"ӎ ?^Ux[Ȭ&^6zf ӳ`Xy㈔ ܶjHxnm g w*QG&X>gц4%0,]Jy;o23Iihd"Tjvm| b.jV1h'T: {V ,ZrA8ɻGstކz6vnPjJ_| "XLƚ"3|ck-* wH 爵^U>JeC[Q@i?DY=st9wzox'B`ıY@}BtU*A9Je&7=Oj8? B҄bU|3=J*|RVE,Xf3*/"3Rt$yC^& WM"pb9;V~uBcɿl!VώʁJsvCWp]9"Ajotߒ ;u|f  yoRM$~Î⾣g=E'Z_j1)HÇՖ% jFvL ODI^]W_kaO69@=(㑝)#P?^g#d2y'WnqGg|^G}2cp@z78&7Nr?_F><%coǑpG~pK;ltogƃ)y] v&c&C~.̐ɰɐ< W}@WgR9e֠k@tCwځK[5PX((?IJ#ŏGN|ڻiW=wG)S32So (LX+qPo!8gCa쿵VC:*2;Iܷ3weXzv(- N^{3(S޶Y(dȲ;'PvOɌe3Wfg9sg2;\W c~G1/E. \_4:d( @TL>'wQw3$WyUk1mqFB*SXA~ANs!?=EqxS) >V'FAyHT|v0Ri', 1#V,/V-eA3!L &_C}ޡAeb7Bj_HNPpJب|.duMY.O"!(:f%\| #*^Gd%s2\ֵ݈jؐtթ ۶S#z {\pY,Xm;oLѸTM=9*._Tyx<5U`,,TYFSg5X0 pɎ'_eϣ|(! N SP.XS s3}fXPfBMGXpY[r_֔ڂ"3 x/ӏ?j1M%_{ 79*%9Շ @l q\WX Ti|"_0_qLͣK2>y4 HIP q9OK6 r#׍&|w29k39YMNvjp9B'b<_BZY&6kv}b~ѥb)GzH_|CL_է2: pׄz~@1z]C̖E>du4];[Kw9*y\{{LkR;^w0G꾞g+? _A`Sx'|>{xy}N~rĢUyAE68F󺒱+!ЧOvPp璠9K!h&]j%ᙞwLIB^8)CG|QptDAq"PovFງ!p&X>gCIwOa]BR"(5ODJYyu%0M]?j3Ҡb]3rII2<2"J}@r8Ā*{^2\A-0@?p|{ѻc.E@$# IV )EoY )6@|mρ ? f%z2u@J& FM-Q.hVG7#bTqg\Q*PTj֘(49A0Q؛l [iMTf`1uVZtbL*|/T_fEPa1&Q*!P.Úbj1㬊TUݿ D\trnn֔Vsv *V}܏R- QXK6\s(؝_-+'6?yѣT8 ՎA'Z>+t3?&HwL%햽}.^SGksBHmAz~9a% i1;>i ;*`BPݟ,46?}6Pvx8ȵhئo`zja2U{OJ:jC_΀+&tr?٧}}X'4cla۪7@~}$3 zbqX)'|A$>q ?(O,hz)9 ŋnט4n}h#= oQaDDҸ$-D6L/4`0ݐ`xPlFsaTS42dI萐OTD<ωj,gqH"#%$C!R~?/V{ Q@64x9zͶ9 GStZ1Y 6:i*f(Con!-MG,T.7ҞH /3U,R?b#yCfվD h N[go0QaD oURÖV^ !9(f ի@9ic *&o… Cb#"b?t/77#WluK92vҧzɮ>3LiaS/g#+64/ ljWoF%*5\2 5+H*!h6@Rt )\w*(uάzLPȀ-(MfZ32)J:uj͢0"x Sd]/̼ȕ"#i3SZ_JNOybW\1J;=9wbA=Wb1Ũ-ӠR5}XzN( ҶbSTv \> 욊ybVED՜i‚Za1!P՟f k21OLJvd=AA|;3|WwHFi TF9Q3B ۆTFfYʜdNu}ag8F/AvB"~Q%L? ~Κ~э)՛x4՝xryo!D\e+p D"^]$x@POZ&|H5A-~h79@ǭD[G:'rHp AYDIX}0ђчA_0,{B@ҩQНY|HtS' F&M)A H%`~K=9QiƴFO<@iFG`D9LH5a@L{ yoe36;[G=vFj?⾤fyllC1?6P}9pOhx;sY "5$> $l(HZ I }ObW^ CZ[7 w~Wg&}ݸEk=O_g]i>tdb@jnKV5eVQ94PB1?L ,zo(RP\Jhsʤ4N#.nU&AYK}hP0ť^KZ@ft5_ \:vL=>yHxH04?$`Pʎ H>Π mՑ+=cHJ# ~XUl)7o.zDpz,UiЎHp&;Ҿȩ-v05cr>㵥9H&TZf ˜LdǓw:[BJfrF_;L k:I0փbAeꞷY;.fK3ЉӍKeGW4X ʣsjɹJU0RAjHNer?kTfؼ>BAnןEK.T={Y])K*vϨq498o[.X=lj|#4|q,6h^ c)A8&#eRQ-4Nˬ*YžfV&9eӝ74 ӊ|9ulj_F= - 1bV߱$4&>.pnRgA 83ghRXcMMoZO 7+j;@3Oas*-& d׋rU42o% ngk>_KByp? wAxSoC=t^0 &ػb+z6{ٕww;vTT@=l#`!HIl7C=Oa7 3dp7 Wht7fڡLBTZ<(]-/ksW.(|EORPv%+=0ZທDU%aoub.'Thr湦'JVFkJA,fϯgߟ77PߜLnr8~бpb/M~CM+CB.LJ/Hԉ{&}D>y~~"ɏǠ7>g;օ剿7]2-7+74W =($SYĨ*І.t614gnrkr]'OTvM|.Z5#`"R\']@ӷ)hZLts;"y@9B˸lNOٿ];a|D2 G ׹_R"l`%TVm>K#Uaި%F&v'כ#Ky x?%qbn%>4TdS~1| $=lJe Jԍt<Mj/3D  l+M<jaߧρ3PBU2/3/ ?HɘsWMS~{Q{*fU|sjuAp=JTsJ\i*=Fn_x ^yoq*<_ ۥ=A /c|֏UX|ki } y柿,zbƃO. 7)VV=W~.[0-##׌$CA`ɚhn`D3"暩i5#>hng+2}A٦ zelԀrJPH֤ +IV$Z@Ҭ!V;!ТLbfdG$7 CjDD8\ /r8=PES`AqjsAXbZŒ* .VhUOUs%٨7s&@& . 1/ey}j {JȆ?k&㮣iy _^Zئ'Qڠ$&>=8QE2tkΘ$5q!1͗ٻabmG"g4{~h~p8_ N%T<&6Ci%;6zKZ.?D',dek0PMX<(}z=C ͝5=gi!iA98n75xzrB# f͈S8# j:'F#?3{ԟmԗwyy;5rvHl3>! 9L@3.cMy쾯 NddL03L<$OK3HJPئ'_ar?M说ǖWoo:gViJf13%YJ FVU8/$qM̐ ao69mV)U&3Gڞ4;J2g,Ew[C !#QV%2sA7ͧV8C8![i6fH8ߑ׿oN̻ Rb~(28=n=he6x*dk µ^n= * 5=('c@IG8?!(<R#cbng+pT6%IJTŦݘdk$'<̈,T~/Y邴e!:bӴk@gjҒ7J'[ FvZ@dqۦ-0\;< qp!e$FK`9dRg LwK^qrGW@J'9owH N]G4T6_v# B\KƦQڠ)pxDCdMM#1J8cfo 2gkFɮV2C2Ι<%'gGDxԦzJDfuXi5|WP<أoo/6<1zT C\3'kv=e;&!@HWtǁqCCC= s[?Jn|6נ}2-G+Ak~%kߢ?;Mgd#Z\rFld$zr|8 p}ǶKBi SP_8A!7ׄ8i`d뾸՞G.V3(]}7pc E;-ٷA8t7. $I|Q0#)|}hbj=jʓZ2Bksm|Tj/W&$ 2咖+ݷhM=d:oL;v-x؃oVUWlJ/:{5-\_ԇJPWiP< Q!:cA}S o gЧ~첫/7 P x HPsɌ̐⟳ Zݗ Gq| +S-jbA$C͊ ttmy)'~%$Mql3g gv^q"f,RNxaJUMHRNj#Ze6X5z; Kauh&zt~Π99{?=ѿO/YmKA/ۢ$Cf i6=LjbS}xl$<1VwpjxTfJCv2ZL L#lz xYތ8EF(ṙ(ÏI1cP$FEbXTRr{iy@jf̻t~9kP ~Fa.!j^WfgVr-2LϿ% zbKkc|lEZ$1l& ᕉ dAO'~|}cƗRWxJ/0u dLRgdg_f9 ;.XG ugn@۽vo`l]O?lrsؠ*R@~hd)'v#؂XWΎ$O $QlM vfLP[bqWAO%d^6##$yd$զ37`Yc.Vp26Dߍu۟2Dʹmq{Pd} TK =EtdJ$R]Nz\nz/q)8fqNMrpa9wxmU?%tn{[tha% &zd>聑d*m@=ү+9dws#.g9 }^uYHm| խU:K>@e\#8_WQṻTi n9O T0a)%$yZjS}EU֌v{c%دumedTJt<Âd t~ι ݺ3 ҫdBP'凞/ѣcI#4bs"*ib FM2noMlȡpYg:c[ *&7 4%BDʐGgOvy$,ۧyrʥNit{ jSEO15^cPFƴD(Kx(sÔ/LxystD5QF٫%{ 9h11Ӻ5zm>T]UUּvz {# kgj嵊9fs9' W?IyozR L( `eQurwWSbV~:v$4S 4wVx RL6Ogw 5KWG6^*QL'@d pخ<$iEIB02)*GT@)njĞ̐ROO#ɹ"A)' LН ]LAGMMiO rȲiAtk[>\nH-4j PO?b0:BrN}o,qڐB%l}q,O7bLL)$zC"x}Aw,Xzs"h=Wmd*h~~ 4'Xң5hCSB?g7x!kcԅ hT\ F}2)p1r5ZG)R{D"0MR6?{#|N(]PQFIp(hʳ"@Q(ZTn (w hA n-U/'x/)%ֆO_c?GP01Jz:ɤ6eIf{bY"j 4>ue%g@juM%S 1ްZ[z)D$ ӐπF>k@(BXf"{5h<'2AOR/9S<%I) $1_AULbTiTMAMHp)`҆E"%@D"B)`5yks]H1hY\&Kg;, i%f(7h=N K~Xx&Rt ?BnʓWf9#Au!>>3!j w||\l|WaS]9 s};#(!|gc\&oois=܇b}sM^Al2#9NTz RN̶:;ǃS@2?E}^Ʊy~lvRWL cTz4 ] ?mMW Eը O7{uV>BA%"Be:6h]PRжJ;^JsRr+3^k!4(fYPs/%U| p9jDSZMQ5]O|X;Cz!=}FpCI~+>K jo 2͵ &JĂu'![gdCssYGNԌ<'LOa94JҞظ%o.JP%&o{s )JǛ%Px zC{ }@-K!˖N;,C7jqm܄}E+K䗑6mdd̲R-prVlDHiz.b j<1QSr{XxN4W˜ƴAqfC1Qw61R>4aVUdZ c uEhNjQRHi Nm^kk1M^\99;m?De96qC("PM2 6I;)o!vm3M{C%酘*i2Uk%qm\i菘*[;ɮSGV `K/x Im-n )e][cVVwغ!=zO|*}"h +ZŌl~.O!gbc'@jrmC*P|iU3z25|5*G@HikZC4%|ОUK)-9U~(iu\/GFJ{[82'ĽD/ MznEh!1WI>'Mm?s% c̥8^w|JD*g? JVi4vmߓCF4bZDŽ3)/yY'5/ ic[WzHX|/5ǝn8ȸĂɐTsrc A+&>`n^h&9f?-ez4|x@?mHڷA+r$ f6q|oI_^څt79v/TN6Ϥ- L+,(* c ^%b$ Z'81,5w)@%ao=UlO(AkzO"Ҿ"vTX^8xBT !}k% ._R!eiݴ 6OD꒜OA;Wj_G.BpESOࠗmQ\3kuQR0_GIɰߖkQ5],dUA}c+K@N [(nj<'Z-)#^{P1 fB6}%C! lq/+I9 I51vZb 1{ߗe@y SRyN*H%ey _f>zЯ sſXHYQ4{- 6]eZ睯 wͻ=^4 yj5uk R]Ńzufq 4e[;<T̙ I򙴈b[MfZ=#|(~~錳-mDEcEIDdH6ՇsfH:Sd-ns*tK1%AU?<|rAO[̴]yGl$$dK˴$e]SW5 n?nQ9h|zb"==N_zkyS TK\dsq?zHͥͼDښ|2#Z{,\iJCfR myI  z jܕECV#z"lgS'a$Mf$ikaZQS&,9r~9D TW od;P S_[P,8iTn=o!-"X-ub"S FԈ~s8)/,Mn i)P6#4Y l'C124<$0uO7=IQv~c\/PӴooi2]!`zPڈIdتӒden"џ KhD} ?KuN8!Aɘ#GJ&-74r} D`z__jҰ*֖)ZX2efU9HM x\з Kn=|:Gǖ?<ϑ3/J2R":S| > 8ƣ}Mhvj$ɏFذ'1w2/ ?kC $RzaQ_HJRHB@M> YJF #[m 53˽ h*E6`7qnv)LHoSCGf9.cAĉ=Qnb`4832?0%D(&D#Ow˘ 7  O灪ξo}_r@&IW@g_jM/hh ཽ֒6+p;@`xj܍=J%VƬ8>88[ggl?0`6.8$82,%dk267etS=›C_=?u y~ rZY!'oSNP. NY ^egݍ%'jtǙ׽bt-[x {e )#(J7a{`wk~<u{9ֲ l q[?/i|ɓYR;$f[f7Xv47Z1h]5hZPF6Pt?3/JqC[7%ˊnTNE"Eۛ+.=2Mݬp<"e6N8iYPR۱#Ǝ,As} 5'_|s HxR#`,]PהToAvM;/Oyt\j|ߺӼwe/b5F؂װ_mrM'Glan#=^zjANw93~ދ{>#;E?k qS e yI BJզ0{C]n]|NT+R™.IATl~D ʰ%JU2͉3c^G4D@>+ۦo9-;slSzdZc+u{~Π}cudfx{'aBJ)fs␹lNk5Aŧr.uۦ7R_YQܴ]Lu B{{'&jTBuwA0ͣg C}g!^9fOfv%H<9[쐼"eƟ[VAr\KOͯg6G,&2~jڧ) J2,5߷nU>'('\*[IqL prϘqaS5bdԍO0(ĩ='"xբsxD?xʫ+ZWrAy"!rVݏ^Foz>6v>+X{ yQwj4Fx&IѨ( 郦tBр~ɠ=)Q9}bخHo@H[ yD}R:}-zqH1#67$ń!ۥŔĩJLO@`zH2CJuǐI>¿!g$'R.y>I<9F1ھ*ѬA%p@vί\WHLMM(tB匚p^xӧҀF$'/P]I=Q_DPTt I4H9ܿw cM啾ܸGx>y'tkI~r?m۠z1(r=JA$ {<Y\WVgRd.Yz)GNUj.}ᮂ!ʉу:k<mTR/̎J-e$~r~N:;rļ_ <9Ǵ Q尶*((ϭw/_KP\,HK w\ެ.A#x‹V>VEQ?Qs>yI! 7o4tOo;~<R…)^h'$.~4R9Rzs6hh'h.mؼ?##GO T3Nr=6@QTR6z!s^sx%i ||Mf(7J*L`)(^9oX(AUE|*bp sAUhC꜠ -hvHiᦔkUˆX-tO_Tr}dzaJ"Lx ·`1ꕤ^;ઠV>Vd7rϞf6B̔9-z̓,c߿63{'u{}9Ӊ ;+ӧkx!+k\ҩAJJIyX]QB)&4RZe3ˎwv/wPVƼ >Sgr4oqE#,|8Tj"yy^BbGJ J xFßxDDrm!XTq 'F,qb(@KE0_ O~E #)ƚ_jDD6[PH$4O<I3 h} w@!N-?d<|>j]OFDA/7!P?^a'2#8e>iɰl4iLO<<`7詐yU@e7arHfɰOUP91(L>D*HCJї?6ReχOr\pUAc XgIK}o2"`) y !Qls@‡jFDeCU<m/N[9Ct.K./BR2t̰Ah> t)?T`*lTGd{`-C\)SW*ZMH ~mڅ:bco;tg7,?|K]GQ@f &:Ro\F1ݮUrg;mAvh WK%Cӏ@aׁҧRZrx P2XςhIRy,ntlz281y2ݹa Ze  U\焙O(V.,"m  /Mi>| VwA%(ЭU:>c\wh|@a\sP4q3HtD3vDWUϹnbL*/niJ?] wN<7d}򵶧 "={A@ ~]"2=њ4<~>Ȼ(@Inw t+Rgޠj9[TS&{!% mdd"tQ?\N1bߺASN~OM .30!P|L_n_`z!OV24/h@8|2DRmiؚZ!V]G@]uM'>K S1/Eҹ]T{w״kGŠOvmւ;;9~YጒR#8=FI)P=i()"1|ʆv;Ae+6ַ=Ǟ*@;_NU-! ,#6™lPb;f`$<+pz1ba75M1/h6ޣݙgz py5,C`et'ip#[PX)f%cX^*v@8D`(v{śJM ѯ7?۬OncNs"ke2~v1ARndqg9ܲ7=':&[8[>#ك@בi4~G@ KNr} ?J9TbYfqa`|~HϾ9HL3$ڬ/!uzZVԢݞ߻6#mMA2Pṫq>$$N&ۗ-"jQ jb>i2$R BC0=M%slR p cX#/?ם j & W;) r+n;Ct=cwAT-3ϯMт_ ʻV Ofϕ_&3m_|~Y`.7քwHɓm kGT%w`aK>~OE`#!כ'c^'IAoxYϜn0o|UX1El}C ՘%@[KsigZΛ.Ȇ? Z><>& 1*y>jx+O8f!s}}&c "U-{><ᘏ f#!x]e]y*jQ$Rc8H8DcQ]2j0PDK!4Rw'p@7>OSړHx˚* zG[1ǐ-KIHЖj^v+v8ݙ=[ZPh*#gk|lPI@`}Mr F9\}ziߛp呙oE"--z=bL? v"gS/XsܭHF[< 1Id_v)Љ7; E@?*r0',fr[Tm]17М-5zӞd1Gr\0x)GKO'Iɲ@rrz#H&SŒ@P5d3h^ VAL3bMz3L\*d8{J.JɥiĬ{ީ 7D_`uyTp}iSykF{dR) }U1$>̴aRy\Xb0@zb2|)2Rҩ=XK$O쀗5[w5p^S!h֬kǍq#ͼ ٻKj[ @ڎ)_tsj(٠Ai8"#NiZj 4hL0DdИŌQx S< s\=s^PT=ެFϪi>4v1|_|!Gl͵g{ݕ^^5ٽ܈`IWJe<$CsX*QP`NW)VY5 K܋4 1Z7eYHϰ)yifE_s8qh8d4·VC ̥-7=/,kDP]:ڶ ៯R* lb{8kV BΘ-,NXͿu[G /du aZjze>E0~zM{ 420ٯ"Ouۇt*4+6^ ¿GOaPpRx_: S^׏)Ұ/~Q00`s+=ZDOo;/Pv)|wv}qvZ3h`wT{j_UDwdLOav\[XOrh-t>M7<8n=򬒥獵 [HA5{kǎ|lx(pmHzZh w!QolH kclXSfS*l6LɤoXx.@zHeeepU59QlJª>L1GLd f`NSˀ=*/s%MyVD?VMfDuJ,?CeYԢJ ʃ{/6sWM7p sTe+5esCӬ>6?4RaJ,7|vS~ jڗ ߄뿄7҆=TX^'_9k?A?xwWGBԗ#q܎dv\MM7mݾ:va^ƃv/{˟|5NU0PTP!^w(ӭnagSF _ϊ=@*a 1O՜KM JɆw|Rq(z>ʘم{/?D~ DraP͔r1|ۦ(C.Ft{ZKUG:]*@Yrrki^;㧤P&6fKfjj eGLI+J"|)n̦]엘GK'Y┥C1[) g.~:1CuM lProJPvɪx_RM;x< ^R;.>w{~\^_wߐ//)BPLҍ3UB}FT N2JH^$f{7fU_eml`! 34LHsBj Lmy!Q+]A{+ssߧ$$S4SXBjC><s)Q=ŷ11:ccx=㔆2)D1#DPO"̀ys\bhOQp#mzP2oP\bjQbv2ddJ=1JKFS3G< $J(wKWH9fVe@hʎs F go#k3awsPsχrP0|D#3|?fG,jFᯎD9Q] .̞wDni6. 9a?dr/㟇T07r͊!ќG&~ȃ=J>{>,$7Ks$['qT~cl1 Z`kHڕC9@{8kaDn'i5~+35P?xFl~|I!y.eK 7j}&>yd|^LNt+YrHoKɫz=4_I;2U)hsm}Y@˟p2Nғ92mt˿KA%Mm;ypCoF#!{~}f<6Kd+m'Gߡ.S(Fht94~N@Wb9&f!sRڂ;>(kV^qSˮzpCSGq SGA{T x)AZ12 S޳6`J ^[{Ь},@i%V+( RGGʿGO^ *G%W?Eŭo4PN )hO3JʒR@El* D>1), ,{co@1E)\ 9hB`E/ *fӹw\R Dcl&Jg6&qA3KTH r01!g3dRIK2 ;?b)ǘ*ekԃkVVjwVSFC|&6x|d?d 2Y2 _RU}0&B0$? @KUIo'ijA/uXzg\y;b̊yRKL318{g)A%9ǩ=②)T 03LQx%L 9'9+0Pz"G3S;䄆\7t x(0FN)酀OPKxޯGN8#Ij/Rڞ7!MrG {nمuLN9M+: ӳOYg7Px*|X CQ_ۧl IOU6ȰDTm`9teJ>8s0$hNh2Gt, 9`0(K* EH6U\ :/6Uwm*u%RMO5OAki Î=X?& 5wx* ~xiUHdF᪼Of1I5(!)Ю>!%d~/@@owfsgds04ʸ=r7cr߯G^=xl礗ȢeX`+L2W(f+boӸjgdtQ~@ĹiXD^Ô\œ@LY#6Aooe.d$V$$ӭGV䚥^QjJ!^ QDP0dE}{^uͤS=^t R4;hdpx+Hw<~p>wuhHeyUy` OY$ObCdQ&*_镂YuGi1EY؉ .*O㮘E@â f2K&e),"ؕ,xlUx\#>lTa,>T_SA8SwDb661/.jf. ֳUAt_:%GzшIؔt85^ˀ KޭCB ۍpIM Ik]kb >߲ _?XRc!v[&HF6P $pd9߾gӇ (ө_^_ }cM3&`(.%3x\aR\ p_s`[AQ* /ij8;O U [+XRkHqr^.# yͤw~"JG4e#@)ɿ6׷w虱!N7?.?$D٣|9u)4U\G/jf:Mf寶g t}5AAI,ڗ/A/{q?h@8\t1KbĴi ڤ1q W 8q ×%RpK!`(tvo\[<4/)BգbD?,KdQ}4qdқiY^W}T#K )YV`Np7h]j,wphHqx?Y͖D(9}<E䇇:,oXOAxxEb##鈹}N( s MRmA(B!9i$InfF0XDsߚӧFׇ+|ZkO16sզ[ed"\ڠ j$2=#LOҔ &5gS Gx{ dp?6>)3N U heJ,z(#PF$v>d:KAdܭ쏽 QXMUa9wA5iIʛ@дݛzdȸ Fx{\J[rrpdf]pmMy繜F̃:'qBDe((9};ONԂعz2'!)[96"~Z>e#hwoXHkNϺ&8ߣ[@ЪobEۧ @ JhC.Ň"Kob{=&c$ISu<.~6ՓxMK$GdvڀF |WP|e,3R<An@k\M&6A7ߗB?SKb "noOis m-9?oI9j<4{{kf{edc)v'}]>Dݾ$B"J12ۥN$nO1ڙqG̰0Zeq%e`3KtNU?apV|y} Z~1cu 9j.7˚TlxƓ @>`r۽Aݞ{#A'˗|~;Wˏ0MM(-U ?=xx"^;|%)Q 'z) ?/ PV23,;⫩ Vf=?;Ǿ}@Hi|1@|m# ݳAZ4Av?a1O~hJE >M~$g J`9襝ۥIR}Ҕ W6>ы16>dIlZeyJE[z$3#+A ^3 "TVWYܴ~U43=}"/r7mT:Pfۭu}iakpӌfrQ{{<}I2} #4L,>z'DJep4 ʯT*J+IJQզ.na#D-P6m( (vHgXmhaY1lض6PE[zy* zk?+Nu!$e!|7oWlRf=ܷV 3^,< c>|0_~biKz24㹻)3RdKI8OΦc,%2Nk}=&S//FfNk:+ԛQ*$8OE/]ua1?u^f.oT!1bU\=z9{Pxs{fT˧RZrx Pr VA=3@'"Iמ~-}vպ)y eN_ʜ4h4;sH}yK# uF>K5T;t8 3 ]ꏯA/y"-!2= .%{uxd62}i%6i#"ZNg+ٸ\{_x@!-+h<Ub9#%c<=n3TJZk>P]rR}W- ;J  ՗ɟ8exہ m]ܧ;AkƟxs2xLz) "+c~8e/ '-^[jo  b H?:[<+n zg'n9f'=o$]ؠM5uKޠub*t43ORښjc?|[|'ئ'i\T A$d#%v4yb-xb,53F3'VKĘq#u!Nx EYOٺxOxq2XI{Y8^MtPKJڇΔ3[4rW%Z:c5}1(#EΩ;LcyKGIIhvvI}Y׬7 PxYF(O!i)((>+^X5Wx,.3C UgAc]!_Aw}q伧!!9ae徙W6E g )Ϟ, )Q>*ᒑ ԏ43<!⫥ ;x6?gEj\)KS@# ܨ0ZE;yT0-8T2s5C pٚ_,cϘ FijS=? kX0Ԛ&'DxQִ0PMsb7P> ?>4e#{y?Ϻ8mnSחu~|<gW{íԬ_}ϯTq`<i]?ab/!$AblZ!mkR|;4E+4vv₟-들v_zZV'CD20;j렗rߺ՗#'rJSIVx\ L{Jd HtLR_\Xs0vD6l. Z~6ezY3[yEuSNme}3z<(S2f|͸Df9#lz`bNT2/6{n#G[$맺f$r=X֧oBݵ@᮷_ p7R_/S}Hmn}7q:DKBzYu8CcnD7#= 8U reĈaݝFviHAQj?%34ЏXIy5= V4cv܏Tb|*h@PE).MRG-3縦,ۈ>iqMkS2+-NH:._r'HgALc)L N9NsP @^$qV A@\f6%pZO?$̜*J|p$2FQ/&ME֨wk~<:E"u ; 3=;g\y_nhH1Xi,hv7@;IwDP6+IDKmEDtmVs; Qfd-b? FLBҹf*"JN}(d 8RV{y~gשiO.f/jLUni/P[u* @z~ :YMz-~:#\+gI :>,E2*qFXJ?L{qcQWܚrцK#@ђw- g2/+]v;mkɣ> L53aO50<+gP S$dIoG$Jՠe'4޶[ ln?''bjW >b:etu]>SL)'Q^C%o }CDw@\a҃m]z>R2f=e!jgrKݠl{Ťa|F>6ƐԾ28dlAż+Xρm+z~>6kۿ/;P?4j>ad[!Q nŏǠ =@t5E@Tco;TkRk(Cv U.͋S!8 2˫f9Ϗہ|qE@e: E/Q;3l4QQ_a;A=3 pUׅ7Ûu`o@쐸kBrηQ4I]4>>fWZgƮٰBR? :XO2LT*;;4-WfO$_<1ۧ'"iy`X(n,O!X6PYH?ϥ|aI%=jcPj>\A5w렌tZ+KYySߛ#w'O\PgwcwIqjG*&T:*CzƲ=x zCKI s1$y4M٧]k;A;bygfF?AIstmI:%g2}&>W(V$H0|+,ilXkb9q9 jc|L e^`;jQE|9MY=;Wqjiר:TnC ~L8(v^7y+{rOrF=n\fw[]"J[| p,X{,KfIrA}Mq+hû\V%e 굾U~ȆGs2^3Dh(#|o*RŎv8/u[i%$4x,h탫dkL և1mPZ13; Ӆ" & =bG}TgrTտnVSt!S SW1muDwii,P xUl(O#>/ڗP}Ǧέ)Cݼ ؑ`^]ڭMClC8AIW8rj폋/IU 6GOx| -(-8 `^kXe5KK-D.o"Bҟdne6?m{vKn t*Zg(}UqF6?"=sjiYfBIˬGԁ&χx=oLM<2C88("y/D:u!(S *RLy8di}஼*D+/RAW`byN9+HO}VmJKG:ӡp @h[LIQo 'DhG|̋zF3ۏeݧĞ7Iw@<+ ̾xRKwH!›eGۖc+eySfYY2OXdoH<{H|V܀~ysy@Ak?. U~ǧ4%W Yt~9[&3O2BEfr-N S\[pf~-mwjf̃Ḷx(# |;(Ϗ,>V{}ckzo|8sHn8C !Y_cK583l ڳͭq:_3#@i%EFSJ2Hm9%rҬCH=~&ah Შ]ރ"CW J638Q.Q㊸ T<(dL61t2CG}m}:l~(&fw}Mߕꓩ=i?n6\/ :b9AT`l2r>ݹePVc/m׵"cT7'/kgn楍|<ʴn d^ǯ/~Y{ˈ_i3bSm y̨+m~0]{h8#ho@xD:o((&|n+f#%OdSSHO@a^,{D.n|g)2>pW Kn*p/UP#CiA v^3|A$'u?瓷. S ڵ_"뗁'BLNG߆AT;}n jzқ%r×Cf@-O7R`ץ˃b ҁɱr79\ [Xu ЦJ5ATz%M!lJ ǩr~ΧUBᓷwi"Qґ~RB!φc!Sϲ=HΠݨs}l@=msξlYH=_ >4#[aG>Z㪋Dl||?fZݣD=/s5E 1=q vWf V[iz"Vy)m\eTOG$Ђ"PF [0DAɶ cb.LYA*foё;n ]z!"BC%L5\°ٝA]0&7@7?e \W{RWV<(G%=^HOԟj ׯe:j]|fAHط8ᇞ\cA^e;&Hͽna}Ha?aW<hVM%߯43x"MySR>/ch }b, "󧊴Gqq9%4pYx/J=~ "~ Z!n `8/(t6+>8gӌl~ۿǛ$e>@qGwNzIxI/+;2}0[a7G$lc^ D<K59DS,#T*ZmcAĕ=ly5AbS@ĶԷ-:Bqkoz"WI :q9%W@PqעI{PX8iܟC b qT[_8}މ3;oʱ{ohH٠Qm 5^),.&;:$GlNQO' yM<&s܏Tf 2hą%M݆`?Jqb|;o\80&-WLӄWjl/Nr~,!x=ډ)(xl9R%_vǘKH=ː[[[?wS"J oF{csͥS's =k roʗm2 JxICQ?7ʩTYΥ3QJh5c=  ~_nL!H0cjAn07 6 3!u،2AV~(CBcOAۗ MՈ1dԚn%'ۣezb~]g"'a[3Ht(C5b!bAaUKah^m=_?1%(fͶjՔLaǩ'l~=A-N[^7Sv l}8\mn5ڤn_igaیlX4[BQ2 殡4a!rBM?^DiZ-|w Y!Yni5ZL &L?c& :CD\u^#RY{ eBׅWAVoO%gA0")wB8FL5RmBi;pn5{pRײ'!Ƥ|~BP5脜I73;V(qnb2gl4[|Ɖu1IovzQ乐 )IM7J.3 jSU72}n {DfD|(LZfWäq>rĕW gX'p.{QRAϛ;9jKՋO?#+}Oq3+R 8sv^53=I#y+I|>6ki笷Tn ,.5ރkbmws5X=8s (Fx[Nrp\o"FIn.MFJ]留ѮBLOnjѴ >qk/i-ǒַy\)h\_[$O~D2FN4(nOv"LOeg @h!wq^ R!uP>Rm?#)pZאry+Oy&k> 5sՉgV *Jt~xl^-?BZn55Tݪϟ>܃~留 >1xNv$- 8nBJ+Mz{b_')ɏk[|55!6h|o nZwBI ȜPcМF3njG; څk OZ;w/?Lo  N9M1f$`H`5J(Wi2P2kls͘偫fkL)ؒ=rN^ٸhBòp5vdؑ6J" eEc 9Fpn¹XQ-69}m)-U~i>&vS*!ۙ%@J5Y :kBX -hѣ(k)#!pg_p΋r};{m:92`#< bW?e2Pz}4 ˙~c7 =m4<;ĝwicF2$Vqs$g;HѼ61/q1֬8arzښ@H4~G<֜}NI+_%.FV-'3T,Wbp}┏,6E|L,kYYẌ́צ76NIV&)Bjg1%Vbr4DPD'js+^rき?Q r\8N;v"%P9UV{ź7xbk*OXj|qwvRR jL~~|}RăZ7v}o#!] C2oi9HkQ|E!fRy_RQ2wiIQS,"_O1%頗m-C[xb{"p艉M'WU1^dzLKF(Ѹʊ1rSMHzbUX7Tx> WςxIm@BW聆FD".QA`+XM-ڂ"PRj<4^PXVAx ,l?GXףj'*R% +jc5oA#uӽȩQyԽY ԿTk}yhj帙:Xl_j#V DHbʉ8AfBe7tKM1<*biUW[* XJb"空*+߂pĔyގi܊aB@pœk@9!YEǦO2m))B[r*ϧepcoowXZݥK\U.!uib5/TEUT$釪VBkJHs}d&.̶Ms._nj7P<+W:ڢn MI xB6)hp,#{Z$i\RPҊ4A<1|ML3MO^Oig7x>ؓ/Hy|{#R璌* '`S\nnLi`&7.~߷:Z'SM  A0{걤=LHq{R"S3^c[d~G N[!fr[@eE"NT ՚mc!%i!رK@K1 [UH?8Ѽ]qe9:9?23P|r.=L~c'5JĨ]-`䓙u2ٔ {5Xݲ햫$>rrS/"(ye2NRR8YьO-st*s!JHj-,(9%2d&qtc,d\R*'))BNxL(ļ<$韗y;a Mܯ7? :]6j${?SɻnJI!x>lB)&*Yc{QRTߎ:qB>:tf^!jyKIncNŜzjSzmQ{{8}O6,m*&z--*IOrH{b\R Eɽk}6/%IR~<pɽ,LI3K$xm"Z{YE_As[ybE=w +'m-#'ks%_ml$=7yV<,(-W,Ġa H/!1dlfP<&B7 J}3[S?il./lݒ1'D۲UU\k.r\?-7(ϭw/_KP ?1W?̴}ȍ+_epl`Cvw\ YV#x‹Vn҈ө|]8T " ۷%,k5bs7ak|>l`0+Q;ܬ6pH1AjyS;"*Vedcs\ljGmŜH:)r<}BOlP̉ Pb<BvsY2{T71P&pNiI bz' ޫS±-?~X|/B OZ7U<`|[.(fͨmh{dhWE yu?ܖbQMxI"'1?lӓ4>?bG\қ'?p{>uA.S2S:דF%0ʦf @Ƌ{v][k@8*J> ~VZ_o84یѹ?ނMn JvzQy}lon7ﯵN+؛rT<ܮSaA(犷N:ht՞7gJcb{v[ h(>ڀ9Un\8G_, >Umz.88U I=_ 4ԎcRկ E=m %]'sPص%頗 m"xJZ#px|F8hnB(x=3dZfeJfo;|C8GxL80G)~zwOx!qH'-?;-b,6) (3CZ@o<{eo压ϝ޴7]'pKB{Ewa&/E!}d" ~Drz|A ݳ  f-1-w]J2$fٱ'hÂ?reڔ Z}̭W7h>͑֘x|.2d0 %R:RSJ=w5R%3~BOTMPq?\DZv ?Gp$B(JX*RG΋ rZ,'a rM'Ţx\q?9'3w5b!.1ͼ7ccyj#$7!4ka jWYh&67{6$c6}N|nD7NK|~5[8((z +nHW#lJt!Nook  @@^5T›T[ި YL J3~q2? ɟ۪ hھi.86X>`/ddCcWN)њɻmQ'n4q:qܦ~2\KI nav4`dcbeZ..p KU$S*Yp]B j&^5DU{X йv2m+_{b8Rp04MܖʴOg7_/-^(bD&3m_|~4:d.7MO 24mUX1XV =.µp]|B}P]<*\_1xk$K5`hN4+3Z?p3+EM I-w)>Ns 4aɗ|c|AL_ZhjHF6,U3XKOD6?Z'$Fixn׍DMzq!Zaz}̴,7D̓L!lQjQWxp}@˥\t22:ӯL U@P6 d58:/o5sWX{9c,*(idQ?ĴI s,2vEO/78?UϜ(hRrQH\I)HLnJM'5ns4g7,>wkb6(EO%b']" r/}{ j vfI~9gR했ۘaS02>Q3\&"/~wg,Drɋ+Ctb;s܃%O5ʈ۴43zt$U]#Cڂih03u|?yU.N# =TP*ƾA<Gmw Ցb myRfm+!unv{uloK/ś!^}_dLcDy%C8zE|`zY|P_g QL(c/1^Re[ծC;4 _ <9%$5oT-PNzgPL\awu#jZ~[8wfS~)ׂg>]DZT B1Ȋ׫o9Hoğ}z՚ei {A3AB-Z5֏s$|dub{XL4R?dʖ<%Z QojfB$hWc܇U8q%kČ0H'"x;'%E!6X12,8rzsyw~|x@|_@qų"lt׹@[“g#@hsJI9jn 7r]w]2KFWc `|f F'9}@>!-B%" "s&Xžqה9n^v58RG=pRҊ]^ѪV^H4ٰft%xT 1o9m4cArcXP^$Qyd)mȟتdֿ8>FBS1W# ǘQDc!X$f[ O1ҩBrP A Aҡ-D=zD#r-Ģ;~D}9ˍS}d-Ɗve@9\.xu1VSZ!1#qS酯:ku1r\oTm$VVU!~ر7K=3 JcPlx|2;Ш{ ^*"놿 ԏ|dES?|NI!bJY~P#?D;+Q!zDNLJ\.>dHi6Ғ2и84@I]/PR*"$)h!(-PzA R6rfPΘwچ9Aό6-( Pa\+k|4qS3=<ޗS}ҫ]Dzծ}(uo'm?An,"PCb` 2u'!so߀9ٮj%_ ϑ!ڧC1TZ`?t="z|@1;Ki 7vĠ={e2a26-+S kqžQK>1H C @D/QB ibb:,zknø] *"KŅ;j߉9ƃq{6CE>2gUCrӦSI ߗ ;!mf>)%Jw eXwh>Ox"J 6;UZ^pW^pWA!dѹ)^VmJ˕}:AG(ǩ n Gxh8}|@+<+c7GW?X//h<JрjZ5!Ǔ ؍39*DHm.d^r}3l8ݰar$l'dg+!3-vJ% v0&>>[/ !>`J%J*IMj(!\(G4 xY Q;uwN7;hӣag6lM{V cAeAGρmOA\bu8F;K, smM ygMXU$ 01[ۋAE A(bx'ו7A$e ?ޘzCA}s,} VYkR!rv$F59$p;Iд:_?O8hɩ_g>q 4C;r?$K{Ӕ w2*@6qd ISFZ k&S? Ɵj@aE Su]q3#1,c>Lߕ2}، U8sWM.M<=Tj\9\ Viu(=fzDW$5=s>ݹ kkm@MA2 1w=!&?~+@l aHPH:WH>[&~1Дu'oVT)QOeIzh-|T +J%R<'8QvOz8>RP9RĶKV2P- E(,xPgc q⧂u<ƂǓ{Dxr1vP_wEO]\{VP2xT Ԅn %EX}?ڂ툠ݮU!v|s3Rmӣ87=x-ZPXgh!_ 4;hiU锠(Q' /| ~eMQv$jk  iX;HW?Sr~v\?RA.!}<RcJVY,'hm&:S@M:CAurRoVJx}BO(>9sOVUCMv[eDP?>Ć8s0$fޢ yņf;zR&6r R\uq4\h K(p}k9x[qT|?RR?dpCpRbKI|VyJ: 85ʄRTx8A (bn2?''l9D@M }Ch/n9Bt>Q:D՞ߗtecf̪;%KG&plWFslZ)Ajh}=Sv ?xF 9!da%Bz,q|}>E}$Fzv?bG{>T^x˒j; JL/Wмv\?& xq 掺 )]n{V^1)v%hG]CgF 4ݳ>yoqF6tLfSmP4*< vyfO4g +źIo}G#C'3O= K$3'/8;e(2tux=2Ђl`XKo:W; *J/. yPG~>g/MmmQZ.UBȣ~-0֑nt}1VM(jR1nt8qr)ܑV rG __9UBь 10h>(:C!(~4n!#r.ڽws-GvrQPգY9#]Hoެ#Cu-#ׁ2FZ٭YLEV mn_9} ԏ]+J. 2 kB$yxQ"#"a9LbneL#V3&wxӷo7T~ʣUwu74 -gi( ik8-H+r˻bN';֯˞԰Y w6{[xFǮQ/<!T8 &z4~TN?xzw/%5ێ9lzBRV)>*R"-747G#ďlNVlPԩ9'EVSGmz%sk-ӋRV p zFu\_LA4Ţ/+>oe6NpB@TTJjWCʜ,tbr?"7D-^]Ҡ:~ؚZщ]Yj|8Gx{FZdqCn}~up?=ߵ)ȭo??c-D7DqQr FI9?)}:9xN;%q A!h+ M۽>)c ?1[͒*@1BXuﭳ&V)C|uX"zzt0切PV:ʆr||xu> Ap(^o5/q)Ol|Ty~?* c5w:oL;v-, 9)XY|ʉytJ lG!뢽N7 a @oa$VEM= RfܶJMW@cІo3Aw IϚφ|Xt%IG"`ao>y/\$&TpR:JzW_cw-(zYg:+ l!gm*du:MvRHgP?|SUt-&<3j;Hye|@!8c3uD+XL,F<)fr<(/R3'Fd FTb%QŪTnzRTs;DݘN^'\8d3PeN[yM W'vlPYkfH/>DfFaD|+(BdIךA?x,̑&93S?o{k [4޵t.kZxY"?x]ˮl=I%^K+ޢ j=kaK1棪cU|pœk@;+tѱRiٿIˍa GvΙvcm{Űm!3_]7#<.96Ӯ|QjSD4pE("(Bi^+T]>r~Կm%S LO{Nv۶zq|I$w5-gX]]b;{w{W0ػbR ذB PJ?f&9]{wpv픹/f|'sغ~2b^tym Z3k;! ]]Lς{vI 9 oUITh ʕE:qi] FqC݌+0E>{Ы/Z:CQbs, 蚞˿#^84.9j#FJЯ$(D 3q8> 41^)% rJ]{0܁Do廲2K`3U،yhX_7Z^y}o]tf@RSFkxbw7i[3h>i]5m *Hytױ{!fw٩.^ A-1C1P],<݇]'ŦIhgm4([Pܶk9ҧk؂X~ħc!,i'y,^H`<3"FC`dLc7&W#t!k4} yB Z|,%T.<{6VY'Zg!D_^gY{1C 5( p@_;'E\c1*d}Ej+k97㴴]t(Y&9)RX*>"ÐQ( 8o}+Y| !+JxTJGsKŤT9eՏ2Sj*%1aO{,]ٜH8Ȍ>$JF`4{cvSTCS:U]L3!P+&׹b2l$Kތf-H_(>Bq'I$4KΟO UZTIqafaqo!Jy{MG@2+Α!t]ۺ<}͙mz y&eo,grA|cz ŁJi&,3A.,BVsrjep:!fSO:{'JJe1,2#!9d^ӌ̈́02I"~I]EYT׌k)AbV:ekE'.1|66Ԭ٠mЯDo[wDL{jo3%!K_\.5[84Ys.;L}Sp@^Y; $AI3zoOu(;?Q]m6ax/ iU+s} :%xth }*VԁŌr ;j|GH| KLII*GHL]ǙVtKfĘ⢼ٜccl2##:DliJ= >(\؎6!d}/\ @BĎVL[AQ&5K +zbD{x*XъGe7kB(H͟(aES O1!J)&#CЄT| 9>VRe}R .}ð[><#+ӳ`gH.^T(󁂄7.)%3,<5h~1T7w,0'f'٘$Um%b%,bjNZK>}SZM(ajwzfW\*ٌ^y(`ϓ&lK4tk5p@6DU!RA4Xf᱘K;Cl@3:A~9@eI:!@%VtT}翵ET |;sz3V)aض~11y^% Mzh As}//a8Ӻ]Xp&'q0:щ״~|/Kq+$\Tb=WhJO}ox bg , jAݿ߆`Hdx=NR  #%ͣ(C4k+pfTei1o mc;;KʷtzB`xo4;w4x_#x KNjMO Pk/\8oUTLlYPCˮځVn1B)fDbwuVtIV; f\t\<<5B)d^@:Bh>@zRie[L;n`|cT;hu[,Jlq',7H_O!ukR,7OpnQWHm2I;(nz,ҿBx*AK&ÙH|R/4Jf\i[N)̵x  YuL01s;ȶe?fb6u?@ ?22:eu%6X,%bf?P_Yaʊhho3 Y2؃Y^Z֪ \V6@E,I֧͟_xYįu1_w~&~`qx$bV |ẑ׿f^rz,?HX9oJDK`H#Bu:y_ڎ(5k*4vVX#0sd^<ϴ]Sy)^( abY+q0ƈa@-X&A-X%!G#Y/ߙ"y)EoSp~. u4nhjZ?<΃E]!4"cy-OxvW% uΧ\kQ?o(!#u$ˍؓq1|9c{qi=ԏX8(If-wCY;fc/d fsjlTC|H/P|<% G\Ik742! ļBGz{ շ{fEr-jIl'gL~ɚ.ϙ%Orϖia3wг}P) >1 |vՂrxB[K xۖ 6iץ{OHPví מ7;@Jg{ʌZQRԉs MVg;"]L.;b<:2-uFF]FJRx} uMIx8W-Xq@fZkQq2He2k4ls9riSx υxK5Mdx?"vR]@%.lE5w+V6ŋvJ5_^y%o^^P}I||c^-Ptow?'۵iZެlyG'8;~[=gB̹[+®9jmUnk a7$קf{$#Ÿ(|D "YѳFʯ3_&- }AB:t)6ۘQec!ЦGCjˊ[ v&rMaDYеڝx*S"mr#l \9_ӛ)tH-#sE)+ƄSD!CfL|L40=Q~9:b\=O6ݽǦ6^1A^xhjnxSP%p^Pb@=N]ϝt:btпAЅz.8)=?S`wݕٯ~'QD3Q|LE|S1!PJ11^0f3~bdVv;gq36w S>{-Π]У؝͠;עPwx t49Z/ǍI`H:yta^<KUp`Twd<= #PyR/41~(͟ƣ(E|c78؜20L Q0`{"^A:,)n`b-]y@0}&@p|E%BFhӆ'yX:-HX{jV YsK؁&f=ZaL(|gP~*~kƽ28z҂#+#O5\l}uw+@.^Z :N7Aw5 >+Ԡ_bP/os` &R 'g1 $6AM^ǧ}-K<.+ROoP8Bq* uDJ(ff`"+`eF\"OqbEWLdܶY&Fh'RƐBx4G[DE6ki)S1BDu?*~cR^աw=BAPY-DVΐA2x2Hj!@\pYWB)v5!|.?J\_,Go#aHH}#ʭ|ex<|$u)\HyVz+ sӳ!*wDJ\FKgtG_ҤH@3[:Þ"cxc̓ !ƭB2S,JGC.9 {>,#Rr2Zk3A3auMtޅ{;>OCbVM]n<1XtjG gYGtu }j5'wnZaNup>mD:9ϟCmEjܼp g~&A1ӂ_TD!yCJkсnΫOYc|!%e#6? V*Qk矉^o8d*f#B#.+ݿ_;·+FT~`@Lu#gt}F #>Lvs_T@.Y[/T-:zp%O4-P XxQ<~ϱ}>oBr)T e-l_tپ> Qj{3}qzҟWfa 4GHaN >Ҝ*V,?0R1ʁ&ӌL81 o,w-4c! ̯8DO2]<>K?σ0[;.keGDaV9Qfo+\a>vtw"A]k@̒#YjLEo-5KTg_R<(l\ZI+L-M4]~p79Oo WB3ZO6͸~B3PupE>_o DOIYC?j=;Gp󷺃sՀ^>I[dh5K]ZhB'=X2|qzѝ?-{%ҳ (C>&/;_K . sLu9|w"Sd.Z4E|GHsT&(?d9Nѹ "VlsDlk1tOWs_Y8&Yuͳ, *s.+"CTek6U." mxvzloA)m#,cܙS>=U%hlo{=Gdݐ?{x|x o-vO{k[SiyZu`%p#dqN&iF9wWq "c7/֨%!R<3iD+`C岷Јē3(I;|y{?0 M(&DQc+?=E> qrZk@s%K~ 2ؽ ]TX +qgK7AII'wDpDJ&Q_R#ꀔ :"%F1ׁ^%͇BZ5ݕ!K<RcOb%2vi 5 A?081x?R{#!vSY7Ab`R/no; ԙQmHpGpW8%9Z'FL-~$ [:rrQG!uBCj%B&H+\1봹3= wv(e4zH[rԲz4vW3[V`]Qf-ОEC;ih{ m< QͶYi.d&[ 7gXurP:AU)j%s<odXؓJ>ǣf$Pg(O{4 Um"4,V;aVp|mJ,5MW]v>te\9\HsxWXXejPcU-Q~qB!wܝ!9VN 겠*+f"k9'ec|z,)MI# IGQG݌35yЫd Eh )] >1f3!v_T-M!J=Ir1I`6f#S a#)A=N{G{P%6&}9 +wz:`CȻ[ǻa?R? 5{]sy AYZ&n[[BpR롤\ „Prnpy#8;M௃)r|C!f$aZ'Cҝܺ|VCaQKLUS|×g]R,~(#zJ0(<ʁTHF;#H])Z b2#TwvK=6c8Hpcn<|q!yQxrS{ c^i\ϭx=?7y:sX_ܼzrؼruyP3dw{a׬_ל]8~޿<<{sOuSa \u>zc5JBN1" w2Cw ,fBFq35|^=Cb? *'BJK܌U uky}[fY59lvH"Ksr#%mj5JdvxN"p&U.Τ2oL=Aa䍚sAjklzgg6dLς&~\3'K]$D%9E6u0R7OL< aƂ_b0#-(3Utef/2O%ua7zd0+]GpT+v޷䦼;C5_Աg Կj6-轫 GKOke6uKE7&;_>*m] gA3^pE8 ~[\ Hd%'e뽽(⛶GwwWϾ).vWm$IL!ϡ%m w-2j2v侂C@7O7g=LF\|Ja? ;K@RۛSCʌ9!ROKi?|)%/r"6wԫ,cz)Oi,KWIs;\ns4#x HnƁF:ߞ&%Nf*L^c|p|O,VLP4w2$Ku'Qm6=}K?P>0wp]Dl yA8%ρ_ߴo+;o]?S#A`zن@'la۵et:Yn@w}wUZ@}_@heRQ|2Eʶ"ҖƣqHݳƙ9 Ve)P!дiCs|OL6eH "mx7d%=%>GDטIUJwTGD<i V2eN"#hz_+'&"YJ{ oVQIHgp'ò_!h#~BXnxgٮ(Vș]!>|ȚvpC޴h7W]R\W\]DD s)]!\XHEV٠S P{kgvJ@]q> eNZ׌뚱g5g hۤ=EJu^O@  ZCڤk6ݏ@6{& fsJ!ۂ;ˀ3ՆK?hOxJΗkUo) /O.'״~Y݉ˎC ^RRYů =t}\\{.nW?rg=LqMIЮ>| e(vh>V HIU!_͡_nYC; ab!kچa4L]gqۘn;?Nj+/WV[u (|^5}n9Bl>'ihUsb5}aji|g][=wK;@.` V1ig[c?>\qm{ǯx?x"Րp(~q5xq8N>%ฟ~X,@Ɓ.]:q+l(k;o}}4nX;= uZZAӈ _t<ֵSB8sH-OA-J8#)AfҮX)3ߤ&Aw$/`U?,uPy(O4\ Z :LFdj4G5R_H|ћЏ:Ӭ+˜R9|/not?r۞|ܒ#R8j)ؾE#AJb[$*R4`n;4 @e QyH&g]T\,AP< k[AIwznoj4QI)zl=>J~ sBpI(B:p^!EA ׏YT 2T<\?Qn~HH|P̶s!9JH4軲SA#C |i2;[Jз+tWmzPL gד`im;ӎܦqHQ墑oH-9dn]]V[#֘8Wf ?H%pt^+`]6 va#7R`#uv0*9uf-q  F&̳MgrQ>_t{0A@ʃr7 ԝ?HownOlYàɚ4_SߟՔޙ",[c+ܹvpRx^} }A5]pݴ>z{u9.gפy80yqjG ϻ?3Y-ޮkO4}rXyDD>G5-Zχ툔筲25vr+16Kp=eh{ mB+9)ɕ DL%im\Z>54)&WR2'Q'%}j-}>i&ˈIjm  {)'|>Q]vBL~eխ w{az]Ir}+DR3cEM"Ý__d2,'H/@o2iwvď\R$t O!KqE%)ɭ8iF: %Sr( qE4|>72c>r79ɪb#8OurbcܱYJ[\<8b'x=b^?)"rPg+vȪnf<5/h^xPw)WV@5Ǧ2C}C̦F>h٫i.P'ػҩpqǪOsz-)!ٓq!ЇfI}֭3O~_dsؘW7>D[ݑ!nةNxHt;] fV?gɊJn{ޯn !_N'6+M]&Ҽ??"ʪnR1vR8G G@J[5c7}~nPv40 =pP$*8T8@/!5׃\xYSvB{U>H/H]"ŐaYҳ`![?>n>GHˀǿqMDp{n̹ɬLSbBg{V=CP@s?.V޵`ɯ*R;}in ޮwEǐT@vا篁>O- W@oҁNWAfKы糃ӳrsVơqt㎈:[P~o=FH ׈ruK\\bE& /9]+|# 2ʾL>();o0Pψ3A!JZدr(]&GoqqF-r{mZ߷iɰ[{+D\.y]PE ht~#:{m^գqGHQu(P68RD8IfL:, o^wi$BbHH޿ՐzO%'B|.l/{7gX됞?w{!F8NwN#IA'ngj¬vWIKј6-(VX'滙я0ov6-dbATVUjy@Ygo툑ǮaKWpp\}@jt+ w/ɒuX̓c\G_.zLlABOIf0$ښZHz@ܧ[,烐נpf^!5pgA"|ȞY@>K " $_߿!Cd vs  -^%T X3b m;dgkL:oߙ p:rj1ɦdQx]Xxb 7 ¸ۅ>(c)s 0{tcPOef^Y%]pe,goAy28t5Bw3h*|'#%+!T8;237 wD# nk;o`f<$`$蟃WwijRN뽺qOЈ>(%SKV)piХ+kD|j "ĖΡ; 3`Y>0r2yM_ lzeI \:O4Q3 )#="įO7.ۂwݎCܸABܭN5\HrӔc!i式ہN A7$ãPnǞ֦gA0KҨHwZTnsq<; )H>[uI&yCxehdƄ`f׌wVM_AdovO Լ5b`[ 4%^l7?jEVI8CM7ÚSX欷A7vh]A]D8UPTi(V/voʚ~q"g@+t/+OW~۩O:vjҏ?NFb`;+[WQ7i1A.JB\r9CRC¶ UYWwG }֫Uo%}]9/lqNd9>= (UO&Q\nêϻ9ą5eZx|wDB 6wL|y2%_08Z«Qs=o;1 ȾM7h.?f@)Ptfuoun/7oGPi<.eдsL0cx5ʼnO>ZX0 ge: u3(ͰJq=u_| 2ύ@KeՅO brʗ~1(H[󹷢eμ#t ,TےMJ ѧ\/iAYEBnIlk>\u܊L%rhѨ!pW r W 'F}k $~P@*Z {ɵ( c[6!~7zBG_ qvwCҩC[>"蚶\1H ;r7 }N?lezPL%5>4ҀrH\C, `Jx2˄h1atX;oL|"jVMCw(^')k<Ǖ{BLt}F i;QdW+Hϴo𚕳vWB "1q5 qV̹1Q\WE☬$c=ԋ [Aj7]'X`"4'&Us% KoQKK<`PWcFMbNc7w_ 1ͅIjuxY }1Cx۴>Q rȇ!.JLqk7y\ye@36sGkČ](*ܪU&_秏'SH4>xyJ{r]ߞ]{Wxц7_IE .R}8O_F!R#_ )ާKέh4Y_*MKz fs[ ;?k0?;ܮHs/w8o0tE dm I 9J`ָa` &nXWwRAPM$y=Op0@|!~}DR|;{AE8!3~s[5^ opɜq 4;TH6ҫAW-oۥ@SululNg7Пj_Bx}ϾdzϿ]ICRBERVrK:ȹM(NZdbע0 ctw8!D[*d `u+NWxN# Dt E~îY?t~WԇߝXTBÁ*­@x퉦Lo5c"aqZq/-s C SvAH3Dνv7xR+)U@t{xгeK+&쁾,X~(diq4 XmS> ҈}i5!3HBPa9[qfY_)\p}NRT+[E덆evgS6JH֯z} u.*=Ҍ(XosAG1^qyJtR[t@^;vS$o͍7x}NR_>>qy-Aҹs%}xߜ輧}ϐL!EAoZO ̧@4MfÉ4ꏶ I! 9wHS[YdrDPccc4&ҮHˍT4\+,|4خ7j,s,߱1+HmYC,EMU9nsU'5_(~`KQ (C֍s;MG=R>Jsjnd(ڇiPjHK_\_zCp:-x)( ~17Iz;PU(ƭ<|}σď'9.ORiJnS)vQWؖ}?!3w|Whhհ0)0-m 0n!ܽ"HuDWxNQTcjEJm_Mi꺭ǝ0&KPq׺נnԤ_\;WXX눵2x2$uGz0ϴc{`ӹkAeN >mSIxʰxwpO~%|Q# "Xmˋuڄж|eLÊU)+V RΪ׷S>Ta/= sJC`"SQB j*u&GFm"No0踡6a y=R<fV4 FJ&т+dE &ydT(IJ 굛g|A@5-`.2r.UnFl,rŌM@IˌAxUm*'W߈> 8,x,d>Cs?o&Sy1k#b>EokAr8aɘSArʾOs~MAJIw!5ː &cǯnB4m;"MY9Ϳ]@xMdvE:[:s9o36rg3w?~j]VN@<5:yN\@ͻpvoR׵FuU; B lԵrѿɯJ''B,y}qu=?êŒ!+:Iڗ9שwd]/%O۹n{Ɏda*|b|$F χ䱲O69N5sxUR DD$]ƶ] e\>jqpYA{³- wREڗFB"LS "_iS+Gc!P3뢋BJ%j_,6*Gbk";G}^ Mς٬LFH)>ʗH-sfi."AkbFjsSfʹ3eEbia'mhbBhL1a42J6w`n.#}I`[Grl۪ƒ蒬*U++&X;_c1eh-mW6$CgMsNb, /< PEA ]Xf"(QQ CG9zaRCCH\[$Q@ /  UwLxF,~HSJI !V,Z(Y#FJQ)H"S)3c+:*&?@'SkUk6 @ xSL_I̍]*1j-gg^5k2dO`}e@UWhj T SPvh1S)J<]#4Lv[>vf _p饷 a#)I%Ji'.Q=]Bʯ7|.NOz , Ar .?ЕQMm7BT di R|-w[]22WvJ@9 2>=/눔7\7˔_I$hD9Rgob" %Lhϋi(̼귤Q^ռ3 V'TQk-5!I+RN>3CIۇj\P&W"AbI7Vkr: !|)ՄG'܎f|c3OkIŮ)蔅Sx_t[2-*zBwd)p9Aa+xz!B&Vw=F:'J#Dc1mm3࡜7 ߖnWAVB^_RF¢!σ[v֭ 34<QrJHك eXd.iҢ-k buﷅnu5AUu_ zkݺ[ R|6};L)\pɹhf~,<=O51\\_,Ost|Q &p(W H6Ҭ~R;@&@7sz*5O>i9 ҳM9R|<}KNq2-4|C@!qcTfN$_lEIr3?J1Fʶo2>Z#i>%"_f -'hS!vD܂EG}娃w@TZFl(m$&crΝ  ' zv8xGӤ|I> 7D~>)Ƶ{qLN2W;(>m<HbTnS l=MMqRI\߿SЙLn.@[ ܈6ݯOyOHG ߙ"/l.у;ny1'73H(Vܧj#X=Hș!Jj-a4owfGU 1<Tׂ&O3{r꽠ڑ!{ͯzPҫvM$u5Im]<{? R ~ko촃@X|/Q"b\+Dx(F}BHZ!NveVS׶}78-׫b^-Т5sT~=c|{t(mIv4̓GM2;Κ*e}~}' .cl"!7!.Rfi6\ɾv]y(<zUmazt?'&CU@J$xlpƵ⠤0]p:-OsV턡 YQ" Yu86<=r$b'@_'7dMh]?av !nmI)O``71w#CyՋ4 4>1.uē9  (2eĠgrrCQ\SP"G9Rq%K>4aQ$7uMyy=H]0cbX҉:)d/싲]B KHox _ f8ˎ{iaN8+)CR҂D|Ps|"$<'~5p^>?fnĭo7߈ ğ2$|JHnCA_{CY@`kB Qj{A/<_.ioz56ާŧHN&Fa \G3m-Oi`EKA>ZPI1M.):m"F\SD֒OiGoA >{T>3Vg;o Dvmj2e"Wf! 84#[- p~ Mzh}kT"1 a.Awuzi Ed*|,X~:ta$X4$*K|IC$|\|wzK >py 31mh;by i@<ꁉO>^e54xV S@Hj>(lW9n֒OiP21b;Ql4^Q>hekPr=3ʺcwyXMox/l+-4QZ׬~xw}NWP7ַ>yy(`1&輌a"_Op)R|w~wH}zad dwx%sݐZt҆uhTqbD' tRɍ|G0n2q l29d:bvWs} T5GCT Ih-fW P9oG\r#v8`}> %2Oa}PiPQ\L 톡]2E`r=VK^8i4# 9{snorз 0hR!ލ*tqK p|5(1 (o q^"`?b7ɾwW3K^ҁ><`m!u筪FIς1}>|<KC+if!+"U"u3nҦ(,:/3Va(P(M9)8׀L<d]Ǵ݋XP9Q%,!9FK4; }M6,1$?b@}.9Z3I9TPL2G8gާپ!ok]|1Wekpc- >r[Jx{CnƏGGq>4OgHb9'Lxl| jЮ3]1R|rNc;g q7v?ဗ GX?ꨩ:_ON&eƮ~N8$ u޺CLO?e W.J3N5dq>XONMR&VNyl>K)t Є2w} IU#ߢQc1V#xvpBdFLX#.3VTa!sr3_Ӣɹmr[+o 9 Ӆjd2^nQ,z|Q;x-Vd7jP;<9&vk7T)- Vn۵Du腑5 4[h[Uc@QHWJ>![쬦i&,wh>i]fwjPx+nw `A! |.M@1s ~wa#} ͽe_ds;h}orhEZg}}gHz5(ٮ툑<.9i{RS));j́==.iJEZDK;jV+*쒆*;LuI"J5SfwUlNG5`#f̿SY݅8cR% -F hϓp5mp-'S!]Xr= H#"MKр?k7GYԄHJ \5mq4Xp,h};N 6v_S~0Yrӳlw>x舔E2r"*ٯO`|ϩH 74ۀl+b~i dXcc?@op67?# ȦpĚQ"VB|Si\Mٶ<f PʫՔQvS x ?7Hu, . X%@.y~F􀠺Cfmf[=phO|?PX]2o mΜ?qr1[ \Nxa͠xES@k5ɠ:aY V>>kA?pHAmǏ+:H!eu1Gt]XWl R߽ytq;>힠oXRwR?>)7J&>6ss]zt?$Orޙͧ`-БiF9e i7@/.4Kf^ViO a.ܯ RaeY%s'j]pNn R_opy"DsML4 ZӗU/!F ;@ݭU>{P#˹Y&fb? w6d'(J] z4jMeï#zN'XHy[+*z@)!ͼ7n<OzNd3-' ̟.OOJ?NRMؔosK5&ekP@m;ƒS{b#[1Pre9dC5b#0{HFٯٔٱB D>IՆڈ_ppؼ@ӼìA[z'E j#e2qdFuX%K4dfzhFtF,#"_ חb@zL|C>[y= 'Ɩ~9$vRgr`TQ0<tS=I~< lhJD쏯GZsܮ؟/)EV0iH-w~}bi K{"⇬ WmxY)l )n֒ւĪ tW4ա? k Ѫ*r?vG&#,)5:"YjbAWnyp{=/6A(c=$v&;\7Zݿ>{O/Um!X("8Rw|)#N,ut~]tvEfS&=> H#q%M$~\0ER_D۽z1>h&-|"'i"øLx>|0Hbo{O<Ri-jdJG 1,+Р6ꀚoQDr<wAHUa!P1.KB|ފxn öpdjN[sȞ} `|#%dd$D.f ,/R>fY;#~gg^MvB*C ]5= 4$@ɗSk?_ {(t^4B蟹BE<|V *4(!t.42u t8^'ӆǞtjCc ` ӎ,a@>$j]hPﱿ- ]̶֚"Ge϶TradD [µ2ޛ5kgM([ ^2IxiI>٤R //)v3R h}omC۶ሔw8u)͗|x l~H|ۚǰ2Syh53ȼ9d޸]mi:5תja7ķo[[ŵ+fM.&ÁMzV==ې6ڟo[/a;Cܰ! mS:\]I9v5qǔ8?. tW#g,|%TGhQєYP~<~4i|n;ҁNF:_L-6>\ as,MtaNUm͸N):aJ W Cc+ ] |u 218ȤM#B$EDqX{дΰ@-p?(ǦIO\3C#M]2_!)# ylx.a= D Mܕ!/ڥBnz/0A&k~8qχ4׏x}󼂖BBu Tfܧ!eww?m( q{RysH gA}w+<)C4H\*gz4DNB8-wws^n h9j"]*+ސC֒ҩ{ӸqИcuE Vh( ]dJYܭن5^ʕV]> MhS|iI2TfߍAMD{~V2^B& g/h>nS-=W͹:}eX,xQ8rKj24_HCM$cN2/;VcJ0!XQpPy2k½ 0p.B JNlؙ#IVhmi4'=:$h\*< ꮧg 5O{,Y/_*NtK_;=*޷Or!p}e;G%O868Gx6o_/zhWA@g;`,K(rt?HAѕ!_iv.. zͶsM/9Sˠy]CxL-Ҷ.9YM-@G$r#tTlzcͰY 51bQ=(5CRC@08*a286L7WܾZuƽj.Mp4;v~W-v})Pg" OLH98-Ȑɚ2=r8_Ã{+Z~kc 𴝽t ;[?@Ʒӓ"68Q;Vx :Q燐i fϲ/zVo ,Z~! AoWJ*tޟd1눔M# v~xJ&mo䨸c|T27>A,wIf1.6*d6f6?"BY$PQj-)M64bXQB%Ь *JHA:6TfNsJ t{MpϥK  #AGeg պM LK.'ҼzEH_2NJ|GMB Jc j%i&T+v|{L!)bc1*o qgxSbPX3Ov$'.kfDJuȇ>=kWD/:pF"U>$M o6>l,$5|rwЬ9<8dMiP{nYf^PʴU?3sVQK?/+v7i%\n>׊; df:Ǐ13p}D)|+op]O?MAjߒWz >+V($]<|Z RtX w/ ڮAy,74֦g=Lt ؑICjFBFJͷ9]?n]j>ӕ}ӕb'!t߅ %T4wuP7vTFP5ktuFcCۉ 8c aJV4(΄5N*ٙ-tFdo9*|fn@jkcAϋA&U5%NN[Ӡ "%4H`}13 㸡YVds2xeB#/^'O2)MO"mp3iۓ(mZ)a,m_P B4`dIf,4 's?3 t xR hۗAID|u jWcm$.׹>˩!ʢ? xKrhsԸnǮ\o pz,ƯXg%K-ICNV^pMq:y`P~q;Xa|q r~ј—QCYhC㕶y(u'kH>B;*BMi|L?g.b4 yU]TjXj~hguFCGe5]8$6p?W5wL!H ^{f𚍙ӕG4ҏH#>GJU9Eqˍ4?#Mf$ :-;qZH5pϰ77R=iW|zP+Wʸ~!c1E&i@TcN吙1)nL, b3ȃlo7{ D@) hj8w55 1>TKF8-oۜ7T[XQL,<ӃtV.J & _ATrQ|;X.=$pHEJ&>73 $#C$& z47蛸x)/93͚tCn7[AcR4>s!Sb?x_> %W'?s^iie6uyHq^WHqݫ@ 5y껙ftbHyhw"ћ!4[uIFf  3 鐡M|Gb`E;Ȍyyd'!Y;u7;X7R&mIyD.?xmEmCg@}gyCOڴy}9kɵFC̣k 1Edc^U  +v6Oh6UKegɭ|NΗ[,+:>+OWw!쬭t:/oƿ/-l_6 "_[G8U偻!>Ľ@}Iiɭ !yrFJoCڼ)%k[U1f>\U{ ;= )MUR%KHI (eg7=NZNUqޤ5F|O4Z25:_``IF:fD'b(Ivؿ{Ղ%PQdRi-g<ٙqci~ !scMw. e;T?*",e+oj6u\axJԵ4z+_~^^f \E%ܓ-hQw[fqO쬛:Q4X-~YęKuP+i|< i!ױ{O O oA?vTrN5ݦTNh|Nd\ns:()ziZFYfuk47(X2F͏YsrY6l?%ɁR~JympGmM1gjk;PO@ 2b&;uNϟ oϝ`l~Gp.G" W/H;-R ( Sՙ&Yu;i}17uBpQ~<~mugz{q#1n?q?nл_?-X27AryTGy_:xŠhgfXztlU[;t2 ]<>WvJƷ;i\ OME1<-S3rʬS3XScyY'R2|3O ZNԂ_h2RL/gI*Nհ$R5Xk+5M%GzzBͯ@pHjc (YFGfDIΥl{"oOl  j ai[:˹"-z5? $2)uw=bu)f|CzZv1ȫm11#9O ]6}A@' sq-/~*Wr?ǐI|Msz f5͝Ң4JB˶xN!rIǦܲ CYFƔ&¸1zClkb|-scEɇV5_O)b'UX\Rφ;-'ekjVs*Pיhߘlr/>&;(Uv< +wG!gRаf.~t/6  4??)Qyb1yAYLS\"Eoǔ& rpv((^䟑6V#_4ZQ㺵VH}Y @‚ˑr~&P̜OqOA,Z d5']ohOh=Zq CrUoФ&YxlNz,c7?xꗏ'MHPh KrTWR.lxbHc+3kH|2(c7&YSFOBLɜbǁ\RuгïVuul\fhS6kHCJrλ{ucKQ5oW <^6N!U3mF>$(GrO6N,!mJG"!1K !p^EHum}`Őzvs-G×>sz9HpꔐH['C?Kٌ@&Ww;YcLaXɜe&BEu$ E@רe"Q"(j?p4Ft~K+<{00V]9vSZŤm@4a*SMP/`Fj@~krNБ NO(f;\s ;p c.6Pm5ȏhk\W5Dk+l;1`_X 0%q kHȊ?ŰFq&Sj1~^Z{%N60~&`rB;v%!Jc$WPYJ;?mPsH\iFni͍Eb:vkѨE_][ao%̗c/3Ep3mf`>~[i;`aYܖ-#%ቮsE&➒_ uJsuY.<(vl\6<R̄[k$tYͶdPkap;8yip$I|z%\/.1 i;oH!*Ҷ|ܝ7S.|n~خ\qym][аosr~}ҳ%w?RMHsPH9?NiQ#糸0A7@YƬ}23էTS%@r1^mWw#N(qBW9\r}k$,*Q_u͐sBcWJ|02"~}nUnAp]osXd.AۣfB\ڕsSG-prȰg-ugH̷kȂ҃@w{kT٭x_7x,o`wDFS4 6IIL+0Rǥqx<%B$&ifQ 턡ZgQ;Ȑؖ=.V50Ҽ,Ը(@#)44es:x+l&dkTn5gotƤ7c_snS`Ut0'_4?A󄠬uwRBAO{+_~ ,Niibb`$0sp%lp埯f _HVg]R g:!NruzP?&fF|R`d:iiH)%"ňn:#W4jb[+ .ʸN)l=ٰI|Ŏ Vر\90!Iӹ#CO)C tn \v!}?P}K9{zv6d3@JQwFpT"};zppTj}Ip#Ìq!o5; ~$쨐$;hQH>#&]Oy/Jeݣ8]e?F~t`)7Y}M79yI4%r[ibDFjC(98g#w%3Vpd",阡 |W43ͱf45s :&'=GO6BO.x{%@tan,!pD\SFĆэA#Tˮ3>~>":(0xw WV IE'9691N*FWnğ(+9^ Mv:%Ɵ97~g~}&~@nK՟!mvr[uDH%RAƛ%V{6o_ťG>c ƌKţţp cHc~q<CLh gFss9['0/c3!f˸be.8xdBIEVL/d$fcu/Յofo > sRI~n϶DS=8S&';\<2)LSV9x|{hrbd}S o_Z~Yצ~V45Se(}/ϔLב?4lES 4Lqib{:$!yi\BUx|T6bi~w&XDS I'q>Ŀ}G. )+scpmWȎ}oWbT | g'"5ݝ(߄~^AܺSF⋮h2KH7C_ )RDEOݙǪo*UWti2 q<(v y |G|m I@N{Oπ@-Zh|8ʄ[2E;|wۼ8<*95\h TZצ]z?'֡qW,dUAJ|$u޷iw=RgoSs-oDI9+2y䀔LSoFz .stد#R<^")]4FJo-!r`(DYci1/qאA4a L:&lWcCAⶼRͯ);ǺI;u [sk*,~8uLULgA 1Oz%;l\. [X5kb}8\ZtsWh\vAH.vI;h '+JXQa n>wʷ)G'C3@rACKwS@nkߓFAuz,L$X9='F =Y FjrglK, \ph ʷ;-Nua! G`B1Fڊy&kvn ;\P<]o17,nßs%!EMKȕ76ݴa@35zrؼ$Á}}Lv2e]=^% ˸6jWsuSa qrWWu(zZl*\bSASֹ;+9uWFכ<gyQ)$z0%$q7Hvo5f |gF 1Pݣi eNO v'8$XȴBT:Hɔ0RKH^&Xb1K}bhWeF8/C[lF!l KV@(آp i(B> eK WA7k|A̔*_UW&0uM-}'9W[ȚN2;'8*@I.ߚquwX4`CԧpDu{=%o 8!Bˢjq"B_6VȬj=11?𔱐pGyP*|O֨!ۿd jsonuV[SH]פvCJɘ C"!6%S-hn;%|SLd[͖# jaSRryO&!dd.0ecaßTaa#W_LRMY3A%%?)I9 'zC#lOLV$x Br$$1;@bAa|YjCn.HiAkt<*`s<rTF+-湁|c&f8j^@n廢C &0.0v1NZ:EQx #;ՂSYd[ХEcO>6! GiѼ^N@='ǗyAuk>L?vviO}GfdE Å1^m1ht=T7hZjË]|t&+E`m2`%T' 7r0R!]$"!7!.Rn/6l=/xR+/?y6?D^9pTk, lRw|R8OG$LUW<ԜCB`@S,"ϣ0|JR~@2&ݾ釗.%A9ݫ=+3|49lԣD Y^ubv_uhlV-8Sm 4b]&_Tqw:,PЇfϑA;%ЕN%.?)=8` X˯KS r?>)3•;!9|ΛEK" ‘نBʎ֪?_6;Wfo,ґۼiN-$a>GmyISM/ݑe`0\+h~101k*$3ʹs) hD3v"~BoHXh-gElkVd=^E]PE-nPx˛5$_r825t`/UɯՇRr=T1Pq⋱x #?E1RzW{ ]k  W| ɇ)U$m4h>/Bj>.A7ܙ]~OF3Ԅ›dz=޷<8A2Y? '7J#Dh]4E~#d_&Иc'Iw5cHϣ&p =xχ#)sZEY*7C 筱}AhjpZRnye4>;r,-l +)Cp< hpqcgCWUwAhD Ѡsﰍ__8pчt;I'!RU*z4MtNrgAMɽ$تpGm/q8J]񜠃\@] P2d4@+Tf,q~F4$Bfi[:s9N>Z!3o9Yo2m41S(quY!oRPy<⦸fsW͖'؂ iS\AZ<߿ifDēHIY9/8) a3M[k=\:G$6o #k.33h̘vV71E9ݳDO&]а#χv9tҳMCm`ȜT͆%.K!UNNx# ZkW/jwdFSO fwtfN<Ҕ;s*"oaZG몀~X4-;wH!~EbD]<76~G~}&AGN|2ۚ '$;oXб= @ꕝjWsncoK_?洧~?|j<ݟH; &ihV>4<KbDE9,s;b-IPbN{r[/0𐾭ȃyR k:ȨL5fXڛ{EHw5Mizibfg݀rxi'"m^4Re"Yqbk=` h|=̿-|Yyփ&a;6_@G75qiӳ`!'=[97P84.&(+7OJ0k,26f70f"e`鴧[B%o#| P)(O [K %'[ӝmb rWP % S }NYBv]!P'ؚOoE5]/,T(]j,5O%ԉ?BԍtFPi]k\HHr9_!½!Yv׎'A:ӦY+en)6T,TKvKV/K&O4nsFFRdsۅJsLZŢ A=[ahֱ8@̼cI2dKrYo,.klxi0}cxrm%mX{e_@sP@SIqQ}b,Lmxi2uAMмjVÜh.dj| e 2Zf~Bb7A!g P ufSٿlUKUԑ;:.YCa'+;"%א88iVh m·O F:ߙ^%MGaHD|VgRsfY'\|2ӏp2d('ut3-^(%eHEҿP|aϯ.!cMɣ&U~pG5AiW^Ì;Bdcx/9\4w V4 ܚv|f@}mC|>Ύ)JE#89ۓ{oTˠ_/. :\SBjA=AjQxP;=  ;7䃪/AIkdC4K>3S|wz|P)\KBA~(Cs|"='hl#|O\쿯h8.UVMĹ@j /uxK>ƾY;]ʸz+hzޣykefIs}Lf|c.ox/l+ `h ._+\z>k~;m[p{wy J?FCvqJ 3Wĭ"|*"_!3Xy!qhuKA򎵗] 5\0l7f(vo{oqύOXt_ʹ(鄞r6 E&t?KF4~l#7.H{ U.cB~M3_TE &<feC2͛4e{6L\Ύ3c˗:=ڮ]T*e@SBM$@Cah\%|Lfٯ8_nL0 o'>(,gtYoA {nrmC ]KΗEG{D>#k<씭 q]>-Oz- n~>*tnϔ+{t(ի$H"Z.oͿ&hz?)$5ڝM $ SHҷCF*XEřMf-MP&4y ̔0VNtdb.A) BW\qYBV?r.2׭F>EPVX$wOxE W仫9 [u!>ӱ I/:C[X{a]-*1eʠجl`!u)[>nRYi,|#UΧX:ZjDi?Ej|©; # h̎|N0~'\:9 \&3.6m4E.K(^k3AreWA]~=UoExTNKjh,Lfٯ8_@.5<[ yFɽ|C{PJ` R!uTzd»B#<oW> '\Wc$A } :~ttZd ^}!];n]|+]/&BυL5@onRѸ$@(M,Pi\X-ƒ=FICoh-@HcaQLca)G]"7؍7Ѥ 4$'i%6.&"ی.n~񿁺Cf[=6]]"S*mj3$&Up7h䂮ƿRgOƅlJ?YSr=O':qI ڴpˮ@|5Sy aIh )G'CJ==?5_{_OW{Ӛ>; rO49+__)9"\[: 巿I@uG:K6ĢJ{ܴS6ᘦÄU%[b&T;KWSi G=kM]8siޠjv⧥o@YTެlyGO"aRkwԝ 10X;. HyB|Տ$-Xn5"KySixX2}K{^.: PutMH;d(C uKJ+gn ? ^%shZFy&ńGxA 4}>;}7bW sYB V4%Rsurq=R+" ݳ_>3o} Wx|n9RZ@z53BC'j}=[u\ߪϧd^7Al]A#|+88?ֲ|p]'K@Y9V'MIɍT4RU>0T)mޘ 9C;dh,߳pJ3!rh׌͊~S}<(H:h콀l5˶v2 2-2HJSm <" &;%b+ k9x̡3)Md=ED_vJA O°!e)+@Acoqi~o[9bЯ %X}]Tz.l}E#$88.쯧rи4~;xs-sX*O=3Z+V!)޶(;ks\nbQ֒6|Uuz('MG2b geh&+65M~Br'Hr̤I;"E>G^ lj[a式$G=\} *5jf\qɃv'd[?4j8ė+"P$y/2ݵ9B@k8t/'6:챧^/t YPV|y&WQ _߿P.i\AbHdu{\!3fϷ|Ǣpfiǎp$R+ys".{,H1fR1Iz1B3a)v2EbJd>̲qR0 arb+a|>,R+I珍pbK/"%M/`eqݐw }l^ z, ;gC,\d\4~Z 'Ik5ƥI QewIJϵ4lf.|W,U1Y1G:oYf -a'3HVp.YQxi dÖjqAlM7s=1y GoqգwW ''y]~ ˸vUe@8g7\.7 ( D';;)Xј'7U[,1CBpl~[کQ''Vku$>~;pMdѵW]{kZcCT ] v]QQwDZH@Z/wr$,uw~3ws $W^Qݐ)S?3hOn%if5>-߮٬̬doMKbH *Z5!-rS}DoygOjlYָę"c$0CfJB\dJ˞#h1.7# ^*Hf `JTMs7(G{l~<(ʸ@^U< uf1EWw}q v!w;> ~]v> xD vsj c8K>:'7ڕZC^O֎]7K"݄s#Еy0J&Gg>{m$3%g_1"ӖG3U>\7Hv2=W_7;S^]/̊..`X=ꇞfVC I}fAB/QG[IFv1*^q٤Lg_#4uwya?Gl{ w <7- XUDT6vTr+Ckê G;ueW¾%A1#AiO![L^ztb .qѪnpfpr!^*^&WpG;]aic{Aaʋ;Ca0a W(gܟxAN gKO^l;#sYHqTUցn|kxk{"О]}pN!:x\іb|34%,&9Rf^#27T{j۱e##{4X?pL"gZ;xx>2mʖ)[!4P|k30pZ` U#ĝ;L (s# Cg'K+|f+DJ>îׇN/D7>nGۃW;JߢUXss&K?x [k[~apҠM 9Sswbz,mP,(obv|T/D1۠hCr#ϙro~hxS_>6&3JdsDT`z \e.g8eJ7}PL{/2Y?q޹q2yXkh0O0jί؜PZ I6(&AP$--mPk F8N! $.tRc_U>mtC]͖!Y{+oGHKbq{_GR{X Yphngv0v&~6Þϔ{I=:1iґ|![xL咨b \R((b&qzB+Ξ>kI d={n]{_.UȦd2~8Bq@/XV :\q@ Pewa7,$P%*I” y[~ɇ3,޿y巜yM7NIoQb$/vHA uϞ9 .mc\lAD[,hp?;m~S0HQ\{1a< 묒gf]JYC<٢RcĤcf/ 8pg·Fo%lSo0>4$8'&= mυ)RPob9?Ym,D Fߗ l-@}w*wAzY"ÑJþf`/G7-zD˯X$w.HFqu{NDyi^oK: ?XcĒN ?^.\ kx|I$?P)k 3n]J4uI"fWR_PDHۼxa)dt=GlmbQ$h]3_Y)"M0'/Sb9[&^ {[.R!Ȍ3+hs"+MĻF9}P!5pFl*Q3oB_jՎ$_Pc$bn5yQ F l^N o.wC;8sm/mŒ C?.o!7AHϤ(qEʁ>{p,r.M3]I }C^ӗ9Εru~IJkG@b|צ.Vג-:NGfVt6࿣ؤ xEFq1 Ƿ/ iր1y0Rb Fy6b)&*f`="(l{BԸ\5B%"ƨҏ8̯ؼC(N=lwZL}gÒX jg"/~. 9+Ĕ9`NhNsB O;J(lO%b?ɵ )\h+7Nh;2h9sɞY3ba4EVt+d&:osY~޾&>"-Ī+)bIv5FF1VXìLY +HK7 )ږ(o(q"We.Nq Zmean&'vo zq\3)VjHbv/+ܱ|?b%%30v^"eJR+;o@!VNv'>xMH>2KAsÉcAhf?g1#Kum?UW0cSZj?RY,ȘN H!7 75I쌁%2>r{܊-pg26aFf19vFmbND$w˟w^) <1n(c6luK8M_(>O{-'x.~#]ܫ~ yG=0RGR8Dt=Dks1x@@{~xqan<('6)j.TlW DIQ { c~<4T|w)Y(gvHy/@[ߤRASyg̬LXpWL7dYp-S5琼txvMlA35јoaxlpp7g5 p2L0)L2^Fy;?-c4"FyВ'l?^)~R'.5Nt?6?g~yvL 4OV7GfV,UR-mtGq'6޾ lD]IKjK~ך[h^d~@uvƛD"쳜2ԷhhROSB$'X/f g{TTsPNSI8.s p1L=fzoѱdƽZ Maw_\qcGåڴq?fM[xPFP1*nenr>o ř@*c<&?>y9o!u#9Hy᳐\xb\dH_cM!󌃴Y#+v8Ԃ!vŒ"$$sԾuF~'wi3I~2߹}}flldF#)3JRneK1KJ1Lg1K ̎~EG9KI[pb^VD=uucc$(ًY׸:߰$t6o!D|t*4I9h$)I I~?ùm)Q˷/Y(H! 7BVZ])3fg=fIleF#q>L v<|ȍNP#~:D ~gVhT)Pc86| 6#%O<-Ldн#)LY8>%'<>XF=nU-'Nݔov+p Rpƕ&؄Aڑ'ͪ?l ;t;ff]Ig|+OO fR82b̧BPJ/Lw~ ~w6ς蟌TmZҌ'Z-5h ƓREe. aV^8(+]w<- >["7W'pui}E~Ce]69/x6Z֟/@\+2 swz}lYH邉2 Y }wm SY$*iJ ՚C1;YK7H$ԍ Lw|",@”ήv;άfS(lfj[2"Ŀ؞xL3(<A|ޜpDmI2#8 VC)m8gSQnE6pJƸAi+_C Ҍ Cq&1a'} gc%'Ĕm[T,1| -$oϮ3oԺwHYDXSDIbIѵOFPi&&zCVYLPK3cF1B|G]{:\BsBNz=bsb/ߟ{hme7 ٪ ņR1 n+W}?ꘈfbA߃ wN>g]݆/.=̓d &9|" 7Ey PN$w~-ˁј~ A2gb6)j O)Z:Is9uOw|:hIV sk;w8ZC+0Q%33u器_֑:i&Ha 63ʉ5M|;X1䁔Sdu,wZTRc(dzըeD *%?6 >ܛ_Ct}vȅz"I.[f_5i \48 _erpMqv\H.Ӎh/.֣ĝ so][m??|X9\"(὚xBMhIr+>Lz.UIH.Y?)(?8G!JiIЖa(9 h)À ݨIRPipfC(|̠eN8Ÿlzx^U▔]_8 fN |,TD3! ɡ6ܺ%~5{ŕ#@yXEb{m8.7wDcFQ*}b;!mbJ9G9'6IQڈ2NiQq>Gͺ) ꫲOB$!diVšg!=ۉMCzK﹡#?kH"yWz%=?1gR )`WQiwa2% `Ds3QQ3C=)*^[ث^ DW!\8Qef>e_Us%5 γ,v-\p(z2ȏ iJ$Da0>[]c-f?  iUd ZD^E(zYɫ*m.!x,ܗ뽊X19yZ‡ &) ezv̮ؾ."[^@{qAÜ7OAy'BޫHK< ŀWẢl]#H_ey'/TP<)(w{7L9Y_⑂?/T@W_DEE\~_J<[^q2%߿{`TPɿd+:KPDpXγ}UW@XTP癟) P0Tx,A-$^KVIo_z{f 4L< :<PEϿSA}Rt?bplMDi^9if&* 7[)&Y0 =}=B(33e$lLE3LF9s2-U Gp4'ZD9Vʷ*s9elS*vDž ƿZ8XW^qބHE]70X O}Xׯ;+!*V&P G@7J1UTp%v"*'oŠʶVۯA> ^.7y Ŏ[@S7ln2Ak{xYڸr(Q(WOv'B'] Pf>Ąh,g>|le7y`ϿHADA BH&FhǛC&=uNxܰ W6#A0ngGM\v"ume^&3Gm0#1Kteu3wN ?/>?k !A;~L\(+-N$oy ,g01y?ԈAeOYA;]V6z x8̧[HҌ-t.&K6*fdo@޷P"cqVt=oyle&Q~۹%%a W\"4Q˽oh;R1?mFؾrζ蒆ru78nfDk#o;]\LٸpܴD%-Hn$crwc(o12zlrng'hsi?vd1 iuڏTb|hFx 5I Jd*Ayc)'6bRe D+v~RN#yb_-\XlӫROJpJ^%Jjc1KU}c !yUy:_E9?m_е+&Db5oO %8o= u?:iq+xrB-_L4~ůDy 1Ȼ$?f.5_ w$ռ&RNh"hgmtТ4O&:UoWPߌbiGl;Ra\߾fa;d΢lG<[Ʊ(ĦySBLp.qX'!K+!9ob'6vxgOP)Ѯq?{yw/(m+( t "]tWNl"/a@dg> |~DvjM{e'M˳$ĚeHTg%~+w O:_ l= Fz= tW^;hfM`fVtu.d<ϒi_cJ1`?~-WԮhs/jGy7@9 /lgyyl~RY+n2&&mnU[6d\UmOuk=²O'""g?Dصʴ%S.>Lڱ8V{=?AY28Q~W׹:l<Ө~_şsd2,ޣCD_;H N؂plV]I]؁0ꊺmnYJ/9cы/>MS^z/(62IC()gykP*du!Ppݔ>ͣy5kGא`YC#!V=jCڥ}WXЎQ=߮27㽁73~~C&o`l79g>% LCfbB .bݖE '$@_ g(b4`+H,5g̣8C6+?lfN誰"vgN؄*労- AgLsb%4T2^ByL9e[n(W484G3P];) h=ku 1+~*%&ͼ\<<6[DHC (ml7ݙG0FeY>>3jb$[[V0٭G0=xH%GZX UHRA)@J96= ʉ++7_ż '@t?D_# 1{l(xm_ZwP] y,)|QZA X٣(?2_X cOl{ABwmS9FH9#2R[pj7hSksDhl{.hιƠ?zԎT ʳ Q) _Fx;jTeF9 ʉ)&ym^TVs ~ٸc&2o>a#)[wK@^ى;A\%lx#qfWx2vz^KwP{<4VP; ZP2]>IqsHQ?l<{%߇Ú\C^o]7pNZAIԅVImhIx,u4ʵy4]feTQc?Bu =k<Đ+ ︔4gd_h=hwv3hoJt]ly%[@W|Es (&w̉hYO/龼y)fJTaSBOf(3O[!1ɝJ\Iד\=cZ_86d AFἉHE KP8/S. EWOh1ɗ k6~iqYRn%XZ?.2|@wMAkqL隷G" 1ۑ"%/##] 8߀Ҷ#@(ڏNَle8[1I3 C]1m"R^*sY*zYDqRr6$`hXr4GpPZzyD!pێH$U؎)[uP_pj$lr߸퐂LC %_AZ+k$48`G̬:|߬0)HYo^ i\h#dzR4aՄLv5*"f Ĩ-S >/)8h/!c!2$IԀ'](<.JvTəCӍs:a&4`(]yQ%P0c,=8'=&j>ss>Z7%njb'8xݙ[ V kBMro~pFqGKVx.^5$;|XHÉ@Ϟm-ڂyfV,̇ȝ8bk5JxD%C;Fplֿ2JquGf89oecjf22#x68'it mu&D UoJHF/B1]?T傚4Eu&٪$BrmXFMD^3Y 8 |/38j_l"㟢<<,"F~gD h >X04_u>X^Σ6k.줱Vx2#}B*ɛ%'Yo_j臖`xIn!x@'#Ge扼XQ?b1Si-mn [a4B6wJߦ lqf^1 n9~6UYˌ.VNM{Wd-/$069 ] w͝~q U6j ɠݥq53+r#i~"̓| 56-DnR`<^(vij$i'1r}fL+DK}@DG|9lyʞWQR6-F*{= IzP+omP0.A.dh,#6pD=`iApay:_#0蟭&',5K|aľ!O., jO)"{G8Z  #ό KDqm<,RT7c_&}؈6-T> (ϟ}3( @"/{.ܺbt^1Ft|&ij}gV.Dͺz.pvJ>?P;yH$.AnrV$T>kZ.d VDm{=!'VE&9;L+gϿ*;*xT^?ł6% '^|hB ')GZyeE1{N Blnkba?AQ5}J=kA>m@Pf!ݩwD_f~rlv~pܫS^6w~Ga 3.%*%Q Qw0 ɱ$7ZHK#U5ޟ0#!IQūΐּ mHUڀEu~oIJLm㗾QFL_*IDngph FK# 8pD6,g<>aydwM SZYMH@3"=EpmX~ #Ub\\]ZkĆ,q/Bdu^PMW)}{ zKM<9p-ƻk\dՎ/Fj,X79Cc! "~@ FpM qẁNLc@,\GpRp7H{cd\h Zff_?ޝa5}fA3Bޱ.>UGq!t+{~߯ N޽B7aY [ߺQX?;nѭ#mʖ)[1{?ϓ; NĞ8+ߜ(;J>p(^}ߔ7?9 D)\H^&/^6x=xz}8ˍ!py{ϸhb]ZO\j|q?|p(Xw$ɽ(-$K$XXIu?)0ǻ[uo:r0h~ 'hL:vcN nxf̊2O31jLwڏ}FH㢥%c"ɦd$WfahSbTĪȌʌ}e<ہy d`BMK 4DqX+pM%4,r2(wg(P4iz)Dٶɣs31 5ɵf;U<|o\9*d/eyʅƯ,=[X^Ix,V KAuuwGPkPGxiEHwp\@h<#m|ɠYMЎ"73w1ORDK(z?mb)ե b'w[IA)̣ lu@O1OT0բcJY%[*r㒌_ض$lp"M QQj*s}*8Л)fqJ]vw/wgޛ8YJ.BzrpϘ26(!mgFrIXe;s'1tً/29h{PyYfV,ߕ[ߞGjf:d)y҉o6zNZ;+"㱳5E%h#Q0̲~\Rw&Y&E\L+ڐp 7hv7~/40 KB+*Clz~K@+*5c~< 38%ȉ,Pq Aά%AK۬!~lv5MDn=8^j;`W*uu?=W'wsb RX^ia{&!p_#4#x ǩՅ:[Q9?ݪu KCj<4GOmڔ|%VÕR@n]djEoD|?_^Έ<{YFВ*MbgK+e>PMD28"X %7""RU* (/P?ąlegDTa{*~h]\@$ƮZ5(;]?~YxtC /9/뵡|Mߴ lB/>dI%;(ya3U*,Q^k#G&?Ԭɐ0Lh0k{c_݇5oW'*7zY s=m4#C`SKf#OK61kր ])➌{~љ1#/!3~)%uޤ}薾nŒx o*n R/H59QDC[: iU -4f:WXVr2\C8DW4&3z>/CBB ? 8k~|]5{!9H1R+f- χ|>th峻~fV,bQ(y耮 /(U"!R/tq!š򸅆a浚e~{FƤ,򠜰֞6FF"N jA ~2b݈ ۷qHkAYbmώ Vz0[1e2vu5yC#!z z2[pynޛ D<*߲8."ѧ< w Uˮ)-$V bT@ԥ'n@jv UBKr6|sNH-ٟ2BHGBHgw*Q{0hf!E!K#'Hd{'5IK!91&{@KYa>>B^[Y1:Yr|ץ6Ǧp0vTDN-|xW+]n2Y87^PϖWv9Zp7s|-DkGGM^uwz*\,pb3!Uϲ.pq篜G7Knt.{xhЛ懁Ex#xxr}`&ߒ(S:5~ԂS617u?imS'n&ŻOK#姁l3EιMxD[[#2>)d")&^!q^%N!e]FyE?7WDyMl&D 1B JLlIĔ) i#;~aHzI񊇾pT"B҉M⫕.©3) ȸ+˼K=.'KP4׺{'邴w !*&% Ѡ<**G+FEN.ziRg8H]uT Ţ_+{@=%m3bi7:IFꟌ´Td:2Qn0xTJ )2mp<#0vrB1ɐ 5I \A68nr5n`a@9;/U7Wf=fDx7v*V 8Np?Z;prx ){r2UEyWsLI9e]InA_&O E7" N@K5.9Xu/@Jh{tgo̬m7ZY(=n4ϖvgH6'ۅŀ\(vDK>1i ˒+ b$ĕM*jYj'ŕ͘yB⌽Z St4,y͋rT~ QEt6̼Ire!H1`|fKB6j qCTm3 ĕ?9/7)nl3Zͺl$+V3 AU~A[“!-XlfVPb[TPE:qiE `&3ۥ"EFb[xշ'R&a@ ˘ޫ׊3!Z+"O!>D%"UPQm(N6kT J嚃꧋@Ο F:兊ccU8/n^eIaB$(VGuC!W, {u*Rg`Ue\ RsU4v].w':k$hSlʑ=eȸ>qħ&6 yI`bj-!ZĚ쌍~߯h=bװDP&Ef!5kj,l Z9Y'D[M,6FbS^!kD߶mٯ4i_ ];(+|x189 ǔ\H-~JP]5ސ쒖uې:k>ݮRt׫?!GiǙY|nkN3R,xn·k@ N Ho@qJMZ/,' ƙXm~@Ϥc#3fc@=‹q ꮑ3q[ ʈ`ֱm=(tlKaj[l-6l3{Il$c- a^>0lm+y9gж =ha [lSt=O?5c#o߾&* 0a^t+4Gܖ 0GW1W0)9C-p P*Bwhj+Yu *4|*Vj[>()ȷ i"/{<͒yGt_ v߼ dM|~g , rj{ [?Q`;|)HdL)vOHFbk7Bl(v_pЁs#ve^s ̊$L ~pؒC~2,"r;'Жn%c)!cimsNfGr4όφKY 9d  N!!$lbZXm~J= ^'3gaK6 ħ҇/Lɐ$E#x0"7/pÓI$ET~f[٧߷Il, cÞaJ$E>yw`1ŤHJ3ƉCdȌ"G;tG8 (*m% +O;'k Q~T??%?5W?˶/ ~_A'!CXϏI|RMĤHJ N7dȌ";.R1XU8q3|z9e aƠ-A&-<7@op\.LPWYoW53+6)[G3G4|ٙ&O6 f?!lbe'.*f9IK %E22[ oŸ|H~CH* cW x>'q"[Wa{*~|ŃC N^Դ%=A7-µ(<\Z Kl RhF>v7]8`h{Z/Tzv Gv<Ɂa7@|,/(sv+E{IC@z ݿ~.e8=8Q7sL]i-ݽB{fv֋| 껊,'Uh#d\HK0"g>Q&; 0x=",Y-[xM|E\%u_L3!f%_ŕѠu@qi8 \?"/>@b+=Խַ dlZt";rO38XAO睾d`C@=} ˃[5{/T[mg/&+pFp3/YZe\Y|t H*iSʙRٴU!Z/+c:dS<7pj~Eq=މ)Þ̇3;x bi#_?\qǕG՗yyN, 뚘fK}qc܌eӤZ|v?h ΄Tn|Td2|1!?"Dʴ@, ΀tCgN7OH(u@bl? Imݬɕ0: n:gRq$uXfVP%#wd3ۧ͞G=P䥱hCjܕ{ KљŔihcK *CvT[qB_jՎ$_Pv ճ>9b uLwiY/GCr(C?| >Uf~Oky@R`׆v+-vy}]yV_'[fV,ߥG2%7.K->dY:@@qCG\jVSs~Wzy+"?'ZO&e[A>.ˌ2^4Pc,;r>c QJ OqX_k @ea3Ptri4(xh Ư &:,kX-t%C|W_$\~yy ԣM]aEy|`j^$̎&C+Gʏ(ShRs I~k!Mq)Pn}:CA8̬O|%)^!qI< :߾&C6@$xl^+Ɍt"psDfY.ʌ30{#c[^9_<~aÅBNb+{QuTJ% | Sw'Azɠl# vuW9 :[;j `ݫ#z~z> ~[ Yǿh_AGLx+//ַB~gI/f?Qj1;%p2SBHn9IA願T"rb1WKB2 I|umJWm=sf.RukŲD>'lnOw9,&9S{^y%.gFsBо# UJkLf>Uå \ lJ9\*R~f>Js> v% KZ#$Q9y=< /[9#hq zHArǓԷdb.jTH^/尝~m2@H̅HF>tpK{4 WdFqZ#5y(N_ cb!Obe,W jT}6W;vygcޝ)'ν rG2P2\-3_B@HYY¡-\]!2IOP p8N,gx/y"UNݶvP8$/5uXtfVt߂Sʸ8#jK#~1Рp<^(v@KOܮƨjỎ3ʌ[,?%3BdrH[D4Em$/o-/P-_#( 1ze ۗe3_('rկy~v<5F_ku;e [qD8FyxC"2%ʰ*8 1Etm7/=5hڲl@A3[dfV,Lo#b_Fbٌ1xj@#ba't{R5eϖ5Ŀra-l#d+2/P,0J.p56kߺrf.bY`CmF /V| .iv2g1{iK'[֮/#B/b7]e_F)V ZeR6]o]eeTN߮Xy$␯AKEબxSE7O%h6f9ߝf3ybd/'- _\/=D G$j8/>'o!G*L _lu , ͇pqc;YA} ѷWP;-HqMH\Qag&hGgF-5I *0PZ}}2;`37)*ӀFәQAmBAx|C(^.LC4;]=Y+"G/PPY gı RP6K o: ݡe!:B'+PPU6UG"maО-\豣x%rq;,ڰ, 㻬CFeb&ʇJ8.&c~zC JWeob@ZK>.: ?GVk4D{|=rv;l^sQ?z(DowB̼?Kqܜ z }7GZLG '.Q$Xo$ʕO ( gђpݾ!.0Ō}B³>u8<4\W{V,րx "os>̊:alI ̬~2qQ覸t+b0̀jzE$ 0٭Xc߳Xo!cvCp8X 8Ne./\zzU'|3QPu=0E?퐵D'PD_`VW#N<_!_@1RƿZ8]M ĉ g0B|Krcz:C"kJQZY?=]]7=噦d&Q^QjRYA}W#SJKm%"#C)do,V1} f('"5N'H6+Gdkl4V"B#9ڦEf$(/{hSUf$/`mRW(6.Aa;Bigm odF!m*C[< 1`1@bH~&TA(! ϟwi$Q{<=Gba$πB6C#9yh#d7t`eKM|>[X8%T;>3 YrS2̇5Pnd_ i(^OC EcsЕ~UTƸs+ m:M'?c$/G[((jC$o^F|G"_qMKA$h3Dt79H>{G;SP-I:nx)'63br"'~fdO3B5 R0iG("}ҌGUg!՚ @>BI j\eUIҌhH酂9X4)_\z~ *8PhX -VH("ܒёPS H e' sp+!ӗASo9x24u"]20ۺSP(oNO)*v(ŀd## 0e# +\)*,қYADn;"ڀ'Q$3Lh<6 ĸ!Ӣ ? eFohBvrLQKfgM.e,DeKlG4n`v>&Oz]a褺S+ؑ硉vqu\zEIbCpk0\Z+Ҷ#ѓQq ѷu(ёdLKBIPc~yuV}6quf$Hʄ@{3L%;DZ2IV!OF/¡n"dYڎn2Cͳ9 ʆeDOR?磺-e$KUo4#CJF% -QT؞ʼ/޷fܰ_w%/AU- N铻}OFl7#Pί)0tXt4\qXS%كtg'-bb 2gҌ4 ϝP޴$ܸ%Y&&Hqx֤[B?Y# [/2,mخ xѻ̬UbsrۊZoXͻ۸Pd7}OM7Eߵ'a$7sSnJ 0< pS-R&FWuF\_:h<9Pr 8`5A~]Kr+i'f3⚦aז`n~GO6{iQnvJ8^zyL1,5xP^2ͼ]u> &ϐV6bN)>+jNd ڣkBz39 [Tbd΂HFR.cHl~hBFe$B[M Fa8ck~`1a&TX"iXVuo.·Մu9o5'S"FB\[euhdNnZӒD_f V)-qѯ{5ꤊKx8VCr{K+FC)8|8[MJʁ|+!5Gn@YZGڛ ]7]얙ԿEP2,t!b9d%UGDцoΞt+)(w_Ț1MxqIeꊷ 8xʡG60#1qTTV%Վ}"g@|+M{Wlyfb=S ~AuĬA>Ɠ+sܬa~I)6OV |Qy{\<`߉a.Z&d8~3ebz 9O(۝z^KY{DNnBAŚjI pː:6g8V : ҳTrs tQ7/߮,T%B"H̎Dw927F QO7< G-˖T|Efaɱ$7bAAnä6 |ΙQT>(e#) 2)Re*QCZ`aI>n}WyKLzb46\rEh>4-hzZ·]R}## C%Vc9ZZԉ>.BOjf,S{$ʌo~v(˛f-VXQ2"%dyt[RjE'뀼_~(mRxcG7OGfהF75BC@om2Oy]5BrmbS30R$*'O IyHi'!XO>Nf<-k#0MC cׯ zwyǂ6\pH+;H' ; FL|<tUz%˿]AsYt_@gJ;" ŀG[3+zQtv)>~Dc1 i!eLY)31B[V ϝ=nqv"NFذѵ-?ŵn9ޯmrӗdW~Ei<3O{ %R΀rhǣ;@Dg.V(9垃\gʬG׶GwƥYL(_>NaB.۪z.) ( X&&!I2x(ϷxvzJ+ &Y>^w{lIˮĻޥ+ T)OM%:?I i/Hnp4kshw1)hnfA593+oeGRmG"!JFer^7e,lxA\2БmG%z*\EMIȴu^v6*Cu$JN,l&.~NLHcA4 z!PLIy=TwB-n"Rrv`612XҺJ5;{؇s0u"pUwjd~ mGd;z'w1Q9!mGVu >ڛHHWBh%Kؙ ҂o-hny,h ҫ̬X؎A.lmG[K6q>F&pWr;x e M )- xLcvNYV') n~X h f H,|j,5t~ų'' z66r vb0DߨfTRĮ+%ۅCg=}'.W{3Zr|eP^0mÖ<]՝[9e +Jh S_ "RsLlH+u h5:Mg^zdfE} ɸvRhb@j \U/ϲ綣~< Dt&Ei6t¸#f$_f~ggf)1i6dlj xTBGFx %2` tN6TqJf{#x͇IGQ txn Bhgx=BڦU?!G9'gʊ_T7hΚAa`1 aX*a A 4A*ᐾĥBAzPD \u)`p:3+HN]o(XN>#S9\ pы'vD q %p{ڟX`$K`t3fWl'9K(,3.؞s #FrH<g <9(Pfg3V^@SX pɣ+\GĖ\UB%б*HM8"E{!=yͺT)FL@L**k UB @r~JvzqE,ZI~hYhfŀ} #߀# Ѝ${ɮB%(d=>>>1y(WyX@%{:*h3o_z Weym@ t(.mXdQR=9-qrLp"kΒTA>\b{wq%Dկ]zHXWb}FK"m'ZFxnQeJ2Y>xp# 3K8/TV0oU!0(0An=_ '7ya$Ek:H$'H~4=d"/ZY1DAhygZ,Y-F| zdI*(YoNdWy.[rĩ<bL= ?C2%[WYrpag]rXGV<[j{Wz<[㠸lDO(T^~<0"Yj9kH\Ԏ^=Y5R^q+􊨱ނvl@ `|HW?uYwGV>]Ay:O*%d%`Y+?]Yc?C w;i{Yg dK2tS.QRSdN[fd4 ?0zH+p).=Э,j20ƒYp??S^S B'Cxa2' "co#ۊ5yFm1ge~P|PkWqⳝA˓M}Ai!w (` (vXb_ﶣȭqfq3\F@;8*T_ zmwݢ|7^=+1+> w=yo\@ڸސ>ARTʙl!ջF,j@zтCoݣZmφ ]){e?W̊埭6x>) Y/!^=ϿE^ކP6"6I32e](.g̟̒ble$kY03ph}^"2 )Pe.?+ }-9IQ|aŏ2 D D n뗲B!j2I1fr/:6 w#?}^hֻ*$u/a+^U Y]?H]~㧨{ 4[( מ"Tx*[1Pŀ8BAQ:-x[pCn$)ܣMH d1P,n̒-j BQ)9=֐d$aDo爯Lq9*rAhva[]o((0gUK{Ⱆ_sMIPH _\='HQ#{PPnmslCeM}]Ḻ6peۗ>-!C*m.KHWm P. bsJol$Q*G׫hsj6.T?Nia!$?Os߸4#t1`"'EM\v"H^@,mƁCA,RqL<ћ=b.iSg$c8IȜ>%?FYE:_,P.^i1|cq{ߎqHB*O# 4!mEBUg! ˹/57>HNףi >gGT3@Yu`ş&#\?;fc%Wf=:t)ҸiV ʅ$DK@ yv~&769̕}> b ϑn@W3 "]@[~|FyRz{ɐPpmZWGAz nt%}|:' |ʷe!@׊v|* ą=>b~x`x"ΈĈJFt2r9L+I爅4B@k2Z":R^(!;b)9m:*syHψjM{e o }E&wqB쇏޴Qg=ZD)gؾR?epxQVʮ!.[A;/ !;C$d~,2N?¤OpxZ\fHy~3mH]ic mlm ;Qϧy}@f~;3B,*!  8li] XI,c[.tH!)m&˦S2s7DIl5DgkZڪB28|DˡB*sy<~:#$?uIa,\dD/ M\ٴfDnO$m@z < nwk{A#z^B$'R/>"^ 9qɶs Uh5(y 7S; sD2~&A؞@#JgǘB#2 }b>ۙȩk^*eF ,H.+ Ub{1d[iNVC5Y}PA.p(Cv+H| 3L =ʬ}H(d_ ݳ (mMACy=>nruqfoF'xv;]ȝK7kiHMm<; Uc݆!MSڀd>]GJKzx[ʦC9iɃ q_>REI64jԸs;Sf52Hf9kƙdDbCA#*|_#^ŲD*QN)'7G5X1tǜ/d JʺP*&s+K򤊲/P_ۻ_!gMR!q_m,- d= ;MRcZ XOT|'oefˬY}HR\͐rvZ>#E0> >4t2"3~yJs֘D`ѦMKg ArY\aH̅ՁԦJߔP/PcX(ψy|e ۭ,\gXR wtRj83 /Rvpfg\#DFHDoc!7Uk9 jdoH4vԽhތFS&łuӚ݊+]Կ+^jlMڧjMo_T1C;EQSRm)ySٞ$R90YOj1ٖO$Sx$jM5{A1V?.7LƃZwCFho?x!Z7mŤmWd[Jxr3WW]P:QvO$[>;Z ?PުSjjvkV16¹еŤZMi}@[ӲsA;ě@flϿ^AYrg#q0ԏfLx:aq1C}M-)~[Ox!$ټV|L=[UXr)].)!Ne1؁ɯɘ/(yjU,1&O|?z_XaP,{J OrC_ӍhQw?L )o] 6f٫p,begeT///yA B&ldI>?]B|Q.$(?< <'L2V5K-I׆d;H2 sc&HwkKtRh?å廎\;Dr7-hi_7lb_D诲k͂r +c-lPlޝt/Q1]_1e#Qtt %f믩֣ĝ& S)uz7AITtI$מ=C;wM!6EkK(ɇÅ$~w !*&NTlê5ݳa)[~PkPG1?LoE˾!W僓!5%2!ͫVA{5,5^Y} ?,"lQ}&h'μxҭx\[xC5<{EfHKFeuA#=[ض 6QM-rUG犖&bTe8#1隣B+@|jʖGv Ӟ<ģAsz7]Xj|_y:B>Sˌջ3BAϼ[H>;@eyMB̅ n6DKfܸ\# h 8]+M>R׾V|O,lܮ}i GuHfrQC:i>ՁK(!!Mn!Jm׋5=B nIm@rt YY yhDKD><";DL"R ߾&Gkc_T,<)vt+)DnWG.Xf(>Ɍ 3idFw6X 'iD~]ى;A|"hpPcwcƠK|}xn]7p(=|>k }.ϗ,6?~~]Ь )^KKYKB{9jj#gU#ßUN<l2X;Cyǥ§Vm;-t'dЭZ3p lIS-oCz3)%5QD*E@T"aH=!n' Vq/_~ ָ's3wN{+|thuGu`Уr㒢\o.7y kҫjVZlH?6?h܄ff-B**\_CBaG[FGQa3b/CG\ (RQgpO'N>^ dJ62Ux2DC/PZSF3g2_[djY} NECo5Rzֿ{J90j<̼?ժ;RfΣpQ&u;e}?A !;&E#|X%Ύ1ۓZM쟣^DƷ31Q Z~=ihS8h+ n̬mDmMY(8ZQq3 !H`(&MK);gz=ҋbg]C^%o4%eD ΏV"W*jm˨eJKƺ2^_Zpis~?BpTһ@̼}Ћģ N[egh_S`hNpuJ4^޻dSUxrx`&NhouPOve&9;5[:2H6rggALz47:) ҳ /$t=s/<̬XwA9y-}x75) Гl7 JX{ǔ.Э25'>ޱu[  2KTq(g([ ԭ"$J8Ne.i⑚UɘV@Z R @j" K22p?:P'~q@Fj H*JaEX([ kNc XGLoUuh NxŠ| ១l"x#EEd^ 4lot+*tS?FfGR&,ω)F qBDv-މLx}lal[ l"R);}^w_x(^4+Pf^j領\5bouΰW&sG%`_/8U"aʺjG]%'l "! (7(opc9A&79lVh.hvW{eIx-gU ?̹R'YA})2:Ol!TR@JݬmdN<u?5M m;Z:2‚Mqg#e=[:1EEtg>+<N c)Xxu4T}{I<(mA2Lʘ`iD[ݒƕ!'J! YdGKM, ;+Np)RDžrӌE-@'™a&1c~)h j y{HE!xC2оd+()ߩY|]g>C$E!TlGl5Mf*:7)/o-/Pm6(J A.8s@Lf޾WЕ^v"+c\Uc`V[rN>o! Bg7r% <}޿Z&_KكFx61x2b9ߚ"¼r8B쥐CK@j)8QЮz n"}"3Wpx~vbmrBO\T<kjSs2rrɧxvV Y'AA5Ysc\j<;+k-t+B6;ڃ8+G]'I"Od 6$]˖kGcDn ʃCEhk_\>T0>=#.nߺ+\Y]@:h!E맅5yC#!Pbfp:Ɠ Mɺ-M CyFSA -f?T.ï)p/}RH8}k !Ĕ}@7Q璻V JU$KiҜC8}͂_ Ah>3+|/6b KD7aП-\Xٶu{< ֢ xp*%Ѡb8[tI#N-FԭEK@=ꏃEHrg!I>7 eNjBwk~m [^ h~Z?3+~ȭMFVU1re)BJQ/.t|hVsW>ڭg'̆Ni̕N}Yq"3_JYҏ@4qϡJlBdfZiDch,!Փr!u5: \2\o I1K#Fc?!E蟭&Y'BHHG"c? ٓCsc!7XC*11!u"(. k@wU-^/߮1KeG3(RPR OF8.uu1`H   sfH>˶ݙۜI%)ŸDw t>B1d U|y҉8V]~BI *DBPDOFR28 ,ez* { !;a/]0TࡕG4OO€4!2miFiX[^KKCq)?~SҚ|Q&q_+ NXPu῅\- YݏoWP>'R&9YL#"bAi1I,u\'dV$,źSDEUmHZ[,<>*WP{<4VP4WYU䭫\-KWM"/>TN:^~^,l!@^l3n h'z}uNb%sW;$u|$N(hwv3hOڍ=u^23+ `Y?_FƞC1ŀE3бX'ٟnv~6D{$Ί|vX4W0xUJ KӠdQ>EØ~S .b*>\-ax] W\_#Y2-`N{EP',pK~lZ?q DٞoGXz+%}{:_|f]j#:I[:hQx>Ap`x?vK;lW&|_x>esG mTnK> a@W-9Bꠉ+3.3+oϕ"C ~Hb2YѸ)#C /&iGq P?Qu'(0Sj>fYVS9d'?p^=zxqDu<~STUWA#͗irJeبc1K\k&YQhP֔~io/ [=/NXO[WC[j^k+Ov>6|m=.wt\ptǜ}x8^% 7(W,Aջ/\WZ oˏ( w͇@N |\='AJA&=VS mׁWޕWoL9hI9N;wEfVPv Q|#*/\!e\ȏW||ކ'(E$`G'3J) I d@%H}1D],ucpvoBK>lѲmj (3uJT?c vDhVۥu;BV)eg=<8c%>v'9x3a YY{;;3ۙy/*[:~}x!+婇:\H|QB$' >AyC=TuV/(8 MڡxS׬ g>6PUb7טPTBuDU%pPU"{O }iKo:WMd\?u֩Bݲ>+$ͯĿ;H5 H(h'_}j7N7Ytm+iŸFspNjz>J@YTq)S'ӌ=?Ǖʀ y ?t'*pEPf* k9HR/ۍ&zstk6~(Tw ;1h8>WLb#~'רrlE\%׊%ªu{5y֋=OLB8!oo{CK]\.X!K\vˀn]ͪT -+|n7"R*9j"G-^٫\=N3Eaj{&U i=UUPeq3ƾ.FEi\Zh|_)8_zǎ|Gd6\ί6}47&ueQVLrHO}HLMr |TC]Q횣|W^ipńW0I6ZGNMLRԋje{]mF]\V>m _3Ge_>s  13ґ6/CWP^;J>'PQ 28"\{@>WOF>$c/) Taܥ_D>X~]/UR37Ccxn,Xx1ȍᰛ˪X.%M;?D5""i|#[5 {m}_̴ ^>k:O'n\Ʌ YH͓"I!s+`^m͂j)Ϗ+cșĂjf<ڠ,B$M ]PzWQlS\ŒMuxi7-lLG/=p$؟~܇qї_i]ؚdr10_Sa݃ᄑKSWpqG|RꎋqҢ?qsԬe?BN{7T^\Ynp \eݹjڦrp'z>cٖ1>f/(13$C8[<|c{&Y2-C{b$v// xz2Kb),E{'[;ʠPnz׎E;< ﵺm@mK ݝ%//bP gz珯tϘBSv9`cOﹲ//ń/Eu.ĭjLq]~uu\?ȸg{~,uO#h3Չp={ ־_PƐsH4|1 To4CH?^;4A`с0ˈ^ Pd72LQiX1%" 2A,+pp[ph䀘?{,?`cV5CFLfEsak$_Ua*ظoa'**m?E|#ipd`Ey(\ҿG!{g]tqÐ}mHFI&/ 5l h~|H}~Y1'B/RE)bfKmzQ+^/gcID&sR6h,Ioᴈw R+}x U!Ųd|#uNJ>2vDۂ=@sh=ː#Zгr[^GEG s >Wy$$U]贴4_,N|x1HFqz& !i}a tծO`y\U46Gthۣ[ȟQO/۶2`^lGE!Qʀϥ!XQ`$Gf`Y9S Z"59c}m2ni:UJz|ɰ^{» 5I(~*@T%RIW^?-VYa/}6PX{^A+l$/iQrmgN!6?<ۊ/mXsi>~y X;~6&5T䅲>YUlgo{&\NUz2eFo/xrx6+{~mBuGI/b5cx2RHVEŗrz,WTIZ`F5 *EB1AnuHnkƷ>@V_ 2gp4L=2jJYeH>hf}Vl<x}1! I|*KAh2_]WB1( ĭ5qEs\H-!Q{F9+wkf>dìJtFUO;W҉:i3D91GFѳeO{+y ;~pƽ]kZTֲ{-kidf!gMRqN X'ϓ†?L"%Gg59>#[ 薌Ʈ&iA%C[@1kd҈yWMݽ!l}_?УyDU>gl(U+&|IBĽ5ݳV3`Ҏ[3Y)}b21l%C8ؘ5ܚb|USz)t|Rֶjpmlx x@\?utF~8<4tKCu{ wɨgMՉDeE}!_l4㭸BlxYvI3"7Yx=N|S*GBgز2 v};bF#~az2x?=_3W`;A?S~n[kQFkO?8^<*J:~K> s\=sºUWdDFFmk$ƹ**řzpgW.H5~ \j}Uq3_P5Fi|qT]W{5ϑ>%X?֋޳-^90T8lqWbk>!)Xba^3mvJz~T"oW3%1Oerѐ(wM?qcm|܏p{1\raSE )1r'ٞO . ٧:ِْr-'pcͰ~t֌i l *"~jMW F%cc89}g(a>nEcj%}@+Ffl";HYϡfM=o6;(ڜ0 -g(Y0[0-hF4q=f̫jq[\?ϸ:R^K9u5U#',u$G3# DZ4' 3㚤S+2ԪYAHZOT8rW89E 5x{I Ao&&[vز#\xu1jBEir !A,!B_ bz+`qi6Er#1{Ԉ~fb`PjSfk}F%BW_HWCqN(@íFru%ǘv gdi88#3xkxhX$c묰KĔv񱋔8>!qܶ_t{^ԏ/KM\ސwחµ%S-ȴ? { =_[CrG +'R"6ֿI`dLb"E'hp#)cq\9)`X.EGH@WYGu(ofO4Y \ E"I}ڙ=ٺ} #4 Jdr"I3Q?"/T"b֬"VM qqA`$f)Dyȏ/[Ԣ\h 5[&K^==w[pu,%/k훝gNz`vM!{'+{_BllbGi_J8nɬ>;VxR1я5E;d'>2YʝFƏ|__=BTj^^8gMaݞG3:|t.~K kQiscWAݒ!߸h;u;u&~/%i|{:.+Ō?fWV-p˸UBvʁ7veg:Av߫ m=[ (pŅ[;0SȺfSFc9hG#xejf:xPK+;ޣe>b-\i7NV4GM}Fc*hvB֏ƈ{^QbMs rppqs|6`/<.&ΘpnP}j3J[VJL=S[-˭vʘ`?OЪG R܊1%!qSFMI^U[g[bTlOyNVS`_c}#^@j =>qTϖŃcI(Xrcwx?֋A?We]!w>/b0JxWP%@^H[5{Օ6 k2 M/K YL UQyZ*M [+SUq}Tv7 S|%6 VPL񭤘wZI¨BoXͶX~TL pzA5?+9Q~7*+ӛk_Ǒ M*m_pŮo;5fQ\F\V]+2a ȟ^ޜ؉;U5{Y*)!Xɦ>mĸ4`m8oȧ_8bS¯ {~7&phdž b]OdkoU{!啐?^0MߝCuGRuRzp!U8JWFqy$b}s#ɵ{a!6 ٖHQSHrD#i7 DuHrT,RjA>Yj=O1+ tI`s41QTzdo , CS{S95q\pp]1QA# |y }f> -}dGR/go8Ow7)'\pSRA4& ^K,2ژضmS|s)̀ٔU|b)8g Y$E~8)>?ŃSV`QբfYNvm;{CYt΂#/6H?P [HE?G! `*1(xn5)~Ҫxd!Xߏ= <aˢ7Jsb#qE(n㸱jwKkm VؗFʄKNpuъu>[>m-ϋ闗: 8< x7hd.OjmG"pMH}Y_X- 2>َ\pNRZ36I & qM:\æKJiPb L֏SQ֧-^I"m3-x1#8ڲ/~th`{5=Ҋ, j Udm 7, *KtC*$\p~xH"hԥ)G鐲cxC!,Qa_u\%_,˹}_,xp! jVc׏EjVE=EZ4"7 4!J1 KJs0Q@'h4ֺE(VQdg-{㵌vW{[~A Qz->u􉀵e{U.$$nGFi4B;_E5ƣQg· ߤi*qv3j'wC2ߵ]_ungˑ _,brkbJW.7uZ9U +Ţf Q/K@6sџU|ԖkISC\_" E"Q! yNt!D!X~}{>z Y^>jiGLt۷ztI` L?|>i'"`F\3,jꍯ!_ $޺&ukV,D s7L2N/i}c%?}k[+c=kumTuTbޒ=3}bkfx?և + t`Yu~YQ#t-1ڇB_,xxs_{ " ob/|dy]Y7N{XFܢ^*?\HD4{%SWS#0F/WFFzepYohxDS/44)>!Ռ:⦕UA8?")t0_qc{kݯnW6&_7T͚9/hn{9+^yh+a~Ğ%m&jn^M\nt_쿚Z).6xFZ :uyaSSWfR4[r~; ۦv*x(\WVG *4TWqٰW(BL$nQ}y(i?[x;Ȋf%tAs _g!C4-g>uU]!j/"-B !iBf[.ܒf;b_l ڔ< 8S{6?{ 5^x; ,4 -zAċ~1 /gT@!"EX _/-C*lʽFe_D 5|1sL %Č``}fJX9VxXbvEv0iL otz끶+h 7'y!k/-0+&e$e% ,"BqSOV~#8}Ft.p~}Dy>]V,cb]Wv48/s(y~!D{j;{4PW<2/y-s@jeGQ}IN*0H`XaCE<ߞ\y:c~X7Em8[֖/˶~8ͯ7  53cW_q&ە EU{Y{w[x{aw|}3 {u[u Y{iQl"<wRI;(;l2}XJ3M?/"kѿW++j;c|h[PVęl9Ɛ~vl~0C D!`M B`Lx2| 3Cg߂?9lN cɣ*3K++0rk`Ng KN?*^`U 42r-w=y6?KnØcފTvnu}r־M0\$.8GiWn~~m➾ \SNl崪zNCvY j={d&s|I z샧 y {o|=,]el]ϊS;4OяTM/i`{ OzoE[9ޕq:EbZ׳=iPT;u?$9S_?n;/;\2N8DIe[lG->jK W. لR& \!Cw=??|~EO$DHpϷw=Rbo8tZ/-;7Qq:E⭨k5ڝy z98ϯpynQb"o-wk/~|d5DAq`^GC ~@gCO `Ո7UYt$$VN~O#4Qf~_kl]z~UH&!e" WjF}E?0:᭨Z\'ۻ9q4\p6؇ajF;[+ّ\e98Wn{~>}؄jJ`[^K tLE5gEZ~8 a?,er0[>L+Bqg_>ߒqPJW?ۇF}0ί ^~E_[qZ9o>'q~!3"]TJ~<4xʍƴb^u]{v{..=Y_/zIE_^l-8Fy:&l\ѸG-j-o8:wJci~J_7 )+IUZ_@KSY}ltmJqPkT|9)ma<+ԿJOϧ7*Wz~|L sEui~{ga' Tƈu/CQOvzӤCIŸJy2dq(jCnYdXqؚqt~bS8?m!^D)G(H\ Np~hTl pp8[`8'a{8%a)sTX`7M|~$ h'U7>UH??=z:)Θ'SZ^l"A w68%c3;. & *>} ozqC2=$柬ťd6yO;p1_|Zbl>kX3d5ot)LߘV4qRmT4qÖQS}{mh_a|Dߌz2-_GAKZa=j1~v[ !61&[2揊t?>qh~5 ^O+Y]..upxdЙ;~THOo=^Տc_NlB~8t 9eo)>[xW:hg&SuPz45` o>󨇈7d[q}9XMⳳ2_wx:9gǸ%zt3nc{21{ܐ|' 韔XP<νƤn &XB8H,ž  78 bnrޙU2m D;c) oEۨ9:[M'FqRZA(6|РwO,3?7%uWq ^g{i^Y{i_8k5 Lt~V=G:&凝Oo[~OЈ_?r i?sk hU1ƭ3=eJev)c$^s,JY_o:~5uðZy MaW <^fe4=߾[Kl:C^==̪&]ūNԐ^vde3l)rf/yvƯ˵}(>QHY H]Em/k/za U~fbRl?=Z6EW'WsRQ~)PfuY 쿱r2ױ޳eŦڛ=EY1ҬK/8+΋WDJf|_)LB86"T'V-R ݗ;G}` 7qr_0?+XF-|+\blQpO`7xs d^?\`Bo{K>y>ɉ\F|!7Հxj)aS=5=OL\N&4n\/Jk2~ȿy~=Ac|øyZ4cU8j`;pl-rI-_яJGCY2Ϧ(瓌~)`,Q/@uVF*~)/aB"5:_L a;P;f~o_C\SBFox 6s`"uez]evi67OU\a 5;FHWk*oܳp; ,b՟?EqTkg'4H}3{)<O ׻/ޠΌvI,7>Oq|?%>xGPuw9О VrOD)O#}C)~[֓[/8| 7Fe3 rV3*gy/_ц|-.t qYftWXus^ގT}q==/W@3] >_]?=e5^BCc!aF\|7I=8?/4R< gßkQ89mw'=gH,؟ _VC&?.fe)2_6{[>̺¦n\xy̿%MN+mѷoaW si!ύaݜKf?g3F c3}BǙDaaWwmuݕ|sj-Jfxо>#`5j_|WYa' z=DZ- }ύp~U7V:$$_(zd-\]l|yd:Đ16)C y NۗK'8_5/pXH~(z`żǻIԿWC`c~לїw ^0_(/GCO4oXM!U\H$VAĂ#F!r$F"-n\fZE哽Wؿ *i AG:1؇[ZDi 8bu~.j8O=>IS{5(yjB?ovakͪ𗴄{K!Yjfo@2|5E\$T!eOq}ϛ_.P|-jLUhU#+& 67iLIglG݃^;`p`+T3?^+!| ߮]`wER< ǁÔ2z{ӷ`K@"ziȯW~C#4OwU-3]e{`fbs7gW7/k.yQ:=15U;j/cy~<FȊh߽'9z7?vU uNxy l&F j_׿ ]ظ!g6{'Հ 0%cLqUծr7>ײJ_W܇ޮ4S,+~;ʫw;Vr+DLٺz֮21nQ[_GלN]gW2Y x쬫l˚i3[Eׯ(3eM"`޶ֲ:0E|5K}3 oLe!﹋?m}z(>P?S୨kc.la?)ܸA󃤉Q j~Yz\ا2B%aLj8Hiӈ渌0w"OMT{}ߡ]Jd]^uk k|.GgT/NpEUspތQ9؁{goFa侇ā0Ekok9l9X'dKgއpD:}\ԃz6u|5߻ 2 H$:!:Ĺ]\gk=aLb\ϼpX'w`)Jo 3]V]ʇkخH1ҝ{,[d8D^/}>V?`?ba8Ɠ{q)_]c^4=dy? B׳Y,iFi^ѐyunR?Ъocy˞SRyk*(:ΗC/T}q?odNyCFo$dnnQ<m8c\Rc!8OVJr06[ q &)9 [0\, 2d&8.x2d]=2n\ߪT/ zonEZ,a%)ǵ }}l땎3]`>n<#60ټ6 twJx1~%npnk۰~|>?缟Fc\|lƪQO̷eLבkg,b__ok :}޶;|48=Y fQ;u4MzR~9a?Maq#66[8vs;4doo|S wn [cw31^o4蕬 Iy|ToE=~q3;怌V<о+]xLO3%\/wVy8_Q\~sk'e _oRYd ?s"9CҤ^Zs%YICkgwcW(!B ~uDR t@}Z`:RY{i7T4Hu؈?t8XKc }=aߦv Ew+_߫7Gcƒ0 3;B\zÛ`le3; SSn%?֯דvvW2j/淓U?'8LY?}YPu|{pi_j}XvBbWM!U8XōS|y&{&FkѶ]wxM_ў+/4~_ِ\=GX_qJ+8BԐ놙a!T͇ {}h:GhwB}:7Fw@ο?c;~joFDŽFw@Z;3ڞ0|A˨i{_/s)_錩*3KNχc7)ʜǙ`'φA.d!lύk]ڋ 8Vrw~{p]Q!c}7Bߣd^?Yl|{1ʤ{0 ,wrE G|/xqr`%`s:AѮXk1ǫ'F{e3t 5oۼ!@+W"M_KHY:q]Owpdi/+LB I'cf/#[#7u6}K.[4ҭ>2kx^+YxM78bF#~|7A_ P`8mpi\nu&Y J,s#5h}~J_*}}{YAoziQPׁrb*lV||Z~2ڮE@̟~4q[<(Kg~y{6O_2XN^6\Zew?]ӨѐIJ?OX:5`>ckY;Y٥ n&(dhGR5a_|mJՊ8F`v>@|qknkp8u\21윮?#V@蟣Wd+3e:,<5~#_} ;qt?p!q]s֋flsD+^珊7ޚQWT1bh>ʧ%:^GUq=*$"O/%F_~Qf}=\_-mhFt:W=MKݾi0b TC },Bƛ7*V3w#Hj$y`-ſWq9u<c1&_ -(:i>>Zt@j )×aUZDŗ^P6=Ob V(ϳW&]_gxm+og5xЗy#F[^,p.}=+ >7M5C}$fqEznVA %R2>~<泓HZZ/cB1LڸaZ})0Sݏ<(ťBU~Q!sf2?&ף_>)fnB 2?[?x/~|v~f.ij exφl sx|s4y~i{ѿp_ +Z2|Bf^loz)O`8Zq> /_B=f{Q-}M4o? #:v+qi{b2a<{[8n$E!wDy,xtNlOWӰ*oJloP滍V|a Z1-B~wsޯkj=댲{6pF{Tٝ2XT3ǹw;ǧ͞4ʉBkΒn|Ĉ#R}l;Y*CC{ i%CG2d5wKv>@E}>>O>=gۙCn٩fR ^Gv@p"ۯ$Ƈd[:G; n~8|Gr+`k0O\*j$!Y O B"E#-?Y C}e9?c=4+> gc8=&Gq0?v'Cx0[Lo:68=p)'ky3RJÄY t[ R9X? jw doxtNdOE$$A{{pxŻG}f4jox- LJ#P:JB֏||Ylpt.pq`?3cWg~ ܴ  Ap;\WĬl? hoa_}2^k]vⷱt~~޿ˊ>3hoS<[sk`hLz!hXgmяݠp< c <Ǿˇ->){@q3zTd4K_Õ,d=7ۆ Z>;v9?CyU/Q|3`9fwgwq.-?:i9w8/4q=P]:,k:]2JVpNޥRp}{"G~8ـ{z2n̩Z_S~QNr-kBB/ʤ ;Ź?_p8n;ɸwgs]ꍄc'i>˟kh!-B=i ߹!r}.8{|TLJ pLeto?Eׯ(0ho)%Z!=VJ/Q>w!8;_ }3x?k]_WS8Z>P6oc)>nṶ|l.LEq-V_N H}[gGbp𰲷.C&kڧ"64 L<[xZw?7mG[疽 œIiyQ]_20i1-ߓ뵘xħO~F֏||JY m7s VW7WQsxGS;0J39ːOiセe9W)-}Jw"m/ŭ > q+OCa!}- }3ٳMBgGl'#ڱNMōb[q)mov4F×';^7?8[2/ÇNce:2T`痂qDL_O ]&̗ j\v4ފv']el^eيwBUZ5کͯ7_vP8G @Ґ *17s(O 1;?:K377y) 6yQ;ѷƏ%2+gn,13l~h{qY&\ TGYu;hyy|KűHy ,n5ޡ)v*dhLgeYo^㓌qG<Ĉ7O0|7px-VO O[QqfI~aw*Nh ^2Ж2xo-/ċziҸě!8lg|L`rvLIqyCoyE( J%qC> bg{*m|81&{d:2fscb=4Cqb۾x;HK2h`c ̯VF&<3'uQ;~|- }|(CD ??{/2+;*?m 'qlm>\O8欯2'gHxk-_heQWlX ުΫy!h%˻g4q%-T}j{{ռѥ0)_VGq6(SF[WfDˢW 㥩 ܵw*%+IUG!&7qfj`ъߐk(0||awv ;uJ/r ;[o)Pv[o+Qc8}UBJW/~Fݚ뒧QFV' =|fXD*}ҴK%{=5#Zqz^GH=0c3x1\]#R6ӿ>p俦ڧQfy8U!qfgy1Ä|A*/9 hFpO#O:ڧo+D/IȜGb}BX%q}{fkuGg(rv_\Oy"qG)|Q߽ F)#XjRoNIظH_x< 1N"JI,-x]K{Wjw&&!o+ uj|z+ȁ84dGfcxR6;8WHy WBOQPuy gLy,u,Tq!BWHx +$yo"7 ;bX_xB"400k+[x_kK؛оQgWW8|pg8;3 f3V{ _"l{cC˶?{4l!}?hSN׀mޣgϰ+ge4 ] o)Oq>Cc+(OWf(À2ӉZokbu߱$N0dy]_јyyK\#:of0Ë5C{ 0/c|Ηۚ@̔wc< OnDMn+U EˊӼxhn,~NlL?ޕآl. 9p\?~%Z^ !ox8Ϩj)sݢWv.U\MXv-pj&d2k }z_~Y(^qa*Ow2Y_{oN*mt \|U/Rke!wVB5 I9Kސqdxň#CTbI7HvK}k8 Q7uc}ɵbI`xV^ ap(ċJZg\^ԗa-pcR,ݷ>^$w7뫪2|l~^Ză+;Gbđx% l>Lǹ7L9!>[xޭ~H|WM:q9+{uoҾx&}ſLq[?y՛GD:E^f(s1]<7E"Jޒx(<^ü^O1n+Z/V8Ro|"!ff+KOZ.<q<@v(*IkW'۔< N6\VhfX;`gz>| _̪/,V]37l VVjY {rvK/(F׏)pqOI~En2Jte%d=1z ii166:> ͯ7ehXj{ +E<vC=Md'PQ_>oE=`v(7D#R;}A%5_ɖfa d|l4C>Lr3^ԴP?ϗw~;{4cb|MBTM'eP98N0L =1\9_^џkrCR{?ϫF6Ym UMg"iRqMLy6qhg3_R۴w^>\_QR{\(3^'?Kp#^Y1q~EBy XKsŰXi/Bԟ,Ox4ɭfgKgGCC`Z6NCnX]|گtV?CNCP(:$^גJ_COeOGE^c[pkQ0f|mL)R<ڟ@rx,eK;P>Ћf6(l^O E|$q WGKɭY⧖ziQ I 7akf׎VHr=_$=3ͿJ[?&.^,&Zsf(Û85WvQnji{i>գ4*]k+˷.$*j;yte;h^`:x?ルa@>mi1|G. S}G= 6Lf oP}Rprଳ&T3U}{o9HtLEײ}fXe >߶%a= )_ޜ%r<ͻ q7u {Gww\pd4nI3װnWHyDV/;͘mVl4E!EũIw? hoDUQ^h QotО}O\ӍjFeB_QF]yׇ_VDz}Y18,|28:OfzBslW5ſ\\)_8 pHuyK:f$kYG0>+wߢx )HɺKAoKtyς2Qs 9.7\9!~kIy)$"[ߡoAVٷ^=FRւ}#%[ Ƥn&[A\Ē sݳH#S:TR^OO)32G#(ނJGzע9P_ٞLjr:G}E oρQ,qq!>W;h2g}2Z5 ѯ>J8 6t(|a3 It~ CQBR|sͱ7,Y@h1vj./I^D󢭯7גn]o_D)jpE׫E/'PQO? wjߕEs̹4plpmuݕ췼k!ptu~Ƌ[t%~tۍ\BnNC~OZ0!M+L4gvVgo.Z]YGo4'pQ{G:dϑy 2x+b?{1D֮pm`4݇>'nQ[ѕlYm_WS NY?|hQK֟@_w#Ϡ$$+y$=vaJ}aݸVy#-|_{($~ Åϓ=7ྂ=+"j !̦/ȽZN1`9-I|JŐh-Αo֗oQμcPL"?gC6z[A2/L&l?_z\|I(ڳG=?Q2{C޲z# ]w4~5>,BG뒺B^90W%ä 0Π)Ń)FȭBf!3DK^W>Xg/}-X81"8rRI!zCoFQysU3W,eZMHYQb?8>ȸWBF4Zf>^.$_앝ӰJ]ƇEs0;[?`5[''PL~>PCt ϼ\Ucj[bhcS g-6woVR_@X_Ny:j61'؃0G*.;ÆVoV0 aAm1lE;_G]o`1𧘈Y T;ig:q^H24M~v3ãP\k_׳ q%7t).mq(mwTk~Kt||%d׸Et}ϣ<t=M$_Va?d!y:IWyp=H>L|&7%$߈?;'ҏoDsd#==3x0o99zvdB1{=Gہbh O}>?"|7OJySPr p2]O]9 8 fwJ ͯyT,wg˫kca-~+lXoK7O8c:Wc~?vzAmU2<' |c$V? \߳8rͅ+{w }!e&#sו?<]$_B++V_EܾOs,d5rןw.OZ%p6'N {vo(}Jz5r-0QWؿk 륱yA\o"`+JNӮj/K2F[z}n cgJ=~KqClŅ~O\9ߍ|LVq84qw1!(!q1^c ہQϋIB.gIU`}swE{-?,8{|9`%~|- }]>&6 [|Pcx~+ 쟷տLt,WHrZq=~i*>?uAD3N?f7b-A\KȟL:,0.鰧hXYkjHXSm;Ǯ'^;3cgJ$Zzq ?zcx?cbɲks}~ň٥:PCypݎs ~kLLߨs1n^=@~5^ʩ|k<~6L?`&[co%o/y۰U|`& z4+Nx+׋26=߄v-~s|hG|+7v?d=xxnظqZThƳ+߫}ͷ cq LkWeAґju$<{Yd|t}^d8SxS߉^.V1OqM̰CȵaV7<* 7?GzuT _ֹvϢ_ },2k- 쭰MF>dO )07? ` oNMqxꭨC |MvdFE~lԷBޝ[9dպa% +8 ߈I͛v*&c`%RY?;쿕K m]oFI[ŧ$Ç}bZ^:~VhļH_EkװqxJobq|Tf-z;yzg+ׯx~6ܖ K%4[\|㫶|]!W5{XJݜ;X\_RcR<8Nk3T?V2_WNjowHl_8-6'ׇ)'Y?|J1Bz[-Tq mi&}\}n<"v<"oRO/+R[qmC;p ,)^ a7N#[YJϊl=Le^`XSYt.a qp>>ϺXz<ϾwKypzXgz./BiF_i`|f|]H}^gV?sF13[wfbfr1J|rr}<(<(1/,t9uɨߩ}вO{^Fe/A<ϙ>'>pnV{Di7άʉ\F"CA\C{ /<&wedh =볿;$TLJ񭰃wG8?DЖ"w uA`{KYC {la`gbMS㈸(~y$,6۰RfɅ? ;Y>7xH7CR|IHfӨg5-BOwF0wex&b:2ܿ[ivvc%d2ku_!MݏV/qܮm8Z,a`3cC!}f&{PC37{auzj6Ctl SVH-`/;%O ,ٷH,\[('d@oqfhªQ=ᾦ*^[@rwiK\{NK կkQO.Oȷz#j֍_9llLڽpIo#yܠR9K J`*g \IHEͣZׯ|WKw"^W$2@DP)uq[q-o!G8a=oFnj,N.TE=n} ¾i~.w!ڼ/+07;BqB&}K~Y> silY{AouBW܏<Wvڜ5l_t98=W^Y_Eyv(_o2I'e 㯞>^X_l\7K D,v \bp0a=fdH<,:K(gbb }qV9ǧQ(ŭ~**g3 .3lr6=X|y1BZ vrAϜc8;m.`7xs f7⿊_ P7W`wêu{5) \+ I7^-nGtG$N֧֋.$|ufl[ѧ$Qa'2rho;|WW wsq#G+Y s-<9?hUS}Ӈ dS9.)0u*?6Pk K'Uk/m:%1Qݞ0q'D} _?}yFW=կdۃ3_XrO_wku_|Gī yHwcqk(lBp]b^_Ť]-ꊢ_!Eű*d4ǵu;/UųY]|p88>$p_ };kr`i^:5{v-b#gifk9F{kifk֮ÍDisċN`u4?ĉ}O<+>g/zu4yķɊ^v/){ʩ;"+_W+j_A??~G{e)dE}@x .ъצxx76d24߼~/(߼[?'uW\,|iˀ}3 ﴇ<<{ sE~x&* O{RVq.O2[2;A!שc$|ހv=Aǿz/Ѧ/֫:v{<בu֏Oi<˜nsf(dWgMu8̷YrɣƾnP48"~e̒#aWnu"%vo~Ȁ]NVvDIqCye} }]<gi>G;V앁׮j/g9EfH1g<.&fgS996ڼ!n8Oc۸Nmסe*R?|e}DE e\RSH5_oE]Cn8^sQ|~xg]"0N _P85%h}OQ)F8dn;/;bxj04C$Ƿ(0LHߒ4T Nʙ΀QN <^fe4.Pd}N'{|WZ^_ĎXE_hNe6cb Ev=y_yxS?8#?E3Ȩjjx~\(|G" Kx$gf=|G??N3Qf5rןw.8:QfQ>ҷ(˚qa+]U@)=SSOb $|c%Ưׅ?skNoQV_ w ywoŵ|r`\˷plIhf=e?$ e"+H+^ y(]zn8޿<իj#66W_;7<d\zGn9& qpKr1r,ܴr HJx?' Es~蟣/jOm* \^ _nmL9Ͽ;N20n8o~ޟ]-m/ ]Y]Sw)mU:OѿI\ G)[|1E׫7' 9'T~/l|)dDHK/{Æ~?Wux!Kϰx?̥o?v2Hr־sa}! {Ia/P{'.)%qo^iЋmag r"b^%xǩ$wʻ۾~]&!)/ }\7iT=O}gʼnf.fz 3;wy>{{{k۸^ljG}88}[`gpq0/"wxqn|`Nڇ@~C`$d-7]0íZSJ꟢ccBt[q}YslRs)G/| 7P(7JǍ@ӟԅ{_U;/ai^ԣQFDžYv j2q!? 3Ëyg ݾϫk` ֐I1nn|&Ӹˍp~U_7̏'T'j=Iσco +3,w:Vw]$!OQ;ᙜbKS\FZ>mD^MCb l7J(\$MI1`$+;᭸F\r35F+^[wZ;x=W q"AK!pvkWge 3k3ne=z%uȅ|xw`\cbwUQF=Wfn{,0cnc~+<6F萺N@,]G}SLBުxDG7`i ׯo"dŻQ|cxDjo&>JַOǜ_5'T;]:'?B~R7d/~X?P_/Z]i$y6 {7~1AHKϑ[& J8S{~<>p8!4v_ܬJG+7G"wMs>ByȺj.'IA[%ҭO6*Uy\ygp>=nH_>3 k/-|AIyR_Hۏ N*zkNl`_cQ_%8T77<׈;y(ˊ7o*5Nv}2?o~#5R{f55!}H LV|'fbkjw2@)621Ήl'Ű>|)ߍ<>]V0?ս"Ws\o~{'UOmbY|/k>AfU2]; q3]ظ!g6{'K2*wjr[?FP CTknoz4dI3z/Bj*pl~a6h&f̟Xl>W{2_pRhF2'H(ъuGXDkUC? OEϊsj?CU',gW01_ݑ71M|E~Y>,<~bV`ȋ" #|xbA?xH8G)݇T2~b}¸'|9?r311icd}?Y>{0J3 vݭGfq^Ǚi|SE>ɉ\T37 >IM>UIuoX_up$|"7A-+/6X7>| x6`F`kyv1/>/~Hh\3@$x_QVqkT7Y^3(9NKM o+? _<1w bKйmf46)?4 #9z`}Gڜp`2p=Ks=ߏٱX@E׶F}?tp$ѧutQ ?yf)n_l=O1`g5C(f8Qh2W)pׇދQq_^߃ 5,0WDzGSѷ׾.BIևB}uB.ފ6s2ÌxEc棧xO8]6λ 'V\7-C1p|rɣ ̤ʟ oS )WSVyujr|hw ѷ叾Ex2W{>˫?.8Ð 5OZ0 F9 x?Ow!zV_J_M&!s˟%J5H'vkcҎix+ڢ9[Ku2qMCcO [y9iRW- ־Z>:2=SmM/I&{v!gbwYRD37{i' ˎg]\i [){0\$czf/j>SJ!t?K->$/+Bo= 8ނD>Z>[P6?4Q?NOK&84=,$ 5B\W--px .`^ qm8>=2~Gٷ 77 _E+B#E#:Vr+޽9sff6Z?,1ο>FǬ>.f1 l]toX#8'KKپ|rEkY}(VѰ-{UX;Ǿ ,r洠_#S=K?zd<>9瓐exp!qZz$7Vshy󘮲g/f2p@4>29%|xA]ʇGi2gn-MvW=t%"B"/WWz$Zb=k yiq>tlQq.ez:\G{ ~Wg:#m!湋<΍ 8W|;9p_@ƸlS;-/nc ǃ!4CyQ@c{on`Jf< 2\Od)q*+rSoTJYg? ;YJ p~ =/ j2q=s^6Ѳ&Xƫ7yI{:<wϏ? ęHp!ȍ)WPAU)ͳ?^P}칆v $΂U#2#=gMQ{]+k}1kiOH 19aI %IF+p o]˳. O#3vmQH"OILε.˭xv' =d)Odyґg}2elVAXoFj;~`Z@^I@n0YExP<CW^WD<@ٻJ_s8DZ|z?⢨^ D^DH}D+LGﺗٰkI/E4")~~s>ŲU6S{5(/;|o{RZ,*gg' ;yKz^mXz|rdӒ8hC\8C]9LGq?Z-^C[';gcg78*Q>aol|j<0]83Vb_F<"BKȼ/r#׷hn))#ggUȋNx+7h7#]<\O)7 O}yoY8xZW}߻9iEw8xjRY{i^KuZ L@7z۵#`~ C%d57ӷlM$?h2X姴`hBlgpE3LhrϽφV(?_͏H|F&e 1H NKM}گIȥ sM X=?6iQOAt|}%d=7u~< _Fb x}cII֌xKuLZKנ z|zw`aw4+_:ql97&#_'㞝!EףW2O]U`E}yIX׾ikJͯ-m 7AFE;i~4c=<'1g/+4^<ل\D2FiǓ{X-ǻ qB8wnu/Tf-.}h% di5~lpVdyOЫ tR}JCkR3v~p5طMm8F yK'Uk/m?ƻ`ܻ@8<{px ׻tJWxͷx ^Oks(^4`7_뱖CK2V v^v$8q/mxjG*o}L׵Äp0/4T B2{|uqz+GK^~ʿdOK ޼}ѿ~%\/S9Zlf<hSU)Ջjۏ5'cQ9Tص jqР[i[!iZJ`ϳ @y44iob~6B?Sj{W=?{>>ޡqE;%<0~8N+HœܛO/dwSCl #kyvoݳkr=d%zv!ݳd\9MS܏S_ut<ٙOd~^ 6uo?cD1qSYTsQY })rgؿS޺ hOf#/`X}<ںei8ѸD#5%V ٞJpco=hUmLL=-گMd/N8kWaF-Gao|7;8Ou\`}'ω|IW*}7MB*3]K4~Kg9?3[8>3ۿS<6 6? t?'m}y1C!s_!z}մON2tl?߷mwԧQb㳕H~\}%d'{$J}A#hOWV;mLw $ߦqis\?u'?m@_ܾ'8? kx_hra=RE!> qiN%pE4Z;=`O/UHTwbVUS}!M>?0Yp|ӝ$q`=DϢ3/D;7g~-O9jq;-cWJp48œBח+' ?ޞ͎k+cUɽZs WY~^ժ_'8_#?g ˏZ?7+8]=Rb[|[~Tdiv m<_=]|*3{;۟8\{(>?Yd s?çs?l*sԞu֏kŻǃ r?g_W#ë ';yy瀋'Hw{;گIr80Vz#aϖM {y{R2^%U7n弞XBF|ԞN~JZ~>ߔG?>M{ ?Gr] vţAO}zo*>qB<>C=p2n3Aւ῿T^~Ya_i =yE+ES)MX&}ţ~B[_FhԞ'vҸlu//}q@@E{dھ~#I8GI~iK'Y]2??4*fڲ`Y3Dǖ/ bkU|nozP>l?!ߑDZ2O2jkeˊio,d' ފse"9k˃g~}=z%&_e)bxRKEgDOY3ԟUwBs(^=n6W &h_sBzuΆF:f*gp~77t٦=D rsE>ɸ9SJAr{ok<}$7ޭF>#j7ua=~Yə(? K_7]93>y6m얿߆x.%g~i?#ZJCsXFWUƗ%|r|$8ߌztXӸ/bo㼎1ڳոK3O_+ò0x_sSnP:~7 G>>^_C/|s"8=OW{'@P\%m_m>9Hlu_a<lFzƴIms?үdV)'`&ri2y(ǣHX2qN`-N${83WA:;@o~H?$ORH=&"%`Z-j}Bz[ďWXX`[\Ł@_y<,̭\n<>8gTpt,S`_˵& ;Z.C¦= BRrU vz>"mOGׂѷ'v%,Hi"Ro7C v@Vwh+ގ#ע yd|N vovoyf$\\'ZYő=|j6h8"~da `M#?FdwS )$m(qO!O67󷞏W?>C&!юEM`it0}c{hK7\| ?-׷_D\¯B'@&&XWIN9JF}7\Ku189hUSꃝ}xqR5C_0<&tC<x^4Cg6|"q'Ewr-PZrW-ƂT߂/K&!q]m!_7{eh mě=G8&l(r}aq`qNo-+MHY U/jxpECp ;w߁ɷ{$Wƌ 3 #`oFS˫;nq.kK_Bїw$D#'DqƸΤ~~zi!'k14?#=(G<F?E}\Ӎ'fܕ]\}ba`J393)oLT* J<4$a'Wr)S0扠"B7?D揺~i^'OGHp95t?qSۨA_ bȸ晾OB{/k{ž %?q_.qI?}",[&8X4`ݭ`gϿ 6H|".P&Y`QA@r<]yßwIN~:.d~%*BKwt|'4 #by_)dxBWbq=a~!E3|*OV HE^_o<(egDmȨa_WS}JQ<][oqS3a;cH?e|V!i- } L&!A@7wu~pvf3ԯsk<O{u9=PX|d~@bwH~K}A[:G|w_pu<^8DŽծ=>ILε{?6$ܾg" 5ߩMV{ྊ#}D'rc}~ @_v 8awc\Q#roQtOQdZ"VTEf5gIض/ްEN͔%q'Yy-H>5!_{( qN>,_sBF_r^oJ8KSI>߆y&q~Ÿ&Dݧg;Zھ%'e]_bB"]Df޻vym+O*3KN?Un{;蟣$.-+2W!nb^invGq y_;aDsn.^)x>|WtgV_>b"܍y2Ƒ{k/^B'~TKusqLA쿽 Qx/g!+5C To w-D!?M#ϋo]e{gB{6?>|_1)M8HqrgE;cXb88 !(O2 QyaxW}}N_ܿZ9J?;d-wY][90p/O8|:菎̎ٮپ%k(^DF}LNes_S>iqv;m4CH 8.e8HY{i"oG]5?SdڑNbߚpv9qf1]9ƒ*!Y>%:%xDPcOdVre_\91 Eu>8*[/~ ?'P( sڲa=B"( Z{tv Y\5xt7q8Dּ'7ϥxO /._Vaʇ,x+d6_b܄,_lxƒ$p*AE~ɬγp9/yi66􌁓2NV}Ƒ5ɏM6jNd5{ )k,ЛgW|yqCFo\'S>*ow ;aCFf>jfCg?IyP1U󿔿KOcY^: /B%koxQ^h fŁCy? 8T]"OopAE)x. ʩ"AD 0 ᒛp,$* ۳l||2;IMWW}[a~&sKѶ:?l-"[~VTe2O{g]@s~#yU_}ƨ_U7KU"rhڤf hQ,K5ʒY>E _?x4<+y'$&={})η֙f' <0=; c!aB[) {>\{+;=lܴo%w67|o[{4Qm^w6ǩd-K$SB'Kmc~@Βy)'Z=~ |||s#~DJzqb /tm8 c]*~b82(;6o/.gɞO:,.[U֋)eG u\MF֑Sr|ο͏4owk>ZC8?(r{y&B?d380NLjQ0N\;ц1yqZ#6򵘞sUWm_i/[;6a{hu/q/^֕d(ꞝD;Nܾj ~mHåݙlwՉ<Ǽ2qonzOE5b^ _PI)Yc+Cj_|#*74kFg^Y>/f4Zp󃾇?BKGh&)UVY1>Jx?W嗨LϹ}wۋpgha|xe0.*}TeS2gF>~|7RLYq&W|s#~V 5W]7|aC~>h/iZmJ?_!\_>/yfzqE=5VxagGx$)9ox~q?O"uzUw9o8/%zU(x˲7!Rg>e=4| }գ_ .?7qĬ#ϯbӀy.V6$x~3T=ⷃn&n6ս,Bf~LoO&iW=?wHWqVvZ/'^ IRZDO)xyV r98c [CO9X/ j'߂ *m<~3_Pp㯽߃CNۦVGlV5}eʒǹHOfʊ$zxh%-ܤ3gP[j}σwcjryHN+}=a;):ޞrφR#ed4\^-.O'h^˙_K~n#qcT}xBMp<+. P#u2T.eZV.Rz{}5>sM-J:.cĽs_835$>S[,Y_ʏY!mQQ'axYa_1aU֬s axG:M{f@b2nvcq-%p7 eS_6UɢT9/b'r>YNH:-cO>?nGy"v~\^o4tGkZqsO㘷ܤ֑x]OkH9z_讜ݏϡF#nܔK?)=iˌrOm+6qmwf)Uw0f^(Ŷ}5p7]]\{Ryya3fVw f7ssNuW䋤\j{4}-Mi~ Y 鴶ꟷXݧ'l=H׿4=uy#u1x2ED#}X_4Gm8`\qV~8'c#=ɉgg86gSIޮ^a8c2cfż.yo>886?6 5(Q u -Du'Tyߒ?PiՆ^!rL#?˩ƳNQ5z*j}Xgw _[܅Y"^079!N2WJKq%M1Cm9ѷO?iZc RBYo Ӻ9šgk]]Mn]%"H9EdRu-[~[.W|O5ųj&N+}=qLy{|3Ko\.:wi:*΅ _nwE;F\ V>Xƍ"eퟆީ?N}fma+ՋKUmb 6'?7CP僨Q$O~z&\_r_e~?F _C?!Uߖ%sr}ܗO3s[,]:NS}5s>'6]$%_|衡.bXaטw𳟡b;n?[ů \7?(ӒǶnX?r.wp&rNS}?YWe3o_yk~k#.8r1/{&vȮÞ7Mkos|N |Nlj9OkL@׍}?v۩/mc}U|+]uemi,,-tpr[Qw>'>'x?O3}=RhIߦjצJF>v봰$pd P*>&7j;bLWb=QӬU :eviשw^-&䱪*L]_E]'~G<̆h ;4w0g]!V["Mfȸf+-uCe걸 ӻ^rh[ߢA)RTiM P >V=]YSr#uL tّԝFK]nS>@2-%Qc0R*~W[ܼo~9kߥ~bƣr%Ii'RZX;۴ @`VOO>7լg_]ꔺU,ryg< ̡F`UP1nmֹQ_0qյMeQxWVܸ5mJ 8#[klGO8+γ2J.P7x;If!\p!ߒ#o1<8QsErOzG0)dz.3p>Q!sGp u([yz=,#s`o|FG ›]Kޞ]8n~0KC_j+3YZT$l@:῕@.N+};yiTO'C zPJ#e4_3_ϊyQğ*TUx̍gģ3AtvO庴P_~V7~yݍ仡*MU7GaLoZ!VǯMxPu=R'gJ |݇ϻO;vク9"gϽČ%[Y; ˧\ן6<߇( ؽOڏUqO\=x0'>W OE9iY(x#|&,žO7ɛB>qچ:ߢL-C!vwJ"xPgB׬˶0 * )[}EM=?gTxAD>wCCT(jtcm g6zu\ݮѵneȑlD|=V02t9gtjg vXr7~r'(Ѧhtxo( F>#g#~+VNt?ќ盎לvmo>J|"r⡷_tɾ>Gq3e%;oy3wqټ'+5u:S 9Pʱz{^F9MjJC՞v5p=g<>~tQFEﺤ/M]7>W.C2ӏCvOiD?zhJh~yWs27>+>ֿaT;XOTݣO^~rk4w8uJ?<)޾Wȏj&Ma~mȍ5fטs ϑr':{t^ٶ(E(me]^.Prjesmo:)C7qvY K,qn ƬTk4ڬ7}\ s̓:=vgnWs|*يt?>x?p6pƥXOvp [|Baםe|}8K.㡞Á0*q<x_4.g=.BRh.bid~\5Y>/_rQkleǗg/vfWg~MBWke7ʀ1Ͻ3~7~27Ϧ' "̻(P +iL4z5뙆E_%g/0aƐyh8pm;Ч{?6<'/ ? _txLbg[ܚ1˨+o+kh "B9^ļ~N^?#օmu^tq?WL/3+d\~gcs0_ XJ±i̮s8U뻊/ q\Oݨ yϡ*'Qjr>L}K͐u`݌?f9_ M~Jc?*'LJYc"^UEfD=~[}f~03eX ?)[C2ztB7w@؊4ڮ_t_ixA[7=.'yV'Dwz6()}wr{߇O9o{~sO&f.lu`g׉;kW~f}_^)WK) Rr \}p Ev٢x̮>Z.OAI>QQMGcu]rz̽GhNMT>Ϗ:'csxia_n~hvAs?|~o~mN^7'V蟯M]tesdAp4$n-cz _f?{O/?igj\w7"Hw>\D!mQpB}{d//^v~LUUQSǽ4~KBM|ym|FB6ZX |LO9OR?7zJdzWZեg~º,:ϊ:vbǜXs밦u_(psY];H6_~=V#F};ugk>l <ѲJFF;~ߔßͿ Gyܼ/bϲx_~xrW:۷FH\]b^gA|u^ս@w(ZP֏C:%^(7]~Q3WsO1*o[fyꯪn$U .eŵEz7zrQHUbqUJ|q&)a\58 7;?AExRzYv*p%j|zlj5A<_qo]?ڑ?CqN?-|CS Dz?twR%4Z^˟G^yߙ=A4zsHUetMVzULz=l6ץ< ׿ioTߵr>]Od}G#pŵl|ڑAr2-n-|'fݫ+~+H:+c̗o0i/W-D<=.u\Oe=70긅/sWox m}??ו/㷁_t-n׮pQ2`$WEs~/j<3LB6L27{efqqzfs \"\y>ˣt*\sʸJ{^5x4t^ ݏ]k7__Gƕќ0xzBy:F=G^Ug><~|,&`O+a*"S> ~)xw6]wW1g#l; {s1_/sB: 6quxFI9;fRV5Q&ѹ36?r2^G낿9Obaw7/⪪Ͷ^@{CkqL] - ]ϝsf.C]f?{\ƿUҨϹMc ȟ2) uGlmF=OgR"/m۳fێP#ZbmQ=@׀{u"'_U.UJ\ ?󆟰&a] (5+՜%).gQQaŽUT@¹u _<0+C&UV/*ܟR8ZӬ>Kԩ=D8ZLJSC?;غIa1J>&}Pmq^cna,-1^< G>ڞf#>{/[wvHLRa(7 m׺NFݾYzӰ6 +4 ̗[Mf[j}gvJub=`w@)a g ܫ. ky Ocw\]x]]Y?[M%zʯNDU7CU?{zћIU(\Fm+o9JcǿvU %kG_=RZݹMfXO4;Zf?RN足.]J!%eϩҫSQH>@"$3(fmWSl4@yd^#l#[6J[wxqOd_^:ILq>n-^så{t~y(?u*?-2~zCMQ$rw?> OйvsuGΤ7RLYqfD?C4LW u'kFu>T3M0#v%eKۤ e/xӞ |]qi|ˠ;Ѹka/ۗ,-lw ?Gkxn8b*?//>Z?sYQq2<>t:Ϧj.z3)4B4[eJ%['qpp/=}_g??:?_83f̻Gt'eמoٿ~yg8q#8;潽L^pu\8SoRA5ޝ{^wc?wU\F;rsKӯJ~o4W+6%xoմM_u xv H^/e}{?uHƥ]D^;Dㆲk8o&Pa Y" bڳ.[: sGnS`KOdblOd䊼Й2&5]8nRr.odV_7X:SoQ0y%[DIR<<#OO`焈GGuڌ7U2vŭ_HB[ǣ\w|A ((Pw%ns;1 eܕM,ЏSva{\ޜh(Ad1Z_<x&BfZeGq_?> r50bs>h0!w]ܸ 69r^حD^W[K2U.:Qf y5z~ y$yp*!e.hukш2e^=.{sG1-E^Ǒ&Fbo;Y L^ƤYON=%,uDrZEWO+6^\)<0RSöB=uy璛PS%R_H|{1Yh~?R IVK9x]5=m#8bgfʖunL%}ซFR?7yqToq'>k Lr5EW4%,Sn9A-1G|ks߆= y<؇a[Ae plҩ=H(ky%MC<4M@L3|AFZY0$q䰏#=}mXMy#%{s^6JV!^q)|KXmyUYSUk8f*Λ_cRon>cD5L7 xA|pN̕vxAK t/*~T79~i܆S>nq< (%,2 s.bNG `PbS+2~3*g6K^Uί#EbEO'R"=MYG/Ϭi+>mnDf)[{elQUc/\[$)ij*ܗɍH?Ь9)~q4-gȮûB!Wv< ׺]ʼbd5TZ5Xp) זw`a!+v6?zxυKh9-U2W< ׺n=jqƵV zB }p_E}޽IJXZ~fŸ |'z|o4 a{y8^Pp| [Ʉ Bz8P@y L]ߧ$f<4ǧ&XO-|PkCr x{t?n'}7|5?5z{vA)Sku {-olb]4b9+F{0J_(6Kx趔%ϣcE:y,5y_>=A'2F7|`KO׬~AOx>+כ믹e8-O~/>ĩc ?,MCY2^4_/ry~rW'q/#ƷE_MJ.l6E{S²C.-5Z*vpȼwtl^15H~.+󚫾~}^GEtY LW}Fj>_usǷuy-ؠe'F-vʓ7co]A_mǴ=7ek(P`ҁVoy37ҕZi55<4A _ze߲K((5І T_w&<lqXm7Uc$2ۗ9hqN Ku=&1 :rD<> =5s8" =ydKsųBM#wQx):I?GLg$~T3_N:q+g#\4ew< zfo-n-Ïo+z>&zUǺW)liGm4Elk;ߜ#\{u ddijR*<:_6< 4~r;uGݶLxfhi(Kt (1qa#5VdZkPiym=CﻕyAx|2d\{#ƟsUiDnwCQG ~hrA ?ǚ5Oĉ/tw>5c󷖚/qnF$a Tpn7#dSAzT}st+d)=f`:}v9Y^ y`y偩gB}+`ҟ8Gt? oAQW<[z_K73C^qrA|z~f;aza:,.BKς~pTFI{/,dX'زs AȮ;9Nȸ} 1?'XDwN,珝@-'lpTT铲?ݓJ;וߺk6jWa5I?ۺ+}ȝTgY- 9KÄ5ZPqj3v%xZ&n(֋ߦ|>`~UX1}GX*'=Yw~_b]⽐#Eba8ØR]G{O>? iפ,Y2}ҨéÇ6M/xp> <~sEGoڊMR߇~=$JFㅼ8|~y"MgXxV w@Fz7Yr$bVOK_>摒/Vh ۅ/Pڄ_ q, _W9,<߳t(i4G" ;uљo~W8xZdׇ?~|~ш6.yu΅.ųu}J|}6}#'5 gjḀ0]ǹ8s~m3E~(ȟ|o>}ƣCEuG?u&*GVLC_: UOX%:SNsUh8VgUǥ- 2H}qr]NtA}}G|}M=)?e]7:k{|O!|%[8_>(vM^r5ݞ/eSp{ 4>By]|Z]P]xߧu.ʣr0gXSfnhG.}Q]I 8>`xvD*|"}v.3>>*xUbswg[sYҽG(xƕg@v5\9Voz_LC挷uU>wT)CsiQCk/J~YF⋯쟪)xqHOFN- %I ;$_[4(FT(Ʒ~wQ'mpWpǛ`|#v y_xo'0'O޾j۰.Ov^RĆ]`MD, gb}!Ɯw@tIy~"OcK~(ov7`m L[CȧCF]vҷF{Osu@ iQc2M/,?Zi*TW7|㛗kv\dq\/$I 6I1M>_ڗ},] GatW>$**Yln E䌎kꧢֹGW NW@V6G36kq~S]." r.Ѣ+čq_\0u‰!ƍ<9T>nq_5Dy#6;:1Nr~wƏYI\qۏh4;P^?/! y?Vm'MŸ. ͽ1Cz~ՋU`5 }r^Oƒo:hezͰgTSR sc6}:_ny^>~o2<H} {Dy{vyX7I K+h/S /} n>.`T|J^x ^D"-rt6?_GwӉ+bT'?ν4/gѦa-FK.U'ؘWUsTxN[[l"'Ȟv{\d$3d{uoG^FsRJxwYqY,o1{xUX&{Z[iH}~,)- Dw򿩫H}Oяs޽δbvpƃSNx,/^]MbkҬ-pOb%־1;̗j| <9TŧPlooȞ}H|Q`M\:xC'׺56=/eGuE 㘚INvOzkv>jZv_,:z ;/3%,;R_}Uh_ ˮq8AYljCXx_PoL[*EkfSe?ڠ+~-]*RrW?=H+7xLFooNn riYǺS~Ku|֎MLyU)g*<ߝ=宼~|J\_8>W}~ǃ߆|UĖcdz̹gɝǖm6)7z߳ByK(hoC_ZJ2sWGgV"CZR]UF&:oЏǚVDYK=;2/\r)x>O˭܈Wq>/w!>_ț**;1ؓm)xU?o< ܺuu_"ݗ°kGS?UFe ^r4eY̔h}6(U Z/-ġl[Fb[yV|Z/j+NZB9:Sv.֟f/Y £1+v+hx+Qnݯsx`aAō"~3uWZ_m ]i{ >@l6{ZW|.дFs9 5JB_UxnOC(;;v˲7(:{h~Mڬ|^lUC9S<H7nfJ{sкfx {N [,i5~γa~\QϻWJ<`4 [ަiVv._a2'W8Q_W,lhG8S2,o[p7 uX"߅M`g^pNnҹJ,GE_ גuW.IS*ryg< EU+DZv!|\ AGƱ^$hM|yF=FiنX?HKVJ7_J^)R8(Jj_9݌yuROCX <<pBOkvT[_Q?+M9ev }X8eNhSlr.h=`e<:)n3ё6U;~˒AQ1.rJg7~jq#-q[XykD{t-+b~$<~y=W YČ7ul<5>>bG17 Sm4~1:Oȇ۵*~v(y_ypeEٞ1QǮ|1"z)٬.p'F.#SOQ?u,;@ӌUUaG vBS?_{XexVm>^#帍F2u]_= gKgנ]`?<ƥKevaCkƴ>_e㈯2US%Jȯy.Gn 0 OSjoO _4%3ghJ ՓiC?ڝyɫ.m8Cy8S#yT+oo%E{+ixهl2ϱp<ΓJqvbGR-lKoJaKax^HOFbq q8I!1|͸?ϋS,=y^b]Ye6W͹&KL^y"rЄ*x CwPw^̥@ӏv,[t䱊fm2Őӊ6 `9i~$ZW17C.?Z5֮GJ_nh7S󹚱W*~ v?uWb<(m8^@1?u?oF ݑ24%u YOZOd=UynJ|8];+=Ry5J}ͯaߴHWZĊD7`/R1|0o }=p]C?'囨 ZdBz_2x\ 2NcWO+sO^x&)a>B4 1?lsx.+I/Hw]:_˘~s|'omy=3@wg9b^xNg1jnϋ9Yӥ0֡"XKPbѣwH# ޹]'=u'iT.ႊS3Qp^06ֺޏ=j<'{^\aN)s5c=4lm88nϣ.rx.zNx]wf_ïg9>|uVǺx>&Qj;] XtPPb⡷n@I.[AMkaSyOV蛢Úg teUlDDZߙoY}%y~7v? XcqG`Ī޸ʿvU>j때wyM<?wk<rkP,_.No;<:swAזwP_f]c~N |VV7)Ig\qZ7zz/?ld~D{}{ꅻFu=|Y9_WLC<Ψ{ ]:[Nvm[c#,HN+}سg^۳܏2|(+y F>5Zg΃+a .US(J`"^|q.Cmܛzs{ nA붪D>()e\<|'-i: i,{.9Nh7˥u}uyO\0as}2vbיLU? nEJ[5Y$Ȼ١B%wG4=uq%w//vA=5E EBFz7XbR'{LvC9xdGؒ1g1uG|Hn@n33WG=$\|Uߨp~Rb;wGlG(6Bys]&PzQ}aǪ3߿fFO.?GXIU/&yfRy\“]“?G'boi['-_fO#j|դitEH,Ot<:-8t[~N+}ˎO;? _sp]G&)wiͷr̨W"9^\<[Cd7Zl"==) iUD" 96 emK}zGݶ%Sh0ՙrfʪIř𠐜C#=}S ~Q#t}TݗY[2ļfǎ {]Q Qa+~f c{.iHc&գ!󥔸.n-_ OVWQaЌgSLFms P|'7+q=pe%l/L 1u+|̉I ?D?1AWC}^k"k'2z>"(&Ʈ|~XǏnUԑcGHcooE+/UU(fKuH~~[7~r zy:) (+r/\[L>_uϱsZSV5AM6;K?_MT.6ntlh~WAKsė>}~E#faa@ql٣gN?[϶hsuGΌ7RLYq&UmF)hixwc+{.:CiD5V6-^ N1D+V.g x< 8׉Gލ%9Gu?{cI=wbW$>G*:2~Lz|_R|l8M{ nlz S`~"벡OKӬf{?l]6ELYG/0cvJM\&1q$8_)o_c~q܇O)z?a}}uNeN?_83~b &}pіToEF^'pi|OKT'R4 ʼPD+ˣlFq/x<lOǯ(ގ^A;'xgnxnn7M OkB?4k 8Z̯|}nt)R^)OJns\Ѥu>r?-Loԡ~f8md=hTS׭'Yt4,SзM弮$9]c[ܼ/NNGXp_7<%x1O#ϧR]](k|f9o(񽌧 :Pn_Oy9SaͫL{>(7[)pw)W*MF&4)4KNh[ HѲʼxцJt߂7rP=?o A]yBFON>h=Hvf/_8q(LE,N^wvgzng,X5WpKN_{>^Hl4v㦷d|>5ڍ@ON^=;׮\9xG_fF_O-|Hmxoo2ak) ~\ }WmN)ږ<9G|_U_zx˔/sqm#R%-]CKnyy 'ͳm㔯aÛ㕯G\4bkE2rq.>h|/e5?2ݱ'{~5c}a}U~oA{sڔ;;"$HF$I‡ ? e׈sGoH5COD<%O~G?|= ea==Qw*?vQ{*D V}jo7svUUfw{ /7/hM|>Z(_=Yw?-Wey Wgq'_[_w͸<ٰCCw9x kh1VNGq8GJn~d<w},^ͷߴnN`1%+Ux4=Pj$t}jTGZt;I9H r^W҄d<'{9~%Nm}G;w9IVWm8ڃ}?C..a_ }v;jYd׈ }GޡSu8K2W<)(J-}_k /h)x*C__OdMۏlQ_Q:yBg$~h^VjDZ~w&oa;>9Gk_2)cwc|/U=;M׳s4KO7~)xJ.lz'{<×XOBß'O L'@1EXwk/UK/K8:}Gx X+# TWՋ -avHhFR~-bJf}<:R7_{R'V1uWOɬh]P^w- i%ǐ%[* 471=\5Rly"=}=9|9__p)]yݿ}o m̳w}:M#~n߾gyʳoi=tL pR9b5ν#fO¾6R%|sMTɞs)2L6z_:yv))x4d5=m#LV54Z|C;ePN/#|Ĭc4m֏R{ f?#/)bǏOYc)kQֳQ#g8RC) <40؅kO4+%٘IZ60ו[\(ןEB;ZdU/Z#Qɿa⌄5QA)ЦxU*KD](Z?m֚ hF)J?7(ֱ7~rO0߀.G*>E^~$%H=5xsL9Z`~4'>k33=.㪈3qfW_*YITt[|O-;1*{r5 ;ӯԥ.~~#oj4=?~CiwKE~)7QrkKzڥ^tR+}q/[ >Y5SWKag>\FossiӾ[zNnצ[8߅scP GX5'̵^y0R=oC/ P~o uM~2*4eQL~/r<P\s3$ТƓ.m<)rDUSiUUZO-(I'oq'o!&<&ٚ.UoP 0v ̹&%_MTy&Wḷb8E|^ .J_S,Ԧ>XHϣw4_V|D%fm$mc#lGiz]th4~iIhu~ߝ(du|U UrwJh<|a*&o^Woߨ3{ D7$O\"cmsNPcUFy,ǿMiamyo/~FޥQ*}x͝cPA,KZBS׬EDz;ˤe=o{^绳Gԣ~=іBq8~R{XܛſO|w{siKG?px@d45D-'jޑ2J s397yn}?y=1=yw*YlW}!엞npgV7*ճQpJ/SJYSݞ>.fwkg{ܽj9X]zhNONOy/? KGgڰMU>sua.='/-?b=둒G)%h =p?-b w()"fΙsު9wP=K~?8XRDwhi G|{:`B1_ɜAfx`V'ŋ!w=t۱Jߎ9R_4hqI~$C[&^wsu=uX@{lNT~J1o$l=_u@tc=wmvn{Ǽnfķ8?"[[ۮ'm0&?'\a(;SiȜu%$)an7GhRqh[?Nw7ͯ8fCrB}}9tߕ=&[v#v 9ޏk~[cbÝ1޴z|qEocgkgR@|k8~?nCo<_o؄dcwy~<ִ Z,?_= !'xT[{lmo.ܝ&obvvp)M2NX<]t]uwyUox5r.Yg]Y8;泖@?^Mu|]#Z{*F k{Tx{|3K҃[ў+'ֳ|ٹ҈a8/{߻d%= Yk>? Mj:,K9对skLCU8R'7--տyz{,~D;bkv]ziieC)ҽGSbA>ׯԡoԩTӢw:A=ʹM$Tw0jy#uLszFWV|\7z}1 Qp=gwZ{e8ߖ7w.tm~DvTK81L8h#N,t1|`L:f_W~<\[C.򟊮wݐ?xpNpkqq='~(]%zlq:_Wr˭s}RoY26UR6\]7KЗuBBcܴ82*qze韇g]r?[yx }FubwXx_o8yydzJe;| yF=\zlGy>ծ牱0 p+4eby~S|y'/1M_)ooU ՛MVxc̊zGN%{G[ż]=쑒o/{Zu'XZć0sc^È3Q:4`9cމ}^rTAlmھ2 0}UP5B0u:zk҈$d2vOv(Cg}˞yM;x>ax="뛴t7nўa+a7{θXJlcX\UϮyk6፬^&{Hn[n.s;.iƐW(v?ghqbr}AӬ1JrukшJ ;{D7in?Yj{녽l=^_l1$#7XÑ]@} |&ooJ?Ԇ+ B_`aGku{z]ܞV6<9~.g~4}} }榑/LCY23Uw͗0Z)a/>q?6~,c^OjΥE9 T睟Fx| w0΍\T!6_\yw.מm=;)yN9^=IRGb_iɼ3DZ~Ҟ7[KoyU/H wnܨe`3uz_uF]zy#_/1v`7}X'?q_Da߻⚰arwؑ1]kυOl8==# }/~x{{k/?=RZWz+lz1W;) vs?Uuuy]/>E(Xۻm@c]ߡ~HB ׿Ofin2-U4ܝ u6_?U=!e ōRq4GJ^W[}7kl1 [ci38iV=:=x~O xLwx~tq]bO~O_\/P6L=*efOk-n=+=.*y{p:̯>vƁnOqs5L;<7Z*T.~횤*"MuaHeM8q4] |=|LަqnWōb~="*<&O rK؟[fFƨSց1 џ)xtF<&p7%"bCfw<}ϟˮ4k;F8 -K^oJ{sв{ҏ{(W}glHNK,tS9MAd~q_fWƜ5aGM(#S cq<%oq厧.%pm*Ha"KS-od>)_S?eellvy6֤?OЌ8\ќG]Ӛ Z/52f2BEMEu Z`߆w:;I*`%4zhKzڥQT~=V#xicw9ײihlzvze672Q7z?Lrpe =ũ/bv?g_¨c\ aiGM;`YDa0;߼f0u<8?~G"_4DXsq_bHoizq8){(z`}-.< O\p.u[@ ,/sYwm,_6/n|\J_c[8[`hOL䛸QݛExC]R f9㿀F^4!mʷؚQTԳfϥµ@;Rf_5uryy5*gMs޹mϚXDZk/ѤZ)^{iY쬰=cUUng.1N4^Fc>nxU?uj n7Oz5k}a#j,;߬ϰ|y܅(z{qAn@~W3xsvQ[;MWoVa}=%cC)֫n6Y#y )XkiZXW ~'U~߆+mm^eכFW.?%tS+>@CQ֊O\޶ :^AYkvU>wN1@]ziN2͟:RMiݶ˵њ6J/Ƿaurʷ\_=Rj~+园}gKoME%ָ#!.ySF95/ƩduIVghNO/Ͻ5p i/SOŃ *Zͤ֝;dNn.Έ bעNkgs> #+u/<`2V&'m;h2*v ֿzS|{GxN^ǎR82[vwC7?j|߀B5ϿVaMle'+?CIRWd~qpX v oa^GMN_ Ml|/Dq,ppıW~޼nKTÿ~;D w5}ϕIrYl'w}}٭oA25dũ\j큼L}R.e)G|W˭]铲?ݫwE G2ҳJv_Q?oIRbBAzpcD:/u^ށkЯz&ܺFi⪄Zz{(g˛ O}Uݼ~_‡.8hO }-ٿ]ׅ͝4ݼ>7cPIxNcܯp+w*月_=tp 򷘺1|3룤_}oD6$0ǹÂw-lj4W{6ıٹ]?xgC_S²}.}iڅ5MnrY&=}m}w\zbk~S;Z QHU`x vH_}!cA`ϛyɸ=?d;+R)Y]٠;+oRG{ue. ծ6.j R8ԗǣb/yhᬸlq6:Ruf? QE"7[#U)_˸ۈ-bZq7ש{uF=/{U=fסLukF׽P^|~(g{x"9 "|‡9xǟkՌ4\&f?as|t̼~*oa<OC}YU=Ǯ~;>UexʪZ.OL\YR_|+gΚQ멅X; {)9rW2F)fB_ELc5|Q huy_^Fc:e0s]^]I ihev%f{>0o㤲okce?~0wԼgS`uHtIT}4rTUˌrߒ ;SfݯVt5y >Zd`6RVys(I.FcOy4֎_3>&,|J);>0B|?]S1pϼ6< pq닭)v-*S~`ΩBo7צBv7 Po4)4R4OՖxhK˪/G(cF~FߖcL~¾KUxq|vΏǎ58/D [hq&̓/~JXZB=OH`%!\kLxOd~ =TԯД 7M)}P@<@߇|aiȜG}&~$+Ga.mCy9* o/nڝ{,Y=G!֑#Z@r_5$sy=[8Vۭ%e GVw?<4c _e~Nlmʒԩ{Os/u^%UUՓ8p{6/=?*q ncE< {b,-<7"oAخع"<ώ\a~qB^w N8Vz\p'۾aU39LTVI$h[_U3ѿ?6hZ׏ :c_#V Whc3$%KS؉to=Xfk%<~3_b о:H; ⹵xle20o]RƛT6/ӈwDޭu}yay5<~"[@{, 'nB|~} żjMå3͹@bEsyS/̯q8̯C^Ͳ]w쿠OLx@^gaS6yO*tkb~㇡)cA 0>nq<[k޽'G.gX[m 7 +|op#̧·uGcI_Wy6wkJs4d#7~$^㆕xa"/x]꽹mox~ x6Oƥ͹]"_}صSxQd\꽁'O:Ȓ9뽹ɢ- *JE͋| k\8ꓳ?P r74gSt`-^Ýhu@)'o}N+V׿5qr_)޸}" |Uq?WۥR'x+"Ճ]ñ}jxg-عYGQY9Ž(O^'? W5 !@zsͻ& +դ~54c u$?+qq4|=R: {,Eru-KfkqI:~xxҙ!y\ʸAdqF'5s9LO MՏQ ZOhޟ\Esm ϗX9~cw|Rv <~`zJK̖S9b}#ٹfObOvs">+fpWq/ܦRÃ_k} {?);ۻ#xO1vӐ)𜒟w(jiEWտ {Yč_xz7|m>7hόwO"Tv.Q4gY<.NTF[bLJ~ؔafmWW 0-n7I3cɩV׸=aJUq?>8Vd\r\1?yQ;]М/ȹ;Y>AoQ ̌RuC=7nQ8^*B?mS _>6CaUe^F7 8o2-+iјƓ.m)a1b\v#ӵ-,t}v 0'en v?/+ѱsMT8{¯C.AJ?MMQͪt MCOVMrsD9zsiECpm+n<-j|2_OOs|ǓBַ;.}#Oq)tv17 }k_ԙ]c?|xj{J)f2OO%Q軜Nx<(1S4EiO7LyL9.r_< | {:2qmnRηxkp^#J۰0/̀ΌC 3Z_A#nܔK.d-7̯>Atה_iȜmwI:A -yR([\-ɣu 3g_=?w_>(/R񽳸]zhW,>]DG1\en~ %,iKș6YyDQ et%P˟|4ڮn^S2jZ_^$h~?33Gֳqb2ݸS> 78K.IRtR*.p!r ;Pr/Q3͓{&5eFߞ]X1/^J;ZJ苪|~_nO{hiH^~ܚ2 &wg/Uy=S_*?b~=\ ]ۼMIRr::$)b-# ؼ4oi}u_/d+:?l-"{}W SiA?kJӞvȤs^'|6]ȭ/[;6!&y4_>ZT6Rr.o@kg^st ϼ)c2J_7.F{& _~?5Eoq"qs|@kV,:'}0z-qzo<q)q#^F~WLE\.)7r^/|"ʺAiGX~8~klʼ m:|X_ϿAӪBxf2*#[kl|>f&oqfq~|jK1?p؅n ;:1jANS̟_$~.i :u0TwAhnO2ꊨZ{-. [{lN?\ߓwlxq;{aX ߻k4kS~t)RbʓRNy!jЫ(Xs%EȯX|ӺOK{Oxj ^I XUWSέ_t[ic>sT߽VNS}?1jI}?\9ŊfsV>x̮IЬ;Q^)SJ^wۣאzWSp[+>qD-ߊ^Ӭk.Qokl#i~`?QwkKwiwVNS}OͮG{/gݼv)bZXE=a}~/I6i}S/u )h6;/+GNiY\63U=<ft֯Χb]&N8Tvv3?^9w\ge[Qկw1ԃG? NjQDÏU确&"ɵ}h4ZW_'PZہ%nΆT:K? ')7[|Zh7}yG$3_wECo } :|3w,:{ ^!B8;k _W6 }S 9Pʱ^ݤ?OH)S4ʽ7Ⲯx<2W~)5OO<KS²Mb%]>M b} ~2Nu]wȢ\_`Mg~zR^(l݌/0aE57K΢+}R'}OQBN҄\3'52H^fPQ?K -n'_wY5Wy_7ﱔ:]s Mp+}8_;ĝUjiu,]xOKg?HE-NQgP a0MxLCY8wu2/#Ysz\t^?ˣF7m>W\z$c=Um6}/'uTf>sgNoQ+$F<]u2p߶oXFF5F<q k1m~-xXb _Z'r̉Z?x.7ҹΏhq Ok4+)_?sϪ?^?# )=FTL2 _e 9FFs YUs|czG}6yCDlkfǼ}11ƻGsW{Ưz2?ԙN-*exv$/qoq7C/seF~ՆߨmbܥvZ[=x^ϳFJێa[snkq5 L_1]d5=Sٽvoɼ&Iy  -mA*:>sDqIє%7~hm'Mv{(ans{8cRǏ=R2Na[G?}qj .NA,/63&#" 0vx_k۞xOyb}:!~i`Z]JG|kNfrǮ"w2fhwMS58!&V[4z)gnrv-hC=)'8oX/b/äW/SJ ܨMb, wW'j]n|=yL*4ƭs}N4Bc ԲgK c~1/U'jGyV-SEgܶFGh\Zd~sixN<׊2ٶS_#‹\~hm\bh7S?MҐ-Nvs7x\Ю: rt6?_GAowߧ}=Vޘq~:?ryi;Rf_kbCTZF_c:Y۪8d$)/.{boƒ|ȮQUix*ݺ>..:Q6:/ڭY1x:MCLmpH&g:w_gkagG7|^ƺܨ08X ߻u Z\YK3ɕ< vśѵ>X<\ ^V(Jn|۴`wκsY5Cv4Z ۯSVn>Ƞ^7ȕ7qY?*:J|_6[~xη$%,U8NDv-S39>{XB $qrJ_x`O1<¯"eu}!n~!pe \<# pf5Wpz~fw7 mC¾ω[ͧvxMw^OGx>^GM p)tu!E"1o58-u<]c^[;\猌__!Qߚ׹v^gG-—%= D6z7k])w(4g/jY2-E{m=Ka+w-zV#}5uyn^uQ_kH7kS-J2(0#ߐOug+8F?9ܩi=xil#.?"(sg6˜I<)a.~{.8eȞPQ_O~/e6S  ϤawU qA }uys)Vδngj>Z>žŃbo }<lv*J{DځD;IRB`6ZZn~KA}^C~Y8^8M.#zyƨHh_iGEgh?YqzRq(w˔91_쑘bķgp?zVgR͗)woN?3Rh9N'o7Oʽ mɼZOATߤ@*_H]λꞯGkt>./-]9{\l~ZjMXb|OHyhG~E~X ;j;߉3OŏmǬk)3R s - _[de4 ex^si; =n\e) hRscTwx ZOZBow'tv ;5̯ys{UQJsWY^(M~t=KP諬 > ([G2,?WY17qi)O4ޔ5^W>?)KK_vf>!fX a#F*6+|8*ⅥlWgPaЌgS`[o4 }r|`ד~i(KasE Meg|'7G9x_Ghc΄EҜ'iUcA+v0W T2~X̯Z\{򵭭yxaź}B^z;PQ U囁jmχ)^x2`/J0N+}=ayxT/Ho% 6/1;kcc*x^  J0 _jpO-2pEe[/%A௳QvL1v<#[OМR.vjNpN0Owo"}颱YJ-#|R^+h~.mb#wF_O~ bK_8⺘}.\;,p=595xH?T|%F3?O^\*SoR@|<_[?-_>=oP~fm_s٨+5l_RSE9)'f {b OEO8_63D㫢b~.ߌ}^?z ^hk~hK>K -x_Qf |x̺\([#6vc_w}3dF9#gRa~:F)G)T CZT,y)4!tѵ}u>[ =oVy\'ڨ1*}FqDz7zjxܗ3R_m4-VC+ۼ/Uj|uS}^ kbxt9ӡEU(W~ȿ#fW'߾i(WMXZfѮf:+8ۑkQhOaPo@m u~*ܷÈ7)XA_'5@5ݠ%B/WU@|/MTZp󃾇?BKh%aS<5Ozc.|PVzV(=>Oc+hS7jgnV(gkZ暃&lm1GZYmmNxȸΐdG¼KJ}zx`-cb>^aQNk/y :3{WB_|&Xw\ǯ5vS/OtgWxxC=hn3NTiaqpa<7FC#)>FgSLM [n}ǻ?W۞j?/_Jүt%\?0+U}hDSzHٻ VnH^//y~b蕲A.ztr5ax +r 9g{s1{4\׳=(&x QFߏ|$;φp[WhxNiK*̷$\B<=*Q'vvYlc\:K-kA 1ˋْ] d7 sgG?y}EP0>GWbiZ8w-j]pNLF!MЬL=`&Ђ|btZKk4tD/GRO㊘?XZ{:m~! ?fm+[,v(ؓ6fJτC]CEܕl?~Xuy5y)_._CE4S+}' 6}Q(pI_B웮=NܩRh|bJ=4QGd]h/޺-h8u<Ɖmx4ϋ}G>}x.ʟ˞)!~7*q/!SDF>jc=pz+%eo+>?(tHRwP "/9;~<՟8:n| Sx4X ~ڙ:r b-N(|entQx3_UcuŒCBw9]DZ#aZG@4YwW|($Jx 'Z*j D>%c@TυqAk[ܸ:s4ϋؿW`:ۺk%sE8 fިǝpܙ8SiEŮ;ÈV8ZǏJTǭ4|7o:?CEͺhh:~CK??UTƹ/9Wϋ} eZ{:wc/zb/eX(w~]ι`w N%)a٤7nw4_Pe(TZ(Sxgkߛjw秈/*_H'6,*t8Ϗqjߐc^z\$>Tu7bݞmbέbĸˬ¹}oLOx}]uϊOY _q̿֊rMyFZo}[?4vt4y!Sivp[ `h֋9C]>:oN}:YkM_tK(:cҫ>JSy8EV5)ɤl~|?ņӵڣxt&K0"e?U#5>nEk/}zxO!zE9xD?ba,8cxjQ#ԈK GE,QfJ/پ0E(4D.h)n%4?rg6Z|S7~6hZGO,y h9;MEK5^[x/L|8dӼ>[}Xp<:x9[aBLyεci*mۮkÈxg{xK#<%? t))hӪhc²s%%ZMG|F"c 3c[[$j>,c?Y!*+E#/q;qL&.ͱW$p|Ow_؊ ԵC'ҵף/yx\ 4^T _X`9WT#.88!c{oei8Y͝K|]%)]|B5%>k|3]]MțG/mijUɡRI۟N$M:-RlF Z#Ҷ< ƓeI&ף~ӅTk8m 3^Tvb~ԈX-oaak~gJOu&asRWƤ/'GŖ1<>&KX=׭qw<'G8`\f2ܤף_ң^Ox'(/_$5MIο8+\B<~C? >;O4BQp3xM6leJ|}.!Aԗm}WA8DAGGx9ܗrC1ۋn=Zhpc#lXIV&_k9xqT%/BErߢl+d m~,Q<4Ss~eBkg2S~|sW/e_}{}:Z\7uv'2w)$w7B=v(`,NǏWw Jb~٣z*>)yMFi3L_@EV[!Nw0y>ϢquPSR#/̏-wV -an|SyF+b=쎧Lþ괕lg} Ə:_{s}yL|^ɿegzoa;q#j-$iڿ<[\/pyOݨ3҈s4y|s-_:~]kVZOt?[c]~m s NY)׾^؋S-Mef]4%U~4_GOSh-ǙO7-_<=+>^C8܇@u.gϙ#^[q!~yB=Leϰe$L]VmCc/8>N h/W}Mu̸6y!~y}:=WkøHϩɷv\_IhKY7sF7~ng[KiԬ˯|dW= =@6ՠ`R_H0teT_Ǔ{ݮk//]KوfHմ(RKjZ2wSڙ ˊ^OoϼZQ7@|[^,31*2q)q%Bo]9aFlr8xvIe6~lg^2u{:8Ja/W_|"%e-CYUy.| T> {yW8l;y[hXW?=1yQ.Gz)l\ ہR8$sx G/@7?rh[}X_xJ>T.׈huX LO1bsu~tGxd)!LU7GĢ65 ͼ;ӺKrڃ^UQ+}E$1sRks=EUX_[yz\آJ走As{"lk~2/OYD=A!ɗ() :RQO^^_)(IN3)[7lDk$8wxmJa8ׇbo^}%8t\Ⳍ(+ӈG8hqS7UpW1";ۿ8H~5XT}Q>wxHKnLmJy6oa|<8 ѷWy}zaR+C1uм:@E=԰lØtY~y&7W gk(H8XGS(꾃)xp|6!i2g}uۦQMymۃr>?W~b~|ڼǕ%ˈvh5W*GW[fލ?Z'94ȷϻG늍GG/M YW3Ϸ|/sq}=pm_awE2ϗdGRؑ|y{۞g_?yy]|ˑ/-X7Q}P2j" )iʣ>~R|=q\^?\Gl= 8K3E{x MF:.{bpƇ\g[;߉ȋJRJn<yE"/ _::"yYԢFExh|JƽzWS)^C5a~.ns>/Io8Pgoxs~Ǭn̳*i_*D|h쮰Gq0bY|n3).)Z}b>Lq# ^'^8NP qᎱTo)˿}A^ݞ >)͋,҈-WR^/3~sv>Tp8bm{g"|i=4zt{4鱇I6^,9>Ӎo ۗqǮSbn?ݾg3sg;)>TKK ~k@ f mE YlG~Mޖwȧۙ!wF|N>ٜ.J?6yΛXOW?t;w/_g8&ިZyw;ˈ¦&)~;l?7qe׌_gSX\D PpME$kW?g|Y1Pok/$+lxT&ב89`ǽQ̟e=)pgq~Fۙ,Gq*N}ٷ^7,]9zkF>H\ty=i㾺x g~h?u>:Ĝ8:nÚ?qN[JmmR|\Ja=<ܒwߞ~(%S_s9s?R%~5my6<^=';~·f3^A_u@,)kyb/9O *0 x3ӳhLψ^ߵ]G?M~`„ƙMvS$*Ay2E: ~.ж3>??1ŷgwc| ;{SoTvDп/Ցo]v|k 7Ylq8*gol[v\ߟ}@i_F_H^,C<ί,^شy(3SJj6_[| }1Vv>[_KHǧ}]?brW^%׈U]48^Sy}*4~ەlťMc|/>5.=~P}瀋ܷVſuQًE] Z!X p/h ,dRZ̭ͺOه\ީδ)\I|]?wvy?}]WU~OW?__`03U翈 -S=-틕Jߏ< $c<8B\ bu sѕy[iIlf41yc)آSO iS-7r}f;jТAZvRhQIׇ?̷5i jZ˓f!nfWL$Ul|XEϯ{F:_O~ܯfñžZŚ>w5\3X :~k۔.KU=7TxѨB=Qm]uzp%g{yO{ֵ=dRQ~4=a޲?j3~<llPҔ~kugXaS7B_y {2}QVgS𺂟[Z?{9sݢk/4kW־|/NoqVu~ۭw|^2q+^\yV f\<>K˷r Hx~}ǘ2`R0_`q~Bj 9K[DuG3{'Ɨa\xUƯǙ%*ʎL^QN%/ 6j]9Oc?x,tW)z:,} 3G^Tt7]5%ӓ̖ihMzYk?w1yt3Tm 䁗ܰ#ϓ!Nޥ˜'?_F<n՜V:'dX/Bc-K}?:%!K{_vMËϸXRҧb45e2di4wȒ pXzE;d1ՊV_^s:4WTZ$&?Yܪ鑗޾$ ?vJ.c2KעJߏأ$iN|;gl/: f=_(ǂgA=ˈվ16M4)v|)'?H<cP%~j0R -ӗRpmy6Tmsu3ٯrV4Ҍ]=/l6O d:w?8 Ԯr{Jm8?hp=L{oG?UQ|.qQ pW®xx^mQ,#n~&sh?v~5#@^v;8㭭| ά3#&xBB5c|ۏ{SiToЉw?Ҵq&$x'T~}KA͕L%\I *8G^|$O_R'x3{T Kxq<ϱBdaWîK1q~TRR5\mPIn:qyO {yQx &yS@ Hړ^7糑9_~42xP 3$?&)4_;|7aZ+h{P:zfzڧdoy au._-C_ߩѲtM"P~ޑW|PC OBGb9^ W t3;G|?`9n?^- zZ}%f17lbO.r ΄|Ε ܷmo7CJ"?4׶?[ҭ9O"ANd^ŕפS.Ru!Nwgnݿk h~-wރV< 0 Ӓ8бazgK9]Nԇ|wXLs=:x1<{VOB,4ei|TV۴Ål^z=\V_dҽ`Wy`o97ldin|w~9Yj\R c-I}Z{ۑoO7i>j5EtucyOyd-NE$bkGVqUY96\Fx@?C: ]H/F^~b勉q;x;6GF|$%S[M¸[=W0W|1e)|LPI{.|`ƃyc!.ż5;?FWɮ3tκ>s{Rsior4^NB ϝT2;;h~*3Z8?l~=/MẐtwvO~\c[=|iu[=ޅ`omzcpL}?m;f}]p:>vA3 J/߼Dv8hf]#Xsuqx>l鹿O_ղ`~zWsƍ= {ǟzֆ!*jE߁ )KR˗D?y~< &l8v`ׯwc~|᧏ L+8Uľ?x9c?,Pvi57l>ꙇW7G(&R?o?-*jSյ8pGMO>rh=Z*{kFX7Ɓ`||dy9nnpew[}6=NSx3G&Ƒ ]xVagwŹ v¾#îmOlqcPpYkO/9*W$'#lbdBQ2Z˵.xțm?}"uG>O:WfhO7%n9ĺXX΅d#?a[?r7GYo>WDi]}I,nKDW.d8WCMgקG,28nnq,ZU&52n}hw} n\ҷ G1yf=G7nt~,źWao ]r:Ĩ lVWkq)2E*-Sם2q>*,^-7v*[S#6s5 u|w&X|ZE]aj:Uʭ2dL _ֵ2S9ؿnf?>_W1*xcCHHƏ`;9k+z`[L#1vW:yŪn7=H%l(t՞ZI\[9B/>01ǫhy}DDu?fbY;H?e^W.pMO`] ;~0~AP_K̤;ʩx myShͷ ;vyJbEoßןSGzs׎?qW` {48>ϴ;c-0wqC'ON jGӐ,Hx=|Jwϻy d 2NI7^<<}=eK)0>K`35/> ͹`P<:_3V߳H@_.o[4ϋïrd xƾ+:nWn%;J5ߥQAĞ?Nf%n1x//{߆v].z] d7 v<Ϸv)Cy}*o PTt Ϸ$οSע6e}NI)ݛI O |4r^me v~u\%oTו]8zoqni'^oT so 9C<ήI1㻬+?YJ(UJr^6VjVmۿk (B8YS-Mexś%T3$_7煍(K@sUh9?z BQ iFH'^|~hl^uv}Qx3^T9}:f'(¾ |}V?P!y$vx'7bAq=c~'Dx3^?z.\r{d](4$eo5;eWt"4N2e8 Q)4Ku!?so9a |25R3Z?!a7x-//ݔNlW{[~xV W}l~U^hk py~_JZ'¯tL6/I/t6kUQދKa{ѡ"&L#fƵe8m*뿍oɒ_J^̭jM`3Yh}DwOVQfG*}=Z$֬ -SiS4p b n3ǡpiiKOm2S=^Ňbr]-E?'$O+JUgԋyqAsM;`۫*"^Z_V<ϐ?;b}r]u1ηڧO{+T|:Y?NOHPI5vY-CYzKgJt#|δ;=Iz0,_NZ4zLg vyљ?4%y>]K;JMܲr8ñ }`8Yl ly㡶gvG%\BmleS`pN9PѸWjCJ-jTja}$OOTf,*^ }/PA2\kI2Q&ˋm)7\?I>#3`{S'l{HM~u~V~-nTҞa$ |/ k f?*w˅/3HRf. z7?R$Wg{g {Hۼ4ZsůB;*eC O@iC%(CVu$xB_[>^.934roneY[g}l\ƙ=g]եܳ4\.n72K qpwIb=2\ut!FԈΏ}uNN|rwzwp%gUK:WB+$8%}7ϳa]-=J+Nwaܦ͐#hkΜN]Zq^syxq(4&5\Qh?y[|8"B`8Zgלidͯy^|dyp?:,tMY$fijˇӏÙ-ة}5W8%ō[,xk~{)AE)=!MI}<&UAwy\Dő?ӈ9$u4-.S! .?\kڏbjp [XwqäTTvU#/=RO9:@渱(5XK+}wR#S(ngƼyMf&Z~KK&pe}G:͌Qe@}(.oAȋi{Pob7)Q_nw^qv{$WNű͏bWJ<.OSLUb5bqgT#N7mݝQC"ި4~,͘Cں/ץnB_9g)S5p~]fքNѧxM*im*"|,ʍRgIGg?p.|Hb>Tlþ'xҬxW}7y|J(C]JQ>$,Y /1Bnoh FޜsXU#g3b%ߡ"WziDzhz'OAڬ2W~;O^Nj@Z.o`^Y_vuM߁}<7w-#[dys-om|+ڻ6_f?g$/?QXiHx< E` dӭX<*߿)<*㻸v>'`pG sɔ~?-g-=m)X(Vu_?]^+ed.KlY_:-n9+w|/-MyTVR3rF[HnCzC~'İy^a;OKK\ΆSz-_2v6a#όV5>fhyVS*Y@=gw}k)ijfC~x{6;i?*xxi>Bf| 4C4oYմ_o;Gx)-Wu q(POb)n+ISv8tTekOS Q;j?s7Uh꒟?Sxoީy'mҴqv3:R1|]nWYz6J_>ބӜw+f?fJv4/^piѻ&|MΤo%CW='kJ] e*"5o.j:V+kśt-J}?BxT8_wKop{T#t/|{b9GDܥK\nyNZ}6f ڴzl lnN P ;/&Зwawjr}@ۈ|/=1E*-Z[=+M4,^5.5iN|} ]%>5x>~_[~]ggaX v->^@.:Gy[uWz>?4C[2ܒwߞ~T3[;}n?nFdߑrR/Ҋfj#S]x S㷎ųV~{.?f=ՙ V||3/U]^ ~gαh\t2<C}v;䗚 (Ma\Jŕ_ǩu3ye)@ѻO_յR#8%?._g/'Ŭb>=å96ˈ&XwN6;nWR~ăm'L%Xr߸*OPF^oҧ^k//ԯwszw÷WKhy-r14^rA%Z-)74-cz|)Y_Inog90\>x, X.nX?8|~^>%s]3̰ =.~TRSnp)tIY?>jGv5^VMe?se_R ZqGlv??b9E߹]M6%p(x{ti5y\|p21%gߜxLHw-W||mHE.ab 4U4|lI`9-Mx2L1"$o$p5=/|&1Y+I6"C;߼~~~h/#0fU,u|aļ-lhՎfGpa8SNzR!X?NwP^VyC~} heȝ>)d54[I:[Foڏ|68yßX 5(m=SS/.E11 _L#f=Ϛ@g3eڿ =dy6-"5H-1zd0JtGFn~mT!*֜ї=`ܟŶAk| G[ OL҈` eyf|!nB>YiT)4|:@[\e7vKy?> \"#Lj٤ 9ad8_w_Ϯw1v /*ym >u?M׮EkWDWT]~tf~Jf]/-,~ʻᾳX{-Qе_ Ob%׹|2o{z&z-o9kaWڔ+v% wy2<:?--(֛O_JbQ0&FsaJgya~nO HG>iX{.õᴒF_m2u~4]qҜGWLTVfGm{Z1?îI1be1WpR@I!7oɺEh]S/k/ZCzQpBʁGzsQjc,Mexq >W+G~)4979iKj59僭h?{ۗ ƩImU;#WCؗKyy>Z?mn\G j ᪯ ~TߣΊ< 1OAȿMS E֒?OZǵl}prʍh5za݅P;9>4<oN?Q7^<ǩi4(dIonFu{BYL#OeQd/v> HV}uW񄫕D>,C[e(]v8-K6w[\iH NP<7 VEZ^<\s6<D(}Gp /"fb~dW1?ց|T]C"/Ug'[|;G8D*{4Ђ-u'x ux .&m>׊KT8Pkv0?G}nw?l+QlKձDyFg#>bT3bNbWd~B=Ɂd8׍n<\AoK?yQpފ^Vn/} ҵGJ-jTj}҇mڙªR)Eӵ^$ ywHsSrs0>7q>>(ǕM%}ہ5wyMfh_k37*ynD<(Lj*KkQk-|2|~vlq?nNS]=b8(qrG+߻f2EgC"}[C-`g)>FΕqY~7޹l6ϓ_ߏx>?q۝E7#;xKN1kVmuydICް͘CǤC}x#}).RuQPڏQqG~]?XֻuL)e͌k h4oELp~IsjڡW~%m 'y}z.?7ydE}Z쟅9:ӈ玅؉α&Y~KF%[y̻A3wKt3M ?9*9l}xr)Io/yWv/_ׯڍaF\pw+̏aȀK__$ƚ<@}N&nY[W?N+ǐiV_%7XoD$^]G۟,>r{$ƴTt}_y+uH%F-54 U<"_aXꢽ>jq3{^>hGIn_߮dG]Kbm-acx1z1<_4ϯ/7[Rbs}SDu{,xB>KZM?p6 wng ,CZ'q &J顉RЌ+s43~vw57x454ϻ/=G0 v6"Wط~+J"r<7ˈqވC1 Λ~3]̚S|mmR0ط*K#Fɰ^O!AwcDŏ3絁m|g^꾺BlӾ] WknkEط+~ؼ>߬qG%7އKk:)pC-v.o_S[Xg0^SFyOMz»<nՌ{LXvxP/5E2dG&ms]L4^%d知xC.R鮇JaoܲWx︖.k//gh3 4M߯IsgؖAZk/gǥ@עc_æOM U|*ZO֮UbE,"ub=\m:xjUhENvdQ_VW̳"Iثzsl^c9vW){pX~WًD!sW {_,/?+e^_5vIfu|sɛ"UkG}_ԏv2K~DmMS~zJޡ3\CEq}bDv5Oep-_$ oF5 5\zKW^tYF_Ays/h=(0^NjFYoi_m+ 'e ͻ7ncSuV,ΤI\nsz]q!SyKEּȌcϊu <Uүy~wLs;Eҕ}((FӝgP]ϜggR|XlD#IhvMZgS>%)Y$A ok*z C^~/eSp{W~O}42,i"Iޟf?>fGw?a>v/>f1g TvV#;6~bo{lv4yD ;7X&cߓs-H ]$.x zտQ0_Q W|&DbPqq|]u (e Auh}D[c{S K1>TP+}?bU(6^ng;Xh'N_QY $lRb / cbx n<n,T ־ (D}SH9=HBY-8v52 ͖#_F饮}Ww#$ZOom ~J*F*m*T`'Q[ioί܂߆]K5o +"îP))Ey DFjƦu.vi"1ş]O=tҔ~i;CwN2b=-fC5|++}].TC>ڰW_x]JQ£{cZW~|{_HohÈl7k3ωϠI}IV7,7oĿ}3ʽ4WǕO@oN4*`89Xk 0b?Yez.!T|XK((/Q@=5a=4OmN d](Og\vX8dWG*ٵ=RW~;ljBTkm+l-?f[㟱'֭ϪFf5 .W{>D%wV$ jUן)t#kT?T5zmoC ZtɾR6JfHs9-Ƌ0r:g77͇Yq1{GdGׇbGaxḳz> 2(6Ls(|SeȜi%P&MHJhs}y(/+kI[Eث"%3^~- ^DW㾜N3rۊ9Ui=]Cl]")xrEtdRY [:n~ Ҷk(to߆;iWz¯&erNOD)9kO}[V5$9Ki_+^D'RVxÞOU;y~eca}$勏W#R )]X=6wlwSU%:|}03\Sv% #=;- i?m+nԊ֬ExX{-G>Q|>qiJbsb톟K>9;:X̟o)Oɮc,tᖿ_2Jd$};D㖦ܫF鴼f龵}Tr#)T LhLWzu {]IE*+ ;1E/Rp%^P Z|v&䣵'vԿeDwq**mP!U^s5%W,p7)[~72|."NX̟‡7oى/dQ 1Wa~% ع>Hyܾ`_<Bg3<1N׭/~}AEۥxNϮ5)xCȋ/O(аPQӯIː8u S}4Ƕ5~lJsShO|BZ;pgW߿?B)=:sKE_ۉ|3uC|uscoTwŁ}4v,?%֜ku[<Έsx!?z_0qAz[>e a+E+Q6;wt4&w.!]L'e͒t/N5/?G]v2m\b6{V~ʋ{/?Vԯ5qMx^`ܸ::e9%"Gf>8Mm:0ܷŦ m:K&fQ=ٹ,w@x`>ngoLO_ikԢˋ(Ԥ;ƴ^@фF|}|ig>a[*.{h̻X֨a>,iE|~e{Sѵy_7*/{&;׮u:un>AkRxѷ?/W{j%h_/k9㘿}2 O(|jo/MOwlD9;txLʻ;N[F=R ĝ.񑱖%xH/?oׯ+}=JاDw?ˈ]O"7v ǻ FBŻKq'#{6wkB။zHx􃕿9wW\B~gwB%^KobyFdUzѳCЪI\#\/y-JF{zPqg\9uBwOpCd?}"z͇T }~'u!k/|Dd?jפuWsmg_ c~Z4ϋ~|ĸ/Gݨ %8t.\Z oP%p)|;}|o +YjAV8G)ߟ| ͮyIzao34pysD#h~g#s>AKDh%X탉oU@IO,޲GQeBn<<Asԑm9ij ˈǂȿǮK1Vo,%}Jy,TR\p#ήzvy[t_T Ν+:E~ך?{99V È u`JQS=o{~/Ϳ;bَzdzȝv.]tω=J,y^T#ϧK_x`߀烹>ĥ98]K>τw53t:냙qM<>?Od}igD/O;gZ/2PpC/e4e!(j1!Np}d}h)͹Ή oH9]uzK֬ U?!_B>8Bn{o{<~wr_o/2byx_ ͮ9 1?8']> y\9//'}ДM-ͩ^"XM&=إή>9\ ''OE~ 9i:> y?_6u>\Z?M집k@kx|xetqŷ#>[\څҡx녑F 4*^[fF^rA%bz'ޞׂ WyӚ83/2Icꠧ~]߹}ZE_vT#W+}5b1}0/U6-<ۺ;sqr3M?2l43>8]%oMo{a!NLF4NIxwAC?z9[q̈́8_i쿵@17T.% 煍0q[[yo/k{ f y-_XL{nWy֪1NN?{f}e]ep^//f컡פJ>k^2-!|6xP};Ϝ/G.j'Y*n3~3XF_+^vxer4&] zz՞-BgEu |+~n񬈿D<&4!ZNusSץSgך|{m <+3eʲOŠ J]KgXr#7>AZ%J^F|GrzǣVl~ ÙBj#x}fh%f|S>M9Sp Lr/bϥ/7ilQ<&s>)pk~x((ؘCp{>z?6s~,b2q4y'+9ӯ:tj+5;?]FK*;kCAג4vl8}|"߿aw5+#_9۫p׾ZBAc rm< \ng\umU2CLl]^-qhs7uN=Z8<+ylc|typӔިL %֏FAil]Q| V.&K}P (eˇ'qb]L|O}DOk?:6XNk\egwץ.%&Rv9J}4~W1Jr+?>?0}m(MEZ-MNܩR+c>ܓ̛х|OL(#/Z~ܙ֎'].uŇx,^/uڞ:U$^EV<9!k;z ?פLJ,Pr~&1^ȋg_:˺ M`Mpڞ&9ӵr͐zOh\. gZFhڟzP5+z4f& 4ZӴGɊk>nv4%Gb=1?1?xuS?x QsOSBW{=ػ 7[ hoan^s:҂Ym*g"_Z%[qӀ]Ni$ھ$z^Ɗ—xL ׯ+}~<G]J:筇 s=vK 8x~g̖4߿c]es= Jr*jz Ե_W(EAh\/tp[#K "W=?L0StrHM5=< p{]!.k󸰹;:k{[avn>T$eMg޺wQ{Og++ g[oGկxѬY.,9NS+ZYӷy?]uf%uO"}X;~iꜟ0qW7*;*̕\/"ryv2q9ÌqCة#^%_K6jPzL>˛\5oEd}W "/ m;qf?VjQR*F6p~ /e*-ܾ={Kŧϯ,.Gf6`kg8ɀ焽g9|FL<,>b[b^{K)PߧЙV>jۦBm{~xV5$_Ws!5qϼz3#E="Y 7g-c_~L@5dRY x^yç佡Tk̺oO?<.Wi8YB5,B%?\F&>ԄO)k̪V&fuN4dc}ONs~ZXG,ҙVsgG?CrƁ5?ib׳G:ށ*3{|qq{JG,%~|.lssVlI_OB\Ү٢̱'_ }yRvge|{,{ye=)4[VnVz$%mRx|R;|>jD*,_TvXcP=?xcy:d= igîVyvuM>o::iGZ_]OŬú/pPs᢯Ӎ 쓈g_/;:dZYjn8~4~< >j Ǥ e8%-Q#ufBx̸~g#g׾<{ڛ~ ?g}+| 5PH_((y`P;댧|+=sam{)ӿ?L۪R!‘3H?O6PR ׃4R#ϏaRzԇ Jq)֍ԑeDcغ?; o9Ns5ʄ%fW\=+Pa3cj [?{vmеl:=3^z&mߩ>ʭ2dhOt⽴F7K> h׏$U vkgIr|3z'>,\Db"gz To"0~1.5x׾풛$ο.N~Td\|3{]8_?c\pI/t>J|pɣ?:(<YFz]c%a_8>w‡0ޟ˒RPau^i!K4yM}T2gј~ >/򢐚/iKO/?N }~z(9]ܮ(lUW+RyJ1{PT ߟF+jOSka 'kSIͫ: r蒼FPLzjRpWk.)]VD>iD+OB~ό~x͟~L|'_,#l?p7k|ACMz»<nՌBP@}|tgMLj3,McwcbLrMy2h||u|iI_^h!mGO"yamף/+/7E}kÙ 'v,#a'y→)N6lg}]yy=`u=ѺfLQjՖTRkGO]W {/e6%Rq >הBZHe=h<I'>Hc:Ni~"~wGxcv;qG>0Dcx/#/p)l܁bkcaIDq$cȋv&3[|/?eS-Cl^-e{5gw y׶/QHtp?J{oGmrk\ U!lb~:,VCuNl+2 q{gj@%OWQz +Gwӿl+_k_B.9ؽ? 5?h^[.|G:- hlG=3H7e@u+BIEEػbG=?sG#YBܟ*ĥsC9n?dתvKm72~P%EY YzAK9T4Vh2\P4s-=2iey?|yp}>-}S_MW/۫Í$ikA^FCyb~߸7*S;xq)V\&Y1·;_s-X,%}JnVr{DerB;CD?#4]k|3]]M{O=6~cÈ*IR>^\2Z i}KɭJ.c[4ztMУ#ez׫Uw&aol8Ě?2׳!xmE .bom6?M縀6v%*RA:6}UoAAa=] ;SXxukC>>ǙVx!lv$]w˰5Qۭuq2e3'älDھve\8wDj5p |gOb]z}E޴L -PӖv%28.gԵ#Vs}eK)xӀ7u !gG\l!s in꿜a)e,j#̼k4VǏ+'M?9/6ֻf^$/.ޒېUn/ktvd];⟶0^ M\#ӏ= Tr׾i'! =?@wtäE2.**~:~9qA$6=`ޞDMfh7KXCm_Kr` n'MB9fv'_8s'5)\T{}NG(P~@s;lu#Ea P/Ѹ?F[7)whO|.7֦5y4}c &+vQMn2AY+<޹CoX&XEyak ;x0J.Q(Twݡȋ2 g_@zwYZ =pP}Od8XKFߎ ~ԝyͽQO)lNB)l/Q͈ͣ2=؛ʗŝ2<4xe2p7R#Mmvi㧜\pO&;纮/ß7ٿx>?\3ņz {/#Ljڊ-Fc>_G᲼|ȃW=[Ύ%DZb[0q6ϢH&^§ =39\*N%Ǖ&_>TI~1ň|l/Dؗ"W+ JpǮÜlVp>m1^j4%itÙZOBouxRYC't^}Kϡ'a~/P1|-^j|ѦoԾ}oʲӃe^g$ZmJ8Z*{hӵA?1o  yvk ~s}D\]JC {cMع8bDqempWW_BV"s ߚ5!G=2l,y2_*>WOYU2X[$~Cr>2y6O]sm&HSqzӦި; _銸: #޿[[k9LL>Oq o ((Y(tw,QR([OE4y Jeqgq/x ?{E:G}S$VvoTW[Og(;cO]Jb=WZD=} <4Ntɲ O;Ou1Ս=B mg#C6+Y0%i1q9"PlQ̣iJBTNXXN3b>q;btSKYoy2<]J@TrƺI'Qh|^W?mk5]‽4Xg)BT\>:rf]b eY>sBQ_CxNџwS(=^DJn v賻q8*9k j)PᗑRK|BS?ͺB,^V=?zfJIk^g)~pZ#m/&NGמ$׊cN?My>]QmOor=v<#SX_^F|kqƭ$>=G钇^k_)y9m{SV6m`o)pҸu{VI{3꺳wq_ J}g«^:kp)-80s iۭҗ;~tkVgZ1dP9_a=yQF_*c88^zp~4Uq6bM+/hƺ<e}d=mUX,\|SDe/Ii lۿ/Gگ+OmGI{ULO*U ײUDa?{=xdv&X=}__GL_Q<OEl0ܐ?K ػfQ,3k]n-b IXK<1WT3Q@f?˽.e#$z3)OV]M[qz[%vyӜ9>cA/fY,#gƾîw!gye> }J(zR/q{RD9tܗ?*4WO5/#qF8xD6~xn`\}(IQ7Z/|7|bs9N9 pg!Pb׉?ˈ N1 u~ }q%W2ݧl$-WﷵvH#ڥ>/nd䓛h>VƏG}Ad6:X+Y&N< p>>ǻ2(G1:Wޥ7ly^V3xy9M7;:iWϋG[+q83x 7Rػ1G6. ηx/$7 qs8MV?^GT\ xL7ּeU~J3nhe'8ϪxCg|U@8 @vR`r!xхNa?jcuZ }ܤP}0Gw|yMC_Sx͚7)mpS~/9!k|.wk]vF5(ѴHMUh=lZֻU*FW>.xG^|bJ1oo~ˍ}0B/WMID/nrgͮΝVtkAbS{lyZ5oqp`"/ȜiwLDEU #~q g7=HsnG/_GBU{{i瞿oj6-bN=Zz9o} ո[4vt⇏ף^ݾ9_58mQ-Ib*ֶ+Z<~(U4-~X} "|^~OPZ'z,g(MW}l ;^"3U($3mSPo^дO$,D!sKgytڻo9hUF;T_gʯ#(W$ib׳j*<fsgQ/W~Ql#ޟ"t9Oηb"Np8~۾zhkʲ׳Cu)yr؅dr>?_M߄/{8Z\.K}֭8a!M_߲ab=W X.K#߈g gq0Yrkqz|GɊ'$?1]s0X~'_'|X_[?\I;qH.v%|ʧgJDɛI!3_@}y;tS oʃ%b˓MU7m$t%ibI%t>#7[籾yC؛>xio=6Jds}y(Yޙw'-CY8w=&FBN碾fv+d<4_ ?nq_{?r<ڋ ձ@9Ftz=Ո_ S%}L(ɠFyC)7]}p*3OP_j޺& f_?)u7U5eƣF4*Ri 4+E|Ђr~h9+w|GZ,D/Oof%ibv|GI.CҔ8E{L?g!o1wOcokW" U߹, b-(6`>7ϡkP?ŷ1^vd<L ߆}7⊋B9=yxz-^=}t>woה c`]#VP</Ί[ϝ~[p̜㙝:8 5䎼mE]{m/RЛ<P`O] 0AO;!p%g=hG/wly#mxW 0^៓8?DkTt|$Qx64 u?{Y qa,z/ O7b:t7!uy[X .Y:=3b<‹') {߿;ۿ8Hl8C^}&brp- _RP@97l|/=1E*-Zղo^%9)sDZxWtQ{2իoTvR`@ձԈ ={ d.^?o8O5CtC~0CQgEdE!sWvN[٠OU\Q/@ֳٴoe:mqi< '^Z4vt5T9:^;oc7œKl|7Ib |dOP@~|/ͮy(}fjKAh)Sw -֨kxyQzW mI};6RԬg}ˋY?ڝ$JbYX=vWV{SuXV|tl<8d#pۛ7(TMv~yycRe(oj-[(ܿ@jPUoAmQQT?-C;9\d) hB{׆EN>ٌ.T!a2Ҥw^߅z48+.ؼ6>%;d̷!װC LG|-ʺug{/P RyQh\ݎl9;$Cegh|bJ=4>"U-SL]{jg}?؞y>71  ׯ+ynW6h9S,ѵvov(X'b4U)@}^.5oHE)﷡4yp(ZBDɍ=/Neѵ_WL>RF\⤘zx(z(ľI}T=dt\3-K}?];φes^>_X/7*M>X q{WK÷ۗ]bįǁ8d)Vf> *d}v35׮}Y~R)XyZ߾k|[NFEAci*O_r{eHQQ&Mr^Z,[SU諍GЂ;"}$~cv( \' Gwy\d iP.|mOSع{2-q836x]'ƛYu㰷q~-\ͥ[N! x+/Q@EZZlI'r4GV@В+2*~oG79'"]1۟|f}(uEL\ u.tN~ :u]ԣ$۷g2>_hc\{kĥ7O6 #aJ1b:nE!Eg3% YYAPxSS(C.kĻ! [#{\wڳޯFXקe40-Gi\gY@WJ{89^vjWo5["^-,_*<+>}jY3Iϙ$2Rs؄9- a9'a/}R~'mVqH< O:Hkxѷ .(Xڞ )л˵}W>-5Pw#ۯ8MوϻP.<zH6kS#ϰt޹ⓝ9 7ӷ(!(Z>^F*b=}goÁt|?:ǭG8-gGb~p`_,0b>f>?[xBw?'x ΌyArs3C*wn1"?H *ڷ߾`rNf{p~4użyJ""W@;IZ] 6><5_)KIŸg[!ɒ3M?ݑyQUiRu׍)=V*ף_ڍÛ j5!)t .mV'x_l`ҧdoY?{;xPܿwfcVy5x&X#p3߿3ds߿ }{wʥL>АLAAyNG'q8(0yAI+ C>ـr] 8߿=~hM`}^xBo6/c 6 u|w&IѾA'd;';dȮMWlO[ee뙼$<:~QL^~c*_9ηcu7a{.3~Zz ՜s<8m6ۏxNQt j5)Wδ1>(yz?; >Bčǯ$":hy^( 2홸s-Q"vDf4]cɟLj'B%~CrRs>C)<"{˺__ke |\mOɂ/'?f.*D%s @2̏-%*NluϢ1=23"\!>i7Ńյ=hg<|>\#*ֈ΅޺_ }4t~Zivs~*yK} b SQ`?[)k|.wkÈl_4TVZ:!(nƖ&RmGAy~ V4}0 v4a]NkCP?XG7F?mac]v]5#~,`k}:%ub|O>Ͳ1K7oB{n.BUdoX񿓎o󎍒ʒ~z4U㧥,3ǖvyO훓x\ ^4n~bצ) ;㬇u:q–֛][yt!~w7RU_i}3H8)[:e]܊˙pq\1wυyqҔd~:G">%>o_s,8߅-mS+?B'|cZ2dbB*?KSWiztcO}X#.p_ze8rm8q1MQϯC[k݀Od)S@IdloC~M2fm E f⨝^~]1k2Ky)R~\!6P$YWnuIc/A) ܝ9R;pA:+#Ko/pM"xZs]ĺs[,%Q$b_-;>!SkO%%(~ZLAWP|5~qF4\lQ?rEu~L}h??>4vLraua:kISx9{q)lg!ݩFt-?6?o8Ϳz:],_~{[AƯWG%/~V H΍|EABu?M~] VfHكmZ%z:h\w;J{ENw]{<<Z?<11Yծӹ_II{Pꘪ)vxaa>7صVuOx>ƕ/Ueߪ??/[{ȷC^hM i΢Ig\mZ[|EEx?dοc_X/?')}n!-v#~ "7@?`?v~|]{iqiʏA~(,Zl;_\'(l0?Nbsn_ޗ'q~G;}6 =RFG~rye tθ{?x՛4FMۇ!HK[F>Uu9x`\!?^bJἘ둄Ql?H%4X;O<+`9Aq[t̯^@ti'RZ=7 ̼<΂(S h_ϻK{[V&fTp>30npQGI,'^H?oχJ:L#$ 3iD 5)F(tF>?LY|0 Mkz$ȡpv@ )4VPHԢv%Pg !]ݙO/τW7^KN|syTf~ZTNLI_xK{+(W8^^G>\a?AU]pf~·0ƈYVU߭^߄~Ky_TzILvYF%:|}ki3P0wWNqjZJ[7M~o656zAC׏MNsf`_AugЂWKϽJ/-Jn_',n/Vs}(YQ0|P}\߁/gG.9 a]mݳWw>]W/䑛dM[>_Jm'w겻VhhS;f1RWxKg CjۦBk[-:N# vƷ] >x}_]Z^`}G} {5{^vwi/ ^-ﺸqWP%TFm#DohWg2q)tu;Dۅ<ϊ?Yǣ /B2-DTңGU[R?D^hC޺֬L8} #~åPq "5y)@hC#֎ӵ] )osVwӼv~~e6LJcëz>_o>Y}^Ӯd;j9N@Wͅ=UvSnߗ|Nq<>1?3݅?,_y~A{u?Èl})6{4ZzWϧAI}?&m0c]t=8x8_uYVoYJ(<{,;ǝD_̴n|{|>u6c~2&QoJkEQ0c,}|7FJv4o+"Vc1aMy<,T`t(4&)NA%^UEW-M箲)JNlAeSh:+%*Ɓ]2X95y<;:~)uU2n.氝 8t\`aaq<,mOi~v>99oeOxy9(7N z(PrYOWzbe;)4WϠŵf]hVFGxM<_6m*ϋ#i6%ȏoJ>ťg[L#Ɠ.; -}2/yJC>0` RbL~Tp*g?@w #^8Su6h\4ϫGk#+U2V}]r%V^qůYm]g|{da l^xg O?9̧;F%[yQhvnkH NY9o2qֻ9;4LJemy\>爊F7-rh}:>*gZ?t[]ߏ4~{X;t3:ׯO)ɘST]QGFo*x2U[?<;O#9?gj]Y(k;ЭϦu?z*ZyӵGKvwOɤL)hqEwo|*rxOiyg(ITt'/+//MIG+y1/'z(_; p? h~V|q/-b ]13y;viSr/|7~u{b^]|GI3ˎw|kFe:[k+b\_vƃۻ_|)]wS8?x~ ȋr9~/ͮyQ\_aJZW^rA%5'D^Dnr1Sb+?F>+UQz:R?bw6萎KUž ÁB[_7\(<;^S v<Ϸv@vA69x'|~9KbʲǹkQ:Qp GyВn|^$9Q^CǷWZN? QR^ܹ[}W!U=aB v|AVtof[ŏC-R*Ԑ4vB~7h1.RuQȭ͗T&iO̗:EBsGjA2fZ-m{v=!L_J~-q͓9dI/I/D_֮9MIؕqʢ^SLvuac x':_S0f޴&צPm]ߡwPMKE5774)19HԟjЧmXJsd<]9D~+u>FxAQ[hשE:K~\ԇ}'x!q/ ;אS ;Rs~lX]"-R}ЪCgtO}>"]9:N=+(IXő޿ף$['nosĥYv' k FyQ g@g~00~q0LO.-OHu3MvS<Ǐx<#<8L=JkP)ϳV(ػ`%$ن^XKEmnw1ǭP#4nrS翖A &Y+ۜڻ2Ӑ?nxFAWD*־~u^+?H?|oÔ.5qcX ^\cx~o_ wl`LMݻs):t/~_^[^{LNSʹKHݑ|6%8uW~eF0> ćڒ4zl &uw̏׶nG=<z7cîV>~;z“}$Xgaُ+>^k 7؟_ &3ͰЬ{r9bץ58J) B%vYwTgې'<+LJ'-oQO%>!۷9̉.!Au{)oi~A u:K/D&FBwϓHty"z+綸|bܹ-69S']}:A3hgeUoM4j4`cXL9.rE8aT;JOlj VgmW}cH٫d#~g=6_i+G99~9iZ;Xgs.M>'.*pBS`d 7\ M|gV}L:7?(?2kf x=n6أp[зzrω8)B~3Y )73b _o#<3mN|%M|pJ٫Mgbs)[RɒM< 9W7d=g|ɬxJ}L Nٛ _ͅ>aJũԜJ_o G!1݄4(]sQm8ŕk}1}s$#~,SsO8>1y/p饛EC}(B7CxR:wM&~o=|4LAK/x{iz;0l}'ίgɼo2♹ǎX:ϕ~l(r̓S/B&hR`;|VrEvA>< fA\\7?:~Lo|'5!ՎE o53 Œ˕> AfQ5q7Gɴg/?oOZ/\"ʉ1 1})Z6#s>[ӌ*i9o0kL=<^'Yꬒ|dߍCL҇B5œYR|sz~YZLʷRz#Ir1$FK&gI K ˄fo,;Ǒd23`1O HiI뫤+g\nЖBJ;}&EGt,rxkydI3l~?!}ATq*YjkFҥ9_wuZ߭!s?[ S{ OoHNj;4iw.jVpOõǓ6w~7 4BfJω* NJ_ Z~\H)~|O/~<j) 2.WG '<g7&ځ?}5{&tm 4|% Nܵ X#s~VS6B0k6\ )T{IbD=ᮧ] <^ÿn.%)xkGˀ.RHyџr~~8d;x~ i)4!𓘾߆ptشMm w00\ س=ۍp^)/OF]U8&Ke!G|IBJ/_[ۯϜ<^~L3헉> KJ"?ή 1чUVJ?N7"A}h[ޢ=>Õ9:\Ӎ'/uV9񖄸\R/<!~#z"bemy_R[J E{ CߚI"{Uɴn2-oc{RĎgI\T+Q{5]3>/r6L.͞w-CBͪSB<lw8Bo31)R'!u7w\˩ ~%?T>VCxWK]gނءbGIRb߶7U?+Bj)v4+蝈ys}_e\s?K$9^0{>Et<4]{~%z^bo·`TQ:=J'Kb}kRϿg??D/LM$-iwjz;}Ilș=}[ŌHᘬ{4g ŃI.j6?kY2{$0eoO݁ M2YzdGȿA2uw]h;t\"VC>z{$x(<_q's|a. _HD89H;h|a)DEҟ깔9'_[ǭwD/sy0藨;諉iq:18ȤTJ)?Ew#~W?]9$\ G< e}6'BƋk?>^\)|2+h=K]r8'|D{myb?z,.Џ/%-q-|r0Rx&7z}H `ރ-(:Kj>lG` ] Nyl;kh|L|Y&;nEQ M"*7sR>wZikAM#!72~$Վ]~x?+ORҟ(! +#!|oov?Wg.[<]%G!z3⻹iOr3rgi6m6inBkiq:NWgBؿs!<.818eN_~ܒ"cxg: |aޏVA³TIHI {G;ko \ײzO)EJb'M༵=~A'qpNS^Zi} MYӫgޅ}-%wm no@B]}Ǎz&̓=u+nZbq׹4R95 4=OImaIxh{l\,#|wr~y翹LJs1$8Yaousg"7B3ŔȑTH /v$%:Ǎ/>L7Knv}u.yJ!w碾܏|Jm8D&牷Ss5Ӥ=4PH#S6}?I? q{$ lw0#x0`Nsgd$.1Σa2g^- vgR%Ɓ5H=6?\}l.4)>%am:!EM&9^׳K G" O4]c=Y]vYͰ [oozsy6t|n -.TΙb9CH /8>FݯNe&t5zH =%Nr='Wz__'FU>,R'z҇%L5|Dl'>k$'J3W:#筫~)1^?A"^y95DJ)E)xe.,m&T\Ht<so?[s!Uϴ^ޟ/ug_I&_i;s88Qtlco)"~8މ{|?I6ss:yg ϿܮMH6̮ $o-~ v)\~aP{C7LClTc2>/Ӎ[c13 OG3ixdN${~z?bsr.ڞS>f)e/&Gmbf4L59z9af?^ /׺־}䫎,u$N^X^fd50ť#ж؊6%W>M.G9%2o;m_f.4gv-3.GrI NtD~]8G9]+oLes~CHfVnگʔ$hukzQƽe]0hW#6g#~ꉞgn AZOzS$_`*[H8jN[؏6&/uؑi$)/ڠpz8 \ǵ~'ۗX oRbg_ҿ@xKP$s`Á.#)s~>qI!Lš $Ӑ`%ĦY8k0c&2؋qKss.Wxc.O6!0.g7jNR]SӕүIk ڒ%3\Ok}B ssfuE7&Ϳho=.0Y1b'U'^o2yUk.v\>1]0\_XjM볂ǣ(sdHIſs\HP?@OhrpЦ6nSg7wւ>),|UFjK˿R-"GIOKeY='~@.`w_5{ GaNuo{ˎ!TI}onoK}']q}1|im;1:dol/+ ىp߯mcIJsv͞Xy}u) G_mמ)xC)u.wd?k[!&npz8:8x%5>nnތNӗ+͟xE_Pp3ڍlB!a)Q?[[bq;K_a*_5sq>Bɬ>HJ [Gꑲ7i?۴~y|nߙ.8=)4\#}4m4kt'ڭɃgMvM9yi|E7mG}-K؏߿ m_VJ|m]ۢk)ԏ9l8͝٤]ϋk}kƉ"\Wgum|OhÁG {$H 68kb{>gQ33 ײkw%xrr `Guk!x.}-w s_ x/(ɏ3z2,:Mg/]Bydl9O8'iso?Le|}"IqR?!%`!R^NʟJzY'SkCfML@2䉪 Uڛ30簳fq3-PǍe/#m{?H r ɷn՝钫pUIٯc%:?*H|Wms+zw={&6A}_!5L'X8c#}޼AD}T:I& nj.t%ָ8m*03[ ok|-пnIدA[y~. |͟p6T\: $}r6RTj.VIr鋴Gl?9B Bp '=ckxӝTg |xbk&i>x\RW/\_1-vw3ʮ2Q M[䊎!{; 6+7?,e='<ƇJnoQ-6 -I􏶫#ɧDpQfC9&3pgTh4 G }c.D?i]bVP_jxy`9}0VgQq\b_=P]o6vh.mXɬɑp/.~%gW^珠OPT3N癠? d9Bph)T1t|j7kbAH'imL˯s{}^FtgӸ9szϠbN v)M>\aa:tH èw6x=^FHӏ]-O Sm8 ^< qZ0AO`z_]~H D!qz#O7~֢_Ǐ˨H~ϫeΏ#rgN>%ym·L ӎ6vq k=^öX-ۋa3 ]K9My"+ -'mPW&K_L53&rm$m+k8M|n~TIHƩ0$յ췁x2LKJݴ}EHӟO%9gz?,=]׏ ǃ͞4Зz㡃W! Mu_&fϻ Ν$ViǙ")9_/fǩ~p50&5 Ι^)?AAސ֗Qz3]sxw*6-73>_*O0b7G͚s/FwfOϫd/~޿NaNOL|]H%/ect>qO?'~ܹ 1rNN9T2$nړt~y_O31?oKYstR]'|9}^ӟC>Y' r.9rAT{K"bO[cK o> MMb2ϸCGQVTiTv[4m6=\3RO>/ԏn~xM- }M/%MK]b}?o%D?t~P?NGlQ蟕h-uD},I2.W718e"-,ޟjyE"̬ gasgC=!΢}VvKrH؀&Xw時?>5n0-%O%~CRquu-mߍOeT9ke|OH 1#Eؽ#n [2+q+gõ=dND`<#-cz5eD؎+p[auSLۡՂuAhhW}3qqE78pOo y0WSk8aWR_<}/+tG~Gv]}$%CZO.^گ{E"ɧv}T2nwDLc_q08O,B2S>e?+WmZjN2;lAM@ q='fT.;iw ̸2'mqcyz;Žp_xj?'8_D]gO O=ڈޏ|qINҏ!bn}WHIL?tm $=JBCCYo(AiIM ~u퟇o5> 5|5+ =dѶ?9`2Ek*I]-{N){ns*ۢ둪`_C~ H/ Kz?b\3B}oE;ףglIo%߉VL2"'7G-koT~&άnY 0]3[/4uU nF$` ҭ)fW$i"\mJGr3m[MnMNiZKߞ?dbߕo/~=h{,sy,sҗX$r;M\ԏ;oIZ&+ohr=@Tx[?OޣRYcIG,'E99C4Ə#d )x rL9ix'q|kO.ݲBOzx~K!%t&6("s:8ٝYL_H7ayLSEԭui:]X` L+z|kc?XzMK?UeK !~&kpSU jEKxyߊ'4~-4~(u؅3"ϓxa=D)/e#8d{|;u伦n;Nܵ[g'B~L3Iӏ_t ܗBw(_ Q/o'[O #1o}%'< Jw'Bɾ%3o]Lu-mſ #J$ K{ !%x2oB#o|bh;H!XFI&ŧ;ȹ;uM'kĚʻy%xβp]H!o;Iis2>'FퟔC)[B)TO "~i79sxwp;[|M.Mj? t%,3Svu?UM0L<3MyMFͽI/f[WgI_ ! n>Hs(P!Kޓwhn`WGwROR tRX>qEg䓌r?|59kӬާ츑!q$wB1dߊگIt^>.,b'$<~[s.۬k0K om+\Œ#;S RrӍ 1ڗm?UH9Q|9].}rh9â=|JO;pj2xëWqiyK!ML?pzyB>zm }si?-lvS7Lˬܬਐ[v wsu;!֐JG*.0_+}k^-韅WR>NlmQ#E9f9y+>]Wix^+ntk60s^H !E.~?~  #@shA!Ge^8H+UwӼ2H[6|~Iם]5 'JPIO*Neq)ۯ:x#o7rIuR)]$A\y4MS'`n;n|CxKzD )r*#׳} )#5qAqKOꋏ̐Z'GNzB߰U_:q B,~S?o~)egrJ2HƩq#ԏ~ %şZC}#uJ_a?|JbO]TڅSAq>ۛ~VC̛BUdj\;xa%K"#E֏{iCxJr~xoğ9{Os\cRs#ÍeQ·cK;)J䟅τ_$rOWᘜ_9 B/ N7?cKqxX_|Y ى%CQ~&vUD.oWB72=]?' iW"Iͅwgѿ)Z_~.3,~ph\=c:yS2%7\J_. ;bm+~rQȯٟ{#^> A⧀Mמ?gD 2?O{sK4_QYAFbuDkoT1yBS4FwToF">\mb9wEu(x''rEʯo /$បGur=}I/Cphm|a$!T㏂|KI(,I*|ثkndm]⫱m5~ҥ#_מ/GPZ~Ө_N<_OPn?N#%'Hb]_LOsc7WsaYxd?N*nVW연b2Yzds ҝB՛7_^MJ 7$G?t)|&@*Hm ) H+W)ڕsiuDz_HOl {sRnvhJ^\LL\R.V,%rvXy̟$iW򽔟Lҗ-!ȧ89Ά;7M }&<ٳQw&||PNFF:UOނ7S  {N:|T^>I% +d'*o9O&X/L<ox*~˵TT^𖩭ݜLMaX!7`kK Ϟ;} 3fm7aVٺMƌӽ{ 9'Y0ZW^X䉓ǥW/SnqLcg7F|4]uυ9~7e?A,.{/*EmMʥ͊6)U>^_-_, (dw ;>GۀtV$ 綀C1Y iS*%fJ8R˗4S. 텔{MI‘l7M78l#++8I/p}[u`IpKH#Qs|Q?bJvݗ1yr[faꆠ9;WlT_Z6/w{ⶨ3=g>Hh? W3 񰄻(,(qӎ~IܸhP%)Y)fRN,믶/o*'프+Ii2+/$˕jO_ά3v*joWi־˔dV_,G"r{vl=3c]Ty] orw ʓRӬ]"7W/L?l{I=?ϖQmOWY[e=z?D~fi&{~z6(?Z_4[YʯwT+HW˕WۛWkqK&_J.W?[aV>̞Xߍg6ҿ[*UO&*>X&ѧAIj~5C1`loy"zYL֢shČـm*C/[PMd'9P>p LYNU(ۆ9zk^^|o"ew,,S-;(ٿcBn(:z6Swnw94cY4;AQlF)/ 9A!-<}9׃ 'NkNvI>k[j|'ɢ~X޾Ulkff&Æ<EA;G62$Q 혹؈Mq $t(&XoK*ۼmo~y|e>Aa1uMMFc`A~԰o.м[qӆVkX|AaMlPlȻ ;pJ0lz|N,#y`F9gs_S ^\C{s`7,G`}ء*(*1MiL M}޶\f(߹f2os`G? r?:*3y[E/ꁼq= 뾯`k@խ2`biI `e UŻ OE%r(l&۸SɒOʁ$M`FUw`?I>`V8r9)u;AQ>8rFvM[r7Ćtǿk3o 0u6&`rVK3jN 3ZI\'c;fEWټDHmt#0l5z#1y0O_ d`Sf\%Fձr"'eh(Z ;@1ufSj^[Ru<+M8[߂9YnMFU_0Au`pm==>NErn7h]wnn9|WYo` ym6.߷5O#@1(:bVmqSGW[_E;>A|X1`x``(:?oʪsE{ ~AxjP 3|G1'%ˌ~-UilZME{hWM9 6O )G*s OOws>#~i>)[Gf{V1' ήn}] #-\0e~t.|:!%O~z|ܽ~vMФX[;=Q~X Vo ތjlB~Ex|!~󞃯/!9{!xwc (*|ueX\UzY7ϔ<dB` q~^y U+;.kߗ&`k@1{͐'5x':_)izgi<6zt+_Xy{ح5b;" ,#_E6E|缠?rXsXyK=m2?0ۓ4ybtK`|·}%b1Atd`KO~՘m#k4*Ԯ3xw`sj3,80g&5Gzӭtt̷ Vӭ6gB'ÁkxJ9ߚ/-E=jL̍pr#_^u0 `jM8Mf {] k[ w:[Sa?_xu8Xf hʭWu.0ݦgxf߅}[I׀7tN~uZ++<0E?yqVc-D?+l:0w;OK ⺮R7mͻr3ɳw~,^ Hش K-+G{m\ ~ެ:`Q`"&0_P`C '4uh=h-rM뒈OBr10{o\OE1֝m:kq Sʧ>P2G$AM;+|`mUċm3'G>U.ynX`YӉ.i|CHc+d\;2 _D5"VǒI ~j\C̊,C잧3(Lu5]Pf 5* fL 7;Qi4y[g-u-7= / oZ#_yw@Clg;ځSSO!% _Kp=4k7yR|%7xYHi Ns".6;zzŀ@íp!"Xemf p/dSGa$Cg!4 o{: I!\8Xc1(ʔs/)nOBaa@?#Pv;~}!@somw+׋̎v.대/ cq(iSWx8;rN_VotlS8.kV.||u|s}[O`?mwYki+O&},(V"M*#~#˖}hNG-¸"?/N8:J+]!o\_'EYŜ[n:߾cӗ#F9aul]W207%x}yxtigz$g(_Zt^GkvnXdD\?m]Y>}?*׋UHOp~|UNJ{ [#8ud wZE"+`` ;IgOEs*wN 1{GᖢfoUvnqƎCY&ycg#h{ Q"9۫"\ҽ*!1o]vKoPiq8ż:u#Mp݇-Z= /[vxKފnߠ"ElGA:ٴCL-15+U~Pg/42Գ>g?N@].9n\O|eeSB R,V!>6`,7~~R.jNhұ qG`or:CSuÈNN[snWk@o^L(.lZ%j̼WkgD]W.t@ym솰7@̆&T }.oO628 O|~lInjQ/!0N>~=lEGe_(O8tltu2!> q0q޽Dg0iܼh~9(~@ĜQLq\ŵ݊:jeKC>W|Qv[I HWw^uGG PdrLC>[ш"{"^NGwqw}Tw{؈xrez|+V|aU;`k7Q!=_}3fE!MH'o(tܛs" s&Q;*<=tN~#cf@1r{nQovC˓}Rxu.p^؟z /lM:u嵸ڥ $|_V__!>1;':4O ^q(Ͻz*%#p<3֮R>`^?_oK_|ilσdQj,xzےKnĮ;љD~jS/ zM{9[ePמ8o ZBd= 8LJo kmzh_돹 |ye=7n(WZ%-^gh'O;\7:-}cRPxƈ$_ FzޚOs vHtKz<='MFz)[w=e8.UV̛trӏVL|䩽GCZ+O7u=[qbp L/}N2Lqܒ 0ݡE`ekfr aHWSMf@>XXj޴v @~yA[=˟u7ʿ01ǻ.;xU 5>ar!~3_?esp}=Qܵ __NFٗC4yfBa>3χgm8lͺЮD|7ʕ\n,DJ/GCoTT0 ڱ\k<ۊ|z >Hwhl | ':Hr8!ܵ8]< 5p=߯(:[ʓ/Ӣʝ|4`nZ-k OJ ZDX&KʍA%Xv:010lE7ck*[qe8uJ)`'[mJƶ;OGu f3GP.-B,l}c*?Fk5(Oh$&Pih?Kv{[v"$i7ʧE*E9Ӎ#QyŹ AZ-u?"TsWQc||l^^^P?!N|' ן7JųHsg{QBT_}C92`(Pѯ#aS AԹꇫl?V5popױScu2۬筕9Զ T Mly<;7EM 5EmL{9kl蝅]ϿE"%#B=X OS/?;=7ɛp'(SH?ނx o|X\E ]/?+x.^K3!US7|i܇?_B 3GS`|t7ވ'V%Bm뛐T\\ڜlbZ_޿//&.qw-Mʶl8q##{>oD9 GWgWy|L^\V㞣Ӹ׽^+&'0\@r]ÉW&ȿ8ʱv s:W})ل4.~=>e]! _ezm +k?^GW'Zsgqw^+]' -ILJ/Dz={6߯vEN}0AQҭȧ>2~Hv0仓TFlr滑 .EҨ}.;bNdRh~ (lKe"_[aVލ5_CClLzV8'{Ym?(1+˪1l'GEE+bz(_2wn#9sr;GZ棏7A>H ȯ.d>PaCLO%q|siu*_'v8_ 4[vxP11))>ـ2K_ߊr oxg!1RʈooJZ,E3]WmJqlgN#^5S=j:"^ӶL\rk{؟;8jrꚲ|q_i&ʥ PL- =}6hxg̀cpo-54]QQaCkX[N#Ϸm _HbH `ľm!SJ%a%]@}{3䧷:p717tCЏ+/zY9n&ҟG.lbY s6_ؔ ju@"F{B68c"60Q?q50]>DgF )xf6p »( 90|* ;k;^N7go%oGPXom|?t-)!;$>ިk8>9;_L̯uwES-uS಼۳_Ł@E%,_x.\ ̈A|vX(XqOFF@x98>X/Ҳۻ#_zH;ٸ!^t~煊ad8}[53;6V}Xn=wqo o5y/dP.xSմ~ rU9Q.kq97K SVMPo@reEG[^Bz?pekȇVܽ*lOD}iO`ZvPw@~v3}+4>.۹n} HO9«\$sh{峢#A<5hf;XKG90vUagu|||/v湰~Zo('(>߽M}tlH ~ؖ8xtO(Tr[YM+.mgW=?>D~]˜;l^CP9ٲ)}A>l{œoĴRME{+J1Z B9#,oz+_fgF<{4" n\uמM#z~Fۛr+<ءՂuXPtX3qH5r g|T < ^fWXF,AzXeWpŶLpK#̆oq~ڎvVizhlYY/z@RI݁h2ݶ^e/"X_x~9|c[NnFbfF[;JR7bthXm<xCNu}1gf⊈ ɚ}ŭ??ݝ&ːpfq[w[`rk-$,=soҔl _Xbc>;R nPրn/\׵K}20006g{݆7AyUgBڤky_!>^~w^7nCj|ipS?^}k3@9Rpƴ ~κn ?mMEos  LyF >clIo3l^V)-sP?}M%` p4#ɸ؏|vuyfpb(G:zq~№v\wqT9 `LڥWnV/#6j]Tړ0{歽ن ux?~H״!!}y(/z5PU,?9?sqy׾)@a8#E&0E$ ߬ٺY_xO;: o`zGmlymxmG>B^W%iW2ptxVǎrGC\Qs]tPkU|j6ӛ~uq znmmbw 5Vk1 ʅ#EWӯLZ> _1`YIZ<$=ީPN`7t:2 ׍Of{!3w{Hosv ժ]+\q}lonϼ lD_"PVN=͋,KgN>m{>:OB9 B65Vp;N6+vV49ȝv(O1)_0=xxLֽF#kWJkP.U]؞%P8M }-FzL7;>7=izeK(7ͩM`v-6E|-Qe,P+[aJ=wk5p; ƪ]RtNv {y1(ؠ6Aﲓr*iRئI!^xϩ7Zn x[CB{L.#_6Yyi5_Ň iw;A^e89xH!]=vya2MEOL{SQtĮGzSeҧBǛlH/ヮSņcM#=| /BsG[a[ӟn\F|afvM\?N6"{ӡs ^=yy1? Z[rޝmCpݯO)xs 'Uh`U/U|y(/[Zp6/1ApKTтc쇠\{yCZ:_\nx:$:GP,-k|mد0<#JꭞUo8t{P!gsrMH?6(3]˽o󳎱y0n֋ NۊkcW0 pK7'![Y'CDze`z2]~qYbӀq]5woYF'jLufe/gE -F9\?y\ t`[,R4p "r'#(4`Wz$;o<l-]؎ F~Z#¼3.jLCȫA{p Jm;ԩw6um"ʋIؚ;y ߪ;һ=(lx1W#ȟv\&(*ȯ6(Yo;~Rrg3,Y"]f"97`61?$x8ͫk;3&S-Ti|*ǾNbڣ;4bA(_'*2Ɂ1D~}9``LUg~ i>@g&J<`&oY옭U9.G!B!c<|"5{oJ*q: @9hrm>oNH K~R\WsN-\3KsG.[ H/qHʽ 7w̶9{\xPˠuPycMcGQSq aæ^ Lfn>+ ;vH5Y8(B|Sm9A;o{tɱi^U ̨6\yŇATK9 &>f<£X`Ə53;6q壓78aGP/?``TGr:0OV쬆s9!oF{Gލ/Z[)Hu@˓]C]U(o9`غkfޣ >&ȯZG~2y0<%Ǝ+8I\7(NbN$8>L0 x5XӢrM T4Y&Eŀ#}[ mݪ&!^n(iqS~h`7Yc ` "~2[HN~?)岇G֎C<[[qGQ~zUkD 3ArcИ~@]D~fXNkm9yFK˳#ƺH75?7址/oEn[r{K+_913ðAaci=h4K q͎yb[wHɢQj#/W8jJ!.w=W-@qL]8WZ15;n=܌xhTX{g`h\D\ܩp㮃 /`70J ;wC}AyI6|_xRq{S'=|Ey\s=5o"_X>0뱂ac{=\ֶ,rEY`a(u. .{UĠ}c yqY`9d;~{uvj/˦W8j }C9ȼøqw]s$?DQ50wʇѥ6sY`D~ wFZXƧޕs'e؈|oGGfЁC*kI!_c_WT(~1(C<;uTP<дp4ȥTn|O@uP#fv/b{ ^*Y3\Qo nm_@1og%330/ ^f?r׳/ @|rHi?ڰe`x rc)9 \$Ϫ'1z'{w䘾9$.xk$+1"yfGGa1k7ݣ߀_ ګ?< w+Q^'K tux\uFzڶY-A[ \cqq>rG>y> Uz>ǖ?-[}17VW.d Fc; vqQmRAQa9-{qvG?xUv;(ܹ-Zqy?^Ok'rۆe~ B>]'XWzWO|hy<4l5OCzyƗ=A-àq۰ ^.wfڌ_mhws3Qu.)ᑠY 4 -@}́qo@7(J| 40U^Tnʦ+>pp3o Fi}@ܰ7/7yN͝.h?枼rZG(hڦָ8@o)5Ms{j޾]CS6 V6A[Syi 7ͪX[U&'|pa^b +D?Zo~NTV# l7pՙ>Tg֕ﻼyoYI@u:aXrPy`h{AՇvf)@}3/:ί;׋&M7xͼg :w:.>2ED)K5霨aݨ{.vAV2!׈bAH$d9/z4!ay{C[E-h8Wb"|gg>yW= F"nUڕ8J23p>{VηsWHU_XOUbAq. Rmo0HiB!՞~ݑ?z$~F*[|SY[f(e'Rꀪ˻7GV4Zۯ=(r^&~%=|L^| δ)#\joα/Tc<9x#sOxtʴѠ VwŪ,ʅO>qL9x8YǯОQ6j}[ZRKYr'_u֯ޫX\ >Ea?vݰbL*U C|ս[*G'p+j~ ãb8G~^B|2k@1uM j"W)<~~ M9(m^( Fesb=ZM ٱįCnRsh$ yUpWw;@ѝzT͠sʦM جeSOrjSuE{ PW ^uяC_rԜ"J)aɣmfwt(7z bPs۠XziNncTL5\- Zq+_gP+@,2G#~dRs냆{'"^o"^~BD߫ҊGTO%_^8Z8d׬2: ~#HTMY+ҁcVs dxPkJh+j:,?Z<(Nfw_8Wf/NGly}VAjv"AJ+coUs/X7P?/ucl.T8PziUwUAy5Cvi%Uݎh!{S%練_z7Z9- Ϋwj]\h%:vo" :Ȇ5Cq:|ѱfXM7um?kPNOFs'Auq4t{L'Ns?;u-߫*\J_Adˉڧ*P= sp(y揕OࠞIfވ @|ZಣAUn *=xwrK,޹TU|S(ʩ{ >OKYYN] /m[#![k {? Gj~a yL-o>%"VN JSȞ#'Ή6Җ{n9|N7;:Noz.< 5d.]/qR__t1ȋyV3WרY)K;W^xGyR^RpӢ S]w$4@iHKC2r Yn=+ңqoߩDz.ޫdܬ>W~vikQPn=̫M:2~o٫!()kA9{Aw:򹢵>UF^}'cʾ0ݺ©|w -}Py/jՓsvGP?X1 WޝW869wU(@#7Z,b3^''6yг;4 ?.tCoPnluZ<=׮18JTN~wt2m.X4-B߉|ܭ ˧ҫE<#![|ɟ!жOm>仵5 i !7km<,?#zZv/^ϺUWo'C6}6$.nnPߴA"_6f F3' zTI!Po3{'ssO0g2A"zS— z?U徍ي޷xQ.1%w؋xnkʼneAYzO"_L虆sC84v}K#aU>~9 _k)IR/mؿš[ X,Dߡ2MEr7szn9yh?M(/ ryZ睨S ʄ5wx"nJI};~o%O*җrR(|_ߺh|m?式.x#_o|kPMzrҏ{qFq~jxxm0仗:~WP*o&W?*p.uV>oP7.yBPEKnq"d{DKϗޏ ڬ"-u$*7 4;|(ոE! M<;zl@]5:o1).W^G>U9)~nܦܨ|6Ļ>OtCD/Vo {ރ(Z u M}dݩ.ן䟑hsTY*y3E;r}y+#_B |^[ؿ oLy^ &VX(0{Yad/ViUMjsqg&Cx}pED u~cM8OT_B  &-+s!fn5 u|k&y ³ u'd_SyUy3tEJ"@]wո#!|Z/礌(/S3SuVٍ;|7ӿZroh_].u7Ec?:͋jrz)♭Z-߹h䇗/5ѧz4A nJSQNtS8{T'p=9K)fob:}} >*kGY_5.#\~fs*ke!qWp=W$C>R8#Ө7~! 3\۷' T fyo_ϸa˭}Z7_o"#U/}xwJ1PvXcTFQr3tnB-[M 6(m7vT1sGWbH#OfռD|}L utzT۫gv_wlhp+>f(e'E}ϭoui~BA=2p}hpYЯȯP em(kPU4Y1ttln n~g{P}= HEU-)U. )G }Z`t9bI s=aѳ&3f3Lc1Әi4f3Lc1Әi4f3Lc1Әi4f3Lc1Әi4f3Lc1Әi4f3Lc1Әi4f3Lc1Әi4f3Lc1Әi4f3Lc1Әi4f3Lc1Әi4f2F]@s:2xvCМłr|r{Т B'1YD\U»nɖ=}VMn>7h9To$AVOns➞fuc9ʀګ+VCm."+1t"kܽE*!R <׬RVbUXs~PklC껟 ߜ[M| TW=dPwZXHt+B^ӥ=M_w \ kBa|^aiv6T7(=/6: RѠir)THezz|j@3pWg)Vfw'Aɻm]cSRҥKP >UF:l;Jվf@}ݞyuT_.؃2w,АXS1MΞD>3qJ[* 4cAi|_: Z<Tϋ[ݶ)b)qWv1pP H4u"64.2RQ(Gq\={_=aܔClhH[.v}갰+m4>$\ug4:SWIZQtG1H[|^%(Ey,Djwń@ݘ!f׬vfDk'ʽ 'n7ՔW/gN~h9AZE@iG&\x9 sqns87TBlUOߪ !v؄|@u1\nXdU{i!˂~yzAQ}#^u>OКVp~=[!ɠ*6<EP 1n0[1$l ޲GИ)||+)$6[C9CBzç—@sWcZ5on9˅tu+˂je"sc!q);qWgO(.I~ϯ h++Vﳸ=JPZB7Εc )Ua?cʩV1i^#6FlkN4{I]@媍ɣurJsPܬ~ _j-E5ܵE6ǃڟԅ7F|F%•ƽRlŒ|ruܧ.bCj(4NjWj+@Օ@3vAyZk.{/A@Uޠi_D߭٤FaRidK BN;h+{]{Ҁr6Aj;L}cr`q^4ds/| \^dۣ,= ɽ mk\ApAyfk-AFΏǁj0lzONyA1Ͷ@|卑~/OG44׵ z4uN}Xwh#e3]I;ë5]7sy E@ʧAaNO@- JyS⚳3(-s (C2k#@SsKKgܷuK֕fqꗘ WU pӄiV#s|za/߯tT#y i\+xP|uǝF x~n;}A. tEmRֈe }_=gq:?+Pi/Uc}We.WOur jc)u1^w= r9E̛@qQO,Q(oQ@\d1="@Gu U *no =*f3 "~# >ٵ&6F~æ|)k6uQ{4E)Pk:Eopwⸯ MBodUsH6& "Qߋ8P>(W0۞xVHu*rk 7+L}X6`j-m^uB<"%afe[h8zPX}1yg >s)7 L: //+(.{=:{:yRy0򇊁͐Daސ`knzؼA@uKN{\w3Aų!x47fm# M+UC:j (iK{Xґe"H#/<Wimt~ib~)fVA$&7;>( f?Չ:8X?O bۃS#:ʣHH}\wb-EoQzݥɦP]\7g Yn ;񀴖O 1W֙'qQAv*Em?/dL(O_3=]v@eOr6P!mQnڝ\@!P)O@0V}C޻Y57}bQ\4nh,{&U/ϧeW(TO i_>3EPdRBЌk|G;O;߬152}%5EF$\Gz_q,)O >^U\p~AS클9rr7@%?_*T |VH#+4(\2UFnuDYfV;h]q.PפT\Rq8*EۧcEP>urخu#Q>bl:QgN *Z-Di(#&r4' jTMs*%#h_..X94A[AZ \Vpܖ8Tk7h^M(P#={;ɣOݑnwewm1;+•w54{l'Mˣӏu|ak&M}޶AZ9WغGQz~I 34MA=|+!m3hA[P@r¶gt2/(Gke)0%lWތŤTE^CJIeF8B8>7T^m8LώwUy1Ց:TONcJAnT }[,U"oVU4ҽ.{JܩF+v=J+?3`P}˻+9Pt1 ]Xg} (y6nA)ge \:^uGGf1P-Q V.^.@e(Om+.ݾK8!=i(9"5hG.\^8r:iY //Lv M'ʚ#!DWGM8t>RDT^HlrkePv+cӅ q!zgU)f6[#/ZW^Cd?A{9?mlT-s9^.ב3lE9rҶz!ݼ`A嫆.O^\'ZT~+Q'tJڨyk18D/"nG? D~Q0UjD_p10[Ԃ|@RGDtm^eѳ=&TAvAű#n"߿rBA]20&jѺ_}r?ؗ/T]{6wnGTe^[Ϊ&OyTHn6hAɉK+AZͅ*)J[jd8 j^BG;W-c6RWA`TI_6׏=|)\ЗoXtLE;E7x*v(('/_j^$iTe&rP⸤VֻPV+rrgc[Dh⾊Hgw[OE(qKАX¾iAA7Yn[觰_.z|IH-7|v>zwQ %fW;TC4㼯.sPzoݾE9R?}*;"_ovr.3o sUԹHd._܋[{fHCEځF%< Ϥ g8{9R:N|L3 <6;`DPUrX/TC/ϧ Y6`r^He?G̋=1>E}AZH]9޺Trrx}P:vTcA|7 ݤ"kh4f3Lc1Әi4f3Lc1Әi4f3Lc1Әi4f3Lc1Әi4f3Lc1Әi4f3Lc1Әi4f3Lc1Әi4f3Lc1Әi4f3Lc1Әi4f3Lc1Ә/eXd[<{$z^= Tr#9i1y_@./ؽ Kq_B;k@n|5rb۞?u) kqB;HB<^}YMLZ2N> QI=mV@ \!AnNR?ߍ.<~9_L`蘭L ~q燴|uEƅ̣XBM`xt%#녌o}2\2d#痔K%yO8a>=2/]\aE\O ҍPO)MqI:!La}&3Y7=q}P(>(8&p)cag],d8vy)4>"G '|/ #dv XYWd  p*GO7nRSxCX2d~vR때O'~'넬s2 ;/w2<>Ey׋zD KjD8$ṭO/Adq#| $\hȏP|S߅n%OE6+4h8~?&|/%~O!^o|M{] g7_ɼE^r-w"tsntK!(~_{}6XB#/d}M&+ #^5x~EE%Ox 7OIӴG͓$GPċd($HƉCYo ' '&oxt|GuT=:!L"օ>𮸾ɺ%3b{hIgZƅ14?HzV2ސq.dr=+ᄬR0Qr_h4ޣ^?IQr""]^K >Wnt"0!@/̏0q!Hˣ4H/ݧ .?Q8ވ|ѯ~|MAƍ{I 2^?zM_F<)2/.~#-ϔ~5O'"ަZ)Z/H8nx>G? #d]Mɡ""L)zdo柼Oy E 8%y< K{JO WH(=97ҟx!FX' _+#Ⳉ[ z@R> ^O ~E𞸎h=S;h}"|'ZJuE"HE95G~OWo'H&ϕN_Lh=#w>Z䟉OJ"A%AG/9_d\i}?#|S;BDJGb>w#%O7NϤ_dhyҗDyo#a~zjJ/d(~W2.o zzBSJr ZHG޿wd= )}-/ gd\)9BRw64K~%b,3nYc-0>gl|6>gl|6>gl|6>gl|6>gl|6>gl|6>gl|6>g9owcÖ;"{`Zz6%0^{oŲn ;C`5!dIn=ofT2}'{:]]]]гu_nVr`(3϶:rӃ[j^ m]C~k^06}oː`nԺ`B qûEòo`&~q!W6{Зѱ$k*^nX0x@/b@eq>g}6~6AA/:wOq> n F]e`\6/*^*h;s0oFW;=4C`(EYA?;@!ze6. u7K5߾]u`] ko>?cGÐ] WK;uk48u+Cn^U_C\^ >v zqB\ϟ9>Nvy/ПVXxo"= "waͰHA$9H>nH0]~Wʼn;gѺ, }K[Ɗ#jKg[Tzo<菈3? F;.C_ezwNy^>\SAGC/SK6yoF՘?QT`|ƅ r {5ha;ok"ZǸnq3U:#D_@°ق]+,Z &~(;0G:b?ПjTeoh7'`tfʗّ16(:}>_-~Gls՜C jk'Lz $;?uvo7f Lԭw=Q@mv`?[opfiF[7`H;&Aͺ" ; ?`cn7tjC}q}&aΥ& ԏ$!ΠM)XgGL&O:=WZ˹V*ꩠW} ?pLdO^70>hmpFaq#i}[ՕI{™A?`]|?9]WWA?J!svc !U3?4k. MW; 9½ _aqnn'O|]!;}py_~ANM X'7J\ƶ￯ [&'ck~j˽EcQ@ۋPoZC\D+/>GFQٷ?MC.=8gJi;<~$Eؒ+_g.%~(@)j! ny0cqA"kq~br6Z[?{XeG>V z?~A89W,/7ʓY t| ^p=A5ub~?='柼[p\qInw&)cu>3V֟G\cID!~h71?hi, M -}> 5'K?`]0.>KL0}enOn]Zc+M{pG L\[Nn#%.uHx}M=$D<\^Vwr?uU_/ LOO^;vrlj&-)kZ5Z[KSjA/Fp`gr<3زp5'㛯A&jzraq.ow$ǂR|PĔP8SR D{D#>2?8`RgG_'z_k\ӇFO GMG#29c^zϢ}V-$a I}!QԦ~cy^q߯e\gz;!O8,K,e$8x|ZCOu7oHf fSiߏ%}̫p;q8.xbGZeڧ_nWdWپ?w0^L69^:/glD1?>QBZ)>F{_}pt,g~Oo 8K/x\U`~__܇u1Bd|Q_  īABg w1>-G=ü̳1^C;fG8~z:x1]qT7xz,w07;~VH8Sg-4%``l8#L0o$ؼL9)Lj1Dqx< A+~tҾNQА7~y`B aCxYSzu)lf| R}_!Ð?~?㈣79#.!oc,^ sJdIļF֏RYS{_<\^') ~| &}7P.]G jy>]sϕ?~ Q?s#MI't%; -8HxA?~*o[we{!qqqk~qax|?%u/wx/c>x+I2:Pn1a f9~xᆴer#[\3u\'W}TvWJ]+uԕRWJ]+uԕRWJ]+uԕRWJ]+uԕRWJ]+uԕRWJ]+uԕRWJ]+uԕRWJ]+ue=d 9!ϴųؿiXO3.OH2]!I<aM㙶=Ug]Yz /IV&']'Eg+_G-ɘ@<q>v$r9|}϶tv3zxD:?wbuil\>On~F2Yglx^gיxl}>;U14ԋDӑ$~Xh >-- 1"^c;3~r@>:f l\<ώavc s`|Yw|CC=K&$2F%G; vCN``AߓlLL8>?;S8?G.^Qຢ]P}CK"]'~6.?+$ijqA\'ߨ< ,դ,ב!?o.G]Oq.dv&_/`\p\<%beϢfgs?M~E6q~3c'(O?g]QgQ~v%mz8IG6r7c{W:?%zq?=HO6MX33x! bg0u(j/̞:[ o88gYeN[7!2B?ga^H9Ʊx&4ƋcG8nʍ4A<8)`vJz\W#9OǙLo<<@rh\߈ߤq )*Gxslxq6Mx'aV'%s> ۑ6)Rq)U}>D^?;+0?dA]໯xy9`D+0?/ٸ v:%3~h{z3/(Cג<:sܗB\c Kߤ<<p{u@yADz?dPLn<#Į3řOݓ}3?xaWcC'ݢ_unh~ ֍,<=R>QC?IqF6pui߆s*7n4O|q⸨l>Q_o0Nw8|Nm[=t}o/cs=@\ C6O済tqP8.ghP;'6.|[+wB-7y7ɾ6~+l\z\Ir8vOGqUW,O]=7?i=Yz&\ij1Or;:4#H8ʓ';iYt(OG..[GR;[<'g>3F>_JPP Y)_fYc9Pyc].?n4_8pӝܺ`мoq2m`r͔gyPHq7_& շ0~SB~W}2T/iL֗mߓ'!f_CqJ_"n1|[}UdkX)\2[t?M.w踲֑ȍ}r~h;?EL]2q!&>bl<ܗxן5#5. ǫD3Q-O{.?<˛ݯ!q'H|B`MTn7gUܐ#2xHQ3QFN7}>*?/!8.]7,i#n:}^$H)dRH I!)$BRH I!)$BRH I!)$BRH I!)$BRH I!)$BRH I!)$BRH I!)$BRH I!)$BRH I!)$B(LS:'w}ϝ|gxwK ;=K&g݆K.3_}ptB0hR>vYěrxm{ ?ቹ] a\R%>k6<*Sn?b'\G0DY_vF_4O2}t 7])oUhj߶C`~k^`Hw~vfvg0ܟl*O[,"o۪3jv?OQWlwaEr~xo`Ww-#zۜmp!tп;zi`\\bgg vy &ċR`#wв(Il_5 =nX 'cӍeg||[º:mϧOnPh-wٺH `h"'^OA8cg0g炾KK| ,1Kk`Kj*~<xUnHsmq!2$> 042. 5z #<zmgs}X+È; s|N|<c_ǩ^:#u0|Q05Q`,3`~.`VpϏV`0-S/?#Ĕ]/gAﷰ`^7kJ[IfYÑn| .mfP6 8] _4u#$YӲM Tgnrb0\nwP'ܚro] yq }w.r۫'cۅW(3{0ܭA?pYKWC08>v00|Wq]zs0YP`\z_˥l=nhmZ2O}.Hjg+ RN 驡SCWntpΕ&RcuѡǶ`T][Ў~f㥡`p)!`@1_!5Wm0Rw L%o1_P?OWUUUo8ʴ` r_3,R u%Ut`4U7kg]ҙ}kD^röK[͐?MNSŢ7ziƮtZU]Ov6~A9A~W3\t?u_aP Wf~tR]twrx2:ptޏ󏧏"zk&xnnL/-no# +~kN+NuHI5h7'`R _O?or\E ?#&"?gK>I{ jo) G CXGywDQ7K~fvi%W-/2b?$>B!`vH趭>y`(7hx"=}5cvj m+o.n_x'fϾ|:khz(H!{ ݖ.,_[Eb37lG>8"ޛ%~X|O~vޘRI Tl_^|nsҎ|0Uy u8(Q W)rz/--{5lM@ﳹD6> d9%Ԯwy9=iW?Q}7#N!~u6>??0chU+v{p2#^Z%;Gr76=2g Q@z$a}z˧aܦS /Amm^L,^ѳ⇯()3v`0H͡O.M;MC K҄xng 8Yd{y0PS!Ml.yK#!jB(aC=/\bU]C<u*o|##p]j~Z`6$u#`h0Q`Uǜj򝔭BS@/S0|qO Y\32ܠT;#Hڦÿ⺋/:64H-Q{k9fdx{o~ !Å .LJ yAD<BW/cx܏rb$_;f' &I:kdkL:J˹ =or<}>)IsRgIHR;4ѐoi7&=.$8/v$z+NR^G[5x[Jl0=sN{$Ԫ2?3Z!`p:B%q0 IFáB|=nOG@/ !HmLF!zf59غꗝntsO k\ЬD -2+m_ƼgG9,BE7&čl jI'#xaR܋qگ*o{Ƶ[v eE0!"s3padVabޥzD!.u5 VG'u5#M Dw+OF>vx$[ap)^ )nQ K.)) J!V9혿1n20.-~D_}Dᇾ ǹ?zkr _0.c1pr|/߇vߗ'6gh(CŞ__I0c.$9-ok zэ4,s˛}㢏'̗~24L|1$t1-3CN/&sD)yX}[9z^.+d_ Z\dCAkW6hf-y.b: uvOk06}[oK2_G~o74ֹa;~B?f<}|XLLogS%cި2{{9aVvH>1sq*]?&:nx^=o~Ng3A?7$)N31^bobw0_OOe渝d1U !serJ{ccgwr\3^M?y8K?WL0;-)#w^n:T\jг9q3nG$3˧ {f-db ܾx=/F?*qy?+}1c/FKoyocg l 2LNf5_WcQs<4dBU >R(ggbbG>l8M+oHOO?-p d8<2[q8/wLzF%c7R%U5JW+ց FftsuicPЮ4>Yw'C 53Qxu`l}k;c0X}2RɣU}"~G[/:4$6F/dqqZGpޔF^y|9Hʟ qʯR/3%@߲RMzK)n}x~aB+ ҋT16ڀ`4ΦgdH*Bd}/nd=tӏrt:#;{[7D$$رr<7 >ak_˚ &ה#>?>Щՠ]K%y>V_X<"²d:z1G?WH I!)$BRH I!)$BRH I!)$BRH I!)$BRH I!)$BRH I!)$BRH I!)$BRH I!)$BRH I!)$BRHE dҊ*90ιV`c7J+VY~WpWn\٠GO  x~ u.mi/6cә 'B’S_zƂai@~Fɠ3Ўy5r=caÄuB_/g0Rni}LN0+k*^5ZlT;{Y~\6\S|b;&7|Qҕ_z\?Y]?? HH6V"+ E t.g ~~y; =4C=WO~n9p{z웝=|9U;q0=19W 7.vYП:?Sj?h0x3JdH8Qf`HbOBPt =9幤G?.>q$ߥpTH➠ΌUVw\N(#j Gy~Ԟ/)>w3\PNO}Ӈ'W6؏ve0)Ȟ  $[c3$*~W`:+u{3yo_(QHV{QoM08~ـ  2\p^ cl'$$8-֏|tL{a)7%=@Kl/EBCSx< fW o!vz1o11]Kn7>>E<2Z/qlx| tjC`tuvVُ7CaC?/ŹoB&^ދ 7<㽹SYo|y<)d6H0vyw7,3jW:OhJ02 ;C|j^nxޞ230N=4˼R˝۸LhLH G@<}L_^zq> Āy| ??nۖ.j{3] >Z]؊/+}nwOs=czf%iQ0'y,'eg=8Y[7pٻtޡCbX։}~vo}|`>?drEa5 ܼfJ\k ?<>4DlLAH^/bJ~8oW3yxblyyڙ;woGk[fdvO>Y,iO _ɻ'o!/7tV|`1\?J9E{Zʻ?2O^W1N wӃ[ \>^Sc^q;A"o[Ъ#τ˽j)3'('W>HB֕q>E0Gⵤv읽uL0˾G)C|P_j|ۮ_E?Rxo')wM~KKY&פ w97hi0rCa~;s!0cv~pu[Hly`L!Ÿ|MN5'6痔U2|-/Ʈ ? kI2r~ߧ mlp/)m!I<w&+T\5q=Ccrx,cE$8p97\j<_FyIx#kw&}}mf LdLƸ ?'Q͟!ssAugyIx5sxOLWYQPk2-:8W?o'o'whYk8~&HgvԾ@9rC?%ɔ~OMO ?>+_] 7JpQ1aq 'b|.Wk;#p_U0| 1}6xa8"U@_ÃݎF'hhGjLInr\0>AE;E;q?G4{Z q=}#ܗ}0a)<`q!.3Ay)8Ax ?5qŢ/3񈸄w̡oF,.ra܎Y\y?MrI1bva4n'o DŽ^mYKQO~i = Rau7u;q݅s,q&U8kNЋ$V7x\(M־ a !<yn1퍒Y6]!n@|G%>cyknu=7^u|ĞGo"yۗJ*gHq,ߢ`v'X?p119 >\cz SVo񵣄{|>qG;.yXidi?M# >uk]Ryx3l̤Ū7|0xIm.RXlߕz1 ̃X<*`qU}X'L/ )0n]q? I>;BRH I!)$BRH I!)$BRH I!)$BRH I!)$BRH I!)$BRH I!)$BRH I!)$BRH I!)$BRH I!)$?I2'v? ETE.v@Cqtu#L L_Y湌K-6\ Wɮ6@x#tm6vy a?  [:޳ <Xyz`:Z^^5n갤"w| Ow.t WFwpgcN[/g{ӶE%uǁS߯ qp$ 4Fv3o6c[V؛7 * Q ѳ>ZCge͗L⠙١cȞ8k@}Ci}XqA,e׫6s@{jąCdHHK g6!M֍5JBpz['݋c(RA䗽g alybU}ֶDw?'%,,QSFʹuu[*kc҃%zES!J S7 i4 49_t)|v{Un.ͿC[D]KXm 4rmN=^l-̞_١vgC{{/ ʁ.V3b ?D)5v[}Is@%`;m}:w}͸efWvAȧzb*~plwRաb =xY?Dږ~G.%|}u7 6f.L}1'5t7{7qJd|ø1io=OǍ1x% t 5KZ [3>/l۶BdQGRB#op n;Y6ºwޞ/Dn3HwZж;yT0u\tG6RmΙ'%6q|,NOK.7+sz [>N kVp/iz@5M Q MC ׽'ø*Sm!rY#xz)X+$=Dv]]+}Y "zqr*SΠx4"oK[Q V;|b]IOp17D{`_)DW>8hFӅڠ> hΞ.irs>7X!|P6cC&Z!D)xOȑ ܀w礃8kRsW: "6 p,=[f7h{t_?oD]Z2/V<§;6T=8mJuUuX:@7hrnT}}= ?v RSǡ/M}5W "-ݱ I[G/i/1<Asoʂg=mtL7w+Pmi_Pٱl e$ m.1t63 5}oV,.uoo5еh-Dup|#t?30t-nh} B M+- owws]:VkfY<ЇA'Cvݽ#ܕ N=/@Tݑw!, ԣxӵ`1o-nx[u,uh/.%X6]7psa9r6(QHmӢU=;͞k:g6mǴ;7Z\s?Cv=BܵkM!r|Qn:P@n^su|[m jM-q+A waOkYȁ!%nkP{4s'D7_ym3³ڃÐ+Vlon.K&*zP=Lxo:<HQǏ=#j k4sCm K}oC!,_褏m:¿ԣADˏKTx4q9ENjYP8=Hα+W96ҫ KY h<L EN? 98N8<* [$s2f+b:Z~$>ʈJ|]  l'UY:>t+\[!8#"fƺ7*Esb^߅uJ~qT3>!W',?-\s sƂg]> b7v|m&qw'K\XuZo[H!;@7cByS fcPW{la4 f&3.1g_1޼qCO}Ṕ7޵4.5Z蹹M0Mm?D NJ+c gCDSJqj¢!U BЩص~ ko;"~qn'CNT㖶^o@ /ā??q09i~hDEPo W\]!}r^Λ x۶g]B^p!b{d@"Ww<5ϼ3m'Ov?\^kS%5ogMvDOl9EX$e^9WBcM/ȵcB xlKT\.m< J[_rz8|v[=SеGS ڽUT3Gj^މzn]z>QЈ;qG?5җ 'u՘`JVA۹`O!4K̫5'S'*^T{ s??ifЄ"7fnq\{@]ZV 3UN=MD|~;vanw]E!ۀ=UBmG쿶8k9rQ*(mrz90SK y~{W'=%X B}!r4MevuQ ?`o) uܝ.D5j5e%o_r>f|_BRwM3rʋR\lwmdmզ:7]:TX/֞ [7{w][Y JqR#s|(c^/wM y޹G:) ""MI] |:yqz {D!x:Н~uI})yt G؉O|vD?}BmWDxoxz5MvW 0JIs}N ;VV4~w˶3րOWgsr<ѶP-7G /:~V]m"bS+uޓA qO:zL/zBd,!6N[v;GA|:"FuiGw |\x~]A@Ʒ5A~t[.!tլ[<һcŁ''Ҧe*g0plqTֆIX> =y :tsGѯ;݄(7n ծCnQQ~{Zb68 Z ~<^/ڠk,4F9{%x;P3~z* &7n3WsY4c" moZϋcVtX$u\c܏ͻ70u:ŸKtX RKFK Z,`ۭC lяڮ:Y 4z6lQ9/ k:zжjpzs `ޱ5DwtoѼJ^m3XkшKu9ZX!GWؤ[Z}6^̱;7۸W[L8,Yv-Qvn@XCro#N? \r@tCV'mn߱c)>4K5jM' } ^<+"y͓>֪pĶ@+YxlM>7W>rXytC`gnIn^ʸ ӿς r]Pؾ?!_Fw-#aR%=Vtwsp׸5d.^gx^<.F;ae:DXΛ YwHr\EvU8MQ;A;3ڂ୻NʼnG5 [-n4iۗ/OS-vB}qSɂ<[)жgܯ|3zTCg nߑFb 1=05}y'DN+qǡ }\9W9Qtmᝢ_Cإv=_>.Iw]˵uA>: Ѧwas !?k~l/=yyUxPWN>撤̿i6-)|:^89?{9]\+gҩB/;D<94!#;y4h W5{Y@̪6{ϔb^ySľjC/޵V][$ qO~XW7d2گ~z+Waw!|UA?"@ԃž֮nXM9@]?~BS2 ; ||+8PSܗz|C]%r@ug{:%rB)=@y%;b+vyA]ڲNc/ ➪+[=ym\u4N@>.}i;?J ~B[q| ܾwz|{dRU֠*_}z4< "~egm}XBw[yK}Ti <Ywi{tesvq)mC#a^NxI٦O)N +BRU^1wzgՠB] #o>w证ѓ qؑ=WN={ m?M;O'Gz9 ֟ꍭ Q'x/v:귻RNՅGֈ5ǟt:7??A\|q=|\ɦ!)8/MM_jAƮ_,9/_㩰| *o=| ֯~#; ~"Yj5g!RCJL bO(=Wdχ9݋{:@zg:orm5J|S,n8˙9Ӏ2MRQ-Tό~"rF rhSj[z:m;^C`zk&.IMz.ڐ2M~qr^%=o2 5.|&BChY?M9#|^ѯӉǡH1V^ }ǀ ~ŠeVzߟ<;G_ a~e}+N{&yG/0ǫ*ocB'{&Mn*~%޼":X.:D\/U8.hW)G›eVݼ(䇥/Om#CkG+>t׫}!?]j?%9.S;&N#6cSWh M)4BSh M)4BSh M)4BSh M)4BSh M)4BSh M)4BSh M)4BSh M)4BSh M)4BSh M)4-û F<(Q^|*;h-=]<}.|M=]D$~F}YncCA#gvKݩ7} @sܥ3 F;b ۟kAduIk lo @d#bׁƂM~m v@m#=@SL #6ls]l"=r|Y W.|ͭ7:vuϠ=KA<7߼V3.N.e5KЭ KV۝dP\="Pib:h}mn 7f KM q;qA3}|`n%@R]^Vw"*n4ڤBL4ܵ\2@WּۏAг|Vl!}ҥBBB6yͫ/ }QJ,>_f D]8P(ֲ{{ AwDnBSBS"|%DZ3hn6nSԟc]{aíĜ! y,m}m6)lw1Aau;ZV7ݓ?BVnбFk.6AAyx)p$h|tJDŞz.K߮>|Ǿ3kv,qWk6u1Нe~Q}q'6kq/@s(<ɥzCh1oO s+Tޗ]5{Z=,,ď-.b|;i#e!ĕ='6{6VG FUAN;-#v뗷v6}+v55~mڝ~M`º=;e8ûZ4auz4"< W(?cCoCK'.c-;.ݓR^=]MT5e@BNyghTî/Dm1[vb!Nٝ/{Dľ} ޚ?/i 6\OzyahUVi՞AS:nձD9xU t\9ն hPaLoo" B\-ÿ@H?ga_$hWαn<6W=}DTZJ}=iT1.1S__2"-=t<npt|U@XC[ ¿ݳQοVc [0"U \/2ĭ -tHnEUZ\aNmhhZt#ko[M6psV% RrUm+lsIK{ކkn4^=Π⮚}֋m ۻ auS 7M߷"ƮK=HTzezůUs~/CA?c{KGdC;74[~ K%?Atz%EW4[t^ U܅`634Bm+VkƱUi`7 $OAxxeȚMS/@\ۛoA~/v]̛0 kL]n{+_*U)Ӫ/~^J{ r{ |HS M(ڻr\MfWDTd\8hF2omo+T%B1BKܲ>|_߭&ֆ9W43 ԃ -j3G}=9?A}t*<#/8"[ش ( 禖[\G4զ_i@cL/ߥEAѩĻ!lÙgAW6ƨlյα@JQvRx1V{h_aj]txsUA3f!*U߀g% y-^sn6|q0DwU {SA7<Mnͦ~> œ6O fsŠHD>UmF./&9<=9w z}K>q{=~O*޷+@xΒ56֘=)=!^EBHy-m*d7۷Aس+\$أ!~9]vlZpD7'VqDN8=^9;$G?]!,شx]R_"gV|SOl|2<,w!7cWRKK9~a] AS6:'p d^ʒ"C=!H!ƄgZg5.Z]$[!?]0U!G W;{wi!ޓ3+ ~#׌ pl6gF.|8Bowtmj kC7[C5 hT\} oǠ\nkD;?Eh={D8Sμ%nnr%{ *3/ ;DtK 5-.i6A>uwj(Čjyd_K/9l 'Tjjq鞫 fB5 c[V%OWnu ®L:d?x=xxRaxלnnevf ڧΨ8߰6MPݞn6w>\+W*!^X:|1gx7_k@P@oVKA4lȃtgԟW t喊K\xg![Utk.O,CT۶'sʂMMmCn་@=]sQuh× y6w^]E1 }[tBqBSī].o Ò ~xh D:dq0\_}~ qqգT;fC5 9P3MB̆9u2@^ut? qK b k^3ȷjkgaz<_}tt5[sCǍ.a6)-[R<5Cw=K]]%wޘ*9W"^=:nڻk'2ZwW}A]+>gCWz^;筳譠we|B1]"o-rWkz"ǃOy:h3tc S"'Ezr- };5"*rD52<*t4^[>^g/n ٿP1fhZlD6AO.o"My:XSgP2`;}!9yĸjz^h^~-qf&یGA29!(؈!5!>;@ d 'm8Y~VG}=< h;ҙZ6B쌾MfuU\ C#[Z@Tz \^= w_}GnAj?lz5ڻDj/v2eo]ФMyhZUBU/~P߉HsbQxWe: >tB{(hFa+-CmH/ uO6pgU=k;V:Ei/JAJ;>Bh/yALJC{ ~L{-oxs!XlRbB872wYieCTd!~8+~hc>7D`i/ w@.b=[5itKv5!{v^2i3*|:uhc кsY<ޝ |zs&jr7x9i-g_-# |޶KuߓoCq.tgqaOYV|[}FG&i g@:!|MU^AD5?oT).k1)ǯpcjN.W@3^0β =Ct pǥ?O(-}[(4^?_*?t muEz >﫯RkUo'hIw/dy|yC^( چ[m=8YSl?HCWBr3l7}0u{*\➲;dP39<:=dG0MGP+#?{R Y]??q+P/V:wgM>m.NQ'bAtegA9/M[AO_DMعg }>n;;kVJs[ r;?_ܘS tpczoݿ>Ϧmeq4\χoSU^5J 8{vJFέd<զw .ibdA{VzH#D߹t9ztH/tǺ>{Wd L݄<ܐWB?7}1u-0?ѽ?zy"t:aS)|`;mm;F__Gs?8t_Wpn};2#_ :;6mnO kV:f,[vUq޳EASf.qݱf͟S+MaS9#ŸidV+7-rF=U߮^ ;> ;Oݏy~6At;E@xoF_񅗋ohh&U/䝛㲶eyi9l0ou}ŏ~SO.U/}О#a|Qۮ=|mNNlJ;Xwf+f&=kJJrB?l|4'pcρs$~ :ߒ\^__gO_K׃;C> ߙ܇4$ t*oq">'Mu왑ވoH%3vׂC9R{[H;jVDo'όّvtΞԩ}7"P?:Ն } ?^Щ"_t}9}srC>p?]glߚKⶽLGYK:ۜG훒vQ)IfNߞ\ǺgF:څ'Q=A큮Svh8N+ό<ק.S98t}O;r?OΤ=k~vN~o(oE?g%]')4&Qyt=)P<#%)ǐoE +4N#'c?ΞYGT~9|R0iCT>(_GOF3jorvH|#]o|So\?.jFnGS~'OCʓCMjX|).S*8_Կ`;S?JjTގ2t*ghTN8/*FN_4Ϧv@C/)uOM#)[:Ϳi_TOx4SvAo.2)*>}LMYϓ4rFFgS{~3uIToh$}ouh<Ր<ʗƵ7xԏ3Q:CJ#?Q8~_nԟs`N-d^N=?:S|L'垣$ۣ=PyxӅO6} Q;qE Yn'h.SQ?Pԩy}\\;4.W8-hކm@sدsLyCys}VҸʕ)7>Gv=3uO;V}(yXiʶu?Y+k~Op!H{7A?[(^ϟړ=3}(֤Qe,龏3iOB}N6LtVw%tO;r?^A;vΤ=ұ?ӟa{gbe_?%tޅ׋Q 凸z훑v=W=2u?vI?8:C>ֹ:߇(GP>8_7{s{e)CyQ\q^&1G;: 3p%%Gӟ a%n~?kwDӼ4~_z8ޒq0Ʉk?{/C r)P8R}x/އ|P#o߹`2.׍\n^ۡ}: ;b2џݽ2пp{g%)΃#JS3Η=֎3C#zSLG>uCD>Oړoz7itoc?Te/#nW8OVv8/?ʃ>{#♱&w~Yqc7Ҟ R]=~K'UF~*';YD!xͅޏiGh8N};RG>z`mdڣh><ѿwqy0Q'g`L{glAά=t_uOтB/q1̧3`:Gn_TOړhGOQ_񼈕4_q?ٶ:K׹ޓyR/J+YJ><))ScBwqt?Mx)~gt"Q}Fyҿq1:iJ}zH˴uIY(Π~s?OqqU|3Y꙱qF8!qWRc +y!}@1x/}.,ʇ=W>VR}?/t泘p|!Kb4Σ{fl~%7X2:{'Vz {wtg',ߍT|9SJ}u2&>P<#']"o·+,n-Zf_KYLe; ߂!M),, ߮wօ#~0x3W#k+ͱfihvM'OKvo3ƓHubc6 kךՒ1ޜY欎wf2jh8/Qf}Y_(;Wֿ W݆wfw=13޺y,pbrg}b큭8-^QMeG'6o`7em[2:K2D^z2[Xe=݁ɤ9%љnͮ9~mbߝXe-dކ/bX?Ln-2ʲ~۲=Ñ53K2k[inX]XEY?"_-T8{\NgmA%32!b8^1 -Yٕ[B%akq{J,EMԝl܂L6"?=ځޘl q}Dqe2lQm []m#6b7*s{vOSG6jWhm\27u`c VUI;񄺈k~ƕV%>P6LG2~3Q񻰾Z~ѷ8J26eeDdmveid6~-Y{g/b55WoMٸL}y+w_#6Ffk`.'Db6X; 245kכAnǩic־C[AˁA%vL>8BN* "uΌތ1(={&O8[ɲ=.LmxA]hdІ][[/3uf|tPeĴZLN=3VɪJ7tf4ԅVfrta4\o'&v*)paכmxmYK0A,/qVI1T'vb\_UØΎɡ-I%nuYٍɡ*)&Gi}X6WoO#e뀘Z`CØ)>}y3ãz2T%"N}i6v@XXQh+-N*)Nm~勒3 ʠ ?@_TU]+®5cu9U/lߐޕW/e.DY bu8*L2Ze']_ovk*U3 R5__*cs3}v(lf$e%g:L++,ˊ*o!?{^/;͌n>6m1#+'Wq|]ʣԩ0;WGɡʬ3BئReKs+~7_H[QYVۈFڙt|VO*G~(.Qz&7*ҷJYm*9+Y)?ߚo.섎4xx=TFٚN#˖沢B]lt}Ufi/Σn֏,:&CS~\'I syf3?+vh.30Cʼ>HnTۛˀdE{Ge֗לsX&%+2y{9, wJ")ЋeIiK^WWǧ}X`{z?-|(TNrKv9u.i/?t=hخ.i'7?|y%׫@N:YuҎ;]O:.NJGŖI]nt|/3]?X/(]_䋮mOS:='|ͳ&)_/;lR}%Oʱ <)_7'C9,IJ**?/ _9;@|NǡS9 /]2O9)ԯͯmIJ ~lI]O>Sur!tO8\?O(>P}I]ξNL분|Q*߿NLI~p^ Ct#_΃3]g.'_mG7:޿t\\u|P9ًܰ@srK\uv5ew9<~zSyߠ;o]R,}mR/(3<9ryL{_xM.>tO)SmIIMqѼ>\M r%r~osaIE.uQT>r]x|||[.7jTNT_Q~(ǥ\!mx].[dKSyٗ>Ӽ\eK=qY_9P=[/N㖿? \D˂~\<)B$OPkrF+9cT m}TؒT:$h|/gTt~\|+7~Bw(rxi/H୊>G.7 dA )K8n z2ͫH#I;6TBsDSR>))nR=q}(TzI?Q=Nʝy<>'όyǥu3cR}F}x].4>KNIS"ْMO c)6!iG>:]?9?|9iD'%3?=6œ2輰(RF kDQ~*8 !_4nM=Gq]S~S~QH{P;~q5]*窤=]_[r-||ƭ#SZ봔+zKRqՃ&Nɭ+E9W`A:OOv҂)?oP:mIQ;q=~lI{q?DƧq\M]Wu'4yR{~_.]ʼnG~>R8^VCz:<2ܐ~oE/Q:7]I>rKq$OqV.qߕѸ].CK߁Jכ'_[VҸO}_hDur@He?/On&oS=%}@9;+3#S{ECw:Ҽ']_GQ|Z h~*gOR|#t{h\)Qt>)q(n};l|Q[!QE9jGND|i~3rvJ+N˴r7C(Erz/J:7nu ӄT;yBNKd;g2lV]Y׃SYw6+vn.fqǰv:/.8T0ixsYݜwvXi>Jt6T6?h;@o{:}:Y?=zu2+{~fw/ok7?]%|6rFx46ÍmvY qWoo.o,gظ(7\;]Į-bz5E>69+hFXk "暕hhWxd62d;(#g<=صI*mcU,VI67񁺁rG{4['q *~p eNd2pm|P7Tus/`/d.fc"}JĿ* 7>]CܛȮ.cIl<媌89gr<'Җ0>5?k9L?U"M`SX9A%LivJ&I*ɇ6pٚ _3Ynl=fJһ* $A8"b2 UObca{Uz:R7b29 b*F$b&Ƨ*E_o%Tll5s6o2+=U>lf3^Y{;0'3A%8X'b ڤ8/;lfCn6*)BuQf^|hdټ7`rA:[%&bD>D^F$4ӌe*IЯKdkh*fvTf3'X }v"a:F%ť30yrcsrWI0͌od1QEv{*cLz>}+^c;W$_dU p&<~y!v]bksٺaL5U%t",b40}URk }2=妒c$bdXCkz6K%2RI80395vf|"vUI\%麇JY8S%ME Gyb&!1¹/UI> ict_&2@uu@>V;_KcAꖪeSe}rcGm~m~* yyfηyITVU;s~wz_VcY2gγ%ReüoݼOJZgKUyikb~]CJ7׊7_k>lǑ_K6P̊7+UƳJi*|}uSt;߳_|̬Ym)Xٽ_ld#Yeў]V3Rsi-⑎enrE!ߴnܺPeWV8qh>m,hs̯[2lC t.YqVz%Ǘn?5`י99 ;^9}7Qq΁l22_a>(늹R{V[vWcrrhA,'Ks{̪*|ck~=+IZF麛0VNi4fʊ5i6re5ϿQV7qULIڔNeM}BV2j-=r|#CE=p_8T)OǫH{sK*o=EVBʭ2;uUE)n=(+ >쓟3L/u8.-9 Zz?8ӯS̾Uޅ'ۮT[\UI1TMаz,eʤ3笙M''ܷ?t`?s}0ϟ pD0c-7穐\/vj9-:*FJ򋥑!T/SyTvfCjFսWV_cun J6V? ӣPX74#i*ܺ3L9z[Μt4jW7:S-&sx1ӇO7r@ȓ *0Dl這lNJ'Zzfٿ\|8wjYϟ;fO.bmOg՟3ޣ兯(^cY .Z?Jq/2ԮQv9Dߙʤxa»2/ߠW~N\{sCRMyA "_ %?wc 4ߧcja_zf*׭(pbSO8?}Έqe<zɾJj w[7,X&XIoY MQFC(%ቩ>MTXR3'E;i!5\SuRte!^%زd.渪W˔XYX>%'g+NB# (iπũ +{z)3F9Y0E U@Fezy;SPH'Z/ -_<YKgd  $EGAŸHXMWoX!gXOes~agB=SHe?Pcwae;?%z8wP8X¯ft_ Dy'W?c*s5̓t7noǽon~&^ ~\8g&ѥɲ7?C}qу7!#)g?K=3+{2l/CI ̿Co7QQe_4J_LDNN.soB+=Ұŵ*L(' (z02c\u0]Îi;~SC_.O ]Si*r?H 9҉YG?",zy)3 b{̢V,(i0 ?ESe$8pSLaKel M+d!ѱ9.`r0 }{Π7 ~usK9>_i RїlVw;t{=X^/Ic:NR>{$<__r~ĬVe_l_)gT#< cDaْ~Z drH`SqH_GrȊW]j"ׯQ ?!` @ h*4~J h O9[]! (aYЃ۫Jo G@Y@g9i$+u~ A_K˳2%<$o^;MŇ&t iޠɾkAm?Id32lJ˵.W_[ xMI8Pd%x?f؊!t1%mfrn*K%9Iw4v*4J6fUNנ}):~vZ~H.c9o7|ȵ?ȟ`xH}VR  @HY)(HVSf< (&PL'ZtB BL'DɉO D#`Д"(c@8аM3^/DʗR F?j?CXGywCd \ aZ{ɌՌ0\E٭uk|ۮcxx-W~m3@` !@>$(哲nvDnK տ-*RoyXj*tr ~,VaKTX~Ӟto.dJI<,=qC;{ZњM*oX0"alS@2 hhdުe`cuyh Hr3^+(rX"CpM LV^[B#*GUGg!^(Z>,&m=:3yzߟ Xtpm .\?K>+0)aik~2y`u!'=KĽ hOS9V4i;`F)DmMiId)cȦD9> Ȼ|3/I]JygoO쿻džDHr帽z2'Co6+ U_f"ZcYy֫  >--?#%,zӟL ?7_IF M7l( ?|=~E?*l~y@2_ gL?ݐcO+Ӹ3?}}ZAZlp.<ɞVc0m2ϰOP0_;A8 ;<7kߴ3ߥ;xwMOnB>[A=X#J܍tTx~pMiv*l/ÑִO+p^倡?"^@rHYQ!|g ~v[xk#pdgfǶԄNW?_b -! 4˺%WV]! L&/E_5P0c{U%%JI +7EY|v^b̵ Yvp=3Uy!z#1< $le9cf,CV'Ar@ q!k _Όr3Si n}T?Y D*W|?"[_29|u&1crq[ʟLrH}vVYRk#.w~OF÷J,887h?~/}Y>gGF/f_b?'Ξn̸+ _jfl7 30e'pMxUܸq:pob{8ֽwօ QAqƍ@@e%'$%勽/n$<ޓ9} BcSy,DݘG5 vW0(':QoxlTpkyPM9-ŌEy"Q?pئ ~@(өHN;I K?A *$&^}>ƑO#0[Φ=W}jH`:W mLi~e0|٫O)+49<w CZt5@{m&j`A*y ~l qd` '\['ቿh3B<7pA}%ܲSaIB>Q)ҺO!QAh;a@lhŰʬll:s5$#|̑4oZ~f&/|t2K% -wxFMB%_{ =AYa52zSN˦fʕ'pݗWTtwn3unXy~[W(gLb+_#Z/mB!_[؊Hs27OsZHK}J q2kZX_$π+ƕ(b>+ˀ^\)<*wD$geVJI}İH;'ڊ`~ `ߴ ؅ηˈ#9)n}u痍 ݭgx Bç*mtN.D(is4v~Z̹AaM~+YGit:HNIxQ^՟q3Q#U=Z~> 7- eʽ/`_qmG+~&ƄI;+DFHl͈hd}0O< 1_䴼^[%QQo<*?nmJqoN¤f^z4$di&< bJDI^)Ðp&5HWaW0߆a|Hzx!Lڹ)CI čhCAЏ Ћgw7Julhq*|ACA & [2*U,8s< Xvfx!'Z^@Ax5aI9z-/3n i[-)N섐X%¶qS #k?m99 m,^GaPw02X$B+]W^&l2ٙ@ӓ {CbA-̃D_&{E >%TqɀPBU-_!:$ÁHFq"%U5KR2X I'PW< `hx1dM)JF/}ы$1ϻ)E).b5=b#EPbrxXKV_u<[oD,gOHE+TjbPgǕ?|dؤLJDZQtFN/?Ve(myȇD򙠈.̎-jغ %e)H'ORX'QϽԁ4=8״rXVYcDRNp!_)f8S >byl+4`D/O'}$)bF(+CdPoZ@q/>b-+]Ƃ5\ )tYGAZsRfsHNEO1 eh%:'Z^/9'>ohN7]P?Zzy9iP$/ e&$Bp{7+o 9'os6r6 Bs< 9gRpNND=*K E7 t&Y};L_m/+kS%!4B#QU K4|_zIT<˝&GxsB5L;f4z%bM U&H~\$6zRII/-:7] 6vg}ɳO?\7|˹QzѮʍ&ڊ[yJeȜ"E !Zo6+.hywѷݺ\;lY&6wZ/<̾+zeM]!UQjj5qwPAWBt"8 bxTs"W |F络 BkK߰dxci^[(T D!ϖ𛼹|*˸?vЋKw~ P|MΠ2ox=f`ʼn8\1'A3[Paa]p\Kӯ+ CKO5@djypʎ ΢bM{EMU6٦ 7~IhԗGE=h^1lxfv[6KY6n=mPfF>\ŕ9eRc6xA@m+}1^!A@AF-]|hϢ2ugs q/.f1c@AyHK~Z!X!mԸt M%ylI^DJ[Z!nϦqs18z: A*Vs1QrkD&%1G#&];CT,^z]`sT;@-̨V@9Hv+7v VYk׀ )^O(^oXv%" |n&ä́(O j ¿c a;]0)ytTt$u&b8V8G`f`WRZ LǀkΔ4)m3 6eRRhXH>) *-5mm|wRɰH_0"WƼT u3@:i>dX%>@AwJ*ن~ A8{5ԟ3PMtP?бFWTw&_% +Én o_;weEpg]Y~B2,4w!>\v#5QEBt@E΂4d(*u?>J Aڹ|@ D:Dl$&V $B ULLbf),hRՌ'?drʚ~@`L!;=o<4\ۺ5Tf]b7TGQI> S0&$g "E]LU+e:tM*=tDЧ-ysgmR3Uw|N">1V;\WP0?p1sr6r&G1< lwALMeW]}{oQI:'BB>̜{ ={DŽեWǺ7<7׮#'}'m7L4yuM87].yğbfY{׋mFcf5 o 2 {˷n\_ Eyez{,a{4)Q7}@߬w'kw}wU( Bz: *95PIDVR[zVnFTg 9 h :@ȍ'%=( ¹;8V΋x#{L1ZA~EPqhMta>LW:dvN$%yaJ+p餄էessy6$h?mϙE56M6zԭBQ TԯLe\y={j_g{qcK@bU 1C^Cǰi,8%JPLRpN:Hr/#h:yC7|D3RQejT[>[1J?πPXZ <*|imB5z3~ǡ'@.# GA~h3фr'==|nv'؛&;= o.>2NtU7o[-f6>< BcQW& d7zw'=&W}5!ъ]d/UK|)mS*#iEB&R/HDaPs~f,]۠c=)'o+G>Ǩ!Rh|)ϔ#n>[ Y\׷tQ>,0 ܋ӯ[B]DI~p0K?l?^GՅ52Csw8˛⠋m,{VK_RG;ϚoOAOCtM;6wv_L80S(c=7)ϰ Yؓ>V"dL&F3l\qtGk+ʝ'{-Q]G|Md*eH*4aLX~AkzQ ^Aȡ]L!Xonvp|N3=:s6{ɛ&A bIv)S٬PQ\!oBz˚BN/@B^՟'GKxvK!un=h|2bԁVRW$Pїȇ׈֛H 6 Lbރ *~yJx5Yoڋw|+˚ YLAVSg(Z*: KedTiE-05t3(MaG_D5rORٵڋ$zM/}ߤ*H 0 q!kTaW.=&Ӏvl;Xˡ$ZP a?ʲXGDY]?ģO"+( gnȵ,Es!aǿ{O9W9y(+%4IEDJnof4ȼҥ+Y^n 7Rhk>cMP#}IvAĈMzaT4;vv"4? ꦟG@ȲJ]I^!缯ԩ`C*9I39<]Y+v1ܼӔD*ؤLE(}rHgCJ^ q헥{aHH9vb:}!zRAHUK}VnJy3mc4׈Yd$4ggBKو}O~9Y|A>RF0O|tJ (@ Iר0ث$TҌ}^yx;"cAiF4`i(?$=S$ܙd\+Z#Y 13Gn4ؙ j8$x}pг 3}@Ҟ"a@B!}EȠPQIEU.t+f'lڂi4Ƣ ,=i+X} ۋ.?d#p"v,PSi-B)iDkp-kŦ䄰;Bj.+u*з1QSgӓ}]WMnWl~<nfG_ =7QQ^}!CH=^@<8Ü7樫!Ͷ?a A@crF_8 RAJEFF-#f+:KZ^o`\E(*@q+DAF-0+|2hfUdߪ%igwl`Gx8UtƆ(=B %;:@QcdE (AĶt4 .M8ѽ 1[.WngD&jH[@K sb˶R4͈f=-2Ag+(iy-虾 WS"z?s' Z#Gp1xL:^PZ7K.#⃽vt}Lz>20J6G4u;.&3soKCl^x'd 3+>NV}ƒO8'e{}xҸdҾ~N+\Vz9̣3 ,UY(/ʔAh{A,4 qmVO =/j)*< BN=Ghox7~@}4"*x5%_ vY<Դ3ίgC`~>#"y7r@Hy4~\cBQ>Ӄz:UÏadǓ/!~ ?@?Թm ơəG⒝[ x hH +d@*424y-b}Z³OzG?c\<鸾yk0# Wcxpx%.S|dqik3%%t[q/lE87[䙁!X=Hq\ P_'dtIJ᠋=|&݄wz@ tTZL"StԙH7;b@eq\QB):`uq+$/!BVQ2=hW FXȠzRףa (⸲D"ߐuhb&dۆqW -MÑJ_;AHp<{ʼnum[O&$eUMm+?,=9Ԝe%sA! M 'k_ pFx=~`]z{;ETpg2AI&QQ_Y12i@|Cʁ.Zݬ oj ޅn?oQߧAʖ-k@yJB_1P,_&-Eg|mYkUejF'tC%+4*cyFӜ<${4E ~a4D>^nԼCS^o K-D~K tO13MCI~pB#5lC?S DbKoՍ !uq=;`G}yT1)ɟ ?W4ytDqD$LEONcPbL|aOu5?f.1&돆4IP;1 i-az DƤeU "r8~~0¤@;?A]wߍL1WnaV8wM5N>i7^;3E5$хDyezZ,`'c!&*ˣ=Nw0߫]!EV ]z=m`˔lRփĭPZQ(ۍc{sz cQ0gJ*72{Q P5AƽwzL㣓27ĭ/,*RcrRoAtN}3mE@crV1dPH('Q2ߧA8"щP-滑94O"_u3bg_#ZzUYvUiLsWXҖhة :Qz(tVɖָd!n5u8_J5dn!ƿ+67.D.GVC g1UT+F94 ;M~Tbm]?M ZW7|?F:;M^:<}w#Ƞ$o+(͏j$ȰHTlƙma) GF\ż-24)4jr{#>6}jZK=&LMoiY;ZmHJX/nU| Mo aJo_{bl4p޷1`Tdjz2P/zTu.Qt5ja<ʹu z ~t6yvΫ7n~8;>MABvQ}6蚒 BѰ-kd}\CV R~;ҝn1t3?-u*2i0Ȇm@b ح(j7-@DwR>.4 1ju۟rq1Sa XApSŹ5?α3xk(/q<]IbWꝊnc6]́M{nzCA_7e+5T&.8qVkĩ4I*yFH;s+sBY9/ ?ӐP~/B8]kUcރ/L\ zO4&VePOS;&^ 7pt}]5sOz]1~QЃINS]:l5d\|[Vp)jߋ;~SXUTN+8)|%?= |-Ζۮ ?Q?P$nJCKܐʽϩc‡}OЏj; 4#*ngx9tPL+|ND3+G7|EX4.pH⚏o X.r%cja>KQT \\l#mVm*hʏCw}ڌ_΁-G~2v׹\ BL=J՗NJ("D_wC8ƃEN)$f*6IB S)SQ R8„`i~f{ck G #FdhX])cjuD[BwU/K(("O6hg;a0'} >dg*aF ѠzVԏvO?} K ;Ɲvw5;B_!>q/󎠯lNU@ߟEߥdÒ3~[ FDb*edIg*2;G`aLf*STnX^䄤-Rf,ZQ"E%&I/bʲd'4RIj0ԦE Bb"BIB5ATcl,"RO<^0=<93Y;R ۴:.6M,'T< 47 3ifAD|Bib&vUp81f9` Z]9}mq]hviz=)ĴS/t:~2ZƗf[ɳ@G)m!an;z҆e:߇/ YGq|'%WDkD˄*o9ms\vD%G䷼GCɘ&YDA`CLAgLdZ*ْuUHP1N`iGja)`ȓGAR]!V#_*D7D *p MZ8iy Dž]8(+D(W_mqgaːvnd%Λ;Ui5x]ņdÒi)bf<$I1Zbv[2]T7̑zp+pbӤ2R҃x,SMkyƛ̎`]I^q>p"3 4wh&kb{QЍ^5H)AN] |SP\$s =Jh -Pֶ 1ؖҖa7Гk7xW!wa*[B# k68 t/w !ݛY?XI^ٖpQs^,mnc-qħ9 q aO3 wqu*"cg~sfGz҈c~^!W_]怾?TV6{@Q‘n$lbl!C[A+"u;-%,ѷš6S%ci>P\" x*ْA< NP)>ŀf͉mnMyJ,꺋? !M57$?LM7\7E\w#Ǵ?x`H{5 .T>~ ^e@= _Q~~6{~+D:b,hZ;6o$|dHpܩI-$iRA$%#sR:(Aw)ٲ(7#v1!tjsT Ka{Y,QXe=oFZ@o)F¤;isե $Ⲟԓm>=1[*RH;D B'-¹owկuou.wH3yg*7m֧dUzlA `xl_aюw9+&B잲* >mx~+/F=|wU(;HJugښ{7,|/N2*DAqd2Z{Q!fȋ)AL;˺%wW~V Q- E=Ma÷KASNxT>BF{ᶙhɋzlGX3xmԪwV2k[y(/qJ2/pkC;g/So4Y{0}rs!6OQ6ts&woQoRt5hyk%YYA@~Pބv^+O32H'3 rK]%O*K}PQ%tQ9qeT|Kw˘4)QW!)3&//b):5OYxX)ǷʐL䔥yQ97_yWPoy7 95BǛi+/ļ2p헠jqk#')F3f]EGAJϑ$PLPtAcQ%Ne7#1OJh!1$B{I3F%x9nݝ^Ljb1B)Bdj\ :1B#1HmzI.pܩb.( ns 'ՠ4`1iO4\?3sd|rږB Cl 㺎]^쟵ݛ;3\tkd+9Tuv]82q~lXRWMCsR❰>x|~w5J+ m臫 F,V'*߂ead&):; ķ*OD>Wޣ4a%?g0Sez<R;Z5p/>n)pvهnpڐFkJ#F.IЃ#3XcTPq[>yio) ODuJM9R4͈ KZQ-X'փ2_+5'UyR8V2%VL!yڍPk[y 76jFq.VǛ0y[NdVe?u~_+o=p4/b&Vۼ[z5͛Xv Vƭ ksVh65+d߈ ; Qkw4 V]܌*MT*Q:[9"ɴnjTʿiό- :Z 7|gY#gP|ǣ>.~.~Ͻԁ4=8|-T 6,Bԣs_qSĵӯ[ Ni*,>l:1;SaIU$"#2sV4 IBaSkQ*3gNeL)OHᚄTSm{sZ¶Kfl]"jh !5B&D=2s7$luO" 1[/B*2{SE*!owQ^kz>%DvQeA}ĕeD Nyx??GlRW 2NJH @}/ș͈2YT,AAUs̤y'+D" ׄ 3*ك͛OC>P\_6D4J]")wrs| q.??_/i{[$![|%D4@]cAW3OpNg(:N{7/ơDd2AY5(elJ+a~R5h;h('"U0!(@?@Pl_P ){FRUh/B=Sb;$/CPj7U>A4ϫ Qx?􆄼ExWnxg$N{'_c$n5YDt:l@9 JƥheOCYcd8 Y1ĒMl?T%_!ٞ3AЬb7 ,xVB\* ,{"ZOw;{h|tas'!ë7M2, %{G8B%=Tpn nkδe@78?2"K#;6(LZ@ks o/.+jl z޾//lb:'sh" m%}I0"٬ޣ=sE4{T9y-suR+vEr&99ry),D6'PG]tpGrJ˿V~Emt}7丐;'}a!빻䔼pR FwiԌg^ 3-r=\_3$.a2~'D :~$d,t;_\p3-藿pa\^ aB>QPywdÒ:SEUhXE+D"lܑyb4",KKIUyޣN[qD10 &(HkD*J2ξ̞zejck~62_?zO)qjmº©7Px"pa.o{nv=J{Ϧ,qتp%NJ,Ǘ^C* Ғ>M& Y, ww+mAJm4h>bYȊ~fܞӲ L`f'?P{lk߰/#!pe*77-}u痍,çg#mky/R0[i<=|nv'.ӽ(sT;s|^ VV8_x 鸌zlYa\ݺ~"l_FS&~d*:vmۏPB=WnOg_*N.ݟДlXRg&0hE!R]q\Ւ+ GVk̿3f`69&3 tE6 ̳A])? 9 sUJ܄D&@3Ԍʶ3̟*+IN+rr?5| v݄(&͏8@). P$W-v^.!>Kt$,Z B"6~. M̳EJ6{HU X^.h'!%_F+D΍hɢ!Uf(/#a1$du4@~ $3,3JWUGC:(4Q~TfnՃ9AG1dmb%᪈Do2>\>';XpXvBػ9Hƿ\0"gKeW0w CV@D):;4͆{ƍx<>=jYƣ~hB~I667_@թ%uܝM ВMl; nnt5Ga+#[G@e.C4m(LZ1YZUqr?u :_st?\:mwg'@_?dW4}.6nZXϷYU*sifDZqH[ܧ1Z8`j7ۖ0R{,|,f <@P[%&U#D Spf[PVBI~E_Qg@ U'ydKO|:B  TfRUfAe_[CRw6^u0KyW п{~ʠHɆ%U2erud moajV[.F̊bR f9KŚ,*QmB02>?k eDjr|#띷MyffSA^U °+Ę$?Ie3'փgnK|X{tJ|)2Ar!kEhgOQϊY11pZ7& Yb =fJgXOF V,  [ayBA$#%yАdXF,)a0j)fyaa+VVnX qɯa#C[gy}<;h*=?1lR1{bD4, qk9'ڃ'>?Ѫ- }mXp+8rMxwFLŒv|Qdh} $׏V+ 7 } <1 %xn揼0k\t Yէ8@]-^ ?j.\S)l\̢%BVf<:B7BC9(‹L aLuI;%ZC9 [O'6&:=Qiiu@hvz2i=E΅_ ׻m7DZԘ ndQ=Q ["qtqNS? =㭇?^kyt/5{4@w*hCǂ>_*L!UԞu% &J$bX׈-d\fHK5Ùz3l ӖʲͺA8;0$ee[*kʏd ŝ)856 W{g eqXGxD%yi>?#$EyM89qFeQ#5?Ps'j^xZ{7ABQt~NPz-2Vb?,QR!#5Wl`!M^k=$JէRҷTSBO|弭|Rr{3Ak,]PY~i#q(˳w. N"R{-MQ/vǮgNYQhڡ^߇>ezi]:?s>VQo tO>S8*%?là{'(㊇4>$@=|8ՙno)f$|{LbQGgpE WD-yC|ӛBiٺZuZ_k97ܵ7᱓گc?@+ï^*=gLZO\|eÖeE߹EoXϵ*8?)qٝلs0Q ߿&bE$AH6l(v?k.]yt^to!.=~;M!UAeV8"⡰K~YiA WTxYU tÕAI{x(Ѡ+.r=5mQ jOH9r (#R߰T1Y|U^H>km`&eTx.MG89:e=B NB}5 Q=h@5AOqtCe\]˧>/Ê5<3Atb=%WԺ$s^ڝ:h|DqAXB8TWpJșHDZi8P֊aTg![S,"ˁ'\%*"{[ *&S*"aeEdfdX\xca$ܕZӴK5K{Fw[UL4K=Ed }h{{*ntw-W5h#n5LLԣ[D·;=;X1K|w'9y">CaKZY(_H~28䳠Tog_#&/j841K=MLcKHDOe;@ W+oC8hx#NCӮv3I\Ê ߜ*xƜÿM^i`b%\QChL9*iP Juٴς,*=as! KUpi.%$c샴)ٰʼEDnͤ'?M%dRh$Ue*_sH7!`PtZsj,t1zvGdTuDAv_-P(ona."R6gtlRytۆ05#6ߺ=VxŰ!rDۂY4ş&9 ?m81tK. [peH?|}ꆷwW VJl37m;KNd2jG7#Zof8XUWW>@'g)M !"Z*-ɉB7gJɹ99OxxBy%~ Rv )DMǍ1\W䨋y'dգ CЇ"ɛ Bȋ {aaqC=£nFMLbƀ0 {%n!1z(Elw9vx[rX 5xRI$J!{7.} 4ݜ 68T*v,Ti#Q ٻ7sn8nSSW7IاgT6`YOd&<юP4dA"{w|α6k>Gnʡw D@>4[K;}SHzSNNчA6:.KG$V]AL,Ig Y5FV vͶT$fܺ*SD " } fw JƎYaw$1Ҁ*;ke>_GI^0ď.jRAQX><u ~ _eHA .@ 2s!JWH1"m:T(3X*ukԼR%ReISÚ cM+eTԇي`׵ULHb/h)>[hBԃP<0!gXE??ܯBsŰ '-lc(L̮]boo|ÔzybAhN}ՠ{u^\{7~1D1ςPhZT j9ICDh׈֫AǙcq5aqY| v*S䃝b# D_K*ž\k'ȑ|X5P3Q$ߋˑ|82 ?rF6IvN 0*U>|[9 B$/߰GMrXugp/HMej %wq+b&Z[BLmw |=9uG,%y 銶^x'I=U nA␙KORG:!#$o39ILWIv͈RbDQf[f [^/9' kh%a9#8P JOy%+J]ͣ@m{B0{*眤ւ'3&8nox[:#tNRDrΒHޫq |WlzL EMw)v8749? Ðe޶5ڽ%W̉ha,jy줲oQeكT\AD߾A\~)CV(6[Z?}L;r"Kw+?,=9M)fp^]*Bz]mg3Q-X-"o}{WǺ7Ku6^4|L)<2qB/pQ~~c]=f$D=|=bz9qwjOjnqö2 V%\ ?$7^H#0%F9LvqdUT׈ 2 `~[50br{Øʗ?`C j|Cb(1d>>4{;mX4'Z%V!ʶ<\[?x2~dX8Uoyw8w+ε^(g뻟eGƑʱ>蛶;4-q'$6^}sc@y}\eRJ-_$U lQt": NHuv3u–f@|p;atYoos–*˒mE}(ͭԇ ZDl3+Cx)i?͛eUu{aF-_",(~3{k<O}#ZGGcێ2(G -+Co\KD2j:~vudL/\}q[xy \) |K}‘1!cA%Z~ٕ^7>?k jks߻Ai RbRc+n9ĕ eV R8҅P!?aGSaH]%dʒD_mEuX[~H毒/fZ' \ "Zi4'N[l*G|h=J*l=ƌjZGsO_5q/l`kOg_Wk[ȓ ϛf{i /zXB>D=+Go;v!x]!5 u ⲿ]w w^遐|ع#NLɆ%u%8eJV9(m;9sɉoHdINMTMxEd33GҵǑ.&P3 % !Zܔ=~ A8,4? y(95eDM)+ Gғ^ޜܪ0sY48`lGю\=$$g\}'x*%WZx\_!^QC|]&|j Bꪭq* ?S4bm9ҊƒV[10U,^`*+ ΒY- ¢]j{jZ57g)F^\f6\ThAj+q{7=ymP@ ~8(Ou?CQ{םBL%CAWz6GWB^]}_̾wR""Kr!bZ W_X,,E&'\GjC N>ZۊoaƐ9 ׋aǂWCZt5@N6hJz:wxU\~r.pÄ*#';- /t8N<]ף$nxϼ=+%?ȩ%>9+ (:J-}MAe脘4+dLFb M0++5O!mؘ?r$c67gW $T ͼӇ1+zwBX̕-ǯD>cyRX]mSlc&uСUK?{s,bi$nQ"+QoVD_cZnW]b6r!T*ΌG;%eEC Jԧ *QKݺ% Ns*y5[0-3/'8Y;īAYNiK{}ý:Z믇)qş ?pխ]L ;RF׭} ;Z;{alpsʻ1;K)efFZٷܷ+!'fsB)Эk7i / x}IЕ2)+tk *@ey/ۛa m(,VW䣰&Eh@> PdIb3g4-Xz ؜(GcЅH~Yօ;4P$U 쾺EѮMc== 3ufͱ#c&_"nڧdSmç~Xz%$X$t& u=72 M 1uNq Rm]n'ƁnQg~b5X[`<rI*Fte=?9ab+Vjhk2†?5 D'ӋP NI{DlgMN>"N9jBJIrSSNnu$SyyQ 9; )Nj,1/=}D:~벃D]捆:@{H?d&3B(?4>$2U7#ZOE,$ MVRge<{7yʱU9)=\enSj/!b+2&bJ%>1H%6G("$QNA 1k-h4E?y($=?%w[ܳӕ|?<"=ȍ~,PW~^,zoz)L%BgC0$N Xa4-Wē͈>t䀼Ə~-{7R`Ӊ/{jpyb˛9@E/u^ԁxGc ?J(|Q.&\fv ϵ'N\;8[pp%-=$^EeD=*!*?cAlA ??7[~ `} ?) @Q : 9VeEos+(jyg{z1x3!~< O'?3PEw#O\M7P_)o33puٜC j<6dP<6'OZ~9J]؞N͇JKCĄ HR/́7wz5BKɆ%U6|BTTY餄$'}5p3" zJSqr,nyԳdX̛&])\|(sg%q +U+Bg3xךRJMɁk) S!?~uy3Q- +m,|aWf)ZoWȱù)f&[q yl<K z#$FyJlW9l7:Q!6O7Zُ_zUnx7z`Jlq? ˨i\1@lI'к 'k bK.+ŬzlΘ49,}0G[$ޅ7-$DĤ`x&@Ċ!(CXpᤈΩ=A}w! 1+C]DWD!YFIac4,4_ D|xU@wQ6loGjX|?Α 2q%'aAk]iB+ѰB@q|'[(5)Xu< ID"WӚ,QAevdPdu=xI;X&2yk`[ՅtU$}dþ'O)cEn ꞣ= a^7 ||$?>Wf"pi69jjC`|R W_'Z=Ö~786#+/ӏvH[Ǟn7v;ޫ~6ϲ:t y] ~ ԃ}16]}dKz qSNJHp݌W:M;$d%r,fy=/f''gq(1-'2#C8Zl 5:>a8q@>>w'bX3Fs5hNWs]zdXq84|'p:$pD@>;!!lzsAyg c[vuAֻlrU,LU˴AuSkd;/i1ePk}Rs^yZ|4ǘm0ĵ>e<{9CZM3w~hNNNyor|P!ZO6 <3~O܈ltDj)Z$#/"~ΎQ/RKԷC\JIro z-FRƾɘ%늴iB|J&ϠBӋ\K[ :Ӑ8|Kv =|?\^'.ϋU⸊NDֈ]|hȢ29䠈9"%@Kt̃C=vcha8PkS@Yoȕ4uח ԷMakmg)0{f mq /tO7e .yʱn`d1 _ӜA**H;G!A֗aEAkZuPg{O;!!M-!!O_]P d*"dQ[NbބeYs d(h)/12 ,sΪ28<4[ =N}ȧ2e :H:| ˁoc+,S~eϟ|Yk'˟Ed i"h4x}0h tZoD X-+ȈQ)NrpW![gY6@*2p !ꏐNX-G˴i|Te!a2~  M1ClXRY+]'K"C&qC bp[ijvRuO4Oȁ\I%TK3ukD|a3P R&x\Պ!bQf{Ka 缭u^f^$x} [7Lhg1;s.7aEy8o-͟A!䑍|Ya>aɨA;CSOAf Ln̂[) vJdh 1@+:ɰ>uvkfp[^+5QezP)RMMc | |U=RsXlr-l ffJRR3S| .q|$?|=_ogQ>D,%߄u#"!#xBEL{e6\hY3sN CbW~h E8D U>Nd"AGSU#ыF 1\d2Ϡc?AaO:._"j:63" ~&7OJl1~Bdl%y3 8pkm|$/!͏_\DQz O/Хj! ˡ4\uks6У^$ySAH9G\‹A\[.ᓟO󢰜HCn}I,jf, , U)V'P\#!L<%]srEw@Tqώ,Sf oJ3gRX ܅P*e jz5/aŋnĆ2?k8:Wgu;!n\ e_|ػ3{kɅ|};~C| }埋}e %>W6 _!7}=TBKvl_ׄ#T#Z&Փѧo 2/N‚ 2i=aAz8!z,F6#ݿ1,8X=\!8S]ϥd04H(ϼm4PaCP_T(W_m QŃdި3}n;$L= AկO_=lRylXRU4@$ m1eg)GVDji@Ee:dѰIzx0f\yB?̬ А /,U2 YZڙsWN lJ*L;'d!.ύ/b1|e ?tE=*K||-@kZXnH(Q/SHlREN m D>xDb&)t+fg/ 6FP[>drI*2"^Iy2a?o Q $&y|"a8oej- bɎ/ kbcޜ6*r鑭_Mg[[N `ēFyZ8_;x9&^Fw ]߶Ш7'BQ^Qo8 D2%&n=1҅j+֮A߀55i}Im9{7C%G[N@MjNJH^Hn;xԇo;g'|ٔkDѸqB.#emFQ6!lX=Wh02ð[ܕV䳠[Qu4nAXZ4+l2|L[^=i>(P0py~^e  Ճ @S\k+{w0Nde-_V+a!U|VOS.igҽK3T,Gb<[y_JK$F1gItXU , .Ӽug6痰;Q}m?teJA7CףdT'V$f2 i2,t8D&nF8Սno4NINTWJNHI.hbZHȷ[܋_4'/6%hnwjzP?_+#ɵGY>\ 55 N9K0ZBՊPqYb8T˦>A;%RރO@{h<me={&H~ b+.b&dPӞA<*;ׄB~򞝇Ϸ)#1$a|]V(C60@ 7$57FY~ ɐPQo%$Fbt9 ĮݤN tj&Ab zԓ$3,*\(i|[+h'q)Oцzm}dξ*X )VAIH"OTK@eTL(SyN>Dd2>vסS@I^ ˜ '7/;Uʵ2+J(OW[ _oV-4>'lgsoЧ[AZHot^d ¿qb+:V4>q%AN{,75mm8Y^M e' 67.ør3._O2 =AH[+Zbu=|.wsOUCsE(3gBnT$INܺ O~[s1g+昩փX/)zF"YZK=SE%w8|Vɔ⌭pl\Zj@"c7QJuBzLH ĭB\?1o=t8e+#$(D?Թ)`Ij{AH BlH[K2,*K2 G=+5DLC&BHT--FTTkB My{sRbf/oxCY[ZvL4a!a6 9ځw˅_v_|}s:Ý'w~lo=p^Du>@HRc~/11 {ypz$M!ɬ$o3r;pDW_]iH瀈K)͒@ &g-h.JRhR)@ ꋯ#ҠoyAH\ % 1:=DMJ):m,҂KXluG'lD<"'J|&]ih9cA[#7':^{Ui0,hJ6,J> 1I\aԵ>q)͈Q$(ƪmֺ;'*0߂Xhf`p$$ Fq4D8}},hV~[XBM{n]FI>IΡ,Ѩ "'8ɩLTn9ɘà8EUh%& 4lļ`+)9Ͼ{t<e@YS򃜪qhIOщ6⸲}t3"E)Zkepuh0 #p0,39v*nJs~?@%Ėʇ~ AD\Ҍ_ ԭ?б*7I)`ȓ5JН tdBW`G;o_;{.u{/}AHBZ!xyp<';Ew&Hx\_!vݖ&CZ8r7HxH@^]-fJ6I<b'M!YugؘV21K`Z~i@.3(|rK4NE&(b'>W[qD̸sLS& {:g) ֽܸ fLRϰwjUfn.unD_7ZWZ&EyzL[sK> ˝$:8Vj@m~1Ab'O#%T$=t?m Ȑ(ēOA!ZtHC1j z"b5E*9}ʰSMeѢl <ZbBk[NYzƽwzdQ f*La!F/N0'Y.6@lfVFm.#R:BB4oS/1jV`7Zoda_RAH+ ybX0HWDB+uzBfRؒdUɛɎCEWtF2!QSCY|̼:h>ܢVEܢВ0-7^͝W΁C?YU*ٷ* n .qRqVm&Ph2늸*~p>jBv]b++ 'maĭ E=޺ݧ8:!Eў]q}vC쉮^Zox. 탞] K̋ ѩdq 9QEk׈n44bɈ[bRA4,W9ɨ{wr#>ELpa#B iN| ?F(Gc|=* C]vu,xqH[;F\E ~DTKLⰮd&X<~ 矈[! ?) ="S0/>24)n5ĨVCvC2Y^B߄3 Z^˷L#Ȥ⼥-S\ZBk9KBJ ..m)'>)q7%@YOx2k-[cW)iAeіnAbp=kqK!ɗEB]LG%ƧqaZuyF*a2Rƣ(W͎ 5?a`a2 w_gyy{6XeQ-6ٕ|᨜阴E bOeu:@&RA?Y`d9XO<$ IQ1ຊnof`t|ak2ǾT܋ov뼜^Vk:u,ܛs{yg&}okn͛eUiqYOx~[۷ !dYXOI E߈u.wH3|r^٨W)Gxw ^$B_,g ?.eb~Ѽ=螆stf]#t+L” n~xNn(滑$'}4.GՔ]|:$g0D=q?X d0%XKY2 $e}7zk'g|fx5zkY #z-ޯd=yB?Nf_6c?DLW[潼>s 9kA|`&32sd8Hmo;jē1_,{):]ˎNWiFv9U+K2`V W?~` wpjV֏8BԃC;@\ʷt'8 h>- v>]zg{ePYJ6,"H(㱖eJ%H[|kD@m:OmX^,Jo&fsBV%Ućo? (8UJKp#{1Cy zL ;rWw8hRx$(K}F|X@җL! 1͈_cTPTq e4a$o379EBGF0qg0f2 GyK[^f;|l&ax€0,H(f*Ǒ0ܦpj>5afѷ2/2MPX+=hf^`ѽ &yH~ =P<h^뷝WAZ n:G~}.Wngj:[nSs|;O6s4G?˱? EnL ȷ(2*b#Sa0šx mU7QD Xlq6|\8G^RNQ˰ۑ6vo\AP[z.a˨BY,wLxÃR5ȷgSW|9V8IޔgRc"}VPTL1c@Ғ$]h(2Ę21$W^J+\*W?ioRe} ƓK*ك _hͲb? ˑ@а1B/JL4K=n<3MJ6}p/y|~جp+wԂlx+t^ˎ+v^HrWBO hEuAc;0M}b3Hx,o=}`GVhg`(Jq^\!\qCV@+KN?D Xs:㲞ptwYb{!_ Uw_rpUp0CG+#_Իm#D8Txh,ldGv*f(}HifuR|֖=p9 '?lQp&v}5W=zݲg5Sbxw$//<@|W^} ζ/{}f<$t'A@cN<;Qdk tHrxd`( ׈t Qɢ%Mg6bځާjEN㼅2 ^dZ[|H#TgAs;ӣ@݉>ޥyq;h 2,nt5G!3&ωpuz}; ϛwb${8:SVn!MQ |~a76 BA~!D]aР3`+}JWq{u{wA9eu}{/_DTY; #E9E*42B*8-ax"#w…#x])W"bQ| v*# 3SpY7*Wk@!w0Zao`!hLߵcqAP>JK<J(8i>`ăpak.xU[rSⅸQK|9/_.=@zJrF;@9(5{4tiҺE#O$3,D/&BR/m![H_qʔ  Ke#Xv&ӰJSKH1f2U idvQҦ ?p3A 韷ϐ0|:"|oQ6,[pDF0H Fjݶk9ǵY3Q- ajtS?.Rͫd;d'~mgӰ<5?WQ~~m֟iDf0ک;|k60,=$t݄l ß.7~g ?_D J]hF1!&25q3"E=Œ4;Y2SGLbja'5̹na$w_g2a|E_PBZD6m~0h9Of;Aݮlma`(۪<*QɋE p.|U]gYV?V2[ [(LڹʎZ9D3H:wЯ~f ЗrS!!5ŋo oE=QLLR02C@; A[QsaQh:Ltl"ymk^ޜA0(E=\ )LHԇrQKkADI:~k68 C%n5(sU3ђ"n'wظ^8OcWpG]UpIg6 ͋/ l&! QW1 AUx+>m{o|W 6i-m ;wT E?lHA B IZ!tU3 -0LKv*^H fP>M$$P6ɿm2+PhqIdB7;~hI'$}NgNa$/!; ̒PȓU4_5S3S YlǍG zhߍ/vs? e1[)I[ޔ4r'3U–Kmhu`5?,A-uRm-C84\+N&Zˍ-X%yXیsXO`zKs奖roǝ_Ǡc9H 3;g<0u_goj-[ JrDii P*݌hI a$:! A$ke+NQL6)HQH.ҵ}oy]lj!ϖfomQ&sz~ɵCȲ? cH~$b̙ɳW pӹNFW0Vg)ZHw?"q'܅0(87>W}v{t*~gM6'Зh:-ah\!SQ5D$i@M_[C pL2r"!(TNGʩHBxA#ybv0"x $^5p:eS\6ptӜaċp?"!0Ye,b?Z^oA*F+IX"Ĭ2VZqmo='nn*hJ|XHIP>YΞ6{gw{II^Vzdx~1_0\UNpWm?dXq5/bզQ=_7޹Ąfw7ZSo_ۓAw`W@/%Tዐ H  I'KL28b'E+$E7P̲~&*y{If  wD_ D"H$ZKT22tv9;$^ f*917椣pE $^3Hbz8􄻜tV zEtK@w%D=1 _ j|)& = a}..@hEh5'뤄b*w7#v2^Z(+V!109(%91کL5t kqNxRg|MHB9|b&@SW75/h'@ȧ%[36| 8 Ҍ}N.QpΙfM!g N _(\՜u=h'|n{aplKFALK [45 =\нl TjrN*dVBQа`HZEI^JtAp{7+oO,?J,!m3EyVjHRG>*vC: ZI~B v~n'4 "LFWo]?ÿ6j|yrID_hyOn'oBg1c^JE/ t7w>.t>?nXp*Hyb ZX7$a>ɀ {5n$ʲ_%J#p8wVfځSz> Cd}-n0ه_A7 Ep56Sez ']MX2izauP?2[ZFCJ07s_Ctm2m\U]V.}_~htՖfJ%%TNƥ- $ (vJ&_#}HhBJ|#0J,;_D>i&,'ȏ >-}M_)U0' K@m4v_q,CK62 .;q2Wp'<8oa+rcp=7}ʵ-"_F x`1E5VzT×BCc]˼GswE[\S)}y-F|B߻A;dJ&T[<_4Rk<|4z 4n:kvo\=gmygb'c*2fiUD;d`}(N?u`wR a*:`͆Kș y!bi,5cO~`DP/r(P7-PsoRfZ; ~r)r W=qC_8>>\{;8kϋeV:d9C ~ֿXQa]?Z e|ݰ8}WozǼ~rt N->u&oE 3IEdkA[Ct*N(b *ʟn10?='e,NЂ*SC>9CéWg&rR?/փ0bN{'_B~۰nr}7-=2c8 _Z'kOvpQ8,M/!җC1?öEm~󗞛q,AZjKZꕒ B ctDHM㊇94|CL%W8ҭds+& V0|tɶ$?Y r2RRq^OZK}(GO7Wٶ"6?hXw24uѾǚ9COjjJyNz 6\^zO#{6r;9(SX6ln԰;qY©\]?C*wX qL.2e,+<!!5@w`ـO):zu" mz'9bxG2ض㒭XQXmqiζʹfKez(9+qLqW@Ϣ-)`.xMyy6wtW6;];J\  ρK5dÒ:39Ŕp1QKzqD$hkZ#JaU44FQh<XUZ O`I)¶*fRrF~wD|!a?3_vr>}L;&<.8Dd$ h?}}h[k;79pCI^p=:&.F|_QXfwcsKuC:x~+E+P .[pSNǂ♚-НGE=DfBL EN{V p+$m?$4[T5>-_lRJC$h2(H9dxл!YUr[(hya -ښ z):¢!+)Z@HBD%&Ub(Ixj[oU;,c#@p`&*W(jS$&X5Qb3Zea{>=1ꭕ'cɃ:Iѓ]Vb.֮Wf9Ͻ7c=.dÒ*tl%PQtr*4#VV,}4VkcрtՆa4E-M`ʆ5;-V"5/KEZq}>CtO@8r(Ou f?LSW!쟵~RGI^ɩIrMUsaO|nSi/o]1~Yess4`4? ySSٹcf~1u8xdU=}v#a+nxw3$P п6jO *oRhA+q%r]7#Rd[ 7;.2떵;/i` [ >S_SGW 5~8Z# Lw@, _h5qf˵C}3U_*W6Ap/xA+Z3 |І:wE O{EyMq[_2TqEϡu[9/wnƥI0}2CA[ rZ^D۾vhlqi`ZdFJer=QG[胠ST}AdW٬|~khcES xj׃zH.m}Y'y0-< URBg}K E7 q< >~گ "r- )\=UE=dPDh;d@ľ_,L,iy98"[]BY/!*n_?kteSԝ-y-/?hS5%y;?^Lq~n~q7aG+#J_ϰKhfvgnZaxAT++$ ڪz@J6k끯o|GDq:' I> /+vNCe?~0*[법%Z3r䖑sug͝WΑM/Ʃ04W?@h+{Fk$x+sJ^29)qvp_DuNu9"nr"n̪K޷::U }WnAϜ@җ vB'._ARU&*S|+Eփn꡸=<Tm ڼ&tPsR̈́+Jq!@DN &wXܔx|B nfZn=(JeS::6j~Ocī+rn2)*@N?z*!&ZNB}hn8ai?Zu_ _ uXy,ה9phCM 5I}t"`J6,j!tDTBܪRwĔfDɀ &]U:G'z4SɩoA[s'ykA[s諠oчA{tB5kR鱄ZK}(*TQSyCufDIDOI7ALYT~~n/ [_*ZC4{+tmGJ;A|o,{m$u4b&6t.ramB~MUjnR^)!,j;T$ifDhV(qJYΆ=?$ S0\?>ʂ B OP W ܅T3Ta)ٰ L (+0-DhA]t+4&Ѐ] ;?rAxp.\奻BC9+IW_"f+^3$hZjaF3sZ2~a7:<lsv3x~-n޽t_9WNpO25*}CDU܈8_}CGa;=k:'HWt´A@o0}) L^d0sq\'%$ȠJq; EafvNED_|dy=0'ߵ2XVMaI(U^?|B9^~^廙fʳ~Po@H.TN?*M95Ng8 Y4x?| 8nSSz^_ih#8'Pԟ(LQQE{NbgFK+6r1gZ WIH4~HhexXjTn~1/B)QJ`uQ4ǃh)R1R*zF_CK,YdVVIq_^xuSOן5!OSRA<͔3| jv/'6fQ%0e% XUm gWgz8w+6o˿rP(Lq%loKiq)|n; zs{n2v|'HQ; _]^ n\A@=F Jb/G(ZA Bҝ&V|Ϣ29[A"T/wb:>6uBg2 0Հ2M_ \_T;y/bִo(IW zG"ܹDLn/[ _XmGO>q3;g<z컡]ZbmЭx:4Z߻A, TOd: ҃O (Tg5q4STVJTty{rl]͏٧gMP: ~"۽ 4=ʿ:XPw~OPg?ޜ=K[%$9DQ #nq<ע68fk}bIpg6џ{yI|Qo.&=Bu极.gx T,LJ~cRet rBm8!̓%,џnQ"%{^JY^/c{g7CPfX ATA$&PIhkV h>,wY$T͘G o⸵}Z=RӟC*c/?/DeQZpUF$h̩0rc"NgkY>0 UVN$rNbR*K.bK*(D!}΅qo) 5}Q{ѥ{] +(Bv(T"K]>${ͮj!1_ BҡU^,=cztG p[%qLώ嫚iX,% bUʪ:u>G{D$uf$BeJI;lb mwlx'9O_KTtIHv٬PPMJpk);0*#vAPgaP\@]h ztI\İc]yP'pn󴰓X$SX-Os)$4ѓb-^'lv{{S ?O^??ʀyNɠ=IW/@kȌ_'gIώK,= G#(d+!!Z_A}`D󜋜 :ɏHn0DẙlNaiA3YKs K9Tr.)GPmn' !Q_:-*(_"nk\֤Bq5M8Nk/v0gK\ 4X𽐛B(rY['vgWN32]~k$/xt;J!ր9Gztu5wtwMb#|1&'/RE&ːiȽh q7b1 cӠ:Ľ-f{ "le])2>AOKƂjomqʀ*{>׮ATmώm4^cp1Y̙sW ?o36c4.PʋJX4GbZ2˛kq,$tq$`HkWx: Ӷ6XS=xaGos%Hn& (&z60$(&O3 'd.F6W2z!=Jxb<)1Dز{I|PBszp>(_aKB3hT.YD!p#F,q:Gwr"`y /9ӠNdrl앺}.=OqfhT4{3Le@sÒ7OlxK<["h@ i{Sݺ_0An4PhrnxCT!AD \adK8y\]/(_ W3?9f#DJȏWC\(vp8xWb%< Y>A{? oޠV7Z]%T9oxn~ݱ[S.6,4ZZoW%={C"n4)6byT6^\1SfS8[{H[<ߐ'H(ec#c׹:j{PE8TM>"OxoU¼][v6M3$i:jy'x-ײRlpBJ}o%J'<+5`*!e6ߔKYI~_z4]~|1h HV.lǖ@7mr~t.}ڥ)+_z˂!j`ҭn Sꋱ5;E/-`q #>_fX ߣ>=AdMM 5W ^ ѥGgTm@=D\S)MLG<uIF˺?^ f_ydO f™zNU!(qY~{ >{=WwAonqΧ-. V}9Ht1L$?QjZ;?XJG)r#՜'}plS -=l3ǂj_aTsV峥_Vg9%݌|=\Cejo3v>prSMQ8퟿i!OeWW8*8,Sm@5*sR?5]g4$~u -.A֧n'@jzv,_gL#"Qť Cl(A۴Ѻc-f(d~X-e2Sv]⹆B;qPqb!$b]T/fI,ɠ*ΔrAɞK 5`3y!}l WtU{Dm,% ΔVdgtD:l1\9-w0m:w$ -&0a豴O}=< .@52@狀<'$}lK5j[[EzTN(n /ϹscAkJE >QW}XmcD `j֌g,ND0b!"Y ]cyO;K(V=$9zv3^GʌBn^dmrwEJ3 ܟ)~\ iB>뾙R_4w4beg,qQ8 ڪZCN\ ?s{ sMpZ #s-mNX:yŢ`eu4>_wԤ)Cu1pdp #1TK)Tb=1ajuOdTS92QJ MB5'!Up6єSvk@c#׀0(h5W!|ϯW'I\Eug&os<.7eX;Jx݂Ezhb'1}ow|c>$v`PЗnc Dȥ#F<3hy*X_ܱP;[B3.biޥ I RE &SK3\Jc6ca[L-C.!ӌxpfgקXf6궻cy6w,d=PU7b/XĂFR(uQc1&2h4c &b,cpYaL7= MR`ĥPbickwx)'ʿ>wYvZ-xrt {m9 mKE-rљl!y/*5e7hWČ唲`gf+tgC;X|Ŀ[ܑ+NKw#RBC98!aB4@Kt'uE2Cnǖ:ÐŮL%dhߔG̹I y5WO\=bE%v.r}ڠ07~k6ӎ|94!۹RC8꿅豻[Oj!h%Z:w7; S+ٞ!GG'W?ae >L/ $@x}C̐۞y*Y3@(QOGۖ˷8H P:.G 3[͑ 7&tΐ<$;jznُR,ph~vG"n*~ ,T_/__q)A=܍E/4nyREvVlϬv}_xhv3C)fk$TC~s+!fUTBt}w;!=T/Y~*8堉)S+?}ۜjffI ^sZYSQDh-y5w 0I'{\ϑ8&B)g?x qu6st%^I['͛!tJ9-]t5' M}.}7vׯf)_v-`#mKS15;#LJ/>YZ,B!>)D&F 3 LLoPQ.RJ "2JqryEvvk #I*}LKmuAw״ڷW:mzv,_%AwD$XR!P)A3 bPRP"8yRXNe$:gU0S)PH+-)lzb6hmkc?됄 M+1H(ٹNԇeST'wT3!`PE;J[ ܶ *gjdL%O}V+p$,v g&$L=hi_cCH6ϻP eT]O/]+&?FI]uf;/_״d$SgbNrHDnDl(tQS00J g~=cFf-fWv$=SFgSrT|q UedRMkrߐ^AY՚AL5ydz]-pGͼs 4gf#Ov{r]=-!p >-~ok Cf@⩐≛AW/OW7o<0~߱mKҳCQBM$ڤL}0i5Eap59lBr̯3vW؞IX:fMq,3گ!DA}sBFoeFJ6vۭ%κxlPr~r^z؋Yݾ}qh@U`d>K-cf2.b-qVL 9"$TV-bk@pƬA?½C+WnWD%HUJr tr]2Ȇ0 Z]e(`~=WbVcK?JxUoP)JtMB=䃘һ!rw=nj J@>E WR(ە(ޞv쎟aT=?cvz]],[㦥S23 LnC 6 Wjl'M: ^V]1, ڧ*_]՚E@zy?[!=`(/YoϢ]꯴K݈enOS3GkJ-.W6JR³5cSJ^-6B}dKR?d!*9BLM0Wki^9>|08v~)migf h&e\`5\o,pW/sh/Hveۨ}IP~0twj 1 c至\;<.(+, ![Hݣ涽~ĬQPM o̓!*nre_ )W񑾷,ԠTT^M^578tvH \툩՞-ԠY: :2!+pgϯpfIu ? ZQ%1G̡Y!Ro_-mp(4g4C3f (uՕgUN: hzbr/d(ھ՞;-4Ә&,9˜b8 ͯ F[Sl"Ev= x  y~:~IP]N^/Pj{;ZcLs3?ܘ>6)Kq%#38Ýqh7G+] q^7@۽QϿ]v4w⦅_6P}赠v.H@7!&;tھRi#3(w89R4q :(5(XXo<,v5ȎmC é@;?QJ;~1lbSg_.-(dߥrqP2(v " Wg>nU3oc!0Jpߕ g*UKބijsƑY=*/&x˱F;VnQ_pR?m!|^?;;41)!h|w{4H:c_쨞יM(8D- ђH$PI^Ԥc:GQ{tSɋmRӗuB:[ HHysezMKЋiժ$'FہrYᆋK/gDR|:Är-4nqjӱ^p W쿅}b֎:;{`, ]!iƵ-ݹFsK N쓷xZo48n5 ;jO$b1F۷5OH DIA90=aq=p=<a14)j[@*\r5B0RUpua`z <2P_ˤ qX~9(_|ueTLK s6p7#t,9$ N5dw'<-dܬ2ɶcF2 r;^aN !U77澸OlӅJV na uL(Vҿ{lY@bZyo^>O94/dR,r6l:7)EMXhIе=ҌYZ([N~NMI3R^ AMi*ڦ2܌EHK0UIPD2+L8s!ʓJl}| ϼ-I3R2 "Me*zcWMf. Y$c>]@{'d|àc@wӈ*A7B-ŘcUi&B11T, z{ВFyocOKR6+it%3:(*)}R h%(Ih*?Kv-Ns{9:ڣK+_~wV'}>M@/uݺQaw,ﳥKd~Qa=CAv@_zMtsI!nEh);> 38ݢDˎ[S]+MǓk\RƲ5<}΅(VL^kG!rI5-)g$mx*{h/-RpR.Oo{؊A E!灶G awOA Nr%qB-)c;: MtÌ34]~!Qԗ>I ((H5ZlWV֞!Pzp! Uan2=lKYi!B$Z Q( 'KHJcoM!]Khal&]@RB߃r[BԚ{ ?Lf/5xZEKܦ~ >.k0yP9v19arp8c1ޢ=^!p[8J!@AMN 9}? m=vͧ5MUi?6R?'Ro &Qlbf :QB)S/pt $Wzcb◬=$01Ԗ`MfL돾Ls1.=} ٧Ydυ <*S=c #Q0n;Vͨѫ{d|LՓI״(O4 1˺bo[{j$uu4(>s>g];nR<ˢNKA7헢5*'?_يI=ZZKė>4hAF׊EFfyLPbK x~?5+KzHĿcl cg[qPUP-BP Cdk?(?W0C8N433wS8_4\Y0_oL(xjϾS \e/!/ QPF{yv:F!Y+Ae+ ,[~:wWIz znN!|I[.9} 4b6g4>*mGZ{L2Fb\hI[4``c.\Nrq`<A$J@+<F , nQp\m0"ɏџA8򯵇]xl4hܤA!b9&DѾb-38HDVR)@yN3 zlzv,"I.ilv^t+"Hhf  2 :JWv +œ8.KJlZh)̙ʙ"qϟn~d2'+dOy !R[HUBqqS " !GsoANԠ[U8`+tᒼ0Ӽ|U-p u+,~EE)Gebb"R$27ut$vXzg`35LL L)0XW$[e)sB_?Pmn{K>CLLU +M@5C?A=21evED]@lxuS8K9N,U'_*g }_Zx%=FM?W gU|2$蕽c|U2Ary]m 5g~]'G< FKm;:m;D#P1pBPzW9nmZFOqod Ҭ.MVD焩Rq^]XǃrʙQ3"lA&ykg!p2Ǻ\w6Y])_cҩq|4Gg9,fMfMI.?t\k(hgMѢPuopwwa94!Zb%YoW% M݈rSBܖl~=Ofa%fֶ=C80d Af~nxCR BǻM?m&vi |kc!zg'Gн/nUymh_@LBw/11a ,J}~;9}pD3\-u3wYr)\OԞ>h/D)v>2pݔ]hәAںs&ܾ?-m1۾vKD3'Bw;B@3+5IAE6[౜30hTq&A 0Э8;`9'QKUq[+B ^f<(wV;,ڬDP&U4 *__ἮMg0?]7z# pNy∷0#3GO;Tq*9J[^b or{THK]MMm>]lp b1#ԩ|孾jڹ" E+]e#=;AEHDNfMRhWx(Җ5 L%Nz$WgǃR- 0[ Vfz JXԞ"fMkf8Dgi߃8+M Q̿5Ƒ-Tp|';CpUf֤w0b8S([J*BTbV. 'Eݦ)67g*vqz~n(&+Kێ ``DDN\>L69&!͙^1=|F@Kǐv--.R)¢h.N v2qQ7nom7Ĭ4/1FP&FeQ 26@Yj۱ãoGtUv4KjD7Ga搖͋9)v5\/gD__í]O9Lm%j/-9bF{:'Ó<B\b{| IA7vOָ:+У w.cD}XoB%*B4eEJLHclLI|d'N$[ xF1 goX`R$f#hb2 6ptS$ HLF`h6m`$L@J,ȣ0Y:qL)O -'2Hc D5i) ݈-/;C*դ \I!.MĤ,,9Kmk#ssaNp;ĕp#v I~{*& vuoas.>~Ɵv>-qba}HV+AaFPBnԥYd誏޽ƋXJmFO[v+d즽 $nD5tBRzvs*R캚,#܊ŠC>s,KEx-!^|b"ںgG⇓ ] ̋?zTv~VeL*'讈nXf.?.o7|[͋f<Ҹñ.Rq^!)ki8Q&܂/_8$ Hn]]]lÆ/F :uwc#A;r㗕94&SO[Qt$BR(ŗXl mcxyI-)zPMt5hb{B:#>|T(ĄJN&| ci<94p%ϓ2K*x6l ἴg6;EXO)ڇ} X3A)5r'qZK% :BcçVJY:qՌU3!~D^7|xVð3h0^cNjKj~jc1Z 9 >tA d imKBqXؖ']rrL50 gI73CeX=<_ @|h!dh]6+i[ TLp (Q_:9] oSjGpCSL;C/.)XEۋCLDdyu/tz?=?_tK3uhf )SYo&L =NNM ATf?| n#=h'l@u4P _! ,@4rj-l48FuhaUa!Mc7>a>ղr'T E$u`oS쿅}bQ;.ވPBG짦@MXʥt/n: HD1qԱ޾-!EW^`$9i D5Am]v)RRى/qaX. *گP-;Dz47Kjs;<8 4xd<6=ʊ|^*xށrdxj[}kl*D̄(}Y.)3#.xcC܏0X;ܘpd: ! Nh+qQw6 '3|IT#wCLE:}y4?G'BoO{HNhA0 j fwvmCecAN&akfaeEAD i쩠ł励Z r6"Бr @ŧgX-DG9!)MYWҲr`i1e>on:Fh>?! JUۊBDZML&5#Tp. k> .4qApYԹdGŅ`NcT ??'!)YW2 rXBGEe燁ۖOKo)m3I(*g PBڍhnbĴyj|)͓5=\mj^E)<HƇm9C8΃~^*{ҋտ+Ffia xDcɓ;_-| {='{z Q1Y0U>W1 =pyƾ?`I-w6|ܐh{k;ȉ "[(յD,kuLzO Z\?+$f:bJN]i/K\l}z{O*$U۝;&Kώ rJԞ('+B@EڥmWE m8< h~D*0,XτԿu;FQd?&$sB"0 aAӊUIۤT ĪqɄ?w1jڈ[nüa~;] A&3~_ /E|+zMCl_-~4| ^7'_!}tB_wcA|qBҮ܌EmF(v\"p0O1g,ji¶eItb;Sۢr3f. gХW㌆ksvf,OGw; eg{=ȣf,p0 f,aeKvr}-g. bغKfA›΋ML9HDXTKgVjUvݱ|C.9018(lNJ:!]i]J2jvO(JX9Rߛ_\`Nf$r.K{F^߁| I+!@v7"a+?DL{W}vuu$Ϫw!ް5A}t&]3OpaKĴx8;L] JF?;_KU\[x/nK Q ^V/`|_cŠ9{2.ï#Aӷ/3ETj%L9"%MLsSOw#">_L=K_gK3 ۢ;QEU©^X#;%$mB=RNz"Jn *PUb]8Df^lb]w姱ﷹaTBpoT9?h0J:y^XgQoKE&<o;3h[cƋ`Ж3ϙfcNCSm7A㐈[FvI6FPكu 1e2fI"qϧ3HL!IqcL/Pqtf(){MN,1Ci8c}ͥQ_Ĕ%^ e>jd"#4 @c#~-W.OU,4gb<ʽ~LFUq6'簲2 [=pQzIm%S>!TƯ8g]!}.Ijn'2{|GHz#Zv:nzT1=p,J?0MvE.~c3p2qҐu~0{otÞK.X{n ??!djKЎFGS M1O}3T:/f_wsDcH|&G/8HjF$•Q"\Q1 8cB.k~-ͯHٱ0}gދOw%hRT^If$ήP,׬˧!-f= Tgw+kƂ  01 G_tR=+g?'ʆlsvd 0$q{3r4c#'$ps{8ڋGijSp&MY]?oWP.4x4裞?:KR4~Wz~Ze/:2mODv6̓n_vqUɲG+_ldD] S}υe[Vc^x|~ͶL¯Z>Q~ ^%~<[r2:l2>\KTMuS;oSͿM8{NY:w=/Sµ$+O4Hn'}c[h7[\yO?h`Жymg>&]XPEXgdOro~yMwyēe]PUe 睷φà<-dNX^9/ƛ,XIJoF.-GW"OٺΑ.-ݪqV)K'?^g+f=RWB_ ͪ]6 vM !<te[MwׯIs 9@_ۛ됤"&8# 6v05ͯNl&P@ao;8cFs*6B#Gp"B N36Y{6PMZ=Ƚ6z"O.)Fp@ezr`EN#?Zk`\TjHS6 N4u|^kIp*difg3ևQyޝQ] i#b}l9tϾ(^Hzv_v@K\3خ,fD`C'#Z!TT00zlOC3ؙ_/U>gccf G*#w1V7'$ZjB׏ټ)HU3_7۟kUY\Dռ1d9U?t#9 S㦸ϧ.~%?VgZpKNoηr%qSsB!C {H쥟hW82կ0׌rݎcMxڊe_wh*/>BZۋbO}RT#9ҭ4է8IG,硱ddͦld(p\*/&xwy/ U~<8N8~5B{]N ?jn4(zOR=ɬqT1^VﺥGbFyή֜lT5)Mjq́?y`xߤō; w l PN^(ճ1x{O#sٞȱ%#7ٮ.b-v;N\WjKΜ9ׯ|4X4l(7;Kht_X|T"2 L '_ҲD$I΃2e`VdmGEͯ Lv%s|De!$"1.E-fLDWOާGނ!|~ K:98SR᛫zۤkBxZƸ<_\ 8U~bn)D`[9 GTb\ K Lܒ dIU7)<hT~a^7\öE@M}ۇYzʂSgU20-+i;Q;ur L[H!nR9I8KÍ*dVc΂Fnil$ud RUtMKQ^6om<.חS2AYwR"!-k&o4fȴ\^H}ϳAyY7=}a{$q)#6>8_ ~3hdLZSaiCroJЮYTXOB F_RD;bXvsyD\C'xUͯˏŠ__ۥD)fAB%n¬e Kh-%mEgYWMLa'F] p:w_D)"|A_愨9 [bRvOD$%׬* tZ+5t}3ws­@7HceRP%4]2XlJ)w#RZ6eePH(ӽLR4\< )RII>0wPmn2WjN+2A@fJ/eM (/2.o/hc3 i_ٓj8?ɷ\2J7p _ ;8oI6?3]+.w1p# /Я~p[&֪E"$@rA۵pb )P,T{q.9W_Tm&f+_ϩ`ykEFbS<y4a 7_ ;v[G gws]ֱJuwoy:É/ –xy OTjr48Q8ӭSq˓iEv8R]bND{%f'ڔ'XSmn%Ad7߇GCcW_,XQ#P *]@XMI NS C`rn*d Ca\Tz48Zy4/ίe l; !xϙLL6+kPU >nΝ=_Px_֦C G+WtbqpX?Jgȳ3/?|ڤYԠwnNM@պg3ŖPE]M?2[Kze믅Z^XJ4pJVXA$BۨT qJۍ.LxH.ʈO^5A3򲡇AaH neLJg94?Ts21IRI5 _:0jݴT G!REۗubNQ%xw#J9$1)\LIƳ|8{7; VUsSGauxN&.BixCD\Rʌ7y`m;vnt`xn%9zͫfo\aх珶Dp=sJ3 Zz2kZ.RsFHaX\qk y玌]Ws " "<=;{ALxw3Yo_vAGKKw#^* T眊=H:Ҥ'*ز$=bD2{no4NVeD@ss2L(3~/)jE˧%c!!cA/VWPW>,[#e1j2@H8Eř׭ u_! Y s؞i DTps+>M*}Z킸u2>XpP7)t2IZnٱ|ib*a}r "$h 8bH=]pb"ي aKD :K;XgIUP4 9=kWK\,ɢ>DžATmώ!;i&]5w,1̰Dʽ xk yA4q-}3l:% 鐽LaQͧ MV[k&>ɉ/Ft@wֱsfc-a~=Ӄ0W>M{Ѷv ā؛_/iW2V ,0̴+#b"& ve흕Nٵ>^O@uC{$-p=YŤkBTFr3Pu,iYBL*tgioI&״$>b-@Sj]_SnUWJ7 v~R1^BG F$祢aK_g/U .ۭEp b1]@|^vk?(i AsO!HbÎ[B@pCy@SoZ>Pc+A3#ҳC:t"9 1CTNcni BKLND"nItCc.?~aޓ%șl%"iu!UҢᝰ!@Hɉ:O-7X%A]g.C5Ĕ66pt/ ۃƑ-Tp痩 $_rtb9GR_Xl=T)ږ ɿXǐLu@8fzŲ}K׮#GE)'4҆(߽h]Qj1 FUQXm*JVi"RAf?SmRDFL1x T*89Ҥ RE$E=Jh;r3>o?u=! ӼQɁϊRhO'y>*ԧ8y]_Ji:`ǠoQ+dhl}?{~jv3AYJO{V@o=sXz#B_/HC翄x;*dg(?ǒ"A9A nP>okc!I?|yLNw%Y~u.N/' |DJDF~+r5㼭jmBm!f]5ekAG*@'_PQgҳC*gt6#8HA}L%i;59T1CK# r"r ˙Iq`̔0uǑ1ft}v* /@|Q <*S=cL*4lXUtLW XVϘ+Zۜixɡ}1K Sw(v6sčI$~H>w֠2Asu#_ y 'INӳcԮܒEVmmR}%!A1 ZSS4 uQ풰r̯W88̉>= 1bU1F4_3@<wt o7tMN嗥|.$>8٫f>p5 U93q8i/$;yucGG{^ Qޠmxϥ?u4~!v҃m2Tr@=&4^)Ps*,VU>lAO9} ˙ǬՍXPɉjmJnZoB&1b c NSV+GNMj>Ӑf%ͲZ[(3noiasAe.F; N1)MD=W.vh[+ڻܭ\1js{@k̊A=sgu3B~Џ`i}9X*jN9Ir, \YDʚÝ ;ٛKوM6Sgh[o@lW_M S'xN_d^y%>əObFd >"^d%+ zw5D=kuO;tUX”L7L, qٕWq}㥃A߸ f@&*?a4v`nE;=A]Zԉ_Q+rWn#Ab#3z ɡ ET kkwƯmwW$;/E۠LTRH--ݍHGDRSc< c]כ? `h[f%b,oy0ũ9MAqtKAK:ӇI5L?5D/ay-R' )D؎oh~`Wvi0}Kvct0ȼ_ ;uuf(0>H=ͷ6HIs@u[OM\wjguiRpTNi%nRJb{S'nGD%VQ[j%y$$>-B$PveУ(P2:ťcѻM:qp'b^NN_zubOeWW0q{( Ouy0OLW|h}G=tѹ ~˜9!&'9r RCf!+?)ݍ(f .tCrSM a(g~=`a3Q8,q.aj~)6Pmnzаx6pHPޫۥ@{\U.(*PU-'DIl&L};-|> K֬A'5> 8(gBpafގpBSQ4Jc48ePoNqN"HYf}bXvtG:^xtc?\34M8_w_>)R)]d6cG(h=9Za^7tI"L52G=t2(I5DI/2WXb-O;TflE2}&XSt5 rYEи)IEIG}['v~N{oj&/x??0 h Fet t 2Ezv,_qK!|"ĥ@ O7~qS; J۩t5oT-JmT`#_J6qKKzpL0fFõ9KRm+Eo20Mv>DR{;(}o1'gNR?'ݐ{<%֙}n e97./hl24/7 h6~9*6藘iAiCib0',bmJK i u%j•̯y?o =T#῕>]tvmP& T{oPF \Pnms! t11Uve(xs1Ygtɹb5qڠ SЇdHvM^w7еz+}ڠT]ORlvDz!z#9 P;_&#IE*vSe/i~(ҝȏۮE%0+?MQo%J67=pO1d@.Qc׹ JÇ52Bdb&L=0;v[u_gE.mgH0\`K9/qili\JvxN'A UB*xVs  ]di NOm&,rC@5vheZGg_?`G:/*ҋН؁$ҋh[ΊH"lYh[2IiY=5(>AJrzHH}}zGIiS5_V Dz"M9${}1i`Vy:gڻސtc=e3W7AW3xt [-4ӳc*Rt-h;STX@ss۷A4-DGp2˜U*ƒY"evbUjux(@6TiJ] X*eХWcI^ T( 5yP篞~lU0rg{=6^Y Nf ;mϼS Lm yvdMB dU*rXVK>&vR xipֺ@_y}˂.6&ׅw\kݱ|yA1T@uڧ'9"1C*BMHws .c$163)f~D2*5Ej٬R"FAWkٴbՁ~)D菣Y\uZ: dWCWK,/!!MHD)-c\II`Wa\re1EWv|-cS~)ZVG_V9eP tOw~ :*=;IBr45%<I֤trZ6@?dM6،^2IACc,n qBh>AxŒ`b*Igp6P> Ɖpg#:x'qC F4?oooq.=OH,$-x7Na]h 1 WW~ zn7X #]gI11(À_#q@ҷi۳KRP䘈8{`̯TɜRE.Kķw TC~&qӅmYfx_W/"8QeP_Sn瑆sQ.g o}0l }rnC(2<ſHD8l7cJw@2,бN _AıɀhNpW5Pqfco8ᩄ'd v@š}qBSWI=Vg@Ϻ_q:CC j: oۗ]zP?Hw#E$7/jc4(_;TaH3aϰwH ^+.MV|0gzF%^6sezMK<׹iժ@/yĥ\BJu@m]!ﷱCڸLT ˿/0NTJ- x,`G. =F}\$OX $M:<4Nv*4#Jzm]IM@b .1(I'])EixL%G\bt̏!LL_~TN*5xLv5#Sп*_^,(P΍6^5 bkb~E,+ZI̽vn%u>GV}n޳Sq5'VηY=$<˗Ld}ɮ>Q>+q+$Ս?wqr m݉o?cKP0v_]!{TjjOTtbi>O&G$%Oy "Ed gDw+(RĖd]b7ϐ@N~N(3~j$`i`6X9b`2dAPu`P'V—0,n%ZkgW=x"\hX 6itБF]p34lEznvcnHR4K_@'AJu-JkNȵ;@"&ǷgUe_JHJm;!})# )ufy Uz< ꛜ㰴`r ( /Z؎E> Ϭ;>}@ҮG+s+H;g^⮃J[B RB59˺+ ?޻eA]o.l c?LPIKos_L-Lؾ--ڍ ϥR4pUfPtQDhKÝ;hAqR߾܋KbZ K JSx6ca4.T|BbXFR(w ۗ|.87lqĸŧ /qKc𷗄ļ4Y쿅}Fu߱b!r]ǺKc7< ٿ@E@>W5Ӑڡ&1%pخ쒅)N`%LEh29XRW/t ֪ƒ}Δeԕzv=HmkpQ%QX 읝D}Ռ+U֎ J Ᏽ7trB0Nvc\pNt>Eq[Lw!9Fyµwgm.BBy!v ᗄ7۝<h;h濴@?)zj ԧ不!y ًb{|H0͙n%><\_I0}چZtP,6A|fqb-4u!)ui9K>CLD=!Z{rϠ ʞ5R{Cr92Υpv W/XG{8?rYɑH }y3PLlx[R3Bbk)bxG=oMb ËǫsNg;iȭ3P~z$@MVOw_u N+YT,1I;^)Vn[PTѶ Qs k(4.hGpIU snxt?`{Gv `<' [4Xc$VKE 4!E#ARӟCJYi/d;է(V{T0P3UKS}? W;! XڃN<4MDMNz. \.D&}ۃv&]KTc熄׎t\b.g"!\lq CK&S|&h "K iu%E:%MM~ !W E4.Ej[_w4~m V$Ggw#k? 1 y] f~f)39 HK;F H3bO t{n{G_Z"iC뱤HPNvm@U4!#Yق:HԀ4",gO8X/5s$mkh"&_,4"-^'lv1{W'3 \_)7Pj~nt/-gu'[Q;[a]n}pH0Fxn{bɲѬYUY{ T嘽 SK(Rcnu=4V`F TO%1"-mbv[Ӝ|nbpoZXH6w+DX'T8ܵHtnH\ꘀa?^z.Zi_n/J9nDbNtڮ:S;*5HMf.[`tp6^QV\'~F3MQ7_@i@qfäA32ϱ|3 qEMN=K݈4*v4L)T/:4-g~D&=q=ઐMH`PH%X*C3j:JIoєCBg}s; ;<"1+'?Cه2#u;ĝWJ݂W9 $NHJ]o?Lc>0~=Ι!CQt4h| |b`J2SiXFK\1Gi%KSiRii1]b`PVqP ##dfPԾ#qে%1 d\1 M)@1 ~/105#=;2Xj #%[ziޅtvyhnww#Nw&ɱLVθ2E}*ƃ-aɄgLϭC~:nu~?%xy'g>}S3DO1l{PQwAZC/ ~,a%!JJw8qÙEKMA Xpg]7ss"+>c%V>n||c8Hϵ?2M|Xo (Q:3A䠈IJJۻ$9b}.Hrp(;5K*R1u.;2$ 3#L91ƭ|pPY\Ѻ " -hlx_bI%&)~ϩeE!T8p 46({AB=D;GJNIHc@[OT>Jל ȝs o'*<a+X<u1Ĥ3'E%."F$RN-j~Yj;kVH,Aithx BϏ>|>%[k%KΞ ʚWx9zt9%_)Bc!R2^|XV}/#A/!=ڃQϊDn0e;!|{#vTĮO9ڃ޿˞fF"Lo<RӟCoFĤ20&ؾ% inD1IjO8`$2Pj7s$lgHoLMnO}ڥa!}夥у!fƦ^7Kp6Ƚ(+N-mYۍuwr`EN#?Z/ovGqQbjc~:Թ%!Y>WE9s@b56aMJŀ>_/o*;{Nmίiq]΂ &&KޞԮI9*DI'= 9yЭ"%tR_`A)Rȑ ^ dki^%* riRq`B5^/ g9e?>q2RkPڥS-bm"7n^|p[Ǖ's~k {&{s;W< Oeey5น_RbDIŲVdĭVv0$?v5fk+eSab c JFjە 8[,h{4 yE<OL!k=! (^ˢ&l]? x{ b:N;LJ}SP7߮(6j<0a ۩;],7ptw v\6jUȷ\2H  Cཷ[Cr,rĻG|مݏ5l[:ؔ($O6jzv_U2}#3h(vڮ)e"Ҁbn9Q Bqheb>椥vC?ex5P=t6xeᓮp#:|}kh{|GHzofٵ>!jja60?qtNoηszm<.ִylazjܔ|Ӣ4ސ9%.%<q;Һ^v?chf}{{OKjArى/f F3tm|ۢ0hyC@|tuJ>؁XWCF}[lwRP݈f&~>ݙ"d1qQ˘_ωVSYT_#mjۗ= xCwP% [1sM +<POse9/FA͊Dt#׭\#gt{߼{%747c;]=2n9Pnfkx H(q'/5 a푹v-=2vjƭԁv_};j94?]!01vDvE3 R"FL}a z"~z?hk|]C \#8CKc%E#M|-I6{l~&U SKr(C*lu&]Mr?(׃JI^?\ i 9!10vuoaIK\CLKdjСT8萹)?9(e%&IYM޾xҒD1AQ䔉Q(-1pY)NQJaTӲω-*,U\XɱDU~b֊0ݞK=fc&5ƃ 9@b ll1 gM*l_ڈ]M4*.7ttEy*bbb*hDԔ̭xn%KDGcx"^4JtUp, \O9:^3{f.S7\CnK@ -xk#xD NFh D @J4JXg,=#-œ $j!оX،%Ӷq"rc LEYaBAm ,bTgQs 7o3Ʋ)RnXB'B1c,lFYmG' 'bD7VX$hq<: "Ko:v#m]Z3%G_G:t3v;c^_]<'=S$eC ("U UfգZMNRӟc:SHh́y6TLou3z Ws(,Fbri`5~.R1JTmT+=Lv!dVUgOˣ~d΃:)\_;tM`$-g 9 Ss-,͙O.MVYJ?o/!OIz90[=SűBm!!iy>ja{}?ISo')ӳCDhaJ 2\ʽ9QjEs(RNp@(5 ̯P*ĖH&W5 @ h-TKCM}A!~-;'0Í)Lar:HAγ<mXm=4> Rb6z!zZtż8ďFLdu\ jb0XwR rR;d8%.}[(hBSr#5IK)H=7=l/)CLW/H &-fo0* WvxsǻM㥒wa uDTwc~'/UkcۀrCF2[KajD# ]0)E4ާ[γ/L;܎vN aJ)ڋJ4 Y>j O| 3TO%$"r$t.]vE;JiӳcANGDQ/AN'9waALL8XmUVz)˕#ANzY9)>"aZRPS7}\&ʶZ4;Վd[¤ke]n%ؽ_S51z{؜ANJOI ';vgWNCrt/k{_a$W݆ XbʄiwJK9P?ʎ_(Y\3l0`VJ_k&rJXR?%Fh(jLVL58gW*S/$Dgsאjj~PNmps̊rI[Zdc\ Npn}+!pq#KEj75M+nI+v8]S~7o2L t.TZKKW{KD"@AF&ESz6 > 89BMҒHVӶ`j]0PFgLN:iESxs;mQ}ι|l%Hz&~m.9|2~ }Æsqٱ7W J֡[%&1xw2XX4a6U"mA4@R!#"\aeתQ$_ʤc)Kd6"\8ImهAni.+PcX$R%bA#MwСtw@۾94VOA!d6(T6s,:*)eﱨf, R *d}&'UF#ǂKѐa`hXsX`%vKj%}A229)+V :sqcS r  =BlW|I #.9A+zY^&KB, ?#~v*!(&[~:X""1+J;Xd Tw>L}mAȊx=wMLiɉ Ck{X-oeҸ"pXOpΑ춋ߔk6IKl>>$:f}u-hy 9lu'}:Q"^z_*u%]/a._zR>~Ғf&C Ʀi6`P ኶Lv) c6mR s$L}TvMnhJ5 T??R{p#PsVyd0D-udtp搖͋9E+˷T⩌7LuwɯkhӁ8idԷC-P" Baeۂp'6Ń6|??o}~sh/6Cf n[qNΈs= K,J~!T/cnS?1׃ 1i!v:Um1%W@d#l4ĔiXͷA=0Or>Q*Ǧ3Tm7lS~\R7oߔ~ǡrB?)g3t:go"|-j[0ʬSq7bGD ZApiU%vT"Xߣ!tSTf~/b \CE@*آC AT&D:y]ޒ#P.տR1B{NWg=$ \ C!X:;?TAR3zmW #zͮmfM_Wt}woT$  t=;=;38)f}0,E^خM 7OF`Dj[QzKItR/y%C o*p- zY-돾DCc*x rYi6qQ$(cB= Ivw9K\8>dapJ{{a mO 7=_?hZQ>= \$G;mDv=nI7'@qd5}FqK݊}mtjؖ9R"%[ϐM@QK"= N1g =)Seͯ )&Eش-ҚjMAJB5^/AA1ѾžӨN/AU՛~%SwwS)_pg|V)G mIG ޺8JW'Zm/wTSQ_ ;Uk `=SM. ~Y4t8$7!|A[gݞ\7'!@]jN'8I rRIB9HٝR\慅FXY2]@z"*NVX<2bHs WpNP+SpVF )Ip[:tD~) 2,@$,E+zmZƄv+ܢF|$>M.AKiɀ= N.C!-s|!-H!WCH|U6W/C**N/Տ\TRUSs]51eNyrw8z֝Ij~ݨ!}!3?2Wo8cIzv,_΃c2 )Im:D"Hw7bAb% VMgwYsߚ{ս{ﱋ%XwXb/ػFc{WTDPTb *eD=gعÒ^v|ݙ;3w?DOõ džx1e9+;dt"ߞ]RHd$"xKZDR2 jMt&.\FH9X1SwF|aV*X DN^M3+O'd~ƧzGpGx =n1k{ꊘYa|`` 8~iAKAiPC> -mb?Ȼ+!*N7}O\B0DEKAXRYǽIh",ɸg[9RZ҃LH$y},C[ܭjf Jن@$;lK࢐PQ|**pn5G2YB39o[+x;HS!Ng0l}h]`hM3\9 7[\2 @Jz`&G瓰D#!bGqC0t竘-XCVVU8wpλ3Z t"o5KDW/%3nGC(a@SsGc3mL-UVkKΰvO>?sp낟0"z rBMp 07;>Vzc0ܭn0w@k1CQJA3|ӲBݎ.O?&5|64j(!DjN%ic}*;e~Urhsz*54 ns,5raIox?]ٚLQa*+qŇAs?h=64iq7B$ #y\~`dm=zX  r0|_͐Z2CETڦʥ*) =gQIYx4cD%Vj>Ţ@wOH4xPld[7*+_ C=^H'Nߧ7wJ-OY>"}Z1]OIDsB,6Y;ZX<$O?_C>z&އC۸ҥdnB23S3QUzoB총 D>/l#$ѸM G!B5grm5H6- ɞzcɏk:S#xS#d'q|Ͻ**CC ԮKvcl1EԝhذO]젛 xw(ҲBߋPL*bI>DiC6.a2@E:%SͅR+z>@ؽ-Su"*P9&xXJ|ep~AXva?y7Sىr!',DӱzGAн'`v`]IuW0fs,wiApۡ<=Jo&R7Y]/?QJݖ{{'sTkJzTT)0 B.NR DDiC2ѼD4h&-&r"g1CuJ7Xsdz^p-|])uQ;g^5RId(HѪdFiHD*;@Zr"Yb\ۑ8hiFV(ؘ]M]7K0!]4N"{%F* y'fb,zE?H6'BsS0 Q^ཨnDBZp|6#y#$),ZtAL}nE In#R٠t܊G_UtieJDŽj˵PVD`Iɹi)~ B.܊c'N PnxDMm+̭8 s%fvU˴0IB xmp6+̈́D*8DG֑a %l1we95D0WLv>NAX߿˶}>ZDl)(u(e}, Q\Lxjw?3JtLXѱYIY2=\TIi֗0gN~ f:~J'2.;Ui+_euRVe+@xw[>f!ʔ>'}D}6d˫v߹ˠ_0}@WjJǁӄG˖]TNҲBd,Ňv+qHJFDMBpQIFBFۙBRQ[4qp8>~Q߮0}+.S?^y! YUzkۄ2k.5{-_pskpg$.B8UąyR[Ew5g(g-4ǿ[iMtsx㢠v_,~< JQb5:/vegOS%M07ŧZ<ڪPnz7o, 3V}kOmpSa0|70h:|ؕ D42%EP*/+a*_<==ոéMqB%N+.Nmi&|(NRȥx=[KXvOYƭ#︂aD3>ǎ-Dic nxLl|bBţU!KG1[})'8>?64շN-g!AL K[?aޤޠ_@_׆@FޣгWG*g>:-+7;"Y@(|{vD|Į~fFTfU%O~hvoEI4sl:wqcY$E j|UJoG܆T򞝗 [Gdh${>㲏R~`D yFX v;Y<DŽ9K|FoW9S+ ʁ?߿dc;t3)cpf1@>`#Znϐ >ns03(WiA*Cekx2ћ^X.7۷hT<'?3Js(s9dg.C"iͽY(2[NmW:w1w5T#cZPo|.ǂMշ.}] 4|6]}YG,E.X7nLxeZ~?3٦yNʦwPB%[.$2j$%_$DT[% =CؙW03-MV`&JآEJdd8h@br-nyĆϼ͏φ?^u NUص"3n =`9u"w6} ]5[?7--W)x ߻u]o;OZ3'Eh|NctY<G;C3u Aڬ or$=i57/xyfNjZ"'USeuF*ٜ/ЀC vm;RKL-IэAMbkE8 dxd@Mʊ`ExLlMZߎ޳o :/4!ͯ24}MX oX ;ycHfrOcou"dށtnpbkA-<ܼ\z^7zPؾI(/Y,E)!|;7x 1 pi~l5u-!1T?Q*`m0d+`p#xDt~MPƮ֯+|| |E)hd+ hXNlRE$ +C#E>r$EAԂl}9 ۏ~*.++/8 IAآͧqzxl }P թ LYfVn =EmOfmWl%^oH6 $R`iT*CP/aF,Ql g̽Y]za `2|Kp)AOml{c{ >r#ˑ2fA3m2<6'z+,9di)CK%Nxp<-e[ awUړǴڱ9ӈ<6_tL{'$<% #>GC\{_n^:\-8~3X˪㌥'!zIqFN-% J7P2Q.]O^Xƕ.%#Rd.Eکv*sD# ufRs;H94]t-Db*#la_ LYY̺G+?N );>yS=(WӲ ^ѝ ]܎kdV sGPh\5T6giK{a$yۃLj}[H.Ґ$N*s*6*Iš-C󨤊ˉq^)P/!E>A+6:ilwgӾn9vڮ}>a !buaU)0*"<X9^*8&aˮ9 c1||>S8r&"EJRL>o ?pm+4y}t}o+: o-٩{1G7:}L_s ~s퐖Wi S񑔼7S FjF jQ1^Di[ݺ(s–T#e7kp#5>*@8VݶTD5փ YTN~pV/['Y}AvUe{B-)1]Ƥ./`={י>o k^pn7 t=qk$/$ 9.y܉Ե{A젫.ٟ8@O}SC2/gk*+an߀|gCߢߺbr!*>|`=H6 VORT|hNs NŧcەIX [t@|q 킐ܮA MwV'BT,]"()"}ږySlm^M.z(+mb?o2fvENwo3{OOfܥ9p 1'HPۢWB0dZHuT,DJXgLUgJo _W8V"9ݽZr{f>+}D%"gv }3>`x:>@<m*E w2փ!CԅH.]_(Wf芊n<Eq.%[/YeTW(K Y[As\E$O.NR] nSB783++mݨަdg{Z!EyDpng3 ܨ@9lu>?^5ѝ`9!@ʎnU㇇O\[>-+kAS)lPjfb6S R-*=_ balt?ʺg 幺A) 5.Z@#P{%gZeN}6A=C'&;٠ٮ٠ Y(g,vFЍN}SA?`A}\'q>o紬ʙ{@OW0r*0xz~l9-hi #'SQI&|<d#ԠJ&ݞݱrt+̏]wGwfݬ N:, $a9<.Ӎ\nlV)aK'8Y77™;_d%<%eH|JfLY>սCF n||Ć4%4Xg? sC%AǷ@Pp٣]ҴMvyCȳfײ~~IR,SUɉglʦ/AqqOq' :q ܲP"ߝ+Yk9#{B鏱7)Ⱥ֓r|ކ{ zDM@yЌkVP7w=M"]; VR59NE\N.]B x7jo 5o\Q ضbqd% [8xV*O2hoofb#S+uUQ{H,(~I\-vx??0?p_Q-ۯߺbrKnBk@i% 1=!iwsϹlV3uBib*) &.e^.Q+G K# z?Vۂ%f',Dic Y ٫p%>Lf4=\窼Ao yM^ -fM?IQ$_Y0.{ק`Ph^pX(-+{B:-QrHK V7ꏌ0=خ=]J a>,ݤR3y~P%Wg2e6T!x2n e6[fl~"V?uGYK^ 'V pyr׳@ta͌7҇02^,;U*z¶\6(SVOu 6 z:(L΍,öpg*/;n1 &aB#I4ThL\wزFH7{Z+p bX+-׍ I*W-2pwXs-(v!Э\uP[3` S~wB0 "  M{5Ӟ_z vr>;6b0"P󕽢9ԊMkv s0(d\"}H=Y_UafEW98Oxs=e ~۵m b8D ]|e?1q9#g.{t<4B@ͱ=U4j5"<| Xc|f*"BleۣijmSXw"Kx#B |:a/@Z-(K"3=ڢ%~monv@{`<-Kowgږ6 ; RXHЏWh!x1xO`hgC a^?ł4獣|y;(!_B퉅{'!2ъ˖|F-S,3-S.d0%NO^ϙmF., UOVLVtYDٚLyocx>k^v6l@yG::]@mPW?UȓRJn]6j*Cv`#pS+1Y^4§UKq Q^3E4s:/gEw^#WI9P#]`[Eפ#t{]a`|uXosE8~U7>:rd)!/ǁ;!Kfw29_[Ai^g D|te xlY9 ?K 2!ͬoqTg]g:8ѥFXLtT@WZzh(eK*iBwl*0rrrઑ+C V$TK X-'{>80brPŷ'bdK%F-dXPNbez37y u$0J&ä1+cf}8$֝etÛ}o> ) &ơv遷WCU}hIA~;W3AԤRh8\8獸5 !rK9[W(ڷM `s>T~ȥs*ʘ&M " O oR7OW"z+8 ^|Ccďs|3e跮87-168*21iY| >,{KĥXUeQG勰TF[Lz`v6J6ȍYd%QQ L @s)K/(XS̯uӍ, 45n%@m52aݰg@ؽ-Su]d"Mt%N&~M4^~< %QI7fι-"%4#|b<=XU,;|vez!>z Iŵs'nrwۃO%v3)]I>?/}7Nuv\l)`v6<-IsufSIKhήhlP~1IP$) -"ݩ*=N&h0HdqX>S̓!<0Ӹ&AS! ƭOol3qFgAYIc$hrV5g7!?~g_-aj^ꯌkEeY\qabq7NkgsLÇ}qL4rz)'/>ALN|{]-yJ}S`$lyY V=툂-YCNÈ Mˊ늋x>iW(R[׃Hf@Yd0ZJZ2Z)pQ@n)Cy<5=P*YL’/epY_#0 "-v?--V*;{^cc9ΪXN)Ш<}s4s_uz!||=?ꦥ"GͲzg,6j%pe!ih( G+W.Y `($NIZ0\?l?i\Ff04WT ݒm+>-)DX2>os|W3vc2+ !oG\BT+*W%O݌dL{VEFH”nF!{W8vOȈOwf!kvҬxF3mL+gxZ?O_Sf W hMyb[`QX0/o|v*0ô  7+QJj`=d6jBxό\ O} T+2T4mps (Ɵr(P+9:+MSw{Q4X5Tڡʞ٦Acs?#XCӃR؉j,r.L; m!c;n+/BH]Ɯb. )+!1bMA†K?c0nnXٮia]R6iKWQr#)Ϛ$k47t@9 u](;Ʉ;IDb f+Oq {]_Q>^ -WԃqO6_< F{  ta?M#߾@ȤjFzEjj<3)~-N3R,t*'Y훻OC:80&]+z;Y!ޘ=*yaieY R{)G#J`^ŠSj!"g8|0ƒ9!|bUN`^jpV`.J~ )|oXaqHrGKqȼ`KI׏6_koS|9GCyZz QLVBcu+W?HG0%ayT懋B+d% խ =JLb Beo%/U^- >ILu*]z⒅Ub7?fՌtB$u.U@oZat"A?c eU4d.;oKCm8źtN K--f<4K1*Yng%6Plɗ<2k f6ϓdA j šTQGW4n ힹ?;#_;T3 4_4&mc)Crd9 fU"^ xlY4==VF0 %K30XLsR;;_p{9!wRE'"$d| t)S)-̵)Z}h)6 V% LRvDEr6SEg "0?l}=P?\ri/Dv> ƒ:3kR~w]xgsoGgÌZ⃯?*2B+-*D'uѤ5M?MPU>0\ʽ;_0Үmݵ7PK{p$9$GƷ+GqW3RbRLMђaJZ4Il?-,\%E_a -bDABVuZieurvٷZjdҠouL)!w\ y:ӃCr]שּ[> np!늣ϸÝUsX1NB*Ňr9Jy9*!ƿDFW@:ﻊn SSv݈ <& k sҲB BEBbZr(*٩f(%Ndovg'=Uq+r&QI N\dL An|~tVfٺ>܈jLo(@;Bd ov:^DgW!z@Իd}cN.>NPNoov䓂hvx~lۑSSf!70CCγ%ĝIݝB q`¦qQ3>l7}DdoO6Uߺ;>&:5h~nkWŌ BfB{g851W]W.ZC l|qP'LiL_vNn H|+|yA{$aNBҵ_;C_ FOʎ㐺 "z0o=[ZV_?H7sK PD!* LP v÷xey͌YLZ@~uA?`|䢰[ޯ)r®QK#r]l LW7RgNB1eĥm_Y:?VatBOb60dzzo "Pj&{4iɩ'ԚS0b[+A%DHJ9 J8s˭Y"&Q CC$˱ LNQO3=AbAX-ߜ|wR H57v*O"_T$0Mlǂc`څ٦7t hFyqzcFO_Qy?z:gE%Tْ$T>ƐUB]%J6C7#Dc돨tE׸>.wrzOB=B8$yyTC &u38ۘy :â,#8ӲB*>]! ct䆣AN'[-Qa0w*L<gv<u9gZGEy4Cyqr$ƞAUEƯW@Cze+@xEWdᑘ{ '\O Ewn쌷rq؟S؃rlK_&+F 1;x>+4$={szae3An.`yeu'%,_R1KVWt! +>Å9baeR%Dx?mc4-oa+XHqx!JxWF`* NGJ(pq͠YKUIӇNO~]/{8w$@tb!GESYQ>ڍk#CL t onf4G Yʞի+\to7  +jqhg;*,qf,xbsW3u#IE5%,uF^# $^A6k%bL92.")0 FMHiԓF t *ϥ Ad̻Z̅WY\fhUnƢFMHiԞShg;V ȣ,p[H@9`Q@"B Hd]>y*]3|?2};įtmyKWcݼ{w2w XϻC@t͹)>cQg%9YoA &4w5#)1ЕL,ʔ*^#I.2\,k6KҨ= "sh3ӡeiј!P0:maf[EWcHic;іB~hcu/lF!0f5CiZ'LNB(^CۓT$K3LC#~m,|$A6?T,b AR0f3dgɄf]x A Dp0~@ |TKoHk )S}D/y`2cO '^ͺ|(b?P`rԟ`!oIB;D~Bȗk`]EBE<ӮŎ7W'U;|DGqC=+$_ BٚL(E$9}m,D:^4xci eT ܆ML"+ KK8 v9™ !醗KspZKH3^i),xڻ.eDAo[#n<sx͜ ՊM{ d琼:oLC0\Hޜ~fL7>Xu+FIhgdl.7ጯ*Ԇ7z}b+Ԃq t,׼9[㪟X[0N9z6݁ B1179j]>lb]O/;t6RSe8&<*| /_rږ9Ӡ-R|5EX҃ȷ#Qw@l|#5E3+vM զ9K:z~ŝj5fJ>^WgY#h8@# 2}l4ѥEܞv{Ԥk 6Zp16KSXd\U' o;'$({RM~ymcBKY . 6g;^r>,x3td!6dA6}?_;3 [ZV_W&Q(qLvgtqFׂtqH!Qh ) nѢKdȣJa^xD,xaH6-/W;{2>8h@bwV'&(SN]3M3v퇰>mKǼ~)p+,BHlN : BpO?_kS!D6}0dI؂-tѐr!_\HA(Ӊ5~N΂ŭ~xB@cU z!C2>"߮&އ\%GV\P-?ZqM0FHE4T _w1JZK_d6C؋] 2ՂA k*Z|3Bq%79`foEgkW6,]Se!A\ⳟ*= V;t(ZV:'$]y4`w`bMA*Ӝђoߦơfŏ8U2/$ 7hI5Bh82fq)AO+k/{BQPNQxV*' s7=DOOXi@T\hcb>Apv]ܠF7J.nBvp,&dLxocxp6{ߌ+xiOq{fyh2#|bt]g@l`U]ݕMκ;+ &`%AϴXc )RlJpXo6Qaqב1ܧhQ՚-/I qK(=W مe\K S zUɽ)[Rb7gHi'?MXeNJo@{. 6D+աȬˑ TqnD8%Tv13?YgGQT=_:JOl/F(vEv/y( $98[pd"bk;N,7 8eK{D1|$lf}34聗-%I!P~0ށ-%XzU\z`;u``JxgۑDHfT5ԓm!Ig s Z,B,k}qJ3 zLЬxxIPQO 5\!f~^lUn0E}9 =E|< Uw'qpsj"Vr=pAO \`1bֺ|3ϾNu۷XbYA4ZJgٹPm JNyg׈LzDO/è88 j &TJp|y;%<e ! xCOP}|t_KTx9+ Z7!`*N׫iQwV֥> h8B[ ;¸^r9uA'!Nվ i輛n[ weڍ}N׽x -pދWqQ_J4NR4Ceac+3*ˌ,:*Y9L!e-j\T;3$?zE^OaM7G'PÛ'A0qtXt\K4xβ-"|1MZݧS3\xT*d c[g"T; ~D x,W2h-KFvT40$qm j[H (uk_ۃ~xɑ^=Ҳb":>a6 Őlڡlt3v͊bc7lmi\4~o\,I!f@S@w?/WM_t̯}4q.|vK M>y)8\{%MS}nPكKK Y("nPP7%sQUO?3 Jm +Ft <٠нw (C)Ad)P?.}%a-uܠyG2 5sT?!3ݦoJTs>KT8, y9߾xt& (:&A'|]Sty7nS,_vOz>@C jjTzȖF|. %3 ;Z`>=$lbRob``FGly$0.pA R;ADQ!ADʅR>*SWC%z`NZMrwr-9d9`]\3q~_8# ذ A 3\RDʍ,EƢ>b KvyΏ44+3i'R5\&] OSZV_W6(AJ>Nfs;ldSy^vHDMBs:FYL҃O|TMs8B䅫F ) ]lF`*nkjn=VM~g;f]E׸l pop!c3C{]-A.ne?1e'$EZ :0AWyS1S'E`yѭkߺB= 8LPƶqOO"E!Ihj,Alvw f2'/'}qJχd k”fR=gs eHΕy~AvorRC݄l'ոk~pJ >H4sq1I*-܏BUC0ZĔ h9vWbC9~5$˟fc>0w`1䅇8KO0kksҲbBeKR(u8TuPBݰndb6 v%y{jry q2"X LQ!S%{R6'0^ɞ@Peώl lTTꯘ fux%/3i ~\q͙euR2N^2[DNrw>bAqV$VCszi6j#Vt<_zT|_Nq9-IiL,ji "^Fz@ ) ]6dzhiBUЩ jrJ~`w.TV7 X5AU@32`_'s z:ZtU:PH(Yp\(BsŪO% UA p_&qK]GugƀOހNaao5О[*] Nd)OᴉS9)金ClO/Ag"c&^KEVUr%/gTD]A%g"ApCek`IAXԕbJU_#o\K(ԕӷYtE*G=ͪXNX, `<}{z]%M^*ZQ>-?_"=ˑR6+m!&{S@2v8%0nQ,%S}O`3r:@5m !0㚚0ٽFv<ԨO&@Tky sWA[x"L]<ê[eiG.okp xFoy2 ٭ IF4˧G-7y(Ϗ~bRjq*~nnǗ!`QdX0ʭ X@T7MvMR(5zKI!LRICG /Xg/gQI XW^d/= n=9Syx+@}}Mg/MDM=/"jPV7u[1;o`h :?rW3u5W}3M~B)3_g`N wϟ^-aw, Qe*x. cKOMϛweҍ'\j5N!`%˰bм n_"u 7rR |&ʁ*eٗX) Nɲ0l%fet$}W2F4ΒR/@e e\-;f 8#SRH )G<ƈGR,n|1ⱨwKo  8SQĈǨ&r4-G j!"хJE:b:A _Wy.ޅe(KH1"t#!/?ǭԫ;]iǸKܫ*ޛ s`Do]!FE%7 b r0 LH[2?eug=_ajg<3&/wZxu`>oJ*]E9jjz2p4Y>{(t@;3<癈!hQ6սCF n׷-4^zЮ _v-|pB@|1~G A1ހlLs!@QS m%1"պi`hS!?KB}?džd7ss?CQjM E;@dhƍpZtM\p*w<>#4ε]zu; nP/a$L8EW?_=+Nն Iݺ3̒@{0|X'k.B@|="_w;6".BzW3BCiVݎCI]'=_t;*ilv|ٍJnGt*30cqnGh>nɞ RB6,p\_G}^p gt3{_)yά;?vqn܎VdrKȣ5.$?dR8* :S^>!Q=Mh212OAtxgO'm#|nC KۂWg [Gdh$D^9؂Y;CV[t!hmwdtA\Tx3*8ݺİp>|!2 ZVflt{+^=ek1p|er_ ~cr5_dѣ\AXF~`xZ쵿~wO_¿&Mi S$E*ӌ=bw?3J[(ڇ;E-4Św0-)ؿҒB.'wD"u1C)ڷx`oG,%lbR$cS" fe߁xx'QNs++Cppbqp~ $G^ lcAL`.K`u18~AS,_e<:_lM(Ue"9'B 4qMw#;&F[pyB%lI5&|[iꉿZ!_y7ٟyHV(Ϡb!/+;_C2ѼhBw_e{͋C͢RB ]՟ƾ k.^0}ny8M@WX,(ysrX ʇgz*J6ʉ0Pl|b=|W:( BRXځ>gE:_[vs^iX+)YmUp4.L)T:_Xn/,KQնb~A _wD"Z,B1TF,%[祐\,F:s-XB ѩvO FaSP ?ZQ҇-E#䣝|љ, ЃUŲCbQSA } w^U/y#?kwԷX=f*[*Mό)]GhI!ѕIR'e`L&]Fu2Z0B~Z<ӘUuh 럫y#Ys-ѕp`\uT܆;wGZ̤EH#YOdFWoL1ǟǵ +AR> ltwyq`Xq1?зWml>nZV_ڷC̡=5A C8͙"0ʹl+ <l &m%Z|B0ר, /v<.l"FZ< . z˱kc^t_שּ!asط{qqC:=9$uF^Vh Gga QnGc[!` ϐl{AZ]IxL|er/Ѻ?N{9$6to,/6tnlӀCz¿_M9mͷ@q$bI>H\IZz WSYDy*\vk 3i2Ekt[G%L8-ҸSM1LbS!mA3bY ݫm5} +L ؓ7`O>Hhj@RK3L0K,nas S:>iY|6 :_l6%"CԻwi\d,%B3H#EecQt,a}hQxKcq99JJM!\h E!ٌ"IhUаvUfBHcqRTH:M*%liySt'$fK$ MI|bic9|q7υt|Y5$y_6Hj[(0\[oWe09ߺb6 ;FB&+|*3E]5+.agq^DT8d|~zF=[jdrv:hqhXww~SYtM*l6 KWpåANvpڴ3 ΄0xof60y ㏽~`Ht{!gF~A9%!f|0]N< 1-vieHQpFNҧ5h H!Y%63rvCC'KF+*=_¨MJ"UĢͱidv)424^< rw|* lE8#{Vd>UUpkh \غN3mӐxf@زf[e'Д0s%N^u~0t`잣58sɏ};P_Іc%/*_YB7ĔX|8L! =_2%c'y=,Im˃ܥO9z}>ܥY!{Dh7e7=׿E-)xLlPɎBܦk 6EqMB.ճ[dë@|O>'}^BN^ݟ?q9bg֜= .3d¿oPVo}) ZJR&Og%{<"GJDhaUoj?zF!&7~|}޾?VF : RƩ_D035Ra@I'GWNۅS`ssӝ!muTnEฃqf p#/gEĴSU[?vxe7$a (/C'v'0BToZV,_E`LsiYDXg#6b|E8z$4~vgtw3e10Y2& Z~APlGDwQqRzs?\7wЌ"@-1KY:J%mW.Y2s]4;ggbޭE)Gx8'xPvm,ۋA]}gC6✻^]饷j0 q+Z0,xeZV_-"KnFȃI h1Jl(2XKHM< 7 M]Pku 8!\BTׂG^x*/D?kdB^ Aׂ@m vqu^WEo~ضb/M6Vt}tW !Eo#T[lj=~S9"N_Rx8 7 `foUl>R'ymΆ )#laSdBz3j|to -*ehٯՎZ*E9v3*qjG ̛\ۯ!@ ["l WpCD$=a'I w{-,hß< /.|_3蟼uZ~DA)>_97&*ġ/-B87|BA8J.Ê+EF*ǽ PTW,TM\FeK@m~WF(O'YB8&MCa-?yq WB8 Y{CoH*v[jZPFCO8'L#0z`m>}g v}'[5يKv5}y-FSRq^6}/߱N!xLnE>يn;j_t zHޅ@sWQxǑ^q6*%Y-B\#uK Q Ng[|8ǜ8/(/H/d+HmUL#{i[7:=7{ (C@ 0fK@m^SҲb#HD) l{tR, *?3ZiYtg*>dRk$8[|odux'a_` J)Kˀ%xjqj^zhr/ęH؃n^y<ѱؑ~pfQÒ;3^LwMhC|42DKr3Cl!쌽G̅A}?:$lX8l50_Phϭ۠RV>P0ӭWy:rSq 4HE 7&.u&W3vx,eʦfpIHLj.].&M<F!3V*e[2\Wf+I^0(gpA+bfW>݄_銘!pnw5c b2Y!2Y|z#\ӞB*y]2FCیg0-?38Q4GY$ 4FF?(;m셡үl&btnaQ+śdr<׷ȅ} zЃy+'&MY|6eO/`~|ZL#8alrWi~6~p"绁^0݄RƐc3? 9Ӡqj  [{I#cv!rhg}+8;-U1$x`X-Oq`ZJ`<9^70]tǴX%쁷C !o+K~FQrk^LB{IO h95EHEC~n ߙˈSxBqR!\sFpBڼJW\.;¬~bqިzS8XhFKPALEJ>D^|e/b䨬ӵ!^^ CJMO/V /8 >f`@y6˗ -57.HsW3^Dql ]͹(K˸&?}؎8ye7": wV5+*ԘnDk{Yt-uqOciK^l[Bb i\T".sٰ5."܉+V@Cn Y 9}Fy>j`x6ϸcgз1bgiY!|K:_ũȷ8àx(m](eʮ3VQR,^zZ,"~F reB1򑘪8ƪT46ݧғ7zs=@JLV|\3wtW9mc)F<~`U.Vfb+/|Ɋ߬Gk,+x|۲kŲ* cW=xh,0r5Mˊi% y9vtѴ9RS4`)S,vR;5|6h~tY)C `|X+42!})n n\+]ZbȦ;yB]wK=Nr]W1o jd?M3@/ ߞ.!h|g"9-  @C%6V_%-PM4Lfuv7qP碂^(YDu٥ *ĦylGr>a"Dܨ*፻A=iV  aM~B$}E=44& >7 ?>C.^7}r"0r3d6b1ixQn8.eWbkɠk?Mm u ImkMH8̘iOhe7GeW(S;& ݑ[gcWtR(d3hjF#iyI!LRIӺEq2~]Bz`7`;{IL)nBnCҡ-LҞC9>cQSO DaV*' ۦn+"7549͚z(o=鯍y7l3]"9k^/e~UF"g3뗗?. |o4Qol3nrmxA8q?Ab8Y`N|eTYF 5jNKI/=1n0=d_9r d=U1-+ˆ3J)="vm!AҺ{H6T Ϊd~1#),=_T𘍐rAl{+PQPZT@H P+Q=0mt}4ߜ4F #ɠO mO/}T#P1Te瀨(m.qh/ *"_bW*nqQ9AWzsz2Ꮯ*<s/tW}hZV_GTk6޾͸1/j,q&i1F%-)hht0 Ur2ےWf!>3 ⁠`j$lPBTNՎ{ړ' ԟשkFY"l}EW9oOQMSަVFv<8 5[M;q3 'eF9KR)"|bVGG%KsEzsj]wp,g]i mڞ ǎuzKZV,_bl$QR\)A=]BRIBE ѥd1"<1"\N!Uc;[؍%qE׎}~)`zd?@oN2FCB.~od(NJw`]B>dzdſ3cR|@;2S:7_+ƛjts 3=xnFJ7Xw` gO$hOxk3ܹzkтAl tD-)20e~ Cj#Pp!Rbd !Rzxvfy:hO!f1[3ɭ6hFRDŹm~Te1 S/.;a]A݌pW !(m7#-?f =ް凡O^  ֮9o]!{َ*~O)@ R`^!D1ё$>SSPYAPAzFLK\PJZ>R=@@Ū׈ZDD-<#ьkVPr>s|vt;kba8* )Ęz;87ج֌pq}6}pSP09lZ 28 1&EK&'dzs(dSG0\;? nhEL{0\t[ȑםFO |G REoRy Z}k {G!b8?ۊǫD9(DyUGq< 8&|Te d,$7,͓`($ ?łqݏXx[?q4c%΋KvԤ%?38,{^#3P!d6w%2A{@H<_J-BxG)sD~%r a显zfUN !a uM3!Urׇ7;T,40$%9 'B|b <06|\~♥ ~̸GC|bž'@VI geVTS#@wrٜu(z{D~F0U9~ G_ǴIbC0T*rYv*s5e*-C BWF!U9hLp@^" 7NTvU66X%\fx go!ݼRiMq9QjL"lO~ݼ"'AW `NiA0XB0mMӐRM0 +?5(!=W<:;`CL4/1#.7QB^Poz#v18r!*HFzMz\<‹Ӈ/ {*[x,#f Eta W+iurĊ< Ef+*/ 'f~k4߃bAV$CzvnfL9N+NiڪA "rB̿P Fcs 5Wcz1+`sֲ`(bC0ڣx[w#^$E׎ \`_߷ d72_pE$@laTь߻QVcVi@̥H%O-;ш7;cʁ;($f \v#R@B Q˧>xt[@t7odg,4z^=gyv^/BWSEW#Ur+lN-ǡpu zoJfj/Wզ[-4ڢA$#.4L>ZN1n7ޠ N^mqtc v}r^;%-+H~h7xJHvW3B#=_4YވFWh 4[=߈ӧ1˺Snո-9 rZgqOÙRڻpj,rQ. Pe>CH%0]Ix׍x8|kKn񃄧ï'څ />a3VOӍ˳M/-+#J4焜oWiM`Gnt )>,)JZ`Ò֜,i͕< NAΜ0*{N1zڳv~U3͉k#' /\lM`UbnI,tiok:à_0lGᖖmoHo_zjc1e={{3"G+A:_OXlϣ!796&pbA㴨9@-A[. Yzp]O; Kg RfJ#j@%>Xlq$8my0"N b/CΆ ES{|(,kv7d>ƚʑ77 H%UfC^%դo|s8{¿fsXR &럫y#M+sqڳLQβc%(~wNMobi<4C 06]kLC@5.Wsq#$( /:}_%8rgZV_Ś]C$>O¿q_!D)KH!8sH\G`YBL1 Q햱V\w?28ְLʖB &zqdQ#-y$ qJU` <Op/?Wb05b ~ON.%|B& akAq : ܈`@D)3S )?)_U>#)m0a3f'u\4C >qX)Y 5V* aooI.N`k'J^޳t0~BS˅ڣ~bQSl>̄0g fz4C >6(i |e3 ck5 էOkng}ݜAarDp]uQ{t P: (qR(O?FYԌPP^SETaͺvb} )#lb^$FJVf}Ak g 3v{gR.wi_"9߮p+ uഺfDDZNu(a_(__B^|eb}}s4W@n#8t#_8 EZ;WMX")>OEHbV GÇ"4p gaj>]qb#{z"r>Dw)=@xUVQQTL-ny&PgOpX`$L(WQAlw_K>X` Z~x1Pɓ' %{gU-*U,q9.yۈରFi[Z )vid m)lH|)d]>1&h]bswT|#-q(Yܿ]1~yy~h[Ї|o]|yHq+shH32Os*(:m;XҶ3J:Z &4aƥeu4d-xBin7]OIi4;E7pe K蛥&).((TB[3c73o;g§+3.Dt猁TO7{7}er!Qх`7X1k51&c{" !;@wdˠAz8nZ0|EE``}ӲBr4zy*6fWI M, rnxhξco~R D+ֳ8^2G""k#V*9uWxj2,yE7"LaSJ [8t.:. 6{s6֥s4p<4N_)7Cȭ&cQ&_ւ!gS;b·~C9# ѰCL-BbgweB䤥qQY8XXFNRENZS9/(r2 +-q%lFNpy}ZD6&vOK5F8~xSi];%’vU3mL+gqIq7I?$CX#'ENFyR)6(Y=e Q-~A|O>'}^BN^&q|ȝt3|>9f;ɦ@@ jʚwFs4q;dj9Hw>Zŕf;1[c j68f ){(f=&.ynwcř-y( WEřUxU~C%AǷ͚?41/X ee bi#d`cwc!l!^<8VR=k~X̶%*l"Fѹ-KVm-o M(5 ='|;|Ož96j Q(gp Nۢ 3<[-d.BMcayj8&!P+l൞mE4o-b $̲7/N1S*s[Qh\j4=Ct=-9hƠD(۷&Gɽ2lQ+K"kY% s7 L.=x DʬD4QɧfEƜ Q D0U!+Z+>Yt[zhQ(|nR$B#l?&ŊQJ' hH>9$9 XvTSb`&1\tH8Uuo@ҕ]W[!>>bQpgLRB>Z[ch=ikJ;"Y^iq.1iݕPrNLҺIXrH!|V*'IKɑd9y|u٥ XCX}͢RⲪM%25KvgE,N Xn[8P.F5c-2h]̿!|Vwç;wvz]GaпX(j+|~?ZjX|n_Òxg(u+}]$[<:AfGMfJZϒyO:SsIBiFBTۼlk|CV[+;+br~*Z>U%'Cy!*J@nuP;TD(e:>4ˆi$ Nc#S 6j%pz}b+#ߑ%W$޲x! RXTͺb{\H~t:C[]ypJA7FsㆦL ?0_zA yIpzK/ݏ.D+W3Ѯ$4Fa@l1E;m^#:"4< Ғ%hWɧMׄ7]+=.{t~=e yM8aF7+F+?N7# TN7g\pT0\!~@|xCw^6䣍.nG{ٌ{s*#: |0jQ|,?)/1_P@_4)Ȩȷoٚό.t E`Z&_ B&Jh+o()p٣R.T"{4}D.3Iu(5aK׋hirxHSД>e4}@=/y@xksG`'Db :s Ë% / 7Cl͢\TWlG ~, \jWnurkE&JkRkz6Ǚ>`[j'-?_m>'c4ޮ&gWҒAKh0 z=rK RwTut ~Ryx.`D?8T)My54X` cF{*m=&dLxcRӅ&o4y$>}3>(B^kp0HۍA9Ƣ|BF>`!bO`޺F>|ӲB*ܠ2c$OI+I]~gȓv@+^D0bwRs.LJW˴WbC`,gFH&-bV.u0PJ@!>Q/R7w}D?ژ#lu "7N5vC4`q keg2 ,Dtq~2k0MOW.,1܍|=Tͣ qm+.Pp87yxGlS.k5?N]j:`iƠڽhC0xv}B 7~ߺB&Iѐ|KiNT+FT=(`S; VDȒ S}"by+{ )7:K S-hO7A7ϟR"!LݔS56ݓN}hUW8+d !{ {ά;Hs,n)H\QI,(~+65mA4fW[}3;ciA:|$"=fS}Ÿ2~fLy\ ~% S"*s42=~%<)(MԔӔX+lBnF5Nq=b{&GZ۷C߻IC?lWI \yrկ5mgN yC<'9$T6xM[Fc=s ,μf[zm[zbG+*u#޺4h OO3|Ad}wA`e/n#?(⊾.=vI) .i(wq2'\Pe|A}4,>Wh)416=?_Tγpуln`RF,N3<7;%1}C|7 | ?+|*S}hryTz (_l\:} \c`Q>w;lnؒNpBUaǵp)Ǔ? ﹝izTd4 |I.~8^BT2ĈuVrNZb\C@ü /}u< ߎz_ `h{k!49D])>~/!OJ[:n>u猁< y;BK| (ސUXNqy͸|҈h&i Tu/G׫,-vH0)F$@3/37OF; ]ʃ"ifD3Qrp(xOpQgAsǃ\3;NJ̧_J.oLzWRt—} %`$\ccTkғƐ4Ra]8~7FDy{S7`iT+WTH,R dبj&)CF[VnbjP~ijEpZV$JT)t1Yikb룶*7XxoOe^%é :yc'- E v6g4Έ2׏\VAxql.~>Tam|ᗐd_\'!gҐr՚䚦纁D%?zڐB}h+U,)_Y|K#"FD[X j^ļ0kGR,#5Ie0BL͖/,Gk?ΤJiLdWg$Cf$|ݕ <wу++R.;\O7H7AהSԠv|\e4JsKP?m|o]|+x ZX熴pE SSڕ Kݲp$F.P"<{7c$9 pE܏jA!pIpE0ۛ:/s~^+ͷQ$^T:ףb1*xU&PS6? 4x%ęF#b!K HK.gͯ0X\LLb}8p k&-hFIYmҳb0Ԏ(Ořyv)Ez\;u7DHfŴ!-ѽ+F[RZX/!ҺlNݔm=K %۽A'ύQPuף#bI@㿃XbO,;썹ssh%,f }) !Ë.n)[ q]Q$ëKjzӡrDS@oYY;5h/L{8l¯7u-oK8"HQ޾ ݏCfo@7j ŊD2Cf-l6l#`nJ g]NXT?aCլOI"uLN% x4i=DN_P%ws7(ۭ>B?r&]f,G[YHrt=^S.osAp+%IU31< k$a]쿅| Kg=H.x(6Py csQmO kb ,xb9{vu9/r4~4%vqw|6{뱠JoAStZӃ-(+n4E] 8F MM x /miI%(ԺN)zTzŖI~kC^ʐl_!eܗ\_W`X.=nXC1+L]]?[ pkE؆StW |5ᒀyZ  C%SH~кvl)4Zt|m /|=.=+ΓUr?o3JI"~o:[$ى/RelF FE0qS| @m>p&a:[W$cF|ja;\M,հXUvRl?v׬ ղKUiP43cǢc,VO,Rz!yg7[Jy"UF_X5\ &xzB07RBllSOq)`~D1$WzAK*m=a5l;)U&b sn'js"?Ƃjİg*/ aj8Zș(V1qdfw'|wd/X-[4p{ry?в*b.)fuKPpbqОt|~KzV2w-|ʝCcAUå~ .#znB0 >t &]f "4S}{7!5EvJ3iqHّ8Ϫ#"'~Ve"PfԾXrFK|Pj]u{AbNz+pދEЬ ]8a{ - qwx=3bnng8ְSڜ؃O s@D@,) ?WBQb-lf ~I[O0э}>mkߤRX|z ge?.7QS|!7GB.\(Wޣ]?mS@|YB=&n ʓc^us rT Ճ<]ubVBO{+聦E`IKȮ0V Xrȋ Ӓv&@qIH0|ܖKߡ|~*3g 6ʪ[yaL=4ә̺}#KuJ g[uGqr,ѹ Ӄ293go{CW4: }޼u h3tt3[;Ptݫ  oo VYM1= A] ЮLzh00\Bwט3=&WJ>=4;w.,O0aUz=S=~L;ZOs3T*lޘ&Ρ),L*x%az:.pЧUn1( ~rƁTaG^Dp'Lsz8#TG6@̈=< /])=d\vq%h/LRw9hW9F(>a-iQ(kmP9rPk!z祱=ϛ aᗔ(kNVgz9ގ Px X{k&$ֽ 3GFHtr H)AgPf ZW-Ou3ۃ^HITċl%|`" '@\  =ZxW$1.)uHZ;᯲ˌvE_FAʵoͼemwPV<ۨ'@v_aJɚ6w0]x݅~^w[YE dnvp 0m„/ )N]&hw};Fж-fcKn˷.#h'"˲QS~4# h4ȉӔe2WDc`Qܙ>:?–1O\\%Mť|?ddϖŧ]-Q+o~E ){K%-c;$CGW={IW2a-HKel Y'U ޚAN:>uXpḤ"K ³%C쿅|Gezյ$~V@ sf|)͹P뫋3@O ~˅@u]H?1mYdnjl]q \O*d,nH$[[.?SpZDTVTҌ.5\Җm"p@ٙ]Cky aH:gh?! ϋ0+rj*[[jcf @إg/:b"46(_N18aՉۣ]rG78wWqct{NH+ ?"cX5oP)Ͳi24S~Ea?A7&ې5ٛҳBJS4 (@Ӎlb_HD)kҝ"@.M-뇃¼P SdC0M*iiA%^# 0\MBtgFObn #;M&t\p!2>WHkۙ3YZjM] (B1ag"'8-FS@%ԼU(̨H%PŖBhh]qC G\Z㱛?]J 9c,A^27?+6kԖ/n"@|a(Ya?K 5CygfhZC[t j7w#_qyCPytI=jM >n}t.tknjx%R4)\,ڍA9tfP7zZ-g?2\tB?OF‘ 9vDrLԞL݀RWD 9vo AI@.8r|Cp7A.8Ϗ6`H"*/޸ߩT<4;sl&JݨadQ*kP1bٗCic(\"?C ~6BQ^3lWa;o.ԟgih?Ro'hO{AߎTyƕ&YMꟘ\DHX ;5c1f2`NHn.`9g/P1= l<"7 3*y)Vr: g9)>:T9Zbn΄b, (]-+v8}!hY˻˭ m-Lv-ˊz3Ӄa ]i^[3~ Cq,YMةioyw'DMH]5S"?2"ҔGƗB]wPƞwJJ ;SգǐlNs KH4垾v*){TgiӋ[v! ַ]r`gIeS8Q aɅ}.5R4 w1h<Ζu h*[q͵;F @v~U$!WX7B8 U g B`YLvno~i~ժJrSxKyUT+))?QXɃYdɓ/TcaB;(WxqǸ.I$紛eÉu]$]ӧ.?aS!UN+&5$B i qzOruBpf>\FƮo n\_h7_| >f blGȨ<8& -ϗBYd \QJLYR,eRhP408!Ɨ-G!1 XoV߀| mDy7?Y(! ˄ ȁ+)K1)dXs'h\YZi}4G@,ӯ#uOn7#h̗LLOnn4_Jĥ89I)H -<5kDSk'ABE$j$`׌'-AGCH"W I%M*E[KtKwX8oN<{gg8s~ 7Mq,1s̀"BRV6%~X!J$p(xO;F!iŊ}s (?)[TNǽ| kyu*h,o*=+dkISEf# cׁf$ C'dW ҂uT\)πY֍cTob SlRD /rJ,Ãڻd-De/WE2rjw>@~|lCq2ǂ:e-J[g5|PHaB!@S'E.UgAfBbH3?Uϰ#Կ{:Pw갦]>ٷvG|XoDzV,_6v_u EBSw3۵p_: Ҍ" A~/:RS4ElK :ˠWy*|+~ƝbA ![68qݕl/o>RP?c¨`}X吆8@d3oOM.k˜)|5n4]/rE2ˈ^AuN(\+Fĝd\-PbͿWڜxq .?oҹp_b}qZ&$0T h2oԗNkrV:b>h|JgU4,4m r 2َNr(Š-?A<'_ق+'s1[-n^pӿҰC ڜiP= *#7e| ɍ^uW:ltՉe@{S2vzRNӳBgb:N եmA>d 6Ĥd^]4& TqfDV$d͖$,<6 6} !?-LiK[~QΠdŗE`WVnzekw~l&]lXeZD7uv{3W%ؐ|fQ'Fm]>n*yb }~Htvy%3$e'dvA9IAsk)NgustY@/Q6,ј(1A 6x4C*9-Kŀ_ #֏܏++5ݏ16J=g,-qR3/ ʇeS8I!$R΄v7r!$7U~|zFD$t:ig&wqN]WگE ωu)0&VV}w_f\za) uX-}1+7HYy_AE]h™@~?urF,cť!\[خMw.mI!Q֨@MmdXr*Kad~>ɓ=XLr3K,9g,BJH86f+{krP=Puu`ݣB/ +YRW}_קZ`4^$89=%\ #v 㶗CE9!݇́Ȍ)HϠרAӪ 6ڃ Jۈt! nђ#v7iEQ*!l Ha _c,hMvC 6*ÃRURYfoR;g>]C lpeBYG t&3 ↈUtKۃ߄ihn!ܱgw-gHHq*)\lN"r)}rB9*WX׆dg"K&?%o~mkgmxa,sM,:43 7p\7X4]; Z3 ?̝2R:7/O1"p[bMP<P^u%D1Sp-7gLf>pǴtBJ[vrj =Xɠ-NY2ySpۜi(yzzy)wwp.;b)NB/߳bC>/5\٫?ݟ8f]q44=JJ[_LQRXo_v!.ylUR] AMLcœڞJuxFAWn$e;Wf,tvIݦ}ڲW!p~ 2xc;BVPɾTQ374:J)K,_.ѽOk"wUzlC?r&]fG[YfJk\k3srR:˗:Lї ^PxrG^x 1g֥@.)v-ڀNy_5Bo]|y#' .ݭ+%Bql8͕"#'e;pQ،٢săN!p#kylJRz7h0C!T3"yuHh1.kеZw i"h8t}@ ]lt݇b/ z%:mr]3Q|\7>ݗnn07֏"_uJ8DG җ}Q\˦?i57fNk$=n7w/;nd^ "}.銘VrX׫f|n -s3?Yvf_~p+zY^]mzV_#(7h4v5EI!P|#q;ag~ w[Ɇ`ZRFH6V +9Vx!URyr2 Y6g%REb1QAym :TNu]M1`C0ܲ@1/;gOv uU>;UqpqXi6R.\=['+be$&xHaݼVKVpc@L(KYޣ@)q !׵ޮIBd1i)!]J3 W}* C=Nf,n~>WL0 A4pmxHab!oOj|4p/T~x(n"T nl7  gW^а>;kw ;GzV_LCP{h!EoLI,&l$Ea}!AY ɦGMRwU^&FT2Ϗ6I\{Q:Z"4<2V@5+#QB>4pf!"4c8ot| ~r'q 31îj{5@yD~B,$fXҗmfpq3?uy+zGDZd bN"62Z( 9SS4`ttFGzufA[ w6)K{HoExH!՟!f#oӸ_v2roΕ BAU=P^ u%|6(T٢@X2gόb]b]8V@Z r8d8U]p&OwҢÖ:ͤ,޲+d_-(!.'j@rַB0$U>U2?leہf>,>>\|K ,FN1gv"BT8dtFHBocdewH o;ӥ(}?1R.KAm?n!2nø$6#,; j굀H&)W(U{A?ǭc"<Վ(`!pPSqڅZp"ucԅu<7r:4w k> Qq(~ HݣҐV!Vߣ+K6gWր>=ӝM:z_gk+Ag~Sw; WK-/!12 o 63\R㱸 c%E%-%~hSehY1L&d۸1A2Vڑw((_B;4V@hY:Xʁ X֎4uť-6W!x9HyE!k3JSwR5VӔ1NW+18ۢ͡8vƖ !שC2J0)8qr$3n Ju33._ƍF$j޼9n~ 7 \ io_Q2u9B_mS4YEhQ.v Z]﷩d+:Oگ"`u(g.y={Tp>hhdFBrOD^N "ڳ\S7uc3k Z5 .[p7;K#B4^ _ۀ!q:-z4$l׷ h&m2VV>m^> ]]ћ v$ 7dov1z06D`A97% [IaW 8 [vBQ%`.|a-cr>Zٓ0RE]sA{fS+]`#9'ҹ ˴fGP$Hb%#^kw@L}>]})NofTi aN݈Hk`aZ,숑F 4hXÚt-5;N~HD[ ,k|I i (XcQ?d)-SHh'}wV'"^\ˋn>9b oDd%t3DTQshƾT) rR kk~K9Qrq={CڞqH H5M6CP!]@sSweF 0ޒrwoD'C9L~:P3ccoc=R28rq(W쿅|7$bsw;PnaH*=*4?L퐒ޣkjY|ˢ!#DBcD!4ޮI -G&Х40oAό8 шlD,ɫ0N }jC`4b1qxoIH>Ueb@ۉա\o W*rӔ3{CX[Vwo"JoF7{LoZf3fI7>sJ_eEl[ !'1\r !) 3erl#(M5Gg5}h;쥞P{^(MYO]EgmC 7@tڳjSICZjPN{̆ BSj3?[v0á}цp KD c3+%@r6S=@UjEK2QO¼\~R) dzqB<Ի6 egCi\TB0~ q"âtō㏩O ͼz$5ObYAc:G?^AvKڡTM. 7m.(4ݼRz)kM1=z|afSb)- 7f˷@xF7CBoA##{0|X|q7~yWgIea?x]=lp\Aͼ`Ÿ#o-?p.^fz'qŚI ;3YFT>o0qK^6>  3/??/үMۗh0h Q&iO~||pM[zCe!K[T≠k۰C]mi,| @ht=Ӗ$ydApEoXJl{폤{nFr/K(W쿅|g /.y.%FPݛwf*\lݞ['bAKv.(K妠.=+SQ$k%c>xϩ(~AܩIR,#p&AP # 1H}~cJL| x" R7 (X t D(S9Py'1kR0@Ĺ`5'c e?~_"r:I|K@OQ6=XCOHgP)(MO&yɆq@*~)j܍DREl挅M3MExQXhbK+7TN"Ym|ʾNZʼ% -i"ׅ$Y(,\!-mhI^n1{LZvN=ǚtUP,CZǛ/KS{AYskΦbQ@/ ii toK!z yb]n;퇔 ?xi ;_8ҷ{+̲[@pn6G'B)KnPGDx QH|{c<x,c~._l $֜4A O# 's֗ܠ=3c!rzxPqC?PUdk*=Ze"27(z3b==/)g8 ~ qxɋqK]7/1'37g@$L Hי@M͞-*ЂVycA }"ݗ"E#|m>7u7 "QdT0OnЮh`ME̯ Q2U(ϥ0,!8oߟn߭?Wx¨:\0ك-f =J*]zpո8 XP6Mʎ22`Tթϝˎ'ico0(lRc!\HN1 6eFSYa1E$H=@uzsa|޾YNnck@~&gu%XjZoID'-&aQL݀SJi0d0LyCQ|0΂lJS!\: !hXa|_2Pn=(_^3x" WoXF4~4C{-|rzEü-wӳbfmBT2$bO?zz4u7 1>Yx4%l0{'"YU"ad}%De"Q!|0\✲tQ#Rc)XExHG tjS1Lcnk.R:DxHdz zRS2:l{j[5uo3Txo.BrPd|~A1#.gx [S<4.9~IRE Y!|I!OwBemRL?D,\L3+o[Y?`8s7"ibfB!b&J3e^n\sNK&K3&(`/縬fNdxMf vcP^/ě/) 9i\Ĭ<('^S:h6:+/(%ɸI31iJ-ZlC &JҺc(Ƣ h-20/9N|;Sii~ޝ"3޶<\p&eG⊾.\FSC^3.}\~ Q3 ݝĞ(^l\nؒ zĕQM:w\Р%1lv*)أI$Ù"O!>Y7k:4Mq3x /q9x5C.(gYIL8bPt8$qǪ|~XȅܻAa=]MnφgzV,_C4r:"ʭ07rb$/ -A hN;hEYRI@*CM%G2ki胑~]TXLZWkgS 47TnJO9Z6aK/J5^F{8ſ\щ]mΌDz EzzQ~b-sBL)v[9t>}0ozz|mؑ@WJ EBE&-9}Gk he7~ROB3AD1g$ j*.`6s`(AAL;(*DŽ Dm>n( |9Gaj4rUʍ*8"9S>C֏ 3銹ŀ' 4Nc8Vv?@lp ۗ!:Q;|\Y6=4%N}th_)PVu tp里A*",Dw`^3v\!ܚdh0ʉP}a`ͯ1EcYVAtb bK̥^K#hUDW%ZOa5$p#' c\Ar^2 ~WXt6jLZ'5įik` ;Y aE!$mHKqF6[[Nt儵-E0eAu[DLP'qjl -"njPÃs7U|@YyVKun_mտgvrj EUaǵp?;~+C@+'9MYhbE4nv1'ʾk6s;nzE{/uχd¢zK˥ !KORXe2¼ehLU\ܜXFLO'x#>D|*`VBe8jY*w;\-i4[pO5,ҟQ4f4G,x(eDO'bZqG[ZFZYPd9X Fkr &LUΒmbo'N˝7MxI[ve)d6A6hYC3ۋEL$[Iߝ57Rxm!8GzV_G")FBJ&rRn+hPxeL>N8k~4`JfK "P%7I9ZA\~K9ǿO "OxUmҌ.<5>'I\PIIqيagkJ5M-\cxl*7V٭ܛ'&W!xjr.AnlbN"1 I}-1J(u1ܙB HBؤaUնf r4^mޮɔwa^ilҬlMP2·f!k.B(#N/_pC8Bw^7&}ܞq3S~LD4A/!I?C##Uȱ.݅意h )S 2}ܺɢWzw4l t =AB0?)! A–خRIs6iC!0 p3Ub 4)KLU"@tBrVd{fnPaE(UBo?Ax?&_ @HrzGp؏VK.!)8>пp'&m bd,仟7m)\l 7aO&O~ݰ~Жy綟cz~xjDHB/ؾ-kMD(3Rd }0[)'V&MrfbL?0d\Q.&TS{Slo:€g!tUx$*9ܒ'wsXN}ޖ e-J[>FݲRlRi|bif9&]]DJ(B>1΂ ЉzAM@ӟ +Qt[g@ֈIҳbCňHR0rzh}h&BbcW9QAhp!r!.S łl琕1TDk⧍eJQ9c+Tգ2V@9EWxaL*Ja7wW%E{wZR4yH>7״ן@"2@u߳E8 KٶEPEJFU#935IRzl6sЫ Մ0k'*ǖeZRpZ68n#MȖSdܜkmڿQn?*q\2OYDt8=(XV!9׶PZE@V_IsG ZG|vZ7!(Hiݩ{GݠB77$œ~X'~/f~ɋr|F7(y= TiUPk:.uo57(z7M1MԕCXVV58:iN X'L׈Y ωW&i < (lx/LҺYs!q{kosHFFv^怚g堉ttmC*ݠ҃(UiS!C &Ep rbz,zёy-*_#1J 2#/(K=`<4eƯxR=)[T=emxv1{*Ai/٤SX"/F #9E8M^ O[ı}w@jSRI lOXP'?) jaDtD gi %s7 -AR/#z2\PK.i~Ya78h Cx*sOTX0Pa( KT2%0PrlֱUo'/)AZ|?~_]X#?E:|*#`_^BQb-C%2:α^Ǡ[.[ۼ_'>O-"0Ia)1<b,O%EALrwJ2<Zz4a/)e^ B[Iƥ1?iͻ!;0](˥aKZiqSw󝝛DzLCS#fqN+b # 'Y,ƴoQ{~0_Vy+=r-,aG!;"p @D-x])-}j/%J|rcTP%z'WnZ?㨟v%_V Ft37LjٿҰĆWy~_'K[p:U]F D2[ r(+=c :~;!}HmǬUp}n48Qu@ `%(GŒETO3p0Pֳ@^bh~S/77)p)Fh6*wQmDvp P|^屛ݬ a>-|YR?<:CF>8tkѤ/Tz gG4rC3"_ɛ4^P1$q(6v޵^:x?tS?|\\Atd[S?!fp1yRwy c ڙ~ރRK(<(Ngz^] 7֥So#AdsgF| .+v q&髅b oASwJ,ЈR Jlb?-,8*D+d'Z`*1!y.kTXS }?H髷+*I%A'׳ ۭ)BrY7_iDz i iǏk\dͷ 6svWSǎ@}'O~ծe6ۣ3/$')TPMXPF }&66'b`6+L:;6BRvFyC %| 㦂 ІPQ}Ɇ2@KPj*NP$%vmTsZșlI!Vt .^bh@/4~G9`L2*&-!ez{ͭ.oWߗ-C﷩{ Ԯ$?ُb6#i\Dѕ"u4̈́̕H/>K3.)Cϑg~7ߏ-p* U=[U%7ΛH*ͩk?Q,{|F9Uٮ=(o߱}P6{]zuǮW! HhhfP5 .CЬLB()Y^>G ]= BN} H$>54wA3kq+c@{+&ҳb#R,g -x1m*8$;#N+$2,<h`~ ɚT4^3K9GcT8 #DRYa G=gpK|!j3~뇁:/+gM/ret1bSweW7W} %5h@壿˺p]ϦV,8^%¼%Ļ$yzrOx^re-ɧ34h)Uy3;g=0k?t/v Z6u匜t))!b%v<3HkbPIciB ,Q 2+0̇#~FNL(׈F"FW!NݣVT+J$L&9F&!hxP+A:8e9o?Etmz"ҁz!zC Li8NF x87OSDoX+SPr A,f.B G'ZW5+(Vܠ mDG$EQ)nŪ:C0X(j?E Q!p=oE!y׹ W`8I<C)#QdT|ꌬoТBТBZstuA!)'ݭ+;Cp@tD)g.r bpbsY2#l)m~d`cNSiہR<~Px#_tCH?D~lF 0ZjB|3(ZOs3"Wߺ P9f:j!֝w+H|*{sPލ.v{ B>RE Y|]bZ-׶ݩM6 2bxlvfLvfFLQLҭ& a+Ҭ}y6x֔f eҮ6aX0DƍT/\]2^q{'@آ/ 1 w*W{bz k(@J7oVʻSq<R:qL>nVm%ZO~1h 8=Hi:>7$?tPbƑJ}OО*qF>MF=*KEk Ihsy>R^^wķO:Km"4YJ3 ''U'FbQ^'#/ D'!;8,8nc ov"rAr/jMĢkAu{tL:OjW\"hdb&݇I] cRRMָ4(i~>Ŧ1 ytf;珌c_̂^4!~0ϋەW_MX9v}K_,CW@8Ö3~lǣ cWtlYq;,`N/ޚApdyWu3q$U*qExk&Vɿ%vcE q\!aӽE}@gk hjbpPMB=YvN )1.B6݀M+I3rRz9)gm=VzA-XH>A`);+?ȓsAS ]@@ 7QLϊۨ(nBtkҌ"&mԭFP) n@ŖХRrWAԨhnMu+(=nXdMUT"M]3u9S_ }<(1VQ݊~!CnRR=[u+b04;aGS8@JO@gXЖtuJ0FJrPhjtvLҢ."yrD4! (GDC|r\W!BUADիqA}ǻ2>D4& <mNdsăN!p)qܼiuu6gFI_DDSՖ#BHc]>Ѯj>AJJhi 2h#呂w ftOO׀vQc}u𡦳k2ηX(`uی$F3ZzHBMbqSLh0p7g=¸gcѶT,>)KķhZbhs9p]-[jx(g ,I!()uމ|_Ia:6a;?YS[p<`Gs&B6rUWr'2r>!BgN]"!A3_\Ԡ9,?z|@)Rr^1vō#G! B ҥ\8bT\^nP&!ȅ٬ 6AcB*wgjz ֧*g!% y미yL8i4 c7 uqD %9&pzݲƄپW Dx {(|FXenA1| aQ~Kvnh&(*?mb66cWt/CzBѸj6o(:trs&[2-g3lLT Koʼn glWPWlx~; $T.qy5<`D8xHyoErѪ-޳K_Q;k3cZ͙_e94yTu23#Jޒ 5B /%9Cܦ Og+ 50KHn}nRzgT\_gu4]ZQ ̀+E3)+y X]gk$ fߙb.sy n#C'ⲬDB(;p%@HD2N 8ť3(r Ӳ_a@$s@=|^p,xS{f5ກKL!/8CCljd!'j'GY<̟Z;k=hSYV_S49h2Y|U3 1 YbR?IM*(LA)L{8.]ǣ9k6?8N?4hJ٠A,+)+&P֧]ˍYQm\xf&,+^\ PYަIgʄKHYOLGN#nw˲CW&íZWd3'o$BC+Y'WvУw5?AW!fŏSCW(^4 ܻ0=+IВCT 76G]q0rR)boԽ#~A (KSO Cl{v .-^7# (JOHށhq*0¨$4ehP5cފ;p\ ^I Xp'TVx 1wܘKN6A\od*ۦ !#zb9/6\ZÞ˺ΙI]Zid kSɠ=2p}*!P< (d4ePT Ď>C0U qioYg%fiʒk| !0 IH33qWVb] T;ϫ4Vj._ J^8OiJ c3{<`ŸyZ'cQd!3_J3 8#`>3=CqǞRvY#$w{i?$= ;h}.2hk޻w>_~kCԨ=6YߺBy=D[\:L֧ؾM["Zq[<%IE0aєlP[h~dd@*Ӥ/QaѠI )Bhk.?mvtȩ [^QU^wsg:tUESqtoN_T~\jȚ[NC+E3P}9nG~7OQ #$?6 Akؾ;Z>p6hZd~܍Egkgu"!p%x?vDbn%yu7q&FMhV"a-E`ݝ)ӥG385&! E* 7,E\ QgAJ@*tMz`ĥy yp'.OoL# Oލ@_@i]qMMPb?%.纠~02S1I K4[(_mf0$ pXYKR`Xf*]!EI}">Fg|=lg365MOuR]hS#+m>>jͧ}oxt|o,PUj/Jkে2ui= q1̭p><;vl[A6QNMtvy%3$ƔWx/W!X:"eak4!BpT ˋ2 hGlEϗ x L)TRsZ9A˰]Z\@|Āqg35f*2Zڼ XkpG$yj_q!"ֿSL7ỞRl^?6uheQX OOQβ>uɧ!fzMC랆V./i j^d ;?@׋Z-m*/A퉶 j]2[?vТw&eKnad3eϗl+}Oz-/5l"mDJm.!Gf;YUo@դϛrqkm9&I,GfC9Iv\9|Jy zx1,[,x,¾lX$=v'ԖZ!n$C|\xM!{OAef 䞧WtsmZեX%SҳB*m#҃+̢ 4GK#ewNu&i,'Hg_9kLjLa"1vƾ _0"q#r2y>XuNy,娋 lbO;Pv3-r>IWF#v6.;Tgy3]͂Wp\wJ@9ȡ DLo[A!g6?w=o"|z@qԜ͞]k&VhAXWi&!*ZzNrHF٠S)ig5ћlϫ04 ׶7mgy / +M%G;g>]CKDHWޮa/js7}O/_p+a%npx´~ Gu ܏y7i5Wnҷl;dӸnYtæM]-}o&r9c'nÏ?o-t:)>%:7 :2=+-+&mEq%h۵Xr^RR7bgC{Nn)9]ERN&Ӽ shâCG$Y"ǕYD{{XnO#+\ n"V@UwO?2l a?&]b]b]8V@Z G4w#߶pn,BAZf ǢsJl.sX4wB!&bTa4QNwkk c?:MrlYWpЧUn~< n7 tp=PqQ CSFLs2gDFxcRj|z8 .~^P?#D#t#hkW <ᷮЛ],ؓ:Inmd %7jk<3ܜ|5d Ы1θ]03åiZHΓ6 `d"2YsM݅ %"l$*Qkπ$h8ߤ;Z"dZkxpo4Nqy09_H:|PIu-ӆ^>|WH߿.ngupjFf貎P h:O| [\?HӁԎH'W:Ԟ.ĪH3 R hw]aN7-* ٪yl$D'Ǧ-S) Xֳ$(X=ӯqnwDxΘ̪%*շS>1n R.esEN̓Ha)80r m v4uS%PMK9/7ϲ 19|xV) #g7RVhLֱgnY9e Uk=ՠrZ\<eO&VLt qG[YfJ[x{pRwCn k\.q bzV_;ЛQ@kb-Nfxs;U4h|-U()nEmqlE?hsl1PX_ Ca-?ql 5IʺAml DPJ^x)W5H@-9rm2<_s1?h2%.&=?_׃Os$e4mO$ֹ4' ;K0TcY%ͯ4(.lC.h ٠iҤZrk@7+J6\T{TWRNp&# X{· /[ur_r}Yצ (Z*|l4sibugS@"ǾtLy9H׳i;fk@7ʏ;b-WLOϊ;.h'.f C)a!'dCbhz7urպV벽&ƭmpCפ uD ? LQ[!?է~B);BH)k*aެ`oA7AyP G$7FwS},y0 Π* ĺ^45_yLTXv}p NGi lq7sNCR.Q>IC+9;re /:%{T;%6>(Γ^O {|퉛ORHoΈS҃~t1Kcؕʃ<) P}Z˛0P-㠼[[68b&JA^9>\{y`@7,#Bj\ᆶk#"Ka<ҏJ?4'<Đ L ڝ\ ;n֫UAc9-+~Y0t ^˰h=-[|#) RHWz%D>)xpj^j1 l7%Zɮ0&99Ϙ{J6ԕ0r hsypߡ|-0͐ @ bAD= tZ=b5s9FOMsyVz z4 \*XlFpv ?7L. p_ 9'\m@%fvO VP_ ɹ:,.Vլ*h0w,vtY1=+=GI*29"튛'EC3PEvKI!2G⛿-o} Kf "0Mo ^!4&LS#d3*wy_" _@v.!tOb미I܏ۋ~N2ݩIp1kSjƇdK\N{rymq5SY7vcXl7iLgynϐ㡍V7³nF/'qm _Ԯ#"D$v"fd ㌘z04u 6S(k~f'd|Kc˥?[/Bٜ 0"lϤ{TW^mevۀ?BMDiC!y X>~!t< ' ӓ0m22,ӟ㰚zҩEs^} ۖVt{'W[}|Ok}<_bKpM]ɺn=k1܌t=[!4هq9ϗYs)ZKrrћz6c˟ .: (wMVml!mI,g3: =ξVw}6ipM ]gMw4,GK9,oq >?\kc>=YbZ7޸P< h.|7ՃߺBǬ|p H9S؞EbI;"cmn@Z4gFb) #;8kOJi);i#F$bB+af\麡WLh<"'$'Ylɺ xtwcMuerϑۑJե=GG"|$n1kaS8hk_Չ/ ?J5~gvmRi P ]Boa>/27?>{(m7z czx˷` Ux]{o>O+g" Fml7AS=oזom{ O!@[h2Y<@ܧVTZ& i =+/f7Nd7\b{R?b%5Aov32|Y cQ.b~G3WOu߀!~3@ tQx4i=DM}ڿ`Au*z+'c!pW62zp ls{>o n49 øK|Y7qFRfBۮ-9?t~|_m&qe<=?_whKobP#ؾK'=S2[^jBs > #}:+ӏ C6kBeQ?uB*@,T jFnt~ggyg?֊WwBrû_iL[PiHl*?AzT$-%ꦱb& }HԔ:Ag9D|^a|XTv/==; ogBpyKx!w$zԇhDӃnп@E~ :tj"lA6n&~rKuRn[\ߺ?: 0{=D&Oju[xR˜탷(\-? =D9'Z+uWҹwEquoނ+hػbcnc{bذ!" Xc 6.,-;{503w=ɜ_ ?ϼT$řAqx^ӏy#0\unűճҲbI܃މC>_Xg \NݏC J7@ْCIR,܃cQtpI$GIHDb_Q6(I(TCL9{8(&)ѥ39A nPʫ%D!>X;oH>wV͝=t{CGj"ڷ5} !/=ybA| C3>:r1l4>RX|$Ɯ6"p"a(F&E`(]g%C<!Z H(3~hz BbP -$#-Id"~vp2eFh;ƌum~| +f'R !OlGB1WA..=Xcfːt|B4W[W,_/PJO:oIv]6Gl'*i4hﭩr(&nSfa|NљiJlfy䨼^R=zr"V~a61P!]xĤgyɄm_"ū*)3q'47\4.n#P,{4rc6= 3} ލ*aG=xgҷmwUݦMl,_':wS=O )}:[ULwSq܋*&sJLd"]oҵ t:;33cB ^ǡB&}P"h7ZXI;bfnu>qDW>Y<ڷƒ"zz'o#zm~nW8*{'m=ߋ@6.l4,?P>ӂ` |K[$޼5sBo->c*$uv-|7KՄ/?ʸ1NxZV,<=),IRL9BM?-+.U\)K3,Ѣ1t+C^ [.QȨj?*i<=e]:aqއ~qg3RC1HUbѥ!C|SHX5?2~DtƏtF])|[3 'DLUL挧|rg}bi9 ŁLgm>FeTH+@ŝy`\,8R<=McfCO_K@9~|狫Vh<_M:qRϞwbG/:/FEUYwCݿ3itkJ *QP'IpԹK5^ L ;i1 d8W8n&%/M^A~Jp>YvA܏^ ?tVen}zUr>肵;eŒ.lt.-U8jϝK ֦A%Kr@t)4,vJ"cBZQa22=~oaP-7o#8jD8d;6s+ݟ[b\s?&DEpqQI8QnW!{BA. ll'Ȭi7撷ip|a K"~R0i zHvk@u2_kb}÷BiH!Jw8吧'/L E,۷ieJW4~h-K6 ,)0+9b%ЦA Ӛ}hӠPơHMpAiJ@=xF+3gD8YaMqj:nߦlΰQ8v39~m ZhΆ(n Cm!6^14H18lG3 VX9e}mÛ4sg]qV0tޫB1-+t1qg*?qKRoѦ4!%qbi>.h`1% Da#$!k)ti88%'IJRGf]>1 NZ |]eYLYΣؒ0z(Mhwb8&:"S  kw҃x'B4lPȏNPrOh!c/PcO^_iZ ODd{_eݿr&k?ә}> 'n\^(cxry<%!_w"善Z_^VbV޾JGL/ƂXЯ_G Q.9Jͷo7pS̡TT(X6jNkQ3<&lz#'U>էu'qU\5jJ^$25ݺQqFjǢ\L5jJb[(VƤ cE/=j6QD.MZڶ|ua uT5~ ILa2N(R] 8JpbZV,˝JH6 xKsWiZ(MH[.&`GOFu<$9;rڧ'"wc0~#b^N\jHK}ݶ](L*{w9=ݢkr8"c$rr/[g= ;3 aE.˂|战C*ئT>-wCR[@r݇}NtNuOA"iY!+jL9UlO|?<]i;؞: g'犙4bb*{٫OzϵFu 9_]i;k,GVq@u{ݘ&᮴* {/ XbeJfŬ_@B{~O}_v/hД yP2Bvj⯠viiRTd. }hI6 "=wzY |ثY/dcKS$S4%bjCc":m͌MUx*p 1ɠ1ա5A0`7#dSӾ8}] ogF侥)XZ8~BMK`0!4Ol-^$dt߫HXX,~=nr,Q<'~=VB2*Ysq |&ON -uZzNlU7THs4Xp[alu+vqifz/փHйttFשU3,kQ-:Ly6cZud1\i!ʔ JL;_wTޞpw׫l6c58/)㪐?GDL7v?Y7:$xĵk[Π/2v  Ys!1!觸_+>"FEQ!}Hsl 7*Ua*rc[_#Y< e)<-i#GߔĄE31?6*"F XA>5#T "X-:"j' @4 )W1K4^b )RmTqSVBH!5$4& 6IJ̺[hQ=Œ.%1˞šE; ?GnR^Xs*̩崏Y *6صYd%X0&8%i2 O^1UH_%G"Fܙc;< Bt<S[j!sA|eBhb`ZdlicrE`ᖢ; };Nw:^ gԝYd羖+OVho(`-͌~ڜEPy<@u[G"- eݻ{qFA[[T*?;T.׃ wC~iId&4IL?Yx2b`}0Ka;[0l%I KjXh,۶~e^n)$ø6 zߗ X}b3!sWH7{)M+U 14ۏJb6@T۾eֆ턈 J]ݗO0 IytG܈3v`lGsiv@lH1 ({Nx*(ھanCB؄_A±eoI2Vo U /\\"6Y5h蕧}鷮X~>_3ty4!^r+4u| A674к줔b<3R'B!!v#)GnԮ-ft&A}s/E?ՓGVBDWԒ/Q\c$W`v tx^q u1"j-})ô| *{XU]Q2=h]Xvn qlj>%!~"BfW?(?S5b< AhB]]&$UҤʠ[TgwЍ\te\x U2ZZ1M~s'-?鲺850ޝ*oo7C ΈmIM'>J!e4N{3e]a,MٝJ+ G(NF8B# Y8I8t3:q3WUD̖]Mqpp3x`u\yMd%dĭ+|ݑq;jBп֌Oi$uǍ?g.[8)-+mH)gAH!E j']P0Z_#V^\xFx҂KgO!L에-(*6/-iTG%GoV@]yOKQ@Oq˒<4;s_l(i4vQ\zqKi)GrO~"l2j묊Z?hf価ͷXqg&[OG K<t19NiBQzIFh:ltU)Y/312A3.H>N/XqyXfbi E?*ZO|Yso1\|!/a-c58)>?S5m@891g߽!WXn Kvm'*7aҨWC"^`E*9: *n^H,|yqᑢ\,|ۧ[8tӇWsj_['9+)GJYKA A3HMBlYDi >-(0_V$LZ)GzZא"/jr5LZtZ!Evn1PݾB&gJ9S*8dJ86ñ! :o:;t,sFAK`B@Ǘ6sMxak"-1HP&qrZ00Qa_2ݗ1b~I>(G#U!pMN|f4kyXLmD Ib.J!lD9,)O!G#T̕RVaH6*Md짘3~nnS]l廗NvWn`ͯa?PwRg^$")9#d,7[2q$v )8|Hqu!?"z%;q;>!ȃ6uʹ@R9}ٹ+ެ_p'׫tX> o7(7*%qܠ-&f:3YcOaJWok jULL-g6AUJhCx6b&u*$o@RB+7D3m@=P0:Y":~!4NYB#H{!{u3fٳ/ UJ67]jb7 t#/e-"Q. S? `}D<$O{%]A|RR9-6wA9}ݝIR,1r3 Pøg}H2`˧0'_z>\ 7􋫲^ޟ\p],Qa2ח 5bS܃seǶ#+q&weqʼjx|\Z+g}$ H>H̫%^u}@,NZeŒ.yU9q;&*,?嚈\={ۑ3wHSe (j{A jڋQ,_@7e33gd aQ Q,g*WN q/,[ ru NW!xY#9i<^S{(8oPu"$ B@DAz ΟViY!x=d g2D@h4a;D뇿ێh1ʀ2\ I"n`D&EpSڤKFr#D2Sq8k@FxF![Nl=f=" lparRK$N@<0WNY ,3i=_:d7 +V!*Aד@3)Yl-67̓BDkit> hh}.ej#8iIig[!lC7yDr ^,'" c<8d; !\ ƳUW@3 m@}Ͼu3_=";l!ʔ<ݡ.:2Nf_ps8Uv!p˪x [GżE7s+7Tɽl_ _X5-~Kty$ŕ_\Z׍iQ=zx!=o?j.*WS4C㧐=6ە~ kijǹg m{+,͒P|A8*LQ7>˶B؉ i}x', B筐Ø酊ԟ[/P3'C;?P-ޫl5k"La z-/E66ޥ#`^tp{ۙ/G%8iJ[1祠Q{ z}bM@z}# yM+fڧڿ׃W6mwKPu%!!/~ amO"tD$/N5F6,b”"´<_4@2 QeO"e(crPc-F.G&?*F4:F _蚵36nNsLp3Dc Irg2"|ډh2:!vpwBAbċK]!SC7m 17\ z5nEPu"'yTu)G\}I3Q!qwĔ lv01b%EeSX$wqLKhN"Y’"*vP;7TOz/n[N12b2 ,D")׳J _Qkse8"?sli)dx7QN)GPZ P'np ɻF][ +Dl'g/t* )ҷR.o ;Tl LEPLg"t ;0Bk,d} jY}}OdxC\vlHBJ]=٠_NZ=Ĝ onz"Džay>R?^] .$A{kцC!PHqヤN٠l"RҘRh4nTs61OklP}~_})e~nitt0mNZV,2$[BMv*?G\ TԤe8},*zalS0%"awf"RC%G8ޭIUgOATi$2$hQ!ArguFL9/[VUChN ؏[ P徕[؇O"Q=ePuxt0Lʀt"Ve7`0%׉PߦbqN@E3BA3 ]~C'#g7DwG0,vW)s4G7h :C^6cqPGb]+C 8Lu"F'BLqo~K3Ln 1|-^P 3ڦ@5suBđ:;S1|_ڼRlGW}y2w]ѱBӸ? Mrs:Zt5p"$웻Py$=ou럝@7_/UOɵc[ ͻA3AFK}sf{b43wBHܙb]UqsŬ"kg);&`seK?܃c~8/ 1Ŗm O|uST/"i?")Gps-窀ǒJKr vo"p(ۊ v?>4Gd"8p$,x'P~Gm$W|y}ۍ?VڭaՌ  މ歐 !EDr!|KjF}=M8}"5Eoi e@ta@ lw,(c+q1TH!H- T56>KaW@LK5TTGծ1TT>Dh]{YyїTo8a67ie wg{}ёg=Fc'/۝PH8DBf$9)A!/hԀBU-3YZ[1n+?Cۋ{AէliY!o$]H6#GAr*:"mEX.ƽqkܙ*/IIXxoҗw$@(;=]34\q4mh㔡~皯i)D/07J \@`\ՙ Rh&/1@!2^rG!ybEpbR灶Z?<v6$CӇ?:(6|5-+i$Ӱe8/eh> (R{ԃ$2F&œwQR<Lm.Ǣ-U,TקJ`Dۦ׷C_rs]:WPw}M Sʸw8D(7-NZ+&T!'xr3mL h;jsU,T)ݧaDK壉6sn4N;qɐPy<@ǎCf?$S·;PBn3Cߺb.Q,l4_C%p oOTviFCnJ 4uU 36U1Y\8tP'%tP$]ĔUŸ5ʵ D UBԲ=#|\dY%q[۾X}Qe3 w~*麸#%иprpxT=o o?n=yiA YU@ҲBH_t}Ey$Z-Jobqi4!v(5plYP|1o;,R!ZCE$8m ,DGa(55PD#Q_u!Yli<ˁr,jb'>D@1UgH s̾ i}\@۫ | '<>!(fB6IsE҄9qi`ltF\"P6d9y ?a0x6QM$}Uކ'89!z/l18V KOn*mӒ6I]9Kpq'P ΰ-pMꐉpu_ZEf۾eֆ眤GaQ o pq ɒö|bk~cCHR} g?fܠgQW>m:zt9}K6NRd$_,OgTd́r6@dӝIR,SlB[(g. dgRX@lCE1"amnxP}b('"Ӧ;ݤіZ@ȟTT ]qӁ%Eb -g(\aTSnKѝ1%^BWmF Nr5= ]~H+}j8f상Rl&P|zbRFc-'s^U> )kܸZ,C_,3$**ez5Cؙ1Za#]iϔpM#PqSpߦ6 ’!؂iBfW?hKp\ KB8SAyh.vK4ef>C’O[{̇f &89 CWVt#cb!-+ts6,Saj4k*Mr KF.C*X_#)\PaXx\ł!!sáFl{pvݫuha sz \-jX/F%4  >;m3+@\b2ǁHł#R=D>|M'aAb%白d |{aHq :qfrlOG1 ."bXPf&Ϸ$} ѥ Vq ]xBS~ C\qjfzI Ia0(Wt?W$xq 12zuwNN08aGFq"J90S;sA|@`%| 9˟Gá|_C)sT`p_v- I !}uΧ 5mo _TtKH!v=-{Ac(yZ(w$;6d659? U}E$Xk1eJ+sAU +\W͓6O#E <Ox?pK`⍞3;ɶ:MJۍԪIs֧?yxË^{bJЏudo]!łIK-+)c}FOGDKC %9*{ 5VK&IiP}BO@DR#Cnɑ4 fsƴi%^0"LK(\bB5*N[86']n.K7!nqK؎|4SY?:@l 07 h %.p>bqI"?)خ:n?]M3J6ǢđND elm Z|J UYr٨\'JH~fW.S/񔹪xO/gڬ=69veqF{&c='!vMpJ+]RR,h`LFFD(c><& myKCr0|H[HqS3Iƀ>_R҃ܩ|!(xvK>T$ExIM҃NwddRnT3;K[g9-=xm~<8pؾT(k9YA_ydJ_ bC2٠IʵF@D2US4eL1nnh(*eA}=".2nJ;C++lb|maB \D> "K q-<7c $2?{ ,?U t.n<;w)vrLiYow*]/ESR05߾=tDH )"TR<㹝yEXݙ3Z`Ue1ˬT o?&u/ܲ*JO!yp:OROsĎE o7]ܩDwb]D ڻXxǽ }иj%N/JzC&O4*I2Vo  sy076Z;hC?xbAYB{53#E&$ `/MRw8XZ!> q!w/?Bw+t?TBF)MHXe\}D wmVm/MH%1gIS&>nywʙ ZC-vY?N!3: )/ Bx/ [qr_")29n3IiBRƖBePdi Z.9".5rxp$ 8Wa|!ѬbKXtS,v=/Ύz=14`^9M! #ՑQB6k1XLrUG3#x_@"e6gf$֜vK֒Ϳān-zج5,s,|fu+.>x.Q.l? #olEVIs5ef9+ѣ,r1>_ v^qH04!ӛ%LHr@꾛tԭ܆DL8^=9 ._ܗ g]煑yl>P8Mih=G<YqFr1dh07疵eJC⛼ [BrͷO $ fbݼN}{7ex9vveݲTZk4hH!XWB 8"NUf`=Ey ;v/t)\`9΂Cn Q/ԯqIox@%5VօpZ];ƥHS;+N?;\ A=&{|w4]@lT b<eXH^40M%z8#&4zmDOLr3@ XU(6C78qyi8HWyYq,qB], Xٞ;gAL`Ѯ%)D{D8.^C!y(.VS6>;PA5iZ+ ivXŸ B M'JōKM ~J(j8p[)"ʇ4lkؖC\'܂cIU[}9w 9Y}h*Jt YW>_j[8nW!f4%qR?+|l0 ]pnŝݙWzXސ0ڧ[ԯ|D?iYʆnwL a ԥ_x0`(k3e>=$ I im.TҥDO=%`u)x}P0saYV$61ÔlsU&! o%l"-G>긐)6 IJ[)"si|1Y*M< &^C[ݦIiAN_5=;!6\Z6߮,݇ox('v:0sз_|Y䩈種_9T+[^{~3'&/}~BHV "y{\4m߰q|Sziٶ'PlfG$6TMUBX-ts[{ζiY!˜GKIv[ (4$Q>RF Paܙ-}]2q"xӏםv#LP?wop> Ýog/&|%!WJ݂2 ǎ{ :g4j,llп9 OͲnhoЪ:]ZV,+!EB>'gXߟl@9R}Ԕ\:(4(B&C1E7_^YXF<Ӹ ?b:2! KǎNpa{AN-P=Dm!|7gCI}^# ^5-w;-_BwWt{W,i#O9 aڼ5B~ 6;.t_E6ݽS^=Br9!҃/YvGE-&$u2S։Pl)m lFQ|1œYi6&Prm%'E-2IOWypjz%\CL~`|Yt$;m1ȯonVzh*|R6v_>m}ZMD,$cӂqo'~ݞIKesnAK_}RӱB96k&uwDK!RBMBDG4>_-`{aeH _ZذE$,U B7>> M+6~Y~5xJ31F +iG@L)Y_ ?9Ltᲃt7NBb5N!LY?h3.F(#3k sU]eבI4W!L9>"'Dq'+J%<\6_=.[QI\r{BwѷlG>R6)G 7EPNA/z)[Jr E†-’2r'vC1MUJAB o-s?4fWsPhr/z^yd'‰L 3/^B9|@SArZfM :^:UHSž7ӲBHtNMDIY\\EjE@*{1r҅.EwOsqA!bO_FǼD"9) 'w1݋5?gߍPޗg?o#_Gq5>TЧ"/m8ŽFTcS4. {h!L-ݽ&2gd]%܍_|77H|l${mklmˆb #>v_u2~U(D6 loWvA#3)tWjšgT }&~I'ۉO?iN_ \oYd# ,mH3>nՐ3ܸA}Uyk{v?P /jz,f-24uU'6'njW g:>Ͼ!HV/9Wr*0$[(By9AdkBbe:=W֩WTBt"Y&V9QQL'aUtv\Oʂ2J6QaAmPq[SA)]oxZNtwdPoeO6PՅQgA{CK>~Eud*ϟ0N 2ǷA(6G|q`T$8IC9mOV, 'EOV/|aqFߨ+4]Vr@YqLE)OkY)iYo#'311K94qł{b[ S{jU/C1y7 "HrD'sH3x2u`LTȚME ,C)G¢S\'R>bNE!բ<NpX($@ٖ։\X3щ $]ra IiN,Bo]]t-kmHTfhBkoHvν:½ڜ{3sFMÒf?1y<@k+/$[_2CCfƎ^쀨GCGx7r$F^|5^ B7y/[!ﵰ^z,T.U%TZxt/Vv!o5ШȽ_WM5kX(G̣f{v3H2.,ѭuB#${>W0>;Ql܉lJ6~['"f9&{fBLwnzۙ@w; jyWs'Nf!2poO!;G[*xlB8ZEVhBbFgLHzE{~AF& ߛO~]fݧAF#Nd#%eo$ش$"$ȓ0dzYEes723AfX?7Ko(7vP! xe|'7Wn>T W[,;c7X.$M)&M=M>*>}|QYCK>$?@0~@~66>a;2«]2 e/22{a ce( zӃ̣nWns+6CԮt yFq;[>*d}IQarz}gp F}l=a&ZvDʍU?΍KaQt5Ä5af}Yk!TVl֦@@8\!X~̔3[Tm4>226;y oIvm/w _JSv![M-AՕ,!iY!K ok!`d!ɗ#/AObds5-A80./,{kqgaK)̑UHx a9bU { n߬ Lk)b(u ZPcBMrT])mUh|$.w۸?+ؖ/qxH8ߓ|b<*ږs4xv7ff:+^q`~}7vXҷwڱ SYoYdD$EBKm{91'},z:*̕[_cEjiL%^F$=쯽ɾFDUW"8 y0qR1y"){- ISÏ-_`Uk.*%\Y$g=Wb˴SI 헅N'_YiDJ 7m="|4+q3?[k,hÀ7K qŻAq%ͫgp$_m5!YUWvl>餭M'_|&އO9-"wfy*"3*^t>_xe Wd隵<~Lj3CR!"2Gicf!m O|UR\:D vebx\_mpB`r%Pl n6~pjE|"sml]%*>v؅j<՞_K9ysBx\se.08t$%?n.݇'m#Єi1iahd5 dܴK]> 0,BSv5N9THޤ̿]_j PQ VQx^h(P Hq` = LP3#ڟA<&'Op(3X/fiy&'Ksu?t4853:,ئĜ}bfVpW@8AbȮ} ٥ Sf/-^2kܛve]"Z9g!ky-/=鋄m<O g=#OsKRl=LWp3803B LP4 `bFN:-#9T"|FT:Mc-5m*"r1M@T_ Q"7gY/q܅ Rň8p X@"!4]и(%D7> z!nn;g =,05 7;Sl9@ 䵐7NQ{1oGBp z9;&umKz —mQl&M:0|%/eY^g8a*ۮ"zjۦWzm>/dGKxb0=6`~" >jk]}:2l: w_j{]좴 x+P4a vMhʎ׋oވNt)ه[,7э*'q!k&&D>pc}~K*0saM!٠XJ{{<{'.\\9#+>9WOiA?iN_>|:xHߺB܅MIQ$}uC/&IL-&hBۤ-v8Fcԣ Ɗ KԓR=0@|yXVTe L,TN;br AG 1LjpVmaA~rI+baP?NsLp9dF+s8m]$[)nMx(LٛcM}ӊ.k s ;wʵDc@#kpKse?.#AF v܅b?=RrMMw%x]\]HLAX.-lg;Ӓ0莈.$wzҥyUB' b 5sj ]+Q\,JQh[% x9|m y^:NU|di!ۿ(6ٯ". ܢ"ݩJb{q nay a'-Щ# yo.>n9򃜾܅t`~sC? :!m - #!gCdrw]V" )`(j!(DB ! pgܒ "w?!T KȖSMHA*9+C,$ͫP4i$ R` !{A:ߴҗ xf#.yoWֆ@+IQ5HMB0o sm U{@!FE'}##HBukyXmٌ  fFj1~@ x3-fFwD9G8S*6N*<nXh\ᗇxAW"آ6?ٳfY ml3~@ i@קޔ>P_$OyFvbIM2410`4.V>_Me՘3)+/d3LTHdpκKυ躙g> 긮vUJ WBJ!p#‘ 0+8.m 8"IDh[L0$$ dAIx Dw."'{uӨ }6˺%&$tjleE?TlYQ!.*Z,Gިh6*zsl ?p8"Zvy2-n>/.^ 9:K_싳:_qԽ{w0nTMGfsswj;^ 8gרH6+&<(Vp˗D>{k42>?׶J{_HrdrEHTs>t]t,8?8K#Q/M׬Lir ~)BFCR?nYy>I$Xҋ$B5,iwS\(53)2 :(xTNZlF1^xfKX\뉨6~k</ݷbrҲ!RTe*)գ}a W^!m^-"f,|Dʔo#H(4!:엨1+gMR:fe#̧06 *oDQG4bʌ[!ypJ!F iFE5V"*PmK}r-QG[ӥ\0d\t%9%ܕHk#~!H˗D>=;[,Q^WN ? 5k3?iiT[W,_f(2"6ݮ&*Jck9Gl#?s; &Vg"c}H(*R= ]!%f(^nۉ$/:TWP Vn<ͩ |\vբ%<}9O{T3pn\\ 0gJ A7 s $ҵEB4>Q{?)2E䤔Cq#1N,k >b7* ͪ uu:_ &d7To\x'-+SB9E )s[*MH6; h}5aJR-g,=V;.Fb އ"#kyU1gt}~*D/fQP~8 Pt]q<8=mAњU-D:#1NU}g n9kVIֶBP;P$maE$I~|FbDg_rOFM:Eko ΃o/)mT=?w1`!XYzy\}ml{ix<'sYtS,v0ZW _P揉pwR<(^r4vžM8Cd>&('=/"p"|bךZB\T,5@Au VCg޿O Nv}: |0[PI F.gv}/ $LiBbǶ)(M+^eJ%ıje[D$^*RdQ˜hG$Q#UJ *%DF]0 ېjR<3K @!n 3D(Fh;T*XȷBߡ.|v^A"' r@9Z^a 4ߺbTt 5Spw#KI13 )D\RSrXJs,ܼbd)T>)P>#L wBm@86ɢk,"Dd:mzl|3ξpav>+~Ƿ0 YJrݩ,QY玀 ?h`RtB,sOy!W*꿜B\)K Kv!g!p] 'm']!l"G(ءB=c`+V܆M+|LQ$+, MZ;#誺D嫠u pE97>NIi; R \ aX/F:(ѣq'G~cB1kQc-y,vt^ 9jZ6UQZi݇ fRas",DaFz`*l>:ׯlAOj:m z0|{D<AD$J"EۍeiWÿ : h{ttPѽs9FExr-?o *q'FN_ܗG SgFN rf0HQ #- "nHQ!#!7FΙ[O`6r8܋hPg  +D ɟ-6pU4rXryX"pɹ*C.+#:^0v!Fp!^J+$ͿmPSC'HzkLA;lAqko0䜐 m:闖K4rJ6hf+.oPE;lBR 5gټ%1q&b(3.:J8,&"b.XB PsiT,}ejNȇe惂9$Ps]XA!)ˇBcT.:*$,cK ixNnk|@hn6Aqx^`xPO@ܾoyi:#}+w?Zȕ=Y&{{Ol)"XaFdnMeLȋB4ĻAB&hA{?Do{rFssbH(r'qҸ8$Ǿh(ыz cy=_XL Q{D=f&"/G(5eYj=Nz-e},G.NOj,%7B 1){1~B)0lxsz\ܞ=10},fmQ^Na;g=Ypr%q'2ܞ{RYJ)DvA+\ 1^F4;AJ+^iY!dCc.`=~Q(s؇Zq[P\-EPr>K'`B|!b57z4~@m@l]Q;l#W7yB>Ƿ< _ǢG"zJ`^҄Zd]4b@'/t8~ݽڮ{iAg(h z;N%uC>.Px x2&[ EB)CNlOs^ -%ED4ZLu *ƠڷP:_Iy3zΌ^ مR,pd)vI[qnE.ѻ]Y\io):"//GY9|*Y%!1[[9'U:UA+A_HXZV+.X>>wֶݮnV *)R&-ڙR0` o{3eQoT׃1>B}Yis%Jr!@m\V9űK -7̇{_[3N#z+]/ gl8עv~!=ɾȳ{*;;l7r}_Q!6. ; ~Sl Vx [fwh_j| NZ(YQn /\ x'9/%] J@|Icݳ~_^T [s*gOpD0]`+gA*Wb^>ͼv6dS."CŎNGc $0Fb狼ow2b($|4k"׳ވM:P0?{މ]A?-|JˊOٞN̂l, ?x1]&Qdf`Y\4qv,g|4{27?Pyŏdf)xn5ȜR-e]vg_#$-+eT 聗 (K!vђG,4!E$KjOEcbmpi{(I)6BKQя˙ "!J- <,m%q# ~E?zwz9jW!M+ADsh59 ɘWR;sgO:n\ iCsZx2EbxNHC;}8оG{6wPf`WЙATe׭|7?+iO$4*`BkQC6R"Ge 5AS}K7i~k^\!?xɸ7PA *6y+]@hP3z#"3"_Xˑ[XxDgn'p^Ex"v"b>OR{gB XLշ\Ir)>/@oxoWǠxvMOKP|#u=aDԖ%R[p{d!sUHh# "B(dĚ&f&(:3RMϽ.//. q˿ pWaf}@#s9eہT! z㯣ú LbӞBHS}zxSձݮD!}]rRM!\o**;<%غ_Ew4'7!7\龇ۭb'XOn]\%M|l}om+)7 q:2wKa)Z56mW!PBM5l龔['$q{ m=K4tOCt`0,|Ϸ,Ej'\?UુB$#aHRɫ0 xaGkD9 {KVjKπm9HOD:>1!ǒ@c-'7^*լyTk@H_C!ŵEW;Uqdsuȣ^` 8"+l M⸉T~dyKY1wlcSp Đ1:ځ  ڢuwڵtD][,>--+iw@N2hI]H E$i)MȮfjbJbLȋbISoYz=jySRp6=a~Q~,D~P V{!8X*ewfg <]`5 x/t78/x f͛g*UW%596U,ƋrG%t/ϼOyT t[N=h_8w,/ eI_ag ͜c-Cu#"bdUr-P.HurLD~O5VS cg  7ԺY?"?nWVΣ8?X' =N.W!-| M.~VIvq?^ PGo9"5 ĚWs.˔)ƺ\-Qv$)bwZ8i.е}?fWӲBH:_ C3i)KԮ(\IiYp}(,I 5 S9ܙ`1{e2͐46XR0vH!cs?2FLKpeo}%DS{~P _Z(Uw [/NUp>>+ʶ"p}jؖa4hD+>4InE4ӑ|4J8?(|2%s)Y il7g3~@ٚECn/r7hZV,b!M L.Z&yoWn4ӌ d̜DLc O@;S"_(f^RTVOoQQܙqmnx#") ^nמqbluDg*fnzml|kP/twS b̓˷hV5pBsAOq?s*5I z)ӥ\ )"*]n7 Ȥ;3ƞ^ <4d4cMW2|P%}oiMʚH0(NMbd(Zz44;UGc+JZ/>1%@Ĩdn&>/10-hę4r(JZ *pLO#D Y0u М`P|Y}ÛOv#Wyo5?h S;H Ќ^ >}B%BnFplc@U:.M Dω@''kە-Hj:y"0Ca"[!6K6Bpub_pȓFB?x95ĬsSTcjڙ'N._y]hi*ayv#% 3zn8 tj>p409%hGō= x /du\m@.i1U( /@C39$|&Q8rTvN@I\|1I2=fxʉAo%z|8q58ᲃt7Ng/pmU/ ڼXG`m~(r">Zywq %^ ~b6? #7-~p?%nja<|״ۀ7Aoܕo rD 9䌒DƷo7P#R!Rdht&89\aͫ0 m 0jY'JX_;*[jeBbTNێ$ O,1({NN!Fl3~[;|<~FuͥUPK _Vfz .EZwOه6Ws?vɹگ`Q8nn/*DGwM'x%qԩ@|% ZDãilQCǔI,K ][A?@ߠT/_7.fd iY:t$Df(n_V}h| DiB~h$) ,%i o}HΤ_aT(6!,G= ݡa,rxwwaaeƯ<8/2/C꞊zs}u#D=mz?9iuƛgDݚg_@~Wร0$pSM_;B^|%ӱXKWn澣AỲ̇X[=IP3ިU,(|BFϦ" *n߮b!w$pKi^$)1 k*ydܻنb);R/@㉬!$xbxW@-4rxpxAUC uW@s[MAicE$|ᮓdUNhcO1)ϔpM#v *lL>%??k\c5gTGrz!#|`ߗ\|%zH~U ARʵ -WVs/JC #O/KպӇ;sD#@Ujd]~mIP'KznsFb7)u6%M=mCDbPz$^0F8$I9J, QT'Ѕ))B)FkN9,Ip^8v@ve! (_i92eIR;&?bmpC3?u-;[{НkvgU_ :uvUM !}-Z4搟QX$!chD[]Bc,vjSuylII=s=Loqyû}U:t_"/4S[=zK%Azh%řev^R@.Uʹ88jspggtdpՏfsXZP8h4^7>?XI}f͜9&o:;KcgsCP]A_iANW|KSLnP)".Ej8ª IM7 b ) {)ۓ'Zyg;Q&y ҌTfͻڮhAURm](,83+@| ŕpDxCznoAKAq\#<&$.͓DJx^xkO= ?_쭇_oK#k6VUtgeH{h}Y..5p $h) I!PIǠ'%u XU.0?d(lCUǾ*.z/U S];bϕ鵤Hձ;NZ,P n|\2Pa>NCX{R ~\jhK/fk+Di߆Īᯄ6e**bc<4?Wz*yzzrhh˸o,f5.} /Mn{G~zXҥqۡ%0 8I ]w*#')]IMbqSX'F*h.Ialgop&IJ[rHb "ՂڐQ-a5*taP&+ݟkEW94Pxy\#tS<[ Q-f_ R}xCkG*c069wa.QA`gߦbwtR(ujDԉ2:E׬0ݻڤRD2NnapNTv<= "rr-x ;%c4F8I㏭=}HhSj;$컙VƠ+Y,?@s`@?}Iي@ڝFe"9Jq\|]! OG#b**d46 w+dQQ] E %S+ ˜L *r.Z42Yp']ekf,&5^ ip5Wv2M!GEuRy+"V d|B|"mvԂۏ%WCلJ)B@|/z` G`cߨ? )6).p^a"iEk).d߱\؇ܗ!xHb #RkەWX38 *QIb4WH+4Dr@1n/j|R<ʳ^EV \t言mpg3V/ަ !ВKg gT!+A]U^rⳞ}3%äB]@V4*[WiABz=IaJ 4}h\NtC3^^_ bXܣZteуA矺l|އggz,FoǺ z4Sip[6, :Uu[ 1v?z07ߠ(xSA;{PDrl{z,갡Vje #J3 0ʢϝ'mP>ZjːqLZut?Ճ1Μsc\/7;K N9_łh)TWĚ;yN;# Id.$)i kIXزƨ$EXz)gʉ j}Xs8THYN)s sOu&3CTj F}>=>>{:XaOE܇${w[w;W5" u?cj /5ω/|4Az>?5YH8!~q Ax:&t`U,(SKRl2d3twR4})rZD3R{⌥83YdWX/,7ۊNJBnISɌ_!}#Gut3Q{{fV9Pf\z||:#;^_qbR[R\v {!pfD[2৫6##9W2*dc6f,7ޏ_"yk|\gk% )-gM$mW}@-h:{ T}K6tD&1sB0)g7}8 іb9KCaKBY,\EO-H٧fyP)<\ ʮ9)gdt:sK,J!ǷG+mJ9&gG=\|X+_W㡜#BY"]j!{R2=Cckom׸(W}rLVݻpUR |&M~IB,.S YU(D K+& ++lbE-1ZbDX#0R#+!CBi#ƁjCz_dk&AT1Y U25k2Bv®zLQF=dnεsK=Z &.\ZP8*M)~ɶ"@<~[9p}A߻vc.izŝr&oPȿ jK ~6.5}apL]v'Xq #9m rInYrGCw-) eƩ at|A Aw1-s$giGO<$%穧i/͜IW" OQ=J .zv<_9pf3_lYexn P_9_|E{e )ά9S-l\oƀ/r9_˦֠wBBYy$% 3nV*S$Y,E{CNBo4i|Tz/XIH-m!voF^Y>;*{c!~dN)97jj߻6ܠs߬U( !)%|44@3 !G8eql )[:>_ ~GD46h\ c26Cyi. 06fU˪.W@5[هp␅(,fT ?B}\,Q#EdT|dCR$74X"9 4=S_#c]wP_ɝ)>P5m%n깳]B a(BW'>_Qɸ@u6s n afylm7_׈cx]݅A=@A#yuۛa*2)A5wh q|fWn]O3A|ԯ< Xjgvܹn ;?oB,[[0{70T%x 1+IZ~3(3GrnB>3##!S}%5EovK^Q`{.wxh*$oJAyl އ&^ڮ{.;Pq@} u  +v~D|H<߃'/I9#CӱxAQ)QN&> iO! :_l7 <}~;!_Kl r5IIRZtQZ_#( Sp, dRfl˫1+ !%F(=55r2?0t_9Ou١)Ĕz ^yPz~r:=q!bܽEX}Iqy`QG')`p24xеP8LЕ =S˳s1K4QSApSBg./ӕD>k> NV8t<$nJHRsO@7s +|[nAR}-*7YsLXF`̶&"s!c<:gkbaK>M}K%tfk6鳻2腯ӲBHKI!I!8ۗ 0 h!"K #sZDNiݔf-#1yn.1' ٯ eƯL)GWd>1,`0g7SjƇA]AsW}#1Gez `!<nsUpA8^׼n.7@#B>BCFsX /|4sD~uvB @r3o+lf\2 ./(/C˶_K✤x&)^q8*oW8IȦh> OhAFI 3 yW)ʰc4D,|1Y4sJgKEb~O54N:*3q,to?n,ڽ}2T٤5ﵶèrQWlFw\A~wpٖ#[ٝi8_ XD'Q^nxx@Ҟ猊mK]3ð}`fqe`k7Μg*Ly^/䇾iY!˙/Gs4kz;+Ƿ,_2HpQ:`)\-vjv6%%f̫0s=x4(*$=ŀ7{B6izuSiӺBg$BuT5~bB00dAEZ)}MkwAM(dy ?,+Xw.HPB8$ivch{Χs6=Œ>(YLM'1S?E҄XQ0>WypP 'AOϗK.xYʆnw;LR+6dpe?F>g!<0$kA6P /[g=I89 A9|鼔,K%߸:dwvM<n5i~k@muiA(D ^ĞobNiB#8ng Wf,Љz&fȈ3B!ЛSc-'iHLA^}F_mo&YtEL@ipzd#77W?}Ծ-gF4^9q&t6Cј O"+CR"B]GA ~[.jhTlLXMZV,M{S&'™G)*Ѷ4h;'ry1e<7ҽi8ZRskxSAFyڙA%d 3znnurחT[ i*a[vCW8Sa|y.6w+D$+C %lG>qYg'D^ΡQD,a$ p zkiYKj8 yHz#'Dwj,ټ;yE,0Rbf”Δg>H5/6J*&bʁWF<$X̖jx\pPvY)Gb&2[ _@eɦqST" ,”ѸYxc..RO!o~$^z/~hkrA9[{F_:}W!wD o)÷#EG Csp!pI31:+8(|AɝJKY&(Q1dbP,?Bml[,q#u!- 6TZ5kwry+l$D[~7@1TpM?OrE!9o$q{&"d˄fKN5BRe†_n ~B I !]uyb{$!)B=^tc>41[iBqr0΂8YXqzLyZw={GB=bu=Pkyh~.&e>y'<{vU} v.2ٟ<8.]J &\f vv&[m Ub\}us@w ׌W/kWiA ;y ß%u-=x+~7'JaAaI*'cݧ5VAPU/J9q<=FP{BkyB{O F4{"?a_kBD1d% U0P)4zIwBޓ/Svrh3-;Єif*ǠN)j}FEܕ44*Kd UsJPc-{q.A\"ƪ㚮UΌ^sBxu Jΰ1|׾Ł/~3p B;oA/' OK9#"I$j6X/(Cؕ|;ylb۫`\/=_uH4pT ҁڥ尲m7}B LF7qŸ13x|fd@Ϡ0fcS^0TScv%]7l u a a1&_~yf\:'xi הmp?R`F9X9+78WyZ^,a|{&I+v%wbgr\NetT bJddxe=K߷gޘ8ٷ@d/]9[S}NѕT1 ztlRlɳǤJE[ک}Mȿ/eeW 1O{OtJM}q_f/UU㮡g3k+8;cďF\;ܷ2uW2 Ozi=}™ z " ! ޴B/ Q.kuw> =_c>߯qDg_Y;$ ޯQgW%]BE;qN4#syeהqql TOw^7⩘U*Ax&mMpF7쇒qg?qoW=Jڈĸ1ԑ$#.egw7|Ƚ? xd%n{'1څ6 /싦:sϗ!`K#\aGo+E\;UPО#\;fVC'OLH8/嘆ׯo=jJRHPٲ畭Khw-ծSS^V!ObTUzwgnW wى+o0 P1\aiߗ#UniyI_ڵкoOҮ\8DJ=t0<ќsYz D A|8X[} l~__^^UNMA8{\j!2rF!zWh_ȯqOh-2'"'+Sa?&|]?#dד]#Ͳc[[>븓i\ǽB_(zHݗCn{]ʒ._y㑨5K@u2!L;/65 Yw[|AKuz>J1r-mLpxKBow@);;kA%;sy ܟ]iFY\4ȠMr7Sҧ~#Eڷ{ik𙏳sCߙoN9-!ѽߵN4MΠ\yW2#⺁ʭ#7!p_zַϷ ? \}ȳmb=C\# PzT뻜x)jY"@XAWeA]"ԋ0GU=xYEstg}a(o:Mwl3ijU~>$I'DE58\ ǁhȲZf'Y~s#S 20÷ڛJD_5!ӆt ?AŪQgl,(0Vxr%6W(,{f"Z9T%C*L]{7|d:x׸ļ<^qYz^_NN;ר4Rk1>./!cyaT?|W9 rg G<%MB"ރQq@Go=@l}YYuVb(p=Dl˽fl׬uW/lfn/G=VS/jߝJF(zȧ>p / vyT| /?G-=֧$Dc3&:-p ZR^*㣘s`yy>1MMcDGÉ3ٛyLfuzHFUs209?E7򐝿?|m{j0] t$^@'5dd.ez0|8øOrR۲󁥃V|i~HEuކPĿ9q=g \\11{UҤ/ x~~ԲנxO:I{0;׃9*|s{M1Rh'q6 {=g(B=z;͢^xU6G.lSԁVgҷԏVo#@Aێ~uB5gw_eO3_CҲbL5γb&EgKO=bI:JNRv==19iBց.6 +Tge_}?+Ny5lSv9o;˜;;9}W%}Mw1Rfl)RSkK6-LJ|x0OPx@Kw$uW>{hyiѴoZ4ǻT#ݢjw7# 1=$I&}!9^ް)ck;qYn8DZe.kn^hm?Wt,S{7.av<+~G=OzzߤoUZ%5+Kk\>fb^g3a^79m9ߛޯؾ_M~+聺OYWq >eDpЧǿ*zK)ZY_y0b(;Yיzz79hw7=K+xcKA*&|]$9^o6Z֗&x&!߬$<dZax˔Kw$Յ۷=>]A6eu^?v#-Sާ|w(z7]g>p,ZU{ʟrK?6>#aປ=fRn݇kmᅩ뻔O{^x]srx:E8ߝFS?x{븊9Ȓf_CD^+NYWx }e|}-v>|Wa/*ɊK&@.O,B'.--5u,ooD|V2O|&+;?OjexlErgwF;iSGPmOW-c5o}ZlJ?uiƛ۝LZ3',0<[G{*gu|^Пq<J @Xuh;v>p<竷Cx {:=*k/k;-Tz.D_9QxYu_u))c+gyr O1 _f(ǹٱ~Xp<FޝqNglƣ>]l7-O1Iےk>tۥ/~v)[_bgmWs;՟ۯLϯV~פ/7Z>z+ߤ+i՟.qk{fav6Ҧ~D^S} o&/z'LLӶy*NZIY|u|1 cs/WA\cvU ˶9EiDf0m>Ӭ`[vuǸ'RΌwc>K(K[-P)₇s(SCZUrCiAÏ{(;f=]Cz'?V9lsIlxşbx8YYa"܂ğ:s1ßi_.vֳ8aOO?<f)񧩑ր1G_>2c_W 8GT.us 78>\~ҿRhSR$\k*ݿnΣƒjK&uj.>azc،4\4Y'$ChΟSϕ8>lx>#ezsq9_? y =M6S9!!8Gkv~]u@/^'x=W>U9<.s?༬^Um.ҲmjlÎUqY\8zi+e/-6 ?yTnkZO[l^oh{achKa –d;~X@tX<%04*tiu"_~O?y.E{oC^ګ(rw\p~Ϟ`Yy-à0E*9CKF,Υ-Ջ}т~[zZ鉏hf^O''Quc0$ψwا^6"` } ^۠y~ucX$b[,Em" 4*7Gd_x[v#Oȣx;4[V])G`Q gU0{YJě.dplgM_>WoXmJgS?Ao7>/Qq^=*Ў2yI_c?J:?t|^}<ٶ08[dAH{&@r%Ͼ3?xB:91_3;:عΘj}crH M4;]m׮FRԒxVǣJQ:wL:ڮ%Nh|;ɰ[#ez_1_Ty׽ztǑļ88->m~-wAuڣZwr<XǕ ArPbbw?Ϥ'9Fcr&l#ʸg>Ϥ/$G=ԽbVOdMLy& gZVwAq~=zs$^ֵe \ϪulrI_~Vפq;Zq4eGN"MFúAP0=K/O$P K(uړ%P}N!_/.(u9Ą] uf>|({zbz׷%~?Nwmu/'?C -/oJ%;`:V0Q56rx-;g|Cs~V(>~?~É=R*AxgLJ?6q}]G+^"sE-6W1|:?f[6d1PZ9 .*pnࡔ93iy<'S /3VtONyMC{r; (n:ו~<{Qr i ܿ lANl?rKRxh$٤ih$8 AzJG0- |8_,)cy*Gof(ש$Q?@f;s4WFEV~_GRD[3"{E+N4ȘlC03ϡye{?M?b^? eK} ֨C@%lӔ?=&WҔ/2OQAhEg1 ח XώVG>@œo]T}z fIY_Zף{[+?oQ?ާz?g߈ޤ bT뮀+o 8D{Ő?N[GpfQB1}w)yak Sa7rQ%o#z4)'́8`Ȳowjъg !~rmo#0ޒzf:dLmCϨ=S ӿGl<:_Iq2}v J>)Ob_c_iPf 9X4Dɏռ޽wĻ9/:Yt]I?qyL8I}ϝeg( g ܑD"#>ʮ9r*/sE^׆|a}dyI6þڐ&| #sp,fmcYvQ'O}sA>Rޫ OWitTkz8|eN"?_])IO?;=ׯN.;οG ;9맅C? Z6d{&})GSrrWM#>ƙ4mϝ<֪7 1ߩ}&~+Z8nOaDܵ-11R#8/cjz`l }6?*_)eov!Om=sc#_/Ӷ|*[jҗ7ǖ/  ӫRӬmj=3 (|RMBzpb5^ {8>ӕL?RQ Y2*[4޲èW3:~M;οzFs g_bR4eם.J OSOc:FounjH{T S0g/#/DaL7؊eTSmzc'Ze>-\zY1o}=E7S$jϵ>C5s^7t4 sк-2ﲉ>2?1zz|Njsƛ7wŸ” 3(e$9\i]O@|$ Oʏ`v<\ɶ뜧.^ԾYC?PO}W]2-< >Nz_zMMBF9Voi8cz塣(G~\?7>$׽zI|h.5V?ez4%4ؿہѫ̏&sx _L%=Znl~PTk* /A=vR,إvM=I^=Z|`VxyVi<;@y8/a\=iw!b"+|7g:sէp>w1C|;E'8w)_4pl}|P3_| ǣJvڦsn;w3ij^>*hi->ixF8?fa?a7_/fu(!\_Lḿ ;q"^n{CySLϤho~'v=ثB%&!sT?pSOhFO})ϯa(y~_̊?1EG󋜊DWP'׉^ &,3ށp9!`yQ<%r)E%VZyL|=|CBO2 x<،w]{4R+c|=kʓQa(g^̌*Cq .g_q~κjT]~|h~k7[,uF&c X^ Rުzi&kos.e(-†CؙXˊ=\g9qC&:YAomA~ߟT_iK/#J9SNsTy_=5p= |hw5{ { >g}tL`kT6 Yv]tGv.zOKU뻜D2q_MG7ONyB o@ы:o7!N[wCT8:Tq?Ǟ Rrd*&ƮbD._Ow{:-,I} |_ 3G}JP|NJ&oC'@gݳ_G`_|mڬxؗG5Ock=c7nnwޛӇ9U@F͈Mro' {Sr?֠Fٛ^y! I>g>dz^d,\>!|ۑit,HOJK(v<^ٵ>W.-8lW9/ԧqvx7 y響x$ωFig9o9>I{3iϤT,HP䔱jo~ΒgP_%OgX]1yv{E&WP:H~N"0S+ N]d-QwLSC< ֫.ӽ`5"g/֪عئsj'+_m?aXzWEr]PQiLþ̸*<~Ͻxdo9.:L hZ)_s?i>z#u׳U:`L +6_iox4Yɏw<xw7で<(gOLc7cr_7)7K`CΚ)BV-8ڳsD?8ж*އ87d=n2|=dڐ'(2Y8ENu7=F7]}~|ЈE3veќ+>Y6*hAWZ#esNq8.$0ՠF۾ꇃ_;2 ^s f7 .WN4A?sK^zèJQl?>(K5'71)' є%!9͔}-<2_m gVn=4lO] ==6/r,6_oM֙Cd?U ?8hίcyc3MJ֘ G:8I_#~M3+Zf5-пa47.L&oh>r@'?Yi|c=ε;Vy>ݯ^xt%7W-zFuy/&}9X7dߍlce㏤ף;X>uJL& 8nb%7R_onrQG+>?lR8|xO#!B*Fr!IŪGA?r}RlZ+?/ר ng V^E|N慟L,} ]~ͯ׉oLj=kj*QDh(.#, 3u׌SrS}M~@\ FkgN <nE!b}+0Xvbw^|~~"_2%Y6!TGCo="zƩ;6|j3X4u?p8%f;cƭ.?0k_ux̿Zd jBrx!LCfy|>W-s?>E텶T?cX *1/2I|P{+ !LNӶYrFd 1sa.խZ > W ϾÿļXU7G-pkv'嫷O? ӊE)anҡ__c4hB^)__?!N1j~>>><}>xHM߹ٹBQ_cNjWW7 7j0Zlүաh|.XxT=c$$ ~izr|.C!m Rުdo|w|FJfK`C!!۲s`~<%X?KɌK,>?ǐ$>~*moK߂psJ#¿8lkv.֜M֛_T$Sgp }lV 77Ϥą)$i(I?0?QAW/}GZc*l9ݟ v~5~Qo¯VWYڲa^y3o*voÏQ6*E'f:oА?-+G\~ uyMi?s΢?ya3 }^ƯVAjOk[8SWpwz }= >;klkob|sRjINľ.CI;h)u'iZt|҈gѳ?y$zB&uĠ>my=5H5'NY8Y9",ޗ<8r3׃Rx=X=%ݛMK> \lBoac".|t^iÔ8{9Lbz{W_w^ii[gt(P| ֯$?ǐ Jb|]˰t7P$␽,Ҏ'iK[/SD@_cW:PD'M⯍ɪln]W<115M{iLx`|8"P%D4p- l%aG";ZsCt/g5Gv_%η;ZTX>ю+Gy}"A4$Ѻx@}/Rު K>1u%_fE> :"/-">"bٹ~^{S32}m**ߋv7վ;Nfc`ҏz9hGO}Ҭ4Fho_ngJceo~U}|d(y_8Q>?вck'ht|b _ aE#Oݵ'ߠoȮMz_z1Ieh|=˟e okEO!js/[Oa*(: uՁ]"|^s( b|eyx㗆:] ZpA'P-q}S@]BTNZ#(#\ڬ~'ǔi[<53Ckn}"В7MZ:SKeZ/xy!Pkz6/AWPq쟴Q.w:wc&)NˣRҜq?/^9iׂu00ezBm:~ҿ.XӢF^%_mI]&oGT7ϣ/VtO.(/#SJ*Vipafy9Nvx{)NOg^c`٣~xiyu>I:hxeT ?g8s>rYЅg\6Z+yLO7q߼`V|;ؙ/@{C>y CmCN^QakVoz 燇SWQTĤ.2dɯ_]>sOS[5h's^Fi-~=~|и4[^߈r>>1}hZ篧oDZ+5GuAGBz5*?^z %8^=q=pMV~P@mcbףy5K`x^1>-3'\t]BD)dN#gViGn}|%ՒO$K1kQNʑg1,l)c*44L>y2,Ls#duGaZi^y}-ǭ<ŋwk[cmv"vT(iQ7<_MRoy}#_Lʧii|?£+hޫUhn!S߿Vq-U\ox۟k5O~`qxM I^č8Pz/ľ(*E/vE~X{kvo7eҏ/iNL]wmգ-Ջ}{Z5I0Rުg|p?YA>}Ӏ^9-9&-'|=SXJ+M7Iݯ~So1wNZͷ6jޥys}9ไF۾ 'Vjb]|Gɇ}N&?|Z6~5~Ì_jg\@U\5sJNT|3\/dw_eUs}kXZl?1J>4Gq^Gk1~?r2iG7O[IyG۾']IΟ7y8C!jkp ;S^;k vyy_uU&.Uߦy~U'.*9EΛ:hzm8_/[=V?u*q)|PE^͎-عNPg~|ߜ?T}W澟#ؗcX, eﶚzȜtH Z+iɚəOOk~?p2V=p<8=A/G-!QQ3;f$rxe?XS,I:4*UF/{^,fҬI?goɣfXŧ~ވ洱x6?!VKKjPD#"^gshG*ڲZ-ih9Kn/?o&ImhƳ> {^>-6oPUzף8P[%Xxz6+֢ W<^rnC<'y{ztĪs͎'D.):re Zף םaX|O]<*p=m`P{l~91IyL{4~JTO%b=NE;cz9,epgTOuȧ>p E>=HL*oiO·Oo}QT3\OڼIWQ́o 2i~9oRvXDPl=ljq) +<)O|ʏ=꾰\qp~}?OLWiˋE~WF(,y+KknRA+~ܯZ8`N]T|9_v5ׅy)-ͣFǝ,@x mJ -BCOEvّD]*sG tIJ:?l p|&?;g}(eS?Gk?2{o!7~LyM}:ة oo/LS>Q.23Rtq"rŽ.JxIqL\odB?.|մo5_┱j<:ݭ?1|HI79GȊyWutdhٶkT`݌)w5ԏY{7=PDKH~ɝZ]ㅛ_s0?|[=@ AfW-;냀4xXWV}L#y0O>"` g?!"NЎ|%[9lr~; >A_H/x #L9/p̑Ӟ&}MV\;<_%Kob.l+οuDվoS}QOƾ͎}E γxTcHtY4]ry:yzǘw3gTco;1ߞ7:kgu=9s6gorrǛq=oZ$b~(U*V~[MʶSg\.!erPߤ-;7[{3H||@32xH;8;8f߿\$*gۋ^x󧼕wBmk?Qѧߺ*)Ƿ,|aРC 3w>VhKf?ys->3oeoJ.=G=w7# |ݨ4C8vkǶR^+#^$?%}㮣;q|G!v o|R9w艢y lHC?yIO}5:q4C[ouqK;k(O^@|S6ꝿ4ᇂ^v߁c\R")ɂϤ=iY~K{zTPKHDmΩ&j.:9TXK _%>0.LJwyST[e)Tb>g~RiS+n9??4P_yHgzQÂe#u~ZOޗ}Sekڤ_|_:Ҕ&AC2Oo{+ǜYĒ|6_{!φ ZI-~#'Pļ~IRX,sqV 4(w.>r/*xml0y!(9^^Fs|4?"QZL~tz<9>*]Yh*y կlB_EMb֯|3p[_}1,! WpN5g{ui];߇xTz6~y x->/װsǥ[0"_cs>R'>K0|ݝpZx- u3~Aۛ7I\k]R~ec7f;/65͖gru}Jٗ/,"@4N+2Z=ٸ5eWvبi/E:_ I>%;׉O擀WҀO>;׿'_L"o}ߢH:M֧BLi=C}!dqhvl,I?nӔ""4X7|) ?7-^KMN`a:kj93? w,_o`_VYENzTPN}9Ub|j_3C-8zgwf"[^3=2*nziu aC,~"(;s8K~]/m /;Ub{3oOLIpyL5*gH5Gq= Cq_}?8y)G,ivģ?OiX(R$O-+TݧI?OIC=t-?rK[*]b\3yaK} lh=m.ד= `p<>a|K:Y-Q6*ܤCc/IS|72}xCGG}o< |$S}׏Q+CQIȅqM:o8TQwdJbe݂u\J !_'Ur9 !(xy'_b6ȉ)con»a9b+f"&+lݏ,Q}Iyumys;cmI%o[?YΓp}~>ʧuğij|D<"b zE}Oph#=ޜr[B4{kkRf_2uӊ3]FyCE Ia>ʍV~7w4y kCĐxEđgڹ^uofƻ[omOOqS4/AWP =yا:aRϙ.ֹ3i--\wlqEV3ɧs3Qu?-|&Os|Ļ`p A4lS86u>þo:)9Ll M&v?< 'KQ%7a:ENV!YվԤWWw'~GhV{L7 wq?:6RR9ϕVoCG61㻆8hoCD<`چ^H!"$cҏ(5fo'pY4sk_|:z~g~O&pgC9[C퍯G4WL|w'LJg aw/_Ӷc9}/T7_z%^T澏 ƿZcYWP%(>Y1gePXE=VVkUz$㲞6lr>G +Q:^GBRRU\Zt%g+*@HH* |ޠ8q<9bސɁ=Cږ9,z]? q=b*Xvbs>ƊG>ŠqNPʖlXKSuY X/WLc1yT?z̗$Ƿ#SKx|UN|sroWsL>,ɌKmELR%p?_ǘ>?mawiJjUAO=p(0bOx‘Fwo7+"q/QOMܼe3>GH'(W4u~JrHZQ#)oQhLrXxY;#֥Έ5|X&G?eA&Kz4 /o6*yzǘE0L^ݻ>E. ٓsͱ kE%'WEt>~JG_iy-}~=-Gg4 \>7N]쑩o<1k~`AH!O2p*YCQvۏ=/3dA+36~>\BE㮎dU9;oi8cRMe z=-}O/Yn۫ |wwXwWϏZF)сsQv́q*cE}ji_zbҺrPt[u^32UiTwL.+9FzLN,}=4cnjn|Mk4}>wuJڟ2V'y5$7Џq*ՉI9 R-wn3`K~#q>}g|>_Vžu?e)gx(RcX'ΓqqZsggH{Q̓d>ǀI>+pzivz <ȮqbwijF.o?'wWVNztsy,Q_,[͢Җ?֌"GS;_?zRV?Ru&:R6ɢZKf/^7u(5}yH{^,v=Kf`)Oi R[':Wčc;Ξ }%ֽAu_MR2*hʛc~V&G9t궜ENHzؗ9^X?Oz(S^g|L|:XyNF\WyCĄ/9lˍe[dk]yvey4eQ>9*ϻQ} \4P(GlӀ{գ5<`UwP{l< iu4G>!vאely>@`>Fo!B&_uF.oqlJd'4FUY_@_PxUGէˑ9Nɾatԯir&A0O_Sk}We( ? m*ͶН9Tpe 1O/eUu vj7xdC/OU,}F꩓O3 Gq=cٶl,?m)1I)$6 4`>ﺖ١4(w3;8o!x89ҎQXLwp^ <&ni'bӒ|>ϼnu&uDB^/y Fb{cYr2= {f}ˤ֓Kź|rkKy({|V~ݒˇgk{RgX'K)_rz{31ieniwo,p }4C?CkO7_ }c<[,L16i2Z=v {{P-%x Yq<ߙS[r<cۊgUH'P U5k4BNg% "jҗo9^Փyq5^~/S݊l=.Eӝ79c" tזk(Ȯ6xf9T8ȠFDKK9N8YdB(|lZOLJ> u(f;F[ Ó4as>q?ʯP2%ְnf]\Gva=ϾPܞ1Gpבyu$}"~SOP/RFϓC׉kA~ĤN Ń7}t}îR'b*uhQ̋y8oDKz8a/f:5"Фף%+u9E?l>C^8!ԯ$o}*S&qM7>lM4_}2!~kԏq߁P&Mbhg@ %ǸDI;KaC!!0s|9~';k23_|{~xM (ruJ/.yT\,J;>=G@=~!z4'_X-#>ʻgR  u&}+?5*O_Nיk\B?uQ'ϺvaUxFx ЏG5~-k#>ZCuIf9:@%CuIs&}!žNJXgyx>21&y*wD1v\aױ!kX<%M8Gțj_Wx %?Bmqz}"kix8%o5#nijPQ1?1 ^HTݼb>cD{Ztg`D=T,ђ؃]K4dѳ.v&xMt*hA|KeRkq=RުGQML>Q3%posу/lho.G) .ti^ԝ}]6pMz(^n_|Ǥ3hZn>\ZvK?64lG of s<;K`C}k7< M\&ļ6 +xTl5oMMu]iNnsѼOlZ""0X| TI^LJ?ڿeؐq" n$'m{]c] iwV{ױoNkGxT <Ǽf~r-? \O>ajU0z2fEדӏV2zR\Ȳ ;I'M|֗\WZIYߔJSo{E|֤g=9X3^.O-Oot}\eo?j9Gx4|N/Z&l?L_&ʧ{ |&KJj}xbT9ͣBP|D}_Ԍ׻zz&}!axް*#P'(c{֛z~OÇ;O p*/: 3;{<79_)s߿י2riast>|HLYTI>mr_4}=R^ʫe#әL6^iNB)S9x O/pcQW0SPT1O|a'a}>) > SVzO|[ y\']y6s+M~?:CAIa7ڥ/I>ȥR4 ni)c/*툯="q\&sUhż,,akw]=>/n"ؠwKn<zZel{7ѓ7)2{Su7RaÙ_v?gr9Cs~kOem=:ٛB4k?e&PҤ/$22\ͧ?wIklM<qL%p/;ou&͕eVe`9(Gս xkS>z;?t6]P}[o0㮺yƷsOQdjz0N 1K=yf9vã,iodn_8%> \IoVGdx>F?4ve?~b?y{oJ?6|6EFi?`zx 5 yP{/V|/wXyDs!͟&6^_1e}G-zL}+/j_Y5cw(TQ,z;(!IyhWo}OG-v= !~ԗ`9ԲHnH[;In=hea$?H#`?71BNc͖MrZޛ)d磯^QcJgTp=j7C|7QΏdo*q-SחM>>M̏mF~3G#l]bV($ ]3u|<.Y 7̊sJCpJ=$bb;{i(^c={݄ȗr苷mx˸KgS796=wr3E;xuT翸ؤ/u-_TGdW,r֡%#S>戟V=w2𺏪[W=$Lxӧfq*0j!b s'q}O()r߰%{ib u=E&Lohi->ixR:-z߰ŴШI1ChƄˆ="/@i+^Ԟx㌳&LSWY[] oܦb_&eˇ':o3DQ`V9_oÇI_SJnRrEL0Yo9L%<\Ass} x>rkgzG-<~<\&'=۫{;^yәd8:S?5><8Qr|8/+.8>Eac_W| 1Q+^Q"C'J9>!-R~w7gFKW({~jL&M㯱TYď~mٹŃ6kp>SҮ?SMMA/Fa.~|Ň}B{x1V6onwF|)colPbu-7K_biSpݷc#D1ŵCP֗Zp\̌˨EL$sH J~Le"NTuˬa%͚V</ڳv{0cAsuk~o+>8RSV <7#r^z&JWN6 8BT蒺_Fa64l:"VprWX>١wm1Y"Ϥ)r4KN߈+i $}J]-S\_ X{ngqtLc Yq+pUC\9|[Npiv.komA["X0xK*:{LNMvUrͅfk>J}nz,/G[cNC? QW)@†TX ;}-ZW<{ع a7x+\ֿ=sn+*r37.j|yg/>ZYשW/I?gNnL^Rrڤ~=;^|x읮0;OL! ϨQֳ%՟qzW}a%T:/e8~sߠҳǾ{Nwf_oh}:z#$n΢JN%-MNNqu+3`QVGdz%4<}0➈øb޾'#^ѝ<{S.b$2oPG%" SP~\5 ;OUGԯ@[V/|N|v9Re:qRsQH7#h(S>Oׅ?ǐ>o\ãlbqQף8\q~lJ&C/6aoY\k; SxQ$dHI~Gb6̫;Q\y}:-QNWF}e|q~؋bTF|M~8Ob_P !Nؚ7F'vsWO~޺:??5ʖ{QnTK}"wo7*.ӫ'@}v*/w3ϹǛSxpKHˁJvb,dX)g{ݲV79O\]OV7 a'jesk pdO|S}o0@ϻ>\](RAvx-)rXZ}Ta}\x$ϩ8?'(&ȥykvt }hzư}C|S_$ON{:>(0~^]!֊3s/oC} &wS^#K$sx L t&E5'ZLwDLIڱOl;_鈁t?z_)릿<+"B]BşvԴpspV Y{OϏE'oB4O^O4ɽZ󪘰sUr^|!>YKMBq^j=&¦e~~y?2}$ztJ2){}ŭ'o-hGt~z7Pc @MNyNLd gU+&8 %0~0X X#\!8`Z8_7g`tsy#K~h[|y4EҖ?v܍$WTj;_?zI_ 3=r?W<=3eТ҆'^s:y~7~>u8Q3U??{V>4&M8d_8LK]ǞK5b&pOfsMLsz/&ld^xt%,m~7P./ZӖ K*su]&.FM i'~>ČI{jcӕ :^!YY^Kf{^k}nKuQYGEؼ)r;JM[_2zIDkW4'ShŊg@|sK}~/|Gzzt%Mzv%] RTkv8X'Wz4o^ͶC]:kLh`7+jY)F}x?_x7`7Ip]_7{"vbv|sq|"/>X&{o|%I5؟Ϙ>5^zbUڼ|w$CI7NJ7–Pc-G_};Uwg=S%jP /Q]si 87d4y\mT;_l`U_jxKr^3>cpø~"!0Cy+Y-?Q;Rv{5Evِpë_me[pnV.po׏YlAy9:uB@zb (uGc\ׇvuz։~L]mҗk7DInDZUfeۧ\z5J{xⳃ<$Ϙ'I'Q.;v`rcz ŊxTP7B;s爸 X%9]k>t[#Z>פ$*hxV>#ezW[l$|>y~gSFJ6^e4|z9oVd}W/i"?WQdWG;='dJ$1av[6!&Mz S{^E?}ٽRrP 8u?`ҟz>5 5)3C)3hkO||-ٵ>*C~qx>yO#e2*O'G*63Abϊkl+wC-۾MœT@r:d9O]}w,}ȿwKX59]*xC*4KU?.ߑPh^Sb@ Ec%ُ%I Omk;Aز8 {b|Gs}U>*c.[l껠R7eWX*]^ƾ Oh, FVw}V}sɟs {_?3q21!5#s-/Q0(`?dvY" q|c3H3wH{Q]ىJ=8 Gz[6?}a%\6&WUkf]}9_ Z{7g2lҠF[obS|)_y7K8D~}r%a]<6'9ya8RL9PZ畋G9|o4cz"5vgQOzI_>{Wm{^Tr¡M/_lw5Er ߫w| :cO<<i)cճuOW~z/ R؟#^NČZU5Oe>@{]Y0S`wvo|<zI2Kȃ?~|-V<&}y?ko^jV?X&8y]" R j9pߊ>#8;?Q&8V2O|%+qw#Ez6*QE»&}y@%'yiwle b({]n&\?L~T~<k|+{pyusNww5HF?KR/]G{ѹ'p#S 9wL::fmXUz<7W<GL?zq|0rpƛEX/\k;v.s˾-Z ~mNySRiڔ' C\Ci`oL/U6X%g' J.\ZO& ɟn_/@[Q_v)c ;`Iؿ5Yt꾝)֘5܌2ݯ7?}!E4c_Sc0[{CO<?b^SjjCџ k^ĉM]zׇVl{yD}>GעDױܯ"3u7~{˔4 uy琩75ۻWOYzYF&V\Wr>յ?_f?Gg^ȿ- ֟Vi:5O9?>GI[}ӿ۫z2_y8(EI_W@ xyC'oTn?fuy=! vv鸄I [.;=HO2?T:I㵫=[(_r[HNC%QI+w6Bc]ſibS| &}CϳGK>v2[>V]{0)FDql+t?;Y%iosW[L,^+_4gn+`AwⓆ'F-ukΐю{z 1vڦ*8mg[)yrtZ=oN \FY* Yz)coU>%d=g~n1ߋcefsDoqYB3>h+8!|AfW֏Uz0* ]Br K؃qd'׃<_{LYnX $q|ɺqRχk~2J&<L޲-o0VxzaO~@TU7+JkQ싢͋}Q4넗fHx7eOٻO)}-+e:x۱wG 1 Ci\Cyy$1Rުz0dó_CÍl예 %lNy^loOل,sO)|X'b|qa\I?'pao4,a9!&8ϲJeo]PAO֕ns1?8ΝQly{t;rJ4{koyQMd^mt% n+?`YI77jzh|]GC}}#T^Z|WF}ľw_ of=<>R!LmX:eUC9{q$WĀ}º$z6iPY |N|9Tu?`lCXGcFNllدr*w<~Yǁ2T~!Gx^嫧^sY斖i= ?n1'E/qܔtRI?>tߟɲO=ޡ9*~V?&pwU~gٛ7yq~H_8\ 6' =ڲsu|쫧g.>|˩]dn"ߛ'2mH'!lcMϱg'o[Еrg/Vs6ǁz~3R޸H>g^/Ng'bFDPv\'y>K*KNZF{S~7Oڮ[din[|coʯ bm_ZJ~7o ze۪lBg/ȿ d~V.yTpŏ ?) ^wC+?R޿܇З/(+&^[ә4 << MS#A}2sA;)ډUxї:n~ت _GUdes*^9:Gtd2z|ףXr?M|eE=? _,M}8x`g4Vmfu||89ZKෆCBSء.\zMdDS^*ÿ{ṘIg21>z>/p:_G=dcC`tD gt?>bN\ο{WnЙ,QGhf\drU>'@UrS!XW)cժ;^eiwFχuyM|{Z6 |l|vf9^pYW'ͧ]>17qUegu)2/ Fkgg?ʴǧ{5F;PR7UĽGy`srޟUS-zN;:ndtI>u65pNv?xMe+yA˓G8Whę8F1ˮb;1o~?ݯoi?Gnb #=D]}M}x3?MU|xbڛ>&sL!{\~ z|ݙ$n^'1I \D8}W8hx6ԬKE%Iv]]*NnO ަ)Ii)>Uj^~/pa4QI>`PRgS"v3ز18 ?5k'v ο7S[=Ko=Z(K8歯Fc^9EZt7RaWZ٤?XZb|I~ ʟס;}6eHfx>#ezg𸭉o||x|˔t+|87ΰ_ηoX63%T=юD}dTK6#<ՆZ{>sMCNv]Z-vHy Zoj2V+^l؟+c0STSP܊]>6xg|2e̸~DBi)*)!qʾS܌|r|WSQWÇփ_y0NE/YĒK۰Zyxu\z㡐r\*< +1?6>'xZOθW=+_fw$x2Rٽt&Qף1 gC ב7r=M8iʮH '}pX~|kjZsgo E39ޣyCC W+c=Z[!M6^zm:sn>Sq`(B8G>˼Paڎ8hڰ;LwjϫlR'z1]='j?h<>T%ڤWɢe{}*?ynH.4|x}C hYXesNtdc?ԿCr's|x:b.*mZ8ҷGYOEvgQ/3? l^[g,$gryA GWNˇz8>dž?-H{1S-@1^DJF[=M{Ѐϴ3gUrʏMopK+vPZr-Cz58aka~xh|Ԏ+-o=sD'u}eH>>#Eʊ-i}9\,}rK秐UhzzzkBqc9kQk3b*<3GY澟(U?v^^$(5Фucu%~D[`yc䋁NFIQV ?vpr}$p=B}(Sdzs?T/>+M=?G_ϰ̫o^8GF!M M})c[vwLcYk~R'Kl}>[Z+gHx{.l?Ųh}zIc+ 8lRW)i҇ϲI{ דb:I_%@ S+EMkvrH`q(d(olέX֡]D,u&}^o}fze?ox;hG~s|cռs$_=+Y"w8QMA 7QmSx.O]إ_̋ |[tǧqiS˳E!T*NCOQ.GQ[ Fva|Ր?Şz =R^g=_㼚z3!CW{v3:Ocz߄'ciy\z_)*j"hZVQDTŮ]Bo๗LzZ.0M|L{,UO;OV~ڭSB0ɰscrѝ4%+q<~:=&Ov)ryl[ ghNŧ>]S乡7<*_tڑqΤ~vt-TƊ:>0zgzY\o_$c-v>b>D=;`˝O,pze|&- ۔ӥ{)zSw;yگ8 4B~|/sttMkp͇ߞKUF43}~ [@>Rᡱ+ނ:ZsQ3׳@2X8 㟴L.*ނw,$Yxdϱ7qUrMFx5Qby%mMj{tyKCofzyYzD|' 4Ӥ ƹ:(oKC:Gb1deaqJT<\?d=U=Qz7H{Vpg?Wa|ߨ!L jpq+|<_ui&OIO5Wp\%DԺ3~Һ.KFy)~ҐWOM~VnUa]f̎|᩻ߚv|dgvY`]Lu!'dɹhCWT)K9҇T1K_RiԯݧS2V' h_uߕtY+gn\[+5Kw3=ӟxƷg.** .L'$Oh#ez'L#> ugN¥X"愾 b?;י/qs<_K&%c;r)}ԣZY{> }m175 %?2ftIi^Sb@k&}s=RުW|7Yy||@O|7CI?K)=:sas_lo歠liߵ[^ޔ>\kCG R.Q%Χ V)$'y\1!^/_a~53?~{roSҙ4a0 PJ%%W"N+Lh-/_&7_=uUq(͌K]' ->8%+8kXU>{b;+=OK/MXءs1\`=o`\4{T3'Q|Շ}>r-腢s'|4ޤiАp?c$W-e4E.%u=aZj2Z=/ooMA?07\CGaEbJr\b\ǣL I?'ǍO/ۜY.>o_Ӛ_~bx_}/1%bup؎o{"<^wG*?Z*^u]8WL7>#?~vz+%X%Iٕ_v9H?>1o`^u|7a>ˇGeӕ '}bL6}՛&+~6DXwp޼KqÃzc_VhZsBy7_Ŀ= j2Z\eb 77 ^d+#˻KbP#K 99/|8x Y@5wޚ;հszxjߣ6'q?/Mcg c*S x }e4 ?yl$Q/ ~Uݨ븆jy#7keNᡴ,6uKo-/z7|O^_w^y e(Y  eי _+v>կ@p"i_ </EWglz6>X,LvzZ,*<H\B>MeiOXлxO?8u{e㭋oR-jy8^(_yWa-pfB~e,|/yV2OIp^ TojA&} ?|'VR4<۫{^1Ox;y+f(q!L#k?̲cN5$BƓl7["6joȶqP|Cշ̒7- T?I_H VoƝjV^_ ˇg(Rb *MmfOM~d>eD_RюUH۾M'4XN?a?|)9up7hMsYӺV~F}N2ɦQuףa2I8/_+اQlmuֶ&-1^b ?H{C0^MvA_n)"=}:{5%јW?6fIޓ,+-ɏҀV1W Q p\5a||xrg%!^WK{E[B㓸3ٛۦߦ'E)oݿPѧߺ-U>Mai|]@+>]8/'WĔj 7O> A?.]%&{Su7Ral8&}u~$y|'&}!.s@e?Fkk5_ <D1#Cf6;5A}`Ɉ_T,. rZQQt(s|ɏמC]#s¥UxM$^zד7Q$ƧldΓSp89 Ϋq)_ω@FS4.!*C5\>P>VYS<4R2u^L).=VVB/x}y>b[}=R^'Ax2Ϻ/@*E!lIuwF4͗jFI~O;y?*y/Cx xVp lzT*T[v9޲\G&Oo򇵱/vE˫(2ye+ϣvo7eҏբ_imuuh|]fyF{Z(~?d׌h]C.q:7D_ qxhp0h=Z1?zmUe9ɮG[ۢ2꺱Oh~/I{Mz=j3⮓x~WQwP7r RK91Y|'OU>^w;/RI?sDg;t>uD6x G&0o2V4||z %58LS W!֫b_(rCY| ?髷ÍޔA$!w򳱼_?qB?g]5I_O1'uc,}wsyl=c.#ejG9ԟý^<<_:?1j܅[΃:v(Cczx~_KoJ,u|ŲjC=9_e q rf:>[^ ǻx֗)c/l>=GCOG^ufK\j8(Oq`W1<a<ڲowe!*=E|+E?/HSWfEzQ'ۨҤ/8v>9h!4皼lKs+17? o|V1{[Q{5 i }EJ6eb`G=*=6LIE]\QEuކP񓏏v2*?}n!҇m4k sE:2Zx%lEmΩP5.sal(&y|F/|*5;5 Z_^SIf藪nHgϳ4Ks~.Jcʈ~{vw}'/"|Vz/xg9^+Lpm8foptsO??'N_dq߽^OPϗKqBV&byoo땧z% LQ/u WP]/wOP ޼H|Z+vPѭo,S,dXa@Gi ˤ*V?Cz.b@A)coջ_38V~5CI])}TPo7=̮Anٯ,Q~uazdl~*ϔTzO0BoL vo5ޤ%*9CGiќfL}VV{W43zZxiS>I>C}řgr g ߣd&+juj)R8/FMePqp~|h^~) ӊۏ:i$ֱ߰[G[Õ#7'Xc.qsy~ݐo<^~gDv<]"ٲr9[JYtQ7ghov,R;5F_z^CV |g{KS9_Mq!v׶yݿeW^SzK/{5*i7[NG \1(?n&}!9K@ȣmkGKc2(^?^1/-KL_[Jԯqha%}Z{5%yvs"!l{ٹi^șo1xǃ%_%?-ESt/괚EI[حs7ҎWߚ2ihg<=3eP|rsQbx*QMgzl? %wX|T3 so އl}b^GfEf=WΧbTܰÆ)qRۮТ3nErFؒ,?-|OP|$c0</0eJp<(N̜C)?|*W 㑱+$JM/Pԇq/-9zd5KB4UZW#2Vp~g_9e~WbM+|e vnekU2_ɭJ1Y⾟@{hif\FCqQX b9T\%6@?Oer"ޮ'J6?q `h!=fn\gܓC}+ ܷ |>h^dmnK6=)3{KHEYcfҏQ9sl4IL{TyѬ~tZ*>Mno)G I7H+tHޗ>{86Uؘ ?׎r$ | {>ukC^klG8^i si|.+T=I?y?HceoGb~u:E=!h#trGx+hyݏE9n9qxI=gzM}YЯ3axNv./s(W!M|p ḌX+#b#s )9Sɰ\r}G"V7iwUUO,ASn x\v ;/)F8l+oiGm_մa[+ToIGU2:aKZ|t`ƙ/>u&ǿwݳnGg%yP1'ع~0y:W5Vw/(dvBs /7SqξH*Gg43 . ȤI\qɮwS^7&]ߖVpبcUU{/qp|=O5ap<8˴-C Gofބ&Ǜr>xS1o}s8E7SD9EνQU7w?9pjNKo=ZNsZ޹4_LLZ)_oԇGq-u{+p=|JP\Wj(fOn &fOݿ=3IؗCxyϬ}Y{cT? koq?3G}Bi5^*?yks>}e(w&`yѐ+xڊ:?̲Nn?d?o|63p%eel\N[wC_|Q?Z~sUx_*^`)F^$eJp^ _<.׉ė_es~3-:Un\<>YWSAL`ATQ%}βt߳m6v JW8ר`㓩fMu|GIQ{t=}S#!b%bo'r|n{k[qrnxmZۘ2=k/ok~Z8~*mzL%GurGGQ4{]=q;,Z3QӅ}}4NT~WZzP$è?$3f:uz=dAwq8Zz 1DY:!e2|fG }|)? , ez&L}+}/U2KO꣎Gع~q+$3i{+ ӮeT3'QGEؼ)r;JE7;Li={X4>6U}h4#6YiNnsOѿM5c2ޤ7($SJ^dbRSasg^0 W+|' r]ئ쿺^Ϝ;T9QuMAc ?3_|xٿooh-?M|;SO ɣ{KC M<7߅*{D|uУ/ۍN5|d ߎlվ;𙏳sCߙ5 IKr]O;+OhOMܼC D<_X0t|Ոo1G$s<JjLǥy,^D\= y|չq( ף~DT3Y7u8nC:d?o]/6kLWy 5y׈#ez!a2I/LJ~. t`s"ؑǻW`fg蓡$rM(.[K`-{͇xH@CѹJ܏+^J>S\)?/F*WI<锳E|Z:RQϤVX7 {90;J~Γo7ɣn' !YqcXuh;9l?xTUjK;T9fjPhzm2ݩ%Uy[/<}9X言e E$2"B]bcE{̓!'_oap&wKe'}}B]̟=aWoZ7D^a;i&o:MԡggK҆9d6 ߹=sOٗۿ} 96e~ޑ2Z3G#*L<>S<I c sGa"qv.pIk}ww\tk-Z^ XpEdv}~CյuNͤ ,Y;A׹.WMA~OyU7ś-qRPWuܤ׉o| @&>[1J(5p\+y9YCr;~A#Gztsy)iW=LӖ BJ3~c=ԏԌ;ħoHQ4ӵtO:/{BQS m5Xn0gϯ~@^ύ'V~N݆w J3Zeyb_bE!wqݧ>f9Vtzc_VI<8 ϓyVLCr~1EgTF˷$|cy6t۩v*lSڅ]k;D^fxg;e_ץ ;vaYy>܎4Kk>of唱ot%zC_Q'dK8o9w|;֣Giy >2u]{>sg/w*whP쪎}(e6jPA[!AZDz)«A[|z-z~3deг#dfd+XeO[ Km=&Qto\"aK&Eq\*( vZ*3&ӔNMINxi CiKzz:UG%!GkV|A'70CIGu_Kh}^Ov#b"L(VA^pO.^fD*>5ﻬM?I?Gz[4s|ȍ3)z绻hQ^nOɝjq/ik2V=#}/"$-B\LnɕX_G3_qNVOK7i$bghG<#Y4SN׈yR7WC<$~H{b38nP23nܚωYmaW kο%l38}!>|%Oٵ>|6,-8lWP/i[7*hsg}  6/OO3&< Z7kX_/GY?*b|&3E9~TC Nǁ_1;D!^0#comU&?8B[>_~uݾT|rWXA_)ѕSoRaæZmhPk m9D񱋚ˢy*>2V!>@noyLNtK{VhPRsW7g aw=}vGQ7 ~y ;mݍ6JA]7 ^y V_ yL)co+֛F$5'8\rTmO6(0nع~}!W}?tg?TrWz2vj_<"7x7u)&Rc?'CO?9Z]'03/<({wt"˔L4u)h>;Oj'Dr\@RUPBqZ=kz9o&MӶ9jiuc+| 51R^+c=Zi17%_{='9s!][/|sV2O|%w)A.tcYUm.#pU G/lҗk=VID]i'ɦ5]6pF} y*\U=޷  Q9{GFcr-}߼uQ?O=u͟sY(Ȯ6xP/8In옗.|lFMWGs',ޡvR[xZcڔQ0_%koz~SƾľkWOug7qV<%bv̓dףMy#0-fm4-|C7ާG} |G|ǥf(pY K1p1S=f׶u|꫷֟ 3LbŋwgJg/^XQrZ%;F<[;xy!Pmr=)/Hn_}upjg;Zcz!yY&SrQ[=4Z rj;yg3Rjf)~㏿ ֟PR$͓(yF'O"zʣ/7a8S9p:丝2sv>''_;Tu?+ ^G(iF!M,>Yֳ}D^R:`P$_i(,3{X}V=ޮ>.xb}e0^V`:Um˙oWb$ ~mxסZrxc$W5 B!ɰ[#e2=nW&䟇y5=Sb/ ޖ]ˌ^ح5N*񬝶_|Uy굩^+9R8.C*eov.5&5!L~>^)h]3qU!\«1Gg2CIO; S8@o{N3BD8\e27y^dז2qA~PEˤ'2^SB4>=tA^eEiOzlHVş=R*:xϣa7P?)],;<'@p u6<t`?Ҁ<:yr>/sRS^58Sp==:H r>5~^ai+.Sו3s_ewPO}۾*W?5INE3ݭvWpb)coU:>ΐoK3T0 sppg?Dސ/ ZVN~Joy}S)zCwm鸆"mXѧH*.oҎ7oydy9|Mr(͗﷥U)ON7__It69L/|8 2# ČmCC-F!ґ[WI#[T_ bտݏylN&-?.MyxlF)r|-盠(^~}7Q}55*+Mdžuė)韏pE.B݄ .y4|xpΓ5j~y5/MC/"~S1/BΟ/YL&^/sp=[j܌po 6;߉wK:woݚ~ܢV~4έLG9s|Dy};W5mߤ/dz9Tlr n8o:) :O[8#NӞ9xԀ>aǪOIg}WoUq^z_{wUշ$(~VcP^[*?4qSS+#h->tk:(î}=ļGlv><~>ߣb}%ۇo9-Uۦߦ磨Su(> esO>F,,#|ݒ~Wlan 7t 7AzؐO'`_pulǻs9g~2cݏ9ޤIkE&L/k7t>ɤǂ.G㖌f?үVZ)oߗ}#eZ;Xs>o ~!>-pw!? |'yP~o{Ws4,T9vܯ *^" LT0$d!$뷥9vԴ0L'Bos`jťVn xɄ{>y?P\&O,Qݒ+lc\gԄoMo}_lv +ZkO}޳hUOL_2%yG1A_-7ƕc|7!x1O|@<XrHKVg}q!{&}< y̦_?ra0-yd xKegT>󼾡|x>^$%R?sӉ"f )%[n[3sLIWE*E#'3[> <(l ۔gTzw\5yگ8 vTSQsV՞hl&d$L3;`idž͍MM[{wyox:u?5K9QkeK|!$ ,JiǥNCT[v^2|^<P::0ʟEO=bd\RoNo{ep Ly]6W~nߤe)c/l{~-Mݵ <2s<Jm'k;p^+-zE/&0oвX}׃þ̸*q{A{#@i6gVK9ZEncb罛' 3<N*yyࡲzSG3L 8r XDD$y r' &S%6.?tWwMم7^W_){r?BNO<z}H9KRO_&_TޖΥnE߭ ^%Kƿi۔eFiCChZ/Zn󒾐o<g֌Y[|>>ȅ6fgC4CD<"aj cb[sL\V?zdB|WѽSr[͆l8#V¿IA\ߔ5Vqnoo&b%8TZriع7pZHx/.ʼH>%Ǽl(Sο.UOX-~9j^ 7g5حm+z_y.1L%8 N;]s9/嵷޷tnOe~yIۜG䟫G^B.[zQTSs{J6,xj^ZForxyOΡiZЬD9?C.R_Q!߽wx2b$O!H7sq v(uR5EM|3ϼ܃Y 3'@?G_GG4Գ)qg~A9/S[.=%}A|hR.y9dncN|$,>VmKn~ǣޢxᾷ^GTRQrSr9=y|ۍoeM1?R?ʜ<4Μ5^7;ORnaߞod.g9m*\raU1'ex3!)ę0?~g=BQB_|e,RX"cBw̡ɯ64ҕ"^҇Ǎpb(k*AG/nG|ԟ}qGq u.5=fs=pD^&|r7GSl>\^7`317_-'^DuiyϺT;H4/hL78ٚ_c--|Oo VddJׇWKv>>՛Sm\)ளR1۶\w<)3#񲖙ʼE}TqpꦞPҏdpѼ1^}wӏNjBWdUk|  7w}Dq la֨j}| ЊN oL @؛ ~bz5*}O[Q+&LJ ^yf6Zh/C0jx[vl*]?ŌU( ;q 98C[Jٞ5zqt9~ŞyΜQrQ;+5R-S9->O[WP-LKvV vagg!rrm u\Οޙ|Q5MTVa%_-k teipn\vێ$x \L|Ex#kf[&0,|yq>+^g7z ;7G8<#袜CiH>'-VbI6+8kE~Vڟ:Su֟.Pb}~'?~RYco:"<7y\+K`C]]NNE^fn~6H7 8[_;sRO->h^o3|uWxD'oO߿8|V3_V_~/oSN7UkX޿z"a7~<T›p:,%R[\kmzA_f뿪ko3A5Gh~I_B7/5^k&~Gw4~U7z:ޞ6U9;<86ĘO*1O}WL1T#gྌ̋ld=| U?\jckQ5pnʏ}#F`>}W>O`fϥEwQba_3+kW T$C5έMYOC޲q9BO='\?6z]1!}|87^/c6֨Qס|! ׸328~\e~ٸG g:G,x,h}9w>WOu}|!9I94Uɽ%շMg1vvwyO̍PPaUlvr|W~G]A^9'Qe pooⲩO:m~Q 4̷3H3}Q](vܲi3_j׮'=;W'xQy=}]y pɐ ]y{ 'e)~6@*T>Wҏko׆F6$mQp[/g҇ح-?^/-|_~?Ay T&wϽ OL\E_MonՊM\LɣQGydi>{ű~NwS.{Uq7\AQ)i4Kb:0%}!q_W(xp{ża*81'ъϱp'|n>cz_F ̵~xZhw8UҗzG}e-siTZ̆_|\rC11v+{y3G΋}"oHo]؟::}[ *N34u`3UkdW%k8n쁵Ϸu~I#NT #wP>31C9;9x ֚٭IV& ;d Q~VϨĬ0S&8͇Y򳚐|G'OۗGH'Hu|_|}˟}uB]O+GXo˖<6fr}TK,O Tu|I/}?^ƧQ%_ 7R(_aKRd,>/5bf-N#O:D_ܟWJWGxKyxδ5is,H|0ϩ~o٪a>3Pl7L;R *쉗T(#|6QJz֭"%>Mows~z7)$]s2zWX|M}y/gZicZh{aB+ )p o ;6*;ݻ P7n;^y*jq43+O鯔|/_{O?sxܑNܑ 8ʑ6af:0yuX&/ws9I{G?DH!-mwhAK^Y_+= z/׷؏w eyOr>~noxO>|6d! ǍK^T# |NN qm-%?8Д>~V>סܞ j, C ՚S7UNΗÓ3/J,Y7pɺAzÁǓ^xC_yAIÇkv9<BX_|;E+$)Rq7?*ܠARo;c|2}.]B*}J~Tz/Scw\Ksq 2rhZ=li5iu=5rB?zs|f71Ux#o-x}CC#}|y*{SM[u q\'.޷߯o{'[vTS\,9_4۾S>MK[볨o7uJް.I^aIe鍋ܜ*Xfp'=}b+]O.c{R ֺ;%~8¢sP"ZꝮPB/^pX;{McwҸ[{m#X>]OS>Ooͥ/=7'1g=k7Ӄ `g) ^ObMl cs鑮K3`s>z5a]w(VuͿW3%XWe&1fh#\Q>}fy+Kc7]$PP=WbNdj~pxکרnǮq{?)N1#7RNw񇂗K[yywI[B./1O#k*Cw]mH/Ծל pjd{z^1gwswXTkKt . "\ysOzԽOӞoBJyuDo}͍_m/v/%3ߝQ OWj$}^c[J=\ţUrߖq>aHJ0=G=a"G1*^bgvw=`vϹx4;N䔍s//RNJO4tK4]C {3"{1_³֯gg<bIX>x\Zо(POJ?KjH|qTҏxϬycƕȵLƼR|' |>>o}[g1ĩo|ܣ\w7;dϡvٟJӶ+(ΚuR_x[8>?zwqq kwBNxL)j b-/૙Uح/H\BcΗx>ufUލisc;ݶ\gd{Z~ĺgpF^hd4o =%}O|;4|۷חOĥu :4fdB&* bs^!w^?j#l \ǧ/Go@=k/qؼR=-?W_"Y;ǔ}ujI?۳kx.3W~N<y#x^Zo̟79rҽy@>| (kȼπw0&F~3;4E.KXI|55^HX}Ev5̣ $!QGQ5غ1a̫75ޫ¿:{rۻ9tb/>:Ne-5;J}r/[ꛝes{~*H⋩)wW*rn_K;KUC4Ҩo~+!FN8gMk;PL^ws/OTz8znߑ` 4_@*$-ϩg$|=],tzMGpqmwہ'lU]z-qqAlC5@Zix$x\[n}ˎ ]ק<' 6'''.\ӷ{_u'W7I"{rG<&~O|Qť!w=.N\E[sߝW7sܶ:|ϼG^Ю+n~c㔸K[|5Ї=EiTp{SȂcOuu(4rrO58罒b#Ĵ&RqN[OTM q2#ec=֒*Fہ뮿wdחymQ[uJnJ,/Uab?%gqdᓎTYK3>t-4z[ҏׇz7#z= ̃Pgס|ڳ) 8Hnoe|&i~|Qb[WJ/`=||!7~=B{?Wᮃ7U?K}> o;B2{7dc6 } RNN.nvgR]/~m=movsaf|%&Ϳ=cTWigTxjDxW=ᅁ}y>؟O<8.p-?A7gT~tXCҰ!~u/OK*r؟wy0׵gЯmA_q.?i*83zg\ sZEZ(Q_^/|@Wn'yaLJk`%U;W޽n|{xדk-3?g ]O[,,_tʘw_#wqEs9 UvM!#5^㓕 ۝1 XTew>}>,YuS+BOlx}rMKG={eS](H>#ɵ><Oj=q)~ݿm_UjH>8ߙK/úQeO*FҎ[ugdHZ[7,,(^|?K:S+CWKX^6xlgh<Z/ OAYc/UC|n''Q/Mjld \ZUͼη ;/γvf3%J:4MO\xG,aWẈ *8A)~u_=W_9RVRb1Lך$$WA>8oW1|=&S#/Z?=$֓KM|r!g {~?P{)>op:aSSU9r҉׿:46vsQ-_?V)x{x&)Mjv0ޙlgzcP eo|P>AoN68.7㹟Lh%5yR#U?׳#+/y>'EXݒ-|Z%׳=eG]0~y'>-_O+$/[0BY_g0`|;$Ǎ50|#KfoWXhcQ>%;O?>zn3_o4%N8i*Vw W=4bsU>V!}ԅQ2ylfL9SLއ,>s=_ |{z~;>MϬ<8A'z]>e ˮqac:T8^:=sXžTM,O+VcO&ϼL*1|u5Vk> ~0,|>>|x{jYlϽY={ #ue}%+=̽qI}}QǷ+dl~ jcfZy`C#}%|=\u`b<_=pqn7sʼ-Yk&_nE߭ U871Vnk5[?[egqीdqz~ ~}?bJMպ㯋PP$~6v r&/f _xoSZo;W-h|M?ۏjޙo))?Rg W̡Ny4GO{+-H~=hz{3ߧc2{Ykd y74>CT!p<ٹIԠY yv_m)ڃJUİ&|v?ŧ~ڰRM''*uۿv^3?/FzögMh{q~sّ?jDP^H:oڐ;G ^q`P۰sXw{x;fd/l>@0?2(}¦C&d?G!_y|k85muh?,屛oaA#ťxݓ;^̀o1,~JytdI oQ\p4UDsC^q \aߗ}F#.0,| }pr ec*fj >^v;>nLnKT;㗥p;&/>3tk8_?@镦]oWcq?$Ql3]=?y 5;OaԚk1vf/Çf<ܢMo8_$|䌳?Sʰ%Gc4Vމr|k|Sxex8Oe=x]d#ySgubg WVt?;?Iqx#zO޷OD}Khx}>S 9[;hzД/D}GqV}?C >v>941E`Ppf<?'qLGYf~^O׎q̩Q|ƺ9\EڏuT|![ m~?IҏjO3N.r^ٺUyBRY]_X>Yz:,?xOZ=aO?KIh2 >oS'Uj*ƪ;jKV OCZGK!6/WT>napMןOs|CtGd[͎72/m.ss ƃ>mjږ\z"Aہz|pw@ S?_?bQR9sˆ(~>[֛˦>TE\/CDiS4q5FPbEhġ>_ lI߿"f$/HW'@=+Jl߿(;# /Cמ;u|I,ʵ,~?{YY_ `u|^>|JG\|\ 7u(ZF;GK.RLxʿ~hr1y|G ]2_]pf'k.z!Q_Z1fbҜ?&ȕBYOqK#(ǜ}f[vNCG·>ᬯh ݦuJAÚ,I^kys8ܪUoZO {Y{x\-Jz칁ߡFUuWfC^V@"p}y=2\Ct#hcQ Ma>6+ڎHJLjfk-G7Sox_W~5""JĸâwG0|֭*|B>kP|~[G7l?kAyodJ4 z^G]X_Qڒ/G(9 0ro7Mr:7\9Jv~4s=x p|jv堧 =qs;9ǎ;*|Sxu\xG2_b_} ?' ?V?jC^>]г>ܦ6M :{|c.;w_#c K3s/G=#Ktް5OlY?PV*3?G!G -wEFHu8$IoyÛ)Ͽ~㝓7TF mWj38u Gyf|n3__SxNKX`?/k[L&ꃸ -O{)%⺑ Gy±>41F5Oo'U{b  ?x ,^ b&_OXQ?'%N~з 8bhPw+{zmój`$ޅ3Q>9urs8\yFnnu׷]4j)7SΣݭo[ҏmrO%e}$|G{*n4v18˼vyz1xWY~E5'rK7|hC׏R?}c>O_Gfzf~,d=YY49#v';` ||76ĻG0^LB֙۞YAdHqE?n*l VW>; UiHԗ6󌌅}3Yc:ۧA+]/1\7u1jMot˸ɐ>>XGs4ֹp lIס|*΂XgvTy>XCm7މAERG~| h opɥF>Uԏ{e{|=I)$U/y.Eiס֙>$:Lg$]?mS|K=q̩kL^hT0qm㟔僺W}?ˡ msfqQb?A}( R)5Oד(ȓˇob~(.q*?NPBuVK'$8c"lK5כ:M'HeZ,ާjBu5Z}9NFnL>>{w}*Ϲ}R-`xE4h(G:TUg#y{!~k8{"L/-sа:vzz+-Ҹe| Ýr)qV},c=|>>D| $po~԰sPCtނR<#y ?y-F g~q~||>#FtqV.uAi:I{5_<?(`~?̣<*|M[v#+Sgdez4fkf諯 ˖#l' j}u<.~3v@d (Ӄ忇v~ɿhxؠcv~=sRe7yx8ߙwb%K%tJ|$Ԏm`Sm>xre94{pܕ{i?ԡOc߬]?p rw5Z3gB?n|\ svPo>v>F#}q}\c~?>y [ϡҾE}v3\(^|\&Paw;󷒾|P_;JD ZiL~s'ZsO 軁,S7Ώ2}p׈ˢ^'8;5/0v (۩8ޘO q9*WWAj8\S* 6S &h|c;AƽFˮ9ƅ_xg]X#uٺP y>v#3)CUVaԞNv~N ; 8&O|+yy)0ʮge s/*K/J~K/҃ s˥ߡ9K8g,2BosX;w]}ZS#~j]q>}sa{ =7}v]oBI3Te㸣p xi'Ii;:~QBFyLb[)agOwqѹ~Ծ %}}rm_-G޽-PO(ʿ/5^ʫs|o%㳡<8 ~E߉ ~e7i嗋ڮț(~VU֥Bݧ%Zoܵ掠OX1ys&C/EUͧ|{w]egCBן}Y^(~P <TRoHN VR%[Qt럻R*QrSbϻ[*:ɿJRw~>hLYINr==]K.kЉWweu"!5˜ ee!y^aGeީX\n%|!Kz-Gϭ-^%Qmrwd/X&ס~/߃7oasw? ; %zQ\}YPma!_/QqMoB ՅMG:)G-7R҇EX୓J}sKUߪ/L_ymC3]sQ'U'*Q%[ Թ|JH?4ݶKM-ˇC]r.` < W jzO#L vz-~1^5buGT;عzb7=r)ǁ 脮'2Q(n}*zrSe#?~O?-][ͮ{3 x^>|Nޏ ~|#R]Q-|&w=z2A1Ș7&-Y_0o6ſ=*9XJ=(A[;T8sNOÞst2r{>M+n=G~x=C25^w fgG1JHb>50̉nCͫ͡jGnίxk sNlY=)c{]d+[k`Hf' {Ϙ/nt={!P5vbO gdeI'l YrnA?jŁ~Ҡw ^toŏx }aG[JY %wOCi^9: ]y==_nk|tޣg/hו+|oG_嫭,J~X$}A=M4~c'(&{ݚYg>scrO|jpaWŸ {L^#zKD?߼G󧯳 C~V%_Tr.̗!ߕ͋4uÅczIBvufg_Okp;{:&:H>b?h q@xj]k yu Kfo@~YOJT]T>gpMfysbOgڜg٫/Pz"ȳ|qM3p ŧ?Nf~W| =ߐp_ۿӇ;gsw3{͞G+=kh#zK} ,﹝8Sa8=+[F~kt^=o]4஗'o~|[}Nu F}qF\UCTCe$#g3}#%!q1]E_kq}>2<VE;l]8.FFwSFupr>.H7o^#сRi!ijM^A?mp,8G僺WNÚ,14oEsǟ+rP}jo9󆮧y=d*0*{U_G?skzXx[ٻmO~R}JRvW*N|RׯppI80`#_xsϧo_[%bSkiO_8_\>@+}<]V]|8o ؟v~qK^ڻU&V\v.@C s}r84];mXTh: >t_I?>>9uCh[mOҏq/_cq#d$x>>_48]/HuDVWaڲsyQkoyFJx!Iy[7*Ѩ^>PQ݂3Fy?G3ryw{Q??\$SciMZ z.3K{D &#ؿ 27Ūesu9>4#kfS0q)䓄~V _Tȍ*UW)OҝK'&þc~9OgD)%.xp͛Q\mtSXM_r^ԏfkN~S7˟ojd׬| g&9>P;\8?SN"S8K)x28Py^_P!i$OQ鐑Oe)l/[Nkش0f)+)~8w`}PRel!^)sgϕaZen_}ƍ]B%w~]‡aǒ}7(E}`ϒOѲ M(V8PL>ޫ?z{7緭Gy4}p8l]V[kw+ `?w޷+`Q gS٣7-; ~Vo(^zjNJ.v>'Q`=nG]Jcq6g=~ݕq]U}4p1:e G(_YGsOeI5Z>;I>v>g~@%=:A>Ipy>eY9I3Yf~"1/6}ٹfR\+Zܘ ?^<4,'i{3rah> FJYco5j`$B<:u*jOֳٹquǎker߾zs.˼%ҥwovR*碟OmQJɟP$*>=O?JQ׿TpDѲbﯧ9n(~i`n(ZR~I|R#kF-<fTL;ozIq)SNoesicY^S?ܺ_jp ^~D9j!}ٿFD=}_x!WO?HR#kf֛;lxO$x^1yy}8E5/zbVQ$[[/!4^18E#N,p2 !|0=vtV1j1jkZky?BHɴ?pߘ?| iM^1L޽>r՞E.qSinӝK|,c2gȟojd|^OS9 eQLobN7-;wN*9`#yzpO\s7K= +C=o#mCŒߚo}O|) ᪯<#V^1/͜ϥPǏAv>ʜ_cg 金ӮyA]rT. Ø>~Aw/^qk'|0>'ȸ~E GP><ʗ5(uR=@r>2Os NǜvgWQai?]*=o>o&7o]oOӮ󯆉iIXiHI? _5 yj '[p~厐^YQ=d${_xFC0$iX.iۏ7;4[_ʟop{ֳ;?LAeƗu-q)|`s r*ְVٹS >e,]<_?4Jus&S뷶k;&*^%o$^]4BQCR9L~KKhrEye#kZd_ s?)T}Nfm΍$CG7[SK&%~%6h#vi?I#o%շ死#vU?aq޴2ە-[Zw^bM:|sI{+ǫfg\b?=KW Rk=GJr7hZfO<ğ[37T&O|^iX=y|~ q sOCU\>I5} ?,s9o.reQCWMl:)[[pZɗ4[.X7Q67D_ʡW}?G5|2o.Fkz)ߘ!Cy:5AQEiazPkϩxwH_ }$^OհC}\ypo|?aRy7VH:Uש nl2(qmĥ_.J)~VUֵ|Ю}/}R&kـtIXZ/c<{5e޽ S|7|Fovk,(O >u+Y):ɒGqgFf _?.Ӳkdπ}N+V|{U˪'2C*)H][D1Og\!ݘv^^2W+qQ[u/uWx9Ưb KU!L:1d}ZĘ sEA~|='v)Ydo53>@|^ip83_^S؁r.9>; < \?\_7<UT%_>TpI_iغцzǪc.5R\;k5Z| 8|L{)8U ;"I?c\e&V ֳ nsk}Q~%^95vge@:4cϹp9 ?f { cʖore/F< ?JRcםr|#u\#skTp rțt`b=~X~ֵ o E,ЇJtp%*<| u#Y۱~| Ucmބny|?7룐KsU#@Z=!(7ןe<&1ߎP/~W>l|/]~;wl}{[8W~7R${)Џ6ANрC):9{{\(p;/G>N?Ȓ7WTrn䋊F3]3?qAd>-Ғi\?ܿ7kf'%W1D1WscպR^v.b2<_!0_/aX<Ƒ֓='|=JǛܕ¤6!Gh-n|]TF}ܯo]vMpgkx3 |V|ތb*FG)[][Cdy57'pn鎓Ẃ3Fw [@)LlPc#%AajRG:5%19L4NPP{<9Uau| ;1 {=<dEʼgϰC[wK6myMbLo1>Ã_[lp-%m3u'o*~l  ?~5R]o85?֦8SASv`׸k7vMWN=u qSNϾ~m^t\Rz\D]HInh$& 5kƺ哛X~} .;D*Yc5ߜMqW}x/:#mAAGUg3Bg !3ϊGqRG?9owaH\QGp_<>g~'>9J0<#{q?O[ֽ/ujʞ۳kܶuP%>L.~TATK~5[⽤o*z!v:wgs-| YdUw~L\yw|~edpo#Q1a`d#;1`B=V_{⼡^7RbC7nlE^1!3c,?dp?_^'s{Yxuԟ |^vhp)ַ0v9~?oob|WJu 'Bw}W緱} ;~oe>]s{Zs?+Wrw_(kuXKq8^1'VsKUY3Zs.l=upǫ$ޑ%m~#pظ$}9 6rC>Kӎz2?#<3#ax ^"`_L9/抾>>M/1?o@ U /<,G/!k^Bơ>kW$~>ugaxC??dax IZ{i'qaK`Gs \4_hOq??^B/QL!#F%!}nKv.Aw ruifk׻FJa׹XU~/ kAu nc͋x~6ϚKڇ!Q1\oǓR- y2} L~CL¤5?Ǟl?#,[8ބ>]\53Kz4e[.12>\$j=w@<P/|( lfqq,ȋafQw͵YшVhye=a ߰Ph+|0T|=n_|ߋ~CBH((BBG~ /hWmby-g<(pS#kz@ؓ`_>֗¥+>JŁb*u*;d܎OW;rmz~ñ=s^kݝJ8}3%0TFhbsmúLTJZdFK\C',5NB,?# %pXO]8O?A}ց1K);zPqZx:Ii<^}X?_^p3_xv0UE]x_,9DO/:-TUK5suX}_C|w]xm!74kcZ*Wކ]8p~xB0kkPYR^>D_a+ZE+Z9b1o^[]_'\ggbrt=o'ZꞆ6q;@]Z<|YcU? m%KpiϮ[H g&}w1$iW2l^G?j_F_T; !I=&kywn9>hɧHC|=x>yLavԿEޯHfξώ1Cir1Ee^sC䏵^o7gW.J^wPB϶8yG>:.UQm)'5i쒗s-~{x'tyApβj7G|^0?7c' YġlQ".>]o\GTV%˘rb,^ˮi`ן[۵y_]uZƥ9wE}M_Ա9L$f|:u?4h/c0>J?|>|_j׷ ?I!+8-JRam?~Y]~Բ,:3՘ƯWG\wτCb=00R/kZc|v!"Fǃ}ǾD>3A~!f֢sߺ}5(޷48Rɧ$_TpדzTcO} HZnUz\⻟\ݚaoa[?lÃ~twp lP1Zek;Ѥx,!RyzgnW*9mu/NV{,|/Bҏ2䌢jG&y4AyV.zK:x_-1neoU׏O${cyJAO 1LpG;P;?$<$ȋp*T%?KK%~n*V f )KH^_24ȝrh1yZvv^V?Y#D嬱j]τB+͏(ٸL c2*y7>  d9I'?x/F"hv\-;n\4>Hު?֕eRaC#3(b4s1 }LG+7h}ͣGXwrůxȅx7;ƯSvL Wy. ߿x.DmЛxL }֩Xv E|KޏneYU-Sby5 1IH/=K*?ۻyb۝4EozϾ#FŸ=,Uy[3!4g~h&M,>5GLjx(K~ؼor)ݔ^Y6g>r#KK~/Enr|H)J>h{=&Fzqj~Uv|+z (^v7O[ı32|&y}JzWHٖ/E}5l?Ysɘ+_^9ïyݯ,/m9BQoS|}/Cyx'&<<&c0ޫ>eWG$z8/l# ,:PՔ`Jx0~mFՕ-Wi6R>ƽ< ?^_6y3y.tIeo[ݶxlMMPA/qF/yj}uV[vֵ%ױe^者ӹHo$9N˳=j"3EuDZ3gz\U֣Uz3<^y$2Z!K5`סI@+cה32HUn&^,S?+{֋Z6z+$uYG3ïLZ=&>|^?缭µ!cYcoUYXuaۡuoxKL3 NPrعn|2a; ٿ(y"LլW WT>GOB4r棬oq3^ki3HABS,|_#3o]/ N/Q9C3xw? sǯ=-k}Q~廌S nݞ|Qрw0fm~TI_}% #9GD /yiѪ #N9;°|dx<Ä'ǹQL [W/: u {/]4]$9>/@D2}_WwnGמO_RVԡD/tB`&LzlH#uL=#?eϋ^c\o~= Uve4  =Kv]}8ٺ0J:ݳwtĘ?}[Taf9Fc4yG\̼N)^}&p+r7Ikxla> y9[|$wO/uhϕqTO1pzgzS횸Vpyow-Ur :4ܿG[aHev~Hԃ/hơԼ<5=|Ģtb? ?ooTPU P{ЦQE*'+Ƨ^zQ>+ePO>s+ԟ㾅T>6kZG/V>E^Gqf PI٣nA=[|&]DR'NX}3?ilrGYbġ'% gzċrx<}x4w5”({ps'ƍsW|b>یǛu׷$ʒOwW_~v.ֽ wS P,J0%#_ 5F>%ۨeOP<_}i[5'$S;#kZ׃Ἄ[,

Q\x9U\S(<>?4Iً[|Qw&_o`䋊Oy%0(p}|zR?p!<74YRO%8s(ٹMkő]3glKΚ/ʯ5Z=8Ϸ!|i">iס֣VG{v{?߇<"OA9I'?|pe+(qCxzٟgXY0qm㟔^擯FiJ'Ҳf\^9jp '?fG#ZiKc\/>=fK|7;gf/Y/KZ:w^ yQ/|^z`z_c[}UĿSuX<#~W7Uܞ:-7oꨜ⁼b2쓀O)޿S]nTЈ W=L}2y,3HACSIN$/~&=Xk`MK*1Q|#xM?ϰ_+7FQjЏ=ZsD#?>LBP7S` wfӹ}_s=2)CZ6V_>yD?au-({4oLB?~ /Tcr1 }<\7sX_ {ڿm7*绱2p r*rCL^E!ڸ?) %}^=Dܜ,5>Ud }|9-xԼ#¡bW98rrc;}+{'2|m\{R]&^w߯-[[.=]y3۸X6N[~.(m?}Տz7H\fm%[ை:3yR<%P/:u:̜_.mMEAczj?g{7 qD/ &%}7IR. Uy3T|ק"8bp|pi%j7vt̿3M['w=> ˖;ѓD rT}53^e&3^"ECa*T|M09^x */O+\<>zM,J?4hv 4kKkqMK6PYc5E=ߩ9O Sܹ\w5o~kMo|J~Tʰ>ŧdZF2 wuCaLuxG+d(\5NIrԾR促ݏ͟&dgM,ߺ_[+`Q_& 6p )woϢ?JY={=qDryދ?0j9bw̡qx}}'[BKz|cֳmb][ֳ5׭];HOa*'uR\/5a1Iq!>xP&K4ŃksXs+|\~ġP.G3|<5]a %}!s@^ŋKך|loy #T_[v-328`BjM^rȄC,5wlZ8 n{LSJX^z7iR7|JQLv۾EA`{|}UѤ Ұ߃;ύB픍5;Uw}1#7̤# .s~{@JKJۃ|1B_5ڰo#k*[f(FZ\L^[qH@St|y]W{ݚ)WS\܈⇪<㽾/xO4rrOhzqCs(o?&"J/s(BxMHn/`/A &:`tbGICGY_tkUȸS/9Fg#MGZ'߼uLZ>j^@q m[k/Caw`doouO|gX^UHn 0갑zx*N3rWox/2롪?fſW8"S xPXC^Sk1zkryhlKsD!~*;lZOJAH^3rRYco530)O+E?ͼyE5ǏSy e ;^coJ;qGIWL4.\WXsI__rN4g떛,6<s%^w F:LJ''sT?`nwu+8) , Y  =Gz_ʛR>#%=zKIW;ݲ#`g@R2Hh]sKhƷ}g%_j PxS/-=e}HkU?] x8'| Qmn:ڃcq ^.ϼ7rGsjpt{&-  %}/x9Ǝ규õd8A<=O rb\\\=wԩȗaxsR9ul_ry8UNBVףJE$!uJ|Ȳg#UzůŸ {+ |>q${nS{Ke߂ ;7{$K/*KI{m^NK_Oh4mJ?tFn;zŋ}ed)HaRzް~[WbO5>q,Tvucq|+ϗcL{_W_.u?/)+ijVnK\z=s9DMQne=O^5_jÇ_X6dXȻ1? nZ@3kq <5A\|=NX/|~}сq(ET|G,P)TZ8Хߡ%pӎTl~-_{"i$pKxbt_k|>>G}KFF?QX0Vy^Sc2|&y{}Mo8g̽SA*|+G.ڜzbsn̄͠4-+<~dUO>H\/ؾcTNKP7uR8!s;-%hKbŠE}ט4ce_6ۤy~^v~| v"yu!9S|j=ZhI{⺍2tzɮYyKMT~L:R,W~v7& }BZ. 5V2E畆^_|2_٠g*/|]|68gd>R"x^SY?;:ǡ]|צ3Rq'~=ǡi3Jx8m4GҎ.V:Y> ;suϵ[{5q>Dn|VCٲOiˮ"]ω[iIüWtozg{m%oIoD߸_wfW}?*<p՟F#||?#Їׅ50toHIł/vBJgoiktW GIqvt*r2.og@:T~SWS9|g~S[}wo^rjJ~O ?x/KSIw5 _yLR|B*+L:ļ|vE9Hk$D_ԓ}dr󹑲&YcՓISOoC?x:_Z{bݩlOuM7Ou%WXoyoO}Z-OZx>{HxYѧ׺\KOşVoM}sKo zr* ';99 eoub 'egA޾>əK=La[M~'_SK6?4}= O[(+ Zb4?l{pe3jue2DސU>w ƿ򼅰<#ļ D{\`xZ}9/ *m_R՟-?? f荤4}O`NӝOs49I?Hο*{pI?Vծ3G޿\R6ז )nNLWI%2|qO?>GS[f_Et_|АoLo'8~F+d|+ Z*}-5xQƛ ~ۥcu֣ӗOӮy;i}8/ScHv~ |^yW{'43U^s=\حuGq|1O㣖G.KT˃Qaf;0+p'eGs{~*KBLJpFzםj>i"Lڃ\w?tRwf}ߓ_ZgjxTt<\.I?>h^_6Z6jy8zb*8?ӄ5{2|P<߁w?B͏Z ~6jgנJω-~C3: I>F?GEE_Ao1Z]Hrf来0RmBhΗaH#kfCIo SagT?Zv`s~&uR9)33WĖoi~%ݲ(D;'_HIuФ#td4UVsʱxYco5/6î4}bWסb5j}snӠz[3o>ܺ0?gvDfLێ']}oD{/>s=TXҗ}$'Cp MINi4ksU(FJB~xo=\39Lr<y.6S VZN;7~ԫc82}~5q.Ą71zx}#w#wz\#'|F.Y6r=$ ?{G̳m]}o%RǨvdst_Bf0v !S7\80G3g^anxwd<]}5+z AwedٻV3W<9N>&7;b-}? hx3)#8UXm򒒾 $㿑pv+{]/s׵|"KF}uح³*T{N^ߏ}e_Uy}p\ |>e7wT/ֿz.%SCS|ƺ9\Ez̫ヺW}{e}qk?y-3Rҏ~E>q>ު7~d (qu(\_C|Zp~Vg$6 ^*n*/}/ _r%_X}KδP uTY\OkX*sܿ߄W1??b](Z!j^ۨԺ^v>b95ih?ROD~F͏8-NJW{ T>%3W^a2}&iL~c'NZe Gy/5^%g?3aõC7[xy|EUԆ V?oM~krOO((~gzh~}7w9JS4?߷+hp?_&zɿ 7%~׊عȗClo_)<.֏{SQ+#>RحhBV_Ϗr\({9RU}_ _~S^2/AKTAPmKƫr#䷚ }pFB?|g0^eΗ=RKA-ꝀOH'#Lz5k㐉>|Q'W;V㝇?'fjظOKt@绫"^xW_;b$FF1%j>Kǯ> u{7.[O}c}IϖSQ9{Ȅsas*DLLy>e{G+YW_z8nRZ ǮFse`=jIKT{Q"aIՏ@t'Iq 4Oi.w|1FK{IHVӌXV}}DMJs ~֩G;;+W}RJļv_W[ʷnyDpwՄOqOMys?{Fܱr~۳E}q?-5Z;{,.tfNjx>hf}pwbGOs]s9rG=^?w5OQOQی6~*01\b/>Nu(hms)q@U'OQIɡf/}BG|OM+qàKh~}Uj[>qx.xNLcH;xYc5?;l~z |8޸yp蝹wX{Klld}Q:2}:at2*Qt.%^4NX~,7BEҗ6mN:4Jr[aN3ڎwic_~l(w?K;eVmqUr}"ݹ ]K+|ʟwfs6\8\ƅWXr٘ߦgn콯kG7o k7v9i%K]ןS#_sɥIziѷU⩵̼/S6d$3畆?7Rۏ9}/A] ɒтVt̽sN:凅snꙹ|-q4A+mT]N+9)dqxHOǟ_jW-wz#L 8>oh\,NBT?:zXI_Vfa[֛ pܺ<8H4)%2xxoFfg/y0_Gx|lj޾P u)۲ad> ʼS']r2P|i}?gKe.MT<8k{}jdVz۹EIzu[;#\0@V<ynOگ ,߀-2J4Zށ`7/szԧiXzB׷KdTzmg'%ɐσa׏ivM|)eG*7o [O7uypS7UlӃ6WByȧz,<<8$Q57\mGώ9.ׇ^ Ca 9{[ zEʼbF6}ܼ/iN#ihSe.d}حwG?^U|G³W'u}֜q?YUs 3/ek>//]'5.hlg*Mg[鋳`dL| ayaw,Vv\QŽU>vp8;SyA8c#s Oԯ(3+/~vW|Krq4iPY3Eib5B+~s7w`H߅_qGxOT`rsiSSwfߗW$}^/ N"wxn)}By5R񖔽5;D ׉u~_8vu%yc}O•`se{. rMHzi+D=MZˉ#>NAK}ne/U_a绽$5/%Nuq*&mٹXqa, }||wI۾H%W7y(qїzjols#*}kzIAMv/sukG[sȈL%Uwum(YcoU/ɞz_!Nfy}1#xej~p#0f__'Gs\5WُڕJնTrި׿zο&$ˁFdtڂU7 Cy1ޫ޷$>m;C_Y "?hN 7߱{-+_|}(\1Yi%bs ?/0AH _eĘ"zI_HdWXc5ZJ3W;u'$>GrD=Wc qy6gу>vny80>GO[I ן0rѻRQ}frF'__=5!sz]vt5*˳cхGGTw>:[yD7]X|42ez|JY/MtOMfoRNl*~oEkfLÎ}[cE{%RrlS/ЌoJNMn\xOٹzc^ëꙏu|_*AW>F"K7Eݭꏣ}qx>BnC}O/{BCx>{QbK4?|QEݒ/*?z lё?rh\4U_~+֟Gh)眲1&7X~]k{ꮏϦwϜ v70/ZCٞ3)ߧ֡kܵϦ?j.?1YrS=UDq]O)]UE/2(в[{p~7TȞ75kV?H^|>߼GڗZǥ#Av.U {s)ǡfև8{C`ܽ۲x?eYapiG4| ۘ3$5&Ka3g3tSE}ys~ɏB@oOh;`ÜG:8)&_|8 wp~4^gTt['KPQ(q֌7碟Oͥoog]ys׿TpD'_|)g/j@k;%b羔D=q/=فؐ~T/dr1߼#>e{SYJ*QO%(>op:aSSO_+rs7hQ6%׿qv^|͹˖B1:MwEG<!Ÿ_jW- O5_zKlTANg0ՏA"7v`{ )ܧݘ(_?E;Fk{)~ʥV>ٖ /fW'%Ktr諍6͟Ԉ57Ԏ i_lyiDj|ǟ~N0:Ioo\ |ZK*ɩӒWWe~m|4>aKc=Z;S[,*^Y}}'{y>Mg;wOO5OF9}E3G,D>}ifoGqև/q0ozqjj^^w*:#bF5| gN%BSinm vO_t+AF65rhƵշOI_H[+c^YcU[cH>88]40uOV>s OA-ٹ&]}ry*c-.as8q636zvtMNMlDS[21'lŒu1 orˆ1\}|1#%!CSz>.uߐmΣ%VTb'K`W>"Q7ȝe3yi Zhؿ9l  ߿q?8DmC*u8~%PJVue ֺ{&u u^'=Glھ7μG?DTͻx\?_TYco5 %yzҀ^>.|pڦnˣZe%.޼x. SdL~mu!+ }Y{%xP1(糀tyČ3Ҩa-eI'c{ mzM$}a.^p1KhS%D\ IFcתgߌo}b|ħ3E1֨1o=*? ‰iq>RX.jS\U ]g*sc.CEghsy~^@<<2Zx> ?$F *`dլ7,ŷ {M٣vbco -R潟m?9Y}>j=ϴHNk_Z[)}1}?Ik?^gmW#.u8i_Z>籠R<qG~1:sJOgE+}):5S\ ^8QΏ/tN[M;8֮>M?L4WƇ$hj5S~ai| .b{u.zbVX?~'~l|qSwZf/Z^>?{QG,x, op_ ^do\L+r]"t{5٭u༌=E ɧֽ߰vKy pZq\uo9YzS#J=zv]TxJN}oϢu|xkϝ:>;o,}9x~ֵ<"Uj_T&wT`'%(.Sp*~?-;usf_b[Ykϧ=~Y wDzMʵz-t_gc|t³ {M$|$x ;_}ב8js*ufZ>}[7/nB mP}=o_/S *{Qߠ4]vx=֟ZC} ޭ#{%{8n. E # c`ʼlS{h%׵yc*l?/M4uOS{ӲeNzgP5C_j+2/"l>?`R9OU{?${sRK+_鄻I,iih,1'牊'B1j#9)FO/]cC/*ǼY|k6sQ_3N7+8os,x}^vmu[nmM^2>~U,lҴ%/Tcd{QS|yLu{MoLϔz}R]D7[uVI?>|L3G],^wZ&ו'e{cHq㖽q>};O?>'}2U?y_!_L8}.|nՋ]?ei#x\g0^ig¦`zGÝKs#;W;x}oe! O/ɦ*di&MԸ7}|%?d7#kf~|+ٛÅֆk@RJZs?qH߯e'>nfu9,V*e?SNF39瑥_|MUI?gnCß{x}=ᅁ}y>My{4N3/B+}pկ^j׃ܿY $ ~ 8G0?E( IGvɱ#>l*g̿,K݂3^I/|G@J4mFI>M/qI [wG.vo7od}ĪO?Qׁ`~|<Z0(>x,.;'V潟plTcPw>䭂xgF[W;lވ 쳿S畆>)x} hd١b u*bw1#M<㈅Z\eeBe+]8`+>2(8o}q mnafϹCo?z h€Weˉ4ɒӆ&?r܏_\ds$kF_Gއa[?/=Muj^w-UlUN|"]9>AK QWN՚M#~Xsj( l'kYb6S>A~o^of-ZKp^h%bd%{~{7Y[v.b-Hzv'Η(&ȒDh>> ׼$A4m񩷎{|@{;v][goig⣘r?3?j܇)8NGv;I |vd |:NS;㝥xL%')ޙ˒ K ߢ)[?e{2_4  |39x㠕 ﷂyy9pF Ӫ)xX8nG=GyT/aݘATS}i_V d?i tڋ%}#D_ڙ? }38,FkgK>RݺWb*e(LWe:82{?&3o)^Q/J҅=Ƽ#:"i)Te ǏuC~%#'ܧ;z"kY^}r$9ļR{Ul>P>ӯo3Wk#wC*oUЏ"yFSLu73%M_C:HؾPj/Ѿ ~i-Sq{5}p!%#w~߅byFB}՝Bx>KٿGOyx}E8[nP1x;awۻ;/~#{Oz|Ň~a_{ٙ $?4%>KM5oPS]Nzx}f.>nyۯpߘ_\O NRϟr;?U]\"zfaΟojdWEq;'oC?+=gqzbo {z;K4yy2֏n{g\E~bu:UǯT80Gå*w^q7#OqTwBu4WUaUݾ}r@GŪT5ʛrd_}uͮ/e@kz#7QiW_ˈT\DǾe`?_xzor/~ԟF(n;B<53|^>B~{j^wNf)m·En(~pXos[tj,RPY^JA=* hZ~m9>󯙏^w~?8nR7Db Ġ~R8>x{dwsc<_y.a,\q%_e)//Jtgi|Y\];+9CФ.;ӔZ p_fz;xpgd?pMڤ@RgM'ug.ki\?oIrl?GgGY2'bǕ,>K%~q?*?[?r>^}gHʯg/<:fI+>S6e{;# />HW}h}B[뮏K%!2kGkXU 5ox-#+ng<8J!7Wy6~Zu%9wt~7Zz.<> X}MU[ۖ_z_ē,8Z!]r:+Eo|&+u_oQI ؇'|=JwfӹOx^ռEhʼk_ŎR'|__k3o`xP;X.ɣ ;aw{pXvf}3/2Y;zTWΛW;Lg^]2Od8NarPaȋp BCz >Os ˇﭜ }rf/>Jnw)1bQϞs$}^=Qܺ<8*JrqSE}~*GOk3?* ^tU^1ϣbA#9oCW?b}*IC?mL;`*IE17Y¿?ug0ޫ_TUT' }ܮn0}<pܦ1#Qp]5 gd"HJi<83B%﫤/y=p{G;p͔7?8FFq b8}Ospq~Fʏ{9\ŅVV$Jlaϑ5xT\Z>*xZ9,?ٕ|*aOSؐnԩpn}oL'^>u<} 㤱7C.i u']* d~]^_9`)i8^S3McJxk9- ~.0h Q OwX] jTQaQOL=݉L5?1y dח {s$ݻ1u*~Z.Cx*81֛~֗+^u֋mZe|QI%hle*˥9U~tre3r[͆l\O}b5Z3L- tKtj- |>~5}x0H!}Fo]oyy-=lōQ+jO vr=U{c4=9CriPRN+?~s.k'lMX%kf/¤zp4yx 8 8O~z ==)Bߠ7oa}mBx? +_o~ۛgl`dC#N5_oס֛ -eno_W|ٛYguej_ҏɹfĬ%x_.{%xm1 㚾|B. xud*>1 ﳏg|l˫SwrR*1ܪ˶Jxu#;IOkytb_g-9^Q[Mo&y=TIOyw%AC${ VOoԇ~̜WOo7&ʗE;Fk~u[ZBM~4FOjD{`i~]_hpBIMU}|"L__fu¾~*_{;l9HMr42! ^=P1K|s_nugΨn94W^=Oo=Z3opK>/<h0;ƒ|q}\ WA*tG.TRɠX:9 6p *{z~C3 2q7ӁM›9cwZ\qżRYcoz=*7^߼|]k"6^ٛ;Β/#u}*[%1Jw'~xJ,|uW<@>?au-_ɟ (LJx-y}h|r#v}93%p?BS5gYR]C_2Fź(ިKw/*ɩ;5/LO;m_J2 KgvOs᪇Fl}2yl;oPpm8Oҗ9N( WW׏Ѥ7N4~ P>/knf>FJd,)\)9ya?0DpI8V|`C%k }c>q,$}m}!#M_UC:߆`VZuP'$߿z,c?E}F#e)j+R{\#FYֱ:xU!NkşމaqɭB".;۾S|:nyo3!V?Ԛy60F VI[[s^o/?7Ǎl?YN4 R:޽>(LJ{O>kqo}Z~=ٶy;!79!ꮩH߀ dno&~xNPחI?>=_#k[W6YI?LJw3{|W*ؓ`X?1~v: o_5O'=4xfu-n&z@q}.˼c>6 Ʀſ[}w/x&_T&cBqZд}'_4/?y-kYo ͕\"{)J0H쿂8v*ʮTΰ5;L׃e@tBק][]o6I_"+ ߂y13X^Q 70y pQpԩ_>ws߲h7LZTro)bS|xg I_ϏХNy.'h魹4¢soKB842%E>pec~KORy>y YRu|TVTz]ןz7ػTw9[A+kӮh/Vr'V&#vV-c:}dC#cPN:3?$H1&2"*}qK>4֬뢶,z?) OQYc5s\W7Orj=*q/r.|~cFqp.{Po>0jOBwTpHu?Gӈmh ͣgV4RZ;Bp߼dUm=R`f zp\Fzmj7o'Qqv<C73C0j$g$XyE(OE^/|k+ؒET~h~;%vġʒhsHowԏ[Jyz!|;Gk͌0RE{>V?^UG+ςB3E,Y9^4 ?j=^1Z2s%}Ex뒊P{ C1vS{U&C|%58D_LǗ)ﳸz_LG?/>Xѯ}6}t=÷Qꄯ)OM6^_Z3u\|LJ,(Lbr&׾dA34l_?4I~>YB_J=w?Vjɯ <^_=֫'pһLOӎTܧ/iiՋkش 4/փ{oVaA\ah GRFW8mދ[=[JxEGReGGq]/t,tH'B+$}:D\}e4zS}Rߺ|쒌-x>^vcګ\?9>|jFF ⡽N5ŊOgm}*:={AL0챓YDCܩTèM2{=/mMhaA{I_H3+jV|G۸ Jz⬘wLkC٪PzF'p٠_? U meK i?Rov[ Gt:"# ݦQ|Y:ήWg<ۚgiكYАNuF4٭_멤x([ymoqT1y[sTXǂT{- W& g7/)bOt='M8ɒФov?)}C*7լjy8=|M US{عiqP ˽׭olϫ,*^[OQ\ Kszr3oWE(6[KVZnueJ?* Y|T{Y_I3_O$֫?%X>Q{?? {}'xؤν;JN+n=)}`*Tf\u>oDcs^ӿ{>M82MQ~"Zr?'z҃ w9*ɔ&Yc5aׇ/ ;/,?(\7uSUWxC\39we!ґ#d?]΢y~9k' )>.NLޣ)~|3__4{F=c󷍯ʧ~/y}KYco53y"Fx d0h9CE108~}'Ԛ(l35Fg|\t)Umk˰~\32|^M'HeG (>m^kF0Ǽ<_!+6hd.: 36c׬n\{xW,X:qo|yJX܃_mL?們T_踘6u[lm8aЀ7?]Ev\|ݍrסjFpW~.yM0~Ϭ+0!m'߷m^=2WmNEǺUz{C1 r=TIoZtMoƵ1qZRޭnm_|0=B9|=oS/1OU7= MU!IJ2QE(,CT/2B 2U2 d=C,;?ӛwu[}s~W9kĎ~vdvB09?!#W=cV: ?wqoS:vVۏk~8m[{u8KI߹gvB0?WA]CqDygu0;,7H2s\oϜ Nqp?xg Ie|ŝ#;_!pھ/^77ș/`__vuqn7ƭ*xҗ]Coz(tHzsN\0OŠ\jMx Ŋ#KxOeL}qܬ-|M jp p ve'@{7>JK>Gfk.=48s_gwdlh*Ծ%+)v|,~]$~CpWӏ+LP^K-/6x}xJf͐^v'Ckq?)D]քE:=T1X*%|؛m_k?G/_6H|8ُCLۯ7? Hq| S󏃪t^_c4'ey5=guҋ JQ=3Y㿿Vos,Y_|nyX aXNv}눢]w [ɾ539%3mWҏ+F6C=ijs}mfog9m"CyCO~|R'"/ow'h]?@>a COuL'/ɧmPDwD|z,wJ/<-^2\$d\B'd/+Eyx㙹uزq7`ܲu|ҰI$?4煮6}a]+ Gyo?KO?E|"pxzaCuq}anp`{\Kw.Zײޓ{2G '{a`UgoM a둘>_}8S[/7v;g3|gi?߰-K++:U>NC|kl>R4Gۿ&P,޻ts0ٵp,gb5Xnr?f%Cwq>??@R;wv~6Χ+_y,e s c|v[=طI\mQ<ZSd7n%νUߏag GNfU~?_4O>g8&s3TPIzk?Od>j/fMG/}s}F%&쭜Oe&Ӡp"nqtQi\GKp=I;R[&㷘Ӥ~t^O è)/?of}JUqt IlWLh__-[;j5͈m>4\-ecV8lCiAtoG 9_X@9_a~}H1^s`TG>g#X[\}4Cʸ=yQ?_B2o?{gN/17p׋#FUffHpS6UEdO^0Au{^=g?O[/x}"OXzϥ̕44īϒ?{F{qol6ޮ)ˊ޿*ӟv|s$8?0>q?i?tEnآܶګO\hX%NdF]ӝXrPzhh?ʁDZ]7PWG=>^T<@u{8yuv]$fȼbw~T{NHձlJ MJ)9Z{)%]2[Kv5}|Al~ٍyZR( ۞,URDZ'B`n6:>#XLA}Z6Ű WC]OzI7e)zU6l6az?$Nӫڶ=.v#ܩ_ ¬f:z YЂH8+4yG.^SHw|&\g4үiCP:g"_ 񏫖ѕ1Tk*WЉ_&Z1)=gDbO>)۹7F9vߴRM]59N%Xק_s3IlB&i~n1h$ NHOEor9D{[I/vwoGw0vvy1=4r.2N1w^K3廦z+髼hkh"m:~97W*hTہ`o[}f^ɋxڛtҰ?԰Gs)}|ItFd1j"Hgx6[H`o_^y1gɣA5_勫=LΦUdlZǬxW{] vb79>1~ ??~Mh/XƯH?*U8|jC|gڷh24$}.:C;Bm}GžjzxS^*1̴ty+{=Kk' ޶_y~.Դ\ kbȳo5.-B;ʼq/H]C"u@/efizSk`نF7DS2S{ZYi?&hpAOPE.GW:x|YpZx:gZB)@pu[c`kĆ&~ z̯n:, ڊ`Ӽm[S a] 4\z6J_OQ?E8BtI[ӓlF.XijAhGzQ.拡2v̦>;Wu;Wgu싟L7no?Nquus>E"{Lo_}rUڋ+~N:oF=^o\fm[g35<ͭd8v}+R\Zߛk}!ϴ?},T39OS[jtŌϫ5?uX8E@|bfM‰)*cGx9{7ܓE[q jy~2?~zc,_J'^՟{{Av3MժXf[-*ڦ9B|{0,`) C=FMK8zcYyYi'`_ A](җ]C|7?lӫC1jJf)>@qUjo8EF*H2x|qsř_R+1 <3֔t.*p&vpg^L< rƏں^a{A3ˁŪ_b3Od9* X_T*;5鼢)a)=S}Tk@W!>5%$G<v]>XO%;~}uN_'77uhGʛ=k|s||zx1l5amOMw`H:A}+qxiMy(Y&I>asL{\OwQsQљ"s>1~f癤\SHP%O|*xp ǶOHHL8TM _qzcC85V4y&/1=􏢷\th7As#ſ]kDEOjQZŽ!] °6dO/&l ,n U 8vy7pdeoTjyUPNr>b3;|^댏8l hnR/}]Cp<)}m+$3}C/< v~*>/ʐWܑμ\{$l??Gdgz糊&IV*$O?kx >'Wl"H<Ɛgqt2 p7\ycBo| <Gk_g웇߭Ri9[ac^^.zk`׏K R>s]W$م烗nGO[TI[1rKckR~}w[WO(ZՊ9>ھW1ج ;T4}Cf!z9`@|;ם^Ρ)e{H+%_ W:M~>ߎtNi_U{3[b ttE!7Ĭvrn.' seG}/k/}>3dN^I~*-%O M f}yxVArI~c(_p]w$y8p^\-OĒ-?ٯ[u8ۗoe?Io ȷU|tz>9IASU%{lJw,U4|dOyY/rygyYy)jJ$Ģ_ǃǃs|jb?4z[X#jJ|Q2%IZ/8k[ߡ)MUNo~jP;ώ I@=O1+ʘ^eJ:i28>.CO,ġ㱩mfTNR+ c^W {`pTtPz(鼧iIyo?/JwMȋanAGW{zF?[gi݂dg=@D\ۏ⡓_Ƒ|Oa?yq|tNݏ* im[8d. ]w z3z{yhn?RcIFmLCb *?R|wz{Pi7%M⟲ە (wf[>}3ܙޙ1$8l7 oS \*J{x?LƸ`l]g :!Z~cp\4NCkpT 1Nx?\n2Oj)+WU]g3G~ Rd^ *2(ܻ?xAzhh8HPz~`]PzRY/ OP{L#!4K9"; "Ch8à 7,5imk=Ow~Xn7/ XtxyxG ?o,S`Ӗ 腍U/NqQٟfoO'K&ˢڡ2t&Kٞ4io?5K(o]M?S ݰE<]oϴ*~_|OIq&lrl 9+uN8)'c =vcIUmǪFQttVIzQ#yeY^M?@zø?ս`k,c8R* Pآ^m3,UihAW${Qi~(+ד0|X~m* MO]L_f!ULOW9lzr-4?s5}f/7ͫ( %7Wp~~qCa)\H^dwz`i2zDA;NWCjCJEpxsq ,זM&?4F#,}PO#( XƥloBߡK$}:Q7dEFiWN~d$㛇cyF6Q+e9zsFKFWp?C4?IYNr!+Xk(MO%7G2<}i~57>ARƕ2ɋ%ə^Aj|!^=+ԙYCN(^U'?&f5x=QKԲB&p뇴(#uXGWyV|~7Uڃ?|=OILz.!^QyB|5gROy):lgoONmS \qg6qBNmqa~/c=|S|n,{]o۟hKrUG?/|ꏊlx^XGܹIf x5UgS}̞af~i؁:A GXݕL>vڙfRI>ۨHkt.J>z=ѣW+!l^g7fq=(g<|MAp밉8N#|Zz8c8q/ޛJIno^Hw =냭cɋۓz0Xӡ/>6R2xQz}׉R3D޺gVi{f?t9Gbf4럼`6)Y/ku^%aB'|'L'x+̬w 3Ҟ,&JU?+ݐQX7JP韢O%;Te_ 2p#>yƌ5g1j@9В&AlC(5㣺FOQNtWZTԯru|Զ'uA=`~"e"ޱoN r.wl59%v@R+F~M=JV{zl0 {G0b_Rb*yn@* {!K Wgv Ghj(o!Q$ XPiB~?e/z# k/_d;$9e1zt\T4Ig]<v럾q\=r4lma~ӟ>nvM''/府t{g;`!E.s}$GWP>AŰ "e{ X?1;>jo?Ϫ#xVʒAW2?_M;7ׁ̟K3\*`3ϑۙTg`e?_AO컾Eo`9L)ɿX>>85ek%ŗ˔/w)Yy5=hBvC{r7_]Q4xqY3Onjo`EަN2,z^:x'㓛仑]w Sd ?@l}~6a$(_PN1|//Q^tZ2J,ayYQ^͸}t}hZJR[cpҍpp=:<vOT3?9ެ,goc}]2l6hq |/J: B^җ]CFs*qy,i)xix`Hy23*oe8Xy +4Ypkx˺}24yRf~Һt퇍^xJn7/~n _E O__w =c&d)5O_%zq>T)=IήyA@d q4;`B0އ,1[ͿKπ/N%n5ˬCdn4lTE H#f=5,Pi@^w =Oz "[ezdyBȇVyKf=eϺjWwɕ=v\߭j2ewC͏<nPXjHd|+$!Uj&/k|mwjBBҷ:nkw͚_J*! 'w ojϑ=V؝q3꿯<Fh Q'\$9I%2$@>RWQ xi/ں_WÑreRV4y_j {~v3<^r$үkw۟O?9&4yKn'@/ W)N(ڢt#ßE|\OPys{nN<;Z{t)UWrk]$8}ubjg732+}[3z皚Z5h&lyXvA~ h7GRIbr5Wosw_'$%I;QOX昭9(Z%'82I\3O%oe:l(0؇f3/㋛k)ޝs;t}r#RYM Fﲧx([wAc8ȿ$'\GW\{ e|^?zSv_+D⟲W"Y~ߗVsA3e,n,ɟ-5o_ c0,way0HR1}?^c?/vB21OZ7H\Eqȕݨ>:oc| 2¤4'CLGʇ)θs_[\77h?RSWL.;Iq_~kY/}]C/if\3+e\ڥΔg ,oA鞊1&%Z oz|!:p:S/p%ٴ:p`fR-·v;@ }i~5ڟ"yܤ,q)5;RU'MxPe} W?k)ˤqi}R.]oV?p6Y[Qo`]0 SS7wkv),kSA LT3:ekze_^*3{Y2xE{ۖ48 bl:\zJ=\=ܮȲ=t|  nѳCa(]>!ROrO{ *Ɏy?o4Dyf!<& %Rez-'QĿi~(KS;Hqra~Ԟd`{q/$HNP)zDIY[-]Xd9ԤD \,/I\Ez{l t)3/?f7Bz.ۚţt~Xcoq`xt LtFӗ5>+=y3Hz,BEo]ų*!f_L&,D&M&zGo/bzqMxO1ۯF>hKWiJҺ(jAѕI1cJo.X \"z iU/[(n '·XY5Gf0zd$ >Yɫ_4?Z&|etu4Amܜ;C9;=y`w @u{4s9 ǹE}zhi܂oP|]~z[Kyw~g/ve|ZִL I ISx$zlٹ 2RtCbE\^'=Gj_+^y+CKh(җ]CO $lԏ)$/)J=j7i}x?f/qqGL)x} =\D[EYNRF!l uy|2*帄fn5"墉??H9ZGIov=Dz/M#h=?WCw&^MsUqwBȈyGۻ.,8BOpd,*Ug_C!`_K]C !]Eڑ;3/Ic)%- W2WOVqs*3_,RߏF}+W&Ӣ`׷/YFt@tHG Ԏ܏fTgxd}6 r/B3GAbfltB~ѐ1=iAG7D?!R+A옅~Kʥ{<V2ˁp]k`o|*~]њP$UM¦ d4m^қw~w{?#G w;r<-5Qq!^_>eGIk_? pgM3/43xEf{;͞J#ˊ3Zz8KD@~U]ݼQx>ت^^{ mA>fVu~0Jdܞ_fDk`jo?%鬄Z{l/sxfJ?-W- fZ4 {]xh-<} s<~ۗ:^!OJ |_ϒ2° ǒCJfO4$(7IV拇q=U>H0X5A7q)}_"E`E]Pzo7/)&JR'{d}2[fO))v~'t^Vƿ~^6z4S?Llq$H]nq#B8,0 OZRRk~GzsX:zzNK2tKTkJe?x2^]R≯rH<6v;+ohuhG3/j{WNe1v޺786S1s]fGtJ#LU.׿t< z.h|3RGWܕ"UN"3\{TzJ2L>ROǶIPP:~?q< |{nGE 2z{0[OȤ|4;2 hɵtH{#L#EGdVRi(^koMy d<]AWO^Qi[GIω(+dܞV՞z]U\lEj!ޜѴ~\ }AUu]W5}q稼~[/?驫]u~jGSWkO7uYME3MR?sWu8/q"}]Coi =\nf`'%G'#u:DFta?yY du=|YcGF#FO^lu>2*n'׭ wY~bX;{&})5Dw2/ƣWOLi*?pMw~ ߚ+|v^aY.7 Aj6W8lj9w޴4.oM)> gM]Cx=_Gl;"g*?dui/fnNWN-X:zĆitzjn9'*;|l n= Ce_};JWp}̖?e`}1۞Z#wR)C?#3*yn;Qo`jW(NXG9|d~T3p5.MAP;ov.5@_`~ NC]+zMWLآͻp7 DizᮡĿg?&lO^ܮ?y="^1gtOK<7&s;{CϐSc^j׳?< u<¥~G )/5ަQo^ WӸ.z{R->?]/&ڥ(>o+$/&'G2K]BG}X%)E`_KM*݆?Sza^0ѻ?寡3|W!f :G>؏'+ڑພ1Ѯ}z  ڕV=3Ch_*i\dOy(ao#Tv]wnW6Mvuӳ'6}:ӦOW֮.}|ҥ6U?k.?W{6OUWի?/]M3Yӷ}ꥻ3]. ~IGn*J=!F1GēF3Mr1+xx.X/{>6Qݤ{{ߴO{f3NqKK8Mn~H)| 2>wqtfqLefl_07uP{L1NPީ0SL`|!_~e`3}@>OĽYS2y?(^frk:~3:|9e?I>iIq!&4y>(佄Ý'\S:c~*)d򾄣|J^P8iϤ 6f&x>^/LafG-( ʧ]X?w*`njodVfg۴X/ F?w/wSN31~`|N-f\???OY9qʣ`b§ޢdVsw̷z,k3r,2\|ϴ 1iǤک 1{̵t|/:AwXq!ɬ\ SAǝ~_֛W㾺XKpGx稑hR/pMw%$u+.yN&CUkZi/~ri9r Lh$״[69{Nj4xs ,]^pNG8ؖ{Sb> <3U)LpR)uTબ'&+t:#>V\| \~֏oUPE_x@Ti= 67ݏg'۞* o5pmB ~9x2Uҷ_cjSz7oX[ߴn΅,PاM[ܹj~Cj0\9;~Yo kf8*F,<;OCpԜA(^x`(pζ)x7> o>ۻG𴃫w<:9eGۑbcw8>7Ĩ#o;:bvyR fνGhrdLw}{ .3 >x<7WM+._We=8?*wk (_gN o7w<<6.*,R{f~~"%<r]Mc)KP 7xR_*ڡ@p| [^f'[]\!'gk8+-ص16O/ܴt꽾"/~kƐ~i..F n`Ôz`gcL3-J31!Wο; lKׄk ZZj ݷ$}[Sν V]Kp)*o^w҉888 kbJK+*x6utjG< Ȏa%g:jp.4 oVEپiT1q{kزײNgQ#Us?cph>ob p<ʅf=QcK~~ycsSǁ/ݚJYQ{ip#>]ydλMÃkγO;A'T:?/t=Kܚ (|@JZ&\8b+~?O[6ZmҵTl^o9q]`o+ ~O mA}r0$hqJm&3͐ҕ{%R?ǹ_ض߸xy-8 f5=Ɉ= jd缊!NZw+sҿu~D]Gzc^{/OՎ}٬DZy凘Os^ Ƹ{qO53K]>y{}8Θ(˳g0 S' %'S}f8QN s+% ^L= *UTp]iUhwmI +Tg]yؐo5<8} t6͙Z6޻yqY{VgwZ-b؛Wl1!rCOYk}\H,:X?PsԼaywdws*fqp?Vm8O>\-3K h^\(숯d[JPu1ReAy#^?\8_yV< zV \K:m;׮#is)4b_y=8γ4;8 64ĜyϿ .x{vһehsN?狞ѹu,-Q IybaFz._|a{~li3S!FjׁK'6(~*Ň!] v{[mpWv0%Cz yp=Zlg 9MFHyqs๧L咛C 9[K9t U^wkت(#ԫ>΀GϿ5_ /^_aRq7׫s*6N޹{ÿlzzܝ8{?x/"KpP}ZQ.7Ϭ 8w}-m^zs7/GeBO>{7pO iٙmeK 7;8(Fҁ88Z8~nCylC0\[ZdL_J{␡ϗ,_oI]{nt9HEub-j ar^uq_M=ޫoWxxK=pzV1uϏ3ن?8T7>|t-s8#CJzʥOSvfW[}n57 <y~V.}KxF`;Z^w+_BIl}߂ mrOnLj_|2n.ԧ= Ox8ъ{ aO S bUhGYߊs1UhCx;R'p؉UopfOac^d2y|=V}VΰPuA;Hemje!N =󃣩J4 <nڠ'M!V ,zO֯6>?vROWy<uA6OwDNhxݗyO5\Q>p/8l(ܕkI`CUDfzl{. m3 8;oq`vg3հXta붃WLҢ};0[ր3RvӼUr,d|!Eqi~Mr%;2_Gr}ݰ^A=N9 _ylpTK\oC;UNSF5° k0Iݨϣ~tpp5{tƘ{8CA^ﵓM=V/QjB ~AvG廁+[j? 1_7rkly0I{3߃?NmwןO~\#7Q~{ʎ3nt׶r<`?zf_}!>b7.~0o(P٭%Ct'umެ¯tߚi'i8Q zЧG8G 5~'ǨKOȞX&O"7ϛ]Yu?6W_y<͖%+l3kNZbJ}0Q Tʂs5C{$Gk]i l[j?3.OO޻C [AkP{ӄO.|kn%^GAey.[`2#Nne䷁ًvMNc{a؝a?ڕ_j&YvdjcɃN-y/tqIܝT5 y^Y/ۏVyk9k kǠKOv~La}QC=x$mFg6 {ʐe%绞J('Ϻi\kl߆fa M2f |Q.zղg~!?F[ZD,tJEK^?]J]lsckYOh}gE=C/wrIkxuDآ<~oȆm,9~:bqivB/:3 7:߳ee#ph[WCX/QjZ5^Fx}u,kʠ*|6xtCf|;Ҹ!f{#]'vǽ.'Եj5sadO|\Gkdtƒ뽼[_xsg>;K3&L+c Nni͔[Ld^ϵcR z~;KEȾ\+|,'O`ʒ[?o]!QW,Ĵ}nO\Y|Y.<AWOs z"ٛq;'*6?QOߋ=~|RATiސsG?|J[BI;&~A7#̠ϏS}Up}%9`/N/-bi( TEW)Na l;*?jaW v 5).oz_T1j8]'˃rѰwegR^ zܧG=sa@s&Ϙ{׃'6ZJ(Q.~Skcg._ʶzj28ۮv`{f(BQxNU۠o pa[C,S%v3DQr f'r== FႧYjgY>5R[GS.m^p_mp38//zl/ju`G>IUb9'GʈS"nW}T|5gri3Vo[ik7q_0ΐ^K|_; ~AM^{'.Uy(DY/y@3M`|~nW3'KGӟa< }yM =ƍY¤}5w75{W=쥏^/39JF#"x\4m]aG%|g-?ǵ2-^7(leWDjxb{x@~5~ )hAclhA8ߚD=o;Un;_e] Gw 37zMI^5MB྆eg#̇S5rW/ W1jv'}awQgY{( y%}-bx%~Pbܾ*JbFyI4b;WhH/߀( {qs}`2|f 8Ƀs5%>Tv뽅t5bOtW \8j<`5Ǩ_Q^}7>}MwԐ`#(Ɏ'ehڈs\ur@B[T"E1h'}F .*!6מwwzoIiJ<Տ'G#aua{;oO}F^`CzQHou}1z՜4Gd&_dC韨;7!nW#S~bG6D1qlu x4X%nͧw'Z]1>{cu,6s|q׀*Kq[.XN#:wPjp7WXxՕg]B;}O1A_Qd Dg*|!_ nKd?y>d؋)\2+&o0?Yw6)&k}\l%/\(!XW]޸iv+heOg܀3s?<#zygciOG xشygox=ޣ e=׮!NrOZn 2KzZs0y&L'[ߣ?̭jm*opO hwb-`F%=ݛܳ,8О'{$V\6_ewz^ZKeGOáeap]xy?+GDޟ|Q'xW_8?~2Y[2ꓤGt l_U}eE? XeF G}~.M1~&M8 JWi}^8_ɽʿ!V 'J{<_0 ?4zyɰ?TVW$Rab },z=D] .6]a(%֥;~37jT{jbSQz9h⛞?; \!]b>|&m[;@|p"$^kJv 12bhxl__F>˦;Ѿ&=ҋ횡 zkq\ʷnKT:㓇4M Q'#].p]b;x^}C 10Jl4=Md{y~|$M^vL_B};Zbv1}XUu!6gTf > 8]9*跡}Qm6xp]qZ@ Qlq*A5=Y軎\v絁X-gB+{r3Cm肽&,lҠq<38۪+i1>?3[m S籚M mb#:{E~b=dG?V^epzsM7ofJpԗ!q8 q=Z?6SMN91sdwǢD(ؘ>>87~4gy_^=ށ˭ $gx=?,gohwcr'C>5x| f So_G~MHrFIP?AXrd=;Av/BBlhO$&0|~T}H B*Ih&$0ϟTפO&2$} ;zSxgw*3O8)F\)a6k7/H,CP[ 3ϯxn)mKϮkMR>@Jɼ9O iL4Q Ar&$vkM~R'W yg+? mRH$#Jb\Yg2L#nywmT;_3>_d<p $>gfHZ!Y i6{G=Ő4Oļf9)4 0Y}:әR}߄v)@Hv Rp_fbtrmƼ'} U N[5 ϟ%#N)$W; afc O/إOG!ᔈ"~w$H}JfIAr&çz׻qf* ~δ]R.͌E{`֍!y,}Rpp[z_'#MF~BLjcgSH<i:guVwjhjn8/~#%HY^ k€IDoRkW{fCmCi\cP]o2󫹐<~TN֐{$~|[Y=)گwR(BzA|o2oid{!+B1E |B}~{I5H\q V o9ܨ|s/nowVHDھS!mTCgn;mވcCopgc' ׋>x=e&1NCrjSt77F&1$ۏIO>~I|+ow'߄4i>| }Ĥi8nÐV̿i% WAڲڼ9N|C﯃ x5Mp }S@>)z4ģ>Mr3{/S 8O_bsrM1Q'r?eуy6KhF1cB(ח?HтԘ?>C"I%4/Vm'O}˘ӐDI.|!P.W`~FJ Dl؄q'!;~X igOE?A] !Vo\cOxNS _/ˉjZ_R$crkYɿԐ<^Ā _G(-߶.%K$9ORǹ1aYf7Jt_o=gOBQIS3?{)/@wki$TuojH#gyGOFx$,~R)gE|ʧKpO\HH۝$I>=W_ q I_|yrj9ϧzHoLǓs\`"*>킔de>4ج $mI=Ŀ$/}}}ލu?~uHjWV{|_{ %Q{D?)4B*H_H]$~W$'/~4':I|p TCrv ?)[HOf~9ĐkHQH;_ - Q.'~'sNݐOO'ѕn̏ӟ?@R!;.I)Z`Tƛd׋{7[3=$muo1+?vӁcX_"C{_ ҈/yto9 H'g>2M+ǎ=/q4 _%@%Hr32c[)*<#uNJ] cLljqRp ˾  %V A/hwEMtFr%5iAX!NJuꩿMð^5T=k'> Ϥ!C*I%}cz#yeSɯ~=EB&WwzNw\OQ$Pb>5Ȏ&lg!0 וJofZ>S]{Iu 4[ 뷷G6{_TX(ҫ~  g\zQbK\i4S㻥7iAAİT$Gn- GKB"~/.«dO@Ilk8yxdO7񕡧xԉ }aba}ǝVR-rXrFԶ%6ϝq)^ϰ_|W%>0cB7җHDWrig=&+܊K^Sp4og_A5*jǹuߜ;X?# n = W)gIv!Q\!xB9kxKz~j7ŧ?~ |g''SH.<ɞO%5b-=Np4룩?oggֳRtߙ}z21[':a=rk > oNhHW#'u(cqb{= ])Oo?.aڑU5Ikߞ}_VT?8$tNQ%yC~$ϓޓpx}wa'/AJꗚΞ IV9 cn|jCSQ^$kS1n 䟖uĜ'>/COS/1:dg$r&cOoaG,gg5ujN~}rϓGHMnm OA_ *:lڹ_A}A:i1(9e2^Hq|i3c_T&9gVTM|nO\㽮R~R1wC콁O6*χgJ 7)>I* 8*m8J8N )8OI e"9Wu̍J9 R1MћA'NXS4m1C6H١JC;xu*9U~I3:ߣ70*5s Snby b_G|LR,[8 Ę K^Qrq0;!~J IGE~b뜮#|C I:urAHxY'aϜm̛?ownQ׫po# ܋k)+i3oQgc/b?1AΥV\i3d:'?z>)UY!~r q8q_$߷n ̭q ?̵KMBTM _ne-Z8dNʣ8=Xc|`KElK7[34̕o)&|">h\D:sH,/HF>@1ψ\'GW])aH{rB󙎮 urxǟĺ̆$#2֣bo`.qq;üo1g|\C~ H"}c_j#˩1]( bn-On$ʝIy@obU2p\رoD͆ U4l=9N:՘'o?f\u_ofϾ>E9α|>;tnpn/{/Q䘋pSď-Fr+1Mr!^%}@tɰワf| 딋!!Sy 9r8GB~ٍ/wΊ el Mi}TWk|sv9dxJ#tWHuCx $kq7+9C0'ueEvnuuY MIC_йs.]9;KEa ; m]:ݣy kϼݮx ()׏Kg>敯] ^8Cڱ?ȏ@tAz<=T S{?Z5_yS39זo|dPJ Ґ|xxP[e.qi Hs`$8[P>`i;Cx_ݽ3.$D&,/ N7F;gm^9% G9ē_@AF-uxޫ%^~:ihܷIIحR~lcǖf?6~K|?qhJ69˧~!L:dG1G's혔XO\]#{-y '{\͏HyJtu$<g+>L{a}_8% }z5 ,9r+,$Xn`ui!3l7\ЎƩ0 K헃#s$}Jc]B|K]=eP"7L8$8ǜ`=ʛS5 ?ZiC'd-d q<^G;-aZӞɐI UQԥN ?_K5$G^";=R)jT OC=/}W 1=,Qϐ+ đ.C_/;0[Bg d!êv19Ijmj>@2ls$SvdvZA;5GWćW1~YOFzNI76  嵃n<7 1";/q#NMWo=_q>tKbBv94t'_'z#=(;Z-qJʖmҶQZFC7[jF䳳P%%᫦ 5n+ | 1#ôl4P+^_!q'}G⯘c-~r(;M6rB|.m@$y%᱒h]'z9SP~u8̏NhwšJ3=%?W 7ߓ~kO0Ej/?9vWO*Q%k7-[2YG6?hW9{hߒ=tߘ+υU|ֈX0g<,EL09*$?k",oSQ>ǣsKA *;MgrֽM|3ڵH QxŪ7%9ܴ!|ϨݼTb#4e9AzUH>E{+o6gDxK~koG;37Y̯~Dʁ&G<#_ CSY$gNza YԨ[H'Az='IO!{:q:gqFtMpq5Bfr,ZVUiUZVUiUZVUiUZVUiUZVUiUZVUiUZVUiUZVUiUZVUiUZVUiUZVUiUZVUiUZVUiUZVUiUZVUiUZVUiUZVUiUZVUiUZVUiUZVUiU*s,2Autw>Zm^3ߑ)'=jguؕ"ۥ=t$4>1R ڵ鐽W~=.o'd}Zv]Ԇ+}ׯ7r1;ߡ~Ҹ;,p's6s||`;=;$qa b9tO! .=np{/~#RIGb씓LFxF㥿Gl/s{WL8.wC?wMh~\<i$D4?LOt+nK1w>G!Cbq >'/~ޣvwe%^3] zfCx~ӽ!33v<3|/3OtF-. s jG~,rg|%$ExEVҡo%? |U!O|(]r%=iޥr NinD^ Kc)4?_(w/̇ho(%?yEh<,-pq}$XTOx.婨?HS/v[Rް݃z/nH(U>_oGv1hH>x M/qb~.^v <g}[̛3Ro'~xF G > [i,H#J c?qY~мJg&|/Ďd=P]sRNS?h }&q3JMܞk=%~Q=/3}O7װ Ir]A#['G9cCx1 =i9LCCJ w=C#Kp27b}^P{|M%/w7)WO=c$ c`=S>煞Hҏ/|..%K9*,?v"3X~ɧn$g_\+ɏ;Wa{$o&^g){۬ב" Oc{lj%3+o?3 ?%"8FO:OXBxHn"ox?_HMogW!VЯfz?/d8^>-JnW釐=?d'r(4?nvٟDz͇\|]_~SXwd9 䥤CEGygT< \ZsuD~O ·~~sDgh{v+JV>#DxsOb|Vt=vߛbΪa>7\>Qѹڮ3~9{~ւհۈ}6@_V) %9K]Q9Õnvl3BT}w}@2q#xޫ77\q-gtD><>?>f˂JCiu{܁1s-nVS}\+9 p]Yq{<h~q>V9|lU MQ]s'&92twg&<܏=G jģϕIQ5wƫH1/tItr V2%ßbr"]>yB_ܯȭZ4!xO^^^3"zحKbl(;C['q+;g\Aum x9WYO$x!}O~!ψ$fhQd1 DW4N7ҫ^l/|gHg|G>Gb$P%<'x^<. OX>xIOC6%ϙqlKl?GxEvA=V飈 gҋ}ۓ)#<(پ;pYyY%G*7]z>NcH1K}W5@ IW^^.F#/G>“:('yH&LM^1Ö`7 =7&>wƅ7vb@~R'9W/GH8<~CһNd|W=)siIޑ=LtLp&2Ջq^A@E\f@rzvRH #T"\~r?њҟ#5Y%ޓM\oO'Wߙ1҇$?.}%NY%*Ev~ Od;CP8v<0@4'e{!g?MO&L~~MȗXF:}H& t#jv5 DWxO@~j#?L "d'z%z&=(G!#/A{WC%tcPyyE1=޻wtϱ0*CbnP(VGwDlWېcF' Ƌ'ǞqFv8Ƥ'ŎŒ'iTRz.`1v%Ŕ%79' wh{Qϱ i8±<( NflVrLW&/l+Ir)!ȱO0&AzjR_ ?3:{Gx+x96kT…O1ywh|^; /O CN]1|9 W Og<9.x{w?.#E8F-ͻ7I18g͛ӡ' ?pq{cT_x%ǬxF%piwRJ>ıh</ _}~Jzb F:PwM-cb?$|L%K,OJaR,Qc<w$%K#[̳䓒Uю%\OXyH%HW3doȏ:+,g%]g:!}WgHjRo&Gdlr/X$SeSIr>XlNЕ'9% Nr^==/KK'Ǵ㖥7r)Xk/%YŽ3?c&G\X^ 8i䯘?=}߅>*,I‰8'/į{K+dFg]wWzg]^>!AsW^ⱙaلܢz釒x"o3Fr ?%8K$#x>L;1^㑱Y_MKeR7WMxOfOqp6{W%1LriEB\br<}D9_Rz#W=O|@ڻ_鏒A]U=qN,7&JD_N$^P]EWx![$>?Kλ_O'> !+]$3}S1r|7z+/=~A^#-='AuFo^d2,N#:7r>BJHٺ&EsQ9jATXRIK?}zITofo>"'Rn }EB.2 /9k&|foJ?w5Oe?=9MbӱG.}|ҥ@ʪ*ʪ*ʪ*ʪ*ʪ*ʪ*ʪ*ʪ*ʪ*ʪ*ʪ*ʪ*ʪ*ʪ*ʪ*ʪ*ʪ*ʪ*n/uR{aW@&1=l'2{EIcKS88ɸL)cQ{=*)='-~S;;2X7W~zXtvY؅r)46| ?9.jO1NAb|^|O _%EE>~vrнY?<)+'a=ggϊ͛?]]Ul|f~ f|o6o7W0|z32|f|K<5/$>_fiƿܸ;MO)Pjz?Iv%͟r>y5sَ\ wv?KL4YF.C3wce7gy4۞ZО ? Q].\tEռ9c Ͽֻnpzߏѽk?ElqDQ;ߨ\u$p~[ # ܬ= J z=888B,Wμݮxrܑ`Ӻ/A-Zp5:v#y[5z}=K@LT Q>f˂JCt3~k=Xm8Wl2~.$eT%5F N۸[XgX>xr)H3>E%T-bms,;|$M-ɒ7C̥G}?g|cvP|_-6^oڮ'|w9Dz[N~Y :xF$=Yh5G?d<8nVgd5}8i9@|=bh~|m}`zU@fCl`qx|Y LiK[L[{\k?9W#}T/Ͻ٥Lo,b~]r0~hҀ·~~194*jǹЯ  |4Cw ~~p\4G <[ft#Ƶ/*x 6;o-LwΫ;=; W^v}[so}^9w'9L1k\O|n!H߀hv1ݺ rv8 eW4~"~l7da h5^GИoq.h7>ϟbg1;*v>D_ uOGm]<{-˦@^CAEG/Ud8tb~M>P_>9NE/O|"+Zi7?k$GbGx9Z *g>W_=uສkG KxNAȱ] Rg_8߈:VN_aϽHFK7U:nVeIoc>㨃3ᖚQ2pyw-e(xj{r,h?(cr~"# gSkwk9$b׈Kp^_~8Vh3vM}ykh"_=^׊1֏ _=]OhEn[׳1Y|܉%߮=}=Xo"=<=**:C1߱\:~ n/FmO3o^u|PO#\kԵ??I]u؇xl{.'=h|,Q_c=/fj%5Ro  Q'ScPjעo|tO n wla{D?'04<=6.*~12;gĢ%= )3or^_+''tA"=U:TC5n:]Ƈ>-˘gzo_ .s/x`>{qͨ|w.x dv0[)u1zy eqa{Cp+_X>@߻D,#uhG ?eȽV<1W?\r #'[a}Vw7A~~fT=gD93{[=_k|eCc;KO*,q<ӽf3|靇.>GD=z>5Ўfz%=rr LX^F#ʷhߑ&z%+7h' o()w['>җ#"i؞E|&8^c\>}7D_l>"% ?u P>:%jGÁif~S{algBD|%:#"F["?eHgB3h7 bٓ]zmEA|@=ۭfIDԛDgW"~Mz9]cG]_Y$dQ cW/C.˷7%cW/?v ‹JO~  /~!xT?!;7eh!bCDtOr82_ԃ݄OI޺o:);kC}C 6h=fLTb4\ }8߳區[Y}vȆ[ſ"̇^'MzM!ƝfxҺU|O|FJt]Q|r$Q;i~I"|!K|B#>>E~~CN y4򧐜aywvyʃwHa5Q(AO4w|4>;}B?փF>ӛ?QJC@z ߠ|!z$>~?ֿ݆;F'|Ku?<%9zV3_=_͋A|cHzK./+h9U}|~%m.2c_p#u '?'Gܑ o#߶k7K/⃼zAһmW/?IrAZD|a>ʯյ'gP}'D кmW&U2ϯLV"?c93?MW׃Gq3xYo+;`G3bQƼ1ex5ĶA~oz 3bgwWfEsLH2$Kփcbs?-p{ɴsQu}_D3rO ǞNUG7DO{_gt_Ska|犮i!%+ۭѺ7Ç%zt}յ33ʿkbx ()#͟!xIF1)$~qmgF>:AyDk<=!  %䘶Sh#˹(g->O߹Ot| gT+B'XAxs #8SbűIcD1i(W oG/ϙ/=@940"eGNI?&rE  /l7ReUfyUelz#T$3!.o˵Jo9Jy^]="z GICC#_ι(7ٝ^v,#\' \iu98~7KI_ >F~ǯkV؊,_Xӌ5ì^|G4%yGb7o^C% /7?__@A*I`@0#Ӱ@%8^[M'P0' nI^IO5 Ay@p rWTJQy"@@p%<}io݋$>A9v*O+(OI^{h7w8wžioX/~"#X#WxnOEN^FC'zbƃ(9|@~9mދ㰋y p+"=Dil_Í%Z]9">=cԨ^[!CL_b?+#DAz'{gHqȟA;Gq./FO?'9Nrҗl^3=?WɯE!;s(S}\H&%J惄'4~(8X$r=xYvtT~`_T١d(ۧ>9jP.HjK׉_zEg{NX_#C,Sg[xO%}'sqG17$gILz!7GS?I$r:w߻4yFyAEv/ΥU:XW'H'} =PgDg%&֓?-ԿHS)t<#ٷh#G/kHޒ>G匧q0ݐ0ֽMtvBv"X~Ѽvhމ/w>&~Xz F 9Lr?>zC:c%u87q/'-̿Hޠ}/1"}2vP>=&?,א/a}ױ A$o{~g?Iz _/~F" [+'UeUYUVUeUYUVUeUYUVUeUYUVUeUYUVUeUYUVUeUYUVUeUYUVUeUYUVUeUYUVUeUYUVUeUYUVUeUYUVUeUYUVUeUYUVUeUYUVUeUYUVUeUYUV_?'SS:qpP &-> 1^Ӟn8 M'+Zy!e8ѦYck`O:=3\yOM©/p~^U:±G1?YޠFR]>13:_XWgZ pj9=9t̫sFU4@A@N(" 2( Kh{GJ^D:HGIN*콛~|1k7ovLU sيoJL[wPg^th9!0\۔p, wkpƕkK&F^*ά~~!}̔npky7/y'[2p,Ww$Uz* o4;o쭹wo,Ic!0G7υ^?J:˜'C콎n3;5N8:Ŏw~&XYp]>['WObV W]ޑ<8 %nwFwK")U.| z}޷7#$&Nz}KQ8}fsʿ~+4j{wʜ !paG dn<^ w7 Bn3o\]!$jűF?{(7\umzwL!$PcC[?;I;]o~Y}.˳XB8mw徫}>dotβ݃܏_^ؼ>_ X?3{Ý-  fµg3NnSt8]!,GN ]"Oʣ. x%|)@g|qp̀s-@gׄU_Ľ3dposFI_SIq~ED[y¥ym6W&g`_Vܦ} Ɉ9UԄ $pikk@gy IMxw>qdpg:9]֕pT߫aS/~8;\ĩz:af_W{vgpJQ X)ŕm3XqKvN?r\}pX3_?&ne5dޞwk<{Bm^Gr-`>m֟/0 hǦOֱm*ϧY p#^P01-QW{6{v/W+v0_ضoϷp8 w9Z8;F} ^/-+2/z5pk%O:Ҵ՞5U ù&|56p9.pwmoͭ͜p:Ckb@?UꥎF t~g690 Tq[sq<NHrCKmց-GzOkz` پx)=w8? MǦhqn(}' .<сp&~ׂZz|n}n7Yz/:O-% r5j$\+S뵾7u]<$rnɯp?_ wuv ӧ= :WY֔unT-ӺFY>&-8G^\9^ZQuqY}K?];Cg]BD̲Azk ~{K.~#ZR>`pzpUG#^7s4Zl=OY> S(<8P5S? LɍKrWc; 1 =|P㮱ߓ\4i٢;獖;B©žpAnyPA^G>{v·+ඔ;z@K[//O+pvӽW~ 7bCXrVY8c~<|x LYM`YJ=o'g"+{@,yx B>Q|ni͖A`޶[C7]pرaǾKw^;n:a[8^y%D>(7|%۽TscI|+[DZ7H=ZVWn>[O?LuzXY>YW;\t j̖ʗ(9]n7k:Z[?]0Je*Ǟ\l B):@K;/Q~#o׿simKN!)ggff[supDyTZR>AEy ל*X}#W6|S}!y zY5WĦ^p},Xv[3Cƫ?7x#i|nT3ƫV~?2cWankѽ\W3zU='v[3W۹'"?t0Kc>MSP/]\{v;uz>>*(/{ê{쇰 ql]=K9ILRwKYA-,gC91N9T&_먇O*74\SWC}'GϜe6Zޣ.s6R^Q>IA|؃# =6i{.\QKzUJFF؋.ByG=d[ZN_+ً-H}<Rt=vkup̋IɆO'ԇH]WK} 'lx䧒IYõvB-O[Aü֥Snm>$.?\t]psק݋L%f^s9cC GoC⥇p^gt>/zCsڳԿ4<ܡ`ǯ^ C}glϰZ{wVQ n<S9:}[1)pN>L;5 ϢЋ?<3ϯ5v(ɦ.~ٗso u mPC~NGOgíE/| o+\vs2xȻ/^)Iw5x8hb d3p"&{==xD݇힑?^;Q7Gy 1^ Gp)? YaŜ;k8p}=K=~S7`$@ͩ-G  ,O?\;$us~% 8<*IpE61\i7!{sp]˜#n+< =_5z<6Y&]7n8BtkVG&6 UW@Hs٥8|{DQw58d'^nR0ϔ43d=wNO%tQO cG#(3_yG=߷UsF_? <:9>?d. +e띧-pFbİ78/u`+L] ʉw3W>|Qe~ 꺱uÕm3g[>rh8|+pۼ?oJeW5D|iеq~pCck. >]Xe9k@ǐò|#xg/fкT5Z,x3˕"L,}.M*x=u| yu^go5}R?" ,Y TnO \7r!Oypםd{g[ x6^R&\ B v<izpsY^g t}eipZl`/B眪IpvCe瀀ewnٿxr.8֥o)s(*\ڦ :klc⺿OI?+{4b?\侇@q1\v;Á:~Lj;1>A@E >=\k>Rz "C}V.r͖phwAe X;*gQ"fDW׍ݏZN=]pE\: .FljA8xYP2ljR~clV[]6eo\CH-m݁xep{nc6;nr//ZƋ+$ܹ /g n5Ϝ%3oL|z/ -.vN: T_l*1pspsS}gmGAÓ?u2 ǵe_s>uǫE+Kvش3{z9kXһc!߾}Fϙ*z v 񅿌1.,V!>wڶ*q@#m%!A{Ro=uGpv`p_Va}<$|j/Zu>˳pmP[c}U=pn?l? !..§B>o:\;{i+YUspņ Kv&gw\(h`>?9-_O/mc]tm;zweY^=\ r_e Gv` = geh}a(nRԮUF#}fB%Z_=m>!gkNz~:Ɂu&o}/ZOYm h`‡ \dq¹wN Gwk$i DϞ~n'rDc>6i> l:F|J:38{]r@Swp 8j;\t~sr~;-2p)5(kj)wza=#b^[;X`b8_kstcދ՞6f.TFcjiۓ!d{E/~h)٪g.7[צx ?rE y@o#N~g>`8\_t̸ͤ:ς-͹PS<[ӧϕ3@A:f$`#߽]F :s]}.˺_"V˯r^۾D{\wo<{m $I}?3֦\.X,fE숪[lآ ߞu/# w lrNj>3%׵L ; ?.sw h\\Q6{!owpѠBcTtŐa.W5/|>[|{ \xl (rɚeCM};|n)ټR vuYYڰ 鱔v< ُ[dFkb_>J988뺗#^PxgGBgof=>n+:knU2?ĺ~.v2g՚ AG&\s?]0>.<W8 Np͖Am}wr\>~ֹP7!g6N*yp"wEBLN_w:C ǃK63 xeݳl/רš~kp^s5ς>) NZ4x[8{1nI9p?|+i?UA\q~T ;:59h j何'd_cw 4X r#OfV__Y.Yd\ڱEشROuYȷ^\wm1Gܲ9屫5Ի`׮W) eG;XjxPr<^TtJR19R[Jy.GK>r' W_}jZ-g^vGˮ溁w=)ӏ|@8\`|EFF]TeQ|c'{䆐 so񂠹/^<7}< ^Sꏌ\eAF~eMہ~\ot |me/NWj~ࡅC@@_ #'-?\|p|ܫ^Lvl{~`^su}gyaxn.{ koW9tFBVA_pp> yylv-g?g9cp.ЍWr=o6F:G/ӣ})rv#Ci獅˝׏I{tZ\Q9)Ou%3\o]y-bע!_-J̓իr<Œ'xߠL>uΟh<νg2[ǚ=frVUWς 5u~͒ |XZ:=%.nnkoڎUW*_ VG%Rqwα[s5OVaњR9;憵. iӬ= \s¡y)npԦZ m#x;.b_[+w}U>'B{zՀXo1CXZgAYs=_.'b[}ncwZ-x|S[Lp}~G&v 귆J~)wL9soY F4쿼 nDž[lG?yʽ _ v~v8pɟ:KW)s~-/zM~o^я$b 6/#&?4"קgVxsmA纆sb涥Nο|޴aΝ#_:=Hʹ6|嗰@hUuk6G+ԀG r9/\y1|k9_1KI{e[%~Ց;9)^h Xx߽v7 ݹxVl$A~S\g/y-Y >_,:`x8XzDu' Wh_drx`̮/zƠ|,G/ s3g}~vcgd}nymWQ=A/.k[c_ԯJrM3i#wӮa>zyN?hD&7FysBfJ}>s >"9쯾fuKW7o:%e?9\,զR򻣼S?'=)^<9kkJ~E8kK]: G}v~ͫ>qSہ{cX {ޙ{sG&;U!{IY)Z:L9O/P۹ )r~<+s׽[#Pla>LJ[OsRΑ@S#r>k"+ER!ϕ (J/ַ )_;u FzKkO~={J)H}lw~_v߹F|t,CU߅ǂ6@v$H>B^ڿ8糓|U? )GkHxiR>DVW:h?#8F({Rz㍾+|~|Nr)=_P)wUPͷ)S7P+߉η:xj'JGΎR~SzT|āɧKרjռ/tR;AQ~D%Ohޑ署 T?E AUGEqF_5N4)KEy?H9)*|ڎ~@?KES]T|M#9ռFhʿT_;|9:_Q|5mws*~ZG~OjE *)Q*~'~W^t?RUJH)G_N$_5_9hSj@CI >>ob^= ~zUI%xK0 ysN ,H8b& \̟k,#'_c=$y~ouz yI$@>O _\#>lF.۵f踒}%X_'B/';ֻy$鼂/[ͼI>ss>>7{eA>aע+~vu%E9I\c?UDX\#/ z"6Xvq+ޏIF:([z$omRJa?)EUR_|#ċ|GC`;qߝ'^:jR>ED#q@'xN/헢}1t~Aݱ>ot$nB#8ʑ#>ȧҡK߃aPy K.:kUrr0I{<eH>_|ߍ53k}ʧ/Iyl_/]#8v_("}#IֻɧߋxGO;'r*b;#HO麉I};|x :_8t wvl w<O|b7||?~'lzx@ɗz#>vA#cHnO|OۇX?|ʟ ߲'X\#>llφ>m;:@x$k:z UtX_UW8~D.Wy't δP~Nwtݏ| ҏ֓G;bMcKǥBbnV:U\Ct^Rwz _#ہԧ KסH\G;B,Gʣ> D և~W_t~zSׄ@~Tx=a{Q^oX;?|_ >*t@ J'u տQ ?D>&] $ҧ|?mO>Qʋ؟p"TvLj9ȿ~r#}I|*waGZK>b[? |}c% C;X~KQDY.=D9w-.0DE ==Dth4&z,.D;&; t3]5S_:\{xOgQtA7{Oq=˾/⹟]?kxb妈~ֹhQ~j&pu`<#c4SǺta-Q;?t; اQ.pѾ~ Fk&~HMNJ\ċFo*hg4L|h(MS0^3^?E{yl5Ӹ!]kiW]?lF$ԧ?asьv*A( 3K<,¡I$dF_/W_o=kk7Z35(7A>q>AE7(މrhc#4;XfįǾ7PԋEO?Mõ\?n;_D~{F{A_[4 0AwG뭙 kG6&k&پh=4̊}|?5܃xw$wLkwL7zr]um58: G2%tLkK7Κi+mxPp]3E3!:S&,+Y) >+;9= z\kXy&^f!m{ӗ,hCG_'}h{~7ɢ.y5ͼwӿ?)Y3ƪ@ߧ׍Nh{ӯY['~+L>,~}>i־+mv}k9.!y>f-Z31gYtyt ӱNǠfլP}8HhycϡCX4뿽g!.X~)GOjvo=}QM: NMr^6+SG4\&kU?2-?z\T~4ŬҤjW%=H9EyU)%^E{/6އIdA?^k֡;0;,VAK6*zi}6ƭģg]OYЭ7y^T'n%vT?iN/Hk߫^6K9(QvqmjE9J<_5h[I)>%WTC^"f|K^s<6򏪜o|ǦMw~ xWZO[Ux5|\-O t[y} z\wz-9H)gz^!}lǖFb>g/TT@{` sr|v(X[K*[ )^߶5I|ᳵNJz5l+U{}5R^Kh8M-`S|Ih9u}H5?+론GSܗ }nkOQNg{G=M^w=`AI޷~vP%LA-9G=0QJ:xPϢmΛy|ҿ5ﮊ׎b9SD|H9a9UGrOb]*^z߉p$嫒|OP1#t2/' >O,A}Wr><҇KR!cHʓ1wU?d~_)B!,HQoQ;Xvv~hhB|N$_u$i!_#121HyHywr!tS<^ DJ )!Jyc/(P>UھTr JHu*X mQb}BqN=tt$y?߅/xH>_:.(q P%/")~yQGE9*\]W_/ HJSgʣTBzz#J z) H;QE@i;2N-'*=Snڎj=Gc:3)Oq{(':/?壤=- x*~jKD߁gz_0e?`}4rT^o|3TutHK稞)h{P!<QL::|v$ϫPy!GաM?e ZJw}"Q^\=x7֭xg\y\I*G%{GUVt*'h'ii`[e%]]DWLy؇JR"ߏxWYQ2MڹFSo+JڿfE3%3%E;b X?.V؇ ML- W Wԕ+.LSij-6G~Qԩ7+>ttԕQFU\$U直ʋrئȿ-eJ tmuuȟpܗL|]~SG]{!,_I.x~XIЀT.KY]p(pca_+. |7 Êi|yf{?Mue5XvDa[xҺQY| 7Qv(7.%5Nirqg^sj1_/8>뮱>8UL( oAz#r4ӘD|xV/L2c=>S\I-h⺶ot*ÇuA) wҍy5mfw`Ŷ9B/!.&~(/ _w8>LUzm}EƷmGytѷOZc~#}k|Jћ6&(EZmGcϼoQhP|d,$-k.T!־fZV~Ut 4ұ@6H6|OZVg}=U}L4:5~ Xk_iqk5zP*y@)/F~חSNߑ?Hm,kJGXњf=N5 ^گ5+eI߇ӨSԵc~ ,bj侅=)^vQh"]k/LC3ɘtñYZ IXQDr1^QyE}1& * D>Tz.mSKl9)IE$9m?Wu*#7Gu[Ix |,)_nW=^er5TA7a,eY>҈!G%3Ik`zg?2$s3 2]r2_% QYҳ[Q#7x$b:n~/1P3g#WixA,+ FQCCG_! ]Xdh^ 6Cղ5cK}ydj t| 1cXsJA\eD7 e ?xEvw*zi0B23m{wb_Hiil2pE; 0 VH - tW$3>VH:T.H|ǿ!R2G3ƐK#(aN^i]]iǘJ' %ȤRUJ~&UO` +)y9iWh !KF#@d)V4<>^ik9~F3x 8ɯ{Eqs@!_&`I&szCh^@h/Ic,oT29Sa9 P$A:4RF$ d70mIE325SXΤ}W!!ԥ7]`Cu4Y2V _^LLK0ï+)OJzRS0+` $Y.!’z"((Bk9^M`+RmBlÀ̀TыKU=DX: BX*$r!y?'E{Hz "4k|AƀK69 ELcofZN$PKk;u%UVڂdSeA"'N?&w5tMl.bmھtw=X<.-=[yXʫ? Qbڂ~%GXNjWR汌3&Ɇf˛E۠y!uZ@XU@d _ (w=\Qk9V3m1ڑzIڮq% Cy+/Xzyhv@d܍ aIx_j8^ Ǿ\/:.p8B0(nI*q=t )mI#~*A]ɂ$!!%ބb1xQOPO p_ h>>L8N3x&-kK jlF%j"ּn,}?s~*l->3 <'8Q3lV]I_ȉo̎l-l9Vxip3;:I9QkJE8ș rvHyֺE,gAT&P;B)ٹoDߖ!r%"BY w$Uzb<25 {ko/cZDg̴;bˢ77@~^T&j)&_(pzӲ 3=Ks+A^=~mi_kN˶׆ȭ_M P*b9V[ێyA2m0A3*S` t~-v.5o !v]!jɴ{N2]w]Sv G8! 2e0njLeBhܥqZ0xюqJ= b$Eɼ*;MLl9($!V\8 (A8Gq15$g`lJ ] zj= p}aw5~xN5{O|1n<ɱΣOJ.rېs JM6g3NnSYVl*U  dr#z^?x\CguT}CuqMآ37#:[HT5׼_ i{r,i^}.ߩ/5/OgPA(^$>%H##tvGQr1i1aL⠻T`?k. [DHui*Ґ4b$7n<"g!3{ xQ}8^y4Wk+zDaC'gxQ'_ӗ#Buﲌ.1Gw*)7Wota7Ǻo-=$/M*v1Il)4S@#1P1yD\[ͧKk lV |@ ٵl-b.͊=7%¦]Y<ԼmBl͊>e.mIHr65N>}ika0iVĝ9y5[إH*u0/ HR|3Cx.)*YDOwz_9 0i)&P3yFFXKi+'Xf:qS*%RuW9 7$KK*Iᅮ!yŀ҆*YlkR[᣸0qo&9)ٖ<ߵlD* wD{"a+S@oS95>>>1:!5齳} 5BH4[FL!*Z0GoX Eиkʴ%urvՒ1zv@h^K5WKD^^-% a )U43$/Q)$~5tGmrBRjr~iCb'3Cx;w+TX[7߁8Qzl>? Ы/o-֦md *X|9^>;S,>kꯢ&pn h/LUb=U~&VH"ޡ4F(59'$$8$;UKz tQ -&Aa8im#͏o3|xt\4*\Jt%eqgKM}ي~y9ĈQr8F!?44s|I_qw=pǼc>;(%('wX 侤/ l!DR]KUSG܎C@'C`g+ZCf"mJjI"3X'm']MKCc_~xVѯJޱޔYRV|l Rt9B}:E{ȵiв\ı d=eMg}H(=37C߹uӾ%.}պ!}.Xaf kWԛQSiڢ.l޴oia|05qsLQѯJFMν |K\ a+~yŜӞv.9.R^vWR3.1ӟA2;&Rs|v"(pT@u4Yd!dvsGQ0Icpw1B3zgv2h8 Fp@pC1ּ=Ԍt/bx щ'&ޞѣt1At?xvﱮ)ngYg1H :^jUpCez? jX/Z_OJcݠZ0=G>8] ?11 E;%uQ[ 4E:'UIJ(X/TVPT@&Ea1phMl%u+f:"YslkN{0HF(`v.aYLU1Юds٦BպN=Vio0h9~F08.޻؋vbY DС}( }pi=x.`IC!FaH1PH6$J4mH52=37!i8>+K%'GzqIib4d,4K݆}8>C*+JNa8n#=;Ң2CXJN4Bn"H-ZR}~%}SV@ r{q*),'UT7&I/8Jh uQ\~l3I9aJL& "s!O\S~%ky0a# xFRKm#e |A+.fX'B';F4G+_o_b9O[JPz5+t;P fneZ^˸X\9>.w1"BԆ=e+,jxdtO҉JqaJóeXN,%PqG'UD$2 XyB1f:?8I_o̮=PmW:YK.6nSBC#4_3=LtgI4⏤fZOQue^q&",]3r.֨| "ْtkpĮ2%'fWS$a? wǓ_ \WA|)_LI/]ӥ 8 ʵ;Wet 'tID{8l~+)=3R@tO{_ h,TtLy݁>^odn;̟C3v.Nb., ;Mъqg>Y,J繤@,rw@%P'iK,n<U )oCPU )P4Y0mdixdL)!c LbL#Xz[@aBUD]?!ddX9]g;/ATLkʴyHvTy$pRCLj<^Cxumr=^8?y%>{'!uNT;C_9}U$ 0@Z1jթHQ+ɼ Q lvSQ`CxA}3_ KhK2N~h|()G&<`nhO"?&10h$X\_hCFzkg!,-Q qb4_~@Ō&F-^@8/'v/tMl 0< wM\Ca(8ciH h >j~AX$20HR'ΤyuzgvZ*RMXP4YT妔4IG|%)SP=F3%%T-=CaA7k2E8x #Ex#>%% ̈/ QbM s"o۽d'^}Vn' .PpuEXjתK#C}8ڱJzީ-4ה^cD=?Y5%ͼUޕ/E@Rթ}BH<.Z|Ȕ ]S*PLt&f8ͨdVei%T."XBܷ5oCzF&)?6CX/N xR@ZŌ zmś.hўkG{`Ga\R{RlN{ک$^x#4 Nm<vP8Ο/7sL,hJ>鬕?G\i/!16ǪC"#wNHjΠ|8@~;Q{Quu|/uɆۓxXA}T+?VRy1. ;['g;rEd)9! |uM NnmQKv"Wv?tj6xp綊~[ h^Ⱦ0طl\pGp~E9Jߛ_ZRa^ s})$I]A. ,Axehv]hԤJW [b@uR{'*!ޭ@ACHw+Po`{M@?cem̂ cMBj$.b‡;A| niCJrBenEV$!ۗXNG-:^,xv(Ia-ΚS';RA3J#k5m@-h!+x|,,7p` 7tegfWS$yj-/pIX st82j@-Z6C:Dc!AЙ̛CuJTH?_z:Gpbg P؉<Ø@yNW,!.= %]XvQ݌*!i$c3z,GKbF QBRH%# 9Y/)_|.`<ʉItl_V`9n %$K$}Ao҃d6PG1i _$BcemV% @# n4֑48ڂv @pՂ$s0K۟ b4^,=EھBRQ4I|5G)1.!يIyk^m"lyef!h<[.ڄg<[q/SNEuM6C@/xOYg<[*\~l!@\ )I"h71!O_v9l9-a/MtWCFr1Bg՘1uӖz m1+5{(hJRU6AtD7!Rjؕ&e ]הi30r'8@2vf`;@iJ++bJ$W_Hfd^T $cWb,KIᅮ!ApҜAG 4g /%` <͖=3t7Zk_a RBIy;Ao2 >Sjd$B_8zg%@ۇ2`(mP/N#W$r B?I0d XzNp SjmP mYyӂA4rGd̃)2Y @>)Ot6(Mg9INkڰHcףMoV'At)(~&SvǟF_>e8+Oozvпm9)*:(jɝ7}{n&wIE=/'㭐ζzh(jnP%ah2_F܀C)o`'3s?%uߌ'hRD~y-%_bI\Ƕ QU~|Q`D/ b}Y,G35ih;oܮp8Y`u[ NdO߀woV(C)DC1jelGJi {:k93!BABywm{<)O 9_)4Bٽ H-ύy e;+{ARhYg{x$$g-(>JHMK(ŏ- @)8 e@ToR!e ]4|u¶ {C*[$AB83G@xx/iƜ&ʳeK[W2## >Bv^hCx>vU)|ŮRzMێB,AJd, $s X|ŇL I匮G d3.:bi(`w(ֳď[ۋtf&d^o?DCشcX hv4!AXADG1>IM{ 8ÃӮUEcoT&s|R?3QReE u&K:[bڻGhַmP3*.Fhgx{ vpovR궔zӰ`K]Qc$[zE6o)lXOLEW㨮)mX ztJ>9lm JzQsn‹">S*V㋒//g箹QH! kn4*PV V[q'(W}3 S Ǎ$QoⷲM ?`Ti1c& gzʬw63/OݧwWYB",TǚU3"ңѬ_MÀN*yHE/M=J\O3A0eJzhO.W$?¹i|ާ=suFVzixH|w&KYg$5Qʚcѵ 9$Q+2"|ԚSStkF:E:uj A.!x}w/0L b\U\Gh4 U=<#EC鱠aӛm! (,%tHz M,KvuO"}V_j"l APǧ yD}w=H4~!|7徽W:G^ YKďt. N77|dݏa ʤ<DlA7`V^iDcnjcC&LM|1 v. Wt=h Vh\]S8֛99tNS:WL˵zssݚ##KQH~KQ^.)8lt?x>x]ղsZ{I?.6,$Zjd3H>] !FZvT:lm!=D$w6vb+)KeU|*݀'VLsYؑnxVgH1ae?*ɬo{D@ prgg'g@']SMl;Zu~_xqe@}zV-a>8_\v szobw J <@6J–^@s[zgf36`qo')GMjЛg7 Lo¾`oب˓6zUo]Z֙Y ^ i+_ϲԢDf#owT/Mmi==&|N|4R4tPl1i~W@.Î;IWY}vZк$ qL*ңsZ$྿d)&>ߜL[ԴXQ4YGV\ӢE}.I5T3o޸TOg[ 8/BgoTu'YƳ?NUj_xRx))x!+NZ(oH??{qs^v# m7x[$:D9Iaaw{hbq>f߉MzmF35~9>~ b=Wmj>r r+u j/k )˾uuHzۧ V³Ftp4/Mq 4/ 삏Z Ņ2G7X-IyV3.Umcyh4o0LgWKL00{8AqvZIxGS(.k 8DM|IocoRQeRk_Oۻ H7 2,|ڡ&&3Q-)7͡,sH(|T/g.F%`>pHJ!l`N<|sN`sz,d@R^vꔊ/Jϝao&O:C-,E{!U>VP\gO7[ ngRNuhyp DzO,D QWDrI=D7C.ix$=}"Dv T)D3<>z.AT<.1.v"IUvBX$?ye<7@ov]b:̨+`c#L[Dgpgm)ވ6H- "*hEtaSrq` MmUE\kLP_U. U܈=@I/.Yt$s(*ঊH3} _Yq E71jO)pZ?c{ጎ Cj]P ?fg϶0n[^tY*vvdTŔ}f숅'HPcNDm7B8?3&oՠ tͯGϥ=.EsPҳ ?u\cRx_M@Xs_q4H17 QJ$鏱->[Z},G`hsQ3h@ԃ@~zB\ǚr3}|#v_.,<2juMf]/1v΃/ ?_{m ZQh v_;A{ABW=/,=3j@#֝hږSNz%6i|gԜX-%* }N70mcVtJD+z\cJ[J(PI@sҩ3Ah$J*Pu );;X6<] Fr i?US(oj jѭ}g0Pͨ'`r^m{vud`@ Z8eGɨ[2,Xv4LgvY.$5ݷf@Dӌ6*Ys-]t)Q6){|әJ~Y8ܰï1Ymѹe]U|-p{-s˿$,T LTJ\WfN'Hd}ZMe6zymhFrv'~C:qR~S1'"ϙ[SYvBݧٚ>sZ>Jh2O5f#:a'pJ2*zq[wNfA -p/y*33b;/I^?vZQhQ{zs}ޟm屙q+=)o?ubA͵- ?ze<RċGY_}uMf]sw:H".=P҇~)_{ߞgТ51^^YCהiߎ3:2ڢW%?W'ǏOPҏtW- Hw駈݋W~]x)$Tq_ҟk[},ҁ$^%Pg ?v3 - %~[֢$_֥|Śۮ?"[85]]tbL\wڍ>"Sч @hW!ư7x,n08$e/ 7!!cJ<,փUZq%SFqvJ܋`w?`&>1(+(}y3t%*TA)d +RZd B?9&ʼZoԌ좜 t%-\QL?T3)l# @a 23/-5Kd m8gG\_%VGUImQJ>AMX $,-@0J0F-T):& FK˫!kJEAj2Մ:^vK#xcE i(. CsX^Xh.Qb'făAyA濟 7mwQl]!0dBXvXN9Q5E讇CٿtMlcT tO]`+T߫:?,UGB!$(Kxx^5xţBb,fw[|0`u xQtñ˷@u͜ɩʌ!]mPdaH .aqv 2"f.q;RVuX}Tk^oˁ/F ue$]_.Rdu&PNR^= |O{ M󸰥k/+J^ kE-=fԪP%]١`(K #wxq8]]Xr`8q[K .Xw k0\]mxFfk5!i鳇'CbϒArj&~[!=3s!- )~U;cÆ1Pͨ,ЧS y[)XR#ҭ Xw&Ǟ MpWDaX`kh,rIEQ@%qiIҁAjkT#CSOE tK]n>dW_MWѧJ~p4_'(z@&9,4F™C{M /ٖuHL7ߊv T:^,;vؤ|gY90Qv$:߀@Xۍ4Pe2Rx<,k9^M8G2VŊ,U ו^RzM& ʫRC2"$r ⾤71ө)c˯-#}ԢE}d NMѠ;&3&( Ǣ0>1z'|po &i0>5#텫"Ґ^[>J+Ӿ~Rթ}JQ?3'l_"7!?%!8(ʴ5P4Y0ďK HQ.ۑ`vIyfPߖ.!R> +<]<,kj&"?ZG[ i4..p<-`9=Frᚰd ki O^e\Flē<Lj?8|U.[Nٵ?d@1 g&3D!᣸)~xZoDTo@a k^om:,8 K'!bClp:G- njɬ!,s@G¡a/7s~Gb!X\SG8/UAJrQCxv/W+NgKL,(Lw@Jބi68Arٖ^y v@5ӓ%ůJH|'-舏u׀*L9#mp*'7)NPIxrt*$ ]ي gpX?*9 T28[8aCH<.2(:GB%S0I` uhC+>Tӗ*1a[RVz0L@ж"W-hofiATI:p| P z\ W}e&KX_V9>T >oRsx[$,Ee`ʧj I dq,ۥ \&I/-!N@. Q3t?VY2Qۅ2 m(!;t cC{nOjD.e_qs) %Tהi3t~HEwnч?t7VҋQ)!۫ ^51[30w V}r$$mvO1Gw*ɷ$x8Qm * UEzLf{i¯+)G|i־ "Ӛ]BTvDzEY%=kmG/sn F~=~֡OSH|R/7z m)JXK8`qfS^_4chDt6ptMs~-!TZ{ۿ=!ɄWctKvsDn-4& {3m{8+/^ʬ7c:^ Q&"ڳ/7d ){TNmČ?`/$k{_{qgv ]@sWi5=+@;\˫B#㰨 hrU@PngV_6!RxF՘ujdjm|, 9^,\ق~&Es*'G%,$WloЛ2R?(Ll[">';0axK`iіG%5SxP%" KXLM|rO~dDI ]%<0L[XXoJ,7 }= uv$K!֗:& |-$:ICc IEf-wn 9rχ.=xZ:&I^|&zI㟋Z;Qhn hG m> 4q1Bg(nݹ->6X0sV,x)pfMpn)l3(7#0\?6ףMf}o𼀗bF} ̳el燌0)r/9ވ7y&2BI_(un}I`9<Σv >J%h׏Eړt϶g!7D5@">8Y,$Gp \aj1@Ƹ8K9^( srXT"=CLd|.$NjzqrWABwjv*s P%z@Fz zEaEΤ,]6 .8xr X'v%|}{xO! l]zt.v q +4j@qJ^ׅ0$Aq Ȍ,$*~2HT5׼_A pkI߿s Z},gj`۫G(rL7M[϶-hx#)GiLBUM IQZF7jmmw qMkʴtMvH935^0T\ۂAH6?N`b!QK8$`>3Cx oyEu4YJ 2w>Q؏@Lmdׂn{v e<%k o7Y%;bnlv)D}Ԭ}< CAʤ8pnåSf0o4BRf.~}+[9TY;c?Ҏ^ f])~kKqlh;ooKBO$Q b&osW @TY詖!PԞ1qoIIyE? a@ay{\D5kc K2y PK #A Wdc& C8cwH+&2@`v3PCh?Vk=çߓǥJHY}@z@"ɾcXXz+cx W#o#߭ TNpW뿱p/%| a5>N:<U 8P:pG:o=3g͇M-tayD-ٜb&7+ jۧ x mS/*~ئ~U k.pñUw_2:7*zcؿJĢOOeA~*^L5n&w2ܔ Kc@ r}/=37{NQڀG06%@#JD.Qŗc.:.!+v:@AfN7;x̺wOA?G7VIҏ9l9C3m>a {t?GUs v?RqØzAb MO816%K?*qm7[ٿf.rG* iK45uu'C})^c@\I >NS<^TNbuMsJX"F`BJfS )9VnBgH{BK·)]Gz;iy)àyb !-,)3>Z1f'<Ԇ<¦Ϻk/cUtc c1Y2힌n!B ;Aq|gXnnGHavAI"!9;m$8_2qRk.Y֫sewJόM,)D<Zhƒ>(AKGI ̊J 2cڶK>KӝEY1ŏο+#<\tY55=JwP@R4IKzqGQteW?p趞P\~) ڸGk5[dhۏupax_E/M'mׄ v5%hӯj4gT NGJ@8K"| Jz m*TbPB| a{餧q4-vGq901#uK3 *dz q"D0K%- Cxy;.$HdQ=<3A[YlY ;^f5}ۅ+6bk 8\t_g5kuzD?.) >:ld[@7IohGTN&xHve*k:qb\AJv_ 陱29tdL@ 2'UIҫDD%TZv"@~dyf:K3_g[skp)mƲW@QkOFHw5b$z$zT҈Տ r5hds٦?@8˭u Jj9~F>2gAp7O8sh׀!Gbӊ)aUNIkAC4W{$f )=R65P9H,Qd,oA 3HK4CF"= !eJ̆JNkU.?&Qu!H^QPyß\<`!5mP|@<ŗm#0AT^[ⴣ8(O9%h<C:gv4y:Uq$|I@ \ж$`NzAF% *H*Fy{ D HsC5e =&8hڍ@PsF B QzL01B?CHq gx=-iݲ҃JR鈏2b M0э<[T mX_zQXBUntsDq<<%-(Tx~5}K4)=3"K <0Y0$AB`ç?#$ tʔHY 48}r`hǫXz[JxA;\=@'Y“*ZޑTA~tWK,'`?VcE.4&Ό7II/=EI IB.|4`EْW=w9Nnm^pk@j%\izfo%-ŇI>]2஄<^톏2zbbC5%v\D!.lx`ҔKa =+E!{DYTTI:G%Ygb@JTp`ۣ9>lЬ&}Ӡ% +RPH3C7/<7q]MU&֕fǥ]\yL'0N3nvPeC LAR ",Lcf?!YbOA/6Cޟ/5)j+=, Ԏu C$DI/URJ@ кRP7cMO#cR'o!z^B蛮C T):kaR$CwS.Fh.0 ՌKdHoCd}L[^AĊ6fA2d$ݹ<~U twWLW)GF0P8lC`(-Qةmԕpyr6wR]t-=3rZ)X~] 3>Ĥd[LII҃D=.ʼng,b"B$T"n~S}?Ҳ~U^`{"F| ;!"<] l w5&+GL,&5\( s\KWHjhd铐߀oܘRFd,uNJ݃rR>iGC=Pq#>fkFFv hЕf&ݖN&OG1׊na?D%lpգ-De7b@!|ߴ8gRzѦFp޺=k K } #^PI~J{XmӮg^R m~v=Ixɨ/z))'=7o;GRUb}.Fh~LL~l@33kfl.;4ǁۦN]BN]v;!#?a:.D0Jg*u>6]7N\5ơ N_76PJ1=MzкW=֝T Fրö @V Z_R}? s}[^ MdA$ |ǘn;Ռh t]?qM%0WhZߕ@jF!`F(#C7$I8+`=b}k*Yk"NB sK. q0A;Q'a&2BIocovK!Rn;byGqPrW ێ+Lj2㶣HZmG:YYX!QԃzqsL]fgCHێn,x|GQcuC9,dmGvS.ۦ W Ԓ6ێ|1]Ķ?fwP@&Ʀ5;߀ģǟ͕x !%f#RgRN?3S? CeI|R[5i`6m0]lW-[LӅ-xg?01ѳ+a0F7d; >&zR*tJG}| v5\@|!!Ba@\<wwf<ĚWu d]Q`'QƳ]V_כ?*gL5! VlBM^ĵ78D)}Q)х`5͘"\58Bhk5"Z+r=[{5խ ZsSZ'oT6&ط$Vt֯v! :@3C@.)NgvR>\5%hMghԶŊE(r&疩'.̺hgbǙdq{̾'uM/d@  2IžC{5M:slRG<:M?R;L\gڐgP ck/q1P#%9gS$ Pv+<ۑ&HI0p p36#%!TN") mx_׷&@RW* IqE2I{vȈl7 C#T+@+?48z~j5TD(W3N=S" ߼!缊>IZt; pnŏts<{\JJheWDq!A(S[ѡ lP{YSHfC W>Lc(_e0㨀{!I8Z;4LF6lߚG]VO5-OᒀBK.m_bI~i>.,Z&M/OL~va%*? K:|dœn~//!-Rv`xo3Cxm nge: ~lݪӌGۓg}xW1mbT9w xb^25!Ds0Stf љi4+rc>D ҇G?kʴ% tfOapp13i0Wu\  a( g(RL> Z3/FIocoH vOORm-\Ӆz(ICajDA}>ќUPWҐǓI:3 }Bd{z@8?=kW%yLy+?] O&9~z p/QO}^!1QU?,S)sjík!VlHxsc%崄 U[<7j_[!i%'ҏ 4!] y8 >SȉI2)oܴJtK D a|דCLy? ]*#'߸쑧9DA-=[QKoW7Pxܣu{6/޸QJztK U2+ݦ /|j43^˛0N?x^s!og>G>ݦ>}f\z0Eg[ޱMԱ}:.Aѡ .=" [zPg$N/觎MT;<}::6QOOE e ) dHbq陱 -; ռ}JN(i (9LX!d[~A]B̓0ivB 㘶kBT9yx"j?djxXl=L{R60ШY>pZc93-cv}SmJ!}]\#Ę OLK4g!$_1$$8E{?!ɧR\uȷb!F b[ɂ!TbJ]Qkǖ-,YӋߓlػ8) c <"Wz7*!P[BBB/!CL]TǼݚ}L9}ϝԸ&sou:gZ]'7fbޟU_Ae"olߓbCmY(DhluG7LZ8*_M8~-4i~#I]փF~(`4wdg7]JnD?)Rz",2)ˮA1 pI N"t$; uni/5~h}a}K[{JM]cU3X%Pz)}pt; S78n!?u nԿ.x|}VǞaZǡvۏGBt*MaM K/• KF2ʽt94VL+iq :} qF:}c0B9l}XS,!8jph=VL6s=PP~Rߚ!?M* ~aߕg}*{`iQ>/|ᦴ'o6.N:@ҳ1}kc `fe/ 9ޞ-B xӮduÔhPLaܡYg\~r[a )8>~%,!=6'o=T(bwB k9v.j2v҃YhX y:.X `c8sV?x<(XN- g9 7M?g\e}!vf\E'-I ̣qh++\љ')VkD'i-(X/ <!qRa^q4S@Hq ^>*p#.pP˯T\tt>1Eul`GƴP9b!vӥlb A[e>GD(0UYd#zn6Pr\b U8=w,|pN|`Z 2Cu#YmѰ:^ =-x/ YYb|{|g?(c5p x0 ?Ȓ#I9@xt(=Ȑ$$@i9ZDN^,|Dv.-v*:24uJ9'!}[tD TY3?ϔ$ Sf#1ʚRsQ=l X۝a\\rpjFJMH_Zײ|P(3ׯI@& N@S5by!WM#+{:NÊ"HxE爾(}TyH.s}bƉQ0$ĚǥwNN$^UCe*!y:u|%z JDD%#|c!"-rZm*sAuA}w^/lޟ܄Wט~,daz ӗ*X7J"`6"cnjyt[2qAQe<{(ʾJ)x%9FNH,p>r{5GxJ blq¦2cBO˟`ql&| AXn` wx#rJds\CȾ|r@ 's=> Ԛ3,' O S PcɈ/@Nt:ўNI$qzO~5j~j͡7%-SoAe͎#58q.PQ!!$ѥv.pQC:\]Q we WkLd[N.y\)KtEAtR@*2mPaAݠ@E7tH\էe8G_Pi1L>t>y-ߎ Ԡr9T;38Tu&4*O9Tm'mjC2:@DZL)Ɛ:|^ S pQ(yykNRWUxh((֠=: piuWiv|<5./M@YoE\NK-D@gv.m'0gt Wiv4urZEՅA1UNZH) rZ iI~̪"<㩅 \ H0C{ jA|!ćPғoDqO1xhกшK懌_yt$wGcG~[{ Snw:!ۦTmҗq#f^ 7~JwJj\X|Igx\ z}兽'1\p]qk,*H5lH4.NTG) h<(( |2"'#DeXqQt-"ؗ E_" Ot,|<035N.0f ~8'[)њEϵz (gE P4Q< EO˞g6aw(?fO eIc3>J!<]]L'u.#qu h2_wX;PKbA-YaHKrb;Tcȵ (P=$tEmXBPeU+I7wYMp/mʈ_ :cL\-I"هPG|t*Aװde nAˋv0||a,;dTFX{BRm58qb44aUP<ۻ{py|g"۪T̂ڹSTFm\J1V1]]t`vT,{?Jn' @ _]?o<PzGa n3$ 2$Pz1JEDrR+<'al-z+IϊDE`p F.#"jtirͳ nX, rX"!*M21 &Iad?AN2%^ݓ5=-u}9>7_1w/>t^[_{b T͆&tZ©Ȳikby8i7n%oҷR?><(3~GB@l8^ˆj54qqH:2lJ; 2D (-,R9 o "b$Z[y1ke#<ЧSQnQ9raGsQ&LA꠯S4rQb"o2!LٵuǥU?ꅨ+J/D JC2r5Rj<Y|Jq˨um2M#uYVNr|"ct[j)Bj1YPٳeץ9`f&|*c}X|t?ye-*1%=aH ^>"Zcm#7 ?N[FD&EOd QLub{"vE6|<,c?9뫺'i YED&e7D^&F6X)/q|"sI1Wm򀒱uĝ@cvZ+|z'1 mh?e\JfL+~ع]'x KS8|I covg4nnkBzG -'GK~ua5AoKﯹ/#};K]ֱ+ eh3=C{ xs7JgT; XЂv {튒"?٩: ^;O2׵B. :`]aDK]0[Q3ju?o7O-%#Ii -Fz^JT~ύq@?ofaks9eR5] q6,$i\Վ(I]JFFBEI !!8AWjJՋ4! cT ;Gv]c4fis bf!骢cfҰW sve2EwHFǺLՈ"щ|l8oQ g]ΓdȷX9+ب.ϓ `|V.FF-$Q E(ԋCqLV,sn0<&YtՄ\2\O[O;ZC 1G8A̍8dV9ОdA.l {Ш'UvL,+u @zVq19(E[Տ@.) $Tšo;?{]>6@]=dŸԻ||dÍ+ۑ$(M(VdOKI-FQ.̡Ɔ*ƀc';3ҙo̥o~-y"H?q?]m![9BL>D)n n+嫰@fNQ֋ddV|~si꓏{u7N~QpPڳ#ݹ{&dſ[Jwjf8WN<o X>PQ@A[}#j7`)O%-Gu.YQ o 2~*/C?L>0  |0Xra u<}gk!hd""#(D-;WV;B'|[Ynb/}Zd_wX Ӝp*ːHRMB@EA A2(E8YլEdd$%2#q<ZXwv7_e!WtVJȑU7{ԑ}_w!,آ-y)cdղmSo8yVoH|acc42}.I2&qD`S?0shEׂgq*|3a:!zBQEң|gcy!WBEP!xP0r R"  ;Cm!D3x A.ċT,bx2ȑ!Z) ­b CXt%B:˃&B1~D!׽fP:7T \NOW(>(3c T)ds5||ݡ\&&5wW`ǖ,҈FCĖllS+܇_ yc]XؒHJ{g-y1tPD{C-_I5K!Q  [r1%#Ï81$:IMY%>.?,!%)L5ۘ`D~+\f}Y(Tc Η(X/ JĿ$s# Wy P0= qXZPkL Zl{kQ#Z02) Ӏ  Z4QO'pOyAn{q5v﷗ӗmO|٢&qaS  `plyfOݬ)|4w=3?|5'?ݠO\u~C(H'1 JkorI rN=،K{_ǃx%= E[qj3P&,ND#ݒ|g{6B=nJKqו.yH_J6`7$/g7$pAif}:poXN@QJ|AqWwJr X5ʁ/CmAz}PT>JۡtnamyGv1*cۊчnKΥwֽuY j>StI߮_wX@5|Kۥc-<6h!Ъ5>=ʎ_7Q @ߞ||B)WǞa\Oe캲`{ZqN#C`+.%?u, >Qή#}P2ʭLm|vLlӥ+ôH34a}wOTt 1mEMHӏd*&~4[1#-zKQRtI/r$5u@'7z"]OS޾W{O/`"x';khsq۞h=+s2h%+vECչDgG4r2 Ue;X%ʙ nV!;^ʃ˂mӉt=+v2aTǶ;xozr}#/o3dEDzfJ3,U ĥ.Gg 胁ܘ#i`+cx.|Fľ %HL= #Ͽlj+3!W4꙽rV4}0p*5ʾaQp;KB}4b"*"*"bIwl|'CAъi?!Cu ُGQAxL]Jn`|nSh 9_^zLȭ-AO֫򀽡SzN%\)by,ec0fD63eS@W}Qr28)rrBuy{#iO@x3 C@E?AEj"D@4.)HAE;`'MXID2¸*7G2@Lه2C )e&"u+`lG~/ :n:\oKNҞDM؇AƵBKO7:76?}^[!0>u{,Tt17` Xw:R6f0nW@@\c`Qu.ArWT&%t;}2o|0|i O^ʃ3n7~0J[^T9Y&>?~^؈'(Lxzvxiw+f .ܥxU?qwX^:ÒΤ PY4D|c}J4}M(]phavH})凥2tK O A:}||} q>|P@BhB(DZ[X6UYK730H390E\@[Іo:<(S52 etih*?bƮ5+T9쫪XW` 8 <$K%ݨb/! KU)VaL5~<r_c;!% k ]].x|?^E OMҷoOH:0hiiIʑ=m+<[7 S/\e;tekBiBZ-@@b1']T_Oo?9Ɋam;6?UrlAg bXŖN?d"ug2ZDjM}TQvf?<Qt~j͡pgGٿe~քPzŵ_/{*~)C@qY߉.jo]CE#yzlQ9`i,:|t[bscD%FK4a6xvj6! =^S{;\*<cT.IlˆJ h{hpPÓ DLDD_"۵3KEkHzqxHм VVS ­(7]M,5B_~}yjQ<.JPck%W CI`b"y_KY; (i]yT)M.ki9ky/򿾪=y"*͔͵Py/ߦI `|C?Vf ?IJ?|"tcWJ˱fyS5"E;է { _DNp~8~ Ge$1R.og>wO,ģ4Ǩ>ғh>oaR Pe'Ai8z;$5jQX#wNh:DΫxt@1_|<ssXd53t]I0Na,f=. ˱g]wq꣓x_~,!;qX[ϏW$%Izaz4wSTH ٹjjNѕ`[_(ֲVfHٙ(c(RfYY *h/e8FWOAX;H.l)_gwtcy!W rK8I'bCω0(M쵪=.u@CXi3Ln[X3yغb|B}3zd0=sof.$|QGwR4իȦոv!`&&| 8.\|gMNJZ3m}` ,3Il*|Cy B]iΫkCC%E)=ؒZ<.%~tGv1n Eƴ<:ϛS~['=p!N I%7QMěG~a gŀ3O}*_4 Ȅӗy~ɉRd"&ҠJߣ RԸ8mT;x\azk"]DԅymM|c0Hf\RK)AEwTTrqC-AWFxsn)Ū+2jȒƣ,[}?VɇUr%v1/xCǤ\|b] 7zPUcZ"*Rb=]VB cW _s4[4;/2F#oeuz+3c1DnW_3BTL@0e EK8d5,E(aqLGE2|NˋFoq>Jj 8T %;o˃/'(w!~"sdOh4vӥLl&j͸[Od.}[kXLuy2d+ceLoT=_WlیOw?Of\u~O}!y_KsUPmL ("&"ݞϷݑ:FO@ ᯲C"ڊ!QA@!#v4|Ŷ,"r iZ}u[rn%b$EP9>g,-:I]jy"ѡb<S%:s)mGdFK<!k?YmȻnT<*(t.ϑV EFX9']8-Mo*(/r|qtE)'ۙ (T[DHdo.|sBfx;szo]7!tYGMAt; JqCbhP2CwbdXalC?7$_kPT,҅8O%h`|hhhJ3,8d4.3euPUÈx g v#4Csy5.TǪP؂ZYW} |`\Xj#Cΐ+4V)ηq&'?~EwQV3,oIӲ)~ہYvz,}!v>χ~f KYwC̻ft'h\hzH5REP 4S[ '7n2rNtYQx< h#47 ϣ<>Gկ 0䇔ϖP!C#|5w_)^[?C@* BՀ<ԭ}]q~RЂHKu7>n" 5i䙃B*wM\W MAw 3ޔ]ml^))^`oE;|oo&Z܊f\RT/$-eV_*w+{|cχK=Lzz6qd 8g矮[rqLϱYO#[zgߟW2d(]<]J~~FBDH9Ӎv#|ؗ pξ52(hkkՙǾ=b>g>a1][ tYgP\!F'! p?IdaF tPbہ( h1 Z2NclG1& ƩSӗCu3?y\5yN.| /Ɓ/~!eP$'C&*(k{1C:pfw|,.%ѻ&Jk]ANNMgq}[]uwݴ :> ]7߲A?BC [l#׭ JmP!eZ0*DY2Z 26Bi 6ӥ:D@ ̙r ɺ"]],{et{Q s o|EMe|uXFCX*PA' ] s{ƍ.0øP)7] v={Ve{Şaj4DZPPl)J5TJ#ڕ \a(|ߺ5;ԾD M;\X!&f~&5_ɾn>7gkd{C wE+ᩗwFKZ 4Pڢo[C`x$5X^GK7!F wvӥ3rv࿉tX"cIK 1$% n+ m/R /ς/{KeȾ-/謶Olh`S+(I|.HV[J| .yoS%a"%}%C5]j+?[F}>'!N?ŭ6Iݖ>e^#ŭ^xӠnZޛzn;(4|t \5})䡦 h\1$-" Ku?EL5F ۧ !`tCyh #KyO]cAf>Q$ SOc48#c ,ur6?ݿӤZC||3{ڈҫ/;斓 ^r,OUӎdK@j|wHHb<Ẁp ڲs)ч# ]aK,7+zoSzZjZi|AM Yfg7N{8B( [e= }oK8r!Xb&G||ݡ~8.@ @C욓\aP6l4Hc2?:z(d;$A}c(Ee (7#Ou16NzYߏ4!Y :ʛg{ {"-Nqa<nԮl{tdSZl߇XB9lX| 6gehzӂݧSqQxE~}z7dR/1cUmߪeſ}v^,/(7>_^MۢG=h2Pvp}Z\zAz|sC]^ ÖmT[mj% ʹOR܃saM5Î{q,jJ;j<ח7 %ύ<+#(sk[=XYxԕ GIsJ:.[nW(W/Ru" Ǒx0WՇˊф> |O<'*jIg\_;r펷OK)Few4xƔrعBk]c[=+c.[H:Pz YhzSzRZ:PJkQvOG2,mxLx)I>co!W-:Ewg3ģ'2D@C?E9RgwvۮV]a"iD&Ԉ{')z9B= Szq(n?/GNh#<>q<{i^>T:ɉ pgX*RHt$ʢ˖WQ>.3b0O9pqRgċ\t%wE7 Kyo8ws)lɈ&m!vA =y0w' N_l<0_g g+-&F8K*jq8|GTRzғ/%WPxTW_/tbA۳kn#V\󮫳cߣ RRSL cQ_(Aq| )F^~48^Wg[ 2v>:7-OQu?o+Y %y碣t&8le-P&ѥx&F@h3f1Ote?nI6@~W9Ǥ0|W+x5=~uu=\3fq}ɰq.~pHO.JmM&z1 eYn#N3cyV])V=k (T.@<] kpkOvS T܇ΣJKDxOÚK6ipA={V_whYsƚ%^?Ov['Nف|EE﷯;9m;8_J3,dE7q(ꭢ58tߏgz&${$aEJOT O7vXoÞKy>\'.A?Z@(,~,r7eJBڇiBIqhƷ5eɯ%& P*xߨJ[d&INW/BvI=zӖ\Yf&F XHNaDģd}s|[d']Fgj9;&߄rz&:byoܺ;q݅3ձhDz!_0ޝ~.IU{,S YnN_~D*_zZ}ޝ>(uos%*B\Q~8()@syʐOAxk@|zD"{t=7T/9.-=Ywݵ+ۄ d;ɽ?̒m{BI^17KҠ@?9/r_c;! sL45a[IRF֍c,wG6Rac_7D{N&$F1Jq)8/z@`b΍ xa'A`}tb11][|FPģO:RtZ]N7RZs=;y^siѷW M{Wb7LS#s=|V:Z9\"l|=4IPy<lZI 䎽_ 㓸uD:ωr*ʪG.#Owߋ/յUYI)uk֋j$a UA.VQϼN_~Xŗ,^E' XͧӗSWHl6{ 1wY]]eg64שC[`Wn8؛訩?Ʈ1?TC.>6%m}4W1׀wC Cb \]BzrK ا"N?_rtdE5P**-^zo,xu(y @oǰppɊ2.9ځ$ҥd$do-9\qvöfov #юuugwZsƝ~~Cז CtPC~X e^N&ݻY?aL"vvm @{|wd9~&Bu5a7fV듘<~$6>h䴣ݰy;N I$ѥ䒼岢 #Ҏ>;_Hxqw p^.uHC8t90qU:X-(ha*#08O|L~?LnӴ2V_ mqK0v܄PIJ%Br($ia oHr'K`t杄58ɳ (9KK)h1E/2@,\ P ӎo0da_xl@wWe{ n4){Czp?P>8IOb+/c`3uP- 6Ϝ! Јcy $p7| J<7k˔)'g_Uvf3q+=8ŽNP RzRq2"p'xfOv\.i!D#<|d t\wӯtx˅fn_H@6K`V_/sȆD!-wp/R9LEq$T;{e,}N DNOv҇N@IY lLKTkb6n#?ٹ!>]P\z:A~KOgȔ P\n(c0) T~֝Epn2|> O3j;ƫO{_qfN wW1yBOv-Χ'=mjIzRڑ죴zӥO]C|45VNvYѦWztE5̑@{V;r} ϲ#}gr^jf"dE?ujjIIN+ngwa{l/\8WQfnhUPķd':idoI=T}ĠPdӓ=2 ΀C#Sj g!OSs + ."> #TW$ɠ_Vp,BHs)~_z  J<-On֜K{g EiSP;$#?E`NlݩH8T؈T]D%5:|}wܲlwkUVJņc '4StY`-xf.1;jemI9c5o};|.s]?@/9 U9^k{Yw>R2cäGo\qLz/Xx8`6H%:l睩ϩG#~i'Ş+xJcPF(g5 r$ߚsh`ʣ;J} l$/-B|mTt}䃳HWpb>0e {1NX?oM@/\vs 07?׳[ۼ}Y kťcއǷԸ#%}"{]cD#j0t,dh!;-=vQ,2vv:uekOz7y}N{ 9.cө~|ͧz:ރ[n=or(m6ÿ?}IP}FPpޔgXϿcc]u m$]G>?gUat]^`]&!T݃}CvyNp~`A7<~ښ3@ӛq>5LedCLQ~ "poIZ}94tiN|z^g^ )sQp=to۸S|Ϊa:ܼN'>h)Hu'à!"Lĉ}\p+:3{a! %rcWo$EP )A+?X1yю1G*s890y.X|y+'-eC@ DIڨdWQyu_b}Qp}SOeſ}v߾s,;.xA(}t׳k[kpApf' ( O>CKuy^BD#v>&dTޟ\ t!7FϐTF'\^٫JMrؗ:Ys.Dyų|v~4558-/yiVYnL;D4sF_H8NQ[S,ˊ$WHDtg qqI{[X=yrE+Xɫ,}nk;(ąoaE|+9G9^,ljœ5}=˩Z{ fA% 6(8=CCoٝ}{ xIyg?lbRP:SS/Ao?p,QH)Yqa, |L]J;7U C~te瓑йzkD.GCv Kqv.9ű2`9$'0D`<*{]2(CY*+Rj6}ClJQoӈlX1#w4.,i{6Ki0em@B/)Tl G(_1y~HiwQ<D^~n?L؈Khn,^VLI^I* #&HNlX& G}lh||ݡ~ҨT۠p(osdgP7[aPzQ[kj~F%!"4UNEѩyT 8.R!GAy?ּl>+=d&suHz'`UXԵnC޵[!U2X^8W]xe"iItcF5fXn=QϜP 4]&.hH~gG = KMa!C2:Rk\52d (ivI8䎈LHR;vvRQFjb ]<yA#=|q,KFt-tjfA! Rt>>C9B)}boB L:1p&$ TcY(.K_RB0 T@rrTޜ.iK<'ֵ|GWp5ۣ!,gT:d+0M9%u8J^LdkG\:5apw{P[([A}Sk洭6dCO,;l*7}y C4EO|\~XڑSҗP5nԮ D0QT/kΧ& [-iLFdt9|"'!.Ku#L9lXȐk$ҏ:}9)T{is0v^ԣ ~,zcUBH*}NQ9>h sӥT@Rbr~;vk݂HEdYϺ1-\lA ==%6L}Mg-(կ faS ,Z% rQ&4o? іOpB02 \ӛGr2T&Pe2څic{sQ6vR[Wء::@:r' '4_[L嚰\WBܩxCQ ұJ44qܢW2LE88zZ1sݸЉ@G!y SIB+F%!bk~߹,4Zd(n6Le-:QME@NLRm 6mGGZ11W$_%&k>J6=%y04sJI\y\aF/?޸A,s3AIϙ*'x og 6i>;ڳkU'? BIԞAt\\kl+,ڃŒwyړKς_Ew0IqA?^gix;$(_71 AyqP^d[USP.Hrx3ᵝ^R7_rF@vV_7).y\a.< ?f6^4Hҟny揰r࿶LAHr bQP<0_8 olʉ@)@L= BeU)r77^DyxrnwHFn ""7/;2D@VCn =q;[DO]j@6P DdO`qD yjL&) T\ul1A!6Q<ȽOA|Zvi!"m.8C58[!J}qa\2ePw]0J$JQ`2g.)CoC2?t,$si|Ŏ[3P.@2&},}(yӋ\_@فD>9$(7\@GAʖ~F#$/­۲bvGbBx*@<ޠ:}@Se>,!~g(átos8:8{\9*P" ykp*3Q  MTi$e,!4#ena6M[e ϳ2! 75z f^|o8;osj]5Z ,-xN k\qPOW+:0q UZpFjBJ)}Np'ai\XѥXT k ҋK8׎,rb9UFWc Ce ~}rw R5^itF#YŸ.$/"}7U<|Zp,š#!Lٵuǥdo2X^ȕ :B K^{0~<:,[zM 8 ##h! ;=a(90}}!}.|F9 Ά#2oUEW#R.ElWӏg180gGD{>C %:( ZQF99JoӵSODD \D)׆O ݮG՟ǀ?Czzy\IHw0Hls+" EB:Gt)Pl dz阢;ĻsHmT))\= )=w-lDT?'#>7$DAAP&K}W\ 6"(A#8<3qcj7k!ss6bGd#i(\r5mf},RBߍ63i1R00>,jdfct{FH*}Nqyu-x> ()y &@ @w3ɚ3Ҡ$ѥ${qqNlb8{v3I@d54u'pW|j\BnVZhaӠ_1dU0k;rUq n4~LE%>0T^y[E"$\:f?+[ riSL>=񝃜k^.k{6cӎ.KAuANx2P <ȕNjBfO)e@2ș qaxKGa,< 6ȉ;%I| S(>sɩP¯F-n7 J>;^P\\oIB'%vk* Ke G (EUp88Z\A ݮ0cX>5œ)y!$;,~ ɞP܉l;SUEfJ0e;Qrc A",lupS!g~ʼ[Cv JZ7-я՞VA~++[xp;$#S'=AE3;?9z(SLC1@G>3Y<{@G>["j`R;g(&3/x\ȕc x 凅2U}>/mœN,xtij/[]0Oģ|x/˾ !O@^Ev/sR4EAEЮ !>Ղ/ ~~0%}k6ݯ5 MuڢR[޽ewMZ 7n5vˉM?c:z,+  >=.4YD鏳syiS`E'$#iGחː SD{!W#߶ 2C|)2`)ܪ\UXt dY(IW~L pLrOv!rc)vPC/ J~+s_3e J<id=u:o5FO|ޅbb[v1篫N̫u= H([>]X[6烜GdBջ0=0Q"C݉U_a]EV^H{N`[vSURv8D ßҏ إ/)MvH:p#xe8̖O ` HhYBh$8å<zC۹# ~"ȹq@e.&J>HYg.S^<{S A~_73} :v&@T|'E {Ox3N0k àtwl|80ǚc T-b{: Ck`KAeѝRZ oQ(bG!A<5H5R؀R mJe/zP^P{}}sL ys^H_5!ɯχɝ-Ho6q v-~'foujF֍cSߞXV\|2g\=y qF%f^Bl%pAG/}GSIN<;t Td*z?g΁4ul.CPpKi=܃HWmrSJVNaiׅܲd1|TXG Norh~xpVO{׃ڦ{Ra5hN\xPS.? Kp=TUUkd 4$+ed~z.+БO;hz~]$pChG=#/2 4BSEa*#4&"EW `D< N_*Jfac.`9DNM:l$&Aiϸ ^cj,VlxFxtXL@=\ Ů!XdGd<=fIY8g^B_;O.03/үw(+~S!cf2/Qc,_M;yQ'<2.KCpӥ|!X̯[<9"2`^ȩ(Buc}[Z,HMR3BÔ/PD Ilӏ _tF,X{),&8R K;4=i/,b@PܤFQn,|'.32ٷkᅩe ܘGϩHWԾ-oWtV*\X1!VUI ބ36>`u7g~5/EE6y@(2jB,I*bڕ<%T ]1l+(iš<@ޅJ 4bA.+3Ď3;2 &!:BoHR>V8Ϫ h30x{o :-aY[: o,_6\܋Ոcaฅ8{%7ȴ\E(2xQO :X6,UBγdC`'>t8!-4[cG1EW6,Z&B\2@+Zò~^FrS@\mٰÜW8HMwG6X5a;>8Q7tYk(b* (URK:=SeO ʌ4Ijo~}yp~= !Aqz8e9whK>?>7e;Ҽw.MݟIƘoc_Fwi=Iz"Z> .F 9}|?a"#$R=.Y;ZumNcӏsN; bY{􋽅\eԇwgХ3|\~X (-H4#Ÿ(v"8)v.zۡͱh2 s@8%! l𥊧r[ͼ",ʐ0\(hj5,օ_B՗#ypF2Ţe| b?ʚD{=>M7 BLi B4U;x#IayCg2 VيGȓh/ Ug.)+| l|;&C WCr.m tQG"}W6LedG:&L^˲W.Ӎ`՗ʭu@eU'E=Lz|wZqG Eo;v)^|<~XxV_ھcx]>8R1O(q 'kK[ƈTל/8 2d{u&sO!T%a=6ˣQ~`[}V]qm`o(^\]l J٭/?k3tڛk,j!-ꏐH4vrR#-;=R4T-S5 \$zO n{KE^>1.$ ;2ME2r`~"+({@rÀTd,I22R%k IIߝpu- )Ekj;w-o gMlGB<@]OR(x)(w#(#"-x;.jo-6!鬍;8dEy T Oyp37zmsxb[tjp2r;{'+p/6:}~8A=PI'jl 35Oo궫W ?i`9ْWWv6eP%x  Cz2o c uavA oje]52A4PdA/! Aנ e`RdP{ _G cg,=& i}ۼ4k /'@HgRCl«ܣ|?9Iù[ ԡ?2 /GviL1uQ M.n̟n-Z - =w<ဤAl)Ry׾8& Q[ gmσ.Orf~RQ.grE5(QzI~Jpɩr Zo9 6?]{r(wr C*Pt ƷՎBR^p/:s)o)#jύ<+ ֪. kykj&d$< SfCf|OVj쳰AIOuJC@|O<+>{O6 !ģNuF l`|\ݡ~5`Br(;|OﲦlV >Ol3@%jYKX|R9S d;t!!e]X'>ID~0ӗ t`~Fiy\2R@"!ꀬ@( 7 Btz]n9,,*904w^X!>2úv\/ 훥FⲮ?ܱh=:Z7I KDBF\r}[rjd :PJCR)}c AF9ndM;$-x 8xځhG)WH P-h}̃7S L0+%!Aj#^r}QtSC/\EVo=Ɗd<Z*&"_>(:@ۓ.} x/D)ju1^279$ {COA%aW6NG)jkriƥ(T64@`T}G΀gơb#SPvwH1b' |-\vA 1ߗK/zJğa _!&?^y h+:Vט~L 2/(w"=`3~ii\x*y PtH2<"퐭 sg$rQh<_I>XUQ ;!iҋy ++Xcwr*JuD']HjM:+wSzҖ}jM[ԇGObT0Gym?Akr[.8ܥ8!p~"ǣօLOnNIynܫ.Ʒ Oe÷$iͷ[o,$sQV;+9$3C {aD%mנ\rۤE?&I[T<;<m# )%}VֺJT9h\BX%.#ۤ}'` Ӗm<3|[ۺ]76m m+dC&_#sHId.ߙy{aI6:Mk4:=9^A1za'2ל_Y1!!ɋc T]YOvPyЎlIk4X4zW׎\_-`F!Zn^BoX8c 6A^nKKw}3|M';C!#/n?B'ln/}+Js5ExBrdy`ś-zYH4y[dqO^.+A{TuYn9ŐSn:>TE6^V*E<\vKDeY'k<"\倭=|mF]{7Py ٶe;)(H'1 ʆ K5/ B浏M&IF[ڜ܊$3.-|m$' nm,r4*8]T4 &ޟaV\l0 &VKZwjK)TĢW%wښ[aצ92Ps鋀WzNA':E//? ‘/N;?IMY%_[GzRT"&p.bP0L!c%(NgwSW8^Xme,/*iw|kZMzp%߭.!h \T=2B#Zo.#CjwA~!/9$ss6>}X\Pb[MMXRX ͓s7E\s0634jQ}=P%zYfsr@@S7>r$22| `t)Ek~(CQzdcF&6h#j:_o2L@`fR1) ?(<㧨<0SQ4䈂byPf8:*J;:rD4L6Hj_m?ȣ'7n^7R|~-]rT1eթp*E4|yZ;Qf*%s"ȃ-(ZV]b/B#~3OAyrXm\ce01ϰHyw!eg8s/lX:IORHc?W)#1"WXK8CC^9὇4s iqYC6CǼz h9h _ha)?nt@ 'N'ĹTϻd|Vܵa1f(+]XTּ+(W d^ɕD,7)C l03K?佺ϲχF֍~!}ը!A/}0} <S 8zMwC]߉e ;y!}5ō/x_Y_ 8O.e7&|YN - ذ Llx_] oO>k{!p=o>jQwԉeP%t ȳ\ƛ%wx,P,P^7]jxC@27z꭪8 I^]Gc.G kQ7^̯gLu>Dx^F;K`=ga}q0KexXjXV@/ 2:xmv~8~@$ҥvq;1]Ad , QLt u5gܹ3egj1js=/̩zRg/Y,J 9 B&Ct`aAF%I^L., 5HC(Tcc3e*J i.Ȃ4C!1F.J]/3tep`$5vRC!`n~R#K6(08c~Smih~RL6y(iO[RtuJ})e+cϰU:dC&v Q&K9c 2|LH$ RQ$*Gg҃{Y~y}~t~m KQwЏ8/JcIp:ohAP4"$'ʐƻ ?~Z (t‹d{;PO ta;/n9;@yq 91 <OEwTKyO]cd B = oWn81|yJ+J ♬K@-%*-O $(5F^B! saX> Yq*9=PW;Oq!Sh+Y8CX" :9ltC.y|FTqןU_,߯E/5:_! IE|\~qH5&b'x6.A AnC/ȎXd%Xhl7;qS{ʥC*ˇ]0m8RUnQo!<(QEIje%R PR~< W2\_@Yue )p dos U/rʚe)j J"g̃s<̒8αi/_ۇr?sGs C{<]_w aaxa!~VP+Zͼ,}"}h S#;s,x㸄?(+L_+uIڏ]ռ(RLylX>#DGm#G4Aѡ'ҥ:rT~P0mF}qCc)O;Ll.*$&sp%{58TjR%ub( QA}x*|!'eIBW+axמօΧ%wC22*x6 -Gعvzr[GjZ'vRS%{Cvۭ9 =`2LOh#ބ˟y˄jY)u?kӑVԴ5Tk%D3)[pm}g|svL}bSLWNCVPRPʎ4ru!-tE@Md$ГYW=#=rGآˢU?E݃es 0@PF[)Nݑud'zxRbUeT~rG3JO[E=P5҅ p(q=dd|\~X /"ft)-~aaSd moVތ$u"_^l`nO%,>)y}go{KǗ S |u= IP|]%}bd'FFy^XY< 4)q}ո88_^q{IouTR??(GAbhyxt9񈎼T_(vD:Z\^.lW\dosɪҀ6[}'h%jwվ' ca3mW*<AO^VD;sEQТzB(zdx.ֺ 9$Q*dʜf!5adKP.Cmâ=y)nc0(t"]+wHZUBR[k2K>e ΡVj$2 "J^D Lgua_Fzeق~Y퇂- 7uH·I/"X9ݗ=Q }_9\L>.9)͗uaWXEQo5esD) ӣ3)PW +ck}.&i<]S>&')21壍?p}n[gTzIFr)oݶ|')"$sYki1K#ǬORBME>_1/M1K#Ƭh7omGX倭= ^Zײ|P(3ׯI #(/rh>nYa|<:,edx\"1u-h9ڜ2I*D.BW[K!< Oր̄\,°/66c)ft%ʚ6X)ZIwǣWA,)yT)*:ϲy(^#I/\TBù8ZK@*8>q;v k-|TLn%rGA]YH$9bGtE%I(D3ʅ(ɗ`ˢ?gٍ3I-7PWoq^K.}_2$~7$$|*dSS 0`юՖ$&"颮]Մ.hڱ9R`0χcN;$"D%  \*KH+:}$R- D\Ěx7JiZ}usV{a0λ1E?w .GK l;&lbב_rn;3bv$':%Ki];1 c`Wef3DӎsG# ֒C2?tλ\ d >@1^PQڰsb-p!Af11K:n* O9A^7D]F2B5u,~S0CEj*g7e!Y{ Je$_Ca21詫ĉ *atUd]+u~ҵU +9ˀق;>|YzzU]0QoZ.]QSWѼ<1-@ae mWQT} 8v@D*WW]vuP{fUǞa,yGW5,UFU*.Gb V̿rycP"om/{mȆ>cy!W.sNeUE+`"b &6GyR kx@0YC|B0rw"rP)cW, -_Iӻ@qJm2Gp9=]NxteMu&}z'ì]KV7wXiVMmiu &jJqU0҉[2ߺwTi૛8_3.(y SMX6Gv\H#z#*Rhv'J3jE;#0wmW]"8+m]ɠa\"9C"QN*b箂EH>煈;s7~ojRcٰT.4H #i\r),-!x' H_>v!hW048{.Gy<riv$e- #2B,:}ĺ;O"} rwx$wh嬺 }<.q8xZ7I>(}l6舒- cP!.3e6ĎQY]4̥&Pq=3[92v74YP\ӗoˣzRW7ɋ]JZ3m}(,RﳠQxn**Z!5; 8PhIs?1Xۀ'kmDXgk̻{:tEzPOZYW} yo8ws{ɹIc5]] 8^^_G \;{pX ̺;ezZS҉r v l3{8XW; @hih+(ͺ*i@,# ʥÎ"Ά$ `K"euK?0*jݑ]c,;1 ^|FшGaXU]j(ׄ7 n߄ěgT7Lqt\ y˕BYi]?/ AXc( UX\|Zvi!EfF p|}nX~.prQB .HR@T}|#$;zҤ:Wp06ԠW 9±dJWnEuCO# )>JY:}9$á0ҩ±J`Kn\Jѵ< Bra\9-73?CY貏S^5$ Ki4R g@0>.?sb䪨xTO5ʎ5hIrWa\xhŠ_nKCIT&-*1ReK}"Nj׏ǷM* ~s_PY, 肓$YA\hIsvC3mUu;߸;vv)N|&ȤlRg3"bhN'`TAL6\Zeܘt*TF6(E0穏ypw{O7,{AHLkSe`YO~5j}y1 $.>=(]&沢 N+3'K{ O#,oBbtAX<7!&KoF0;pZ!)B~ қ!l&cMJgrJ$ Sfp"h4= O fysS]ݓ{Mu O3j;ƫOsw‹Nhtp~ o\TuNi8J SL60K>P!%.wHvv%"+i>/tv"d_;N$HpB҃{:N;r-(ݷ r,ofaOIWw^ q}bd'FÚ[:ꛍPaN$ÑӤFFdD25/($&$P`ڪV3di1fäA*`_ǫ*)w;$=qD "(;O9ߪ+T* ełw5Ol B"V+bsUPZ0%i`,Ġ6a>]Włqq_ÇAI?>| d,/@_u ҉ҍV[y*t& vȮȢR;U1U_{Ww-x.V]Q_?n禭"R$צSbE}mULP%wotM.@S^`Gnk k=8&uOxÂ,>P4^RƋ ^6x1oWc`%=Ƥ 1KA(ϽWO<|~s^*AA:}u?ɯ_PcuX, g8a>=A#9"x%3ɍNO{3J/kpb._o|\~h{VR^E! OlEj˺Cp}zYw/˲iS>.@\ۯxK6CX[E-.Ck OHvZ[@]@ܞŷ9OH;A]u6sI]3fa~-!_ΐ;\dL2uo )k‹n{zw)Tv6_k+vrM7kq}x;ho_}odKzO ;u,ioƧ@_l8(=SLDʿ'os<^RxP&Fj4b A<Ɣ1`[ۂ.|we୬Noeu 2'J޼ۑj}T%n{2 KP, rC"C%T)ti$zy!l`G]ɸ݇a6,TlD(JZ'ރ\Q4r=E%u },#;<,]T5j)QV*B+VdTZy{eoԳJ%8h9;-@Dk'B@VoN; ˑG1T0$Iבk¡Ū(.CrSH\y81==98OCQ j88C!Sz~T;á҅~(!\xc(ّUPr{ {piႫ)rդPizL.A vd5.}( ZB{vIn[1[TIWHYIA vNbP\޳7; <ή}'~w%S էޟ e'AYB׆)RRle,t_˓$ӟ AǣòO@8NSa,:jёn6ќ,oljIBњK_xˎ}Qp}SO7{-aW gO~ͫ. :B{ʖQVi-! Iҗ+S"]jW$ECo=e.-gtER,@FOP%[f#IX`'Kb)mJ ")kAe箪~5(}eOP-ݨhwRW=$ BՀ@t٣|;ғ\;P5t)-pcXQ!Jo'w n֪4̥o`Em}k!O>Cx2ȑTxmTF6C _JseWaxe]I0@7fg`gm.xq>J3qC9h{kC6oow\ݣ `1{ 9~<:>t><IMaPb<*~ dv;~;%/~;E"UՏd(eu ؉i᭒ՆaVAh=/rJ)mQ9UqU9!)ŏC)VE*bo!WVHsꂀ:c*>XZT$R1> 8p'vѥczZ-Yp1χPp> My//9Ke>Rօ$ hh'C\p+-| JX6GN$ -t>v>jj.]EaC!1m5'ۘZ4 4c(J,INF>Ee7f!3\n=QE%2,(N|-?OP2>h@ > @b{?J_J(cϰ˖<)SƱ)+Axˎ".[&JxK)G aHQv:> :1߷upW|CyV&fe/ ~xn|M{0L}p5 >.Arg}r`~ՒShՏ$\?5^f/ޞQM҉l;J~?5㗷22YDpR &~?rsp&D!qy5E]@;v]j6ém:u rt``VU_ː\}USS!8E-q㥲-KJij o]uzp}Ox6 L.QsT'n>c㣭 k-Ue.S, ~|Cc CҹXP]]V#k3aM.ex\2v& ˍ Pz}D2,ZAB(r6duȐ*Gv IXvg,er Ve`\LN\(e,R,U9? KNy؃. 2Z`tsea8ĹHK*v[VU :=Hԋl; L܊ĩL~Q!6֐N܊TTц/N \:r'uAefVhx0' B.sY45@zd, ?.3 ,xr߉kPL? HV,miC$('!Cn#~j_E:$+XTmef&R~6wue6wiH ^9po*Rc(uALfAiNk 2b%١1] R@_@ <ELݙ:sy#;l.8ȃ}[- 6d]j2H6r0x~!O'tۮT0p!ϭJ~A ~j<ΕQ@($o\/^y\G?@ HXmқԄX.K#)/||T` Q:02~4 D#pE<{4L_.I ބ!VaTV,8_r^L~_rk95HˉVh~ }0)-w|}wܲP77Q!_bPT5t.NjXqR>x"5P#@ 8(V-5.E0PO4X2%R$I9Lwgv!rZ 2 d"^IXqR)2v6b,Er̀o+ʿӟU$ dj@ R" ^bP'r|b^|rZŲa8&u?&xj\҃%Ó R2D"qmXe:a$s *y5E/*!O]ul<2.n\Q\9. WB~2Mӏ?u iu t=~5^ϧe?>.nexJ'r`(v!ZBܣ QLȾp"'#;ߎDGE=! E2!` k? ZK0!Fd[ Se))0A!s?!ɆL! E2!+wpN_b;*B_/YVJ tu㊒t_K Ak=IKb#€]!`q9e9x݅񰏍;'Hclp|>\ uz^yKP;삹&|A7aD/EDņJ"*ƎXQ()wiHB: $x;ܝ93wge=fK7:/6IeԽjәAq:?9 N2EkEO"3(nd'$۟[ɋ &7rʋ0|c뜝{iħ45^^0 D]phǮ sbtx>oy`H E{+ қ[gˇ#/=ϖyavZe"1yET KyT:rtN;nƽChznښGuK*BU5@HEԤ7u4Q5'Ϥ<15Alp wrJ(XPS  ĺ3c6HȲ$F n̔LdGԫoH]{^Bl2|rW(M[8l @L]`rZ0Xu* Y;0 #hcRoF{#1FlSR7'/G:hf*fy6>V>џXсmϪQI|0ٹ:_b7j2V6 52%[e2 7J˟ =/kpG Rv`9h|(pI)/BÉ鈮Ӗ-ihq `}t+ʽ,/\net ^'` ,F ïCYŦq EP$OOA4q3 fPF= FiJȶwrii&!!}^HR&}JROB9/vH>PT}*M-e TOOBAQ2:SN@iv),G"NPz7,z޺Uhvrx 1gVlQ'`ZTdt0^&( >M:" VoU6 73Jd+Żcݜ[=?L+[bY2wa8ϐӵTus^~lXiz+Ncw/ZJ֚~ٵy3֒M&@ݛ`RUa2&ꊓܝu>h4&>ڝxb ' "$G&Ńk]W!3/ sw%V@"#3: /P(ˏ/85BH"'!3MdT}0?9i}s9 ,jOCGq]]K9Ed]# rkuJ;8@.8{9*|~p|iTA4n[IH^A8!)3PhvuaZxaNaeZʅa/ѽnҺSᡗ_oFx4uWO?j P}wu[ZG[-K`-1 ,Μ ||0)aZ'7LyZKqXV u֋`|@]~+v5?[4"x|.'5Й=}.X> %AIT4i3mKh%BaD3>ʮ'&U5 L]Nx>^}W+UC.tqPtyo aIcZ|r>j2ה0U~3}ߨ?, ae\dIE]XK ZѴlξ"9m|ѷsj62#^T(;$@VNNsvܙ , '' DJk^B@PX!$Dd;viN،#C 2i6ʱIm/1Au4^7V)Q{hˠcӆ׼ WxwqM6au-ɝ{0YNftZ+k6~fN\qb|~L͸nDIRK)? IIS>jglGjfA詼N[ K7?M 4ů;2K48 RpkDO.H(c$ҭ9cy mC"PHU$5gP ÏyPSiXsa{ʲ[YE6HYv.yO,)Kt|#ti5^~adY8f=d >Xy wKA}˰K@4l2 _zݧ{ѥݒ>[Mp㶱?ZitS# < (u VT@{tM,SI 8K)+sP|dʼ a_7TbE['D:0/K:dѭT>?7]i@!G_nFU`tF|zU;h(}đPՎ>*</醙q/B[^VÕoGxS8< re((#2 ]*.  eC,Vʑ#=qjG~vrҼ@jG|r'ar1섶zkFU0V]-Kħ>LN̓^2&N91M+G73 9c|6T :@_Mtf]?_)NJ :uC9!t̏X}G{vGprXZ'n%O@KaM~.tcr< <œ\.a@1:' BNuN%C@6eB*$ۯBDBN~'XajF&Ny\zL?Ju#!֎c[é$/N g~ %PP[=!]5>Y +ѐ-{s d1F`tꍰ@WgAF9=-ML1jpjHDw?·lާ =~}zÍc 8Sk {BmIfp`j6DGU$VJjFą4nU"-_ Ins5DYmȾ;9bjGy꼧τBYSՎ䬼7_7PoX;I\jGOԇS EWS NZ|Qn#Go:PV{G>5T,=GOW>d,*#s885qq$ns4@ʋҚLn-JӅb5qCFQPpO5'[>8%Tg[t^ ږ %, +(`]6AAY_OktA ҦqKh׳6ɛGy[χD8h[ z':;olΐ]w_{({SoʅVKcZ p/zG?ɞJ& %D/(ȸ,UgˆrV;mye&fL?˄)˒QP(5s@!WVfYL $H:{ɨ/+y'akZiS#*.mIB-\Y " [ BNpdIBUP&IJ#'o!tÌa?Î*=7#JYVzlk EEϻPvm/|jcBS|~y#_E?2~ !B׷T#)dP>C|Wi%S;w`Zxo퉽Hs-:Łw(WW_ue3xtN_$M) u 2`;ɉjDž%@_qfBx?u%C"Wz6Dp]'6Ž)TvCO$HuWAJgy|! 1Rdqf'ze5b{)|&-0iBP4?f_ C0T.~ C34P>ļ.z&UᯫyyGPu}4FH; a!*(aCvlH5X{ؑ  ]4wt@tq8)Snw{vhP$x{;d Wô7;d]PB^N P62aqEvUj{;Tz?aǿZh.s[=P^%@%&XDQav$^:kqZFf&E QtHGkO& Xre[;P^C&R Ct[={Iֱ'A%#G({W;y{@$7)}aOt10zEƢ|>GI.@z8')IҊ]rI|J靓f[H$ !o.B~?'9'>s7w L g=d:'\cP&̎|>CbAgqL;*7rtNga՗ğNp4!\/v|nnJ+@/b-SyTQ] 44<}XMt,^lV,kIPĩF7 W$ۨаj@yP"u*v&GH(T>^'LC B R^a\)ݩ+L CgĪ/ExӊpW_5]C[}IՆ> 5!Ph֜ :$##YyP՗ad:.9`a^n`K};]}[Y{W_FUh 훭oM0Bg&`VI,9!=/ H)3oFIQ"L{ݰC2>>PljS$88֠hYU9'ȸe,EL.*Z(?/Urz`]=nCEVQO|x6k1 ώ5~3N|6^`r% J^De)aYSPuBȴXNP\ i_'σYx=WYP#QBu@Ukfm!m\o j@e/0K_C -:__Znz^D7DTTUn!*,&jM 萪\k,4/i*W"UvHԭ$$|E PfHn&ukmu]:񩑰Ƃ8äiϤ9 tYH!]tPNךJ P^|Er/R(~H(<"g[DR07ڳ^ {L9u/۰1(<jW \0(~U``4KP2/b%,^+:~xkCs͋buoaG=wdm)P&j:ov5~KF$ V'Us8 S5j-=) U)i\pNRs՚c \&̀uѫ+C@X5`~L3_7PSa .ӷ㟇O'aͧpQ#^Xc^ X}d d,ճ?i^]8t䄤ʨ;B t W󑨻;x-VY2 ɸ7j)0+d$\p$(JH+ɼ M>P+t&ͯVϯCI2ȹxRO@ߋE$chq P-C3NH3r,y4 g(&]*|Xt5+ب >1`hGadO/JUaIPFiV>>f8XcaPʙLIυr}BKa5,X`m#"Q UN4 wg̅hͮOrw*nrreQ!q!NrÝȉחZ21P"Ge) B+硚^NND)i D[//]BmB Q*7yf$ ?ni<ǝz8H넫Tݚ2:s2np%"#Ʌ5ʚA}sY"#j ʂtO7ѐ+0{Sǿn_0ъ[Z}O; Vrτ+JUz'ZO WT^ HP\vn]={(DkLPS'`j?noexV' Ģb>%$+ME2 zuDPuocD Bcj K0XG >Q1|qݙ߿9=(G?4hGl>* " A,wx _^v@@CԣjA2]繱sҽ9k:hSϤ .}>q!u/bD:iL2=| T"YT(:~r> wNQӟJPy2jj%SAlyTPaF؅ `V?(ȝ#k ! &BDF}'@8ꊺx=&BؕN&>M1Y0;N:2 U?&$ n p*q3i*_<yK W"C,e|UB-3 T2ϐuC x>~sR3/PiG TY4}^> P"?3V-)f Viy9V^󬽤~w|PBr@a-9 [ \a %τ1rLr̂y]:6rhh^WKQra({[PcwI>uh/9x33 \k-ZRSx5<1"þ{=6]nM#DPF[Ca}0\5CCjn9nt_`ݱojzly0z-|ib,'_)ț˼ya}3]i Eq@x7L`*JFN'{ss~ϵiYvwޝ%c߫I XRlnǞx{z*)md^b7K݄A 65/!zy[K Tׁ=//RPr{gceVGyL==v 30 3< ،{xS{F`l~ _ #}:Ah­}ZxEo PlŜo XGS?@@*)e:*@+t.>՘wB;GO`wWGy<6uÁ?WN6*PT(`X$wvU?W?1j$ꫪ@DՀyAYf5PU(īZRa9GasAiy5 #XAۍB9+;W_GuϧB:7ݎCJ~|Q2ҢZkQ̻"nH EyݻNտ뎭s?W  .lC%|Ν m[rD˒kïL<SWMެ s7=6|я.^ ږ Ws~XCvx}#KnjCk?.Ppu?(;GmOiwdUOEJ xΑsXxkl5i:JusK9sz}Bd)6C64@uu0ϴK c{L|/]l`+?v8:vsw G=gԫjCS haDž "&Ӭ*I(4o ^^ThhUnڐtRLok[UttϮOM3^{3f1݁6\NR M6w>9fݲdFe&{T*TEuy354sORT+ 5ի +4A ](Pp.BgTkͮGߥi;RXLG mE*LV(ZgAF3JePxKo'= >(Nnz l](NC9bYr>ם*XS:Dr3y9mD9x=,7Nugu>HI#Pi\O @8;6qSݝ!/T?%vPD ۏl\P~c% "m! | +~XZR`8DRuC@@'Xg09JC}u#Np>;VK<;ư{喭g_QX챐p=8e6FeFdRI@|{//o,qbeЃoyTߔ:Tw^_,颞lu߁.b@REQ fF ?kFt˱W4ʱ'S+ DaB7g&QoW[ktq*ȱ?ًh,~+`/^P6!c1aʱ>uA'i2ootM4ˇ#l7խ4G/|2'fk_s4!B͸/`|QUY>b,e|_ď\2ڌv-<-kg|ʼ ݒ9tO֜z%9xǞW&8ǿT7 /97O,8%h,z.e0MsK߼N5'͢[鴦Y+Z^2kr2eF(5'}}y+yzPTxvO`6bY2u~HGH#MtA6,?d֩jӕs{S尷:=WnXWD s>7]kj2oMMd??`nĀ14ړ-OQ-9'8 A؁]Ku3an ~NC F&Z"mPJ"\@Oa:|#[j90]&_n^l=:u q Ww ߧ;7lk{&;mm')9HT[wUܺwB tٵܻ/^3l&zȈ`SrЍ/bDlQ*7*D&H&U{TiTmFTlFޱn;PRIy#gUQʬ{, [s0s*FRq]5/۸ܖ5I+`Mz[{ȋN~,kZŏs~q rW]\yS ԧ+`̸q>sK}nqfZ{tqy}m]1]= 0M6{/?^9WRa~0,9Je|"Ǩ k˱*M@#|,բ#ΩFph:x"M:pLH[`!{'@ m֪=9ox(͎Q'N %"vŇN:UpdEC otsAfpr =N6aS9p!h~ #w_z DLU"ePG݊ @!0kL< AG_C&UH>V/6ģ6nu5,/k`NuPvC/?|l2I巕(k SLu*/P]~DS;w`D)9XNNj|t? QQ;J,z:F]OI9n}ljF'Gq0|=VˏuEGȜa|ԥT&Le [/9%|ˇ-y1wJ:R|q>^D{I۸b尧ޞ#'~{Wu>nh1xƠb[IH؋|(y{2UV3#s2:}z-Fé,%&-nlBs=i>Ҝ 0@:+}'Sk ΖzXI[qš}~BAU1֤2|HR|bv蜓^AI >CM?8CzJt࠮|+=ա~}^=Z](./╓Sm7X_>Mo.& 2%J-EL#T ’}^8no{UЀ'@Q Ьo:Dz*=BH9v8' MS> GT!: %9/!v5CP| T(yثfRr tiyw[ߣOآy^aN]؃pr@9"Hɷ(7taKxJ1|#MA/"ݰ*nEFyAVDJ"xE 6f%/ _,C@?%Dy@U2A/4B8.T8 ^Diw( Ώ (%$`Tm̂Z".I߫KGA*&9'{\ {2Z kT-[ܛ_I}xfzDѹ#cQ%gME?3' X0bĢ%7*½قc`P.jX[qlS|ү!x"^'6*ɭ!8:KtRu_(LR2Iy߲ RDHDE<")q6}8u6pC/(D?c,E9Ky? dߒT%z_9~}L|0!-?1`ꇢI'ĽI_z8҃r~cy4WhI -[iC&Ws;ӏO[8<BEPgG3TϤg*{G1< (e]L dR9ե'Z(wƮ 7~׋: ˒"x3u# ׁy'ANѧOWέK%Oy|vM{Ny/%'ljxdU(RzA{TypS EYmpL 7Ȇ]V?(U;A5^rsvOV NE/ ?U7g[2H\9mX mkzR˯W U`V6 PMDpE`bsya2 8٫2U~>/JsϤ!b޷ ;艈<_T^CKv's.hNH#Jqk߳ Oĭ>o@/Gpފ/|tȂƩH&鮄*̷À+GՖD'NrN4՗cNk(?cX;Z)o#5NT+\ȩN3phҼ<62 \"r (@hd6F,Ipbzy^ǝl~oW#CQW [=?9yk_>ʗ`̐ӶTŕh㗜 [ɀ;VT V>ooHfPLIe վϯڼBU&AA՗ԭ^"@!FQѰ qOJUFhWbWHW" Hdjs] %p9@7ޢ7P8x[7CUK 70ea0h8gc~Z.`6)B%`kRٚK."EE+A\HD/۳9D{b}{hWi5P" ;j[C!ׄ;,e|M/F+~ig8vv=Kp_*MC?4>x|%DW}#361cpF9GÁ)!3i|habM/pD=7s_q"j*hs/*qe0!:rlY2w@T|?/ ӋKUvܷw&-] yY"k4k!| F+M_?i#kOT<'rH)zXԭ9}EHH7̚ص@/I35T=Q`h7rcrR FAҹHl|89(L[ j!HLq ToM<6U8ib~y<4{Fn~y=RE@KvՅbOʅjjte}E7}N*G'+`5Q?Y+n@߀UW=Sm{R54 :MorP`itk&D2s2HD` MIt835T64qdM_;{Ap\fs~ rkj? MnpRE{u:ך]TF{-[ZpbRZ)NlZJj|;ֺ\{3UH\_F ([ "2&&3\}X ٳ`5zur&>zʵ?Q2{zUv#Ey\!~!x`yuC}=-Wit@x/1ד8[q HT B&?rǏ\uP͖%LL  i G/Giޘo}Vv>u22!̞QΪ3\sz] T}  O߫C{ǽf{8L9e֑uխ:TaaJsa-*ʉX$(=Q7#:@Qc"g76H,af1H"t5>_sDusaI!Sߓ@ _& .0!x^ ͱ@I8>nh(9prgg-*"ZnK8a$x=4ޔ9i9MDu&@?ym?d>;#$K;Gg1BVŰ237r%C x/@,nՁ (٥Z}ʓ); 1 :ʙ F&XK&EYw8Xonײĉi䌤r^2-ʲޕwUg>B?71t039,MQA M}.g(rѤ}&ՑB&Ci*Wi?;uQ4pGb/2?O=V@t-,F4oFvTb PvF~ RPHor0My7 Y-#%!!p.H)|Y4@ .ip# UF$:]weO9 a4Aj71ļV|(Xl(5Y9lQ&nRIaRՋF-?j1LRW` S`>G?$MAh/y L|V6,DS`I" @7aKeL AS&ާM>PR5A'"l%ttVִ_Ri7wY{ .^G!KzV`z0[y'<0c& w1vVRB 3 9m M?p*:PqW'Fns|~Y݃By[8ʏ\_ uNI XM}oL]tl'F&_ ҭ(p O%pՌã !xG6b=Bq`,ʰ;nwٰUF -KOх2Z}O; z 92(.sPe(ekw^q8׼mcQ^}_Pqۯ\Y/-o'`}t:~:30n%P@oɮS߫*2 uH PMJ<Hly[6ݝ?j(h|V_=QEZjz<¡P|hLc!Szެ!|qΰ=ɼ3P$i |~P>>}nAjG ^BKB@ؒCv<9p5z, ?V\{+2*RD הbI\YZeYzH`ʎ^)ExFt^%$G&F,p(@BjE-@Tk /Jxa;ula,_h Ve<{ 䂊 Ha,{k&x銠b@B&ZȰy}vb^AɕnĤ"̗֐#ɣ |xOoo sp04 =ϳXn[ĝl ׫ +B1'|\(~O @>8|84({ IE15(Š"aρQS:3"*d"P y Obө|F$E43 fH9mWUlfG-k5)Ýr~cR-a 6W #!B߆NHC >te*Td5H<zq^NE+=)S*ʔP(,>?b(䬼7`Y2ww;<醗ξf9`y0)Z|.N=Xq©v_krzGvMi] nҶ[<y-O\ a' m)GC6r!*Lc1ebڃ: "x, );y?[w@s]t(ȭĠA^Ƕ4ȉ5}6K1[aA1X<"ʼn=7JZ~8<ˈ\eHK3'Pz;.a|^OmU}Fu*;ʯw OՂW!%[[e [IU6:Z-NYxcEukʷ8\~?ϫwqkˠV3 _~97%|(<Hg!y=w_#ʑ'ԿimO[{m=!.?+~O TO"ݯmu!}{!R^^'lp{p"J. *ERۋ A N=nþN3 k3KH,Qvٸ9($TP|.ڝutIqTAC`4j(ɟRɶf\߀P;ڌU t]{DC0ƔO±`p0 "MkDƒБH/ fpaHXqL7`Jv H>PA.}A Oz'ok> !|0BO{*wͦ*4[RQ( 0c\q:WnPzb> UF7.'\㤯bOD „(+Dz6T(bDx @%\Qpᛢ/w(?S@&Դ |\eٖ/mS`<#-t"1 X- _zz^K,r)#y(er4Fa$(~L t_Sicp ÅT~L0B]|d|z"qQÅzQNY`Y…/!@2Z)k rb?%d䖣[|N=aѿVy77r{$Qy~|>m`:)*A ?ҭ9E%:+=ĮjQ+Ex>SuOYvk50㥁P;> 6fG[oGK笎^郟%baVC&OyOU`,|B|/=So";!X@_XSDᦳzTt_Iˇ#1wJ)[Imy {] &9d'ѝ}YH~;5Uw1Uu@8c[Crb>Ê2b?^@# K^wW*XTFFU81WcuQ]4,'0Çra_m0px[߾7hX^GtT}NV\/`wU}6>/QpĉRQ'jǮ~+(H|U>HUbN9oU?DX*RUT+a#|)Ra;Lη!ꏪZ1 7Q|sz!Rr^H_YX?7_"_xu9ˇés)5ϤiV:}H1}q Ʒe[ۚYܜs6i&b4AT}H=.+ 'HEJ- ~}˲͌O9%?)e!\*Kc&@^9g\`% (8/|#?^͗ܶvi{7b bmƈ1 1}:~9݀!``t!r,XyB}a l< > (~t? 6ߟ炄I2#xq{ag[S+' ?'g8Ed*l;+?/8}T= zOz|:kL@~'tQCCػ8}J%h(ؼnsT\>nj? 65&Κ6m{=w*blĘ w G ?/|t(6.G5X1R`:9ӟsw@Ez9׶џdހUQ׵);wq<_>n8RrQfӭwߍN<FZ{j!®?:܋̍tܩEt#ao{IEi#)(_ӱikBɋ\* = y <}B ޽kM_-,qb>~~rQiCw.C}?L_#O+ BN7:.(8#AB_WW 2ިʞ`McGvozR6ۭĥzW6W׫wmyFnՃ؊] |ty9>Q}=@ysunh:U<JBz9PLпtrUxpv=Ri墯SPP6w(T=:A8RCG~4GA{_ GkmiVh_ H2;+ ! e's!_4? r8a  fFCaW |W(C&DJN2zAdgl!\?/ECPu|?.i|gDPdv2Lފ.N Aw"zι/QqƁq실вjxǫ|!נNǯuh砬y d8D͌U!ryvr WCU6p||8xWA@%-_u ],|]+^֞VO1w"U]'3(u*9rⷧVs ?қu:"M}o}3{~8y-|c>Nbw߫ 5y"/ #Ώ\tO|"YɼUJ;uANE цiI 튓_?jyi"x+4'W^ /Uf'es*Rxf@N_!Zy9NCdz eC0xG1#R:T E>,X©6T4d14 N[) HA$([XUX*@~BF?_l#AP=W'}F^ g;C70(~'~@t!`8{<$k=ڏk:ܜ~wPk洫/ n2(}#_O \ŷC`DۯZ;7`U 3>?/"'e 7|tz9}k=5+'t=|1h >0Tޟɉ7CBg_]j/QrjfSί6/[G'fX~< ۯM>P=Y)t=)G[R|ɳ/Nr!Daσzk.S i)X[rPX){|rT4|g1Sic _/N]@TG˚CXĔ_*V#L|L?}|&Uq ` Sk5+'ylTuX}ǩϫuP,Ni]wo%dE"'l[ ?~ Jaun_z.Vbq x^aw<S/ǬOG\ HG˒@>hu=mHy3P_ n%O=%Bق"*pZ=jĞxV;޷>Y%]^?fB»C%ĜB˒#B>3UO,:ZϢPO_>{{Y޻ה.;ϔJ};'5JeR5\ CɷWq'su_7}bN|P9VK N|zR M g"]' ҙ(^bI<#l$t*R*a/,ԩ!'S1:\`G(դ!HO0W'`V:l#W/>#\Heü:dЭ$$zlĐD5#2bQ~>[t-nĄ4HTloZh׶L(dPuֹ/eOu't j6 ^|eoo{ q?@ʣB8 *D^џ<d2k#jDߝX|Ko_So}^A($M(.ӡ,("#Ęo⍋XӨS2 Q>n8gA)aM1/=I'aѾNH3Ĩwbد@FR5 NoM=)9G@ܡjÞ$څl/NiH) ףàq=vKB2? Z=SB5ng"!1VPSB M?ocN ~z5 1zF xg[;O>ּ_"/bF~l>nT8ȧAn^c/ 2TFsxJ@x"$d.0b+L+5TPUԯ#AƫS??f؟j6IPXg=|2/yn𶫖@nW7 >1_/1F[ <0S`'}ͮ-5 ;| %J?rr귯^Pt lR]6b \iЛ߇<  kaR46y13o|ٷ M|6g,B'Zt~%g/wznZNr~c,YmGH?!0ep\ xAМCཡoj_OHfP=5 é.➢xSEVW!mx4i"4t4I-5 H444P8 ˹ >1`c yĄa1+ Y 4tCF&4S \nh,*,m4Zٰ,OGt! aYD/$!Y`bt%M$~'i"$HYkD i$W?⻻`lU? ǒfCon$`!d\V#fk% em̻4PPTGQοCSم(5Y mx:.mQ:,Ljݾn%N t Jt~O'ܶ##/#TSW@:k).ĕOG hPrHAEPFhLCMJ 33u PJ0LP8p{@7 5Hǜjo_޵TE=Gp"!ڰg׻B0ߞpTJ_hwYP˜ڱW}(;q# 9mKՎ}_ܙ{8w@ԅr\0>w8$IA霕v<o99 _ Uit+oz4t# ܄uMJOj:xqu涌!B!2DI|9t &~ D"%8;NOZ)S=bUsi@x:4"6*v8ϴ7΂ptl̂zE= vOUDi>$<¦393ShwH7LzRIxU)ՖkUv`NYT~U&awt`_> Djei}ə)G]JdJe*3go DdfO,Nfp`| D>( ʑTt#nu')*<Pnzܰ'c~1+PO{ ~P m W,Gj7V!Cv Lz+ÑbO,tRjZzN0J5 ϩƢ8?iTH5_>Ĥe&G4O>RъTU_h OL ,B"QD+VpJ'FsVbT³kDMA+FjL3A1a|>W5~&50jJB5AXmx17rUD+jVv#k6pMwF3vǭp# A(,(T:^EG'7dkq:{p(>SB#AAK nQC4}6 <|`4"F΂~0֭V=Xj-?Sq~6{&'f}=TuK؍%ɼUz9eJbuڢ(NS|Լ4t$['t`w^E)2[kySjqvf((X+np˒Ը'y[*d`#YbW-+?~r&hs'jԂNuP Lm䪍oݟhI|M'.J*n%gϰ OE_ɞV;6zl=Ȗ&oe3%o^ǭA(ˡȼL}˽tВ!uM?a 1Ͱ 07+xa|efY|ʥz \ߝ"_Q!|v'VvVzRf&P1繓=v Dp'XgOgBD#>/C'@T 47-/x|0 Q Bڅ7(ˑjQPCx>^P}zgy۠8tejF3,rӮTC >~wasXTcAE_vB|A-&? W>x؂Aeԅ%K?g~AY/о9Dp+&)Z@':8Bj"W^Hn?6EZa~1M7,H]5cL p ɹ@+>)Sʓ~'Qt_P@+$Jnfpx h%cPQAjiE4BSY!={Iֱ')۩MZz_s h%@;R$(RBiB C#Ahî'%4_CXNBNg ٚ m^UAa^n8@Ow4+qė3 %|;ߚ/ `lbdxɇ̓-fyB}WC~aeMMkk\5f;DuL,[\\ PV} ^ߚ:az5?ݥ4. ;'uNޑJ V7$i Ie+v=9'*A򭜓;' ~S}&%'eaI srR|r:R''%!D%$p:L8UgP \n:!ß4N`Tˇ¨|hM%(pWv 1Gn (@4l W!8YI 2 f8N2$~k U˼J=_` HI 8M%_`(@*E˙(i 6ႂQBcI7!Tlr8 aўCBê=pThw`hL coMDq$i=h9 ^Mɶ_OyȲĉE+į&LPnT :ɛ:hLu"tA0@*{V&Ҟ=Ž۠<|C7M@_2Nƒ?nJfR= v <@ |$H QNK0(aPzAIY0-zƩ鷯wy}2w}, ;ξߦ4Lo wa0`tjaP4svr=àew<|_Ci.³P>n} nUyxVT%AК(w}S$h*|t+eCvWWB"ZRw$9Vh2'&/o".P8bR ?2uWyي;/,{URaL7 Y 伃a|acsds(Ng}>rRZz@H_`5?*o#WI/@mDvNdb4@J^ѭd&XAP()?Biz:愮Ynl=&#eNQ]$D1 Kku9mYcɝI? %Mʲ}7>ӢS'!pO,E؞>CT9>aI2'7E}.5/]G>HiSBL?nӺ7 )Nx[H7taXdBНk%m䀢kPN8]TQޖS}~1 ĸP=o;M` "-Fo’a~7}>FdUq&g؇΍˃ykq(n"^ޚ]k&S06+Hg+E .*:5eXp7?&(Ȳd&b/aΑӵ7]Ԥ4/_\[m,n%kGg_P<ޛyȨQ!'ImkW lSe)$ C誸)nuc \f׻5՝1T,|ϩ&_ E 1(Eǝ E8(Uǭ iGD 7^EːGTl;˔g˦+aUŕZ~I5׭>_m@/DlrX|~y9LfP-:jOvM1GqUH |&rL!Ad"xAts귯^ ˪!_@n [%9˲5L8JM`09mB7]jr=3MSίC3(*3˸LVeO f3hm1}=0BB9f<^gD:razź`X;/YaƬ3Y#]|5k@ɔW EQ1* _<׍Q(`Xf_5y3^uֹ2=([=+(b&^;p(λw` Tr/ *{~DnG2E4FjG]uNf|^>R2A8=Y^Bp'9,/n#iWx;~Ykgo}2>2\5/*pCl̀\كx5P}C&@[Gg  N"ÁUx2iVre,`dZ(Z{n^@~ѭ9uU Fnî%5#=wR;O}{SUL5"c]PxI?9f e72$ẗ"9{Z^3AϝN91i>_6 ZY:f}#$)Zb")WF>խ2in<:i{Ce D7|VDfRbd2犷,0 fw(auO&X\qA[LKyy1Q R\r,*ne "+o Pc&j:>5yu$8NpGugѭ, vuVDa<;o+2.ηlkrdڸ+mٌ4= jZ~8ՁꟋ`&P>x w;wy!^89MPSq_rӉV:ay' V sS|keD5ԏf qƦN@w G4݇'2u"| hu4]8ō P3[U' )/n;t%ZY*?6W['gAq[mmjx" OE_-ٵ㝶v&jk44cz( j4˒CJ#t]a1,|OW UhKs_ xɷ0'?w8'5HU5\J'5 ;[&q<fƷk¼<gܼW|w7r琿k/uK:;![~|e)=a/Wȇf9G†O>E?K^u/gqsodx}}~|mKl͞\|.̭^_n!ȏNfP=o~ @?u 8|~p 'ԭ> =]T̀w,/+$ߙ]s@aԏd Z߫E=Rݚu-x {΄ri5 oƽ>;fd9O*LuY+ _팖ZhS |øAC[jޝ{ګuyB=$0x!7NY0 ?h*CA,zy7HYEPbU +n0PVPxH!ogs:h TϿpc?3(jM\@ͨ\Ցg'`90?u&o_I B)M|&M*P'AaaJyֈ@$NY.A^<$UNB}Xj}ȕU{?Y8A$ ,S`9w`&>Ö?j.Ad`EwT*<ү[=?(_w;A(?Һnז7ӥ>?r?/,)z;y @$XT*ě3b"T*;{xDHE#1NH` cOU}K':#FI/Z812Tb4`&NIuU9a}:u쐤D=xE`,S9dDva|ꬤ?0KWhh*RI!HUitk<0Rfz{X7aёH7XinK)> 逸||8HGx#f)Ȍ~)<,vZ~|"NQݰ00g+ad`hV*$A,oӶP9KIS 0DX[uTA~Yi /PPVӵZy~:yk>gʘ 4j[(T<)WiZ9+(C\ӵ`cyG~GQ~EY>{/Q)OTI?XO>C Pf&9IƷLjOPHf9½:Jne0ʫx|LUbMFZ F-?3 <bjJXXոSuq^R9?1pc*u7Tcf˸?ɷHj?a::gd&aHד2$)Z>0Hx"I8 [>E5UaP (2TYݣ?P}ʰ)$j>w4cKr:0g s=EQ-aPQ 0.baP 1(!zB;V&@"??`4QLaQ +?n,F+1e&CML==x _&F[nd Thy'fIՎZj9i&r]B"TJcfZuN<*|"v9U; j̀]TՈzU A4QldYGiEמG!h#ӉL)M|&w"*_av-)ș4Q۟۩r/c=x[/(),T؊i6rLV~aBW9 /:kS69vs,G߈?@;S44AÏ7N@!ի4*ua&j7jruɒnZ_Gf^ ;@~3 Cv-{,F ?H}s.^`MT~j͟ԕUP (Vtjp>(+pgh'^FqUk 8d&? lJN0\#Nj,2ݖ]O-Ja3{D eX(lpz7C>& C%|wasL4a ̗ˉz%8dt>6a|k2D{}ky{Ƞ rŲť*qF|)&JEg{ ՅDf}d{` @Uѭn 34!7j\sl/qP]IeRLɑ=xN= i{ᵟ@w0ݲe~nT<4gfę`6 PD\ ;wlA >TCN;nƽC?w~/S?r f{a4TN_͎/|=pvn|nı禰|FWV۟۹ȧxކm諚~˦?@0,gY2E=#e+~9];X3 oQx?/8N|$ZaR,1[-J\-ot4_b +΍̋~xw9zOaC]Po^0P0┚}t+=0ص%872օonj1S 763dY2%xnPL:mdSΟc#-0e0<Fds#6tW{]MQ]wWyƚPEQB*wyryuM>M85ReW܉U<*95RiOӨ1~y=Oۮ~7"@q |GAd>M-OUy㽊Ta6o(_RAfP-ժ[Cmnej,| ߾6u qS*wk5ѹBYٗ޲^|䱺0ss1H$UO@-F (WKn$"m1xw~.!WxB"팵([iG e T4Lz+xq009a`׻:@ 7\PT OlqܻN~-K_ y>W~2eulX#wxrAQYo|iٯJ^RCo]C 0VI:@E _@2ȅH(ˋ]T vDx^9s5@>9&e=@@+=)P 9GC{Z0_-?-K_ | @?k@@G'vXfi.\yX)7KS;8#{r~c3j{o_ } >vExJwLGW5G 7CCuM Hi;sOިZn8RbPӇ;%Ɍ(>Md,szN*gly]ÜwF`x|?S"2Lp89ͮ}i ]I U=.'.JCHaTїj|^>|tH %LJaPn8; YkE\|bLY"L\Ch.B̓w6CE}]|`_@a. (C7Hv`0@oR4ԫN4r2R9GBH3B/bXojZ^n߾N^G0i1@j  H#BKVF{ @ xCNʲL˜/7 n~O*OTl=t.#PiT9I(*ZF꜓fPc׋յE.|+ :I7S󳇝{B!қ[g,ebI7SIxKO;n4'_TN8UY,E]Rмe79%I\TiCV7_ n `sa/&┣r귯^ H'Q2hcOnP衆aW}䓘%@a4 IDr4^F9j^^LT%r\O⢀~@M9ZӃ%8h84OvvM@ǵt#t7VgsOdyv"bCy[ _eujRIOsdqQ,HFP=:q>Qqw7..G_C_Ǡ;:{)pԍl oO>Ad#`Tw³|> GF" Pm|&_O|DE@Jx8|Ψ#Ag8?QAo2ɲd" L(H@`OY~e;ZtPZs{J~(=뇎e"Pb΍bA.97~uDfӫ7 / rz[IY^&}Ů:e==sgYH9{ApacR |[}UHM8XBrWg:Xbە1i912N o j?@yDSA3Ɇg)d`&|#xLqiT\ a@`_>R!9@5gHB)F<4r֙2^jnQTHP!+rݨ)2: %pypɫO&oԎ'myQ@M7Lz7pG&,XbPK(i#c,<ļ6A8]TQN$ms$ XtPǯ.oLw9R Bm1zC9?WG 4iU% 4\3|S {O AO(6$'i zX5S -0) H)/ ;`#@tR2f#|>?~srAK9y`N4cCe& {)ŗVy ᭰ bYt+9Ɨ0 ('D}Z0[a9Q*W4l穊ˡyzP !| }S|v`0{ɨ/+y'ayX#sz\}]C*K7po޷;\]v wz%|3WN|y#W3QU%C HCġ{Df0D$@l~ëR@l84A:a< h~CQv]ũlkpl'%BQjWNPbKiZv~Q?#1/-F/x q'|7?u hAwd,F;D3ϱS>n#D/@E1OY(@O9!Å 4[5pT1RuF#?F~o?cxKn(]rք[3frȿ,o{SD U7NY]a:>~ @VObϫcmjG.1ªKq]7{ Q^ʻyC`Eg6W5nZAX<θtk6v HMޑ@,LqR9HlXBB! ڰxɲi{LF=ltnht"SH'c:t(i8L9f\tέ6?5!~o#C|a0XR|=7.LH'q? M‡L@T @l\Cizb!N^WL'E;?#Jnx+>T'vq yE]$~@e);yO-0Q9m-tBst2sjj<7r~'3Ȼ6p^+ww>ãk?|AJgSwN{Kj'@VՅTڇ@ã* @P=}]w88!T[ㅈ08Vǿn83v lU-~*!ŽAF^k:K' T%La!F| ,U﷔:ꕘd/rx/p[)r@CBHmڳkǤ=UƢ ^%ND4Ss t6/ (iH оٚ !,,v@ ojzly-yˏoLΎC;¢>_P*M,^*E)o#W(ٹ@*&F2PE(HՂӭtwc/P:ȣ ?18ˆ9Rc4X9Ta'F969pXHXC?33' wӡs'ˠ`-#e36CΌ-iY4!ݹ|Ǐ*A, ^_}?V蝁^CڌFyDaK!}*pPO߹\(>YB3BB(!y@tHF1 !SCɖKQ!I U hJ| "߫e,sv2t"TmÒ40^GmɷC8'>o]|ipϤB~,@a"um:J]p8yxPdQ#a y}i 0t69+oM/ NzIx;9\(O 0Q7Å*L@rF#j1ԶC[;O.8_OJfR~TB4pl|^8h(-:%[Re ,~s;}"JPï7pBtBT[ s{`ԁc SdT#]m|Ο??C?96vћNmxZಛ/X-nxA֞yC:m<7r"U}pdYwU!~/eA/:4bͳFo'2\y~#A:iC7B^}NZRyOsSP'Z2b;Qpq7duuïCss?'u*᱇z:0;շE٪c?z.+v z%TV=auGW/9*w@}ͧtq?68۳xx`: 'hcNa}K'zӯswW?0 x#?^}a<ݰ>?nRPnml@,cJY US҆aƏ [[lx#y{qކz[3b=!8ȥ;>^OEhcSC,Yx=5 MDHo9"Osl]}4؁|O MRK\-{욜{yP<0uB 3.nXvz:<9/~z~]]xQP*MMoYcP>3`x8%*#~~I# M@ҭ]$n|VaMuy{zWOUx]}l|o't[ĥjoNrV_oUÛL/@hDڦjFćQ_N GQǓn!c1X2AH,A!neyj:suhdJ`ԬB_J Dp¨Q 7B]BACz@|}S Ӄxư!1//"Б 8!1=80"oQa싚F,K_ PQ@[+'}bT\XF Tg? H$$>BIP.#pLC+'AI8L  !0Ӏ[ּ7cl=x \@pAᷯ^Cp)]XMB s1,K{HA`@Sa,χS*(2w8P 9mK ܡǜ4%:0’@(u a93AU˜G t te#h.z R,nu_@pb"Ua2p (lh#ȣi2P eˡ@\6wYҲm#NˇJ@$iW.s|BcVa7*TK IXӨS:[jOB&hpO] T}Ut`NG> ϋab"P0C^Y#?o*,cG@Յ&>l4y&BZΗd`Zޘ$Ɵy3SΟ@iwǨV¾BqgOҭnPc"}ڄDwZCCP]PcTGPc*l ϲOv#1]u1 z۟9ՅzW\cDv:v^_Ư?B=q4)t,'Vx%"G+hT{3dBN?ҷfגQܙHe'G*KcImv: hh V#x?z.u |TO':"{[#ɷ(ŧ|^>]Iu'gaR퀽O: Cn J?c4fj(x'W Œt;X߳9 ^o5mU7S`5ag\iЛ߃OvbC7vc5!UX㮆~ՆȜ<5>L,cP1Q.DN 1'BpuZ]*^IM7E_^}Ӊ/֮)h?C1T\RY`^}Q^Rf  (:/f(U˧;|@S&fN;OTD>C{<ڳkŷ~| Fʝw Щq}*?ŽG ׄ,?PCJ_SƞZˑPeD"d4s‹P؁D>(HBV%F>0T}WOuGBģ0JѭtR2웜y.xڰi[yؙ4Q dO~&vȿ_y}^C3 $ sܡVJ^/=.:A밖 KdGP _9Gs/(5dBw$p`Bܣ&/N|/$ x5Ux>^ YTI+V/rp-tt3’{Hۜ9> %'}` 7& 3ϧ%~my*s/n% |Y{頽˪X|¢gq ,?~rk߫}~| ~؆G\θ/nN} w_Jon=LǟK1K!&fzab Xvm/|68;N{9x{ ol(]{ ®~ʟmxkB"Wz6on-}lznl|8T}WI\%.z͈eND Mxm|d(~{%; (,-zH -KGY?U )r[aFox'$Cg_IA"WO !^ tg/hԕ>cnEO~xdRC5~*Ҫ*MˇO <^?oŇOlʇWrA!ھjo̔^됡1mr]}"r=n+_,du.УIS^$(i[ {`( aq?BiHD;s0 )6PN fQǿnP9_wUQ'AJ~?,dN''"S*0EiB50 Ċ,U$Ruk4o*x 29{{Y3 Eh1֊c5OvmV0(ru,ʌ#(㟆BAlWtϐ?ş5|J-XcѨo{ 7wK:;4H|XuHpk @0RZkB| zƜ@_׬Z;gR?ޡ?C-暇,Yݍi^R`^n,!`Ǽ%[ 6ȴqIהW5&AS}^>Wn%{gy%bz*Hu1XvBgD3]O8K%xc| 6G+ Lt:HWl8)<:1ׯ,|ɾ ؕf@L eHC S&@^ k4उ-9Gr$$, ;)C{;ɶũx߾NҔll*$Swm|&'B3u,OMCmzrc |nV*"Ai[i70Z]HsA4 4 2!(R=[4 Ch Ee#(Q;/4 Jω2b"AF~4_Pi.Bƒ_/2F,/AQ+|&4f&@VIUCzkD>G&%9"!LFv5PrSLY4lT~Ge>#'VykԘ ~Aʫ**+K=d2`>?/RE]c$5U]eĤCUjbyRˇ#7UTnuFDRD x+77፫4i*^OR)*׬Fˇ#qt<833uz Mp$@X>!]( Uo ji8|ܙtuÁD` DJk^"A4vIRB m=*0tՙ1MLɇ%9-MyM <}]랁33sҮ 62W6Cݻ5d">xUǿn0yHf>?s%߿׼r2Uh]h+FmEK© kd!u]DNٽi?w=on!rW1y[ۭha~d,çV8$BizBz!D>FHL⯇dXsP+eN@pE玄bP4繓=vo%1g"8 M~/0qc[cH:0V4=-#m\5O}R`6AS PQ! O{yгBxwdբs]}C#Ӄ0zs֗ŋUQ}?ޭC:&QJx׾ EvM(ϐ/A(h/$MSQԟä:VG9j97b"T28/" Lap6m aMbV_jG9h%v o*j4HP4񙴽n%3kfػ:{j濙X"ަdV6N$(Ry5~oթKAq5;NC  |vK+mG|_7`g1*镐!0f mz>2VH6Zj$^)jc*.Tj\o%X|=|v3B>T1 Vږ>}5D3Qt)YT S6Mu_7&I$X(gR0M6ykU)+Lϡ ]W]6%H0zBt-:C X$fF >149Iab4)Sc:_uSK5զ邔U:Uu)Fh2d aJ` _A%gBL⟷#A2B3V #1*v`[M5/k"^o_ODQbߣV J R&fŒ@%KHra2#ak5au]nz77B uK(?X\8)B Pr~&"Νd`h:iV-@+)GbyY3@] d"%[BSL 뷯^ 46iϤyW s) 0d8,"B%DJ '& 2 "@&SSgZ->!~yʷkJ]XK8ٵ=t0~hY2u'6g(K-fyB}+˷7k࠼0Z6Ę=c~(976/jоٚ !gBvɼ/]GeQi> NHT*QjJmͲ\ t|ǏV`غ OmOvr_RS5?]iTj#冏R]Ƕ0* kpPA :[S'̃ȱP*Dwb/IhtS5܆^%^ Q *;m蒅]o_}$Ymdg8+cYJI,"X@NN.j>uE\-UQM?65\ֺ o浏#pu L`yp$LQ%eHȠ[ݜ> [Sݢ N%[_ⷯ^ HgcP,\~ǝ Eu(Q[ALg8rLRJ~0RN_&K'f"0[ηVSPǯWz4V@rw_f _w~.!,Ƭ`7DÁ.zhF Cu} R2 oGj^¤GG_{͌:S H&S o+2E-_F,N:u" ( StF6E>[Z}9ҡaT C~}P}Z}k?̂Z3h1&V'^A)i (uϤk1O"HH:e[q'|uyin6ե\q}~D)LE5gd88F!}u(EKj'[ޕnE&3ZR9?}Ow%G3V KA:Uɷ"Z|xx jÔ>5^ ᧠_3^.lYyx騚b#Fk0 PԌ2Noa/"254}~-^f:;!,Q#j(,/"Qʢ$|^>}'%6Q&܊yBݾl5BI{G=tPm:J6߾> UK z''& @p3PuuF=t~:$?4ʊxIL(E҇>@=(E(PwjdtkĴG9&Rt6<M|&S/ᬤ܇ٵ ={njp?sLI:E7UQmj seM ^8'e2ܨWS˟y4 MBSXS"Dx ^V>>+y#W-L}*蕿>g*rAj7|b' A–lŮ;qW>ENDJe#S5:򱷤Ϲh ꍊJոg鲍k:dة`HT)Cӂ"hb%xգ߄jqo72O@'29T7Ea> ضصYHuU{D6u`9b`DR]ǟlqj˱ m5tj +Uu!UsWnhճUyxjvCG͛ު4l7,/I'By"Ӱ-TD69ck.?A6m Y@F^ g;Ct_7/w4|oI{/zɃ}^[Z~)3p.$ {=@rLKO%cΆ;/ZW3 7;#h,ֶvctǕiSn60];vW>NS]󴵩Ž?d z 2߿<±9 ]*A 2_sYgC˦ɷwxN6ݨupTx-6R{*:"yKBe:ɷyu j6Ý'{j{W|L?ߊDm96ET.=T8h̰vS7jH!RCiMP! 肥f¦05 ]Uά5y|܉Ha<(#n9!BwÌ ׉UMosKs~~/AKu(J% sC,l+g^[~WK!O)^<4WfC#>=3Y!WN=B7}›ă0X w1ϛ}&_n,Np'7fדCrx{ҋ?P,[7 C┣e9-RwXsrd`E^v"ɀ_egT1ʌ{L ?Tv$SY @WfLԽzP#~O<`ҳVR)ێ6>x=mrw0'w1)>J`A9 Ȼ@AzjOuy)_]#oy̓}ORYe8b9?z]w՟}>ʤ ;XmX.@H$}yηYɼSmTO} TtDqyW[3VRso4v5oZFU(s?KG/}oy?w~̌ã ;('L̷+afoi1 ѓu1wP.0=?Zt a ypl#e54>𺋓V"5p[oD!8՟%ΉA|beKb^;ߚ/uaŧ.c_ˏf].@`Z!k* p~ !U !7B6wuCHN3CjN;\ q‹XW^_p#:뤳ŹM4lyޟ/Ւ''T?ro16_7>r#oޗ_ ?@&0}~nSF_X,n0**$"X66CK_Cd,*<[net?lHsue"D'Q+v{ey-շeïr16h L9?_f_ K{ɤ[jwܟRCrThC,ܔ&ίh,\9›R [vѭ$$Vȁ(4qî$P4 Uh,~iS,I[L*1(x7bR֗@#ZG`kw-Բĉ ao:M)0o?}A0]=̼w^ߪOϗ/68s\~rc λ חLX!) C<̣.>Lyj}# }$x >$@ C3݈!îF!]O9T തk b(@OV7; %] 3"a+ ߯KK)`7p@E!ZsAx ]; Qxd" w3 3sw,qݙSe>>/e|<>\y]{!h;1<(,Յ'/E I>#X2<@9Xfi[||@D5aKs:!P`7LD!|?Rp2Qo@&o!AGżVQabA 4 3G=;EK[6A49lw;L(ɋ ?] uNNSW#*NL|Ҽ1P~i*8nա?BY)G7Yѻ q٦ ~o;z`, Eo~ RNP`d3 .X y_щ8_h2D5xǵoPjϼ *~iCE֯R JfR~nzj(j4?OHi|MC$<3jjVco_xHp%)U1bcNǶ~nxlR4S@|9ir+=5 $ .P:CV_Ysρ[v+:wӒ } 1fW%@k|sRaxDT9#MKitsRhɸ5^@jnl/:'ySXDN"crE (EOqZa9)H\[P 9'݋,5\:$+tNu-W^b ~\fs v%kGb@/j@2 RY@$_Q$.B\ pJ d$*n S);[.Id IsX KnovnЬ9)@عc˶giz= v܌{߇|i~}I?ni<.~nM>/4 TL^{2 ")tÙmMr+rTu}ɸ]TVr(+j79C,xES_^i0)rLa{M-'#.\iW{2 l o[ qïz2FDN^Cpܲv >S]~3-ᘗ[jK{ M]7Aaj{PK͈WDGuvNbMHIߧ~ :$80/7|Ծ6;)Y8A$ֆ|!e d_4OՈPg%^߷׈ĩa <~/A%"kgƨT,XECH4ͻ硨ib)b^k6 0?Ddw&Cid lʶ;T[MCd טCkF F㉜k*}^C3fSX9m+L Z~y*dhHUJ@b{cJͮkBoFNJ봚E5|^>> Jb G TQ*ep B&RW@TOf_ðkhjF5X2a5FAjpxKBJ 22"ǰ9)'`wV&-H`(d4̈7؋Ȫl:.`rs¬V@w(%gL gjw-^=*^V!n|cH1JcKr(Zi׊?PZffN\(5L5/>'eKy;~,e|y9 A:\_0˩/s%,81$u'$3҃;*m0~J!4Q0`{_cAW]Y T ɩҵ7CSSV LabH#e`ִk=tk,_R2.4? ЀQÙJ& M|&mn+{ E Aa/o;0݄r^xՑfKUhD ]'JȄaByZ81CN!2I'XOaм ]C>n8jJ9ʫMw#urizpti-35D ,7a mDKɔW ő?ߵm闍A%|ΝiЛ?Ų 46ɛ)kjZfG<(XG?\n95DiX#6Ys*Oc7: "wdd76".y+ 25awBx{S;]@,U_M3eˇ K>HICi3i| R%05niVʷ$,V*4 %Cl>,xA@r_>nw"$Vt\~YFy=/.exq: Q"d˧ah.)Dy+ -Er5YmnyYYx>޳9Rs2R}ejx |ɑ"JrNi6E ׳% /6zmB9;RďO[8,@UNSuX(AA\pC wc/!307=j14 P HPo(EG(j߾Nަ R@E|9/%M 'wm.}Av]hY%N^ÀqoQMyr ,u1ZyEZ~ާϗo[ (jbg @AiJ| ]TGZA6 |zbExaz2 Ӡyty:S8qP wDݣ, 8K.E8} ~P ޅCĽ !m 75z`6m.Dޅ=0`?rԐQ<ɔAA3o9~ڵ] nҶ[<ᖵ`o:Su:S4&HTƗ0SSDVn؋ĵaSy4sג7 g1 ? 倩> :y3>%\E瀰Gw:}W%FV9I%SWdÑ˯PCV- Ffao.DYn$ډLGПTmlMsvt ]7d1'y{*“eoo執V?o%Š@P擬ցmUl?#Dd;,XE>]5tգ ? $@坒a 4oCգ/q,䠸UNFP\觾=Bmo{*ʉd(.bSp)~ZL1%s r)GF _2g`wDŽ9txӎ SAyWgpU Y MmG_p \p3=oAG9 b g0 G–jص|ni2,iYADUA(^aPP! _d+2 rqgS|=E&4 3s:̒ӷymGr(,ʍs~Qi;}>e2L.UJ"wYк.W<CX'l 7wY2%7rU 5F޷ \4Fbpy j7[lVBQn<ŗ6(1f̖1$H&aQ ؓ>!'IUmb?ġzZ~F$Tl7.Rp?/9.==x _^v@(-}dހd{' FCzGMj DBܫO pŕO%2B7t*vg[Er~Dmu: miF8r:he2tb] ]'. ?N|zz~~kLTF^<H3 VIԭ:% =n_xHwpN9t u ,tFDLg>3{OS?sDKFLK1²ld͋=yޫyoV?;3^Of[:J܃gr2B9K=K2W9GU|2Od c$KzsQar=PIRe#,V>-̰Z} zׯ^!@#ך>X&2*l…t,,E.,QwaidA++*]/$Zy&d|vd sn BD@2vKPa)PRyPᦵ~}e5}^cmw'D~斾IE-6[ZC6yL2?7ӯ&r><'%I C kgVL;8q4C3OU ?wO 8o[яVw~ޔj?~e܏|}cC*7y2M?lC gþ.Grlw4?R/iT#L[Ww>GVM{οNovn5^鷬OdL#ˤ8d`tAߑqܑ1ݎ\[f"t^ |DT 35ownQ,@rױI[kiV ];ٹ6M]:M?-?ӟN&>ڴiƦw/mNes"DY.$$ۉ&._BLE-LnNd_?-AU /<8C!%t%$($Ed*8soͯ*wdu^V;P_of=F3 #?}C0O!mz4)Ǧ3/fx!17s-ؕ!z_PD}/ؿVQs~Ծ^3goj;p{.(a&)R @B@Ҵgt4g=q.zirGvY _ݝ壩Ԛپ8GSed8h>we< Gm\&^/} v6/NO.Wݯl{7XH-}5i }~R_quaĮ2 +s=mՅ㘅&s~ Vׁ?puZøO蘅ڊm7*j⇱w?ߐZ.<ڵ,e4p]b C.8I I q?,KiZf'$1:ǥ%GJB)5"Z}*8Bqjd7SWFu*}<̶!2q4u~.+{BID.p:!!It{9|lF֣6SP}"GHҶe$)a4Ba8߆&׉_ks8 K[[a5KbaPi- U!ÕQla]h1|^bKwmvj ?yXjS-Th[p'4?qΞJfd9 v:ğkWq-HgӀ/< N]:i~]=[A;Ozku:_ ai8XhniȤ=Xbد4- .q+,g{jQ?`1ni`"T{)$ ǀ>UQvzҬt}Pf4|:?x& At/GxNm#ٙU~65}l/èK8} oA/A~).a(a  ,u\7[0QSĵ2(cY./E%IQToȢqHl/%I1F)lGOK*.%I6cӹs!Z9y+t%IAʤIRBsI ,M˾}q+[D10N$D8dR|"Gqǯ4Q=ϯΟSg }f>w|T*cNqU޸ד>Rz;hCtؗ^O^Sھ9MMA'痈Hp+ ?tcCLsUKO9:`*n+sz/@?<~(-x^Nn%::6eWa A+`!DS0 ^)Tu\ QBhV }^o.*(.mC2 [hÊ(2Jfd{eГCy-'n.CT/`cʲ 9~ IٯlN/;K-$f0rנ#j) 2\C1xAJ1.3 `V!;RӯS%uoo%xp,/BJE--t̩Y}&$iJ:^\%eE-/B uBҋE L;̩B5}es9/q h}_g˧0ڭ4so-E,RBEWdkF$0 (kBwtZ5hYZLC-qNw٘ǀH߂ <,0ea·lhoA>M!㱋W%̳y):~ T4@.ﲹ ,25)-@JPz=c!/}ұO&耔{)dDlL7\nҖB+waݺ}}CC@=g9wwV&oP h'_fgF?߿ԔthM_J2dg#[ y"y)_8@RqthN/K(Jsޟe,˅&|rzaϑy N@˸~hؓ2/i&;,(#0im`$-K'~@ʄً_\rDϞ|d't:U̙tq}",(R#I`~|z5?XfcE k(2,2a[pIN?@kkYpI ?@5% 9>eq)K' Vnlag ,Xpk],"EF');^,!/ /fC*Q2:y)ILsH'xa@2D(b+RQHYR)&: $7: wG7 KciE?"1Hie$<1 5Lqcu' B ЈMRLU SǣTo;Nڗ8}gbFaewkٿ/}jM_J;MFT"q4Zh~Zojn{.Du%qV >eCWB^?wO1Ki9Rp$-NqBVL7akjƹxJ`TzA,:\WYfxkBSԞ7iܿ{qM?JMq_6=,a=j=7bBȋ'\wv s_1@%EƉKGrk;];\^3[Tk?67R+!ˑ~95<#uBY>q;|E[+SwxOR>{nNG1ɫb+6EǛ H1+`k7 J"@|%/ * ÀYL}{i >~@6!M_܃Hmo2I?J}D [h]]z2VÖp($,[(L̢[#z ϡZb|)'?? )de,鯵e(,evQHHj$Bj_Bs/u4sgށ/FL--:ZK~:eéE.(:sV{%,4e|ZbWg@\ӖG*Q )'?>Zˆ{.ysD&~FuO6ڒ>YR:ך k>f9!t0B P.HZtQ D%Y! QF;@yf;%sY JاBLj!eiZf/-Df)j$Ӗp,#O8k@ kڰH%a@ -g_o}Yڪ3W - gaX50P?OQ/%!|Tap]BPHarP Tv`)PCh8@1Ƥ4# I+; T{-g@Kj[vBKE4Hl"sz -a)-CJ2{g2~>c|$J*}ҝ?|N/T~ԭa?3-򚾲9TD?>dOBQC>B`(+vxzOQ+"Y:} oAXN*Q &$dҴ·`vw?C\ j~Ύ,YBJvv(ˤt2oȢwvd12Y+i Y]J\Rl,E$-`*NN`=ۘDWx9&,1CQ9ȐWN}X*M y`&q|)4ʳ;ub;SX&۱#Lt.}ϴTvpjS-45x~4bMӊhT~>~%Rx9ӟc>y`Gߚ~ ㊢5>ѫCt^g.ݘev>uf@1QHCK 蜬԰ʯp$==M_\ҫG1-8Àx>M_܋9!>~ƂJ6dec'v>N[^eWMtgG{C;gzA_B'шDӟln(yd0Rͨ</uAjBmg[G5;;[S*dJ"ս`.yф9H6*ZTt eiYk}Mz'ZqA,aɘCrbi@xhH32:ɷ#!8H-lmJKo-Kg^RBmW"q2giZ;\z2 &$g2^Y4Vx>=*BgoL6wd?;שC8Mn릑ކj?u>껽>G }Q3=/s!1Vcjo}Rye}pȾ <7RNôVȫ?8훐gMmﰍZ=ZF.}[/iZj_}9͸:5ހ8o<+f;;WV7gvPAz_\ u8",#y]wvmW vaxIL+Ӽ ˰#ԟ;o4W;vF8 o"/a5'ehUVA:0p=br/\egk5ܼBd&ܵ?H [sQWTۻ˽Elhv|%~N^{7U+,?:kVI76US79X~W?ڗ~~E cI^rD=ȓep],ч(*ڲ_Bq6/a*nraE2@V!SDYoiJY{|d>Υ,_g9eK8&1AٖR N][ٶaY*-!aEdz'zeh!'] K׀iΒ3!niȐqm|谚Ǒ/eٷWP}ݔl7pٝ&pYt\F?/# ?hjRmyjgS+; o"/UeC$~C<ײ˴XV(u/ƭ$^nv}kvoX nqz;aRLn~*8N᷑׭R`WܕAs֨ҟ67ɼO2eQ|<'|^votgF4K!~#_$npQ# ʂ7o|v5{Cwnx삆_]jYxz[2eGR+[(N,$03 o`NCpXLNHC᷉M[ S|*دPpKj70~T+iFl4^e޶}Mct$UsL>PIDxm\q@+~ſ!~]J/nm ,\~i~= CX@2Y~= 5F_qR]=Yv4H?l37q8'4ʉf?b]zwN[XzY"C^Z@*}8b.2f\"4_Op^3XL`/a[ߐE"uqxu{`-^/P0}2Q?MtyF~7pa\]ķ8?daKqLKq̱ G:,=XRJ`KtZNE?Wn}C=F 񶛞6^LSѼxr!ˤ&r"lbJ#k#D+?g+Co5 ͉,6ev%,%I vLk4͎G\UB,[O +sHLP)ST_t!wݗl}֔rW5u4:f!c_ yg0y4ˆsӨ?4%Jh2KM_.々E [`Js9|waʅ׏[pނpa1Ņ+ JZhgDŽ;!,P[@dvw͞__ rgO03$VoobPM?糶:CnP؏3pf{H/+!s\y 1!W)Dίj鮘3Odǎ g+Ҵ |&>n&^wLd S ?d:&G.lLW YD۶tǻ9Wj*䙪J>#7No﫞уZ8v\K-׿sR?5foj7D^|l9Ȍ;(+l2eϕVxo/ 0?}=MyQN8Ч}9lKvK S7~7ђm5{ʏށj7]@5WO~Ǩ>W8ٿCiqϛ~G>n+a7ӈMsO|PyoW]gk=7+}{Smw?T]5U_|d ._C}F#vBϸ[Okbfq{7e5)X(<~u9pc~mhۑizɨwZ$s@ Ca$ps8Q/@0 ʼnZ?Xl:Ky9v3-EueMYZVyE=8Nϳ(cXN) OJ@"L? ߏ&sѥm`,Jӯ&}}r+R5}2G8{Xc&,J8F܃WZ=$ I/у[ġ0j15ϣr?5Wx BZ8+z/9#5&Լ?G:&=}Ck=͏Bm'~M`[qg$p"Ɵq"d3 B_܊ w܂+u`@K'C?^!_: a>H8R{U;xo-)dzxϾ9[g`)NHoᵊ8@QBA<7$!P:[!SG>C|k>QNmo;^;<>^aH5)pV-`,?&b!IMhbbC.2|Leۧ5S3Ӓk=`fpm੿i<7ɢ B6` KjVbmdp]esʅD.(ɐ(|}YԲ7Qs/ې2agq&6oL--:Z>= yaY*MB.R~es L2@,t: 8yiT78\\봺eF_c 7ޯbHC](v%SI^^y-qu@h2+Pf4^Ұ'>r|C|-\@_~17f/r/tTяw~R4 BMW1Ejk/h 3IˍHr:焔JR2 Tq^8,%h]M[gt!FQ]`U(exÈq:3O9zU5F8\2#GQ~(B#…O[mVtD^%\#u)ˤSCLpGvZ[S $~-d9;SQI SwvS'0toH5?U~a e 2ONrN.ޛFzNGє3MmU}aHLQk>F2P;/x|c}#>?P+aDy!@rbk2waҴ ,~o/e0rSsѼ/o$d?N56ΟPGMrs!L49(!Pn¤>?O+r\Ϲ&^6eP.B6I o2eOB&2?<<- Xv4 zO8KQ Q)SK35uwvPtiB@4 HgS9:mڇ0d]@$! z|p?YZWևڽKVG^S7ϙZ//ʠ-Ŋ^f;ʅHD(r|5^GP!Dq$5ⅹ8lA rQĎ S%1aQC;SwL8j}C,0ZE2Oq^bz(q2ؚ,yX !ɖ?daz Z|1MUd_ Jv*!8䑩00 A*ha=^Lgm䖻ްn,o/Pe􋫜$7 "(кlͨmOC5}+P >/cBf'u*2QAdbx"CYrMJۇehX48e D~$CNq DMwq5f~xx >olJu7^w4dD~/YdaZZc?}"^C*Rꗙ\ؤyWu-ܻ;c׻eqߝԱ_?~#筹=lD{Ub)E@&0{01q|ԋah&ٍ6EKWqma0_"+)~PFIM?-IJ{h\Ð9>Mi܍"t-9gv/qE]{X`W@sn7;qs|/L}fx<ߢpfIğ֤#|Jݼjk9oy{zN@8=/ Xk@ QtŧWN'~ێq+H?Z`=:3p+eS0it@:w2T%/nzr~Xzt/>Yt@J )9J`YNB\˨ ;o(G@P}$y)%tkuhlckǑ6|ɤi@-r<5{u&eTEp@D'ʅfKX8j\F4Jf<ΎB/$ QV6QHD*"pu{/\@X7a/"Kjdp?~O q}f }}MY IF '+_;Dž*#q?Flqi,d܎ic1#9 oaY*rp]%-bp2JDW3q npeh‹fzĸz K# DKni؊hpe|m 'l)իUIW6zؖBʷ~PlfTlSL7qKE$qIV+fR jW:d'-ujTYΧw>IutZ R|%,qJiZuj(/b4 H\2~S=~?As=#S-80vv&v,cr L<ђ;rKFT]9qT}3YRM4pd84ߕmӲEIп=@? )&G HHaLQUw/0zG.DѰE>GI˝r(RO*#>1" U?Yi"MsscRC6r/,TY* %"B5}2Q2Um}7~ڼEBjGhS|nYIn/,"lgxd0( R2# \X?e`_NjآTipLM=ε"dpK)mWi KM_ B4rDQKΙ^)-셳kN?W &x8} oAX*r+BG)Z_٠_cAد4-Ւٗa'&+'8DYҒȌG EjxTPz> N/vUy,鍩IiY8{su}Σ-N~cphт" YFF:7@p:z: ?{7Z*xbèRG'[g&#.H^@ u*C,m3D.e"S֏ly ,|Q?DZ7WZ}Cui{y_W~eȱ7O,3bWѫC:;ԾQ'RĎ0&Z\ ;~f dOBu%3͎oЊNj{ ^Kv,YNaY!$L!Ma ˩S }B5ov#Uf/Wߋi[ yfC}y#egOSUsg+Sre!Ղg ,[U{RP3oQG;?G}*jf/(e Y.l~_D'E*BBB=ّH̬ RQ"LC?2n="T}Rz7H4>x^_mF(8;lukm/K[iE,QYC*JĢR!-C*箸yopnN}[P'ٯl<,X2{RC YOޡ 2IJ3S~,ԛ:,;+` +sMB}79{uPYqIRLRQDWUhZS/ߧ_놇]v;+Sǣ6tY_Yt@CU-et`U84-B;B\#ute^9{2JR.5!n#":N&N›KA5\ ُ=wj4$^&j`f0>C" ͙W^rx!ڍ)'?އ(3(x!MrQ9kTP+5@9F3;Ah̬]їY% uQj:F&pBjEj9YHr ΛMӯ+[qs55mLMxNNM  y"/a1|e& d,DHl@Lrs8Q\SeD# @ *g)Cv=|>=:_Av1vg}aH@20N{{rL-;do:wêr>iL-߿ޱr;T:-W@ B)}zsh@1Bhp"8EctZ"#DVk84eN f$/鑡cs?]lc0njd7Ɏ r-Cv#Sw0?skK 5?HSνd1)ؿPCva75|`*E-{[NLa~kp-,=2,"!s#.я % ;PAӟ,Ƨϋ.u5b̑A,,2GV([C}nH5'wjM?|lBjvИXF,3=bhd 3+.䉜_b::rAO;=&s#'2 ?ؼX~7`f$qD"IS;5&:LoG$F%ڜ/9 Yة%'{d^XSJ_ }vStT-DmEhd~BF\d]ϥ%RjYJE AVؾEjpޒz{Ђ-Nlh=d}`ӷ|V,+MOM );ןDB%@In߽Mxj/m-h^ZRH~ԝEuUGWƼv|C9Nn~YzjWܲRF3CNdR׏ܑ~l S߿ijV~cBKK$vh] wv&9ԧVxokN}AI/:$vm8d^ Ycw~I3N~oy=d=>x/?W}yy玢/^~Frħ*/ y##nY~3A>n[q;~Ohǿp3qv?0{+墙|_.E??7T[j78q'h{6L׍Lw;ͤ6NVRc//Vg8ϢFJ-w FIv<D·/sfe8tD 9f p tq ܊I5fQr$~3{>R&ht;s˲X4^?j,GY&T\ʠ!ZkGUs>ZH<5}2:?W$Ѯv57꘻.^@6&jy(xZ!O|Er'g\}GV$ؿ4-鸍ImvYA? ߑ,7%gm&+%-7 bMkNiRswi69->5bs̻6Ͷ_@ci% g/:4XG=u[2jy8j߮VxZvqػGmC g*)R˪a7ٯl(oiZ:@E 1lN9d0Rƕ OCwʙsf-6U,&U>wߜro(cj,xG9,'}lj/LҔ~akʤ)cʅK}3gm2RãIg\wsSc+{td 5Q9{e}AXtgzᳶ o8ӷJn=Lzc asĵLH=cKg2vF4ΖjMr꿟9iNeyh:yXWhMYnbiڋvFF^JV^K6~jYWk!/5qG)ˣeD>Gַ <^m8:BXG8磔CrbE]xz?2?r,/^~_9BQD4Qu樁JX=.:Qs_Xz.:Qc7}쮔))&W( (DSh}<׶p+ h+],=8s ,+Mxzpc K7{{u̿TGEE B=8q@}IQǑG0=V8daуpH;V~S.Cq; ]|db~q=" r> !&G\+!k B%K[[;ZKܳWmv?!9~Bi;A'ZiC%Bj91}3ӯ&Ru q嚥(2< IFYƗa0ph:2 ~d)ٳ?,;d+,Ed%"kY_ka9^- iT>nS߿y9Fl6bܣUD#7?Mج飝-pZ=9?e+,Ed%b랕O'c g¢5L" }q?@Qp[5Q$2_9vqսpu">g]8wf,+d taX֖e =ْ-,Yr$,?f9%FPVBr<) 8zpL4-Ye;G;e)_6E^HXWS7Gh܅x a߄qz*^whL" = |l >wآDQK)[ek-a3GNRz _O뎩h)xhD2x>HI+^{aKJCԴrJwKj~õGnjW7_%l#0S+[(l*i[J0njqdr,"0&24#XJxTG`ʰH6o`zE130hG#O;X ܍Z ? l 0?B"ZX8+M`_6HOLq? ۙq= t܏ o5SyGJWךKF5䷸ 28 G,i]/ص۳q< "M;!q85]udd_%wȫS4.%IbhARKW6SE1֨,N,ةY8uGeqHc8@1Q,q?m?ߖ&;nf@U6qlHo2.bwZ^bGǎ>~eqbGRj{b乩[@/Y3y`HB^OZw1˅ Hy$5[S 0F-" \s0 %ע?[r86QRPaA?x޽`Wyb$62<o&ُ]څ"[JohA@-ֻ2P.j\qUj6%[/~SN_\<1Đ ?TcX9~o/4( -P'weE+ 9$(ՀW2#BuI^ QEbDj <`AE!9(RߌSAae0%. ZNesAXBQ|O BRbcm!Kʤ- oLfRԎ?V]@{w;g8bkyWoC!O"k=gJ7 c Kng/ƭ ]DNaq0&|W)ݰҭne7emVi|CsgJ7,t89)4}%YJm!HJse;Wy0jZdzV;)j_qӃpo/?jW/_Mߝ}p/.JX}XƧcc›,q\dً+B ?NH1.ұ?!s@J-'4vO9wAs 5Ƥ;^6~ykF@M>/'fzl@M>o1eBKGB-iȸ%0Apq+&'uf2G|VTǛpiٍɜs9w.^z8氳0oȢ'C#p}j}{ij[Ѫ~piيɜpڅ|ؒ>8[jٖDΟG o!HV72'e~ʆ'sɲ|/u5TqCI@q` Uil?&kX~WN0Ֆ=x+&ˉ˲]ul|v2";lnaSB^N盧Hq9}0e9XU7f.Zb|r"+;-| s`W׬dJ@m}C\MHsŢq!4>'+1iU!+&rg"զM4+לU=杼uwMc y"D/f҄q=(e4@x"0L@9b*ؽ7;Z`"kDM5osK &M2NsTnH>gU,gj/ )YWk=ͮ‚Ni>iA=pM#-0V]'rӄ58: ݣZ{]N'$^[A\/Pdt3} rD9 E L4BpR |:aXj_7>ۓy::jC q2hn}/wbt́s` ;Gaޮs4;/Nb:MMg1B.(=o9FY3 EZ͒;^Z|ʝ?9f\XvWh֕nX#79AG\43=δ}O@$€9jֳȒ.oiLq T#H}G7m Ծ}@Y3KשՇ1!g_ dVV8J`Nŀl_ ;ǁHCy3 dyY,Ҳ4-k{e dr,GrR2_Φ2Y~*1Mo^5-[L ?eз%R\B;;I5I)4'kċ5^^iWXoȲ+(٧{M? eº֐9ؽoqha'Pez'Y8}/RزP\^ݎ jm_fbSdϨ8_jyUYx/ yzKw-? NiϢrm#^JǗdv#[ۜ7mOߙkQq>MSAw{!O%4@K a+%,qzp* !b r  hQ.^tdY)Tg-,!QJ:jx'E`mVBp>4Ԍ~1,e>yXM'YZEԶCݍZjeIH;]! Iug&48\U3(7}fgi׌p?CGUs{Ŀ4Θ;x/zϴ/KRWgDKEg#`9ě\+?|x^˵3v9_m 9pn͇ǵ.>k!m}׵dyEs-,f.k-x{<4-k9Xiڅ8K] 9qҥjQ^Gson8iTk_/s{::R`n{/TW2jzΟ9ZRhEwLwU]~]5MptP-|_0?!O>jz?NwaۻqY_X]QTHS,dtn,}ѿ8"9g,ud`!0~ s9G\ ޒ3g(NCCEˈ?<6j8666[/sz>d@zvח޲{3S5e_&h3=K-ig3_1ʴD^XI#n,`~~T1GÄcL^zԒ$3*6|_&SMwCJZ2qSf> Oߛ\'0)49-Mn>EJ}]8󷤡Dߒy[uOn9G-/SC}qB^ :"!|AO|t`io/0:Ƥ7E3lj{g~8eĒ3^ % TpbHuy `#xf8iC/BSQpyZqcȰ?Tz 7qq#s5xHiM4B^Xh![8C Y(/ଏ D߭^qXpqV. 2BT - zDP֩8҅;pEi-LAr᎗Lَ[S馢[5]2<3ejZ+#F y"/#C1˅M)27j-/8}Xf3G`y(YzI%Gjk[Y sz\x s ~dzLN sI Qq %zK8]j:ϩmxS?S f\*1 @]Gj {Ha"e*8N@-" @ ţP7'.[L1=R|d5'єG +K),$ HKE-{n&=dlN;~~ ,?-tFaGy$d¥^'d_qmRS|RZ RN4ypߐ1WVa8߱D/l*Uذ؇ts/=Zo֭G<|oԼE!OOҝ>: R_ؤ4-HMⅤ$L~?#AHR4f8-0_"H`26.sš`Pui:o8\ 6cY m'{r]F,c?[mIqԟOԺ-oo{Z&]^Y RuhȘ,HٿBq䣫@j4V&qnjLGt6!N҈_ `(oaШGv.D餄𣝒aP-&>fi Y>9Sl]*9!BdqUWy=7˗k_|Cy{}?r}AB\|JѶ>:u=@,'/۹D?8 ` _x RuUr œHQ[r%0GQFh8g!}LyOՏ vi^\}9>08FgT핪LK߄Q2* $CO˓R}ӝRqw֋ial돻|>U>U B~ԋ*R _j褩tl ,.bUaqfM\Х/D2 B9K:E#V λP^q?qQ}{l78#nY~3A#7?Ml{ >s8_&ңNz C2=~\7$K3> >_r[yW\=YFOܪ''T#dK6lLQٝ*/RʚT-x56msNwB#ZnZ9KR Nbj6N^zI)E ȈQ eѲ_5Pל\#->-,K4KOM9; z r7P~Ҵ 0ƚ0>ZCG#0B.,x >wrX剑{.ys׶p[ co&y.}= w.]Om4\ ՜E_(zѸQ2`CMWv oNǩ}dP!O\YsF "$ c_* f~T'$ ӟ}C=DFb$ SLJ{i d@knu֘AJ/JWv^R v}rB*g{%" ;>M OfB1g̚4 Îo 4w)SНt\ PPڜ~p 10u|C}AWH xqH| p.R_ׯsxvum￟G?osQWg=ZPȂ^yfa﮻?7?_xhY_fNEA) +pw@$-њ3/cWȮ28Mm[abPߛU"h9=4umh$Ӧx1~U-ʈ9F6ZN\ע>ڲ?Rwr!O̮QiagܰD`#_ܳWiZ Lw8ߎFUY>T!4>/loPms]iK{c6_^V,2\g6=o:x)\RѶ<_̀7#\s>|PjeǍxwЦx`߹r5׫wM?{>^gtЗ>4žW;!@ֱCO68p&uLXSӧdNM>ow-y%v+R+pپ,oOΘe~!xVGg:>"J`^Q?gҋr31WJmC*e6q63@&(Z# yAX:7GJ̈́*$ۯ4-s,LQ>Eףx.D)6Jwh&[)l}C xC-.y Ȕp[.P׸-@BD7TϺL&y,5=|M;;ͺn.e&6IM{%UZ1b [!fq16~3=~+dyNlR2LNehpݗ#+;y^/9 wm=DIH/-I^MTSx8FMX,ob }=_|6"JM@UH ,jeNW2*],7'njbz-/ drFrIg%I&pY'? "D ,rLjFCEgV[wD#\. pg('cvyt#`%)$Zɹf%HS%Dy̚vGo( igGb/]U ؚ XeˢS7Ǒ1Ho~#\i6XB^ⱘeҟZ`$k4h+3u" 걯>ʚޱ,W)e/"([C5֐8LY`)|Ȗh[~b1be g-BY81B+3e?[~'~/e`J]%[[K cQ8/Ȝ^R?h':残Js{5>Cߘ-FK)xȖ6pqѺ#.*Cl'w>zz!O"84%dX '#vv 8U ȝO Bnr]cv7_n[g 7LBj@N>(:Kzq9J}g=_"v:=in'G=&qyų/\mGXr.Y]aҴwvs02E]([ή)NvtfBNDU'<6+hg_\cm?i0C9rή9~=_a)'^/Y3yypD^<;AᵰZ^tB 3xeHD#!7r8*o\]#^k{?vђ2 xxJΫVqP/֋\/Ksp4Q\np2m8!pN8Wbo:y UyD@ +ύQ^#G׻md\]K-;WG4²TxbZZt"d$,hӯIhBz^a5GSQEX5’xHgZt*^a乩[;johQN_}6;[d;rDM(˄QJ%:B`ҙh(P;o=-y% :EF&j"p!:_B 2l}VLRXf10}3ljMG}Ck9xGR=Ӳ,-k5,gye_g2KDYg94OH-Wr Kuƒ,H˖~ZM߃ϝ.iYra/Z߷BWB KDc gBt E" { (B虖 eiGHMiZVye_ @XòX {Q.bp2=~'y/d-66 A K黬/ ;J߃>*D+2+Q):И `@E}2%V2$8>x#` >fU归/׷|CsMqjL>jrTe7r1=՗QysQ]PH_8Z 1?-|?9nPS G+2ZO7\-O_X _BH,8*`ٓ̂` &iuIYx ہ䖰D>+qeL &uC$ٍiCNuqfc8EqwBL[H2T߂*CH~LNu<~ Tr9,ӄ Xpm!( Ď'ӄZom^sSXfC~Y{g.9[H~B'cO-` z]C@ʇkfjoG>_JO?wNySn+}_-<p]bB2$c2Y:H@ lm^8oEQex(قxR|}D׻YxcuTx`7L ך S ;MTQ/sm>R׿}`GlM'"3#FZv%/%x勈JiI/YA4ӯ& uGq/D )sߐҰ6LAidKummu9Y4M_{y)=ޱg}upo[0m8|),#Tmlj~c'˨c8[: Y:y濴ܜ 7'Ήr.^ɉXJX&"yF1nEÝ2ޠ 11 qm<:hynL*S[r"9S ;G"+aR;ИWΏ6p,wh91D 츮p7[q`EttNk 1V6A;lykNyȖuG#5 ۙ:{k؅ZW-9gfjn<A$wR-ί`Rh@s'@Px_#ӟL>2^{bY) a<12HT5'Zթ2T娺?PeGdTT\uE4,%G& )˄xtm`%W›I?pLP[:}n zM7E Ǡ@y{뵝:3N2y5rh} rWNu֫ss@ '4`l$K_5oF%xr<ޖ7ہZg]cG:ӧf\"4dHQ?0jМ#6yNJ{~n802@ Jg A K j_V_i?.+gYXoy(t́s` #iV>/,(sjLM`2J,-,|gx@=,0(lWAs?Ჾ俶cR 2灅νV-"@Oׯ&~nh1|~!`x EO4-Tr'[,DrSb'A")/7GBr?}}ӿoc"-a!G3 -9~>,8 E>Gńh]Q=ϯΟgO_ja#S..OGLx6ՏH A-NKE_D.TiGT9 ӀI'oVYHQXݨ#ژ7_x C!cFKPeOnB U\o[~!>il"CVuR @kipK"2 ƜP^}4S4LV*$H}dO '{ԑQa q!P4ɞ=n&{DC#;8} oAX:E,JZI > 0( ʥ +_InqdO"t BV(2/<_Np{5c0&VH Elw>"ت4~IG$y#Z?"iW6rvΡpD^DQs"/7'* (45~ٟWM^2Η!]) H2zyY!d bBn5ldϴTsmTii:y^?O4z^VLi}m}ji>mbKMpLG1VR7"w̯&i4rGq/=V;uh sT$s1o~S}{v5Yݏ5QN+\v檕G?c'nY=i}}US.R?V0my{_85b 4w ;!#Hc6/sWNQr4Z*'3μrjطgR5Wf5[ga+>t}1bQ#ijv7}j?@V#S @̗E + cR#AP<.l~dV^3=k\-Z@AW3W 'geG~< {^W'hV0-bo*ߴSHϜR9wnƺM4:vLJ:/^mk/9F~94[?QW -Smp_\yCُO\b/+ayH)nŹpˌoq Q; l{kd'֩xn2wY} {yObe'?<}쿦g{&>ʃ2 f/^raHُOb:݂y-ca⺨9o2Lz'"ӘՖuZJe0 h̏}7ThUGps69eRyBs ުݟm4]7`~Zgٮ{]7XmԞp+"z'{N"dh~%z\QNk o<7j})LN?E 8ߗ _}m7milki\vt:tρsGvܖB~Вbu2kKoq{[H\͑ڤ,:dr69=AKp!,ʣmIӯ"bDrj|#6T|C^ޏ5wbİ>g٥X\#}*>=GEL#;j}Q]ŸVT׭mĽHl7t9mvW=z^Ji-'?YC5ψ? -b 'n{L5y `,7d. E=ohtYMǍz+_\=ƣ z˚~Jksq]d*(=meK%ݚ>Nm}a'> +ܖ?x0zH<0m++fvm,(vFr!+zo4T/V˥TgnC5:~9w yZsC) jcjomӝקۏUIpQ 2οvnxĵkׄ 6qxY&.\ZV0-oE Hoy~!̜B\篜eOfG&=q 1ݟ#ivoHg\XjcU !YZ T`iυSe̥/XKq+ |BqO(,`i|_' lC(M7b?-vB'Eo_v]-nvB|/vI1nynZrO_[Sgpĥ.8M%^0 > Ml||յsV귊/4?CCuUqtڹk=-JBLk~P28!{B #LR K$Af3lsqMrGRyZ5}C=N?3zһ;lO2~og/V>UQM<C̗_l~oqMyAy߽pWTo6asy z^?O4zrS*o8r?vw"ʧXTd'G|e/x8/ϝeV-IKyL]qz,;9y&4}l|Y{̗Cg 捛MLK^d0Q|I=揔q ~״aTmHsf6WǜgK{?R.܊!{%=2= /fyP).'y{v}c_MTiRQ;s숋qQ ^Ӵ߾y+ʿ׈`^/|9I! 7sF\-.j]?kyu_vd*ŻQ2?l~b!e=ι=9~ |hWQ9q(kƎT\_kdx߇k>_.DLB85|~-T<+ŭطg9UiSqoChZz+ 9eRRTk\L ʔS4W uWh*+iΦJ|~Qe|[||1x~}?:o/[M/3_G&}]rﻼ*񵾯 _+;2~uwW5}sGL[Kof2 *U2o#/xCg<$8_W{jE+9^OjsW-|/[68P}~pdNX>^9P#Xi!>ᖈl#7qx%MwC} mY#eEpp9 ־7K^eZjFH/|Q]>5~'~Bf|ͯeoJ?|%m&FZ*Xr^y'.l#zk3_ zL5P 鷻#xCq}oqx;&y-A6Jo{^_Oi!ml#Oi`oMߘ-Gi3_󱿭oKR'uC?iw M;zA_*E eKH%/l_ ;_fjrszJ?<?OeMb8YNy-^|7&f $zd1Ywlg,)X16B/`,{[/"ll ĵl.gYH>ݟֱŎ㙧x6Et?jy1-S. oKw_L]/cзed)p3uQsJŇ'ȸx1dK7}7$3CZ57o 7|+(Jq bSr3qM\?GSoN3]MuX@UMh_~};׼}܊Ư[- \1~=ٟl i2oJ g> FZ߂ϝ<W`}]?U'sV0m XdP.z cEc7_4߽ 8>ɛ2Y[̗*fO@ݯl!{NL;zA_7|zԤHR%3c_?> vßKN eqbNYo)/s7hT0u#)e!GpO&~Kk$]S~|&u~䪵B*L2'|%NE4',|=>/5y[.{| χ}E9_-Und.qA\~jYo{ME?|$K~k"v8[z}Ov_p+_|@1EFB~T\%s4[*<reR߃l˄hSqha_X" f^so;~M<GW摦 e?>1_/N/uC/-,u|5f?&㰠!=ݟBj ~iS⪁??<'_~ϋ̳%`wZD\>礘e Jq+m~d9f&uIe;ͿeTW1=е;j<gI#Эm$켨JMz?zZi{4fkϟO=)y+)x)3'S/q'3D\aAe&,+xN P牮~NTy&WKY.5)x%/\ .>?VC,aQ1a+xl-8>L9J^ܶ̎ߎ:<}ݨ}_|+|B;7\ =¼>|s(ť%gdV}2|'Xq}sڟ2G>%ŏ'ſ Ͽ0F!*sH +M2H_o:k½-M淪R1K;{jk%xV)+X2zR7yS/e߃_44^WC|[I' /I8T|ɯ?> >qr|2`9 `/w;1/,2gĵ_;:cU/\CYf7^n3k'Ee^4z*G?Hh%Co8_ e"25B} b~^M?z4 eg`d~{yTZkZOSU>Nn恝RgW,\%~ո0:Φ? "9_E]s鶹:ϵ\\}Yy<{Y<>؇L{y¶.ףo-xBٟ^O87sG_.*|Le?zKO:Ǫ}ϴz-vut5<\`W,IKT-!L7a#qmV)zXx-aT64Ob?yDw|[*I/ٟ'~c!n᠟?#IJLOl`] _-m~^B~5oGYG>M26/D=n|[Jٯla x>1pahf$Xݐ]Se1઀vsk]WcU9Oy+23N>DpŮ^KF%4 MfMB2d O6-kR?U׈2OhNlj,=~W|8`'rwCO^9[Ki=?uG48Cx ͚fg7OMÆqEmOqrOl>@/SO{Iږq~vg]w嗉}sɴWj8,1OO\;ے#>ڿT#vݤO M>hnرe4tPL-|B7_0#qP>V0%09#3Iylgp#{aNl.ɶOe*ug_'S:U<`:k/ O*od;m}zZ-].^к=).źe-s&H8|S+?M5Z/yfk{:NTv;hGhoC؝G'cXl|hO~(f)ŭ6yrcq]B{yŮQc7m>qdcŪ4kO6]28NGF;sWRE#3m/,؟~4|0^n fd?LJH$__Wj5}^كZmYAKe~"2:_²Ǻx^G c?LyBȮ!FWߗ~g}}l_%^2Ӗ>]?PK;^5s qem.E}YV,'|#G+ c^@8~i<[yvi3Zz )3g6#c!IPTsϹۖcxՎ]_?Աo`'sz7YWyXtdގM/ ej-xm>Kp1K</9 8 =2^ߏ싿8^ |Vw:+G=M9[Vv,Q/u-B+}Tk3-~o'G1(c6Uv{V ]gŃD}0Y+q|@ǃD0[,]ZLk+\-LCvC`σ~|_eSq- #A k J| [-|X<>se0/ η WxhV', >mzTcԪYiM_\VBi}G-_wSg=WA< :ύ=2eM?k0a5^U/K-!R Njgu[_] 7f!83O;ϔh3_X"d@'EL~b[{:wi\<ߘ9p|+~jU]el`0rqM_+&_篘qXSHyl/fmem=>}}lt־BIk -k-r]X2x.3wg3YGjq-c؟Z+o7D-cqZ+_~~rυj +a<י' &ڤx~n| w//N'Pesz7ωgb?3g~yHEoK>;0>.Ǽ<7 [ҳ ޟ-Oa'y>xX#c|hn|[DUi̗Ńo)fo&oNsU 0F5i|UW>ζK z4: ~!4k&oj2Q|oH5j|Q]'ã!lMIjKWGùEY'9 G]G,3_Y.G~dGG'qv~s#n+[s#<9WndWq}L_ Zv!VLK;_.pH}R>GU槗xAq3S5%~z?'劬P=m50O>1 il`h4H䧿;䥏'MAGL.edo{%ec&<=&e{F>?^ueNW)C 3<υ 5{0[oIO-wϩ;]KN-u{ʎϩ$#V:0߶qmoχPڋ:LډxL^ے[H5{29vne\_GBy5v[Qu÷6x]P8ʾO{ɳGHYq(HُSڝ ̜D\-6+y9NMQ ^:jߟWsx`9C'}L~BBy}?^ 1ZşߴKWi$ܽ-KVt>p}~J>%% >Řz=w? {R#Sܓ5ŊuIw3ϧ?c8\+^qEOTR{d?DϏP]w}nh|s('>zWK{[}):^o.ZyQgFLG1)V^)3N#J-q2tASO̎ܵ.!?e?4{x(?|E Iv<ꞀuNy/d̗%_#P_+'h_k3q |rKOcud\`40$8C'l{FEȯGg%^؃#ϗK4{ rnoK4@6Rg<>qz;Xy3OB{,3_?E,IS$ܟ\Ot9OޜKQ-z?9 _*5ds~eU5y}_|[6_QtJ<x>e[rcq}6,7Ϫɔ{x$):<@uj}`~e'3/G2 f旟5OM)tyå{C"ϙp=6j7ru"jM렪msz>`Bӫ\u"?u&i}IȯIR?O뮗R܊9+(M7jJ|;n[ړ&|[r!S]vWuS_cWSǮo}HyvPFO|gA{4142M>ߨ?ymo\Hٟ'^(/ 'Eֻr_3}M?{/݁sfɊߖVrQϷ(?4W#./Ly9ܡ'2<?ߐB/K^ʪ4PP8pc[ۈ{j<gIsnT{l7ẗ)ݣY~a:>w(`I~oυDC'ėX2~*361ɱ_X>~*OUf+>" ?D5#\.g?}̗Y."u2{ f!; 2Um,n5}^_xǖ{8}ݚ>sŷej;r#xzHyhqh~a^,ƿo J~\!x2 3/>{n3WZ?fBzɖZj1Z}p ,a}/_K(e~%Okq: ZpI{ SKK4޹YmΎ?O7Wj9=6׭MGW~4ߏKCiMկ"ķoKE>I =޿&G7;]ᗒ*kkU樂-|˛=5) c,1W/|2s [qxx|z*B-pO\1zHwRVhO,[̗WU!_5XyCM;yAN]؍IZp'0Bud346YK>JTn,+V }fv^m1yV0mKAg m ~Ln/R\ŧ"竈eyX6+X;f YbA}epk:>2?3m Mb^AM)c+ fPx%) /d//=ocqZWdiURj~A̷{=Q^Fue͏}GG/2|o}E?% /'Uk~fq6EP/sy6>~&w ՗Y;#qgM]V0%'R=e[dB">&k|| !Sɤ}1ɺkDqt]"5#y[K/eE qZ_A^ 6^(5{҆z^:eCۥ󿧂ۇ'Qo)N{Uе; DH_28 Cs;b}?[ڊVrhN9TW᥌g4*|F$EޙeЮ4 ^ =2nǒ?Rߘ}5x-P1 :XozyIOqM?'x_ayЃS~MI/o3O}bK^96~;uz[aMx^kb TSիfvDW6WzKԧgYMtg>!{XuDK Wym&G?擜Wx5  ͷYeǐj+恘 m?Js 5?hp~Jp,e[qm\萞]rzf?8_ulQ 1bGL+tBvq$X\km)-ϲs)Q /L>zc2菦umu-n3sIxw\Yu*;Q[7q yHb'ϯn3_[|d'oGri)Z|N˥ڃ N̈́ y7i=?uGOGwgN>]S~[Xo/]2ļG7@{%hC?o?̊w}GYwA,)gZ~)cΏMSo }x'%Hߛ..&|>.W:x*.G<v/0d?h^ yeoC(u/vG'OŸV7$uyaxׅ|e|]9~et,h~}eżL/b_*yN¼dxOvگ痸s W6{ `rDʼny S c1yT1SN<+Ӗ7COS0/|I\O{^iG4ᰣyjQ}-~U>1-AZN^4OOY4Y拭*{DϬy7m}V_p/7_&7jd}zc[3ow SDz\S˺UOE#,e]r~qaXKE}|O )ev-8>(: px79WF67do#3ûA~ƿfpRj _k4T[xv״_>|͌oׯ2z Ws5Qݥ6LN5G j931=hD숋qQ w5M+n 4~]UZ{8H_7Igz|hV0=N &B~Sfcs]\B}>՟/63-5}^#%p}~zE/On~nQP~e }.f ;a}/pIr5Bz| wRô `Z?KqU/\CYfw^wYk XOj$|u4ɾ\ϥCy Kd=!ْWO,%r9N# ?|2n-e*|$mTi*?qCe? :&r"n|V8\!'oFa pSۈk_O*z{y5y oҟ,򔽾?٫/~"mߜmW\ x-`QtZ WRO<\i>yfLW߂Tβf_*vbw&r6Z-H޷hk^f?̃?;q6hZo__ڡe|+Di'??Hw~%,~Q WEB J/d7eίYդ;qhfF?/b%E-sƃ[̗ڣ(C2f_,\s1me8̾ff ĵ|Zw:96}eg\$h{y/wcyvy/s>T U_7)T,_#ģ-eeVMŵs{-42erw-Ag<6B~2A|=Y؋&^ u gj:tD%ZG?` ΋u[R[5q?43'5LEo?I<' ~l~NODpa"+-S-g8WOMB?̳ox+s q] Y2پI| O!Ɨ MJ}^9O%fZ̗;TL~%Z1hi_q`TKfIOݟxeh,clY2:L f7htÊsA*zfZ/ tb'*%+2!dE>J}CAMG|!u'c.9=|ɇ?\__$5~Q2X7g+?*^;"}3[kCզu*/n ;d9#v-142M>-~_ \2Ry6CH_`7k#3/,4?k7>9s8{} 8<|C5!6~Bi_pೕ4Z-oPd*>mshئd+9^4YK+WS7y+xBY.jpBWk{!U0/x:<[`ȸz=UlqS'^D[g{q3_Z̲_~7GQi9+. < ^:[\xl#J<گY;F f{~=iڹ,~,9dSc 濛~%/yis1j̆_9)e Hނ7dZs+O;p˯D`ÁE&{346uf9~>!Sq\>!|5t!N/4EU<@b: f`[楜jc FaY[{GѾw}uB ="{OЂhy빂7X\Gˋ7YUNe!TUL{[?ɠ?-tPË[p4F̢uq9y)4O;oTW2jTW=~Mג I8̇jƟq{*ݗɖ| '2)^VIq"bC!FSk%|JN6"̟\iߺzp+~j珋q!G(o63ah8 x-~b]ۧϷ_~r~?-9C8ZO!q'= <}Jy5!{Pʞ^4;y~W֍/`q]\+iked<ɳ2!lk?d>RoH6P>$V0u=-hv'S*0-}Ւ;(3ȸ1HM f㼟+4d?a^y'JX9>Кaد͙-go3k7{ii>ݻ{_]\,>2 5|%dR<7dyx)nŚv/*|{٬aO.̻}mM9v9o>۽{Wh9=lY.NMw5 {7}~&o3 #>&4p}); /I.2o{GZی{U2/&p7U PeGdʍ U?  )2)D?T27,Er_b)h`$b!'3?fIϣRƟGEhߓi3_ @^=)fy`)nŞu,xke.Oyn5|T{$ՏjͯOZjh{~ noRMU?7d}_!E6]M~~?zq'q.4^ФܟB`[>şԿͧ<ypnG[˳xt$ =#AU9|Z>WO,}>`wbbiZ\c{T^.ayyfU‡'z͌'q@n3Wn`A $5NT~#咷?]8+^U9WGJŵSUm|i=B*]EO6WWm{!.D3~Se|_Ȏ]?w<2/oN֧|B&ex/صwTk[_8aߗ~>/KhO"U+V0ez's? e-m ba.ڨeͫ,lJNAi[p?[y ok!՚z-&l5_ˌa7V琚gꔡ^F[X7Ycz͓6U5BJ?2-S5'`}q]W2]z!{~HK!Vز{iUMzYNОX/'i2Y<;9^?`_2{xi{^bQ;?$|.ee ~>Kq%:OwO?Q4yF߄~ML+_|}t_H{Su&t/V\^%kDI3Z|m'ϧǿSf2!+rKq̧Y<~k%gi"~zK:̧t>]ޯ fמ\\ Wk42ؕAw;2ye'SAJ/ΞkX땇_iU>`[Z kE/kvd`k>?E+[{dv,uL^yi(/5)a"Şl2 nd4;{ )u ]]3k&qZBhi| ۣ1BG:Tv̞.n >_EP,"O9fc )A^;AէB1|ɇ=d}?`_F ) l,Ggz8|/h8x+'kb8[z za%նTCB~-_Q q:緻 >mĵSamfT3F]2|-j`Te>+M?%{_xt1% ~_f7UP|]澿 )iqHُ3s3EوU(2]zr?ļB2a~E5Q |yOi}ȴ?[oķe|-j'6I䫄__O^غGl+U,U+%/4ٯ} ټ~xeU?{ooWQ44O#CrCaP H@ŏ`жvxD'*BG S01!!!p2z;O9@7ϻU^UkWs=wߡ>dSU{վ{U'F=+E"X&K`nBfWϊQ8B_c'TceNY,^RjKYoxWV\dKyicL} {cr $dIBU|7ZKS[?E5{jb q&g_M[ ]SMC9ZISF^G6hOk_Z"@|YrG["}9wjwe{ϜZ<ŻzrxsۮeaoivGA9h2{W^O7@jA?ڬ/\ >1QP_g,|P> _(OYy;Y|?QǪN9~ _Vw[?GMN>XQ- O4c@$HFc}2;g)> Jڝҭ}kLɿ'nU~pީP^o>I8O|*3fgIbI;$uZ_4>ke='6k)s{秉W^} ʬnf'>jsCKyqv9u=3rthM~nRxC//q^G|b}1M?\).`g~.}iB: \ube[Zl{B'E>+۞^=GV+NSO\~HՃ ̷Dc]|R(nͷtǒϷ >55y:SvgLQyQӭi>,~sFgL@C=~'_5/ŋ,ijf(7$}8'BcUBc>NSPtuHDQz4+/Il[4m0CV2 i+W4j9Och|pGcyvGA|Ds dQ;UҴiZI~YnQ}oػ ^cx =U+s0ďnbPҴ)o:F0L!5Ws^v˅'Nȑin{DkpZwmOClӔ){hJ^l{EIfb^ E]鼴Q֯6p+DW受]C䍳®@>;9эO屛C>85|jή;6GQYzk(i/eMB9d72%L=4?$Fuwe34mhZ~,5?麂r>ZSDZ/mߣz*f_:ժ#QUuSתXn2G40ClOo- hM=s96,Q3udUk8 JI]fMr +yk~=]J\?s4sxl>W<4nqB;":ֿM;_&ѽ %:W7m>}Y~܁9oߕǕ 9|ρscxAz凬+F^rGT+"g`җ x5kzЪ3w|E'qG*>|E_sqvF)b15*/tK. 咴1&Q <__UZz}~"e>^_xᅆ*]ia䥹0;M><5=-?;^G1eD]l|*^5\>_h+8zwm1n v"4~ƜFޚ2@FzQ#ڏ#衳LW_I#H|d^OȮ_}{;y!:ϒY]q=s\Z݃~Y% ӄ}Җ4sͺ.C?@KrG<Ƌ^r iUS.7_n@>um7k,. b߈s`\(mn _hgO".>1~ox>_^Y-}?X?sjaIl{>? 8/6&_?6}ao>(KO] >鹐G$^I \tlygM+>Yo5;Y3ʺU=NUg]_Lu}ߞx̟?DSl*TxA]ƥ{r׷۸צc76xQ/gCo>K3#lI.IG eM~o9q%:mÞuCuO?ΎZ>ϟ_|K?f}7JwwkvI>-=@;tGBMlQSՋ8ҘȜ?;A;6kL94;ֲ<#<~~ȷEjDPC ]Ey#zyz[]ACf7*,s~ڃ/ꯧΰl-Ft|>/C+5<XyAȻKs#O(k^ Pe_-UM=Fx2>-ԽGwC*k|_%69_[Ulה> y@4,-1Q:FӅ8rPG^߮E~=|w?C=߯%n>ANKWUtxv!?sb2 Mmv`M1츫[?p=ċ}r!o-ud҇~^Gd]>?-HttuM 7yUXO/ko:>(ÿ 7C?r{^_3ף4MԎ@mg=K9f(űQ"\8!G:UEy#<'tB/csq+zy><9#HڪKG.y:~]Kۖ?/cHL$n><-P1'5Y0n}7*gXx?C!C36l74%^wCC>q=_5}monun^m}叟|it -sů=OCKfX_ 6|\]@lz_Q dB.DpVzDį5=C1/G|֓6\lÌ`3F&t=pN˚rד /ipF#|:?EPJ+8~:? \`5a6B7Mȋ-R^/l=EI%M)~F.G%wqT^8}U}Қ~|{5O۷}S2c_˴=)eGgnYWƕͲ7ƃT<'޾oopm5$y2m{dx:kA( 9?yhc0Nsp-|4t>aC>ϑF^ig45>"ߣ.dKJOLQM(v>cW_iԭD:*' Q~ou`]#i[:EӤ mԾVӟ礘7C=).DvvU9-Yt/dUTSM8myp\+x[74|~:/}sP1(IlڻZޯi;p>A5?'ܗ2ܢCG0 #okiu^`L(^ lIT߇G1_ORbD\Ck>W? 9+n0r:7Si6~_O,{G>=œ1'/PJjGҏ:l{XBsmH`w (_Ok+F^F_ԣObl1kfn?0Y#)ٗ֓E>F땗 =3!nUv<2>RU/Ekn'o-w|{Kh3c[4C C/V{>/vŜwdb "߽cB0(!qM?>q?HW2r[g7.k'Lsг?|*ǮwNB9@ka4ϧ: ٞZxg1?J5QUd۸ǧ0|ּ{~_Fq6ߩ,_szʲFޚiLάO/q{ER:VAoG?~St<{=-qqowN_f9?Z، 12VjdL ǗǯZzsUGWսύb>Y׎Oe[awEgrpP?qeMq>N,s%Ъoʈ_.oEIwe{ϊo{K2;m~:N|z'U+}=ƿ_1̃q4-G+9:JR"BoUB1{[q;_־O7|Y8x6z. '?3yM~y9\~Y5qz;KO6]G^%aBDnd`_y\|g;?7C!vh\)Cc89!$":9~i!($K7ipF/Cs{NJ_/}bھ!;.Y-_L ߍ]մ|LC`^ʅk]DO ?ڌ}v5rڎbwQdO #o#=@Qyばc5ME|ɜyb=1l7Jka4 } T3nGò=gD^ʬ1=$-M'oc_;& 63C?!5-\M8_[ѴH}$7JL(J1ķR>m)(Pƕ5OC<G%Mcrjw&㉸'壘kzsj?/j_S㧚q2[aeLćG=?YJZ.C <ĭOcqE㏳{Lć{?H(63?Wk[!cruPy+c¯&zVn}#6<{M,VœS?Bw^G]x*7shVt[`5?& qkˊQ5Jǀ٬ y6 [NumVeǛ\g^T~= 枿)?7TKJ7lk/Gu篐Pv|UBv O>tL"{$Va'xUs]7{ĭ0WҸ(&NGqd!oqb?hpɾЍ/ ݸ GK't^ظ+'X7Yv@,IYQѴ'nsNˈQ O7{$DwTBQ/[x^6q+|teQGܩK崒0ڌA9Y}_Hi{[c4xM3;^m߃Q%&^_2vC!rl<Pg)ίQY }} }`ڶ=(:0_@ϡzǬ7Fޚ|IKZ); u)38D$K:*"yG!~"]'>B~;G]+ 4I7cJ>P_.0"BU4ϙRTLwb'=smU{:S/W5?W/8%B \~ȗwO?;JS:|K\!ۏ8dmizrJѿ7R0kBFokBnK{%ۭ0{s0?~D=Frtүsym&>~~&Jjlot^ڬ /iJ9o2bu}ҟ-}?<^;x{K1g\ #ş GGY+kΧ/vf){SHMƝPVѪau܉' 6]Ma䥹hJyi3a+dyi^3Z_C[|v |%zSHߴx~U*z.]>s\ƾ6G6Kjbř{}Fyy=9ۇH_k' ׻y>4a<Νp=K(^Spf?OVσ^]wkmhn^c~!Y>3vM31+AOg\k?)T<*_ų>ޟ&^S||yo8yA|jf(b|("F'^w5')}^O}A9OS(=_DX<|>7Q/j8oQwo(w^zkiJeJK>ysOU9[9K>(=_D/sj9os5޸+yz՘ywcr W_K:sR=_ڴUoR\Z_%.O}\ϷZ- e~90 {EF u'xq<~Yɳt%CA!ȗUQ}9Ѧo8 Th]ud(7 _cy^ɗ?Mi;'+P<Ht~/^_EӪ y}WCzɿmU憋"[_>9CV.2۵+4n {zyiƁZ? 3PWjSGdbQ'_մKשon'C ?O,Wh^KبףF~񋡍ozק%M:k!Bo%4#HyU눬~u3Nat\~:}hS=.**`}*]iael?xp=L3gYeFH_zq{a_~vѳ]W/^m9 Q4-b jFbk9~򞿘{hQi}ÎL(_/ԡ?!/5>{?>l= uٹ?xu'."Zcegʘ;e 5b,n[d+CˏO'oq%ovSc _ Jjzv^8i?!畣7ZcJjLZ_?_ݧ)]O䮧mߧUE/@ rώ #E[ yA(f[ISz_OUOaOC9yrW'jw0zI'j!{ZO3*oF&$(6: yt!ſOJ;!哿~}$p0 n90T0KcEX/ L|뗴)H qЕɾP۶DrG+z{PѭK3 ZǁgOT/jt[]uUۤȷ9 #o#[mxy|g'!)g({% 8WIkzLҺOO▸p i=`hG K6dkF'u˰D@oxINқbz;k\ɋm\]Q#EͲR|Y4N#%iW hZ%4|q9]_RM-PMn{K9hluIe▹Oĥ_uxs*5|NO59sW0yJF?|$G $Zg>GZJphy_}yqH+=EӜ)D(6?5W2åLn{x-|qEzh3oAkf'g1}\iV6s҇}4ҟy-_|E>; _jh\gZMUkpi,Qhln}H鼴Y*p^Kx%wG[|6~>X^Qw'uμ'Q_OW7z5SxfWIrWƕ習y_KhazTΗԡN4җE+Vѣw5u:yn}Ǜ[o@7W_K9gsYl;8~o7G~Goyi\˙ z :|.ڝ?Λߕ>{9qE=W n?swdVdSKC~/ĊW.\罢I7?zdK/ǚi4+_r73Wqr@w) \\\? j|Tx .f=/_9Fފu~ɚ!_i;O r0\^?QY|SEm;?q+=pn4z;F&(W !W|f9/MF;yOwlO Ϗ*:?Z| u{*i:8kߏs\' 9NI9+AdQSF1) qwzġ?]bQK.-QnkokƜFj~Kq۟@p?$&~>xz} #n? ўݖ]8cw^_H?x!Л~Լ7ծ]y{h/q\%Mo ]R·I9Gc,Ս _"]'{}jo.ѭ`]z??=Nl7_S&֫ybsD|I'[4@yC3qq͐7>+CL7/o5FUՍy㖷pmy卻Ʃ~#~͂x?=IJǟп\_vQ3|.U -GaOe[dp~<jq%ov u3<D|$_8$+Ei>ϵwHwrcKz0U k?x_8g?hKqrd1d n?lY|O7Fq9xPtv5ǘxI>"qƫ5}A/TϘI?>#ow4wc~иc5Mǝyq'dt?$7{&zUƣ/p&iBM_7X}0:2%My=?;qvRsT⅜R^_E*Cl2S]tAcMܬ펏)z;nTNf ?[aٙq\1q|r2q ''Nhkώ! 4f8qc! 4n3ʭq*/CcG෬i:?F.G1fAH? 0j7^`~O}"ǏFmwY7 +yiz=$7t?x8'1Ca861A^`h^'ǏK|%qOU{~ح0h39pynNQgKzKX&?GOyh㡧8щW2/)S*OTnÀEPtM? >W >Cȇ-'hQi~r,2x"nG겈zqnGlWB>'!ڸg7>p.:m!`vDP) ugsƝ?עwV_;kmw쑏Xƽ*^&>}Ggv3sF~'Ka %5KAÖd0͟\e O+4hO2USjմ^׎aGhl íMmEAԍjHlUĺ+WW6 'soPoz8#sb?*ko+{H4C(˗+#52y̍7舷%ԇ6rcIP'rNG})"~`3/E~}h_5]ߧ#P9:^}Ҹe*a?O,y Nj.x)۪_^?yg,藡ϙ~ |.0C3Q:0>ȗjg~xD L:=)JL?4稦Oprޤم!?/6x°z}_Vwyb%Mu|hcp|x\I8 iZn={ 5j?E7tf:_G [#'}h5 (wF^g€|jڣY&"[ٽhb6.FH}p|zkuxPuaϧ߰4x_9?OǾϞKsva\IW!ߏ5DsP\?P_~8- Ͼ<:>WW9Ќ/%M=r۰ KOϑ5?~97n)/w5k3o +Ϲd//osrxIǩq}c~>6xJ۸وG6n_8? mI'Jϑwu\Qz|F3z8>)6:\g.P/r3Z|7^>Х3$zU݇wur+U6q#o&&u&(,oBVyp[YykV )k֧r/i#41W>ԯ}zVy@x{Pԗ@4} {`ֺ>N\+nl^5=u^5߄FޛQ_YDYx%MOOU\/etq~phWG[ ?qk-:~ #oc?Up@{S zʚ$kgًڏp{#Zx[/C\6-ߓ#ksm Okٔc9/6E=k2vGS|e (نt}Ҽ9+ۥ;1x8_|Dyۻ+P~8 OYw#EcB|~yp? }L>::1R#}}|P]~vuo?_iw=]vwˮ;EO >'.%EG/3_'7o'y?;z>g΃I?'sC5dV՟:LxM}^3%nAq^ s #/Ͱ7x -k/"Խ2M?gŒr$pd_>}UD>#à'hwWy~ 'yo~~R<rΉIv|HQARF.(^wE*CǴS~(J1?8C9?ފƭ066a·=9O2(}N'NNĽӼiĽ-qߧ|iĻ#_㇞?&z@@mťiΘs=LH$~b~)G+{5O۷E*Z3uT]o=+T٦X,1_ISyX01 xO-PP2;%arK*Z%4t?[}_D|SEϏ~EΙK_-vjH7 ^{$cn+Vϩoj1V(';xkjùiZfFv#MOcaJ-u|L}?~VV$m-oc˴C}uJ=xY5xh$=sϴm\}Yrt9J("V@/DU2ԭ4؛[ө?iY铪߽ ܲiWVyUOxy:BxYf<6G'CH, iϮڹ?'*@BѷUreSϪ/cl< 7u!yw7Z֟384vsLqFq:|CZ|w{_sXs>w=u\`F7o9>ߋs҇樰S>W3vy=Ts4w~"/Oyh 7k_A81#&wGOki\;+Pܙs.Oώ}fߋSof>%$mO8'jd#O|d `wc:w-ˏmazD۝%.?NhQaȻ[E=ҿ׵lJ9p&9󳦓7GZo8Fwbհ~B[;V/|4?/|`? j_P3hI(m kӄ˘x-_] ? 1'K Q|~t+]!|)`}?'xxJ8s;cŴOOR@qEMqPZ罹Cř5ym$N'!GM!Bq{={׏KgaxEm[Gf{z5Ì]lp #/8/P:t_9DWHr_&jaD$[zUhp~u=L6V]OzYox+a7Ο'&{$W\ɛ2-7oDžx y%-T|t^],Ę!q!qOތ}Iv*xg.M$7jy~EY^y q*oÔy)6qq~RP7i[jш7Pn?I-9hc4ƹ4.yk t>ڼ89fdKFGxoyK]-UBka4ۮTwN}AdmbC|ÊOhs{ fc۸aGrX2oD<љ 1vC9/?UIkr  u/xµ{ ?iUp(MH!Z|{r?aɹF^O4u_m73U6H.~v}}Yu.eOK%BNFN+=e_ #]΃iz(GaϘ7餟O[-FT6p~P56yP!7|~.|_'ȕ^jO<ݎ+: nݤq8~(c_q0ś< cq\dY!4y%_Sdcb~ tm\qxS%M9ZM{|╌9-$ޔ߄Ǜdě[ >Uǁ _ >6O}&uoz< {bCihEް/Y9HI[C?'XN>xNN}|nl} T]O蜯.lp>'[xX6Y8Evjy|HD><'O&SKm]5n^ /xƭ4m,q{G^p]98A~9 Sl/t6w ;W-O^s']#z.k߻םzD>Kă>%g=&q!v^88_E zO*'$GC6nFBLTW .WkMFQzũ~GovE+n]q%/M'Ьr{xz& 39RJOuWsZb>>Gij5S lsIk)zبlTsv+Jޖ ʅQi~0JatAg[zY{A/![i|z3?ģS?+OWou`xWR<;f>:'JWEt7˯s(RM!slY="FފOmv=oMvGy&!oR3}!6u!wauW\ѧ` oR&nUv<]jXxHg&I}EKڎs0NY58y#Gga~sI+V % 75+P~ߞx`7UH8@}qX_-YsC|aɾqu)>3s>f۸!+_tOKyrG(lSI:__3v?bs.1VkIlvb];8~CW?&P|CyLb?Hc7W~iPǜ"v?HHo/7062|eV?\{Z!%m?J }=Ov)%|egX?J.~ݏVK ?pgЏwB}(ݯ}9~&nsNJF~ϻԢiQ\rW/l#ɿ%&޼=m&?pe=PV"o>ax"z~itO9v\OeMv7+=J'T7Pp3ÏO}(>|dSs?>C<y4N.TR?qͭjh'l|/|8q,F^v7Ңiڽ-@Y/Gl}uݔ-b\[sZuQE/36]O6X> ;)%|:wxwCHd=Lm {.8Gh~/dU4 \}~?m\os ְ㍄ yLZWsե˫G#~Yso[^]vQ鷷@t]U7^:o?Ey#%Eof=ybjb<1Wl{p`uln>0KЖ0J?%M!T\O=r(]=i/^jay꒨?׿" (ǟ_#^5:>^B #ouK 1:?E\jAs;l󂁟n..}wGt~?,?7V~$Ut㲪NY,_R[2aɴ<ᘔ5M?yN29R)r/W-N=<[FeGv˨2:k >Dↀ'V[8: -w=+6u泚y8NoVw%K]_!_v/f UM=Uc~Ϋo.X~OGC>]ڭ0\ Z~`q<24=o%7.K8uǮ[ooW)ɏ_m)?x#nP8u%_VM3_Sw*ց ~]J^^_kͧ<}DS^slRL&}Otu#Rߝ/ ugBk\en{;K𷽪9|Z>0 {~j>'7>N# '1}bT' }>+_a~c}{e6.TzzB}{C ^V?j<͈o~<Ggq>=;oyAr(ɾI<,xk[UOpxo߽ "_[ޝ[[|D "gq b4>~+p>;'"[qNƧC$X}l<ٜ}^-GqL^?m_|~ĥc ?tƾ_0K>'o ,L?Jkuri6siCsRyk.vIac|t^Ko-P1I ds)UO|7#7u6F7vAR_|4hMzL΃\EǤ-~ `>g\FSڡk ^iguSR~?8Ә0)8sCBJLd_ORd_աYba>D.z1ǟFekCnAClR=G)sVyQ{%O6En| YOͳWzOQ0>x.Sѡ2~9zB 8RJQ=_b/_ǿQymQ"}~DdžpS?PJb?hG}޹Qq~ /gҼc_~7o:H(^Kqᠰӡp`.ێĭʾӡ.p`ڄ=|)rlC1zayi!tQ6^XH.w(^E0#?^Q{ )w}F^O1I7cX?W<\3ĿҵR$|5UB=O:/ >[^'oɗ^[*Y$u,1$몸i #/=W̎)'(kίMR^"|:**Ck4b_7DXalM<ן2 w[?Umɳ5H:ow,?̺m\ːKH?3ԭOxχ#{d"s`ϓ2r(wQѴJ[oxѷO\REG_ĭ0;cq>J1_4N?Cw_b&UaӦM__Zgs/5_;Mt]v_ O_NȰ,?i\W໮x^⥯^>Х'm 7BCx+L|ˑWɷgƛuvI?SE?5^ nx}w_:U8U=W<Ŭc #o͍WmR~kοs~JsP,d$β>k9T9./Uzk.@vuM}aV60tlJs fG ͶwjW+i B|_/,$ml^krڳ#P/UF }?/¶X~OF^Fe<m9G璦x%I|~Llm9f$O W仢Wሬ= od?ѳ/.(<%qORwX~Iܺ*q%/}19a|kT> zDO&}|C^/P7'Pqv+ ڰ ܧp]֔ϗQ|A#>ϓx[5`}>Ws[v咦{o̓?(Gi|F͑"^u>>œqnShr^-l5+x?*]iaed tDi!AL!J!oqަsWk=bNxUC zGxYpަ{W24ޙ?Q:?,? wnJ"/UP1IKg%[>QMƳߛOOm v#n9&nָyj zuxY]c'õ[^0G>?(C;Բ+;;7Y'-7ˇ`;q}\1E+>(cW.p>B3OMxE=WQuxz).<|xU(k7C5G?'@qh4\Q0- Cs3)]{ Aoxihq06&WO1A=FOM&L}twګ`GvH(=Vpy?=8{ gl| ~twVb.AlsjADA"ޏ6qSzEx PmD>;z˜O'W}q1C]R5"}rMr.wݧ¹e;T\^uGQz4g~Xyߩw?I[ɦq+Io7:)/orYb'%7۷߬|~ۥ"Kz_mɫhUrsǟs7*wO.bAb_kWfbn5U|9}}@Ya͋ gr)5̅J̤V(? rr YߍON#ȦU,\i/=OeC;p+*M)2;9k˩~i^a^W~$kм5ٟ.e|?yA1,([ 3:n1ԮIcIaud圼A9G?u}˝1AŸo'_7[a䭹!? f?}YӴF ~<<]Zb.Q|nT_5vp՟%_V`|5?H#)磹Ұa"_&7;>$\_mugJüs|h?L~':QM6}ޢ0Ɠλ_4:!,#"?wU 38?r{~'X7k_UѺ#W/ʷ3,:SsM?F#/oqGߨ0.oloFiY z {}#ƹ sqޣErF㼽"x\HoFqqW /;π{><jg <-6,exy14:  Umn{ ql&Î|9Ɨ/ {G{ޜ{'7dCq2M1O,OިKU[=?D~b7|Е: ya?̺0 ߾עiG=3ÿɾ!5{W|ᗋOB>J~̫Vy7t f>0{C1ɾų7pkop:aoLz S;;OyTqT?$v{L O{zB'EvvxUMܯqT3 ^Q; mlqG/hx 9_9JdHu K [?rJhmҥ?oֈ6}]d~BjfECV('Zt;}u@/uҸWRB'. ,_w%UnS u!U9h7:sݚCno'Mg\q׍۸=~?}OI}%~Gԯo:R g~#[e[fpɞ~ua9$8>qwu݄R0 Bkx;#O@vS0U_k|w(܍ozmGQz>ֽ_Gw^Uݰ0;Mݏ4nU|AsPǖħGDVe͖s6]_~.i-s<6 ryj> Oq1u]F?8189 mTޚP;~)i߃!k%o.f[Zz>[4`1.OG԰ }Ym߃԰~_6liGǛq]*?!FC( }h̬7_]G5odH9eoÉ)gQUp*]Qaf^~gQ;wMֈ<Zz8h&U;xg+kk>r)O\͌8rM .%{H?s +qԵ8ձcS܂ʋ:ܲS]D7[amlqqC@:/mf~Gf-9\qR_!V$}HIy<>I¼]t bF=>6q+_M tʧA|$'0ڌx!m6G=Vù(+JR~dv+ #w>z1pul/4:򒣥x.n;K8[M# }>wcoc[n{[,/R3v6嶳 ƕ4=^5G·[zw6Cq~Ř-('OM 9Jz DEރGt_uyRuW߮:r>Usr5 Vζb|E:_Uo6+%oi]^ z\ ݳ }gGahWYӴ?KOލQM'p_x޵gJtI7*ZU2A۴~Y%>lZKBO:k!&m ;BUjM%@?yni(=?.]퀚y}Jn;@~q DF^kϦ-6(/ǦG RwS9$^pIϕ;$Pګʝl9uy.*o>abi+y!;3'uԠwz9JITҷ8szorˑʷoqJy@M!=s> oOϫ{y՟1|q%/ zr'IOwD/{I>צ/M$WOd_;S|0{m?"}4ܓJNa?BޒrtnmgIC)UISF^/or6n?{!B|\ddi=PZKӈO}[o k9+/=~3\,:ޯO`@|n^S"T5qYuL e\ #oi-5ױXޤ`w8cyqm=Ўgwb[w2qUL=A_dž^<֧2įHbXVw0c_yzh-q'c `cCzin|_Ǚp8hBhPΟ2uHm?X>:4ov?>;P+Jyޛ&VcD\/)i}xZ;0}(}wDߍON;o+=k?sw$ǏK~;xHӧ]y\5r"3ܾ؉;Py)B0tkO`Y`vH0{p-F~Jp`l~=Wg\Ci[1mJ^l{pIU=roJXvL43/v-؅q?r>S3a+ F?;Uy/"·:83GCqVx?_USۘWtV?Q%S:^]Γ<@7Q\/ 'Rc"*<ĥ֟97?eKss|;u#}^JAu}jCrJȨćX}ӣ J[ZcYP8m68-ٔKu/ij/,IHT"G$Dߕ=ѥ?$ZUgg78yk]5Zzorl4>}۞-e+i8|;CXNt<ٴmgɏ=ֳ}Q۵|20{sT?h~Ygf>]O;&J>g~\ {}:=x뺿O7_}=O@.zO>ц<ցo^1r <:%T~۸JGr 8}!b(?$mh%evJh-F~SnA<%Ӣ}7>o[k_R ? VaǫGCt>k^y_n>gzBnio{M1{~7v]' ٞ4"Z?'8>u"ob݌s .Z`<ցoryhg}%kara_SmyWmv]eטohkH^a_dVn'E{gL}+ψKig:^87jaZX:nU{.JѥsDcy? gj%bA_^ԟ'[aׯыʚeB/OxZyz|CnsY;yr3}wd_ѷUrKg ǟgoˎsŝ*zxL~GK76Nmi\!7d=&kO;0l4bM(#p!s^g<xeOg˹^+ykRO잗6:4*/dx.Cm41/2{мz}]Cfy4qfG'i|0^?R{ ȟ(] 7Tu-ZݍЏ'O)΁A.q}{PYOq"zқ,z~1'Gi->1Iq锣4N4UuF̎40.,G)Nhm獘fmPܨwخ,mVi #؏X o ?3iXISEg $c~̹sDyeNU7¯ɋ'5<9kh1opuqrd'GߐωnN[N-J▹DjMʇ+MF?}~GEɱoB qM궒ɤ/ÓlaZXyI3AGt^xѶx_<5 ?=/`xf35ݤ[tNjW8q*o6s-sftobd+"epx0Ū~܋{_޸Ǣk:gE1?#ĭʼw+*/&^,?`TRYS{?+ xIm*0.u:F1?7q%cg 3[a䥹fma(sh&eMW |xd| 90`Da7$e0zux.ۘa輦?Q{k#SH✿ho" Zv9 5DžWU|Ea_Dzft>8?Q!o(in>s7@〓G#(ܸm[Ӽ}|Rњgb(d%{YlF㕳UB?~p:]틏5Bt,>}xYs1envłS'tS4ӯBT l+4nJކ,?Ar\ˇS/Bdƽȉ8sqT@)#ڡdGC'tyz]'(0y!+>ˁre;c_>dCp,6 onF^G& ٢ixωWg,2C` 'wU4j(oǖ'w*Jtݔ~]߄Gw=p>RRO ->6LxO\>t^13 U˕l1[5ݏ'o4qmpf#>qDq׍۸ؾט>$`({[q+*GiܷI_G5|${Z@tKqktؾ}=Z?:VlyޛakZbڨ\y{Mu#i9@`9/$8v]Sc&'VJ #/͵4jZ C/^o#AN/U':K5踻>_3uEOo]pCz`{苿k S|xcKYS=z~TcGS]}*n;@Bi ;/Pii7ޒmq%/7_|4ynydH^xU'|w$lő@;8O^c)Gp'`ˏγ{?wpJ}}X?'yggVy)To"?%Mt܏>1Mh+4;4b1u^]5;~8 jV}?Y≖O+64S'GKO-~#_KɁr1?n(pM;>E7\{63ޠwWeg7+ޜO] p9^ CVG~f<?if5RHڇH?.v-̾V4,ƁW_;tohsۣbCPo~F<͘>`輦?vc4 9 |Z6/Smþ̅ TI? ]_|K?&|s㕋D=W n=G_yܴ}gu3q>%c▹Xo_Tu8h>Oa[/Ϲ)r; ZV\XM}aO OtzEK3F^{N?ѴO6xZdܣɓ37PO?t6{ftG}QwKLShgxJ>&qa:z;"yZQz 0\<'kFgY"}i?_˟,=(кn}Gᇡu=z?8?rlC/Ǵyq,u0 i91Thm]% >y[.x!ƉC=Y[t-\Tš.Ŗ:˯ON9Z\ym^-%MK^)Y8OģY$^R^Qa?WhZe(s~bSΖ[?E5l'&z~!ۭsj"WӖmX߯lċ=on; ƕX=PQ:/v\ |> Z ՗TOSM$JJ܁U"6ۄ+.<=g.b(_I9]_08]gggϽU"xKt.ZJ\<-bKk?x핔2vKsW%MGZ?yWf?V-n[?~}| Oik-c+4s#^ T5L4ݦ>+"_9&t>4\9ԍ ;6JF&ϡZ}#xAt(fly> *lpaO6Nm_oh]GQ~1`2IjDoW:v?e[gοڌE"{e=u7zOqvJ68CwIq){RBKoǡv4O ~@ߎKGN'ny͌_4>7'{:Njxo_ɛ=l+Is3|"QKzޢq9<_+yk^=B=}^O桯>Y9i>ֲ)Ƴvw`or^ς}z> ӄ}7ho[]-}Zz%˽ ߱בT|8WTkɭijb߃F)ވ+y= ?;[z?^vki\-?,gtskWs^ۘ u|Jb߃?_kB&>V>p!TUE~ b^r4]lWr">aJuB^f͋˟2]w7_R~2w_sZz}:/ u>#z˫:">r鵓/$to,?9wZ_+F^Pxװ!IC3Fvm#IY!{EǻzG>am+*_ڬG>b[TzVyoh{D~'KK'ME|y#[owv>yOD$v.HL}QMWՊ\$6~H>˗R|'}~{^s?k'{Q$ ҏG#돸$=8n{}(štg?I[ yi~w)h'L5/<Z }>v/zU~Lѣt,SSeD<ÊxRV}Y,VGSԟ!_}CuW42Գ_|GZ y_Z y|AK #oFKR60mǑ&8k&Fx_ZzxY;y7rI喸t1){\qFNah #9nO&m7۷ϏF`?aO>7F^q~9aSy^lw\Q\wP}~i|7fp:˶|X߯rjj<oB㭿O >0|!fG~x/~_՟Sh|<ŬzQ.W4w./"raeTg(fSVYt^Ǖ)mz~>;F<Ѯw9~hתSfq*/`ƁTM3@ NZ:rvi u:ua6?K4]鳚մv?+h9%o?u ԽCDRڦ~}˹ӥSu8z?''ۄ(ڢ %~op=+orb/d>I\,yq!]_,/.!O ѡD_ԟN K_lR3uYy oh$/ov}i\,;̓= Rϸ1|w idǐ ܱ ?cWq@+,\cCff]vW2論?k`7C|yz&+=R$}ChZ V@ebFK~_|IamT֓PF\~~/R*U]-^@֛?ۯ;Y~h>-#F-=0 #/O\pg{4z*o_בHIJ:N>tB#N?Qjp'+|o ߞx̟?Dh+moJH :AoXb;'/jܟ]_u/~QDs{DyQ: y66Ii0y~~{;k{y}D UMZ|Vy_wsgG)k]>J'?zA]#6<璽Du}e KA={ɠKcͭG6!RydΏy}̼/MlWP{yɳԫr&)SIw~(4 px\j7/9wq%ǻh)Ly|%sOz,>k4Ο/)綇# 4])nnQH[a䭹J泧ןrgBtEm#t{>.ܤ.^G*n_zi}ʗN=??_׿E>zxl`W7y$_W*ΈfkE3K /46ѥ_SSxCˠaTte{ 彗5ME|I'ܧT\-Lj{x뺿|]-Ug|]A{x卻ƕף*/GΌҘ9T:8l#ŏ!7izCb4p >޷o K^8݆~x(BGdQ|ɼ8,kʟS %7Y\mOaŔƣQZKۖ?-Ρ#ex65\)p /zH<1'K6+mqχf7Og`ϔK=8M5@iUSj?i[5Ny{JsgK_ųz܍{ݳfh'ϩ[ty]Mțíװ[ gE)fZKijΰlP>nn?+ e+y+<ގs19ORI9Yn | 9UqyuZMSx;aO@/uyO(iJ4C[|UP [Z/ 4y v/O(`yh|3̮ ݕLrlZz~P_F<$/3q澏8H_!9`q\[Xux?)k W!xkK'z1>?7ªz /^nU'Ū {}Y0;R0E痦8 i\j9Gt- }C ш/=I5lSMtǟ8Jb7vShe_x>?qv40}$K:"OT/O~8s-M#Nޠۼ`0eףZo { 3 >_|rkeLӚz\G~T4jɡG>1/o PG=p*FL"9|zK>ݕ|4nwf>?P+'瘡cr@n&E}h>_R.ͻk^'Sʓ >%/K5^Ê7x%'ޛE)eClƕaW6~l~hZI[A} ޢ f_ @jJ'}>?Qf :>5rs0yP///b/\yݢ~GzFUtMG9KOi?0= Eϫ5b[nƕм+J˗(?3|!x\r8i< Ga{ sԵmĭ_A>!k)<@zB|hxQxMiIX£#w윯h{KǪgw|Qߪ  ne_L[amLO.O#/uTϕ42^_,?$?sT8/suŭ0\{pq3~F믙|F_,_IF)O!Aki(p(=? .nr׍[aiw#oûiˎUz'=~(>k0s%<lmw=Xm|*^<cZ4*/}̅%^ox1v{M6zC~Lܟ/9qE$*'Ny ;p`!M?tGBM7KxVy|zª35 3Rg@f/A3 _G5/p ,{_mQ?1e>,4 mߪ-eU<=i1@ez{4ڱQ3ߒ~$*GuAԺԞl᳟峣eسGl7&վf?K=lwmsWzjо\{p}4ОfƁO_^= J&u=^37^uM^Y^s']#Lsno_ǯ8hw:O:)ӌgF٣?c|{<H#KaaG\~3~4G H[?Wj~<`};ѣOml+Xvx}j7MJ֕IA'wNSO}A?O}2hg|4軗u6O^022 %MG*>=m?!#:( tG|O}F#~uO ^Ud4Y0;Wj%E^7[a䭹EϹg_[Ҕ͚z˻QѴ)cwh:>4w}Ͳ1t}d 7þ[[4 #4ʦtqtxV9.i[Y14>-VxJz8ˬ~]XyNjR/ /͏-kJ~ݶ̍LOU:칢OǶg9 wq-!M-z~?( 6lԸeaH՟ sG-]uhesy}R62iFr˩1'uۯON[{z 0\XIOc3w|lDkzSx~N`Gj$~݇ 062? ߘy& =OrgxDOIB7q0P\ed7y oyh3bz3=񒽧D؃^NF/5NQ՟bKM^K#ys}M9h{ݤq_JO4E[{Cdy|xQ΃}c9c+PҏpK5'gH^"Wө\▸'b?4/p\Wƕ4~O_}5K]X\7WKߏUM=c9-c?0{BCf,\+`}oLﴅ>2~\5hX6+2O{_k#ϊwVm{8~ _ăO *xaHl=F^Ƅ QO4_?8S8lgÍu0-si`Z'?n1aw~/hZ/a{N'N'}E_dn20^~aud/;+bh^Sy~t|􌗬X"}OsisN{}9#qs%' k 7γ!>n~ya-n[T^_߫/[?="5dUInyaɸ!OQG3P{+6C`A=≥D()~?zfr~ :|l諢^DcX>}crx~XzXMӸr<6iwu?O|WD=)ZVx}-}?RsMsևu/Zc #͵4!'Ep}˞9-rr$lH_.F*نeݶ^$~,pk!,mr?5Vy[=J=Pf<񘟟g9Wo O#q<]+GP(cr;pMDOP8k* 4Z%n{8pMMhVi< `y%7J^vK#6fX}ohsts2~4~v+57toŃwCox8Sy#$}ͽhZ%7w#IkI/*~HtOꜹdE_=nExWO2_1b7KŒ +yizQ?$e1rk?qwrD~e;2v IZ'3|ո}b#ڮ8|&Q yzo䱧yFW'jz ~۟_I/۰ǖW]'z9Et]U7^>ggQg9`x@[ĪNްX?0=On˫bze=ڸӶdS:/mf>B !!גx̅XW;Շ!#>O?թ`DS&޸Y'uTVDzA{OYԧ?E #c2Yڨ~ w~IcsI؂  VS▹#ej /ʏo-=p\zסrEy, 99>3t'kO^GZ6xߥMܦi w4˸0;c,/3|C $o/9y<<?r{8X9>gOFHkXeiUS7b{oQxX!>)5nU'?sN0{3ː4čg'6ű~*a꡵:b7qt<Gg?6w}Mkr7gbqԵ\3uhU2N06*J;n~`~.~}ܹ߰c'Z8]]gc}$Qs ӿN_Ü?KsA8 ϛnr,|x!^?2(ߪ|p=n+5<oćW4uY}D[amdJR ̼t<MMdc¾bĝ|zxe|JN{c~)r5'*v|CX~F8W99\ ayx^s !)x^Z_70as47!'^QPfOw?C\x"_1^ ȧ%#P[}%#?Ob #oc"_1=ɮG# >+,fZv"UM_~Z_M)1KcOnUJaփ2#nJފ/Ѵm'ðzm}(1I!{>փ'׶LS_Q3Z4b5wueM8}rCm!}|Lj.;Lc_Ϲ^IFo7_lx|AV?a{\8r]eӻ O?d9_}{zV3EEeR|?wSyYċj=v1M*{p+04}[YӴOCIԻ5rv2LJzJ\>UvK %Wutqq Ͼ,0Q;<~ދ9-da~EH/ja4y*oUd7ѭD yU8;jW?d]0 4 7x__3~,{C2#ҡ7C1n?~!Ox/>/4~<Ž L|(oͰ7Lb嵤vRDGPNOk~:rױQ]orXrvegy3I^=K\=Ӷd{kbX2z[{*=Fx2ҳ:ggLb,i2w>i2Y ~ ӌ_e7\yi~֟/G|ۛ/E:k?9V9f/E-X\ '#lU_D>,&p{קyyx5lISr GQ9wE9*CkBB>S(=.'pr+Juŭ0\0Řgvխ|~bsr|g* ~sE_]nyޛFGK6b=W>r;Al*$Nc7w|D/d՜;˶I+:Ylrj,\zźOL+ |A_%M?: .K"^VA/-*Cka4Kr߲%EA^?fm\[|-Q<Jtn#",{}1;oxVSw:S~lg~ɖ1zK3?MӰ "|4>w|D9J`SN WWZz}EI|"P_T.'.I:.G .uECg]qWR& 9-}܏g 7O.y;>|a%"0SIӑ:?ʛOx8?y>?eB9ys-lǟ4Tx3cjo&p8 =?4[ivy)_]ҏ[N/+oWc/^6M9~w F^,i:)0GeqD<ρ\rh}xX+ dh-M#v?H8z~MigyOkJ_8u1n1٨}?ᜈ<4MǛy!%c'FƾGqһEze~J)^SqޱPujߋ:}U_'p_Y026SD˩j0Cʗ)^wUMOl=RMQޏ#Eݛ%K #oc2\(6TR?l|P<_|=R|ouM[af o꣘Geǿ!ngy.;+~ޏ奵Y'7}a_]aqpȃpx{Fa|oZ4m>9w;̊bBFwR_7^_EӪtC \ѫ׈ݳ1|ݥoSb|2J9~<~Ql~l/>{ez-Pȁ<%rٳ9cڼ{{.O=uOלnI׈Ko;O\p#׾whGGv9j\M<3,xVO{[Z'zƕ4;%MPrDsPe!YG/4yegΜgʞ_0{3/#'(66k>`B >1Q[p{)QCߏ5$~ҪG 7`y{}v=߉no7n [yM؊xVz/ϩ<تgQOheM۵Dq?sTymn=͑omIS:5;a=Z!#mr%ҷ8׼;soAGtvʗN]ۛ{TxU9|wX/Y~VyonaWt=/2 Bޥe/%mz |x^=I9.[aed%MhqqeM瘡؟x^ODtҟ˃OGsu4PW8뀞iSufV%nG,AoUdiQaėRˤq&x?LϊM/!r)D=zO'&KFyg푠Fy,=˕+mr'o>Ï6#S*wu/k߇TmIF.hZ\i^"G'=`}ͮ`9/~ zEQ7K[~ۡ؏y8{b`#Aq.69 l2sPȥDh-}?vC}w~D[g iz?YK&>g~}Ҙq*C@J͚a_-I{ܛJ-Ij?I#~eGܶ+9 /ml3 ?+y-N}E|"?SP?q} TDCg\;n'8  5zEԻE+ɴ|g%M?vG릓~!qrDݰxX~8;Raaq?H+47~)M(MNji>[YS^+~2y-hG6 T-J▸'|jи _y0g<9 r?kc$q7nqaE nƯZF~6ݵ}Er~Nt>olW1~'꾷xQ7i?=/̺6xԮP:9}_F>)/3luW4J=6eX` C?'j #]㏋Xiff-y+f2Edz^pդzI*7UMyx.G#^oT| (ny|n{_^c؟DyP' qoH?]}iώ.UtCebDu?1|ݬ6MQ^V;~ntae"^6A鼴YqL!2;lae6?rW #nE0y="t?5ާQr6|;z8~"z|bKݡ>?:ӗd9uEŽy2 ;_[`HygEnL[fcpoUE¯}@%ne~ppתi jړf}_"9sMOЬ4? YtoŵxDO%})oh8Z%!0-eA'd{RtlmxU|ibi185󼮫S9O5z>Q 06*hQ|#B߹Һ!3M;<((ԉG{=DC%':[_?] T`y{E9I?W7}x+8 #߂RwC~mm=9u=#U'n'Uku+9' -=o E\{E<釾}#Y8#ȿ*2H7U?&5q tfbzjezcw3q+ {E&3?Q("X{+Y+iwx+Yv{}y x})\.[2MQ*YW,47gohKY]1Ca8V{tja<0lE 0OV&M{]p>3)W-jDxy[adS:/m-kDZA>V7F4ՇoDVy|JXMKrޣ/h)rITDGf$^Wt%ne"5|zب&2GOF~֧ODkƞ>u%Ri|z(Enj?vİ<)ZsyYg |NG^8zƄk0Ύh*%gp) 7&@QWe9_5?'t<x)ǟoƕ-36bhZYʝG|O(>󓽎@=ݟmم?LG||U:Oѝa+<4U'd -yi-=5 +ɸioqi=-~žW7܍2?T秒743si;ݡ9J=ex>Z7!oQبšrYQ\o'K/ln{WuMܨR<+jW}#|-洧{ZvefebH223iGӽxv*Ã+d&-qߧU\JhC?> ?qqR3O+x_k}UH=7)[J\2-~szA9.k<@J=۸a:ui/s<9d _^G/eX}VK[b+Wx[ؕ|2vyޛkۑ>CƗͮ*CL!uG2h:K@V5Fĵvw}~zq47χzۨ}>q 4]C50b*_f~#׿벳vM Y-Ϥ~Y5u.Su-fzk{[U >hG&)ڳ=j_ߢ)).;:3HߐO@4g:[f绫?wGI#}o#/|Vyk~*i:D5VOQ览|B qǠ|5w>r}_dShTnd~۾ú ~KS3S9ꉯfJ:ȳQkla|E2+gz} vѣp>np:::iUWjY~9?-4[a䵹O9 y }R.~U7ޱ轪4oF|߯[x[vQ8|u|q#4062Hm_}<4ɲ/.P_#pR(~d͇\J9#D<9l{KS%ܪGAޑbb~΃f{њW.Be ^_~T*Ck4oeph4΅> gkƝaoQמFxť >mHjHYZ0vh5roG\;ZU7h^;ޱ]Sۄ(ڢH ((iJ6J<(]]PPǜ]Vy(GSs6EcB^>,|$Ϲcq#}r!wX8('ߤGQɴKd?? ۖ`džp]xn/LSҒMa~.S~?zcc%+T?+WW˗"O3Ep燯17׋uN?i8:s40/W!ot^ڬz ɼ,k26c~&6k;}n}]ޮ>xPjIsz $ne8Z$uX~yլ~=u_^5 TOcƕaŗƗ-Eu%=?,גZߨ:@]T]ȕ%n$Vh:@T/?ؗF+F^koѡא3^63g5=k!BNHd003#\9*8ymv@ߥ˷k_7kD|w@h_ǯmzcShgxJg~/YY}Ns^yq*/Cdmv }#b( SdղZ?+2O{_k[}Ž~MN~g!#ϊ_,{p{UH<x\'O=Q<>Z)'z5T~8Mc^:gq=!x_x_"{?VIkzE>oU>%R,m%iO/~Z[>? sxJ =F'.и ɷ)25PK ?e,{}?O+θonp{8WGiZy~Rv4sL=|8p8 C\Wg F^Ǧ=AJͺpj?eB&g')8;sA/wu!'~Dz{-{{'_z/mս$qE':K_xIw=]!oW|t^3g:OLΗ{d.&W_r7֯ҽ=:[}ey xE2;GݥV8ebnبUlU f,z^~ĭ068+CDGฎFP?1/!0yK@pX|6QK۫'oy%nQ}wx I4+sy+iژd➏63/qEz> ;[USFyۛrexx*G+u|Pg}oJF ͎_T.i> 矵C$%;2'=UwU 3 ..0Sە9 ~g{K" _3[aeLʋ4Yg/P^xg-’B7ZKӈ>_X'$'^6ѓEZYP?w:GB9 o}擋J~okʆX>_,6ϫ|?Jeq%/#oH鼴Y#C~rޙQ=g)V`񁽷@>' 9~i38|J3q`mĵk3MWc"ߓ9fzxUISogF~s֡2 ?ﲵ}|v+ԥۤ *Kh߿^SAԧ{@M;36wNuCxca֏>|h> {a|6͊v Zzݶ`gSm2yo,ڣ(=_DF\q^P;eCzVy!7.ijՙ!i-pby5<.[phr|:Ox~;.0 =qvD3:DJOpҷ@7SdUd9i=gSͳH? Ssc #oO_\7DǙymo`=CJhM1.~ISͻh}Sɻݻs1 TPtt>v^J¾pB 釬h]_|K?&|9qEܟ/x"#NC~/yaKոxZ[/}oyic尤e^WNE:+M|5IpS;<0_č\:8C+6׾WtIZҔGOӸr#t~!s1@743^wUM, ^p<+:NJ6s;?-7x4~K3N,9IVyhsǒ+Gz(7B:W"KӤzEL_M>>W|oD<:5~r㚈-Rw>#'9w->?OdyZù?#>VM}]ϕ{FƄ~ y,~h>1-d>#pn$<іj_y+tdZ׾QqǴ1ū}Yٛoo/i:\J[<44UISևlZU"]x7\D8 ǔ;UuW[2; 7Z8 4T_O5hfKfigȗԎ%7+ɧrPS~G(8?jߠv+|~/j?C/gx^r(~uPu8f3@Qz㏋۵ƕ[3+)ԎOdzv׎4!'sRḾoy:s٩ $sѽGwCu_<'.7Km\j,qΏcė/XCC[<૤) ˕tio?ٶz쀹 q}sc_嶿A"9+ov@FF}0gtro܆.)GX Z/<$^j֗;m_Ӹ ]}kHǧN'i,GrOqm'u'~xWR?YWeS:oeI e+Jo9mEu F~h':}OAY9f_dd?WL+0J(DcZGNg9ѦJҋiJ_*h^02&/o/㿱pca@+[I_p~q .[@}vWp]▹/@ ^u$7z<OH[aߖ/RȒ7'孖^W1P*݆1P/y'c78֫#K(i yDP6Eh+R 1rpN7xd=2d] J=p֫b8"+|EEK/5ub(=r@-*Cka4bP;e n{%˿/UÍOO<(S߿)pm,z[a䭹t_;y1I:NOΓK|EW=ex9orqj[}nRqw%JXlRuaፂ[3%M hnz?Y. }>w}I5?E5{jT]Rd+4%\ӵ7v ne(`]J^_ϔkIS:s|GGv^/lԾ^wD1@oI"p2Wh^nv+~1o~hk@~'7!&>6v?]/Ǘ>4?>0v:8ms͵Wi+H╌'ree]i91|>;z9 \ #/͵O5v^ɟÌ7sn九Vju_e~we{Ot=!ۓח*u"VTEbk~zx+ތzq5=~D:/mf>I5it|E屉W9J}c"e_ ][fݧR]?BZĭTe-e  #͈lZ>6c{V~|9*×+Ma\vl>(u_?=Xv|ҟ2xIϣ5ӌgù㫟TT{ׄln><}xUQ {Cdi Or簰:m E~'>ZK~?)pSnnOGcS Z_/2?֗QЌdq-ٔKuJ\/i?A:/v^ߍOθ=W n2u?>p^BM<| 9͞ke;vj=X~6xziofdGi|Es/&:_WH-sws~ 7F]{KrL{>82ْå)rGI+WHˡwfʗ/w ;dQ G7 q!UqfCNWiyEvIN(X?V #c>8>JjQ.eɚmygʼn|A:&Z6_m*^Phx+}t}> b??@ɕc?yZO-^wz|$]7}, !qu4w^[w*Gʹ OYO^Kh=R4sOGk]Ѥoq:R{˫D] t{xK[}q>zw+y%MO6ٻec|-r]9JJW|/3^{@w|#'>-xna{hJ '?|qr䎏%sqw6-N7Wf+4Z_ ;Êy84~?+G+MקfÒԟV~cF4$~2,ޚOpx}h]#~>FFk Q+ \{?,0`sͲFdQk<4Eh= SsUML]1A7)?=}eG #ocޜ/΅cqeJ Ib蠦s*Cki B>_t^S;>OҺ'WFgp֛W-X|JKf8#gxwF9 ѷcegW,$_퓾Zz}Kъtc~ylV{_8Z0y p}kqK2CH?$NÞƜN݁Q{ rc\>?r /۸Aq^v9.N?K_iUlAϖG||>vϿ_*\ 1}2yiY:+F=lG=gu﹢Wsֈ>DK߇TKm?1#Vʷ.3"4nyy{p%LCOF; !wQ8U'yw4lW Trh5#UZ7m q0:& Xp`՟1+ ͪ<Km._;.nLKĝzmN[Do;Z^q3|rPEuNEȌ=Q y߉ +#Wfl% WkJ?=2MWhNSoo''={soh C^eISsCGC.I4uտ_1?&_~d{Zt݁>i?O JVߢEԞM_qhf皎zYIy4o"(C dN2h~Qm3 h-M#NL~*1PtO}?*]phY|LQ3|"I=srX[U/*_gb/z6NmtgGlIS:Ob8r"˗y[EӪܹ*;nׂrn^}dq{8v>[ɦv6@Jh?..@~.$RCZxOmVkF <&Ot|7*aǟy<&Qԧ,^Q}ާoJޚ?kyiy뛥i 1K,!h=Xy c)7^?Ru/mo'[" jړWrW # ._?~/UO6+_'O?TQ-Hqb96s ŋ9GA+njڏ8ƾhM g@X|6/hX 7SA`q2SWp=%N К;7yQ3vr/* %ҟË-}?Bbj?C#~uurKL_)9 ċ[audBu~dwuj -Gq| %ҟSxyԇTKq v?F[}s_jٿR6WJN;59C<{˚1 nEFo+]_E*0ybGS FSZ~9C ;U,?F]j^U}%YWx+4#eC_`OѨ~/La8/v~Oi[Q4!s#w=+gih~ D| 2 j#{Cʼen!W/x5CC5`Ma䭹f#Z)63gBgMQ׃clq}(v6c`8sG>{uF6m-i:8}7)"ߣ4F\3xSi?ߕ[bHrLHsgcww ~rnѻ_=u䫯~~}?9Ҵk8jwܸX9b`#̟֧E+: ֣E+.mOMn43B x}>|/%?Q瓾44/|ӎӻ~Gy9-76=E G/m91{wQCW/z~B#2~G7>kRoMȯĠv ??=duz"%6_q;(7:7Bx6)?zfo7\Nq1?4,-'P/B8}c7o@/q=~ 4W0A7a9B}1ӿ.:^w@֒iL4+1ui}:G~i>O|wHv-aSLܽBҷ^}I2N>S.#4mfkv#FS d'K_F=G>%/MTAO߄ULܸ~8 0>Q @ zti~ ~s=2[ni冴 I\<Կ~Ex_Ư(%Z7"-7\K Gxw6?ϧvpM9>C6OHȠPsx5ad8_а03/_{z򖿰%6VP B҇٨>هFRM )[bHs.`C|= wأMa{/}o|{ϼCqiB2گaQC7$=H}ۥ{Gۥ7WK4}Xfz^ܶ՚Rp&N]g>/'K1}} 'Qr{ykf( Hߘ٣s7u}ɀ}8}NZgj\iG [~~+!RQC^%{x2/?oѼȧ]|oѼȣ}W$[nerN|jL]x@_| lCzl|˄u5k'f-7 4a}OKh~O8ގ zxoCd ֔`/ȓ=?#iތOPАyǖ@Km7cT{3CP.U~~% 2~TϊZS1ҥ:=O꼧Xz~B_&ǟf`i i}OmPSX&ibȞ+H|8~?yvqŽmF=s#_xo}[̡4KlE"|PH_/\wx Q|`O8/qA'H/"}'2tc*Mj1\/W|s^ɳYK^Ըئl{t lY7Gˬ 5FAéO;c9ҧ?#To.8 )3j k_Eݫ ^8Ob&>3[~}=ARC\ѵ0'{bh?<0䳢zw#R]GduDxVnyƮ}2>7ηS!_Y8 69\R߷Cq`ƹ9!;na>&P?XcW:_9*I\ L`klQGXWKaW,h8><^>cx|z=W)zoT649Ѹp^:AQ'j]D{kGE]4ZG㘦nُN l?Ϡ)j۫s3|&Ťo~+z}Jop:iR׿ɹNLVv0.\y8sӕS:?NBѺM4NJQGUXzh&/<ʇއYz}I`=H 4~w1/4 n74O,P/d~vnݏػqst 6/ hxK )3seLm~Mm~(<e #~"/NE*hsx@`c٪`Oj;3}n}0J?E~QEÉ~kx䁏m8?0]e+`BU3v-Ξl'XzUcX5GW6ۋ? ڋ|򂆦. h]ZZI-dRWף3jU\|@]7_*oW8 }B{Lڋ0.)Kvb W?z>ufCW/z:34{ rJV^No߂CyhG4oP! "]牾Sr滍wXgkY0:+n{_PvxI=%7H2r\{oAÜ' ^a@Q?^K֋d@7^h~2vB0s^-Pҗ>Nλ~Seק u&u>ŜpnCky}{/6ߚ !<\G[NùΖqv5o=~ 3X0_atM:+7}}/xeo9<3SỆ/KOjfͧ^q׃=yypU?f-ecE6>Yz9ÌSrïg/q8eisɏ?#* 8 |>8pp/?;U xN^H;<]HM[r>Y\XblZ/C/{w/_[kՋ,=?r{ď,wlb'v*x]}⻻ŁY#WW՟j0IF}oC9{7[=dG9pɳw;Ԛ)X,ڹ(w>G_D#IfגgZ6~GX`?ccpFq󘿎8=]8Q;\7fmZO.o9'@GAC''} I*?eVÄg?x~}=.?!?wf/g~ipF} ̻rH=d~!3_oE!_j/4^f^6cR+П]g S;Kg0asD8Ic!^z>M{on| ۗyD{ dz򶽇lX>"_ev|iX$|gwl㿨D~9#D۟,8H7׌fc?WՈ71'㊝ڡjإٌ)'o:]KM`,#z[.װ*5$kuD$qz6:\NU~u}دȧ|&2~_)?x`c̟_*|]y;.-{o ~ȷγ`^ӊ_&?'2q_Y㿢v%ZoI>R?=/n}S|qf`}G/ }_x͖yR;4 }|l,:H>*aW@S|U`R \W+^:=9%EzKo~\VKϏ+Gwq,e0:XɓR8IPlceFX-qPwW oxvW<twq&Eo=GU(C= UfO&}3d\_/a{Wo䓫wm$>/d}K11zvR@Q: 봮|@inf""_<^~*s&^)iV;Sa~unݫw|Wꋷɋ\n;wZjzӽ?{Ekm"n~W{v*houZ7ӾhMrss7}M3}κn??=::ξ: ͠ޒo#oڏ^+WXykZ;VGގYwuq]Tg9ͭWÀK::;ޱ 7Vrn\v׊;VXqgADW)Wo/Wvtt3[;g3?#L#ikcutpointr/R/0000755000176200001440000000000014066411540012503 5ustar liggesuserscutpointr/R/oc_youden_normal.R0000644000176200001440000000540113475240564016173 0ustar liggesusers#' Determine an optimal cutpoint for the Youden-Index assuming normal distributions #' #' An optimal cutpoint maximizing the Youden- or J-Index #' (sensitivity + specificity - 1) is calculated parametrically assuming #' normal distributions per class. #' #' @param data A data frame or tibble in which the columns that are given in x #' and class can be found. #' @param x (character) The variable name to be used for classification, #' e.g. predictions or test values. #' @param class (character) The variable name indicating class membership. #' @param pos_class The value of class that indicates the positive class. #' @param neg_class The value of class that indicates the negative class. #' @param direction (character) Use ">=" or "<=" to select whether an x value #' >= or <= the cutoff predicts the positive class. #' @param ... To capture further arguments that are always passed to the method #' function by cutpointr. The cutpointr function passes data, x, class, #' metric_func, direction, pos_class and neg_class to the method function. #' @examples #' data(suicide) #' oc_youden_normal(suicide, "dsi", "suicide", #' pos_class = "yes", neg_class = "no", direction = ">=") #' cutpointr(suicide, dsi, suicide, method = oc_youden_normal) #' @family method functions #' @export oc_youden_normal <- function(data, x, class, pos_class = NULL, neg_class = NULL, direction, ...) { stopifnot(is.character(x)) stopifnot(is.character(class)) iv <- unlist(data[, x]) if (any_inf(iv)) stop("Only finite values allowed in oc_youden_normal") cla <- unlist(data[, class]) if (direction %in% c(">", ">=")) { patients <- iv[cla == pos_class] controls <- iv[cla == neg_class] } else if (direction %in% c("<", "<=")) { patients <- iv[cla == neg_class] controls <- iv[cla == pos_class] } m_h <- mean(controls) sd_h <- stats::sd(controls) m_d <- mean(patients) sd_d <- stats::sd(patients) if (sd_h == sd_d) { c <- (m_h+m_d)/2 } else if (any(sd_h == 0, sd_d == 0)) { # if sd_h = 0 and/or sd_d = 0 the cutoff would be NaN c <- (m_h+m_d)/2 } else { c <- ((m_d*sd_h^2 - m_h*sd_d^2) - sd_h*sd_d*(sqrt((m_h-m_d)^2 + (sd_h^2-sd_d^2) * log(sd_h^2/sd_d^2)))) / (sd_h^2-sd_d^2) } # Extremely high or low cutoffs can result if m_d < m_h and direction = ">=" if (c < min(c(controls, patients))) { warning(paste("Cutpoint", c, "was restricted to range of independent variable")) c <- min(c(controls, patients)) } else if (c > max(c(controls, patients))) { warning(paste("Cutpoint", c, "was restricted to range of independent variable")) c <- max(c(controls, patients)) } return(data.frame(optimal_cutpoint = c)) } cutpointr/R/print.summary_cutpointr.R0000644000176200001440000000540613764644226017607 0ustar liggesusers#' @export #' @importFrom tidyselect any_of print.summary_cutpointr <- function(x, digits = 4, ...) { cat(paste("Method:", x$cutpointr[[1]]$method, "\n")) cat(paste("Predictor:", x$cutpointr[[1]]$predictor, "\n")) cat(paste("Outcome:", x$cutpointr[[1]]$outcome, "\n")) cat(paste("Direction:", x$cutpointr[[1]]$direction, "\n")) if (has_column(x$cutpointr[[1]], "subgroup")) { cat(c("Subgroups:", paste(purrr::map(x$cutpointr, ~ .$subgroup), collapse = ", "), "\n")) } if (has_boot_results(x)) { cat(paste("Nr. of bootstraps:", x$boot_runs[1], "\n")) } for (i in 1:nrow(x)) { cat("\n") if (has_column(x$cutpointr[[i]], "subgroup")) { cat(paste("Subgroup:", x$cutpointr[[i]]$subgroup, "\n")) cat(paste0(rep("-", getOption("width")), collapse = ""), "\n") } tempdat <- x$cutpointr[[i]] %>% dplyr::select(.data$AUC) %>% round(digits = digits) %>% dplyr::mutate(n = x$n_obs[i], n_pos = x$n_pos[i], n_neg = x$n_neg[i]) %>% as.data.frame() print_df_nodat(tempdat, row.names = FALSE) cat("\n") purrr::map_df(1:length(x$cutpointr[[i]]$optimal_cutpoint[[1]]), function(j) { x$cutpointr[[i]] %>% # dplyr::select(-c(direction, method, AUC:boot)) %>% dplyr::select(!tidyselect::any_of(c("direction", "subgroup", "method", "AUC", "pos_class", "neg_class", "prevalence", "outcome", "predictor", "grouping", "data", "roc_curve", "boot"))) %>% purrr::map_df(get_fnth, n = j) }) %>% as.data.frame %>% dplyr::left_join(y = x$confusion_matrix[[i]], by = c("optimal_cutpoint" = "cutpoint")) %>% round(digits = digits) %>% print_df_nodat(row.names = FALSE) cat("\n") cat(paste("Predictor summary:", "\n")) print_df_nodat(rbind(x$desc[[i]], x$desc_by_class[[i]])) if (has_boot_results(x[i, ])) { cat("\n") cat(paste("Bootstrap summary:", "\n")) print_df_nodat( x[["boot"]][[i]] %>% dplyr::mutate_if(is.numeric, round, digits = 2), row.names = rep("", nrow(x[["boot"]][[i]])) ) } } return(invisible(x)) } cutpointr/R/oc_median.R0000644000176200001440000000153213475240564014556 0ustar liggesusers#' Use the sample median as cutpoint #' #' The sample median is calculated and returned as the optimal cutpoint. #' #' @param data A data frame or tibble in which the columns that are given in x #' and class can be found. #' @param x (character) The variable name to be used for classification, #' e.g. predictions or test values. #' @param ... To capture further arguments that are always passed to the method #' function by cutpointr. The cutpointr function passes data, x, class, #' metric_func, direction, pos_class and neg_class to the method function. #' @examples #' data(suicide) #' oc_median(suicide, "dsi") #' cutpointr(suicide, dsi, suicide, method = oc_median) #' @family method functions #' @export oc_median <- function(data, x, ...) { stopifnot(is.character(x)) return(data.frame(optimal_cutpoint = stats::median(unlist(data[, x])))) }cutpointr/R/plot_cutpointr.R0000644000176200001440000002305513764660457015741 0ustar liggesusers#' General purpose plotting function for cutpointr or roc_cutpointr objects #' #' Flexibly plot various metrics against all cutpoints or any other metric. #' The function can plot any metric based on a \code{cutpointr} or \code{roc_cutpointr} #' object. If \code{cutpointr} was run with bootstrapping, bootstrapped confidence #' intervals can be plotted. These represent the quantiles of the distribution #' of the y-variable grouped by x-variable over all bootstrap repetitions. #' #' The arguments to \code{xvar} and \code{yvar} should be metric functions. Any metric #' function that is suitable for \code{cutpointr} can also be used in \code{plot_cutpointr}. #' Anonymous functions are also allowed. #' To plot all possible cutpoints, the utility function \code{cutpoint} can be used. #' #' The functions for \code{xvar} and \code{yvar} may accept any or all of the arguments #' \code{tp}, \code{fp}, \code{tn}, or \code{fn} and return a numeric vector, #' a matrix or a \code{data.frame}. #' For more details on metric functions see \code{vignette("cutpointr")}. #' #' Note that confidence intervals can only be correctly plotted if the values of \code{xvar} #' are constant across bootstrap samples. For example, confidence intervals for #' \code{tpr} by \code{fpr} (a ROC curve) cannot be plotted, as the values of the false positive #' rate vary per bootstrap sample. #' #' @param x A \code{cutpointr} or \code{roc_cutpointr} object. #' @param xvar A function, typically \code{cutpoint} or a metric function. #' @param yvar A function, typically a metric function. #' @param conf_lvl (numeric) If bootstrapping was run and x is a cutpointr object, #' a confidence interval at the level of conf_lvl can be plotted. To plot no #' confidence interval set conf_lvl = 0. #' @param aspect_ratio (numeric) Set to 1 to obtain a quadratic plot, e.g. for #' plotting a ROC curve. #' #' @examples #' set.seed(1) #' oc <- cutpointr(suicide, dsi, suicide, boot_runs = 10) #' #' plot_cutpointr(oc, cutpoint, F1_score) #' #' ## ROC curve #' plot_cutpointr(oc, fpr, tpr, aspect_ratio = 1) #' #' ## Custom function #' plot_cutpointr(oc, cutpoint, function(tp, tn, fp, fn, ...) tp / fp) + #' ggplot2::ggtitle("Custom metric") + ggplot2::ylab("value") #' #' @family cutpointr plotting functions #' @export plot_cutpointr <- function(x, xvar = cutpoint, yvar = sum_sens_spec, conf_lvl = 0.95, aspect_ratio = NULL) { if (!("cutpointr" %in% class(x) | "roc_cutpointr" %in% class(x))) { stop("plot_cutpointr only supports cutpointr and roc_cutpointr objects.") } if ("cutpointr" %in% class(x)) { rocdat <- x$roc_curve subgroup <- suppressWarnings(x$subgroup) } else { rocdat <- list(x) subgroup <- NULL } xvar_name <- paste(as.character(substitute(xvar)), collapse = " ") yvar_name <- paste(as.character(substitute(yvar)), collapse = " ") xvar_name_plotlabel <- xvar_name yvar_name_plotlabel <- yvar_name rocdat <- purrr::map(.x = rocdat, .f = function(x) { met <- xvar(x = x, tp = x$tp, fp = x$fp, tn = x$tn, fn = x$fn) met_name <- colnames(met) if (is.null(met_name)) { met_name <- xvar_name } else { xvar_name <<- met_name xvar_name_plotlabel <<- met_name } met <- sanitize_metric(met, m_name = met_name, n = nrow(x)) met <- check_metric_name(met) xvar_name <<- colnames(met) met <- tibble::as_tibble(met) class(met) <- class(x) # Avoid warning from vctrs x <- dplyr::bind_cols(x, met) x }) rocdat <- purrr::map(.x = rocdat, .f = function(x) { met <- yvar(x = x, tp = x$tp, fp = x$fp, tn = x$tn, fn = x$fn) met_name <- colnames(met) if (is.null(met_name)) { met_name <- xvar_name } else { yvar_name <<- met_name yvar_name_plotlabel <<- met_name } met <- sanitize_metric(met, m_name = yvar_name, n = nrow(x)) met <- check_metric_name(met) yvar_name <<- colnames(met) met <- tibble::as_tibble(met) class(met) <- class(x) # Avoid warning from vctrs x <- dplyr::bind_cols(x, met) x }) if (has_boot_results(x) & conf_lvl != 0) { # Add xvar and yvar columns to ROC curves of bootstrap repetitions for (i in 1:nrow(x)) { x[["boot"]][[i]]$roc_curve_b <- purrr::map(x[["boot"]][[i]]$roc_curve_b, function(x) { met <- xvar(x = x, tp = x$tp, fp = x$fp, tn = x$tn, fn = x$fn) met <- sanitize_metric(met, m_name = xvar_name, n = nrow(x), silent = TRUE) met <- check_metric_name(met) met <- tibble::as_tibble(met) class(met) <- class(x) # Avoid warning from vctrs x <- dplyr::bind_cols(x, met) met <- yvar(x = x, tp = x$tp, fp = x$fp, tn = x$tn, fn = x$fn) met <- sanitize_metric(met, m_name = yvar_name, n = nrow(x), silent = TRUE) met <- check_metric_name(met) met <- tibble::as_tibble(met) class(met) <- class(x) # Avoid warning from vctrs x <- dplyr::bind_cols(x, met) x }) ci <- x[["boot"]][[i]]$roc_curve_b %>% dplyr::bind_rows() %>% dplyr::select(!!rlang::sym(xvar_name), !!rlang::sym(yvar_name)) %>% dplyr::group_by(!!rlang::sym(xvar_name)) %>% dplyr::summarise(ymin = stats::quantile(!!rlang::sym(yvar_name), (1 - conf_lvl) / 2, na.rm = TRUE), ymax = stats::quantile(!!rlang::sym(yvar_name), 1 - (1 - conf_lvl) / 2, na.rm = TRUE)) rocdat[[i]] <- dplyr::left_join(rocdat[[i]], ci, by = xvar_name) if (any(!(rocdat[[i]][[xvar_name]] %in% ci[[xvar_name]]))) warning(paste(x$subgroup[i], "Not all x-values in ROC curve could be joined with bootstrap,", "the bootstrap confidence intervals are possibly misleading,", "see ?plot_cutpointr")) } } if ("subgroup" %in% colnames(x)) { rocdat <- purrr::map2(subgroup, rocdat, function(s, d) { d <- d[is.finite(d[[yvar_name]]), ] d <- d[is.finite(d[[xvar_name]]), ] d$subgroup <- s return(d) }) %>% dplyr::bind_rows() if (has_boot_results(x) & conf_lvl != 0) { p <- ggplot2::ggplot(rocdat, ggplot2::aes_string(x = xvar_name, y = yvar_name, ymax = "ymax", ymin = "ymin", fill = "subgroup", color = "subgroup")) + ggplot2::geom_line() + ggplot2::geom_ribbon(alpha = 0.2, size = 0) + ggplot2::ggtitle(paste(yvar_name_plotlabel, "by", xvar_name_plotlabel), "in-sample results") + ggplot2::ylab(yvar_name_plotlabel) + ggplot2::xlab(xvar_name_plotlabel) } else { p <- ggplot2::ggplot(rocdat, ggplot2::aes_string(x = xvar_name, y = yvar_name, color = "subgroup")) + ggplot2::geom_line() + ggplot2::ggtitle(paste(yvar_name_plotlabel, "by", xvar_name_plotlabel), "in-sample results") + ggplot2::ylab(yvar_name_plotlabel) + ggplot2::xlab(xvar_name_plotlabel) } } else { rocdat <- rocdat[[1]] rocdat <- rocdat[is.finite(rocdat[[yvar_name]]), ] rocdat <- rocdat[is.finite(rocdat[[xvar_name]]), ] if (has_boot_results(x) & conf_lvl != 0) { p <- ggplot2::ggplot(rocdat, ggplot2::aes_string(x = xvar_name, y = yvar_name, ymax = "ymax", ymin = "ymin")) + ggplot2::geom_line() + ggplot2::geom_ribbon(alpha = 0.2, size = 0) + ggplot2::ggtitle(paste(yvar_name_plotlabel, "by", xvar_name_plotlabel), "in-sample results") + ggplot2::ylab(yvar_name_plotlabel) + ggplot2::xlab(xvar_name_plotlabel) } else { p <- ggplot2::ggplot(rocdat, ggplot2::aes_string(x = xvar_name, y = yvar_name)) + ggplot2::geom_line() + ggplot2::ggtitle(paste(yvar_name_plotlabel, "by", xvar_name_plotlabel), "in-sample results") + ggplot2::ylab(yvar_name_plotlabel) + ggplot2::xlab(xvar_name_plotlabel) } } if (!(is.null(aspect_ratio))) p <- p + ggplot2::theme(aspect.ratio = aspect_ratio) return(p) } cutpointr/R/plot_precision_recall.R0000644000176200001440000000501113766660360017212 0ustar liggesusers#' Precision recall plot from a cutpointr object #' #' Given a \code{cutpointr} object this function plots the precision recall curve(s) #' per subgroup, if given. #' @param x A cutpointr object. #' @param display_cutpoint (logical) Whether or not to display the optimal #' cutpoint as a dot on the precision recall curve. #' @param ... Additional arguments (unused). #' @examples #' library(cutpointr) #' #' ## Optimal cutpoint for dsi #' data(suicide) #' opt_cut <- cutpointr(suicide, dsi, suicide) #' plot_precision_recall(opt_cut) #' @family cutpointr plotting functions #' @export plot_precision_recall <- function(x, display_cutpoint = TRUE, ...) { if (!("cutpointr" %in% class(x))) { stop("Only cutpointr objects are supported.") } args <- list(...) if (!(has_column(x, "subgroup"))) { dts_pr <- "roc_curve" transparency <- 1 } else { dts_pr <- c("roc_curve", "subgroup") transparency <- 0.6 } plot_title <- ggplot2::ggtitle("Precision Recall Plot") for (r in 1:nrow(x)) { x$roc_curve[[r]] <- x$roc_curve[[r]] %>% dplyr::mutate(Precision = tp / (tp + fp), Recall = tp / (tp + fn)) } if (display_cutpoint) { optcut_coords <- purrr::pmap_df(x, function(...) { args <- list(...) opt_ind <- get_opt_ind(roc_curve = args$roc_curve, oc = args$optimal_cutpoint, direction = args$direction) data.frame(Precision = args$roc_curve$Precision[opt_ind], Recall = args$roc_curve$Recall[opt_ind]) }) } res_unnested <- x %>% dplyr::select(dts_pr) %>% tidyr::unnest(.data$roc_curve) res_unnested <- res_unnested[is.finite(res_unnested$x.sorted), ] if (!(has_column(x, "subgroup"))) { pr <- ggplot2::ggplot(res_unnested, ggplot2::aes(x = Recall, y = Precision)) } else { pr <- ggplot2::ggplot(res_unnested, ggplot2::aes(x = Recall, y = Precision, color = subgroup)) } pr <- pr + ggplot2::geom_line() + plot_title + ggplot2::theme(aspect.ratio = 1) + ggplot2::coord_cartesian(xlim = c(0, 1), ylim = c(0, 1)) if (display_cutpoint) { pr <- pr + ggplot2::geom_point(data = optcut_coords, color = "black") } return(pr) } cutpointr/R/boot_test.R0000644000176200001440000002223013717554410014635 0ustar liggesusers#' Test for equivalence of a metric #' #' This function performs a significance test based on the bootstrap results #' of cutpointr to test whether a chosen metric is equal between subgroups #' or between two cutpointr objects. The test statistic is calculated as #' the standardized difference of the metric between groups. If \code{x} #' contains subgroups, the test is run on all possible pairings of subgroups. #' An additional adjusted p-value is returned in that case. #' #' The variable name is looked up in the columns of the bootstrap results #' where the suffixes _b and _oob indicate in-bag and out-of-bag estimates, #' respectively (controlled via the \code{in_bag} argument). #' Possible values are optimal_cutpoint, AUC, #' acc, sensitivity, specificity, and the metric that was selected #' in \code{cutpointr}. Note that there is no "out-of-bag optimal cutpoint", so #' when selecting \code{variable = optimal_cutpoint} the test will be based on #' the in-bag data. #' #' The test statistic is calculated as z = (t1 - t2) / sd(t1 - t2) where t1 and #' t2 are the metric values on the full sample and sd(t1 - t2) is the standard #' deviation of the differences of the metric values per bootstrap repetition. #' The test is two-sided. #' #' If two cutpointr objects are compared and the numbers of bootstrap repetitions #' differ, the smaller number will be used. #' #' Since pairwise differences are calculated for this test, the test function #' does not support multiple optimal cutpoints, because it is unclear how the #' differences should be calculated in that case. #' #' @param x A cutpointr object with bootstrap results #' @param y If x does not contain subgroups another cutpointr object #' @param variable The variable for testing #' @param in_bag Whether the in-bag or out-of-bag results should be used for testing #' @param correction The type of correction for multiple testing. Possible #' values are as in p.adjust.methods #' #' @return A data.frame (a tibble) with the columns test_var, p, d, sd_d, z #' and in_bag. If a grouped cutpointr object was tested, the additional #' columns subgroup1, subgroup2 and p_adj are returned. #' #' @examples #' \dontrun{ #' library(cutpointr) #' library(dplyr) #' set.seed(734) #' cp_f <- cutpointr(suicide %>% filter(gender == "female"), dsi, suicide, #' boot_runs = 1000, boot_stratify = TRUE) #' set.seed(928) #' cp_m <- cutpointr(suicide %>% filter(gender == "male"), dsi, suicide, #' boot_runs = 1000, boot_stratify = TRUE) #' # No significant differences: #' boot_test(cp_f, cp_m, AUC, in_bag = TRUE) #' boot_test(cp_f, cp_m, sum_sens_spec, in_bag = FALSE) #' #' set.seed(135) #' cp <- cutpointr(suicide, dsi, suicide, gender, boot_runs = 1000, #' boot_stratify = TRUE) #' # Roughly same result as above: #' boot_test(cp, variable = AUC, in_bag = TRUE) #' boot_test(cp, variable = sum_sens_spec, in_bag = FALSE) #' } #' #' @export #' @family main cutpointr functions #' @source Robin, X., Turck, N., Hainard, A., Tiberti, N., Lisacek, F., #' Sanchez, J.-C., & Müller, M. (2011). pROC: An open-source package for R #' and S+ to analyze and compare ROC curves. BMC Bioinformatics, 12(1), 77. #' https://doi.org/10.1186/1471-2105-12-77 boot_test <- function(x, y = NULL, variable = "AUC", in_bag = TRUE, correction = "holm") { if (!has_boot_results(x)) { stop(paste("x does not contain bootstrap results.", "Was boot_runs > 0 in cutpointr?")) } stopifnot(inherits(x, "cutpointr")) if (!is.null(y)) { if (!has_boot_results(y)) { stop(paste("y does not contain bootstrap results.", "Was boot_runs > 0 in cutpointr?")) } stopifnot(inherits(y, "cutpointr")) } # No boot_test if multiple cutpoints multi_cp_x <- purrr::map_lgl(x$boot, function(b) is.list(b$optimal_cutpoint)) if (!is.null(y)) { multi_cp_y <- purrr::map_lgl(y$boot, function(b) is.list(b$optimal_cutpoint)) } else { multi_cp_y <- FALSE } if (any(multi_cp_x) | any(multi_cp_y)) { stop(paste("boot_test does not support multiple optimal cutpoints.", "See ?boot_test. Try setting break_ties = median", "in cutpointr.")) } variable <- rlang::enquo(variable) variable <- rlang::as_name(variable) # If y is also supplied, x and y should be ungrouped if ((!is.null(y)) & nrow(x) > 1) { stop(paste("When testing two cutpointr objects these objects must not", "contain subgroups.")) } if (in_bag) suffix <- "_b" else suffix <- "_oob" if (variable == "optimal_cutpoint") suffix <- "" if (is.null(y)) { # Test subgroups vs. each other combs <- utils::combn(x = x$subgroup, m = 2, simplify = FALSE) combs <- do.call(rbind, combs) combs <- data.frame(var1 = combs[, 1], var2 = combs[, 2], stringsAsFactors = FALSE) test_res <- purrr::map2_dfr(.x = combs$var1, .y = combs$var2, .f = function(var1, var2) { dat_var1 <- x %>% dplyr::filter(.data$subgroup == var1) %>% dplyr::select(.data$boot) %>% tidyr::unnest(.data$boot) %>% dplyr::select(paste0(variable, suffix)) %>% unlist dat_var2 <- x %>% dplyr::filter(.data$subgroup == var2) %>% dplyr::select(.data$boot) %>% tidyr::unnest(.data$boot) %>% dplyr::select(paste0(variable, suffix)) %>% unlist na_v1 <- sum(is.na(dat_var1)) na_v2 <- sum(is.na(dat_var2)) if (na_v1 > 0 | na_v2 > 0) { message(var1, " vs. ", var2, ": ", "Omitting missing values. Using ", nrow(x$boot[[1]]) - max(na_v1, na_v2), " observations.") } sdt <- stats::sd(dat_var1 - dat_var2, na.rm = TRUE) t1 <- x %>% dplyr::filter(.data$subgroup == var1) %>% dplyr::select(variable) %>% unlist t2 <- x %>% dplyr::filter(.data$subgroup == var2) %>% dplyr::select(variable) %>% unlist z <- (t1 - t2) / sdt if (t1 - t2 == 0 & is.nan(sdt)) z <- 0 p <- unname(stats::pnorm(-abs(z)) * 2) tibble::tibble(subgroup1 = var1, subgroup2 = var2, test_var = variable, p = p, p_adj = NA, d = t1 - t2, sd_d = sdt, z = z, in_bag = in_bag) }) test_res$p_adj <- unname(stats::p.adjust(p = test_res$p, method = correction)) } else if (!(is.null(y))) { # Test two ungrouped cutpointr objects vs. each other if (!has_boot_results(y)) { stop(paste("y does not contain bootstrap results.", "Was boot_runs > 0 in cutpointr?")) } if (nrow(y) > 1) { stop(paste("When testing two cutpointr objects these objects must not", "contain subgroups.")) } dat_var1 <- x %>% dplyr::select(.data$boot) %>% tidyr::unnest(.data$boot) %>% dplyr::select(paste0(variable, suffix)) %>% unlist dat_var2 <- y %>% dplyr::select(.data$boot) %>% tidyr::unnest(.data$boot) %>% dplyr::select(paste0(variable, suffix)) %>% unlist if (length(dat_var1) != length(dat_var2)) { warning(paste("Unequal number of boot_runs. Using the lower", "number of", min(length(dat_var1), length(dat_var2)), "bootstrap repeats.")) lower_runs <- min(length(dat_var1), length(dat_var2)) dat_var1 <- dat_var1[1:lower_runs] dat_var2 <- dat_var2[1:lower_runs] } na_v1 <- sum(is.na(dat_var1)) na_v2 <- sum(is.na(dat_var2)) if (na_v1 > 0 | na_v2 > 0) { message("Omitting missing values. Using ", nrow(x$boot[[1]]) - max(na_v1, na_v2), " observations.") } sdt <- stats::sd(dat_var1 - dat_var2, na.rm = TRUE) t1 <- x %>% dplyr::select(variable) %>% unlist t2 <- y %>% dplyr::select(variable) %>% unlist z <- (t1 - t2) / sdt if (t1 - t2 == 0 & sdt == 0) z <- 0 p <- stats::pnorm(-abs(z)) * 2 test_res <- tibble::tibble(test_var = variable, p = p, d = t1 - t2, sd_d = sdt, z = z, in_bag = in_bag) } class(test_res) <- c("boot_test", class(test_res)) return(test_res) } cutpointr/R/utils.R0000644000176200001440000002661713764455235014017 0ustar liggesusersfind_metric_name <- function(object) { if ("subgroup" %in% colnames(object)) { return(colnames(object)[5]) } else { return(colnames(object)[4]) } } find_metric_name_boot <- function(object) { if ("subgroup" %in% colnames(object)) { return(colnames(object)[6]) } else { return(colnames(object)[5]) } } default_cols <- c("m", "subgroup", "direction", "optimal_cutpoint", "method", "acc", "sensitivity", "specificity", "AUC", "pos_class", "neg_class", "prevalence", "outcome", "predictor", "grouping", "data", "roc_curve", "boot", "tn", "fn", "tp", "fp", "tpr", "tnr", "fpr", "fnr") check_method_cols <- function(method_result) { cn <- colnames(method_result) n_col <- ncol(method_result) identified_cols <- 0 oc_col <- which(cn == "optimal_cutpoint") if (!is.null(oc_col)) identified_cols <- identified_cols + 1 if ("roc_curve" %in% cn) { roc_col <- which(cn == "roc_curve") identified_cols <- identified_cols + 1 } if (identified_cols == 1 & n_col == 2) { metric_col <- (1:n_col)[-oc_col] } else if (identified_cols < n_col) { stopifnot(exists("roc_col")) metric_col <- (1:n_col)[-c(oc_col, roc_col)] if (length(metric_col) >= 2) { stop(paste("method function returned too many columns.", "Should return optimal_cutpoint, roc_curve (optional)", "and a metric column (optional).")) } metric_name <- cn[metric_col] if (metric_name %in% default_cols) { colnames(method_result)[metric_col] <- paste0("metric_", metric_name) } } return(method_result) } check_metric_name <- function(met) { # Numeric vector if (!is.array(met) & is.numeric(met)) return(met) cn <- colnames(met) if (cn %in% default_cols) { colnames(met) <- paste0("metric_", cn) return(met) } else { return(met) } } check_method_name <- function(mod_name) { if (length(mod_name) > 1) { if (mod_name[1] %in% c("::", ":::") & length(mod_name) == 3) { mod_name <- mod_name[3] } else { stop("Could not parse method name") } } return(mod_name) } check_colnames <- function(cutpointr_object) { if ("subgroup" %in% colnames(cutpointr_object)) col_nr <- 4 else col_nr <- 3 metric_name <- colnames(cutpointr_object)[col_nr] if (metric_name %in% default_cols) { metric_name2 <- paste0("metric_", metric_name) colnames(cutpointr_object)[col_nr] <- metric_name2 cutpointr_object$metric_name <- metric_name2 } else { cutpointr_object$metric_name <- metric_name } return(cutpointr_object) } check_roc_curve <- function(object) { if (!("roc_cutpointr" %in% class(object$roc_curve[[1]]))) { stop(paste("roc_curve as returned by the method function is not an", "object of the class roc_cutpointr")) } } has_column <- function(x, colname) { if (colname %in% colnames(x) | colname %in% names(x)) { return(TRUE) } else { return(FALSE) } } has_boot_results <- function(x) { if (has_column(x, "boot")) { if (all(is.na(x[["boot"]]))) { return(FALSE) } else { return(TRUE) } } else { return(FALSE) } } ifel_pos_neg <- function(logi_vec, pos_class, neg_class) { predictions <- rep(neg_class, length(logi_vec)) predictions[logi_vec] <- pos_class return(predictions) } get_fnth <- function(x, n = 1) { x <- unlist(x) if (length(x) == 1) { return(x[1]) } else { return(x[n]) } stop("no conditions apply in get_fnth") } get_numeric_cols <- function(x, class_col) { cols <- colnames(x)[unlist(lapply(x, is.numeric))] cols <- cols[cols != class_col] cols } midpoint <- function(oc, x, direction) { sapply(oc, function(oc) { x <- c(oc, x) if (direction == ">=") { x <- sort(unique(x)) } else { x <- sort(unique(x), decreasing = TRUE) } if (direction == ">=") { mean(c(oc, x[utils::tail(which(x <= oc), 1) - 1])) } else if (direction == "<=") { mean(c(oc, x[utils::tail(which(x >= oc), 1) - 1])) } }) } apply_break_ties <- function(oc, f) { stopifnot(nrow(oc) == 1) optimal_cutpoint <- f(oc[["optimal_cutpoint"]][[1]]) if (length(optimal_cutpoint) > 1) { optimal_cutpoint <- list(optimal_cutpoint) } oc$optimal_cutpoint <- optimal_cutpoint return(oc) } get_opt_ind <- function(roc_curve, oc, direction) { stopifnot(is.numeric(oc) | is.na(oc)) sapply(oc, function(x) { if (direction == ">=") { opt_ind <- max(which(roc_curve$x.sorted >= x)) } else if (direction == "<=") { opt_ind <- max(which(roc_curve$x.sorted <= x)) } return(opt_ind) }) } summary_sd <- function(x) { x <- unlist(x) s <- summary(x)[1:6] result <- c(s[1], stats::quantile(x, 0.05, na.rm = TRUE), s[2:5], stats::quantile(x, 0.95, na.rm = TRUE), s[6], SD = stats::sd(x, na.rm = TRUE), NAs = sum(is.na(x))) return(result) } summary_sd_df <- function(x) { x <- unlist(x) s <- summary(x)[1:6] result <- c(s[1], stats::quantile(x, 0.05, na.rm = TRUE), s[2:5], stats::quantile(x, 0.95, na.rm = TRUE), s[6], SD = stats::sd(x, na.rm = TRUE), NAs = sum(is.na(x))) result <- data.frame(`Min.` = result[1], `5%` = result[2], `1st Qu.` = result[3], `Median` = result[4], `Mean` = result[5], `3rd Qu.` = result[6], `95%` = result[7], `Max.` = result[8], `SD` = result[9], `NAs` = result[10], check.names = FALSE, row.names = NULL) return(result) } # Printing function for data.frames without returning x invisibly and with # row.names = FALSE print_df_nodat <- function (x, ..., digits = NULL, quote = FALSE, right = TRUE, row.names = FALSE, max = NULL) { n <- length(row.names(x)) if (length(x) == 0L) { cat(sprintf(ngettext(n, "data frame with 0 columns and %d row", "data frame with 0 columns and %d rows"), n), "\n", sep = "") } else if (n == 0L) { print.default(names(x), quote = FALSE) cat(gettext("<0 rows> (or 0-length row.names)\n")) } else { if (is.null(max)) max <- getOption("max.print", 99999L) if (!is.finite(max)) stop("invalid 'max' / getOption(\"max.print\"): ", max) omit <- (n0 <- max%/%length(x)) < n m <- as.matrix(format.data.frame(if (omit) x[seq_len(n0), , drop = FALSE] else x, digits = digits, na.encode = FALSE)) if (!isTRUE(row.names)) dimnames(m)[[1L]] <- if (isFALSE(row.names)) rep.int("", if (omit) n0 else n) else row.names print(m, ..., quote = quote, right = right, max = max) if (omit) cat(" [ reached 'max' / getOption(\"max.print\") -- omitted", n - n0, "rows ]\n") } invisible(x) } # If the output of the metric function is no named matrix with one column, # convert it to one. Also run some checks. sanitize_metric <- function(m, m_name, n, silent = TRUE) { if ("data.frame" %in% class(m)) { m <- as.matrix(m) } if (!is.null(dim(m))) { if (dim(m)[2] == 1 & ("matrix" %in% class(m))) { res <- m if (is.null(colnames(res))) colnames(res) <- m_name } else { stop(paste("The metric function should return a numeric vector", "or a one-column matrix or data.frame.")) } } else if (is.numeric(m)) { res <- matrix(m, ncol = 1, dimnames = list(NULL, m_name)) } else { stop(paste("Can't process metric of type", class(m))) } finite_res <- is.finite(res) if (any(!finite_res)) { if (!silent) message("Converting non-finite metric values to NA") res[!finite_res] <- NA } if (nrow(res) != n) { stop("Number of returned metric values not equal to n") } colnames(res) <- make.names(colnames(res)) return(res) } only_one_unique <- function(x) { if (is.character(x) | is.factor(x)) { one_unique_char(x) } else { one_unique_num(x) } } which_cpp <- function(x, y) { if (is.numeric(x)) { return(which_are_num(x, y)) } else { return(which_are_char(x, y)) } } is_equal_cpp <- function(x, y) { if (is.numeric(x)) { return(is_equal_cpp_num(x, y)) } else { return(is_equal_cpp_char(x, as.character(y))) } } na_inf_omit <- function(x) { x <- stats::na.omit(x) x <- x[is.finite(x)] return(x) } .onUnload <- function (libpath) { library.dynam.unload("cutpointr", libpath) } add_list <- function(x, y, name) { if (length(y) > 1) { x[[name]] <- list(y) } else { x[[name]] <- y } return(x) } # rbind list elements that are tibbles with different column types (list or dbl, # may be necessary for bootstrap results, if only one bootstrap resulted in # multiple optimal cutpoints) # Convert non-list columns to list so that bind_rows doesn't complain prepare_bind_rows <- function(x) { stopifnot(inherits(x, "list")) if (length(x) < 2) { return(x) } else { list_cols <- purrr::map(x, function(df) { df %>% purrr::map(function(col) (is.list(col))) }) list_cols <- purrr::map(list_cols, function(coltypes) { which(unlist(coltypes)) }) list_cols <- unique(unlist(list_cols)) x <- purrr::map(x, function(x) { dplyr::mutate_at(.tbl = x, .vars = list_cols, .funs = function(x) { if (!is.list(x)) { purrr::map(x, function(x) x) } else { x } }) }) return(x) } } # Return indices for observations based on nonparametric bootstrap per class. # Preliminary tests suggested that per_class = FALSE leads to better # confidence intervals. simple_boot <- function(ind_pos = NULL, ind_neg = NULL, data = NULL, dep_var = NULL, stratify) { if (stratify) { b_ind_pos <- sample(ind_pos, size = length(ind_pos), replace = TRUE) b_ind_neg <- sample(ind_neg, size = length(ind_neg), replace = TRUE) return(c(b_ind_pos, b_ind_neg)) } else { b_ind <- sample(1:nrow(data), size = nrow(data), replace = TRUE) return(b_ind) } } cutpointr/R/boot_ci.R0000644000176200001440000000712713717554737014275 0ustar liggesusers#' Calculate bootstrap confidence intervals from a cutpointr object #' #' Given a \code{cutpointr} object that includes bootstrap results #' this function calculates a bootstrap #' confidence interval for a selected variable. #' Missing values are removed before calculating the quantiles. In the case #' of multiple optimal cutpoints all cutpoints / metric values are included #' in the calculation. #' Values of the selected variable are returned for the percentiles alpha / 2 #' and 1 - alpha / 2. The metrics in the bootstrap data frames of #' \code{cutpointr} are suffixed with \code{_b} and \code{_oob} to indicate #' in-bag and out-of-bag, respectively. For example, to calculate quantiles #' of the in-bag AUC \code{variable = AUC_b} should be set. #' #' @param x (character) The numeric independent (predictor) variable. #' @param variable Variable to calculate CI for #' @param alpha Alpha level. Quantiles of the bootstrapped values are returned #' for (alpha / 2) and 1 - (alpha / 2). #' @param in_bag Whether the in-bag or out-of-bag results should be used for testing #' @return A data frame with the columns quantile and value #' @examples #' \dontrun{ #' opt_cut <- cutpointr(suicide, dsi, suicide, gender, #' metric = youden, boot_runs = 1000) #' boot_ci(opt_cut, optimal_cutpoint, in_bag = FALSE, alpha = 0.05) #' boot_ci(opt_cut, acc, in_bag = FALSE, alpha = 0.05) #' boot_ci(opt_cut, cohens_kappa, in_bag = FALSE, alpha = 0.05) #' boot_ci(opt_cut, AUC, in_bag = TRUE, alpha = 0.05) #' } #' @export #' @family main cutpointr functions boot_ci <- function(x, variable, in_bag = TRUE, alpha = 0.05) { if (alpha < 0 | alpha > 1) stop("alpha should be between 0 and 1.") if (!inherits(x, "cutpointr")) { stop("Only objects of type cutpointr are supported") } if (!has_boot_results(x)) { stop("No bootstrap results found. Was boot_runs > 0 in cutpointr?") } if (!("subgroup" %in% colnames(x))) { variable <- rlang::enquo(variable) variable <- rlang::as_name(variable) if (in_bag) suffix <- "_b" else suffix <- "_oob" if (variable == "optimal_cutpoint") { suffix <- "" in_bag = TRUE } variable <- paste0(variable, suffix) variable <- x %>% dplyr::select(.data$boot) %>% tidyr::unnest(cols = .data$boot) %>% dplyr::pull(variable) %>% unlist() values <- stats::quantile(variable, probs = c(alpha / 2, 1 - alpha / 2), na.rm = TRUE) res <- tibble::tibble( quantile = c(alpha / 2, 1 - alpha / 2), values = unname(values) ) return(res) } else { res <- purrr::map2_dfr(.x = x$subgroup, .y = x$boot, .f = function(s, b) { variable <- rlang::enquo(variable) variable <- rlang::as_name(variable) if (in_bag) suffix <- "_b" else suffix <- "_oob" if (variable == "optimal_cutpoint") { suffix <- "" in_bag = TRUE } variable <- paste0(variable, suffix) variable <- b %>% dplyr::pull(variable) %>% unlist() values <- stats::quantile(variable, probs = c(alpha / 2, 1 - alpha / 2), na.rm = TRUE) tibble::tibble( subgroup = s, quantile = c(alpha / 2, 1 - alpha / 2), values = unname(values) ) }) return(res) } }cutpointr/R/plot_x.R0000644000176200001440000001110013672457720014140 0ustar liggesusers#' Plot the distribution of the independent variable per class from a cutpointr object #' #' Given a \code{cutpointr} object this function plots the distribution(s) of the #' independent variable(s) and the respective cutpoints per class. #' @param x A cutpointr object. #' @param display_cutpoint (logical) Whether or not to display the optimal #' cutpoint as a vertical line. #' @param ... Additional arguments (unused). #' @examples #' opt_cut <- cutpointr(suicide, dsi, suicide) #' plot_x(opt_cut) #' #' ## With subgroup #' opt_cut_2groups <- cutpointr(suicide, dsi, suicide, gender) #' plot_x(opt_cut_2groups) #' @family cutpointr plotting functions #' @export plot_x <- function(x, display_cutpoint = TRUE, ...) { args <- list(...) predictor <- as.character(x$predictor[1]) outcome <- as.character(x$outcome[1]) if (!(has_column(x, "subgroup"))) { res_unnested <- x %>% dplyr::select(.data$data) %>% tidyr::unnest(.data$data) transparency <- 1 if (all(na_inf_omit(unlist(dplyr::select(res_unnested, predictor))) %% 1 == 0) | only_one_unique( na_inf_omit(unlist(dplyr::select(res_unnested, predictor))) )) { all_integer = TRUE dist_plot <- ggplot2::geom_bar(alpha = transparency, position = "identity") } else { all_integer = FALSE dist_plot <- ggplot2::geom_density(alpha = transparency) } dist <- ggplot2::ggplot(res_unnested, ggplot2::aes(x = !!rlang::ensym(predictor))) + dist_plot + # facet by class because always 2 ggplot2::facet_wrap(outcome, scales = "free_y") + ggplot2::ggtitle("Independent variable", "optimal cutpoint and distribution by class") + ggplot2::xlab("value") if (display_cutpoint) { cutpoint_dat <- x %>% dplyr::select(.data$optimal_cutpoint) if (is.list(x$optimal_cutpoint)) { cutpoint_dat <- tidyr::unnest(cols = optimal_cutpoint, data = cutpoint_dat) } dist <- dist + ggplot2::geom_vline(data = cutpoint_dat, mapping = ggplot2::aes(xintercept = optimal_cutpoint), show.legend = FALSE) } } else if (has_column(x, "subgroup")) { res_unnested <- x %>% dplyr::select("data", "subgroup") %>% tidyr::unnest(.data$data) res_unnested <- dplyr::full_join(res_unnested, tibble::as_tibble(x[, c("optimal_cutpoint", "subgroup")]), by = "subgroup") transparency <- 0.6 if (all(na_inf_omit(unlist(dplyr::select(res_unnested, predictor))) %% 1 == 0) | only_one_unique( na_inf_omit(unlist(dplyr::select(res_unnested, predictor))) )) { all_integer = TRUE dist_plot <- ggplot2::geom_bar(alpha = transparency, position = "identity") } else { all_integer = FALSE dist_plot <- ggplot2::geom_density(alpha = transparency) } dist <- ggplot2::ggplot(res_unnested, ggplot2::aes(x = !!rlang::ensym(predictor), fill = subgroup, color = subgroup)) + dist_plot + # facet by class because always 2 ggplot2::facet_wrap(outcome, scales = "free_y") + ggplot2::ggtitle("Independent variable", "optimal cutpoint and distribution by class") + ggplot2::xlab("value") + ggplot2::labs(color = "Subgroup", fill = "Subgroup") if (display_cutpoint) { cutpoint_dat <- x %>% dplyr::select(.data$subgroup, .data$optimal_cutpoint) if (is.list(x$optimal_cutpoint)) { cutpoint_dat <- tidyr::unnest(cols = optimal_cutpoint, data = cutpoint_dat) } dist <- dist + ggplot2::geom_vline(data = cutpoint_dat, mapping = ggplot2::aes(xintercept = optimal_cutpoint, color = subgroup), show.legend = FALSE) } } if (!all_integer) dist <- dist + ggplot2::geom_rug(alpha = 0.5) return(dist) } cutpointr/R/prep.R0000644000176200001440000000421513475240564013607 0ustar liggesusersassume_direction_pos_class <- function(x, class, pos_class, neg_class, direction, na.rm, uc) { # Handle NAs if (na.rm) { na_indx <- is.na(x) na_indc <- is.na(class) complete_ind <- !(na_indx + na_indc) x <- x[complete_ind] class <- class[complete_ind] } if (is.null(direction) & !is.null(pos_class)) { if (stats::median(x[class != pos_class]) < stats::median(x[class == pos_class])) { message("Assuming the positive class has higher x values") direction <- ">=" } else { message("Assuming the positive class has lower x values") direction <- "<=" } } if (is.null(direction) & is.null(pos_class)) direction <- ">=" if (!is.null(direction) & is.null(pos_class)) { if (direction == ">" | direction == ">=") { if (stats::median(x[class == uc[1]]) > stats::median(x[class == uc[2]])) { message(paste("Assuming the positive class is", uc[1])) message("Assuming the positive class has higher x values") pos_class <- uc[1] } else { message(paste("Assuming the positive class is", uc[2])) message("Assuming the positive class has higher x values") pos_class <- uc[2] } } else { if (stats::median(x[class == uc[1]]) < stats::median(x[class == uc[2]])) { message(paste("Assuming the positive class is", uc[1])) message("Assuming the positive class has lower x values") pos_class <- uc[1] } else { message(paste("Assuming the positive class is", uc[2])) message("Assuming the positive class has lower x values") pos_class <- uc[2] } } } if (!any(pos_class == class)) stop("Positive class not found in data") if (is.null(neg_class)) { neg_class <- unique(class) neg_class <- neg_class[neg_class != pos_class] } return(list(direction = direction, pos_class = pos_class, neg_class = neg_class)) } cutpointr/R/cutpointr.R0000644000176200001440000013354414066363322014673 0ustar liggesusers#' Determine and evaluate optimal cutpoints #' #' Using predictions (or e.g. biological marker values) and binary class labels, this function #' will determine "optimal" cutpoints using various selectable methods. The #' methods for cutpoint determination can be evaluated using bootstrapping. An #' estimate of the cutpoint variability and the out-of-sample performance can then #' be returned with \code{summary} or \code{plot}. For an introduction to the #' package please see \code{vignette("cutpointr", package = "cutpointr")}. #' #' If \code{direction} and/or \code{pos_class} and \code{neg_class} are not given, the function will #' assume that higher values indicate the positive class and use the class #' with a higher median as the positive class. #' #' This function uses tidyeval to support unquoted arguments. For programming #' with \code{cutpointr} the operator \code{!!} can be used to unquote an argument, see the #' examples. #' #' Different methods can be selected for determining the optimal cutpoint via #' the method argument. The package includes the following method functions: #' \itemize{ #' \item \code{maximize_metric}: Maximize the metric function #' \item \code{minimize_metric}: Minimize the metric function #' \item \code{maximize_loess_metric}: Maximize the metric function after LOESS #' smoothing #' \item \code{minimize_loess_metric}: Minimize the metric function after LOESS #' smoothing #' \item \code{maximize_spline_metric}: Maximize the metric function after spline #' smoothing #' \item \code{minimize_spline_metric}: Minimize the metric function after spline #' smoothing #' \item \code{maximize_boot_metric}: Maximize the metric function as a summary of #' the optimal cutpoints in bootstrapped samples #' \item \code{minimize_boot_metric}: Minimize the metric function as a summary of #' the optimal cutpoints in bootstrapped samples #' \item \code{oc_youden_kernel}: Maximize the Youden-Index after kernel smoothing #' the distributions of the two classes #' \item \code{oc_youden_normal}: Maximize the Youden-Index parametrically #' assuming normally distributed data in both classes #' \item \code{oc_manual}: Specify the cutpoint manually #' } #' #' User-defined functions can be supplied to method, too. As a reference, #' the code of all included method functions can be accessed by simply typing #' their name. To define a new method function, create a function that may take #' as input(s): #' \itemize{ #' \item \code{data}: A \code{data.frame} or \code{tbl_df} #' \item \code{x}: (character) The name of the predictor or independent variable #' \item \code{class}: (character) The name of the class or dependent variable #' \item \code{metric_func}: A function for calculating a metric, e.g. accuracy #' \item \code{pos_class}: The positive class #' \item \code{neg_class}: The negative class #' \item \code{direction}: ">=" if the positive class has higher x values, "<=" otherwise #' \item \code{tol_metric}: (numeric) In the built-in methods a tolerance around #' the optimal metric value #' \item \code{use_midpoints}: (logical) In the built-in methods whether to #' use midpoints instead of exact optimal cutpoints #' \item \code{...} Further arguments #' } #' #' The \code{...} argument can be used to avoid an error if not all of the above #' arguments are needed or in order to pass additional arguments to method. #' The function should return a \code{data.frame} or \code{tbl_df} with #' one row, the column "optimal_cutpoint", and an optional column with an arbitrary name #' with the metric value at the optimal cutpoint. #' #' Built-in metric functions include: #' \itemize{ #' \item \code{accuracy}: Fraction correctly classified #' \item \code{youden}: Youden- or J-Index = sensitivity + specificity - 1 #' \item \code{sum_sens_spec}: sensitivity + specificity #' \item \code{sum_ppv_npv}: The sum of positive predictive value (PPV) and negative #' predictive value (NPV) #' \item \code{prod_sens_spec}: sensitivity * specificity #' \item \code{prod_ppv_npv}: The product of positive predictive value (PPV) and #' negative predictive value (NPV) #' \item \code{cohens_kappa}: Cohen's Kappa #' \item \code{abs_d_sens_spec}: The absolute difference between #' sensitivity and specificity #' \item \code{roc01}: Distance to the point (0,1) on ROC space #' \item \code{abs_d_ppv_npv}: The absolute difference between positive predictive #' value (PPV) and negative predictive value (NPV) #' \item \code{p_chisquared}: The p-value of a chi-squared test on the confusion #' matrix of predictions and observations #' \item \code{odds_ratio}: The odds ratio calculated as (TP / FP) / (FN / TN) #' \item \code{risk_ratio}: The risk ratio (relative risk) calculated as #' (TP / (TP + FN)) / (FP / (FP + TN)) #' \item positive and negative likelihood ratio calculated as #' \code{plr} = true positive rate / false positive rate and #' \code{nlr} = false negative rate / true negative rate #' \item \code{misclassification_cost}: The sum of the misclassification cost of #' false positives and false negatives fp * cost_fp + fn * cost_fn. #' Additional arguments to cutpointr: \code{cost_fp}, \code{cost_fn} #' \item \code{total_utility}: The total utility of true / false positives / negatives #' calculated as utility_tp * TP + utility_tn * TN - cost_fp * FP - cost_fn * FN. #' Additional arguments to cutpointr: \code{utility_tp}, \code{utility_tn}, #' \code{cost_fp}, \code{cost_fn} #' \item \code{F1_score}: The F1-score (2 * TP) / (2 * TP + FP + FN) #' \item \code{sens_constrain}: Maximize sensitivity given a minimal value of #' specificity #' \item \code{spec_constrain}: Maximize specificity given a minimal value of #' sensitivity #' \item \code{metric_constrain}: Maximize a selected metric given a minimal #' value of another selected metric #' } #' #' Furthermore, the following functions are included which can be used as metric #' functions but are more useful for plotting purposes, for example in #' plot_cutpointr, or for defining new metric functions: #' \code{tp}, \code{fp}, \code{tn}, \code{fn}, \code{tpr}, \code{fpr}, #' \code{tnr}, \code{fnr}, \code{false_omission_rate}, #' \code{false_discovery_rate}, \code{ppv}, \code{npv}, \code{precision}, #' \code{recall}, \code{sensitivity}, and \code{specificity}. #' #' User defined metric functions can be created as well which can accept the following #' inputs as vectors: #' \itemize{ #' \item \code{tp}: Vector of true positives #' \item \code{fp}: Vector of false positives #' \item \code{tn}: Vector of true negatives #' \item \code{fn}: Vector of false negatives #' \item \code{...} If the metric function is used in conjunction with any of the #' maximize / minimize methods, further arguments can be passed #' } #' #' The function should return a numeric vector or a matrix or a \code{data.frame} #' with one column. If the column is named, #' the name will be included in the output and plots. Avoid using names that #' are identical to the column names that are by default returned by \pkg{cutpointr}. #' #' If \code{boot_runs} is positive, that number of bootstrap samples will be drawn #' and the optimal cutpoint using \code{method} will be determined. Additionally, #' as a way of internal validation, the function in \code{metric} will be used to #' score the out-of-bag predictions using the cutpoints determined by #' \code{method}. Various default metrics are always included in the bootstrap results. #' #' If multiple optimal cutpoints are found, the column optimal_cutpoint becomes a #' list that contains the vector(s) of the optimal cutpoints. #' #' If \code{use_midpoints = TRUE} the mean of the optimal cutpoint and the next #' highest or lowest possible cutpoint is returned, depending on \code{direction}. #' #' The \code{tol_metric} argument can be used to avoid floating-point problems #' that may lead to exclusion of cutpoints that achieve the optimally achievable #' metric value. Additionally, by selecting a large tolerance multiple cutpoints #' can be returned that lead to decent metric values in the vicinity of the #' optimal metric value. \code{tol_metric} is passed to metric and is only #' supported by the maximization and minimization functions, i.e. #' \code{maximize_metric}, \code{minimize_metric}, \code{maximize_loess_metric}, #' \code{minimize_loess_metric}, \code{maximize_spline_metric}, and #' \code{minimize_spline_metric}. In \code{maximize_boot_metric} and #' \code{minimize_boot_metric} multiple optimal cutpoints will be passed to the #' \code{summary_func} of these two functions. #' #' @examples #' library(cutpointr) #' #' ## Optimal cutpoint for dsi #' data(suicide) #' opt_cut <- cutpointr(suicide, dsi, suicide) #' opt_cut #' s_opt_cut <- summary(opt_cut) #' plot(opt_cut) #' #' \dontrun{ #' ## Predict class for new observations #' predict(opt_cut, newdata = data.frame(dsi = 0:5)) #' #' ## Supplying raw data, same result #' cutpointr(x = suicide$dsi, class = suicide$suicide) #' #' ## direction, class labels, method and metric can be defined manually #' ## Again, same result #' cutpointr(suicide, dsi, suicide, direction = ">=", pos_class = "yes", #' method = maximize_metric, metric = youden) #' #' ## Optimal cutpoint for dsi, as before, but for the separate subgroups #' opt_cut <- cutpointr(suicide, dsi, suicide, gender) #' opt_cut #' (s_opt_cut <- summary(opt_cut)) #' tibble:::print.tbl(s_opt_cut) #' #' ## Bootstrapping also works on individual subgroups #' set.seed(30) #' opt_cut <- cutpointr(suicide, dsi, suicide, gender, boot_runs = 1000, #' boot_stratify = TRUE) #' opt_cut #' summary(opt_cut) #' plot(opt_cut) #' #' ## Parallelized bootstrapping #' library(doParallel) #' library(doRNG) #' cl <- makeCluster(2) # 2 cores #' registerDoParallel(cl) #' registerDoRNG(12) # Reproducible parallel loops using doRNG #' opt_cut <- cutpointr(suicide, dsi, suicide, gender, #' boot_runs = 1000, allowParallel = TRUE) #' stopCluster(cl) #' opt_cut #' plot(opt_cut) #' #' ## Robust cutpoint method using kernel smoothing for optimizing Youden-Index #' opt_cut <- cutpointr(suicide, dsi, suicide, gender, #' method = oc_youden_kernel) #' opt_cut #' } #' #' #' #' @param data A data.frame with the data needed for x, class and optionally #' subgroup. #' @param x The variable name to be used for classification, #' e.g. predictions. The raw vector of values if the data argument #' is unused. #' @param class The variable name indicating class membership. #' If the data argument is unused, the vector of raw numeric values. #' @param subgroup An additional covariate that identifies subgroups or the raw data if #' data = NULL. Separate optimal cutpoints will be determined per group. #' Numeric, character and factor are allowed. #' @param method (function) A function for determining cutpoints. Can #' be user supplied or use some of the built in methods. See details. #' @param metric (function) The function for computing a metric when using #' maximize_metric or minimize_metric as method and and for the #' out-of-bag values during bootstrapping. A way of internally validating the performance. #' User defined functions can be supplied, see details. #' @param pos_class (optional) The value of class that indicates the positive class. #' @param neg_class (optional) The value of class that indicates the negative class. #' @param direction (character, optional) Use ">=" or "<=" to indicate whether x #' is supposed to be larger or smaller for the positive class. #' @param boot_runs (numerical) If positive, this number of bootstrap samples #' will be used to assess the variability and the out-of-sample performance. #' @param boot_stratify (logical) If the bootstrap is stratified, bootstrap #' samples are drawn separately in both classes and then combined, keeping the #' proportion of positives and negatives constant in every resample. #' @param use_midpoints (logical) If TRUE (default FALSE) the returned optimal #' cutpoint will be the mean of the optimal cutpoint and the next highest #' observation (for direction = ">=") or the next lowest observation #' (for direction = "<=") which avoids biasing the optimal cutpoint. #' @param break_ties If multiple cutpoints are found, they can be summarized using #' this function, e.g. mean or median. To return all cutpoints use c as the function. #' @param na.rm (logical) Set to TRUE (default FALSE) to keep only complete #' cases of x, class and subgroup (if specified). Missing values with #' na.rm = FALSE will raise an error. #' @param allowParallel (logical) If TRUE, the bootstrapping will be parallelized #' using foreach. A local cluster, for example, should be started manually #' beforehand. #' @param silent (logical) If TRUE suppresses all messages. #' @param tol_metric All cutpoints will be returned that lead to a metric #' value in the interval [m_max - tol_metric, m_max + tol_metric] where #' m_max is the maximum achievable metric value. This can be used to return #' multiple decent cutpoints and to avoid floating-point problems. Not supported #' by all \code{method} functions, see details. #' @param ... Further optional arguments that will be passed to method. #' minimize_metric and maximize_metric pass ... to metric. #' @importFrom purrr %>% #' @importFrom foreach %do% #' @return A cutpointr object which is also a data.frame and tbl_df. #' @useDynLib cutpointr #' @importFrom Rcpp sourceCpp #' @family main cutpointr functions #' @export cutpointr cutpointr <- function(...) { UseMethod("cutpointr") } #' @rdname cutpointr #' @importFrom stats median #' @export cutpointr.default <- function(data, x, class, subgroup = NULL, method = maximize_metric, metric = sum_sens_spec, pos_class = NULL, neg_class = NULL, direction = NULL, boot_runs = 0, boot_stratify = FALSE, use_midpoints = FALSE, break_ties = median, na.rm = FALSE, allowParallel = FALSE, silent = FALSE, tol_metric = 1e-6, ...) { # # NSE # predictor <- rlang::as_name(rlang::enquo(x)) x_sym <- rlang::ensym(x) x_expr <- rlang::enexpr(x_sym) x <- rlang::eval_tidy(expr = x_expr, data = data) outcome <- rlang::as_name(rlang::enquo(class)) class_sym <- rlang::ensym(class) class_expr <- rlang::enexpr(class_sym) class <- rlang::eval_tidy(expr = class_expr, data = data) subgroup_var <- deparse(substitute(subgroup)) if (!(deparse(substitute(subgroup)) == "NULL")) { subgroup_var <- rlang::as_name(rlang::enquo(subgroup)) subgroup_sym <- rlang::ensym(subgroup) subgroup_expr <- rlang::enexpr(subgroup_sym) subgroup <- rlang::eval_tidy(expr = subgroup_expr, data = data) } # Get method function if (length(method) > 1 | !(class(method) == "function")) { stop("method should be a function") } else { cl <- match.call() mod_name <- cl$method # if default was not changed: mod_name <- as.character(substitute(method)) } if (is.null(mod_name)) stop("Could not get the method function") mod_name <- check_method_name(mod_name) # Get metric function if (length(metric) > 1 | !(class(metric) == "function")) { stop("metric should be a function") } if (silent) { suppressMessages( cutpointr_internal(x, class, subgroup, method, metric, pos_class, neg_class, direction, boot_runs, boot_stratify, use_midpoints, break_ties, na.rm, allowParallel, predictor, outcome, mod_name, subgroup_var, tol_metric, ...) ) } else { cutpointr_internal(x, class, subgroup, method, metric, pos_class, neg_class, direction, boot_runs, boot_stratify, use_midpoints, break_ties, na.rm, allowParallel, predictor, outcome, mod_name, subgroup_var, tol_metric, ...) } } #' @rdname cutpointr #' @importFrom stats median #' @export cutpointr.numeric <- function(x, class, subgroup = NULL, method = maximize_metric, metric = sum_sens_spec, pos_class = NULL, neg_class = NULL, direction = NULL, boot_runs = 0, boot_stratify = FALSE, use_midpoints = FALSE, break_ties = median, na.rm = FALSE, allowParallel = FALSE, silent = FALSE, tol_metric = 1e-6, ...) { predictor <- "x" outcome <- "class" subgroup_var <- "subgroup" # Get method function if (length(method) > 1 | !(class(method) == "function")) { stop("method should be a function") } else { cl <- match.call() mod_name <- cl$method # if default was not changed: mod_name <- as.character(substitute(method)) } if (is.null(mod_name)) stop("Could not get the method function") mod_name <- check_method_name(mod_name) # Get metric function if (length(metric) > 1 | !(class(metric) == "function")) { stop("metric should be a function") } if (silent) { suppressMessages( cutpointr_internal(x, class, subgroup, method, metric, pos_class, neg_class, direction, boot_runs, boot_stratify, use_midpoints, break_ties, na.rm, allowParallel, predictor, outcome, mod_name, subgroup_var, tol_metric, ...) ) } else { cutpointr_internal(x, class, subgroup, method, metric, pos_class, neg_class, direction, boot_runs, boot_stratify, use_midpoints, break_ties, na.rm, allowParallel, predictor, outcome, mod_name, subgroup_var, tol_metric, ...) } } #' The standard evaluation version of cutpointr (deprecated) #' #' This function is equivalent to \code{cutpointr} but takes only quoted arguments #' for \code{x}, \code{class} and \code{subgroup}. This was useful before #' \code{cutpointr} supported tidyeval. #' #' @inheritParams cutpointr #' @param x (character) The variable name to be used for #' classification, e.g. predictions or test values. #' @param class (character) The variable name indicating class membership. #' @param subgroup (character) The variable name #' of an additional covariate that identifies subgroups. Separate #' optimal cutpoints will be determined per group. #' @examples #' library(cutpointr) #' #' ## Optimal cutpoint for dsi #' data(suicide) #' opt_cut <- cutpointr_(suicide, "dsi", "suicide") #' opt_cut #' summary(opt_cut) #' plot(opt_cut) #' predict(opt_cut, newdata = data.frame(dsi = 0:5)) #' @importFrom stats median #' @export cutpointr_ <- function(data, x, class, subgroup = NULL, method = maximize_metric, metric = sum_sens_spec, pos_class = NULL, neg_class = NULL, direction = NULL, boot_runs = 0, boot_stratify = FALSE, use_midpoints = FALSE, break_ties = median, na.rm = FALSE, allowParallel = FALSE, silent = FALSE, tol_metric = 1e-6, ...) { signal_soft_deprecated(paste( "cutpointr_() is deprecated.", "Please use cutpointr() instead.", "The help page gives an example on programming with cutpointr", "using quoted arguments. For general information see the tidyeval book", ": https://tidyeval.tidyverse.org" )) # # SE # x <- as.name(x) class <- as.name(class) if (!is.null(subgroup)) subgroup <- as.name(subgroup) predictor <- deparse(substitute(x)) outcome <- deparse(substitute(class)) x <- eval(substitute(x), data, parent.frame()) class <- eval(substitute(class), data, parent.frame()) subgroup_var <- deparse(substitute(subgroup)) subgroup <- eval(substitute(subgroup), data, parent.frame()) # Get method function if (length(method) > 1 | !(class(method) == "function")) { stop("method should be a function") } else { cl <- match.call() mod_name <- cl$method mod_name <- as.character(substitute(method)) } if (is.null(mod_name)) stop("Could not get the method function") mod_name <- check_method_name(mod_name) # Get metric function if (length(metric) > 1 | !(class(metric) == "function")) { stop("metric should be a function") } if (silent) { suppressMessages( cutpointr_internal(x, class, subgroup, method, metric, pos_class, neg_class, direction, boot_runs, boot_stratify, use_midpoints, break_ties, na.rm, allowParallel, predictor, outcome, mod_name, subgroup_var, tol_metric = 1e-6, ...) ) } else { cutpointr_internal(x, class, subgroup, method, metric, pos_class, neg_class, direction, boot_runs, boot_stratify, use_midpoints, break_ties, na.rm, allowParallel, predictor, outcome, mod_name, subgroup_var, tol_metric = 1e-6, ...) } } cutpointr_internal <- function(x, class, subgroup, method, metric, pos_class, neg_class, direction, boot_runs, boot_stratify, use_midpoints, break_ties, na.rm, allowParallel, predictor, outcome, mod_name, subgroup_var, tol_metric, ...) { # # Prep # #NA if (any(anyNA(c(x, class)) | (!is.null(subgroup) & anyNA(subgroup))) & (!na.rm)) { stop("NAs found but na.rm = FALSE") } # Check classes if (!is.null(dim(class))) stop("class variable should be a vector") if (na.rm) uc <- unique(stats::na.omit(class)) else uc <- unique(class) luc <- length(uc) if (luc != 2) stop(paste("Expecting two classes, got", luc)) if (!(is.null(pos_class))) { if (!(pos_class %in% class)) stop("pos_class not found in data") } if (!(is.null(neg_class))) { if (!(neg_class %in% class)) stop("neg_class not found in data") } # Determine direction and/or pos_class if necessary: if (any(c(is.null(pos_class), is.null(neg_class), is.null(direction)))) { assumptions <- assume_direction_pos_class(x = x, class = class, pos_class = pos_class, neg_class = neg_class, direction = direction, na.rm = na.rm, uc = uc) } if (is.null(direction)) direction <- assumptions$direction stopifnot(direction %in% c("<", ">", ">=", "<=")) if (is.null(pos_class)) pos_class <- assumptions$pos_class if (is.null(neg_class)) neg_class <- assumptions$neg_class # # Calculate optimal cutpoint, map to cutpoint function # if (!is.null(subgroup)) { dat <- data.frame(x = x, class = class, subgroup = subgroup, stringsAsFactors = FALSE) colnames(dat) <- c(predictor, outcome, "subgroup") if (na.rm) dat <- stats::na.omit(dat) g <- unique(dat$subgroup) dat <- dat %>% dplyr::mutate(subgroup = as.character(subgroup)) %>% dplyr::group_by(subgroup) %>% tidyr::nest(data = c(!!predictor, !!outcome)) dat$pos_class <- pos_class optcut <- purrr::pmap(list(dat$subgroup, dat$data), function(g, d) { if (nrow(d) <= 1) stop(paste("Subgroup", g, "has <= 1 observations")) optcut <- tibble::tibble(subgroup = g) method_result <- method(data = d, x = predictor, class = outcome, metric_func = metric, direction = direction, pos_class = pos_class, neg_class = neg_class, tol_metric = tol_metric, use_midpoints = use_midpoints, boot_stratify = boot_stratify, ...) method_result <- check_method_cols(method_result) optcut <- dplyr::bind_cols(optcut, method_result) if (length(optcut[["optimal_cutpoint"]][[1]]) > 1) { message("Multiple optimal cutpoints found, applying break_ties.") } optcut <- apply_break_ties(optcut, break_ties) # Depending on method the roc_curve may be missing if (!(has_column(optcut, "roc_curve"))) { roc_curve <- roc(data = d, x = !!predictor, class = !!outcome, pos_class = pos_class, neg_class = neg_class, direction = direction) # roc_curve <- tidyr::nest(.data = tibble::as_tibble(roc_curve), # roc_curve = dplyr::everything()) %>% # tibble::as_tibble() roc_curve <- tibble::tibble(roc_curve = list(roc_curve)) optcut <- dplyr::bind_cols(tibble::as_tibble(roc_curve), tibble::as_tibble(optcut)) } else { check_roc_curve(optcut) } # If no metric is returned if (ncol(optcut) <= 3) { opt_ind <- get_opt_ind(optcut$roc_curve[[1]], oc = unlist(optcut$optimal_cutpoint), direction = direction) m <- metric(tp = optcut$roc_curve[[1]]$tp[opt_ind], fp = optcut$roc_curve[[1]]$fp[opt_ind], tn = optcut$roc_curve[[1]]$tn[opt_ind], fn = optcut$roc_curve[[1]]$fn[opt_ind], ...) m <- check_metric_name(m) colnames(m) <- make.names(colnames(m)) optcut <- dplyr::bind_cols(optcut, tibble::as_tibble(m)) } optcut <- check_colnames(optcut) # Breaking ties may have altered the cutpoints. Recalculate main metric opt_ind <- get_opt_ind(optcut$roc_curve[[1]], oc = unlist(optcut$optimal_cutpoint), direction = direction) m <- metric(tp = optcut$roc_curve[[1]]$tp[opt_ind], fp = optcut$roc_curve[[1]]$fp[opt_ind], tn = optcut$roc_curve[[1]]$tn[opt_ind], fn = optcut$roc_curve[[1]]$fn[opt_ind], ...) optcut <- add_list(optcut, as.numeric(m), optcut$metric_name) sesp <- sesp_from_oc(optcut$roc_curve[[1]], oc = optcut$optimal_cutpoint, direction = direction) optcut <- add_list(optcut, sesp[, "sensitivity"], "sensitivity") optcut <- add_list(optcut, sesp[, "specificity"], "specificity") acc <- accuracy_from_oc(optcut$roc_curve[[1]], oc = optcut$optimal_cutpoint[[1]], direction = direction)[, "accuracy"] optcut <- add_list(optcut, acc, "acc") return(optcut) }) # if multiple cutpoints only in some groups, all cols have to be lists coltypes <- purrr::map_chr(optcut, function(x) class(x[2][[1]])) if (any(coltypes == "list") & any(coltypes == "numeric")) { optcut <- purrr::map(optcut, function(x) { if (is.numeric(x$optimal_cutpoint)) { x$optimal_cutpoint <- list(x$optimal_cutpoint) x[[x$metric_name]] <- list(x[[x$metric_name]]) x$sensitivity <- list(x$sensitivity) x$specificity <- list(x$specificity) x$acc <- list(x$acc) } return(x) }) } # Suppress "Vectorizing 'vctrs_list_of' elements may not preserve their attributes" optcut <- suppressWarnings(dplyr::bind_rows(optcut)) optcut <- optcut %>% dplyr::mutate( AUC = purrr::map_dbl(roc_curve, function(r) { auc(r) }), prevalence = purrr::map_dbl(roc_curve, function(r) { utils::tail(r$tp, 1) / (utils::tail(r$tp, 1) + utils::tail(r$fp, 1)) }) ) optcut <- tibble::as_tibble(optcut) optcut <- dplyr::full_join(optcut, dat, by = "subgroup") } else if (is.null(subgroup)) { dat <- tibble::tibble(x = x, class = class) colnames(dat) <- c(predictor, outcome) if (na.rm) dat <- stats::na.omit(dat) dat <- dat %>% tidyr::nest(data = c(!!predictor, !!outcome)) dat$pos_class <- pos_class optcut <- method(data = dat$data[[1]], x = predictor, class = outcome, metric_func = metric, direction = direction, pos_class = pos_class, neg_class = neg_class, tol_metric = tol_metric, boot_stratify = boot_stratify, use_midpoints = use_midpoints, ...) optcut <- check_method_cols(optcut) if (length(optcut[["optimal_cutpoint"]][[1]]) > 1) { message("Multiple optimal cutpoints found, applying break_ties.") } optcut <- apply_break_ties(optcut, break_ties) if (!(has_column(optcut, "roc_curve"))) { roc_curve <- roc(data = dat$data[[1]], x = !!predictor, class = !!outcome, pos_class = pos_class, neg_class = neg_class, direction = direction) roc_curve <- tibble::tibble(roc_curve = list(roc_curve)) optcut <- dplyr::bind_cols(roc_curve, tibble::as_tibble(optcut)) } else { check_roc_curve(optcut) } # If no metric is returned if (ncol(optcut) <= 2) { opt_ind <- get_opt_ind(optcut$roc_curve[[1]], oc = unlist(optcut$optimal_cutpoint), direction = direction) m <- metric(tp = optcut$roc_curve[[1]]$tp[opt_ind], fp = optcut$roc_curve[[1]]$fp[opt_ind], tn = optcut$roc_curve[[1]]$tn[opt_ind], fn = optcut$roc_curve[[1]]$fn[opt_ind]) m <- check_metric_name(m) colnames(m) <- make.names(colnames(m)) optcut <- dplyr::bind_cols(optcut, tibble::as_tibble(m)) } optcut <- check_colnames(optcut) # Breaking ties may have altered the cutpoints. Recalculate main metric opt_ind <- get_opt_ind(optcut$roc_curve[[1]], oc = unlist(optcut$optimal_cutpoint), direction = direction) m <- metric(tp = optcut$roc_curve[[1]]$tp[opt_ind], fp = optcut$roc_curve[[1]]$fp[opt_ind], tn = optcut$roc_curve[[1]]$tn[opt_ind], fn = optcut$roc_curve[[1]]$fn[opt_ind], ...) optcut <- add_list(optcut, as.numeric(m), optcut$metric_name) sesp <- sesp_from_oc(optcut$roc_curve[[1]], oc = optcut$optimal_cutpoint, direction = direction) optcut <- add_list(optcut, sesp[, "sensitivity"], "sensitivity") optcut <- add_list(optcut, sesp[, "specificity"], "specificity") acc <- accuracy_from_oc(optcut$roc_curve[[1]], oc = unlist(optcut$optimal_cutpoint), direction = direction)[, "accuracy"] optcut <- add_list(optcut, acc, "acc") optcut$AUC <- auc(optcut$roc_curve[[1]]) optcut$prevalence <- utils::tail(optcut$roc_curve[[1]]$tp, 1) / (utils::tail(optcut$roc_curve[[1]]$tp, 1) + utils::tail(optcut$roc_curve[[1]]$fp, 1)) optcut <- tibble::as_tibble(optcut) optcut <- dplyr::bind_cols(optcut, dat) } optcut$direction <- direction optcut$predictor <- predictor optcut$outcome <- outcome optcut$neg_class <- neg_class optcut$method <- mod_name if (!is.null(subgroup)) optcut$grouping <- subgroup_var # Reorder for nicer output mn <- optcut$metric_name[1] select_cols <- c("subgroup", "direction", "optimal_cutpoint", "method", mn, "acc", "sensitivity", "specificity", "AUC", "pos_class", "neg_class", "prevalence", "outcome", "predictor", "grouping", "data", "roc_curve") # subgroup and grouping may not be given select_cols <- select_cols[select_cols %in% colnames(optcut)] optcut <- optcut[, select_cols] # # Bootstrap cutpoint variability and get LOO-Bootstrap performance estimate # Data are already nested and grouped if necessary # if (allowParallel) { requireNamespace("foreach") `%seq_or_par%` <- doRNG::`%dorng%` } else { `%seq_or_par%` <- foreach::`%do%` } if (boot_runs <= 0) { boot_res <- rep(NA, times = nrow(optcut)) } else { message("Running bootstrap...") boot_runs <- ceiling(boot_runs) boot_res <- purrr::map2(dat$data, dat$pos_class, function(g, pc) { if (boot_stratify) { ind_pos <- which(unlist(g[, outcome]) == pc) ind_neg <- which(unlist(g[, outcome]) == neg_class) } else { ind_pos <- NA ind_neg <- NA } boot_g <- foreach::foreach(rep = 1:boot_runs, .export = c("method", "direction", "metric", "break_ties", "neg_class", "mn", "use_midpoints", "boot_stratify", "predictor", "outcome", "tol_metric"), .errorhandling = "remove") %seq_or_par% { b_ind <- simple_boot(data = g, dep_var = outcome, ind_pos = ind_pos, ind_neg = ind_neg, stratify = boot_stratify) optcut_b <- method(data = g[b_ind, ], x = predictor, metric_func = metric, class = outcome, direction = direction, pos_class = pc, neg_class = neg_class, tol_metric = tol_metric, boot_stratify = boot_stratify, use_midpoints = use_midpoints, ...) optcut_b <- check_method_cols(optcut_b) optcut_b <- tibble::as_tibble(optcut_b) optcut_b <- apply_break_ties(optcut_b, break_ties) # LOO-Bootstrap if (!(has_column(optcut_b, "roc_curve"))) { roc_curve_b <- roc(data = g[b_ind, ], x = !!predictor, class = !!outcome, pos_class = pc, neg_class = neg_class, direction = direction, silent = TRUE) roc_curve_b <- tibble::tibble(roc_curve = list(roc_curve_b)) optcut_b <- dplyr::bind_cols(tibble::as_tibble(optcut_b), roc_curve_b) } opt_ind_b <- get_opt_ind(roc_curve = optcut_b$roc_curve[[1]], oc = unlist(optcut_b$optimal_cutpoint), direction = direction) auc_b <- auc(optcut_b$roc_curve[[1]]) Sens_Spec_b <- sesp_from_oc(optcut_b$roc_curve[[1]], oc = unlist(optcut_b$optimal_cutpoint), direction = direction, opt_ind = opt_ind_b) Acc_b <- accuracy_from_oc(optcut_b$roc_curve[[1]], oc = unlist(optcut_b$optimal_cutpoint), direction = direction, opt_ind = opt_ind_b)[, "accuracy"] kap_b <- kappa_from_oc(optcut_b$roc_curve[[1]], oc = unlist(optcut_b$optimal_cutpoint), direction = direction, opt_ind = opt_ind_b) metric_b <- metric(tp = optcut_b$roc_curve[[1]]$tp[opt_ind_b], fp = optcut_b$roc_curve[[1]]$fp[opt_ind_b], tn = optcut_b$roc_curve[[1]]$tn[opt_ind_b], fn = optcut_b$roc_curve[[1]]$fn[opt_ind_b]) metric_b <- check_metric_name(metric_b) roc_curve_oob <- roc(data = g[-b_ind, ], x = !!predictor, class = !!outcome, pos_class = pc, neg_class = neg_class, direction = direction, silent = TRUE) opt_ind_oob <- get_opt_ind(roc_curve = roc_curve_oob, oc = unlist(optcut_b$optimal_cutpoint), direction = direction) auc_oob <- auc(roc_curve_oob) Sens_Spec_oob <- sesp_from_oc(roc_curve_oob, oc = unlist(optcut_b$optimal_cutpoint), direction = direction, opt_ind = opt_ind_oob) Acc_oob <- accuracy_from_oc(roc_curve_oob, oc = unlist(optcut_b$optimal_cutpoint), direction = direction, opt_ind = opt_ind_oob)[, "accuracy"] kap_oob <- kappa_from_oc(roc_curve_oob, oc = unlist(optcut_b$optimal_cutpoint), direction = direction, opt_ind = opt_ind_oob) metric_oob <- metric(tp = roc_curve_oob$tp[opt_ind_oob], fp = roc_curve_oob$fp[opt_ind_oob], tn = roc_curve_oob$tn[opt_ind_oob], fn = roc_curve_oob$fn[opt_ind_oob]) metric_oob <- check_metric_name(metric_oob) mn <- make.names(colnames(metric_oob)) bootstrap <- tibble::tibble( optimal_cutpoint = optcut_b$optimal_cutpoint, AUC_b = auc_b, AUC_oob = auc_oob ) bootstrap <- bootstrap %>% add_list(metric_b[, mn], paste0(mn, "_b")) %>% add_list(metric_oob[, mn], paste0(mn, "_oob")) %>% add_list(Acc_b, "acc_b") %>% add_list(Acc_oob, "acc_oob") %>% add_list(Sens_Spec_b[, "sensitivity"], "sensitivity_b") %>% add_list(Sens_Spec_oob[, "sensitivity"], "sensitivity_oob") %>% add_list(Sens_Spec_b[, "specificity"], "specificity_b") %>% add_list(Sens_Spec_oob[, "specificity"], "specificity_oob") %>% add_list(kap_b[, "cohens_kappa"], "cohens_kappa_b") %>% add_list(kap_oob[, "cohens_kappa"], "cohens_kappa_oob") %>% add_list(optcut_b$roc_curve[[1]]$tp[opt_ind_b], "TP_b") %>% add_list(optcut_b$roc_curve[[1]]$fp[opt_ind_b], "FP_b") %>% add_list(optcut_b$roc_curve[[1]]$tn[opt_ind_b], "TN_b") %>% add_list(optcut_b$roc_curve[[1]]$fn[opt_ind_b], "FN_b") %>% add_list(roc_curve_oob$tp[opt_ind_oob], "TP_oob") %>% add_list(roc_curve_oob$fp[opt_ind_oob], "FP_oob") %>% add_list(roc_curve_oob$tn[opt_ind_oob], "TN_oob") %>% add_list(roc_curve_oob$fn[opt_ind_oob], "FN_oob") bootstrap$roc_curve_b = optcut_b$roc_curve roc_curve_oob <- tibble::tibble(roc_curve_oob = list(roc_curve_oob)) bootstrap <- dplyr::bind_cols(bootstrap, tibble::as_tibble(roc_curve_oob)) return(bootstrap) } boot_g <- prepare_bind_rows(boot_g) boot_g <- suppressWarnings(dplyr::bind_rows(boot_g)) return(boot_g) }) missing_reps <- purrr::map_lgl(.x = boot_res, .f = function(x) nrow(x) != boot_runs) if (any(missing_reps)) { # Some repetitions may be missing even when boot_stratify = TRUE # when there's only one class in the out-of-bag data message(paste("Some bootstrap repetitions were removed because", "of missing values or errors.")) } } optcut$boot = boot_res res <- optcut class(res) <- c("cutpointr", class(res)) return(res) } #' Calculate optimal cutpoints and further statistics for multiple predictors #' #' Runs \code{cutpointr} over multiple predictor variables. Tidyeval via #' \code{!!} is supported for \code{class} and \code{subgroup}. If #' \code{x = NULL}, \code{cutpointr} will be run using all numeric columns #' in the data set as predictors except for the #' variable in \code{class} and, if given, \code{subgroup}. #' #' The automatic determination of positive / negative classes and \code{direction} #' will be carried out separately for every predictor variable. That way, if #' \code{direction} and the classes are not specified, the reported AUC for every #' variable will be >= 0.5. AUC may be < 0.5 if subgroups are specified as #' \code{direction} is equal within every subgroup. #' #' @param data A data frame. #' @param x Character vector of predictor variables. If NULL all numeric columns. #' @param class The name of the outcome / independent variable. #' @param subgroup An additional covariate that identifies subgroups. Separate #' optimal cutpoints will be determined per group. #' @param silent Whether to suppress messages. #' @param ... Further arguments to be passed to cutpointr_ (Use a quoted variable #' name for subgroup). #' @examples #' library(cutpointr) #' #' multi_cutpointr(suicide, x = c("age", "dsi"), class = suicide, #' pos_class = "yes") #' #' mcp <- multi_cutpointr(suicide, x = c("age", "dsi"), class = suicide, #' subgroup = gender, pos_class = "yes") #' mcp #' #' (scp <- summary(mcp)) #' \dontrun{ #' ## The result is a data frame #' tibble:::print.tbl(scp) #' } #' #' @return A data frame. #' @importFrom purrr %>% #' @family main cutpointr functions #' @export multi_cutpointr <- function(data, x = NULL, class, subgroup = NULL, silent = FALSE, ...) { if (rlang::as_label(rlang::enquo(subgroup)) == "NULL") { subgroup_lab <- "NULL" } else { subgroup_sym <- rlang::ensym(subgroup) subgroup_lab <- rlang::as_label(subgroup_sym) } if (subgroup_lab != "NULL") { if (subgroup_lab %in% c("TRUE", "FALSE", "T", "F")) { stop(paste("The arguments to multi_cutpointr", "have changed. Please see ?multi_cutpointr")) } } class_sym <- rlang::ensym(class) class_lab <- rlang::as_label(class_sym) if (is.null(x)) x = get_numeric_cols(data, class_lab) if (subgroup_lab != "NULL") { x <- x[x != subgroup_lab] } if (subgroup_lab == "NULL") { res <- purrr::map(x, function(coln) { if (!silent) message(paste0(coln, ":")) cutpointr(data, !!coln, !!class_lab, silent = silent, ...) }) } else { res <- purrr::map(x, function(coln) { if (!silent) message(paste0(coln, ":")) cutpointr(data, !!coln, !!class_lab, subgroup = !!subgroup_lab, silent = silent, ...) }) } res <- suppressWarnings(dplyr::bind_rows(res)) base::class(res) <- c("multi_cutpointr", base::class(res)[-which(base::class(res) == "cutpointr")]) return(res) }cutpointr/R/plot_metric_boot.R0000644000176200001440000000620113770660733016204 0ustar liggesusers#' Plot the bootstrapped metric distribution from a cutpointr object #' #' Given a \code{cutpointr} object this function plots the bootstrapped metric distribution, #' i.e. the distribution of out-of-bag metric values. #' The metric depends on the function that was supplied to \code{metric} in the #' call to \code{cutpointr}. #' The \code{cutpointr} function has to be run with \code{boot_runs}` > 0 to enable bootstrapping. #' @param x A cutpointr object. #' @param ... Additional arguments (unused) #' @examples #' set.seed(300) #' opt_cut <- cutpointr(suicide, dsi, suicide, boot_runs = 10) #' plot_metric_boot(opt_cut) #' @family cutpointr plotting functions #' @importFrom rlang .data #' @export plot_metric_boot <- function(x, ...) { args <- list(...) if (!(has_column(x, "subgroup"))) { dts_boot <- "boot" dts <- "data" transparency <- 1 } else { dts_boot <- c("boot", "subgroup") dts <- c("data", "subgroup") transparency <- 0.6 } if (has_boot_results(x)) { res_boot_unnested <- x %>% dplyr::select(dts_boot) %>% dplyr::mutate(boot = prepare_bind_rows(.data$boot)) %>% tidyr::unnest(.data$boot) %>% dplyr::select(-c("roc_curve_b", "roc_curve_oob")) # If multiple optimal cutpoints optimal_cutpoint is a list if (is.list(res_boot_unnested$optimal_cutpoint)) { res_boot_unnested <- res_boot_unnested %>% tidyr::unnest() } metric_name <- colnames(res_boot_unnested)[5] stopifnot(grepl(pattern = "_oob", x = metric_name)) if (all(na_inf_omit(get(metric_name, res_boot_unnested) %% 1 == 0)) | only_one_unique(na_inf_omit(get(metric_name, res_boot_unnested)))) { all_integer = TRUE dist_plot <- ggplot2::geom_bar(alpha = 1, position = "dodge") } else { all_integer = FALSE dist_plot <- ggplot2::geom_density(alpha = transparency) } if (!(has_column(x, "subgroup"))) { boot_metric <- suppressMessages( ggplot2::ggplot(res_boot_unnested, ggplot2::aes(x = !!rlang::ensym(metric_name))) + dist_plot + ggplot2::ggtitle("Bootstrap", "out-of-bag estimates") + ggplot2::xlab(metric_name) ) } else { boot_metric <- suppressMessages( ggplot2::ggplot(res_boot_unnested, ggplot2::aes(x = !!rlang::ensym(metric_name), fill = subgroup, color = subgroup)) + dist_plot + ggplot2::ggtitle("Bootstrap", "out-of-bag estimates") + ggplot2::xlab(metric_name) ) } if (!all_integer) boot_metric <- boot_metric + ggplot2::geom_rug(alpha = 0.5) } else { stop("No bootstrap results found. Was boot_runs > 0 in cutpointr?") } return(boot_metric) } cutpointr/R/oc_youden_kernel.R0000644000176200001440000000701313604121756016157 0ustar liggesusers#' Determine an optimal cutpoint maximizing the Youden-Index based on kernel smoothed densities #' #' Instead of searching for an optimal cutpoint to maximize (sensitivity + #' specificity - 1) on the ROC curve, this function first smoothes the empirical #' distributions of \code{x} per class. The smoothing is done using a binned kernel #' density estimate. The bandwidth is automatically selected using the direct #' plug-in method. #' #' The functions for calculating the kernel density estimate and the bandwidth #' are both from \pkg{KernSmooth} with default parameters, except for #' the bandwidth selection, which uses the standard deviation as scale estimate. #' #' The cutpoint is estimated as the cutpoint that maximizes the Youden-Index #' given by \eqn{J = max_c {F_N(c) - G_N(c) }} where #' \eqn{J} and \eqn{G} are the smoothed distribution functions. #' #' @inheritParams oc_youden_normal #' @source Fluss, R., Faraggi, D., & Reiser, B. (2005). Estimation of the #' Youden Index and its associated cutoff point. Biometrical Journal, 47(4), 458–472. #' @source Matt Wand (2015). KernSmooth: Functions for Kernel Smoothing #' Supporting Wand & Jones (1995). R package version 2.23-15. #' https://CRAN.R-project.org/package=KernSmooth #' @examples #' data(suicide) #' if (require(KernSmooth)) { #' oc_youden_kernel(suicide, "dsi", "suicide", oc_metric = "Youden", #' pos_class = "yes", neg_class = "no", direction = ">=") #' ## Within cutpointr #' cutpointr(suicide, dsi, suicide, method = oc_youden_kernel) #' } #' @family method functions #' @export oc_youden_kernel <- function(data, x, class, pos_class, neg_class, direction, ...) { stopifnot(is.character(x)) stopifnot(is.character(class)) iv <- unlist(data[, x]) cla <- unlist(data[, class]) if (direction %in% c(">", ">=")) { x_pos <- iv[cla == pos_class] x_neg <- iv[cla == neg_class] } else { x_neg <- iv[cla == pos_class] x_pos <- iv[cla == neg_class] } bw_n <- KernSmooth::dpik(x_neg, "stdev") neg_k <- KernSmooth::bkde(x_neg, bandwidth = bw_n) bw_p <- KernSmooth::dpik(x_pos, "stdev") pos_k <- KernSmooth::bkde(x_pos, bandwidth = bw_p) oc <- suppressWarnings(stats::optimize( f = youden_kern, interval = c(min(c(x_pos, x_neg)), max(c(x_pos, x_neg))), maximum = TRUE, neg_k = neg_k, pos_k = pos_k )$maximum) # Extremely high or low cutoffs can result in some scenarios if (oc < min(c(x_neg, x_pos))) { warning(paste("Cutpoint", oc, "was restricted to range of independent variable")) oc <- min(c(x_neg, x_pos)) } else if (oc > max(c(x_neg, x_pos))) { warning(paste("Cutpoint", oc, "was restricted to range of independent variable")) oc <- max(c(x_neg, x_pos)) } return(data.frame(optimal_cutpoint = oc)) } youden_kern <- function(threshold = NULL, neg_k, pos_k) { youden <- vector_auc(neg_k$x, neg_k$y, to = threshold) - vector_auc(pos_k$x, pos_k$y, to = threshold) return(youden) } #' @source Forked from MESS vector_auc <- function (x, y, from = min(x), to = max(x), ...) { if (length(x) != length(y)) stop("x and y must have the same length") if (length(unique(x)) < 2) return(NA) if (to > max(x)) to <- max(x) values <- stats::approx(x, y, xout = sort(unique(c(from, to, x[x > from & x < to]))), ...) res <- 0.5 * sum(diff(values$x) * (values$y[-1] + values$y[-length(values$y)])) res } cutpointr/R/roc.R0000644000176200001440000001050513604121756013416 0ustar liggesusers#' Calculate a ROC curve #' #' Given a \code{data.frame} with a numeric predictor variable and a binary outcome #' variable this function returns a \code{data.frame} that includes all elements of #' the confusion matrix (true positives, false positives, true negatives, #' and false negatives) for every unique value of the predictor variable. #' Additionally, the true positive rate (tpr), false positive rate (fpr), #' true negative rate (tnr) and false negative rate (fnr) are returned. #' #' To enable classifying all observations as belonging to only one class the #' predictor values will be augmented by Inf or -Inf. The returned object can #' be plotted with plot_roc. #' #' This function uses tidyeval to support unquoted arguments. For programming #' with \code{roc} the operator \code{!!} can be used to unquote an argument, #' see the examples. #' #' @param data A data.frame or matrix. Will be converted to a data.frame. #' @param x The name of the numeric predictor variable. #' @param class The name of the binary outcome variable. #' @param pos_class The value of 'class' that represents the positive cases. #' @param neg_class The value of 'class' that represents the negative cases. #' @param direction (character) One of ">=" or "<=". Specifies if the positive #' class is associated with higher values of x (default). #' @param silent If FALSE and the ROC curve contains no positives or negatives, #' a warning is generated. #' @return A data frame with the columns x.sorted, tp, fp, tn, fn, tpr, tnr, fpr, #' and fnr. #' @examples #' roc_curve <- roc(data = suicide, x = dsi, class = suicide, #' pos_class = "yes", neg_class = "no", direction = ">=") #' roc_curve #' plot_roc(roc_curve) #' auc(roc_curve) #' #' ## Unquoting an argument #' myvar <- "dsi" #' roc(suicide, x = !!myvar, suicide, pos_class = "yes", neg_class = "no") #' @export #' @family main cutpointr functions #' @source #' Forked from the \pkg{ROCR} package roc <- function(data, x, class, pos_class, neg_class, direction = ">=", silent = FALSE) { stopifnot(direction %in% c(">=", "<=")) data <- as.data.frame(data) x_sym <- rlang::ensym(x) x_expr <- rlang::enexpr(x_sym) x <- rlang::eval_tidy(expr = x_expr, data = data) class_sym <- rlang::ensym(class) class_expr <- rlang::enexpr(class_sym) class <- rlang::eval_tidy(expr = class_expr, data = data) if (direction == ">=") { pred.order <- order(x, decreasing = TRUE) x.sorted <- x[pred.order] dups <- rev(duplicated(rev(x.sorted))) x.sorted <- x.sorted[!dups] class.sorted <- class[pred.order] tp <- cumsum(is_equal_cpp(class.sorted, pos_class)) tp <- tp[!dups] fp <- cumsum(is_equal_cpp(class.sorted, neg_class)) fp <- fp[!dups] n_pos <- tp[length(tp)] n_neg <- length(class) - n_pos tn <- n_neg - fp fn <- n_pos + n_neg - tp - fp - tn if (!(any_inf(x.sorted))) { x.sorted <- c(Inf, x.sorted) class.sorted <- c(NA, class.sorted) tp <- c(0, tp) fp <- c(0, fp) tn <- c(n_neg, tn) fn <- c(n_pos, fn) } } else if (direction == "<=") { pred.order <- order(x, decreasing = FALSE) x.sorted <- x[pred.order] dups <- rev(duplicated(rev(x.sorted))) x.sorted <- x.sorted[!dups] class.sorted <- class[pred.order] tp <- cumsum(is_equal_cpp(class.sorted, pos_class)) tp <- tp[!dups] fp <- cumsum(is_equal_cpp(class.sorted, neg_class)) fp <- fp[!dups] n_pos <- tp[length(tp)] n_neg <- length(class) - n_pos tn <- n_neg - fp fn <- n_pos + n_neg - tp - fp - tn if (!(any_inf(x.sorted))) { x.sorted <- c(-Inf, x.sorted) class.sorted <- c(NA, class.sorted) tp <- c(0, tp) fp <- c(0, fp) tn <- c(n_neg, tn) fn <- c(n_pos, fn) } } tpr <- tp / n_pos tnr <- tn / n_neg fpr <- 1 - tnr fnr <- 1 - tpr res <- tibble::tibble(x.sorted, tp, fp, tn, fn, tpr, tnr, fpr, fnr) class(res) <- c("roc_cutpointr", class(res)) if (!silent) { if (is.nan(res$tpr[1])) warning("ROC curve contains no positives") if (res$fpr[1] == 0 & res$fpr[nrow(res)] == 0) warning("ROC curve contains no negatives") } return(res) } cutpointr/R/oc_manual.R0000644000176200001440000000110613475240564014573 0ustar liggesusers#' Set a manual cutpoint for use with cutpointr #' #' This function simply returns \code{cutpoint} as the optimal cutpoint. #' Mainly useful if bootstrap estimates of the out-of-bag performance of a #' given cutpoint are desired, e.g. taking a cutpoint value from the literature. #' #' @inheritParams oc_youden_normal #' @param cutpoint (numeric) The fixed cutpoint. #' @examples #' cutpointr(suicide, dsi, suicide, method = oc_manual, cutpoint = 4) #' @family method functions #' @export oc_manual <- function(cutpoint, ...) { return(data.frame(optimal_cutpoint = cutpoint)) } cutpointr/R/globals.R0000644000176200001440000000053113721440430014245 0ustar liggesusersutils::globalVariables(c("x.sorted", "m", "subgroup", "Sensitivity", "Specificity", "value", "metric", "Precision", "Recall", "optimal_cutpoint", "ymin", "ymax", "m_unsmoothed", "direction", "method", "AUC", "boot", "TP_b", "roc_curve_oob"))cutpointr/R/plot.cutpointr.R0000644000176200001440000000312613672457720015650 0ustar liggesusers#' Plot cutpointr objects #' #' The plot layout depends on whether subgroups were defined and whether #' bootstrapping was run. #' #' The \code{...} argument can be used to apply \pkg{ggplot2} functions to every individual #' plot, for example for changing the theme. #' #' @param x A cutpointr object. #' @param ... Further arguments. #' @examples #' opt_cut <- cutpointr(suicide, dsi, suicide, gender) #' plot(opt_cut) #' plot(opt_cut, ggplot2::theme_bw()) #' @family cutpointr plotting functions #' @export plot.cutpointr <- function(x, ...) { if ("multi_cutpointr" %in% class(x)) { stop("Plotting multi_cutpointr objects is not supported.") } args <- list(...) dist <- plot_x(x) roc <- plot_roc(x) boot_flag <- has_boot_results(x) if (boot_flag) { boot_cut <- plot_cut_boot(x) boot_metric <- plot_metric_boot(x) } else { boot_cut <- NULL boot_metric <- NULL } # # Compose plots # plots <- list(dist, roc, boot_cut, boot_metric) keep <- !(purrr::map_lgl(plots, is.null)) plots <- plots[keep] plots <- lapply(plots, function(p) p + args) rows <- round(sum(keep) / 2) pos <- ifelse(rows > 1, "right", "bottom") # suppressMessages(p <- grid_arrange_shared_legend(plots, # nrow = rows, ncol = 2, # position = pos)) # invisible(p) grid_arrange_shared_legend(plots, nrow = rows, ncol = 2, position = pos) } cutpointr/R/data.R0000644000176200001440000000376614066360614013560 0ustar liggesusers#' Suicide attempts and DSI sum scores of 532 subjects #' #' Various personality and clinical psychological characteristics were assessed #' as part of an online-study preventing suicide. To identify persons at risk #' for attempting suicide, various demographic and clinical characteristics #' were assessed. Depressive Symptom Inventory - Suicidality Subscale #' (DSA-SS) sum scores and past suicide attempts from 532 subjects are #' included as a demonstration set to calculate optimal cutpoints. Two #' additional demographic variables (age, gender) are also included to test #' for group differences. #' #' @format A data frame with 532 rows and 4 variables: #' \describe{ #' \item{age}{(numeric) Age of participants in years} #' \item{gender}{(factor) Gender} #' \item{dsi}{(numeric) Sum-score (0 = low suicidality, 12 = high suicidality)} #' \item{suicide}{(factor) Past suicide attempt (no = no attempt, yes = at least one attempt)} #' } #' @source von Glischinski, M., Teisman, T., Prinz, S., Gebauer, J., and Hirschfeld, G. (2017). Depressive Symptom Inventory- Suicidality Subscale: Optimal cut points for clinical and non-clinical samples. Clinical Psychology & Psychotherapy "suicide" #' Nodal involvement and acid phosphatase levels in 53 prostate cancer patients #' #' Prostatic acid phosphatase (PAP) emerged as the first clinically #' useful tumor marker in the 1940s and 1950s. This data set contains the #' serum levels of acid phosphatase of 53 patients that were confirmed to #' have prostate cancer and whether the neighboring lymph nodes were involved. #' #' @format A data frame with 53 rows and 2 variables: #' \describe{ #' \item{acid_phosphatase}{(numeric) Blood serum level of acid phosphatase} #' \item{nodal_involvement}{(logical) Whether neighboring lymph nodes were involved} #' } #' @source Le CT (2006). A solution for the most basic optimization problem associated with an ROC curve. Statistical methods in medical research 15: 571–584 "prostate_nodal"cutpointr/R/plot_metric.R0000644000176200001440000001541413764660457015175 0ustar liggesusers#' Plot a metric over all possible cutoffs from a cutpointr object #' #' If \code{maximize_metric} is used as \code{method} function in cutpointr the computed #' metric values over all possible cutoffs can be plotted. Generally, this #' works for method functions that return a ROC-curve including the metric #' value for every cutpoint along with the optimal cutpoint. #' #' @param x A cutpointr object. #' @param conf_lvl The confidence level of the bootstrap confidence interval. #' Set to 0 to draw no bootstrap confidence interval. #' @param add_unsmoothed Add the line of unsmoothed metric values to the plot. #' Applicable for some smoothing methods, e.g. maximize_gam_metric. #' @examples #' opt_cut <- cutpointr(suicide, dsi, suicide) #' plot_metric(opt_cut) #' @importFrom dplyr %>% #' @family cutpointr plotting functions #' @family cutpointr plotting functions #' @export plot_metric <- function(x, conf_lvl = 0.95, add_unsmoothed = TRUE) { if (!("cutpointr" %in% class(x))) { stop("Only cutpointr objects are supported.") } if (!(has_column(x$roc_curve[[1]], "m"))) { stop(paste("The cutpointr object does not include a metric column in", "roc_curve - maybe because a method other than", "maximize_metric or minimize_metric was used")) } if (has_boot_results(x) & conf_lvl != 0) { if (has_column(x, "subgroup")) { roc_b_unnested <- x %>% dplyr::select(c("boot", "subgroup")) %>% dplyr::mutate(boot = prepare_bind_rows(.data$boot)) %>% tidyr::unnest(.data$boot) %>% dplyr::select(c("subgroup", "roc_curve_b")) %>% tidyr::unnest(.data$roc_curve_b) roc_b_unnested <- roc_b_unnested[is.finite(roc_b_unnested$x.sorted), ] roc_b_unnested <- roc_b_unnested %>% dplyr::select(c("x.sorted", "m", "subgroup")) %>% dplyr::group_by(.data$x.sorted, .data$subgroup) %>% dplyr::summarise(ymin = stats::quantile(.data$m, (1 - conf_lvl) / 2, na.rm = TRUE), ymax = stats::quantile(.data$m, 1 - (1 - conf_lvl) / 2, na.rm = TRUE)) } else { # No subgroups, but bootstrap roc_b_unnested <- x[["boot"]][[1]] %>% tidyr::unnest(.data$roc_curve_b) roc_b_unnested <- roc_b_unnested[is.finite(roc_b_unnested$x.sorted), ] roc_b_unnested <- roc_b_unnested %>% dplyr::select(c("x.sorted", "m")) %>% dplyr::group_by(.data$x.sorted) %>% dplyr::summarise(ymin = stats::quantile(.data$m, (1 - conf_lvl) / 2, na.rm = TRUE), ymax = stats::quantile(.data$m, 1 - (1 - conf_lvl) / 2, na.rm = TRUE)) } } metric_name <- find_metric_name(x) if ("subgroup" %in% colnames(x)) { res_unnested <- x %>% dplyr::select(c("roc_curve", "subgroup")) %>% tidyr::unnest(.data$roc_curve) res_unnested <- res_unnested[is.finite(res_unnested$x.sorted), ] if (has_boot_results(x) & conf_lvl != 0) { res_unnested <- merge(res_unnested, roc_b_unnested[, c("subgroup", "x.sorted", "ymin", "ymax")], by = c("x.sorted", "subgroup")) p <- ggplot2::ggplot(res_unnested, ggplot2::aes(x = x.sorted, y = m, ymin = ymin, ymax = ymax, color = subgroup, fill = subgroup)) + ggplot2::geom_line() + ggplot2::geom_point() + ggplot2::ylab(metric_name) + ggplot2::xlab("Cutpoint") + ggplot2::geom_ribbon(alpha = 0.2, size = 0) } else { p <- ggplot2::ggplot(res_unnested, ggplot2::aes(x = x.sorted, y = m, color = subgroup)) + ggplot2::geom_line() + ggplot2::geom_point() + ggplot2::ylab(metric_name) + ggplot2::xlab("Cutpoint") } if (add_unsmoothed & has_column(res_unnested, "m_unsmoothed")) { p <- p + ggplot2::geom_line(data = res_unnested, linetype = "dashed", mapping = ggplot2::aes(x = x.sorted, y = m_unsmoothed, color = subgroup)) } } else { # No subgroups res_unnested <- x %>% dplyr::select(.data$roc_curve) %>% tidyr::unnest(.data$roc_curve) res_unnested <- res_unnested[is.finite(res_unnested$x.sorted), ] if (has_boot_results(x) & conf_lvl != 0) { res_unnested <- merge(res_unnested, roc_b_unnested[, c("x.sorted", "ymin", "ymax")], by = "x.sorted") p <- ggplot2::ggplot(res_unnested, ggplot2::aes(x = x.sorted, y = m, ymax = ymax, ymin = ymin)) + ggplot2::geom_line() + ggplot2::geom_point() + ggplot2::ylab(metric_name) + ggplot2::xlab("Cutpoint") + ggplot2::geom_ribbon(alpha = 0.2, size = 0) } else { p <- ggplot2::ggplot(res_unnested, ggplot2::aes(x = x.sorted, y = m)) + ggplot2::geom_line() + ggplot2::geom_point() + ggplot2::ylab(metric_name) + ggplot2::xlab("Cutpoint") } if (add_unsmoothed & has_column(res_unnested, "m_unsmoothed")) { p <- p + ggplot2::geom_line(data = res_unnested, linetype = "dashed", mapping = ggplot2::aes(x = x.sorted, y = m_unsmoothed)) } } if (add_unsmoothed & has_column(res_unnested, "m_unsmoothed")) { p <- p + ggplot2::ggtitle("Metric values by cutpoint value", "in-sample results, unsmoothed values as dashed line") } else { p <- p + ggplot2::ggtitle("Metric values by cutpoint value", "in-sample results") } return(p) } cutpointr/R/print.cutpointr.R0000644000176200001440000000162313475240564016023 0ustar liggesusers#' Print cutpointr objects #' #' Prints the \code{cutpointr} object with full width like a \code{tbl_df}. #' #' @source Kirill Müller and Hadley Wickham (2017). tibble: Simple Data Frames. #' https://CRAN.R-project.org/package=tibble #' @param x a cutpointr object. #' @param width width of output. #' @param n number of rows to print. #' @param sigfig Number of significant digits to print. Temporarily #' overrides options("pillar.sigfig"). #' @param ... further arguments. #' @export print.cutpointr <- function(x, width = 1000, n = 50, sigfig = 6, ...) { # print.tbl_df is not exported by tibble, avoid ::: class(x) <- c("tbl_df", "tbl", "data.frame") old_sigfig <- options("pillar.sigfig") options(pillar.sigfig = sigfig) print(x, width = width, n = n) options(pillar.sigfig = old_sigfig$pillar.sigfig) class(x) <- c("cutpointr", "tbl_df", "tbl", "data.frame") invisible(x) } cutpointr/R/plot_sensitivity_specificity.R0000644000176200001440000000621513766660344020673 0ustar liggesusers#' Sensitivity and specificity plot from a cutpointr object #' #' Given a \code{cutpointr} object this function plots the sensitivity and specificity #' curve(s) per subgroup, if the latter is given. #' @param x A cutpointr object. #' @param display_cutpoint (logical) Whether or not to display the optimal #' cutpoint as a dot on the precision recall curve. #' @param ... Additional arguments (unused). #' @examples #' library(cutpointr) #' #' ## Optimal cutpoint for dsi #' data(suicide) #' opt_cut <- cutpointr(suicide, dsi, suicide) #' plot_sensitivity_specificity(opt_cut) #' @family cutpointr plotting functions #' @export #' @importFrom purrr %>% plot_sensitivity_specificity <- function(x, display_cutpoint = TRUE, ...) { if (!("cutpointr" %in% class(x))) { stop("Only cutpointr objects are supported.") } args <- list(...) if (!(has_column(x, "subgroup"))) { dts_pr <- c("roc_curve", "optimal_cutpoint") } else { dts_pr <- c("roc_curve", "subgroup", "optimal_cutpoint") } plot_title <- ggplot2::ggtitle("Sensitivity and Specificity Plot") for (r in 1:nrow(x)) { x$roc_curve[[r]] <- x$roc_curve[[r]] %>% dplyr::mutate(Sensitivity = tp / (tp + fn), Specificity = tn / (tn + fp)) } res_unnested <- x %>% dplyr::select(dts_pr) %>% tidyr::unnest(.data$roc_curve) res_unnested <- res_unnested[is.finite(res_unnested$x.sorted), ] res_unnested <- tidyr::gather(res_unnested, key = "metric", value = "value", Sensitivity, Specificity) if (!(has_column(x, "subgroup"))) { pr <- ggplot2::ggplot(res_unnested, ggplot2::aes(x = x.sorted, y = value, color = metric)) } else { pr <- ggplot2::ggplot(res_unnested, ggplot2::aes(x = x.sorted, y = value, color = metric, linetype = subgroup)) } pr <- pr + ggplot2::geom_line() + plot_title + ggplot2::xlab("Cutpoint") + ggplot2::ylab("Sensitivity and Specificity") if (display_cutpoint) { if (!(has_column(x, "subgroup"))) { res_cutpoints <- x %>% dplyr::select(.data$optimal_cutpoint) if (is.list(res_cutpoints$optimal_cutpoint)) { res_cutpoints <- tidyr::unnest(res_cutpoints) } pr <- pr + ggplot2::geom_vline(data = res_cutpoints, ggplot2::aes(xintercept = optimal_cutpoint)) } else { res_cutpoints <- x %>% dplyr::select(.data$optimal_cutpoint, .data$subgroup) if (is.list(res_cutpoints$optimal_cutpoint)) { res_cutpoints <- tidyr::unnest(res_cutpoints) } pr <- pr + ggplot2::geom_vline(data = res_cutpoints, ggplot2::aes(xintercept = optimal_cutpoint, linetype = subgroup)) } } return(pr) } cutpointr/R/optimize_metric.R0000644000176200001440000010037213764665743016060 0ustar liggesusersoptimize_metric <- function(data, x, class, metric_func = youden, pos_class = NULL, neg_class = NULL, minmax, direction, metric_name = "metric", loess = FALSE, spline = FALSE, gam = FALSE, return_roc = TRUE, tol_metric, use_midpoints, ...) { args <- list(...) metric_name_call <- as.character(substitute(metric_func)) if (metric_name_call != "metric_func") metric_name <- metric_name_call roccurve <- roc(data = data, x = !!x, class = !!class, pos_class = pos_class, neg_class = neg_class, direction = direction) m <- metric_func(tp = roccurve[["tp"]], fp = roccurve[["fp"]], tn = roccurve[["tn"]], fn = roccurve[["fn"]], ...) m <- sanitize_metric(m, m_name = metric_name, n = nrow(roccurve)) roccurve$m <- as.numeric(m) if (!is.null(colnames(m))) metric_name <- colnames(m) if (loess) { roccurve$m_unsmoothed <- roccurve$m finite_x <- is.finite(roccurve$x.sorted) finite_m <- is.finite(roccurve$m) finite_roc <- (finite_x + finite_m) == 2 mod <- fANCOVA::loess.as(x = roccurve$x.sorted[finite_roc], y = roccurve$m[finite_roc], criterion = args$criterion, degree = args$degree, family = args$family, user.span = args$user.span) roccurve$m <- NA roccurve$m[finite_roc] <- mod$fitted } if (spline) { roccurve$m_unsmoothed <- roccurve$m finite_x <- is.finite(roccurve$x.sorted) finite_m <- is.finite(roccurve$m) finite_roc <- (finite_x + finite_m) == 2 if (is.function(args$nknots)) { nknots <- args$nknots(data = data, x = x) message(paste("nknots:", nknots)) } else if (is.numeric(args$nknots)) { nknots <- args$nknots } if (!is.null(args[["df"]])) { mod <- stats::smooth.spline(x = roccurve$x.sorted[finite_roc], y = roccurve$m[finite_roc], w = args[["w"]], spar = args[["spar"]], cv = FALSE, df = args[["df"]], nknots = nknots, df.offset = args[["df_offset"]], penalty = args[["penalty"]], control.spar = args[["control_spar"]], tol = 1e-100) } else { mod <- stats::smooth.spline(x = roccurve$x.sorted[finite_roc], y = roccurve$m[finite_roc], w = args[["w"]], spar = args[["spar"]], cv = FALSE, nknots = nknots, df.offset = args[["df_offset"]], penalty = args[["penalty"]], control.spar = args[["control_spar"]], tol = 1e-100) } # smooth.spline builds bins of x values that are closer to each other # than tol, so not all original x values may be returned if (length(mod$x) != sum(finite_roc)) { stop("Not all original x values returned by smooth.spline") } roccurve$m <- NA roccurve$m[finite_roc] <- rev(mod$y) } if (gam) { roccurve$m_unsmoothed <- roccurve$m finite_x <- is.finite(roccurve$x.sorted) finite_m <- is.finite(roccurve$m) finite_roc <- (finite_x + finite_m) == 2 mod <- mgcv::gam(stats::as.formula(paste(paste0(args$formula[2], " ~"), args$formula[3])), data = roccurve[finite_roc, ], optimizer = args[["optimizer"]]) roccurve$m <- NA roccurve$m[finite_roc] <- mod$fitted.values } if (minmax == "max") { m_vals <- stats::na.omit(roccurve$m) if (length(m_vals) == 0) stop("All metric values are missing.") max_m <- max(m_vals) opt <- which((roccurve$m >= (max_m - tol_metric)) & (roccurve$m <= (max_m + tol_metric))) oc <- roccurve[["x.sorted"]][opt] m_oc <- max_m } else if (minmax == "min") { m_vals <- stats::na.omit(roccurve$m) if (length(m_vals) == 0) stop("All metric values are missing.") min_m <- min(m_vals) opt <- which((roccurve$m >= (min_m - tol_metric)) & (roccurve$m <= (min_m + tol_metric))) oc <- roccurve[["x.sorted"]][opt] m_oc <- min_m } if (length(oc) > 1) { res <- tibble::tibble(optimal_cutpoint = list(oc)) if (use_midpoints) { res$optimal_cutpoint <- list(midpoint(oc = unlist(res$optimal_cutpoint), x = unlist(data[, x], use.names = FALSE), direction = direction)) } } else { res <- tibble::tibble(optimal_cutpoint = oc) if (use_midpoints) { res$optimal_cutpoint <- midpoint(oc = unlist(res$optimal_cutpoint), x = unlist(data[, x], use.names = FALSE), direction = direction) } } if (return_roc) { res$roc_curve <- list(roccurve) } if (loess) metric_name <- paste0("loess_", metric_name) if (spline) metric_name <- paste0("spline_", metric_name) if (gam) metric_name <- paste0("gam_", metric_name) res[, metric_name] <- m_oc return(res) } #' Optimize a metric function in binary classification #' #' Given a function for computing a metric in \code{metric_func}, these functions #' maximize or minimize that metric by selecting an optimal cutpoint. #' The metric function should accept the following inputs: #' \itemize{ #' \item \code{tp}: vector of number of true positives #' \item \code{fp}: vector of number of false positives #' \item \code{tn}: vector of number of true negatives #' \item \code{fn}: vector of number of false negatives #' } #' #' The above inputs are arrived at by using all unique values in \code{x}, Inf, or #' -Inf as possible cutpoints for classifying the variable in class. #' #' @return A tibble with the columns \code{optimal_cutpoint}, the corresponding metric #' value and \code{roc_curve}, a nested tibble that includes all possible cutoffs #' and the corresponding numbers of true and false positives / negatives and #' all corresponding metric values. #' #' @inheritParams oc_youden_normal #' @param metric_func (function) A function that computes a #' metric to be maximized. See description. #' @param tol_metric All cutpoints will be returned that lead to a metric #' value in the interval [m_max - tol_metric, m_max + tol_metric] where #' m_max is the maximum achievable metric value. This can be used to return #' multiple decent cutpoints and to avoid floating-point problems. #' @param use_midpoints (logical) If TRUE (default FALSE) the returned optimal #' cutpoint will be the mean of the optimal cutpoint and the next highest #' observation (for direction = ">") or the next lowest observation #' (for direction = "<") which avoids biasing the optimal cutpoint. #' @param ... Further arguments that will be passed to \code{metric_func}. #' @examples #' cutpointr(suicide, dsi, suicide, method = maximize_metric, metric = accuracy) #' @name maximize_metric #' @family method functions #' @export maximize_metric <- function(data, x, class, metric_func = youden, pos_class = NULL, neg_class = NULL, direction, tol_metric, use_midpoints, ...) { metric_name <- as.character(substitute(metric_func)) optimize_metric(data = data, x = x, class = class, metric_func = metric_func, pos_class = pos_class, neg_class = neg_class, minmax = "max", direction = direction, metric_name = metric_name, tol_metric = tol_metric, use_midpoints = use_midpoints, ...) } #' @examples #' cutpointr(suicide, dsi, suicide, method = minimize_metric, metric = abs_d_sens_spec) #' @rdname maximize_metric #' @export minimize_metric <- function(data, x, class, metric_func = youden, pos_class = NULL, neg_class = NULL, direction, tol_metric, use_midpoints, ...) { metric_name <- as.character(substitute(metric_func)) optimize_metric(data = data, x = x, class = class, metric_func = metric_func, pos_class = pos_class, neg_class = neg_class, minmax = "min", direction = direction, metric_name = metric_name, tol_metric = tol_metric, use_midpoints = use_midpoints, ...) } #' Optimize a metric function in binary classification after LOESS smoothing #' #' Given a function for computing a metric in \code{metric_func}, these functions #' smooth the function of metric value per cutpoint using LOESS, then #' maximize or minimize the metric by selecting an optimal cutpoint. For further details #' on the LOESS smoothing see \code{?fANCOVA::loess.as}. #' The \code{metric} function should accept the following inputs: #' \itemize{ #' \item \code{tp}: vector of number of true positives #' \item \code{fp}: vector of number of false positives #' \item \code{tn}: vector of number of true negatives #' \item \code{fn}: vector of number of false negatives #' } #' #' The above inputs are arrived at by using all unique values in \code{x}, Inf, and #' -Inf as possible cutpoints for classifying the variable in class. #' #' @return A tibble with the columns \code{optimal_cutpoint}, the corresponding metric #' value and \code{roc_curve}, a nested tibble that includes all possible cutoffs #' and the corresponding numbers of true and false positives / negatives and #' all corresponding metric values. #' #' @inheritParams oc_youden_normal #' @param metric_func (function) A function that computes a #' metric to be maximized. See description. #' @param criterion the criterion for automatic smoothing parameter selection: #' "aicc" denotes bias-corrected AIC criterion, "gcv" denotes generalized #' cross-validation. #' @param degree the degree of the local polynomials to be used. It can be #' 0, 1 or 2. #' @param family if "gaussian" fitting is by least-squares, and if "symmetric" #' a re-descending M estimator is used with Tukey's biweight function. #' @param user.span The user-defined parameter which controls the degree of #' smoothing #' @param tol_metric All cutpoints will be returned that lead to a metric #' value in the interval [m_max - tol_metric, m_max + tol_metric] where #' m_max is the maximum achievable metric value. This can be used to return #' multiple decent cutpoints and to avoid floating-point problems. #' @param use_midpoints (logical) If TRUE (default FALSE) the returned optimal #' cutpoint will be the mean of the optimal cutpoint and the next highest #' observation (for direction = ">") or the next lowest observation #' (for direction = "<") which avoids biasing the optimal cutpoint. #' @param ... Further arguments that will be passed to metric_func or the #' loess smoother. #' #' @source Xiao-Feng Wang (2010). fANCOVA: Nonparametric Analysis of Covariance. #' https://CRAN.R-project.org/package=fANCOVA #' @source Leeflang, M. M., Moons, K. G., Reitsma, J. B., & Zwinderman, A. H. #' (2008). Bias in sensitivity and specificity caused by data-driven selection #' of optimal cutoff values: mechanisms, magnitude, and solutions. #' Clinical Chemistry, (4), 729–738. #' @examples #' oc <- cutpointr(suicide, dsi, suicide, gender, method = maximize_loess_metric, #' criterion = "aicc", family = "symmetric", degree = 2, user.span = 0.7, #' metric = accuracy) #' plot_metric(oc) #' @name maximize_loess_metric #' @family method functions #' @export maximize_loess_metric <- function(data, x, class, metric_func = youden, pos_class = NULL, neg_class = NULL, direction, criterion = "aicc", degree = 1, family = "symmetric", user.span = NULL, tol_metric, use_midpoints, ...) { if (!requireNamespace("fANCOVA", quietly = TRUE)) { stop("fANCOVA package has to be installed to use LOESS smoothing.") } metric_name <- as.character(substitute(metric_func)) if (is.function(user.span)) { us <- user.span(data = data, x = x) } else { us <- user.span } optimize_metric(data = data, x = x, class = class, metric_func = metric_func, pos_class = pos_class, neg_class = neg_class, minmax = "max", direction = direction, metric_name = metric_name, criterion = criterion, degree = degree, family = family, user.span = us, loess = TRUE, tol_metric = tol_metric, use_midpoints = use_midpoints, ...) } #' @examples #' oc <- cutpointr(suicide, dsi, suicide, gender, method = minimize_loess_metric, #' criterion = "aicc", family = "symmetric", degree = 2, user.span = 0.7, #' metric = misclassification_cost, cost_fp = 1, cost_fn = 10) #' plot_metric(oc) #' @rdname maximize_loess_metric #' @export minimize_loess_metric <- function(data, x, class, metric_func = youden, pos_class = NULL, neg_class = NULL, direction, criterion = "aicc", degree = 1, family = "symmetric", user.span = NULL, tol_metric, use_midpoints, ...) { if (!requireNamespace("fANCOVA", quietly = TRUE)) { stop("fANCOVA package has to be installed to use LOESS smoothing.") } metric_name <- as.character(substitute(metric_func)) if (is.function(user.span)) { us <- user.span(data = data, x = x) } else { us <- user.span } optimize_metric(data = data, x = x, class = class, metric_func = metric_func, pos_class = pos_class, neg_class = neg_class, minmax = "min", direction = direction, metric_name = metric_name, criterion = criterion, degree = degree, family = family, loess = TRUE, user.span = us, tol_metric = tol_metric, use_midpoints = use_midpoints, ...) } #' Calculate bandwidth for LOESS smoothing of metric functions by rule of thumb #' #' This function implements a rule of thumb for selecting the bandwidth when #' smoothing a function of metric values per cutpoint value, particularly #' in \code{maximize_loess_metric} and \code{minimize_loess_metric}. #' #' The function used for calculating the bandwidth is 0.1 * xsd / sqrt(xn), #' where xsd is the standard deviation of the unique values of the predictor #' variable (i.e. all cutpoints) and xn is the number of unique predictor values. #' #' @param data A data frame #' @param x The predictor variable user_span_cutpointr <- function(data, x) { finite_x <- is.finite(data[[x]]) xsd <- stats::sd(data[[x]][finite_x], na.rm = TRUE) xn <- length(unique(data[[x]][finite_x])) print(0.1 * xsd / sqrt(xn)) return(0.1 * xsd / sqrt(xn)) } #' Optimize a metric function in binary classification after bootstrapping #' #' Given a function for computing a metric in \code{metric_func}, these functions #' bootstrap the data \code{boot_cut} times and #' maximize or minimize the metric by selecting an optimal cutpoint. The returned #' optimal cutpoint is the result of applying \code{summary_func}, e.g. the mean, #' to all optimal cutpoints that were determined in the bootstrap samples. #' The \code{metric} function should accept the following inputs: #' \itemize{ #' \item \code{tp}: vector of number of true positives #' \item \code{fp}: vector of number of false positives #' \item \code{tn}: vector of number of true negatives #' \item \code{fn}: vector of number of false negatives #' } #' #' The above inputs are arrived at by using all unique values in \code{x}, Inf, and #' -Inf as possible cutpoints for classifying the variable in class. #' The reported metric represents the usual in-sample performance of the #' determined cutpoint. #' #' @return A tibble with the column \code{optimal_cutpoint} #' #' @inheritParams oc_youden_normal #' @param metric_func (function) A function that computes a single number #' metric to be maximized. See description. #' @param summary_func (function) After obtaining the bootstrapped optimal #' cutpoints this function, e.g. mean or median, is applied to arrive at a single cutpoint. #' @param boot_cut (numeric) Number of bootstrap repetitions over which the mean #' optimal cutpoint is calculated. #' @param boot_stratify (logical) If the bootstrap is stratified, bootstrap #' samples are drawn in both classes and then combined, keeping the number of #' positives and negatives constant in every resample. #' @param inf_rm (logical) whether to remove infinite cutpoints before #' calculating the summary. #' @param tol_metric All cutpoints will be passed to \code{summary_func} #' that lead to a metric #' value in the interval [m_max - tol_metric, m_max + tol_metric] where #' m_max is the maximum achievable metric value. This can be used to return #' multiple decent cutpoints and to avoid floating-point problems. #' @param use_midpoints (logical) If TRUE (default FALSE) the returned optimal #' cutpoint will be the mean of the optimal cutpoint and the next highest #' observation (for direction = ">") or the next lowest observation #' (for direction = "<") which avoids biasing the optimal cutpoint. #' #' @examples #' set.seed(100) #' cutpointr(suicide, dsi, suicide, method = maximize_boot_metric, #' metric = accuracy, boot_cut = 30) #' @name maximize_boot_metric #' @family method functions #' @export maximize_boot_metric <- function(data, x, class, metric_func = youden, pos_class = NULL, neg_class = NULL, direction, summary_func = mean, boot_cut = 50, boot_stratify, inf_rm = TRUE, tol_metric, use_midpoints, ...) { metric_name <- as.character(substitute(metric_func)) if (boot_stratify) { ind_pos <- which(unlist(data[, class]) == pos_class) ind_neg <- which(unlist(data[, class]) == neg_class) } else { ind_pos <- NA ind_neg <- NA } optimal_cutpoints <- purrr::map(1:boot_cut, function(i) { b_ind <- simple_boot(data = data, ind_pos = ind_pos, ind_neg = ind_neg, dep_var = class, stratify = boot_stratify) opt_cut <- optimize_metric(data = data[b_ind, ], x = x, class = class, metric_func = metric_func, pos_class = pos_class, neg_class = neg_class, minmax = "max", direction = direction, metric_name = metric_name, return_roc = FALSE, tol_metric = tol_metric, use_midpoints = use_midpoints, ...) return(unlist(opt_cut$optimal_cutpoint)) }) optimal_cutpoints <- unlist(optimal_cutpoints) if (inf_rm) optimal_cutpoints <- optimal_cutpoints[is.finite(optimal_cutpoints)] return(data.frame(optimal_cutpoint = summary_func(optimal_cutpoints))) } #' @rdname maximize_boot_metric #' @examples #' set.seed(100) #' cutpointr(suicide, dsi, suicide, method = minimize_boot_metric, #' metric = abs_d_sens_spec, boot_cut = 30) #' @export minimize_boot_metric <- function(data, x, class, metric_func = youden, pos_class = NULL, neg_class = NULL, direction, summary_func = mean, boot_cut = 50, boot_stratify, inf_rm = TRUE, tol_metric, use_midpoints, ...) { metric_name <- as.character(substitute(metric_func)) if (boot_stratify) { ind_pos <- which(unlist(data[, class]) == pos_class) ind_neg <- which(unlist(data[, class]) == neg_class) } else { ind_pos <- NA ind_neg <- NA } optimal_cutpoints <- purrr::map(1:boot_cut, function(i) { b_ind <- simple_boot(data = data, ind_pos = ind_pos, ind_neg = ind_neg, dep_var = class, stratify = boot_stratify) opt_cut <- optimize_metric(data = data[b_ind, ], x = x, class = class, metric_func = metric_func, pos_class = pos_class, neg_class = neg_class, minmax = "min", direction = direction, metric_name = metric_name, return_roc = FALSE, tol_metric = tol_metric, use_midpoints = use_midpoints, ...) return(unlist(opt_cut$optimal_cutpoint)) }) optimal_cutpoints <- unlist(optimal_cutpoints) if (inf_rm) optimal_cutpoints <- optimal_cutpoints[is.finite(optimal_cutpoints)] return(data.frame(optimal_cutpoint = summary_func(optimal_cutpoints))) } #' Optimize a metric function in binary classification after spline smoothing #' #' Given a function for computing a metric in \code{metric_func}, this function #' smoothes the function of metric value per cutpoint using smoothing splines. Then it #' optimizes the metric by selecting an optimal cutpoint. For further details #' on the smoothing spline see \code{?stats::smooth.spline}. #' The \code{metric} function should accept the following inputs: #' \itemize{ #' \item \code{tp}: vector of number of true positives #' \item \code{fp}: vector of number of false positives #' \item \code{tn}: vector of number of true negatives #' \item \code{fn}: vector of number of false negatives #' } #' #' The above inputs are arrived at by using all unique values in \code{x}, Inf, and #' -Inf as possible cutpoints for classifying the variable in class. #' #' @return A tibble with the columns \code{optimal_cutpoint}, the corresponding metric #' value and \code{roc_curve}, a nested tibble that includes all possible cutoffs #' and the corresponding numbers of true and false positives / negatives and #' all corresponding metric values. #' #' @inheritParams oc_youden_normal #' @param metric_func (function) A function that computes a #' metric to be optimized. See description. #' @param w Optional vector of weights of the same length as x; defaults to all 1. #' @param df The desired equivalent number of degrees of freedom #' (trace of the smoother matrix). Must be in (1,nx], nx the number of #' unique x values. #' @param spar Smoothing parameter, typically (but not necessarily) in (0,1]. #' When spar is specified, the coefficient lambda of the integral of the squared #' second derivative in the fit (penalized log likelihood) criterion is a #' monotone function of spar. #' @param nknots Integer or function giving the number of knots. The function #' should accept data and x (the name of the predictor variable) as inputs. #' By default nknots = 0.1 * log(n_dat / n_cut) * n_cut where n_dat is the #' number of observations and n_cut the number of unique predictor values. #' @param df_offset Allows the degrees of freedom to be increased by df_offset #' in the GCV criterion. #' @param penalty The coefficient of the penalty for degrees of freedom in the #' GCV criterion. #' @param control_spar Optional list with named components controlling the root #' finding when the smoothing parameter spar is computed, i.e., NULL. See #' help("smooth.spline") for further information. #' @param tol_metric All cutpoints will be returned that lead to a metric #' value in the interval [m_max - tol_metric, m_max + tol_metric] where #' m_max is the maximum achievable metric value. This can be used to return #' multiple decent cutpoints and to avoid floating-point problems. #' @param use_midpoints (logical) If TRUE (default FALSE) the returned optimal #' cutpoint will be the mean of the optimal cutpoint and the next highest #' observation (for direction = ">") or the next lowest observation #' (for direction = "<") which avoids biasing the optimal cutpoint. #' @param ... Further arguments that will be passed to metric_func. #' #' @examples #' oc <- cutpointr(suicide, dsi, suicide, gender, method = maximize_spline_metric, #' df = 5, metric = accuracy) #' plot_metric(oc) #' @export #' @family method functions #' @name maximize_spline_metric maximize_spline_metric <- function(data, x, class, metric_func = youden, pos_class = NULL, neg_class = NULL, direction, w = NULL, df = NULL, spar = 1, nknots = cutpoint_knots, df_offset = NULL, penalty = 1, control_spar = list(), tol_metric, use_midpoints, ...) { metric_name <- as.character(substitute(metric_func)) optimize_metric(data = data, x = x, class = class, metric_func = metric_func, pos_class = pos_class, neg_class = neg_class, minmax = "max", direction = direction, metric_name = metric_name, w = w, df = df, spar = spar, nknots = nknots, df_offset = df_offset, penalty = penalty, control_spar = control_spar, spline = TRUE, tol_metric = tol_metric, use_midpoints = use_midpoints, ...) } #' @rdname maximize_spline_metric #' @export minimize_spline_metric <- function(data, x, class, metric_func = youden, pos_class = NULL, neg_class = NULL, direction, w = NULL, df = NULL, spar = 1, nknots = cutpoint_knots, df_offset = NULL, penalty = 1, control_spar = list(), tol_metric, use_midpoints, ...) { metric_name <- as.character(substitute(metric_func)) optimize_metric(data = data, x = x, class = class, metric_func = metric_func, pos_class = pos_class, neg_class = neg_class, minmax = "min", direction = direction, metric_name = metric_name, w = w, df = df, spar = spar, nknots = nknots, df_offset = df_offset, penalty = penalty, control_spar = control_spar, spline = TRUE, tol_metric = tol_metric, use_midpoints = use_midpoints, ...) } #' Calculate number of knots to use in spline smoothing #' #' This function calculates the number of knots #' when using smoothing splines for smoothing a function of metric values per #' cutpoint value. The function for calculating the number of knots is equal #' to \code{stats::.nknots_smspl} but uses the number of unique cutpoints #' in the data as n. #' #' @param data A data frame #' @param x (character) The name of the predictor variable #' @examples #' cutpoint_knots(suicide, "dsi") #' @export cutpoint_knots <- function(data, x) { n_cut <- length(unique(data[[x]])) n_knots <- stats::.nknots.smspl(n_cut) return(n_knots) } #' Optimize a metric function in binary classification after smoothing via #' generalized additive models #' #' Given a function for computing a metric in \code{metric_func}, these functions #' smooth the function of metric value per cutpoint using generalized additive #' models (as implemented in \pkg{mgcv}), then #' maximize or minimize the metric by selecting an optimal cutpoint. For further details #' on the GAM smoothing see \code{?mgcv::gam}. #' The \code{metric} function should accept the following inputs: #' \itemize{ #' \item \code{tp}: vector of number of true positives #' \item \code{fp}: vector of number of false positives #' \item \code{tn}: vector of number of true negatives #' \item \code{fn}: vector of number of false negatives #' } #' #' The above inputs are arrived at by using all unique values in \code{x}, Inf, and #' -Inf as possible cutpoints for classifying the variable in class. #' #' @return A tibble with the columns \code{optimal_cutpoint}, the corresponding metric #' value and \code{roc_curve}, a nested tibble that includes all possible cutoffs #' and the corresponding numbers of true and false positives / negatives and #' all corresponding metric values. #' #' @inheritParams oc_youden_normal #' @param metric_func (function) A function that computes a #' metric to be maximized. See description. #' @param formula A GAM formula. See \code{help("gam", package = "mgcv")} for #' details. #' @param optimizer An array specifying the numerical optimization method to #' use to optimize the smoothing parameter estimation criterion (given by method). #' See \code{help("gam", package = "mgcv")} for details. #' @param tol_metric All cutpoints will be returned that lead to a metric #' value in the interval [m_max - tol_metric, m_max + tol_metric] where #' m_max is the maximum achievable metric value. This can be used to return #' multiple decent cutpoints and to avoid floating-point problems. #' @param use_midpoints (logical) If TRUE (default FALSE) the returned optimal #' cutpoint will be the mean of the optimal cutpoint and the next highest #' observation (for direction = ">") or the next lowest observation #' (for direction = "<") which avoids biasing the optimal cutpoint. #' @param ... Further arguments that will be passed to metric_func or the #' GAM smoother. #' #' @examples #' oc <- cutpointr(suicide, dsi, suicide, gender, method = maximize_gam_metric, #' metric = accuracy) #' plot_metric(oc) #' @name maximize_gam_metric #' @family method functions #' @export maximize_gam_metric <- function(data, x, class, metric_func = youden, pos_class = NULL, neg_class = NULL, direction, formula = m ~ s(x.sorted), optimizer = c("outer", "newton"), tol_metric, use_midpoints, ...) { if (!requireNamespace("mgcv", quietly = TRUE)) { stop("mgcv package has to be installed to use GAM smoothing.") } formula <- as.character(formula) metric_name <- as.character(substitute(metric_func)) optimize_metric(data = data, x = x, class = class, metric_func = metric_func, pos_class = pos_class, neg_class = neg_class, minmax = "max", direction = direction, metric_name = metric_name, formula = formula, optimizer = optimizer, gam = TRUE, tol_metric = tol_metric, use_midpoints = use_midpoints, ...) } #' @examples #' oc <- cutpointr(suicide, dsi, suicide, gender, method = minimize_gam_metric, #' metric = abs_d_sens_spec) #' plot_metric(oc) #' @rdname maximize_gam_metric #' @export minimize_gam_metric <- function(data, x, class, metric_func = youden, pos_class = NULL, neg_class = NULL, direction, formula = m ~ s(x.sorted), optimizer = c("outer", "newton"), tol_metric, use_midpoints, ...) { if (!requireNamespace("mgcv", quietly = TRUE)) { stop("mgcv package has to be installed to use GAM smoothing.") } metric_name <- as.character(substitute(metric_func)) optimize_metric(data = data, x = x, class = class, metric_func = metric_func, pos_class = pos_class, neg_class = neg_class, minmax = "min", direction = direction, metric_name = metric_name, formula = formula, optimizer = optimizer, gam = TRUE, tol_metric = tol_metric, use_midpoints = use_midpoints, ...) }cutpointr/R/RcppExports.R0000644000176200001440000000172214066411540015121 0ustar liggesusers# Generated by using Rcpp::compileAttributes() -> do not edit by hand # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 any_inf <- function(x) { .Call('_cutpointr_any_inf', PACKAGE = 'cutpointr', x) } get_rev_dups <- function(x) { .Call('_cutpointr_get_rev_dups', PACKAGE = 'cutpointr', x) } is_equal_cpp_char <- function(x, y) { .Call('_cutpointr_is_equal_cpp_char', PACKAGE = 'cutpointr', x, y) } is_equal_cpp_num <- function(x, y) { .Call('_cutpointr_is_equal_cpp_num', PACKAGE = 'cutpointr', x, y) } one_unique_num <- function(x) { .Call('_cutpointr_one_unique_num', PACKAGE = 'cutpointr', x) } one_unique_char <- function(x) { .Call('_cutpointr_one_unique_char', PACKAGE = 'cutpointr', x) } which_are_num <- function(x, a) { .Call('_cutpointr_which_are_num', PACKAGE = 'cutpointr', x, a) } which_are_char <- function(x, a) { .Call('_cutpointr_which_are_char', PACKAGE = 'cutpointr', x, a) } cutpointr/R/print.summary_multi_cutpointr.R0000644000176200001440000000533413764472515021021 0ustar liggesusers#' @export print.summary_multi_cutpointr <- function(x, digits = 4, ...) { cat(paste("Method:", x$cutpointr[[1]]$method, "\n")) cat(paste("Predictor:", paste(unique(purrr::map_chr(x$cutpointr, function(x) x$predictor)), collapse = ", "), "\n")) cat(paste("Outcome:", x$cutpointr[[1]]$outcome, "\n")) if (has_column(x$cutpointr[[1]], "subgroup")) { cat(c("Subgroups:", paste(unique(purrr::map(x$cutpointr, ~ .$subgroup)), collapse = ", "), "\n")) } if (has_boot_results(x)) { cat(paste("Nr. of bootstraps:", x$boot_runs[1], "\n")) } for (i in 1:nrow(x)) { cat("\n") cat(paste("Predictor:", x$cutpointr[[i]]$predictor, "\n")) if (has_column(x$cutpointr[[i]], "subgroup")) { cat(paste("Subgroup:", x$cutpointr[[i]]$subgroup, "\n")) } cat(paste0(rep("-", getOption("width")), collapse = ""), "\n") x$cutpointr[[i]] %>% dplyr::select(.data$direction, .data$AUC) %>% # round(digits = digits) %>% dplyr::mutate(AUC = round(AUC, digits = digits), n = x$n_obs[i], n_pos = x$n_pos[i], n_neg = x$n_neg[i]) %>% as.data.frame %>% print_df_nodat() cat("\n") purrr::map_df(1:length(x$cutpointr[[i]]$optimal_cutpoint[[1]]), function(j) { x$cutpointr[[i]] %>% dplyr::select(# .data$direction, .data$optimal_cutpoint, !!find_metric_name(x$cutpointr[[i]]), .data$acc, .data$sensitivity, .data$specificity) %>% purrr::map_df(get_fnth, n = j) }) %>% as.data.frame %>% dplyr::left_join(y = x$confusion_matrix[[i]], by = c("optimal_cutpoint" = "cutpoint")) %>% dplyr::mutate_if(is.numeric, round, digits = digits) %>% print_df_nodat() cat("\n") cat(paste("Predictor summary:", "\n")) dplyr::bind_rows(x$desc[[i]], x$desc_by_class[[i]]) %>% dplyr::mutate_if(is.numeric, function(x) round(x, digits)) %>% print_df_nodat() if (has_boot_results(x[i, ])) { cat("\n") cat(paste("Bootstrap summary:", "\n")) print_df_nodat( x[["boot"]][[i]] %>% dplyr::mutate_if(is.numeric, round, digits = 2), row.names = rep("", nrow(x[["boot"]][[i]])) ) } } return(invisible(x)) } cutpointr/R/print.multi_cutpointr.R0000644000176200001440000000071413475240564017235 0ustar liggesusers#' Print multi_cutpointr objects #' #' Prints the \code{multi_cutpointr} object with infinite width like a \code{tbl_df}. #' #' @source Kirill Müller and Hadley Wickham (2017). tibble: Simple Data Frames. #' https://CRAN.R-project.org/package=tibble #' @param x a multi_cutpointr object. #' @param n number of rows to print. #' @param ... further arguments. #' @export print.multi_cutpointr <- function(x, n = Inf, ...) { print.cutpointr(x, n = n, ...) }cutpointr/R/predict.cutpointr.R0000644000176200001440000000641513475240564016325 0ustar liggesusers#' Predict using a cutpointr object #' #' Predictions are made on the \code{data.frame} in \code{newdata} #' using either the variable name or by applying the same transformation to #' the data as in \code{cutpointr}. The class of the output will be identical to the class #' of the predictor. #' #' @param object a cutpointr object. #' @param newdata a data.frame with a column that contains the predictor #' variable. #' @param cutpoint_nr if multiple optimal cutpoints were found this parameter #' defines which one should be used for predictions. Can be a vector if #' different cutpoint numbers are desired for different subgroups. #' @param ... further arguments. #' @examples #' oc <- cutpointr(suicide, dsi, suicide) #' ## Return in-sample predictions #' predict(oc, newdata = data.frame(dsi = oc$data[[1]]$dsi)) #' @family main cutpointr functions #' @export predict.cutpointr <- function(object, newdata, cutpoint_nr = 1, ...) { if (!("data.frame" %in% class(newdata))) { stop("newdata should be a data.frame") } if (!(length(cutpoint_nr) == 1 | length(cutpoint_nr) == nrow(object))) { stop("Specify one cutpoint_nr or one cutpoint_nr per subgroup.") } predictor_name <- object$predictor[1] # The predictor may have been altered using NSE indep_var <- eval(parse(text = predictor_name), newdata, parent.frame()) pos_class <- object$pos_class[1] neg_class <- object$neg_class[1] if (any(colnames(object) == "subgroup")) { grouping_name <- unique(object$grouping) grouping_var_new <- eval(parse(text = grouping_name), newdata, parent.frame()) opt_cut_ind <- purrr::map_int(grouping_var_new, function(g) { which(object$subgroup == g) }) if (length(cutpoint_nr) == 1) { optimal_cuts <- purrr::map_dbl(object$optimal_cutpoint, function(x) { x[cutpoint_nr] }) } else { optimal_cuts <- purrr::map2(.x = 1:nrow(object), .y = cutpoint_nr, .f = function(i, nr) { optimal_cut <- object$optimal_cutpoint[[i]][nr] if (is.na(optimal_cut)) { stop(paste("Cutpoint Nr.", nr, "in subgroup", i, "not found")) } return(optimal_cut) }) optimal_cuts <- unlist(optimal_cuts) } optimal_cuts <- optimal_cuts[opt_cut_ind] if (object$direction[1] == ">=") { preds <- indep_var >= optimal_cuts preds <- ifel_pos_neg(preds, pos_class, neg_class) } else if (object$direction[1] == "<=") { preds <- indep_var <= optimal_cuts preds <- ifel_pos_neg(preds, pos_class, neg_class) } } else { optimal_cut <- object$optimal_cutpoint[[1]][cutpoint_nr] if (is.na(optimal_cut)) { stop(paste("Cutpoint Nr.", cutpoint_nr, "not found")) } if (object$direction[1] == ">=") { preds <- indep_var >= optimal_cut preds <- ifel_pos_neg(preds, pos_class, neg_class) } else if (object$direction[1] == "<=") { preds <- indep_var <= optimal_cut preds <- ifel_pos_neg(preds, pos_class, neg_class) } } return(preds) }cutpointr/R/metrics.R0000644000176200001440000007203614066364240014310 0ustar liggesusers sens_spec <- function(tp, fp, tn, fn) { sens <- tp / (tp + fn) spec <- tn / (tn + fp) res <- cbind(sens, spec) colnames(res) <- c("sensitivity", "specificity") return(res) } sesp_from_oc <- function(roc_curve, oc, direction, opt_ind = NULL) { if (is.null(opt_ind)) { opt_ind <- purrr::map_dbl(oc[[1]], function(x) { get_opt_ind(roc_curve = roc_curve, oc = x, direction = direction) }) } sens_spec(tp = roc_curve$tp[opt_ind], fp = roc_curve$fp[opt_ind], tn = roc_curve$tn[opt_ind], fn = roc_curve$fn[opt_ind]) } accuracy_from_oc <- function(roc_curve, oc, direction, opt_ind = NULL) { if (is.null(opt_ind)) { opt_ind <- purrr::map_dbl(oc[[1]], function(x) { get_opt_ind(roc_curve = roc_curve, oc = x, direction = direction) }) opt_ind <- get_opt_ind(roc_curve = roc_curve, oc = oc, direction = direction) } accuracy(tp = roc_curve$tp[opt_ind], fp = roc_curve$fp[opt_ind], tn = roc_curve$tn[opt_ind], fn = roc_curve$fn[opt_ind]) } kappa_from_oc <- function(roc_curve, oc, direction, opt_ind = NULL) { if (is.null(opt_ind)) { opt_ind <- purrr::map_dbl(oc[[1]], function(x) { get_opt_ind(roc_curve = roc_curve, oc = x, direction = direction) }) opt_ind <- get_opt_ind(roc_curve = roc_curve, oc = oc, direction = direction) } cohens_kappa(tp = roc_curve$tp[opt_ind], fp = roc_curve$fp[opt_ind], tn = roc_curve$tn[opt_ind], fn = roc_curve$fn[opt_ind]) } #' Calculate AUC from a roc_cutpointr or cutpointr object #' #' Calculate the area under the ROC curve using the trapezoidal rule. #' #' @param x Data frame resulting from the roc() or cutpointr() function. #' @source Forked from the AUC package #' @return Numeric vector of AUC values #' @name auc #' @export auc <- function(x) { UseMethod("auc", x) } #' @rdname auc #' @export auc.roc_cutpointr <- function(x) { tpr <- x$tpr fpr <- x$fpr l_tpr <- length(tpr) l_fpr <- length(fpr) stopifnot(l_tpr == l_fpr) tpr <- cbind(tpr[2:l_tpr], tpr[1:(l_tpr - 1)]) fpr <- cbind(fpr[2:l_fpr], fpr[1:(l_fpr - 1)]) sum(0.5 * abs(fpr[, 1] - fpr[, 2]) * (tpr[, 1] + tpr[, 2])) } #' @rdname auc #' @export auc.cutpointr <- function(x) { x$AUC } #' Extract the cutpoints from a ROC curve generated by cutpointr #' #' This is a utility function for extracting the cutpoints from a \code{roc_cutpointr} #' object. Mainly useful in conjunction with the \code{plot_cutpointr} function if #' cutpoints are to be plotted on the x-axis. #' #' @name cutpoint #' @param x A roc_cutpointr object. #' @param ... Further arguments. #' @examples #' oc <- cutpointr(suicide, dsi, suicide, gender) #' plot_cutpointr(oc, cutpoint, accuracy) #' #' @family metric functions #' @export cutpoint <- function(x, ...) { x[["x.sorted"]] } #' @rdname cutpoint #' @export cutpoints <- function(x, ...) { x[["x.sorted"]] } #' Calculate accuracy #' #' Calculate accuracy from #' true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. \cr \cr #' accuracy = (tp + tn) / (tp + fp + tn + fn) #' @param tp (numeric) number of true positives. #' @param fp (numeric) number of false positives. #' @param tn (numeric) number of true negatives. #' @param fn (numeric) number of false negatives. #' @param ... for capturing additional arguments passed by method. #' @examples #' accuracy(10, 5, 20, 10) #' accuracy(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' @family metric functions #' @export accuracy <- function(tp, fp, tn, fn, ...) { Accuracy <- cbind((tp + tn) / (tp + fp + tn + fn)) colnames(Accuracy) <- "accuracy" return(Accuracy) } #' Calculate the Youden-Index #' #' Calculate the Youden-Index (J-Index) from #' true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. \cr \cr #' sensitivity = tp / (tp + fn) \cr #' specificity = tn / (tn + fp) \cr #' youden_index = sensitivity + specificity - 1 \cr #' @inheritParams accuracy #' @examples #' youden(10, 5, 20, 10) #' youden(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' @family metric functions #' @export youden <- function(tp, fp, tn, fn, ...) { sesp <- sens_spec(tp, fp, tn, fn) youden <- cbind(rowSums(sesp) - 1) colnames(youden) <- "youden" return(youden) } #' Calculate sensitivity #' #' Calculate sensitivity from #' true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. \cr \cr #' sensitivity = tp / (tp + fn) \cr #' @inheritParams accuracy #' @examples #' sensitivity(10, 5, 20, 10) #' sensitivity(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' @family metric functions #' @export sensitivity <- function(tp, fn, ...) { sens <- tp / (tp + fn) sens <- matrix(sens, ncol = 1) colnames(sens) <- "sensitivity" return(sens) } #' Calculate specificity #' #' Calculate specificity from true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. \cr \cr #' specificity = tn / (tn + fp) \cr #' @inheritParams accuracy #' @examples #' specificity(10, 5, 20, 10) #' specificity(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' @family metric functions #' @export specificity <- function(fp, tn, ...) { spec <- tn / (tn + fp) spec <- matrix(spec, ncol = 1) colnames(spec) <- "specificity" return(spec) } #' Metrics that are constrained by another metric #' #' For example, calculate sensitivity where #' a lower bound (minimal desired value) for specificty can be defined. All returned #' metric values for cutpoints that lead to values of the constraining metric #' below the specified minimum will be zero. #' The inputs must be vectors of equal length. #' @examples #' ## Maximum sensitivity when Positive Predictive Value (PPV) is at least 75% #' library(dplyr) #' library(purrr) #' library(cutpointr) #' cp <- cutpointr(data = suicide, x = dsi, class = suicide, #' method = maximize_metric, #' metric = sens_constrain, #' constrain_metric = ppv, #' min_constrain = 0.75) #' ## All metric values (m) where PPV < 0.75 are zero #' plot_metric(cp) #' cp$roc_curve #' ## We can confirm that PPV is indeed >= 0.75 #' cp %>% #' add_metric(list(ppv)) #' ## We can also do so for the complete ROC curve(s) #' cp %>% #' pull(roc_curve) %>% #' map(~ add_metric(., list(sensitivity, ppv))) #' #' ## Use the metric_constrain function for a combination of any two metrics #' ## Estimate optimal cutpoint for precision given a recall of at least 70% #' cp <- cutpointr(data = suicide, x = dsi, class = suicide, #' subgroup = gender, #' method = maximize_metric, #' metric = metric_constrain, #' main_metric = precision, #' suffix = "_constrained", #' constrain_metric = recall, #' min_constrain = 0.70) #' ## All metric values (m) where recall < 0.7 are zero #' plot_metric(cp) #' ## We can confirm that recall is indeed >= 0.70 and that precision_constrain #' ## is identical to precision for the estimated cutpoint #' cp %>% #' add_metric(list(recall, precision)) #' ## We can also do so for the complete ROC curve(s) #' cp %>% #' pull(roc_curve) %>% #' map(~ add_metric(., list(recall, precision))) #' @inheritParams accuracy #' @family metric functions #' @param constrain_metric Metric for constraint. #' @param min_constrain Minimum desired value of constrain_metric. #' @param main_metric Metric to be optimized. #' @param suffix Character string to be added to the name of main_metric. #' @name metric_constrain #' @export metric_constrain <- function(tp, fp, tn, fn, main_metric = sensitivity, constrain_metric = specificity, min_constrain = 0.5, suffix = "_constrain", ...) { metric_constrain <- main_metric(tp = tp, fp = fp, tn = tn, fn = fn) metric_constrain <- sanitize_metric(m = metric_constrain, n = nrow(metric_constrain), m_name = "metric_constrain") constraint <- constrain_metric(tp = tp, fp = fp, tn = tn, fn = fn) constraint <- as.numeric(unlist(constraint)) failed_constr <- constraint < min_constrain metric_constrain[failed_constr, ] <- 0 if (all(failed_constr)) { warning("No cutpoint was found that satisfies the constraint.") } colnames(metric_constrain) <- paste0(colnames(metric_constrain), suffix) return(metric_constrain) } #' @rdname metric_constrain #' @export sens_constrain <- function(tp, fp, tn, fn, constrain_metric = specificity, min_constrain = 0.5, ...) { metric_constrain <- sensitivity(tp = tp, fn = fn) constraint <- constrain_metric(tp = tp, fp = fp, tn = tn, fn = fn) constraint <- as.numeric(unlist(constraint)) failed_constr <- constraint < min_constrain if (all(failed_constr)) { warning("No cutpoint was found that satisfies the constraint.") } metric_constrain[failed_constr, ] <- 0 colnames(metric_constrain) <- "sens_constrain" return(metric_constrain) } #' @rdname metric_constrain #' @export spec_constrain <- function(tp, fp, tn, fn, constrain_metric = sensitivity, min_constrain = 0.5, ...) { metric_constrain <- specificity(fp = fp, tn = tn) constraint <- constrain_metric(tp = tp, fp = fp, tn = tn, fn = fn) constraint <- as.numeric(unlist(constraint)) failed_constr <- constraint < min_constrain if (all(failed_constr)) { warning("No cutpoint was found that satisfies the constraint.") } metric_constrain[failed_constr, ] <- 0 colnames(metric_constrain) <- "spec_constrain" return(metric_constrain) } #' @rdname metric_constrain #' @export acc_constrain <- function(tp, fp, tn, fn, constrain_metric = sensitivity, min_constrain = 0.5, ...) { metric_constrain <- accuracy(tp = tp, tn = tn, fp = fp, fn = fn) constraint <- constrain_metric(tp = tp, fp = fp, tn = tn, fn = fn) constraint <- as.numeric(unlist(constraint)) failed_constr <- constraint < min_constrain if (all(failed_constr)) { warning("No cutpoint was found that satisfies the constraint.") } metric_constrain[failed_constr, ] <- 0 colnames(metric_constrain) <- "acc_constrain" return(metric_constrain) } #' Calculate the sum of sensitivity and specificity #' #' Calculate the sum of sensitivity and specificity from #' true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. \cr \cr #' sensitivity = tp / (tp + fn) \cr #' specificity = tn / (tn + fp) \cr #' sum_sens_spec = sensitivity + specificity \cr #' @inheritParams accuracy #' @examples #' sum_sens_spec(10, 5, 20, 10) #' sum_sens_spec(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' @family metric functions #' @export sum_sens_spec <- function(tp, fp, tn, fn, ...) { sesp <- sens_spec(tp, fp, tn, fn) sesp <- cbind(rowSums(sesp)) colnames(sesp) <- "sum_sens_spec" return(sesp) } #' Calculate the product of sensitivity and specificity #' #' Calculate the product of sensitivity and specificity from #' true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. \cr \cr #' sensitivity = tp / (tp + fn) \cr #' specificity = tn / (tn + fp) \cr #' prod_sens_spec = sensitivity * specificity \cr #' @inheritParams accuracy #' @examples #' prod_sens_spec(10, 5, 20, 10) #' prod_sens_spec(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' @family metric functions #' @export prod_sens_spec <- function(tp, fp, tn, fn, ...) { sesp <- sens_spec(tp, fp, tn, fn) sesp <- cbind(sesp[, 1] * sesp[, 2]) colnames(sesp) <- "prod_sens_spec" return(sesp) } #' Calculate the absolute difference of sensitivity and specificity #' #' Calculate the absolute difference of sensitivity and specificity #' from true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. \cr #' \cr #' sensitivity = tp / (tp + fn) \cr #' specificity = tn / (tn + fp) \cr #' abs_d_sens_spec = |sensitivity - specificity| \cr #' @inheritParams accuracy #' @examples #' abs_d_sens_spec(10, 5, 20, 10) #' abs_d_sens_spec(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' @family metric functions #' @export abs_d_sens_spec <- function(tp, fp, tn, fn, ...) { sesp <- sens_spec(tp, fp, tn, fn) abs_d_sesp <- abs(sesp[, 1] - sesp[, 2]) abs_d_sesp <- matrix(abs_d_sesp, ncol = 1) colnames(abs_d_sesp) <- "abs_d_sens_spec" return(abs_d_sesp) } #' Calculate the distance between points on the ROC curve and (0,1) #' #' Calculate the distance on the ROC space between points on the ROC curve #' and the point of perfect discrimination #' from true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. To be used with #' \code{method = minimize_metric}. \cr #' \cr #' sensitivity = tp / (tp + fn) \cr #' specificity = tn / (tn + fp) \cr #' roc01 = sqrt((1 - sensitivity)^2 + (1 - specificity)^2) \cr #' @inheritParams accuracy #' @examples #' roc01(10, 5, 20, 10) #' roc01(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' oc <- cutpointr(suicide, dsi, suicide, #' method = minimize_metric, metric = roc01) #' plot_roc(oc) #' @family metric functions #' @export roc01 <- function(tp, fp, tn, fn, ...) { sesp <- sens_spec(tp, fp, tn, fn) distance <- sqrt((1 - sesp[, 1])^2 + (1 - sesp[, 2])^2) distance <- matrix(distance, ncol = 1) colnames(distance) <- "roc01" return(distance) } #' Calculate precision #' #' Calculate precision (equal to the positive predictive value) #' from true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. \cr \cr #' precision = tp / (tp + fp) \cr #' @inheritParams accuracy #' @examples #' precision(10, 5, 20, 10) #' precision(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' @family metric functions #' @export precision <- function(tp, fp, tn, fn, ...) { prec <- ppv(tp = tp, fp = fp, tn = tn, fn = fn) colnames(prec) <- "precision" return(prec) } #' Calculate recall #' #' Calculate recall (equal to sensitivity) from #' true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. \cr \cr #' recall = tp / (tp + fn) \cr #' @inheritParams accuracy #' @examples #' recall(10, 5, 20, 10) #' recall(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' @family metric functions #' @export recall <- function(tp, fp, tn, fn, ...) { rec <- sensitivity(tp = tp, fp = fp, tn = tn, fn = fn) colnames(rec) <- "recall" return(rec) } #' Calculate the positive predictive value #' #' Calculate the positive predictive value (PPV) from #' true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. \cr \cr #' ppv = tp / (tp + fp) \cr #' @inheritParams accuracy #' @examples #' ppv(10, 5, 20, 10) #' ppv(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' @family metric functions #' @export ppv <- function(tp, fp, tn, fn, ...) { ppv <- tp / (tp + fp) ppv <- matrix(ppv, ncol = 1) colnames(ppv) <- "ppv" return(ppv) } #' Calculate the negative predictive value #' #' Calculate the negative predictive value (NPV) #' from true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. \cr \cr #' npv = tn / (tn + fn) \cr #' @inheritParams accuracy #' @examples #' npv(10, 5, 20, 10) #' npv(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' @family metric functions #' @export npv <- function(tp, fp, tn, fn, ...) { npv <- tn / (tn + fn) npv <- matrix(npv, ncol = 1) colnames(npv) <- "npv" return(npv) } #' Calculate the absolute difference of positive and negative predictive value #' #' Calculate the absolute difference of positive predictive value (PPV) and #' negative predictive value (NPV) from #' true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. \cr \cr #' ppv = tp / (tp + fp) \cr #' npv = tn / (tn + fn) \cr #' abs\_d\_ppv\_npv = |ppv - npv| \cr #' @inheritParams accuracy #' @examples #' abs_d_ppv_npv(10, 5, 20, 10) #' abs_d_ppv_npv(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' @family metric functions #' @export abs_d_ppv_npv <- function(tp, fp, tn, fn, ...) { ppv <- tp / (tp + fp) npv <- tn / (tn + fn) abs_d_ppvnpv <- abs(ppv - npv) abs_d_ppvnpv <- matrix(abs_d_ppvnpv, ncol = 1) colnames(abs_d_ppvnpv) <- "abs_d_ppv_npv" return(abs_d_ppvnpv) } #' Calculate the sum of positive and negative predictive value #' #' Calculate the sum of positive predictive value (PPV) and #' negative predictive value (NPV) from #' true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. \cr \cr #' ppv = tp / (tp + fp) \cr #' npv = tn / (tn + fn) \cr #' sum_ppv_npv = ppv + npv \cr #' @inheritParams accuracy #' @examples #' sum_ppv_npv(10, 5, 20, 10) #' sum_ppv_npv(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' @family metric functions #' @export sum_ppv_npv <- function(tp, fp, tn, fn, ...) { ppv <- tp / (tp + fp) npv <- tn / (tn + fn) sum_ppvnpv <- ppv + npv sum_ppvnpv <- matrix(sum_ppvnpv, ncol = 1) colnames(sum_ppvnpv) <- "sum_ppv_npv" return(sum_ppvnpv) } #' Calculate the product of positive and negative predictive value #' #' Calculate the product of positive predictive value (PPV) and #' negative predictive value (NPV) from #' true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. \cr \cr #' ppv = tp / (tp + fp) \cr #' npv = tn / (tn + fn) \cr #' prod_ppv_npv = ppv * npv \cr #' @inheritParams accuracy #' @examples #' prod_ppv_npv(10, 5, 20, 10) #' prod_ppv_npv(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' @family metric functions #' @export prod_ppv_npv <- function(tp, fp, tn, fn, ...) { ppv <- tp / (tp + fp) npv <- tn / (tn + fn) prod_ppvnpv <- ppv * npv prod_ppvnpv <- matrix(prod_ppvnpv, ncol = 1) colnames(prod_ppvnpv) <- "prod_ppv_npv" return(prod_ppvnpv) } #' Calculate the false omission and false discovery rate #' #' Calculate the false omission rate or false discovery rate #' from true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. \cr \cr #' false_omission_rate = fn / (tn + fn) = 1 - npv #' false_discovery_rate = fp / (tp + fp) = 1 - ppv #' @inheritParams accuracy #' @examples #' false_omission_rate(10, 5, 20, 10) #' false_omission_rate(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' @name false_omission_rate #' @family metric functions #' @export false_omission_rate <- function(tp, fp, tn, fn, ...) { fomr <- fn / (tn + fn) fomr <- matrix(fomr, ncol = 1) colnames(fomr) <- "false_omission_rate" return(fomr) } #' @rdname false_omission_rate #' @export false_discovery_rate <- function(tp, fp, tn, fn, ...) { fdr <- fp / (tp + fp) fdr <- matrix(fdr, ncol = 1) colnames(fdr) <- "false_discovery_rate" return(fdr) } #' Calculate true / false positive / negative rate #' #' Calculate the true positive rate (tpr, equal to sensitivity and recall), #' the false positive rate (fpr, equal to fall-out), #' the true negative rate (tnr, equal to specificity), #' or the false negative rate (fnr) from #' true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. \cr \cr #' tpr = tp / (tp + fn) \cr #' fpr = fp / (fp + tn) \cr #' tnr = tn / (tn + fp) \cr #' fnr = fn / (fn + tp) \cr #' @inheritParams accuracy #' @name tpr #' @examples #' tpr(10, 5, 20, 10) #' tpr(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' @family metric functions #' @export tpr <- function(tp, fn, ...) { tprate <- sensitivity(tp = tp, fn = fn) colnames(tprate) <- "tpr" return(tprate) } #' @rdname tpr #' @export fpr <- function(fp, tn, ...) { fprate <- matrix(fp / (fp + tn), ncol = 1) colnames(fprate) <- "fpr" return(fprate) } #' @rdname tpr #' @export tnr <- function(fp, tn, ...) { tnrate <- specificity(tn = tn, fp = fp) colnames(tnrate) <- "tnr" return(tnrate) } #' @rdname tpr #' @export fnr <- function(tp, fn, ...) { fnrate <- matrix(fn / (fn + tp), ncol = 1) colnames(fnrate) <- "fnr" return(fnrate) } #' Calculate the positive or negative likelihood ratio #' #' Calculate the positive or negative likelihood ratio #' from true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. \cr \cr #' plr = tpr / fpr \cr #' nlr = fnr / tnr \cr #' @name plr #' @inheritParams accuracy #' @examples #' plr(10, 5, 20, 10) #' plr(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' @family metric functions #' @export plr <- function(tp, fp, tn, fn, ...) { plr <- tpr(tp = tp, fp = tp, tn = tn, fn = fn) / fpr(tp = tp, fp = fp, tn = tn, fn = fn) plr <- matrix(plr, ncol = 1) colnames(plr) <- "plr" return(plr) } #' @rdname plr #' @export nlr <- function(tp, fp, tn, fn, ...) { nlr <- fnr(tp = tp, fp = tp, tn = tn, fn = fn) / tnr(tp = tp, fp = fp, tn = tn, fn = fn) nlr <- matrix(nlr, ncol = 1) colnames(nlr) <- "nlr" return(nlr) } #' Extract number true / false positives / negatives #' #' Extract the number of true positives (tp), false positives (fp), #' true negatives (tn), or false negatives (fn). #' The inputs must be vectors of equal length. Mainly useful for \code{plot_cutpointr}. #' @name tp #' @inheritParams accuracy #' @examples #' tp(10, 5, 20, 10) #' tp(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' fp(10, 5, 20, 10) #' tn(10, 5, 20, 10) #' fn(10, 5, 20, 10) #' @family metric functions #' @export tp <- function(tp, ...) { res <- matrix(tp, ncol = 1) colnames(res) <- "tp" return(res) } #' @rdname tp #' @export tn <- function(tn, ...) { res <- matrix(tn, ncol = 1) colnames(res) <- "tn" return(res) } #' @rdname tp #' @export fp <- function(fp, ...) { res <- matrix(fp, ncol = 1) colnames(res) <- "fp" return(res) } #' @rdname tp #' @export fn <- function(fn, ...) { res <- matrix(fn, ncol = 1) colnames(res) <- "fn" return(res) } #' Calculate Cohen's Kappa #' #' Calculate the Kappa metric from #' true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. \cr \cr #' mrg_a = ((tp + fn) * (tp + fp)) / (tp + fn + fp + tn) \cr #' mrg_b = ((fp + tn) * (fn + tn)) / (tp + fn + fp + tn) \cr #' expec_agree = (mrg_a + mrg_b) / (tp + fn + fp + tn) \cr #' obs_agree = (tp + tn) / (tp + fn + fp + tn) \cr #' cohens_kappa = (obs_agree - expec_agree) / (1 - expec_agree) \cr #' @inheritParams accuracy #' @examples #' cohens_kappa(10, 5, 20, 10) #' cohens_kappa(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' @return A numeric matrix with the column name "cohens_kappa". #' @family metric functions #' @export cohens_kappa <- function(tp, fp, tn, fn, ...) { mrg_a <- ((tp + fn) * (tp + fp)) / (tp + fn + fp + tn) mrg_b <- ((fp + tn) * (fn + tn)) / (tp + fn + fp + tn) EA <- (mrg_a + mrg_b) / (tp + fn + fp + tn) OA <- (tp + tn) / (tp + fn + fp + tn) res <- matrix((OA - EA) / (1 - EA), ncol = 1) colnames(res) <- "cohens_kappa" return(res) } #' Calculate the odds ratio #' #' Calculate the (diagnostic) odds ratio from #' true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. \cr \cr #' odds_ratio = (tp / fp) / (fn / tn) \cr #' @inheritParams accuracy #' @examples #' odds_ratio(10, 5, 20, 10) #' odds_ratio(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' @family metric functions #' @export odds_ratio <- function(tp, fp, tn, fn, ...) { or <- (tp / fp) / (fn / tn) or <- matrix(or, ncol = 1) colnames(or) <- "odds_ratio" return(or) } #' Calculate the risk ratio (relative risk) #' #' Calculate the risk ratio (or relative risk) from #' true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. \cr \cr #' risk_ratio = (tp / (tp + fn)) / (fp / (fp + tn)) \cr #' @inheritParams accuracy #' @examples #' risk_ratio(10, 5, 20, 10) #' risk_ratio(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' @family metric functions #' @export risk_ratio <- function(tp, fp, tn, fn, ...) { rr <- (tp / (tp + fn)) / (fp / (fp + tn)) rr <- matrix(rr, ncol = 1) colnames(rr) <- "risk_ratio" return(rr) } #' Calculate the p-value of a chi-squared test #' #' Calculate the p-value of a chi-squared test from #' true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. #' @inheritParams accuracy #' @examples #' p_chisquared(10, 5, 20, 10) #' p_chisquared(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' @family metric functions #' @export p_chisquared <- function(tp, fp, tn, fn, ...) { samplesize <- tp + fp + tn + fn chisq <- (samplesize * ((tp * tn - fp * fn) ** 2)) / ((tp + fp) * (fn + tn) * (tp + fn) * (fp + tn)) pval <- stats::pchisq(chisq, 1, lower.tail = F) pval <- matrix(pval, ncol = 1) colnames(pval) <- "p_chisquared" return(pval) } #' Calculate the misclassification cost #' #' Calculate the misclassification cost from #' true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. \cr \cr #' misclassification_cost = cost_fp * fp + cost_fn * fn \cr #' @inheritParams accuracy #' @param cost_fp (numeric) the cost of a false positive #' @param cost_fn (numeric) the cost of a false negative #' @examples #' misclassification_cost(10, 5, 20, 10, cost_fp = 1, cost_fn = 5) #' misclassification_cost(c(10, 8), c(5, 7), c(20, 12), c(10, 18), #' cost_fp = 1, cost_fn = 5) #' @family metric functions #' @export misclassification_cost <- function(tp, fp, tn, fn, cost_fp = 1, cost_fn = 1, ...) { misclassification_cost <- cost_fp * fp + cost_fn * fn misclassification_cost <- matrix(misclassification_cost, ncol = 1) colnames(misclassification_cost) <- "misclassification_cost" return(misclassification_cost) } #' Calculate the total utility #' #' Calculate the total utility from #' true positives, false positives, true negatives and false negatives. \cr \cr #' total_utility = utility_tp * tp + utility_tn * tn - cost_fp * fp - cost_fn * fn \cr \cr #' The inputs must be vectors of equal length. #' @inheritParams accuracy #' @param utility_tp (numeric) the utility of a true positive #' @param utility_tn (numeric) the utility of a true negative #' @param cost_fp (numeric) the cost of a false positive #' @param cost_fn (numeric) the cost of a false negative #' @examples #' total_utility(10, 5, 20, 10, utility_tp = 3, utility_tn = 3, cost_fp = 1, cost_fn = 5) #' total_utility(c(10, 8), c(5, 7), c(20, 12), c(10, 18), #' utility_tp = 3, utility_tn = 3, cost_fp = 1, cost_fn = 5) #' @family metric functions #' @export total_utility <- function(tp, fp, tn, fn, utility_tp = 1, utility_tn = 1, cost_fp = 1, cost_fn = 1, ...) { utility <- utility_tp * tp + utility_tn * tn - cost_fp * fp - cost_fn * fn utility <- matrix(utility, ncol = 1) colnames(utility) <- "total_utility" return(utility) } #' Calculate the F1-score #' #' Calculate the F1-score from #' true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. \cr \cr #' F1_score = (2 * tp) / (2 * tp + fp + fn) \cr #' @inheritParams accuracy #' @examples #' F1_score(10, 5, 20, 10) #' F1_score(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' @family metric functions #' @export F1_score <- function(tp, fp, tn, fn, ...) { f <- (2 * tp) / (2 * tp + fp + fn) f <- matrix(f, ncol = 1) colnames(f) <- "F1_score" return(f) } #' Calculate the Jaccard Index #' #' Calculate the Jaccard Index from #' true positives, false positives, true negatives and false negatives. #' The inputs must be vectors of equal length. \cr \cr #' Jaccard = (tp) / (tp + fp + fn) \cr #' @inheritParams accuracy #' @examples #' Jaccard(10, 5, 20, 10) #' Jaccard(c(10, 8), c(5, 7), c(20, 12), c(10, 18)) #' @family metric functions #' @export Jaccard <- function(tp, fp, tn, fn, ...) { f <- tp / (tp + fp + fn) f <- matrix(f, ncol = 1) colnames(f) <- "Jaccard" return(f) } cutpointr/R/plot_cut_boot.R0000644000176200001440000000477613604121756015524 0ustar liggesusers#' Plot the bootstrapped distribution of optimal cutpoints from a cutpointr object #' #' Given a cutpointr object this function plots the bootstrapped distribution #' of optimal cutpoints. \code{cutpointr} has to be run with \code{boot_runs}` > 0 #' to enable bootstrapping. #' @param x A cutpointr object. #' @param ... Additional arguments (unused). #' @examples #' set.seed(100) #' opt_cut <- cutpointr(suicide, dsi, suicide, boot_runs = 10) #' plot_cut_boot(opt_cut) #' @family cutpointr plotting functions #' @export plot_cut_boot <- function(x, ...) { if(!("cutpointr" %in% class(x))) stop("x is no cutpointr object.") args <- list(...) if (!(has_column(x, "subgroup"))) { dts_boot <- "boot" dts <- "data" fll <- NULL clr <- NULL transparency <- 1 } else { dts_boot <- c("boot", "subgroup") dts <- c("data", "subgroup") fll <- "subgroup" clr <- "subgroup" transparency <- 0.6 } if (has_boot_results(x)) { res_boot_unnested <- x %>% dplyr::select(dts_boot) %>% dplyr::mutate(boot = prepare_bind_rows(.data$boot)) %>% tidyr::unnest(.data$boot) cutpoints <- unlist(res_boot_unnested$optimal_cutpoint) if (all(na_inf_omit(cutpoints %% 1 == 0)) | only_one_unique(na_inf_omit(cutpoints))) { all_integer = TRUE dist_plot <- ggplot2::geom_bar(alpha = transparency, position = "identity") } else { all_integer = FALSE dist_plot <- ggplot2::geom_density(alpha = transparency) } # If multiple optimal cutpoints optimal_cutpoint is a list if (is.list(res_boot_unnested$optimal_cutpoint)) { res_boot_unnested <- res_boot_unnested %>% dplyr::select(-c("roc_curve_b", "roc_curve_oob")) %>% tidyr::unnest() } boot_cut <- suppressMessages( ggplot2::ggplot(res_boot_unnested, ggplot2::aes_string(x = "optimal_cutpoint", fill = fll, color = clr)) + dist_plot + ggplot2::ggtitle("Bootstrap", "distribution of optimal cutpoints") + ggplot2::xlab("optimal cutpoint") ) if (!all_integer) boot_cut <- boot_cut + ggplot2::geom_rug(alpha = 0.5) } else { stop("No bootstrap results found. Was boot_runs > 0 in cutpointr?") } return(boot_cut) } cutpointr/R/add_metric.R0000644000176200001440000001670613766733525014753 0ustar liggesusers#' Add metrics to a cutpointr or roc_cutpointr object #' #' By default, the output of cutpointr includes the optimized metric and several #' other metrics. This function adds further metrics. Suitable metric functions #' are all metric functions that are included in the package or that comply #' with those standards. #' #' @param object A cutpointr or roc_cutpointr object. #' @param metric (list) A list of metric functions to be added. #' @return A cutpointr or roc_cutpointr object (a data.frame) with one or more added columns. #' @examples #' library(dplyr) #' library(cutpointr) #' cutpointr(suicide, dsi, suicide, gender) %>% #' add_metric(list(ppv, npv)) %>% #' select(optimal_cutpoint, subgroup, AUC, sum_sens_spec, ppv, npv) #' @name add_metric #' @export #' @family main cutpointr functions #' @importFrom rlang !! := #' add_metric <- function(object, metric) { UseMethod("add_metric", object) } #' @rdname add_metric #' @export add_metric.cutpointr <- function(object, metric) { if (!is.list(metric)) stop("The metric function(s) must be given as a list.") met <- purrr::map(metric, function(metric_func) { if (!is.function(metric_func)) { stop("The list elements of metric have to be functions.") } # Get numbers of TP, FP, TN, FN at optimal cutpoint(s) from ROC curve(s) # and calculate the metric(s). Allow for type instability of the metric func: one_met <- purrr::pmap_df(list(object$optimal_cutpoint, object$roc_curve, object$direction), function(optimal_cutpoint, roc_curve, direction) { opt_ind <- get_opt_ind(roc_curve = roc_curve, oc = optimal_cutpoint, direction = direction) met <- metric_func(tp = roc_curve$tp[opt_ind], fp = roc_curve$fp[opt_ind], tn = roc_curve$tn[opt_ind], fn = roc_curve$fn[opt_ind]) met_name <- colnames(met) if (length(met_name) > 1) { stop("The metric function should return one column or a vector.") } if (is.null(met_name)) met_name <- "added_metric" if (length(met) > 1) { met <- list(as.numeric(unlist(met))) } else { met <- as.numeric(met) } tibble::tibble(!!met_name := met) }) class(one_met) <- class(object) return(one_met) }) oc <- dplyr::bind_cols(object, met) if (has_boot_results(oc)) { boot_augmented <- purrr::map(oc$boot, function(boot_group) { add_per_subgroup <- purrr::map(metric, function(metric_func) { metric_robust <- function(metric_func, tp, fp, tn, fn) { tp <- unlist(tp) fp <- unlist(fp) tn <- unlist(tn) fn <- unlist(fn) met <- as.numeric(metric_func(tp = tp, fp = fp, tn = tn, fn = fn)) if (length(met) > 1) met <- list(met) return(met) } one_met <- purrr::map(1:nrow(boot_group), function(r) { met_b <- metric_robust(metric_func = metric_func, tp = boot_group$TP_b[r], fp = boot_group$FP_b[r], tn = boot_group$TN_b[r], fn = boot_group$FN_b[r]) met_oob <- metric_robust(metric_func = metric_func, tp = boot_group$TP_oob[r], fp = boot_group$FP_oob[r], tn = boot_group$TN_oob[r], fn = boot_group$FN_oob[r]) tibble::tibble(met_b, met_oob) }) # Bind rows allowing for multiple optimal cutpoints has_multiple <- any( purrr::map_lgl(one_met, function(x) { length(unlist(x)) > 2 }) ) if (has_multiple) { one_met <- purrr::map_df(one_met, function(x) { if (length(unlist(x)) == 2) { tibble::tibble(met_b = list(x$met_b), met_oob = list(x$met_oob)) } else { tibble::tibble(met_b = x$met_b, met_oob = x$met_oob) } }) } else { one_met <- dplyr::bind_rows(one_met) } met_name <- colnames(metric_func(1,1,1,1)) # just get the name... if (length(met_name) > 1) { stop("The metric function should return one column or a vector.") } if (is.null(met_name)) met_name <- "added_metric" colnames(one_met) <- paste0(met_name, c("_b", "_oob")) return(one_met) }) add_per_subgroup <- dplyr::bind_cols(add_per_subgroup) boot_group <- dplyr::bind_cols(boot_group, add_per_subgroup) return(boot_group) }) oc$boot <- boot_augmented } return(oc) } #' @rdname add_metric #' @export add_metric.multi_cutpointr <- function(object, metric) { orig_class <- class(object) class(object) <- c("cutpointr", class(object)) res <- add_metric(object, metric) class(res) <- orig_class return(res) } #' @rdname add_metric #' @export add_metric.roc_cutpointr <- function(object, metric) { if (!is.list(metric)) stop("The metric function(s) must be given as a list.") met <- purrr::map(metric, function(metric_func) { if (!is.function(metric_func)) { stop("The list elements of metric have to be functions.") } # Get numbers of TP, FP, TN, FN at optimal cutpoint(s) from ROC curve(s) # and calculate the metric(s). Allow for type instability of the metric func: met <- metric_func(tp = object$tp, fp = object$fp, tn = object$tn, fn = object$fn) met_name <- colnames(met) if (length(met_name) > 1) { stop("The metric function should return one column or a vector.") } if (is.null(met_name)) met_name <- "added_metric" met <- as.numeric(met) met <- tibble::tibble(!!met_name := met) class(met) <- class(object) return(met) }) roc_added <- dplyr::bind_cols(object, met) return(roc_added) }cutpointr/R/summary.cutpointr.R0000644000176200001440000000650513766661066016377 0ustar liggesusers#' @export summary.cutpointr <- function(object, ...) { x_summary <- vector("list", nrow(object)) names(x_summary) <- suppressWarnings(object$subgroup) for (r in 1:nrow(object)) { temprow <- object[r, ] if (has_column(object, "subgroup")) { x_summary[[r]]$subgroup <- temprow$subgroup } x_summary[[r]]$cutpointr <- temprow x_summary[[r]]$desc <- dplyr::bind_cols( tibble::tibble(Data = "Overall"), summary_sd_df(temprow$data[[1]] %>% dplyr::select(temprow$predictor)) ) temprow_split <- temprow$data[[1]] %>% split(temprow$data[[1]][, temprow$outcome]) x_summary[[r]]$desc_byclass <- temprow_split %>% purrr::map_df(function(x) { summary_sd_df(x %>% dplyr::select(temprow$predictor)) }) x_summary[[r]]$desc_byclass <- dplyr::bind_cols( data.frame(Data = names(temprow_split), stringsAsFactors = FALSE), x_summary[[r]]$desc_byclass ) x_summary[[r]]$n_obs <- nrow(temprow$data[[1]]) x_summary[[r]]$n_pos <- temprow$data[[1]] %>% dplyr::select(temprow$outcome) %>% unlist %>% (function(x) sum(x == temprow$pos_class)) x_summary[[r]]$n_neg <- x_summary[[r]]$n_obs - x_summary[[r]]$n_pos # Confusion Matrix oi <- get_opt_ind(temprow$roc_curve[[1]], oc = unlist(temprow$optimal_cutpoint), direction = temprow$direction) x_summary[[r]]$confusion_matrix <- data.frame( cutpoint = unlist(temprow$optimal_cutpoint), temprow$roc_curve[[1]][oi, c("tp", "fn", "fp", "tn")] ) if (has_boot_results(temprow)) { x_summary[[r]][["boot"]] <- temprow[["boot"]][[1]] %>% dplyr::select(-(TP_b:roc_curve_oob)) %>% purrr::map(function(x) { summary_sd(x) }) x_summary[[r]][["boot"]] <- do.call(rbind, x_summary[[r]][["boot"]]) x_summary[[r]][["boot"]] <- as.data.frame(x_summary[[r]][["boot"]]) x_summary[[r]][["boot"]] <- tibble::rownames_to_column(x_summary[[r]][["boot"]], var = "Variable") x_summary[[r]]$boot_runs <- nrow(temprow[["boot"]][[1]]) } } x_summary <- purrr::map_df(x_summary, tidy_summary) class(x_summary) <- c("summary_cutpointr", class(x_summary)) return(x_summary) } # Convert the list output of summary.cutpointr to a data.frame # x is a single element of the resulting list from summary.cutpointr. tidy_summary <- function(x) { res <- tibble::tibble( cutpointr = list(x$cutpointr), desc = list(x$desc), desc_by_class = list(x$desc_byclass), n_obs = x$n_obs, n_pos = x$n_pos, n_neg = x$n_neg, confusion_matrix = list(x$confusion_matrix) ) if (has_boot_results(x)) { res <- dplyr::bind_cols(res, tibble::tibble(boot = list(x[["boot"]])), boot_runs = x$boot_runs) } if (has_column(x, "subgroup")) { res <- dplyr::bind_cols(subgroup = x$subgroup, res) } return(res) }cutpointr/R/plot_roc.R0000644000176200001440000000676513766733576014513 0ustar liggesusers#' Plot ROC curve from a cutpointr or roc_cutpointr object #' #' Given a \code{cutpointr} object this function plots the ROC curve(s) #' per subgroup, if given. Also plots a ROC curve from the output of \code{roc()}. #' @param x A cutpointr or roc_cutpointr object. #' @param display_cutpoint (logical) Whether or not to display the optimal #' cutpoint as a dot on the ROC curve for cutpointr objects. #' @param type "line" for line plot (default) or "step" for step plot. #' @param ... Additional arguments (unused). #' @examples #' opt_cut <- cutpointr(suicide, dsi, suicide) #' plot_roc(opt_cut, display_cutpoint = FALSE) #' #' opt_cut_2groups <- cutpointr(suicide, dsi, suicide, gender) #' plot_roc(opt_cut_2groups, display_cutpoint = TRUE) #' #' roc_curve <- roc(suicide, x = dsi, class = suicide, pos_class = "yes", #' neg_class = "no", direction = ">=") #' plot(roc_curve) #' auc(roc_curve) #' @family cutpointr plotting functions #' @name plot_roc #' @export plot_roc <- function(x, ...) { UseMethod("plot_roc", x) } #' @rdname plot_roc #' @export plot_roc.cutpointr <- function(x, display_cutpoint = TRUE, type = "line", ...) { predictor <- as.name(x$predictor[1]) outcome <- as.name(x$outcome[1]) if (!(has_column(x, "subgroup"))) { dts_roc <- "roc_curve" transparency <- 1 } else { dts_roc <- c("roc_curve", "subgroup") transparency <- 0.6 } roc_title <- ggplot2::ggtitle("ROC curve") if (display_cutpoint) { optcut_coords <- purrr::pmap_df(x, function(...) { args <- list(...) opt_ind <- get_opt_ind(roc_curve = args$roc_curve, oc = args$optimal_cutpoint, direction = args$direction) data.frame(tpr = args$roc_curve$tpr[opt_ind], tnr = args$roc_curve$tnr[opt_ind]) }) } res_unnested <- x %>% dplyr::select(dts_roc) %>% tidyr::unnest(.data$roc_curve) if (!(has_column(x, "subgroup"))) { roc <- ggplot2::ggplot(res_unnested, ggplot2::aes(x = 1 - tnr, y = tpr)) + roc_title + ggplot2::xlab("1 - Specificity") + ggplot2::ylab("Sensitivity") + ggplot2::theme(aspect.ratio = 1) } else if (has_column(x, "subgroup")) { roc <- ggplot2::ggplot(res_unnested, ggplot2::aes(x = 1 - tnr, y = tpr, color = subgroup)) + roc_title + ggplot2::xlab("1 - Specificity") + ggplot2::ylab("Sensitivity") + ggplot2::theme(aspect.ratio = 1) } if (display_cutpoint) { roc <- roc + ggplot2::geom_point(data = optcut_coords, color = "black") } if (type == "line") { roc <- roc + ggplot2::geom_line() } else if (type == "step") { roc <- roc + ggplot2::geom_step() } return(roc) } #' @rdname plot_roc #' @export plot_roc.roc_cutpointr <- function(x, type = "line", ...) { roc_title <- ggplot2::ggtitle("ROC curve") roc <- ggplot2::ggplot(x, ggplot2::aes(x = 1 - tnr, y = tpr)) + roc_title + ggplot2::xlab("1 - Specificity") + ggplot2::ylab("Sensitivity") + ggplot2::theme(aspect.ratio = 1) if (type == "line") { roc <- roc + ggplot2::geom_line() } else if (type == "step") { roc <- roc + ggplot2::geom_step() } return(roc) } #' @inherit plot_roc #' @export plot.roc_cutpointr <- function(x, type = "line", ...) { plot_roc(x, type = type) }cutpointr/R/grid_arrange_shared_legend.R0000644000176200001440000000371113475240564020131 0ustar liggesusers#' @source Forked from https://github.com/tidyverse/ggplot2/wiki/Share-a-legend-between-two-ggplot2-graphs grid_arrange_shared_legend <- function(plots, ncol = length(plots), nrow = 1, position = c("bottom", "right")) { position <- match.arg(position) g <- ggplot2::ggplotGrob(plots[[1]] + ggplot2::theme(legend.position = position))$grobs gb <- sapply(g, function(x) x$name) == "guide-box" # No legend because only one class: if (!all(!gb)) { legend <- g[[which(sapply(g, function(x) x$name) == "guide-box")]] lheight <- sum(legend$height) lwidth <- sum(legend$width) } gl <- lapply(plots, function(x) x + ggplot2::theme(legend.position="none")) if (!all(!gb)) gl <- c(gl, ncol = ncol, nrow = nrow) if (!all(!gb)) { if (position == "bottom") { hei <- grid::unit.c(grid::unit(1, "npc") - lheight, lheight) combined <- gridExtra::arrangeGrob(do.call(gridExtra::arrangeGrob, gl), legend, ncol = 1, heights = hei) } else if (position == "right") { wid <- grid::unit.c(grid::unit(1, "npc") - lwidth, lwidth) combined <- gridExtra::arrangeGrob(do.call(gridExtra::arrangeGrob, gl), legend, ncol = 2, widths = wid) } } else { # No legend because only one class. Different methods to plot ROC # beneath dist, not under, if length(gl) == 2 if (length(gl) == 2) { combined <- gridExtra::grid.arrange(gl[[1]], gl[[2]], ncol = 2, nrow = 1) } else { combined <- gridExtra::arrangeGrob(do.call(gridExtra::arrangeGrob, gl), ncol = 1, nrow = 1) } } grid::grid.newpage() grid::grid.draw(combined) invisible(combined) } cutpointr/R/plot.multi_cutpointr.R0000644000176200001440000000052513604121756017052 0ustar liggesusers#' Plotting multi_cutpointr objects is currently not supported #' #' You can try plotting the data manually instead. #' #' @param x A multi_cutpointr object. #' @param ... Further arguments. #' #' @export plot.multi_cutpointr <- function(x, ...) { stop("Plotting multi_cutpointr objects is not supported.") return(invisible(NULL)) } cutpointr/R/compat-lifecycle.R0000644000176200001440000001741413604121756016061 0ustar liggesusers# nocov start --- compat-lifecycle --- 2019-06-13 Wed 10:58 # This file serves as a reference for currently unexported rlang # lifecycle functions. Please find the most recent version in rlang's # repository. These functions require rlang in your `Imports` # DESCRIPTION field but you don't need to import rlang in your # namespace. #' Signal deprecation #' #' @description #' #' These functions provide two levels of verbosity for deprecation #' warnings. #' #' * `signal_soft_deprecated()` warns only if called from the global #' environment (so the user can change their script) or from the #' package currently being tested (so the package developer can fix #' the package). #' #' * `warn_deprecated()` warns unconditionally. #' #' * `stop_defunct()` fails unconditionally. #' #' Both functions warn only once per session by default to avoid #' overwhelming the user with repeated warnings. #' #' @param msg The deprecation message. #' @param id The id of the deprecation. A warning is issued only once #' for each `id`. Defaults to `msg`, but you should give a unique ID #' when the message is built programmatically and depends on inputs. #' @param env The environment in which the soft-deprecated function #' was called. A warning is issued if called from the global #' environment. If testthat is running, a warning is also called if #' the retired function was called from the package being tested. #' #' @section Controlling verbosity: #' #' The verbosity of retirement warnings can be controlled with global #' options. You'll generally want to set these options locally with #' one of these helpers: #' #' * `with_lifecycle_silence()` disables all soft-deprecation and #' deprecation warnings. #' #' * `with_lifecycle_warnings()` enforces warnings for both #' soft-deprecated and deprecated functions. The warnings are #' repeated rather than signalled once per session. #' #' * `with_lifecycle_errors()` enforces errors for both #' soft-deprecated and deprecated functions. #' #' All the `with_` helpers have `scoped_` variants that are #' particularly useful in testthat blocks. #' #' @noRd #' @seealso [lifecycle()] NULL signal_soft_deprecated <- function(msg, id = msg, env = rlang::caller_env(2)) { msg <- lifecycle_validate_message(msg) stopifnot( rlang::is_string(id), rlang::is_environment(env) ) if (rlang::is_true(rlang::peek_option("lifecycle_disable_warnings"))) { return(invisible(NULL)) } env_inherits_global <- function(env) { # `topenv(emptyenv())` returns the global env. Return `FALSE` in # that case to allow passing the empty env when the # soft-deprecation should not be promoted to deprecation based on # the caller environment. if (rlang::is_reference(env, emptyenv())) { return(FALSE) } rlang::is_reference(topenv(env), rlang::global_env()) } if (rlang::is_true(rlang::peek_option("lifecycle_verbose_soft_deprecation")) || env_inherits_global(env)) { warn_deprecated(msg, id) return(invisible(NULL)) } # Test for environment names rather than reference/contents because # testthat clones the namespace tested_package <- Sys.getenv("TESTTHAT_PKG") if (nzchar(tested_package) && identical(Sys.getenv("NOT_CRAN"), "true") && rlang::env_name(topenv(env)) == rlang::env_name(rlang::ns_env(tested_package))) { warn_deprecated(msg, id) return(invisible(NULL)) } rlang::signal(msg, "lifecycle_soft_deprecated") } warn_deprecated <- function(msg, id = msg) { msg <- lifecycle_validate_message(msg) stopifnot(rlang::is_string(id)) if (rlang::is_true(rlang::peek_option("lifecycle_disable_warnings"))) { return(invisible(NULL)) } if (!rlang::is_true(rlang::peek_option("lifecycle_repeat_warnings")) && rlang::env_has(deprecation_env, id)) { return(invisible(NULL)) } rlang::env_poke(deprecation_env, id, TRUE); has_colour <- function() rlang::is_installed("crayon") && crayon::has_color() silv <- function(x) if (has_colour()) crayon::silver(x) else x if (rlang::is_true(rlang::peek_option("lifecycle_warnings_as_errors"))) { .Signal <- stop_defunct } else { .Signal <- .Deprecated } if (!rlang::is_true(rlang::peek_option("lifecycle_repeat_warnings"))) { msg <- paste0(msg, "\n", silv("This warning is displayed once per session.")) } .Signal(msg = msg) } deprecation_env <- new.env(parent = emptyenv()) stop_defunct <- function(msg) { msg <- lifecycle_validate_message(msg) err <- rlang::cnd( c("defunctError", "error", "condition"), old = NULL, new = NULL, package = NULL, message = msg ) stop(err) } scoped_lifecycle_silence <- function(frame = rlang::caller_env()) { rlang::scoped_options(.frame = frame, lifecycle_disable_warnings = TRUE ) } with_lifecycle_silence <- function(expr) { scoped_lifecycle_silence() expr } scoped_lifecycle_warnings <- function(frame = rlang::caller_env()) { rlang::scoped_options(.frame = frame, lifecycle_disable_warnings = FALSE, lifecycle_verbose_soft_deprecation = TRUE, lifecycle_repeat_warnings = TRUE ) } with_lifecycle_warnings <- function(expr) { scoped_lifecycle_warnings() expr } scoped_lifecycle_errors <- function(frame = rlang::caller_env()) { scoped_lifecycle_warnings(frame = frame) rlang::scoped_options(.frame = frame, lifecycle_warnings_as_errors = TRUE ) } with_lifecycle_errors <- function(expr) { scoped_lifecycle_errors() expr } #' Embed a lifecycle badge in documentation #' #' @description #' #' Use `lifecycle()` within a `Sexpr` macro to embed a #' [lifecycle](https://www.tidyverse.org/lifecycle/) badge in your #' documentation. The badge should appear first in the description: #' #' ``` #' \Sexpr[results=rd, stage=render]{mypkg:::lifecycle("questioning")} #' ``` #' #' The badge appears as an image in the HTML version of the #' documentation. To make them available in your package, visit #' and copy #' all the files starting with `lifecycle-` in your `man/figures/` #' folder. #' #' @param stage A lifecycle stage as a string, one of: #' `"experimental"`, `"maturing"`, `"stable"`, `"questioning"`, #' `"archived"`, `"soft-deprecated"`, `"deprecated"`, `"defunct"`. #' #' @noRd NULL upcase1 <- function(x) { substr(x, 1, 1) <- toupper(substr(x, 1, 1)) x } lifecycle_img <- function(stage, url) { file <- sprintf("lifecycle-%s.svg", stage) stage_alt <- upcase1(stage) switch(stage, experimental = , maturing = , stable = , questioning = , retired = , archived = sprintf( "\\out{%s lifecycle}", url, file.path("figures", file), stage_alt ) , `soft-deprecated` = , deprecated = , defunct = sprintf( "\\figure{%s}{options: alt='%s lifecycle'}", file, stage_alt ), rlang::abort(sprintf("Unknown lifecycle stage `%s`", stage)) ) } lifecycle_validate_message <- function(msg) { stopifnot(rlang::is_character(msg)) paste0(msg, collapse = "\n") } lifecycle <- function(stage) { url <- paste0("https://www.tidyverse.org/lifecycle/#", stage) img <- lifecycle_img(stage, url) sprintf( "\\ifelse{html}{%s}{\\strong{%s}}", img, upcase1(stage) ) }cutpointr/R/oc_mean.R0000644000176200001440000000203713475240564014242 0ustar liggesusers#' Use the sample mean as cutpoint #' #' The sample mean is calculated and returned as the optimal cutpoint. #' #' @param data A data frame or tibble in which the columns that are given in x #' and class can be found. #' @param x (character) The variable name to be used for classification, #' e.g. predictions or test values. #' @param trim The fraction (0 to 0.5) of observations to be trimmed from each #' end of x before the mean is computed. Values of trim outside that range are #' taken as the nearest endpoint. #' @param ... To capture further arguments that are always passed to the method #' function by cutpointr. The cutpointr function passes data, x, class, #' metric_func, direction, pos_class and neg_class to the method function. #' @examples #' data(suicide) #' oc_mean(suicide, "dsi") #' cutpointr(suicide, dsi, suicide, method = oc_mean) #' @family method functions #' @export oc_mean <- function(data, x, trim = 0, ...) { stopifnot(is.character(x)) return(data.frame(optimal_cutpoint = mean(unlist(data[, x]), trim = trim))) } cutpointr/R/summary.multi_cutpointr.R0000644000176200001440000000671013764473705017606 0ustar liggesusers#' @export summary.multi_cutpointr <- function(object, ...) { x_summary <- vector("list", nrow(object)) names(x_summary) <- suppressWarnings(object$subgroup) for (r in 1:nrow(object)) { temprow <- object[r, ] if (has_column(object, "subgroup")) { x_summary[[r]]$subgroup <- temprow$subgroup } x_summary[[r]]$predictor <- temprow$predictor x_summary[[r]]$cutpointr <- temprow x_summary[[r]]$desc <- dplyr::bind_cols( tibble::tibble(Data = "Overall"), summary_sd_df(temprow$data[[1]] %>% dplyr::select(temprow$predictor)) ) temprow_split <- temprow$data[[1]] %>% split(temprow$data[[1]][, temprow$outcome]) x_summary[[r]]$desc_byclass <- temprow_split %>% purrr::map_df(function(x) summary_sd_df(x %>% dplyr::select(temprow$predictor))) x_summary[[r]]$desc_byclass <- dplyr::bind_cols( data.frame(Data = names(temprow_split), stringsAsFactors = FALSE), x_summary[[r]]$desc_byclass ) x_summary[[r]]$n_obs <- nrow(temprow$data[[1]]) x_summary[[r]]$n_pos <- temprow$data[[1]] %>% dplyr::select(!!as.name(temprow$outcome)) %>% unlist %>% (function(x) sum(x == temprow$pos_class)) x_summary[[r]]$n_neg <- x_summary[[r]]$n_obs - x_summary[[r]]$n_pos # Confusion Matrix oi <- get_opt_ind(temprow$roc_curve[[1]], oc = unlist(temprow$optimal_cutpoint), direction = temprow$direction) x_summary[[r]]$confusion_matrix <- data.frame( cutpoint = unlist(temprow$optimal_cutpoint), temprow$roc_curve[[1]][oi, c("tp", "fn", "fp", "tn")] ) if (has_boot_results(temprow)) { x_summary[[r]][["boot"]] <- purrr::map(temprow[["boot"]][[1]][, 1:13], function(x) { summary_sd(x) }) x_summary[[r]][["boot"]] <- do.call(rbind, x_summary[[r]][["boot"]]) x_summary[[r]][["boot"]] <- as.data.frame(x_summary[[r]][["boot"]]) x_summary[[r]][["boot"]] <- tibble::rownames_to_column(x_summary[[r]][["boot"]], var = "Variable") x_summary[[r]]$boot_runs <- nrow(temprow[["boot"]][[1]]) } } x_summary <- suppressMessages(purrr::map_df(x_summary, tidy_summary_multi)) class(x_summary) <- c("summary_multi_cutpointr", class(x_summary)) return(x_summary) } # Convert the list output of summary.cutpointr to a data.frame # x is a single element of the resulting list from summary.cutpointr. tidy_summary_multi <- function(x) { res <- tibble::tibble( predictor = x$predictor, cutpointr = list(x$cutpointr), desc = list(x$desc), desc_by_class = list(x$desc_byclass), n_obs = x$n_obs, n_pos = x$n_pos, n_neg = x$n_neg, confusion_matrix = list(x$confusion_matrix) ) if (has_boot_results(x)) { res <- dplyr::bind_cols(res, # tidyr::nest(x[["boot"]], .key = "boot"), tibble::tibble(boot = list(x[["boot"]])), boot_runs = x$boot_runs) } if (has_column(x, "subgroup")) { res <- dplyr::bind_cols(subgroup = x$subgroup, res) } return(res) } cutpointr/NEWS.md0000644000176200001440000003022114066444732013407 0ustar liggesusers# cutpointr 1.1.1 ## Changes - Clarified the help for the boot_stratify parameter - Better examples for the constrained metrics - Added reference and citation for the article about cutpointr in JSS # cutpointr 1.1.0 ## Changes - `boot_ci` now works with multiple cutpoints (multiple cutpoints are possible if `break_ties = c`). - `add_metric` now adds the selected metrics to the bootstrap results, too. - Include metrics that were added with `add_metric` in `summary()`. - Change default value of `subgroup` in `multi_cutpointr` to `NULL` (instead of missing) to make it consistent with `cutpointr`. - No rounding anymore within the internal function `summary_sd` so that the various summary functions now return all values without rounding. - Descriptive statistics in summary functions are now stored with the additional first column "Data" instead of giving the class values as row names. - Nicer printing of summary objects in Rmd documents. - `boot_stratify` is now passed to the method functions so that the bootstrap within `maximize_boot_metric` and `minimize_boot_metric` can be stratified, too. - Subtitles (such as "by class") have been removed from the plots because the subtitles should have read "by subgroup" and because this is already clear from the legend. ## Fixes - Fix a bug in `multi_cutpointr` that forced the `class` variable to be named "suicide". # cutpointr 1.0.32 - Reduce size of tarball for CRAN by removing some superfluous files # cutpointr 1.0.31 - Accelerate tests and vignette building to lower runtime on CRAN # cutpointr 1.0.3 - Some changes for vctrs 0.3.0 and dplyr 1.0.0: Unname and correctly assign classes to a few objects instead of using vctrs::df_cast and vctrs::df_ptype2 to keep compatibility with vctrs 0.2.4 - Added ORCID and article reference to Description # cutpointr 1.0.2 - Minor internal changes for compatibility with the latest updates of some packages from the tidyverse (e.g. `tibble` 3.0.0) # cutpointr 1.0.1 - Prepare for matrix inheriting from class "array" in R 4.0.0 by making a minor change in non-exported utility function `sanitize_metric` # cutpointr 1.0.0 ## Most important changes - `cutpointr` and `roc` now both use tidyeval. `!!` can be used when an argument should be unquoted, as in `dplyr`, e.g. `myvar <- "dsi"; cutpointr(suicide, !!myvar, suicide)`. `cutpointr_` is now deprecated. Transforming variables directly in the call is thus no longer supported, e.g. `cutpointr(suicide, dsi * 2, suicide)` now throws an error. - The object returned by `multi_cutpointr` does not have the `cutpointr` class anymore. ## New functions - A new `boot_ci` function is available that calculates confidence intervals (the empirical quantiles) based on the bootstrap results. - The `auc` function is now exported and can be used to calculate the AUC from a `cutpointr` or `roc_cutpointr` object, e.g. `auc(roc(suicide, dsi, suicide, "yes", "no"))` - `boot_test` is a new function for carrying out a bootstrap test for equivalence of a metric, e.g. the AUC, the Youden-Index or also the optimal cutpoint. The standard deviation is calculated as `sd` of the differences in metric values per bootstrap repetition, then a z-test is calculated. ## Plotting - New `type` argument to `plot_roc` for choosing line or step - The resulting object from `roc_cutpointr` can now simply be plotted with `plot()` ## Bootstrapping - The bootstrapping no longer tries to redraw bootstrap samples if only one class is drawn. In that case the repetition is removed from the results via `.errorhandling = "remove"` in `foreach`. - Subsequently report the number of missing values in the bootstrap results. `summary.cutpointr` and `summary.multi_cutpointr` now print an additional `NAs` column in the bootstrap summary and `cutpointr` issues a message if any bootstrap repeats failed (e.g. because only one class was drawn). - Stratified bootstrapping is now supported via the `boot_stratify` argument. # Misc - Make the printed output of `summary.cutpointr` and `summary.multi_cutpointr` more compact - No rounding of numbers in `summary.cutpointr` and `summary.multi_cutpointr` any more. The rounding is now done in `print.summary_cutpointr` and `print.summary_multi_cutpointr`, respectively, and can be controlled via the `digits` argument - `plot_metric` has a new `add_unsmoothed` argument for adding the unsmoothed metric values to the plot as a dashed line (default `TRUE`). Helpful to inspect the smoothing of functions like `maximize_gam_metric`. - Add some mathematical details to `?oc_youden_kernel`. - The Readme and vignette have been updated and condensed a bit. - A warning is issued if in `metric_constrain` or one of the other constrained metrics `min_constrain` can not be achieved. ## Fixes - Fix the default for `break_ties` in `cutpointr.default` by setting it to `median` as it was already in `cutpointr.numeric` and `cutpointr_`. # cutpointr 0.7.6 - Let `roc()` return a tibble instead of a data.frame - Printing results of `roc()` is now possible with `plot_roc()` - Extra metric columns can now be added to a `roc_cutpointr` object with `add_metric()` - Add prostate_nodal data set of nodal involvement and acid phosphatase levels in 53 prostate cancer patients - Fix fetching of method name if method was called using `::` or `:::` - Make test of summary printing more tolerant after problems with `tidyr` 0.8.3 - Issue an error if plot is used on a `multi_cutpointr` object - Add a summary method for `multi_cutpointr`, a corresponding `summary_multi_cutpointr` class and a printing method for that class - The column `variable` is not returned anymore by `multi_cutpointr`, because it is identical to `predictor` - Run `multi_cutpointr` only on all numeric columns, if `x = NULL` # cutpointr 0.7.5 - Add constrainable metrics, e.g. sens_constrain to calculate sensitivity given a minimum value for specificity - Fix a bug where dot-arguments were not passed to the metric function in cutpointr_internal - Add a check to ensure that the metric function does not return only missing values - Replace (fix) ">" by ">=" in the documentation of `cutpointr()`. # cutpointr 0.7.4 - Add `sigfig` argument to `print.cutpointr` to allow for specifying the number of significant digits to be printed - Add `add_metric()` function to add further metrics to the output of `cutpointr()` - Add `roc01` metric function to calculate the distance of points on the ROC curve to the point (0,1) on ROC space - Fix `plot_sensitivity_specificity()` if `boot_runs = 0` # cutpointr 0.7.3 - Fix display of bootstrap results in summary - Update benchmarks in Readme # cutpointr 0.7.2 - More tests and modified two tests that led to errors when CRAN checked the package (`spar = NULL` in `maximize_spline_metric`) - Add links to the documentation of all method, plotting, main and metric functions to all other functions of the same family - Add some checks to predict.cutpointr to prevent improper `cutpoint_nr` - The `boot` column is now always returned and `NA`, if no bootstrapping was run, so that the number of returned columns is constant # cutpointr 0.7.1 - Fix a bug in check_method_cols that occurred when a user-supplied method function returned a metric column but no roc_curve - Add chapters to the Readme about GAM, kernel and normal methods - Fix bug in bootstrapping that allowed resamples with only one class to be sampled - `use_midpoints` is now also passed to `method` by `cutpointr` to allow for the calculation of midpoints within `maximize_boot_metric` and `minimize_boot_metric`, which before happened in `cutpointr`, leading to slightly biased cutpoints in certain scenarios # cutpointr 0.7.0 - Change defaults in spline smoothing: `nknots` is now calculated by `stats::.nknots_smspl` and `spar = 1` - Add `cutpoint_tol` argument to define a tolerance around the optimized metric, so that multiple cutpoints in the vicinity of the target metric can be returned and to avoid not returning other "optimal" cutpoints due to floating-point problems - Change default value to `break_ties = c` - If multiple optimal cutpoints are found and they are summarized using `break_ties`, the returned main metric is now not the optimal one but the one corresponding to the summarized cutpoint (thus may be worse than the optimal one) - Add `maximize_gam_metric` and `minimize_gam_metric` for smoothing via generalized additive models - All plots with `geom_ribbon` now use `size = 0` to plot no lines around the (transparent) areas # cutpointr 0.6.0 - Return multiple optimal cutpoints - Add spline smoothing method # cutpointr 0.5.2 - Reformat docs - Remove superfluous check in `plot_cutpointr` - Add metrics `plr` (positive likelihood ratio), `nlr` (negative likelihood ratio), `false_discovery_rate`, and `false_omission_rate` # cutpointr 0.5.1 - In preparation for a new version of tibble that will restore the old printing behaviour and in order to pass the CRAN check the print method for cutpointr has been altered depending on the loaded version of tibble. - `silent` argument for roc(). - Reformat docs to include better formatted equations - Remove superfluous check in plot_cutpointr # cutpointr 0.5.0 - `cutpointr_` now accepts functions instead of character strings as `method` or `metric` - Fix naming the metric in the bootstrap if the supplied function returns an unnamed vector - Fix help for the `use_midpoints` parameter. If TRUE (default FALSE) the returned optimal cutpoint will be the mean of the optimal cutpoint and the next lowest observation (for `direction = ">="`) or the next highest observation (for `direction = "<="`) - Rename `sum_ppvnpv`, `prod_ppvnpv`, and `abs_d_ppvnpv` to `sum_ppv_npv`, `prod_ppv_npv`, and `abs_d_ppvnpv` to match the naming scheme to the names of the metrics that optimize sensitivity and specificity - Also all metric names that are returned by the metric functions are now lower case - The `summary_sd` function now also returns 5% and 95% percentiles that are included in the output of `summary` - The default number of bootstrap repeats in `minimize_boot_metric` and `maximize_boot_metric` was changed from 200 to 50 - The message "Running bootstrap..." is now displayed before executing the bootstrap so that possible messages or warnings can be attributed to the main cutpoint estimation or cutpoint estimation during the bootstrapping - The `summary` function now returns a data.frame instead of a list, also the printing method for `summary_cutpointr` has been slightly modified - Add `plot_sensitivity_specificity` for plotting cutpoints vs. sensitivity and specificity on the y-axis - Remove `oc_optimalCutpoints` function - Remove dependencies `ROCR` and `OptimalCutpoints` by rewriting tests and storing benchmark results # cutpointr 0.4.0 - cutpointr() now also works on vectors of raw data, that is without the `data` argument. Thus, it can be used as before by specifying `data`, `x`, and `class` or alternatively without specifying `data` and directly supplying the vectors of predictions and outcomes as `x` and `class`. - `silent` argument for optionally suppressing messages (e.g. which class is assumed to be the positive one) - Parts of the code were rewritten using Rcpp which leads to roughly a threefold speedup with larger n (n > 1e5) - The automatic determination of the positive / negative classes and direction now uses the median of the predictor values per class instead of the mean so that the AUC is always >= 0.5 - The bootstrapping now also returns the in-bag main metric, the out-of-bag ROC curve, and the out-of-bag AUC # cutpointr 0.3.2 - Add multi_cutpointr for running cutpointr_ on multiple predictor variables - Add metric risk_ratio - Use geom_bar instead of geom_histogram if all cutpoints are integer in plot_x and plot_cut_boot or if there is just one unique value - If bootstrapping is run, a bootstrapped confidence interval can be displayed in plot_metric - Add methods for median and mean as cutpoint - Fix display of cutpoint in ROC curve (use get_opt_ind in plot.cutpoint and plot_roc) - Fix picking correct metric in plot_metric_bootcutpointr/MD50000644000176200001440000002002114066536752012622 0ustar liggesusers64c6b1de03a0ff3f67b47f886bd5bf61 *DESCRIPTION 160ed78cb3c4936d71d32c06e156567b *NAMESPACE b088b869a58d7f50e6542ba549f6c80e *NEWS.md 74fe61477ad8642f48775ac43c32a7b2 *R/RcppExports.R bda817a71a3bace9d4e03466dc8269b5 *R/add_metric.R df25a01f7b0ffa8ac1441d8f661fcfdd *R/boot_ci.R 84087d4e1ab02375dcc7eebbed34c5bc *R/boot_test.R a584d37c9a7cdb3fbd25829dadae1fb4 *R/compat-lifecycle.R 2153b5023b5c0216edb24103eb13ab91 *R/cutpointr.R 1c66c16ba28a485b881b7945d0b8a175 *R/data.R 8c9d622276740fc63868c4dd4ef37af3 *R/globals.R b635ed1bc66dba8cf74e86c97cc373dc *R/grid_arrange_shared_legend.R f22727b1697f59bf1d73882a9f026639 *R/metrics.R 08bab27f3b87dd4636a26aae9c12cd25 *R/oc_manual.R 61458b954e869bf1df31fcc6742e7c99 *R/oc_mean.R d1fc481dc0ab92ba72f9d64e7b8e5134 *R/oc_median.R 18fe3e06b7a1e92ccd007d10b3e9e257 *R/oc_youden_kernel.R 41b376e70fe19cbde90ad36aa0062317 *R/oc_youden_normal.R d0274b35d0326efcba47e9545c0c072b *R/optimize_metric.R 3dc14ed6c6ae4e94294f2a36c4a73c0a *R/plot.cutpointr.R d99d030c86f332ef17fdc2c2f0cec6d2 *R/plot.multi_cutpointr.R 9b20728d8cca3def8f03ea58ae37a686 *R/plot_cut_boot.R 1f7c25b183de8cadf81fbd3b6094c6e8 *R/plot_cutpointr.R 5db2be040c3a5d4aa0429c518e4d21e6 *R/plot_metric.R 91f7fe2ade36e5414ba72d9aac4004d6 *R/plot_metric_boot.R aa80daa6c1115b48da7dbe36806fe12e *R/plot_precision_recall.R ffa06a40467953beb38a21dab34b058e *R/plot_roc.R 14c7d6909b27b9bde20ca4c647e6607f *R/plot_sensitivity_specificity.R 40f60699e354dfd49325c764897d441f *R/plot_x.R 1b67bf1ef20060c43e73757bf4a7ff60 *R/predict.cutpointr.R 1c5ec2c9681c157842039cd968473a19 *R/prep.R aec0e1f6041457aad98d276a46c3eb6a *R/print.cutpointr.R 645c79818950b0d2e6d78ba9366958a6 *R/print.multi_cutpointr.R 47e73740d8afe024e9aeebefbde2cef2 *R/print.summary_cutpointr.R 783314ed841fd424bff563b9f436c738 *R/print.summary_multi_cutpointr.R 9d36ee58049e463bd614e3ef312bbbcb *R/roc.R fb2f461348551d2642967ad8082829b6 *R/summary.cutpointr.R 1504abd45031539469a034341502b86c *R/summary.multi_cutpointr.R b0cd11ff507488d8cbc3da73e85c8849 *R/utils.R f97fc8bc561a972efea1c1eadd8d266f *build/vignette.rds fc18517070c515950b5a981c34891e1e *data/prostate_nodal.rda c5858b95c390466fe85b7e996d88c0f0 *data/suicide.rda 91c73d643409535108d4786c689e5d62 *inst/CITATION 269e703bcb0832039a3e492100574b0b *inst/doc/cutpointr.R d20f5a840efe68381cbd9c720d7ad963 *inst/doc/cutpointr.Rmd 1f846b9d576cf140f4daf52ed9b232ef *inst/doc/cutpointr.html 96dffaa4cf27fcf9ff977aa770cbeb0e *man/F1_score.Rd fca9d477153ee93b0aba290e4294414d *man/Jaccard.Rd 9fe3fea4c83eb04ae3b31b1de3945bef *man/abs_d_ppv_npv.Rd 3af701ec86942c0334bf2d223c2ae2a9 *man/abs_d_sens_spec.Rd 6df4b9ce4898f5a736b6de545d5b4918 *man/accuracy.Rd de50662f80140c8a4e9d232574f5140a *man/add_metric.Rd 63c08c4910e2dafe52c0bb68160df274 *man/auc.Rd 7cb875e9144864a0579da640a922c1c5 *man/boot_ci.Rd 71c7142970704c5445de5514b7c3ac93 *man/boot_test.Rd 6eee4c770419fda57022c778dba122a5 *man/cohens_kappa.Rd 778c197bfac37101f0d954190c00d05b *man/cutpoint.Rd 9225fa88b60f9fadd343f8974ca8717d *man/cutpoint_knots.Rd ddf1ef2a9b1f21f18a75c33dfca561cc *man/cutpointr.Rd 84be0a0b7d5d9ae06bbe8017b8e6f5f2 *man/cutpointr_.Rd 057ac64de1934d7ed4c9a7cc4ca2e428 *man/false_omission_rate.Rd b8f597cd9a3e916cf18d82cdd5b81279 *man/figures/README-unnamed-chunk-11-1.png 3ae5da83efaf3ab543b270782412642f *man/figures/README-unnamed-chunk-15-1.png 159718265ca11048ee1560b19e2d0f04 *man/figures/README-unnamed-chunk-17-1.png 6c7246c94483f7ab8f5aff747933e6f9 *man/figures/README-unnamed-chunk-18-1.png c880bc43481a7011dde968aa079cf389 *man/figures/README-unnamed-chunk-19-1.png 2e88dd12d81a455c8bcc0766c27cb9bd *man/figures/README-unnamed-chunk-22-1.png b1a00581ee457e579e7710630b928006 *man/figures/README-unnamed-chunk-24-1.png 0936411b418cbbfb4c51518b2425eb17 *man/figures/README-unnamed-chunk-26-1.png af8b758649d6b5f52cfee9e92a91c223 *man/figures/README-unnamed-chunk-36-1.png 62fe453423c58d485c8677fd39157738 *man/figures/README-unnamed-chunk-36-2.png 7f8aeaf25a04b0b5df8f8bd99fda2da7 *man/figures/README-unnamed-chunk-36-3.png 8ac1a624fd1e4df56a7b2379f4c44356 *man/figures/README-unnamed-chunk-36-4.png 8b01555b801af11124239d752d13fd8d *man/figures/README-unnamed-chunk-36-5.png c8af850c1201179f2f22fed9ddba4233 *man/figures/README-unnamed-chunk-36-6.png 27f0c1f1ed28debb36263c5ee4a4f917 *man/figures/README-unnamed-chunk-37-1.png d6f8741a155dd5e893eb55e2aebade3a *man/figures/README-unnamed-chunk-38-1.png 8b0ae0a9eda3e25e0234226e5040a473 *man/figures/README-unnamed-chunk-38-2.png 092a051a5f6d0d84f1a1060b44498e2f *man/figures/README-unnamed-chunk-38-3.png 226e3cd54174f70d32bc3a4ea6fc5383 *man/figures/README-unnamed-chunk-39-1.png 0274ac1b9e466d3d93bc67f281cddd56 *man/figures/README-unnamed-chunk-46-1.png 3428481a240c41ae977a1bcd5d763067 *man/figures/README-unnamed-chunk-5-1.png 747efb8e6539fff8056d4ed9827bd6db *man/figures/README-unnamed-chunk-7-1.png ac61a26e12991f5ceab01b612e64147a *man/maximize_boot_metric.Rd 29fc2bd7c403e7fae0714782294e4c82 *man/maximize_gam_metric.Rd a442fd59ee4373d3483916344a63999f *man/maximize_loess_metric.Rd 7c5c24068b7ec5275dd168f41dc577df *man/maximize_metric.Rd 7c09f3dc53f017a03818b66745a0f6a3 *man/maximize_spline_metric.Rd b46fecc577abb2643a7ed618f50295a4 *man/metric_constrain.Rd 29db90e26b8b2040f968174d9afb45f7 *man/misclassification_cost.Rd edcb119d21e5768a6783a7eed3931d25 *man/multi_cutpointr.Rd 0d67327d6d64c099f9005e86dbb56450 *man/npv.Rd 3d478b3b206e9660c70e21522627777e *man/oc_manual.Rd 62d3b5eb078df045516f91c80c704fa0 *man/oc_mean.Rd eb39058f3c50afdacaf0099a5e9a85f9 *man/oc_median.Rd b66dadcad0b529e26e91b27b29c409c1 *man/oc_youden_kernel.Rd 6f5e1d2392129aa66676cf954a344b95 *man/oc_youden_normal.Rd 6ff6f05586d450db335fc1a6fc36e542 *man/odds_ratio.Rd dc46b3a086b3be1e8a6ca2cf4fc08933 *man/p_chisquared.Rd cc82f918cfdb3f323328566bc3b457c5 *man/plot.cutpointr.Rd 0b55fa099e196c45a00cdf0b8bc84c1c *man/plot.multi_cutpointr.Rd 52be73f0674b2b13a3d87ea8ab89d937 *man/plot.roc_cutpointr.Rd b70cfd0dca6dec49bd7ae8a2494710ab *man/plot_cut_boot.Rd aca17ffb6e5c556cf1b561a83dbdf571 *man/plot_cutpointr.Rd 9d71d2e79d14632381319d0c99ea0ddb *man/plot_metric.Rd ba80f5d4d261edf8efe5958dad8b3858 *man/plot_metric_boot.Rd 740239e169ea3dcf8b89c6bde5e13e6b *man/plot_precision_recall.Rd e65c822abc6ec7d1753839b918acaec4 *man/plot_roc.Rd ebeef0c652e5758e44b3767ab1e914c0 *man/plot_sensitivity_specificity.Rd 4d4b6258d50423c033b150430e82ffad *man/plot_x.Rd 036b9d3983ecdff823d5a4dc7604a388 *man/plr.Rd 967a86dbb89cb299b3723b91b0a70778 *man/ppv.Rd 8bbdaa128684c91aa09939b25b29adc5 *man/precision.Rd 2a3b95861eadc24865efd6120dee4f2c *man/predict.cutpointr.Rd 13327e97386b501357d8b6895a877be5 *man/print.cutpointr.Rd 8d8f3f5dc510efdfbf13215b6438a846 *man/print.multi_cutpointr.Rd 8d9aa56c0b01c07a7be8f294d318113e *man/prod_ppv_npv.Rd f74bc05649bae1506fbb876550c115dc *man/prod_sens_spec.Rd f93448e51ffaecab35763bc8ebbf6af9 *man/prostate_nodal.Rd 290081e5c350cefec9aec59600ea69d6 *man/recall.Rd dd1c2db7b39dd5776de83721806d3f76 *man/risk_ratio.Rd 56ffc86c365f12b626ee881314167a9f *man/roc.Rd 785d0e8cf9fac300642c428106bef0d6 *man/roc01.Rd c4b9163da1ac7ba24da5252329b0de20 *man/sensitivity.Rd c5fedc999eb4f69099592d5f333c0a5b *man/specificity.Rd 2b83207bdae22e3a18514ce0e2c7abd9 *man/suicide.Rd 317d5bede8b030c9812f64fb63e86ca6 *man/sum_ppv_npv.Rd c84fdd10ff202018d88c2452cc5f4629 *man/sum_sens_spec.Rd 1f4e14f74027237bbe2123805a6fe569 *man/total_utility.Rd 70949a24ff2ef3cfedb1d8da7ee7e56a *man/tp.Rd d901f9afb7a07f90ab16cc642ece22c2 *man/tpr.Rd cb3c8ff0769c56294510cd71cfd8aa3c *man/user_span_cutpointr.Rd a3a8131b480cad56a39bcc8b70b2ad1e *man/youden.Rd af39ac4dd81f6cb1e5f2b457f49cdec5 *src/RcppExports.cpp 385ce4c96b03232a5663ace9c63f33c8 *src/any_inf.cpp 0350cfd489e23640678d4a869ec8371e *src/get_rev_dups.cpp b95fdd80a9b3c0e1147dae38ce725f33 *src/is_equal_cpp.cpp 83f74134d6bf7e4524a80f1f9453fbe5 *src/one_unique.cpp 6e0cada596ec84d20e96a4e11df04f89 *src/which.cpp c0d0c032120604a9b78789cc46197ccc *tests/testthat.R f6f02cbaba0ddabbe4904b4bc0b25013 *tests/testthat/Rplots.pdf 4c6aa120dd84a72a86fc2057230f2988 *tests/testthat/test-cutpointr.R d20f5a840efe68381cbd9c720d7ad963 *vignettes/cutpointr.Rmd c78e6498256e26d17e50b6658a163e01 *vignettes/vignettedata/vignettedata.Rdata cutpointr/inst/0000755000176200001440000000000014066445216013266 5ustar liggesuserscutpointr/inst/doc/0000755000176200001440000000000014066445216014033 5ustar liggesuserscutpointr/inst/doc/cutpointr.R0000644000176200001440000010402214066445216016204 0ustar liggesusers## ---- include = FALSE--------------------------------------------------------- knitr::opts_chunk$set(fig.width = 6, fig.height = 5, fig.align = "center") options(rmarkdown.html_vignette.check_title = FALSE) load("vignettedata/vignettedata.Rdata") ## ----CRAN, eval = FALSE------------------------------------------------------- # install.packages("cutpointr") ## ----------------------------------------------------------------------------- library(cutpointr) data(suicide) head(suicide) cp <- cutpointr(suicide, dsi, suicide, method = maximize_metric, metric = sum_sens_spec) ## ----------------------------------------------------------------------------- summary(cp) ## ----------------------------------------------------------------------------- plot(cp) ## ----------------------------------------------------------------------------- opt_cut <- cutpointr(suicide, dsi, suicide, direction = ">=", pos_class = "yes", neg_class = "no", method = maximize_metric, metric = youden) ## ----------------------------------------------------------------------------- plot_metric(opt_cut) ## ----------------------------------------------------------------------------- predict(opt_cut, newdata = data.frame(dsi = 0:5)) ## ----separate subgroups and bootstrapping, eval = FALSE----------------------- # set.seed(12) # opt_cut_b <- cutpointr(suicide, dsi, suicide, boot_runs = 1000) ## ----------------------------------------------------------------------------- opt_cut_b ## ----------------------------------------------------------------------------- opt_cut$boot ## ----------------------------------------------------------------------------- summary(opt_cut) plot(opt_cut) ## ---- eval = FALSE------------------------------------------------------------ # library(doParallel) # cl <- makeCluster(2) # 2 cores # registerDoParallel(cl) # registerDoRNG(12) # Reproducible parallel loops using doRNG # opt_cut <- cutpointr(suicide, dsi, suicide, gender, pos_class = "yes", # direction = ">=", boot_runs = 1000, allowParallel = TRUE) # stopCluster(cl) # opt_cut ## ---- cache=TRUE-------------------------------------------------------------- set.seed(100) cutpointr(suicide, dsi, suicide, gender, method = maximize_boot_metric, boot_cut = 200, summary_func = mean, metric = accuracy, silent = TRUE) ## ----------------------------------------------------------------------------- opt_cut <- cutpointr(suicide, dsi, suicide, gender, method = minimize_metric, metric = misclassification_cost, cost_fp = 1, cost_fn = 10) ## ----------------------------------------------------------------------------- plot_metric(opt_cut) ## ---- message = FALSE--------------------------------------------------------- opt_cut <- cutpointr(suicide, dsi, suicide, gender, method = minimize_loess_metric, criterion = "aicc", family = "symmetric", degree = 2, user.span = 0.7, metric = misclassification_cost, cost_fp = 1, cost_fn = 10) ## ----------------------------------------------------------------------------- plot_metric(opt_cut) ## ----------------------------------------------------------------------------- library(ggplot2) exdat <- iris exdat <- exdat[exdat$Species != "setosa", ] opt_cut <- cutpointr(exdat, Petal.Length, Species, method = minimize_gam_metric, formula = m ~ s(x.sorted, bs = "cr"), metric = abs_d_sens_spec) plot_metric(opt_cut) ## ----------------------------------------------------------------------------- opt_cut <- cutpointr(suicide, dsi, suicide, gender, method = minimize_spline_metric, spar = 0.4, metric = misclassification_cost, cost_fp = 1, cost_fn = 10) plot_metric(opt_cut) ## ----------------------------------------------------------------------------- cutpointr(suicide, dsi, suicide, gender, method = oc_youden_normal) ## ----------------------------------------------------------------------------- cutpointr(suicide, dsi, suicide, gender, method = oc_youden_kernel) ## ---- fig.width=4, fig.height=3----------------------------------------------- roc_curve <- roc(data = suicide, x = dsi, class = suicide, pos_class = "yes", neg_class = "no", direction = ">=") auc(roc_curve) head(roc_curve) plot_roc(roc_curve) ## ----------------------------------------------------------------------------- dat <- data.frame(outcome = c("neg", "neg", "neg", "pos", "pos", "pos", "pos"), pred = c(1, 2, 3, 8, 11, 11, 12)) ## ----------------------------------------------------------------------------- opt_cut <- cutpointr(dat, x = pred, class = outcome, use_midpoints = TRUE) plot_x(opt_cut) ## ---- echo = FALSE------------------------------------------------------------ plotdat_nomidpoints <- structure(list(sim_nr = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 16L, 16L, 16L, 16L, 16L, 16L, 16L, 16L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 18L, 18L, 18L, 18L, 18L, 18L, 18L, 18L, 19L, 19L, 19L, 19L, 19L, 19L, 19L, 19L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 22L, 22L, 22L, 22L, 22L, 22L, 22L, 22L, 23L, 23L, 23L, 23L, 23L, 23L, 23L, 23L, 24L, 24L, 24L, 24L, 24L, 24L, 24L, 24L, 25L, 25L, 25L, 25L, 25L, 25L, 25L, 25L, 26L, 26L, 26L, 26L, 26L, 26L, 26L, 26L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 28L, 28L, 28L, 28L, 28L, 28L, 28L, 28L, 29L, 29L, 29L, 29L, 29L, 29L, 29L, 29L, 30L, 30L, 30L, 30L, 30L, 30L, 30L, 30L, 31L, 31L, 31L, 31L, 31L, 31L, 31L, 31L, 32L, 32L, 32L, 32L, 32L, 32L, 32L, 32L, 33L, 33L, 33L, 33L, 33L, 33L, 33L, 33L, 34L, 34L, 34L, 34L, 34L, 34L, 34L, 34L, 35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L, 36L, 36L, 36L, 36L, 36L, 36L, 36L, 36L), method = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L), .Label = c("emp", "normal", "loess", "boot", "spline", "spline_20", "kernel", "gam" ), class = "factor"), n = c(30, 30, 30, 30, 30, 30, 30, 30, 50, 50, 50, 50, 50, 50, 50, 50, 75, 75, 75, 75, 75, 75, 75, 75, 100, 100, 100, 100, 100, 100, 100, 100, 150, 150, 150, 150, 150, 150, 150, 150, 250, 250, 250, 250, 250, 250, 250, 250, 500, 500, 500, 500, 500, 500, 500, 500, 750, 750, 750, 750, 750, 750, 750, 750, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 30, 30, 30, 30, 30, 30, 30, 30, 50, 50, 50, 50, 50, 50, 50, 50, 75, 75, 75, 75, 75, 75, 75, 75, 100, 100, 100, 100, 100, 100, 100, 100, 150, 150, 150, 150, 150, 150, 150, 150, 250, 250, 250, 250, 250, 250, 250, 250, 500, 500, 500, 500, 500, 500, 500, 500, 750, 750, 750, 750, 750, 750, 750, 750, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 30, 30, 30, 30, 30, 30, 30, 30, 50, 50, 50, 50, 50, 50, 50, 50, 75, 75, 75, 75, 75, 75, 75, 75, 100, 100, 100, 100, 100, 100, 100, 100, 150, 150, 150, 150, 150, 150, 150, 150, 250, 250, 250, 250, 250, 250, 250, 250, 500, 500, 500, 500, 500, 500, 500, 500, 750, 750, 750, 750, 750, 750, 750, 750, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 30, 30, 30, 30, 30, 30, 30, 30, 50, 50, 50, 50, 50, 50, 50, 50, 75, 75, 75, 75, 75, 75, 75, 75, 100, 100, 100, 100, 100, 100, 100, 100, 150, 150, 150, 150, 150, 150, 150, 150, 250, 250, 250, 250, 250, 250, 250, 250, 500, 500, 500, 500, 500, 500, 500, 500, 750, 750, 750, 750, 750, 750, 750, 750, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000), mean_err = c(0.532157164015659, 0.0344907054484091, 1.09430750651166, 0.847845162156675, 1.72337372126503, 0.893756658507988, 0.0430309247027736, 0.785821459035346, 0.368063404388512, 0.0256197760404459, 0.54480529648463, 0.54385597929651, 0.657325657699579, 0.578611116865437, 0.0400491342691897, 0.515688005217413, 0.256713912589642, 0.0444582875885996, 0.326975493112402, 0.371128780921122, 0.473515115741104, 0.389519558405289, 0.105044360789378, 0.301924717299333, 0.207750921776918, -0.00318128936770314, 0.215170156089776, 0.27218780048926, 0.260519564021842, 0.236792923882582, 0.0209319074923902, 0.232957055204834, 0.0726605917614469, -0.00282823355849125, 0.0753216783313991, 0.147121931849656, 0.0986417724955371, 0.10048009778446, -0.0117861260923649, 0.0650845904350442, 0.0985144485083747, 0.00601003227249322, 0.107439979908118, 0.120777421732797, 0.098470489820427, 0.0940946984227826, 0.0340166854141625, 0.107851118082414, 0.0249685210781582, -0.00275219600614378, 0.0258069390207201, 0.0303381972274654, -0.000994602151869198, 0.00196854833683764, -0.0172319489562159, 0.0230957871932473, 0.00787486424680835, -0.018438041997315, -0.000808033567394628, -0.00151904153864496, -0.0258118523805697, -0.020984156892953, -0.0411584927473141, -0.0462075435919094, 0.0481149217843661, -0.0115241085997692, 0.0278045708419731, 0.0358588316426625, 0.0424473909450939, 0.0379773233328197, 0.0298772985879321, 0.0494939492036379, 0.561286668337778, 0.0210874502384648, 0.607711822769155, 0.944733906256477, 1.32069801051061, 0.623604782428556, 0.0138075109769806, 0.640859854412358, 0.284873604303057, -0.0170357985365701, 0.273426417633118, 0.524432737895336, 0.355003110979807, 0.312837607951434, -0.0316296929553873, 0.270109834098986, 0.174110335581819, 0.0253101719615279, 0.199956222742702, 0.375485416120771, 0.278956745944806, 0.244245525945888, 0.0325126314233263, 0.253352659868514, 0.154840760004461, 0.00231589709639472, 0.154412480165179, 0.264847742842386, 0.196572744185608, 0.182934783774992, 0.0207139021497755, 0.17351041376412, 0.14190910348156, -0.000766834484010096, 0.159975205214477, 0.191222128926019, 0.119768252112669, 0.12033372914036, -0.00429047209392067, 0.120982527821078, 0.0756304869484406, -0.00890884219048113, 0.0727782693168392, 0.118690444738942, 0.0814898789647033, 0.0799724348001957, 0.0182926240912726, 0.0887155007804252, 0.00799604720502299, 0.000599148388616836, -0.00567769035990384, 0.0358412514670032, 0.0308474979074875, 0.0341668723768997, -0.000180318451026095, 0.0180733341290925, 0.00456876236626807, 0.00150574966485876, 0.011152095953916, 0.0176039119729626, 0.00608274255434991, 0.0146257828313115, -0.0108877417404102, 0.00341198000323035, -0.00198459880370283, 0.0026551895445694, 0.00199040664534129, 0.0150165794544221, 0.00646287144368147, 0.00999205240904708, -0.00850278571195971, 0.000833666619266177, 0.714730067273087, -0.00916546079360956, 0.662799490366986, 1.18552468844156, 1.25901933062308, 0.672701515532179, 0.0311066140197676, 0.699068058809396, 0.451908043813962, 0.0131716226592205, 0.429551369887738, 0.697928133235757, 0.445367768988423, 0.408463448982185, 0.0318707241721211, 0.406284953982951, 0.257736307754364, -0.00525924423719458, 0.236977000055322, 0.429144726596141, 0.291381752107184, 0.267557606428613, 0.0103657879176852, 0.254728590646094, 0.187783398487578, -0.00216064381479362, 0.209025103860707, 0.318293592390017, 0.216751610346408, 0.195630579126633, -0.00355723971644246, 0.174111826408428, 0.151010324964235, 0.0152409223899092, 0.159002511320467, 0.214643583389694, 0.136211731513269, 0.138948149207635, 0.00736196817594524, 0.115637867729083, 0.0491348055596302, -0.00133957946235943, 0.0507437758212659, 0.103956325245849, 0.0641182216839426, 0.0721933081297794, -0.0124376134651938, 0.0632317888879588, 0.0322195712438111, 0.00170122889182022, 0.0287526766624194, 0.0589662164030242, 0.0348535721709848, 0.039527944642463, -0.00617539706415593, 0.0274246010641889, 0.0325877909680824, 0.00530528253248245, 0.0221776555499961, 0.0389702052631117, 0.0221602091288215, 0.0254478639695596, -0.0016189234058987, 0.0197144417326668, -0.00632485262604172, -0.00364979854195596, -0.00276076468388984, 0.0126267527301874, 0.0123592498266038, 0.0154921632247644, -0.00591512196680815, 0.0098685016547149, 1.19276916750486, -0.0296831640401583, 0.99406393593888, 1.95758669445116, 1.45842790978446, 0.916899913902239, -0.0240222410217233, 1.00771193034927, 0.748151091428865, 0.001671855025917, 0.665180535306263, 1.1777049634557, 0.578603609273264, 0.546625362141714, 0.0292152981607387, 0.615230814912951, 0.417886753756131, 0.00324593885807739, 0.406076310942717, 0.732191741449251, 0.352684769616612, 0.326901376027897, -0.000759357576337989, 0.350075431324921, 0.310927617707656, -0.0107255472998434, 0.28102101085112, 0.514683023356017, 0.24913510139508, 0.235155452507568, -0.0220885572014814, 0.243370611433649, 0.209652330609093, -0.00502865663759991, 0.2172246261346, 0.356540958804122, 0.172121720418057, 0.17487914828986, 0.00365942442127361, 0.176594681455494, 0.126956927057327, -0.00270525933073803, 0.120116234221594, 0.210827536708082, 0.101520409193932, 0.101379097920023, 0.00238043252144371, 0.113027315928011, 0.0598624378953727, -0.00538838415690431, 0.0568400730102315, 0.0978115258288965, 0.0454207684906316, 0.0473140143579152, -0.00165813015281622, 0.0521772135812508, 0.0530224090961669, -0.000416993405198653, 0.0353236911458531, 0.0605493601241619, 0.0316204159297213, 0.0344789374555544, -0.00446984887315054, 0.0328807595695966, 0.0396438546423947, -0.00331466369719113, 0.0379029847219126, 0.0572435100638761, 0.0253269328104989, 0.0235663211070417, 0.00220241478536399, 0.0307132312422208), youden = c(0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8 )), row.names = c(NA, -288L), group_sizes = c(8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L ), biggest_group_size = 8L, class = c("grouped_df", "tbl_df", "tbl", "data.frame"), groups = structure(list(sim_nr = 1:36, .rows = list(1:8, 9:16, 17:24, 25:32, 33:40, 41:48, 49:56, 57:64, 65:72, 73:80, 81:88, 89:96, 97:104, 105:112, 113:120, 121:128, 129:136, 137:144, 145:152, 153:160, 161:168, 169:176, 177:184, 185:192, 193:200, 201:208, 209:216, 217:224, 225:232, 233:240, 241:248, 249:256, 257:264, 265:272, 273:280, 281:288)), row.names = c(NA, -36L), class = c("tbl_df", "tbl", "data.frame"), .drop = TRUE)) ## ---- echo = FALSE------------------------------------------------------------ library(dplyr) ggplot(plotdat_nomidpoints %>% filter(!(method %in% c("spline_20"))), aes(x = n, y = mean_err, color = method, shape = method)) + geom_line() + geom_point() + facet_wrap(~ youden, scales = "fixed") + scale_shape_manual(values = 1:nlevels(plotdat_nomidpoints$method)) + scale_x_log10(breaks = c(30, 50, 75, 100, 150, 250, 500, 750, 1000)) + ggtitle("Bias of all methods when use_midpoints = FALSE", "normally distributed data, 10000 repetitions of simulation") ## ----------------------------------------------------------------------------- opt_cut <- cutpointr(suicide, dsi, suicide, metric = sum_sens_spec, tol_metric = 0.05, break_ties = c) library(tidyr) opt_cut %>% select(optimal_cutpoint, sum_sens_spec) %>% unnest(cols = c(optimal_cutpoint, sum_sens_spec)) ## ---- eval = FALSE------------------------------------------------------------ # set.seed(100) # opt_cut_manual <- cutpointr(suicide, dsi, suicide, method = oc_manual, # cutpoint = mean(suicide$dsi), boot_runs = 1000) # set.seed(100) # opt_cut_mean <- cutpointr(suicide, dsi, suicide, method = oc_mean, boot_runs = 1000) ## ---- eval = FALSE------------------------------------------------------------ # myvar <- "dsi" # cutpointr(suicide, !!myvar, suicide) ## ----------------------------------------------------------------------------- mcp <- multi_cutpointr(suicide, class = suicide, pos_class = "yes", use_midpoints = TRUE, silent = TRUE) summary(mcp) ## ---- eval = FALSE, message = FALSE------------------------------------------- # set.seed(123) # opt_cut_b_g <- cutpointr(suicide, dsi, suicide, gender, boot_runs = 1000) ## ---- message = FALSE--------------------------------------------------------- # Using dplyr and tidyr library(tidyr) opt_cut_b_g %>% group_by(subgroup) %>% select(subgroup, boot) %>% unnest(cols = boot) %>% summarise(sd_oc_boot = sd(optimal_cutpoint), m_oc_boot = mean(optimal_cutpoint), m_acc_oob = mean(acc_oob)) ## ----------------------------------------------------------------------------- cutpointr(suicide, dsi, suicide, gender, metric = youden, silent = TRUE) %>% add_metric(list(ppv, npv)) %>% select(subgroup, optimal_cutpoint, youden, ppv, npv) ## ----------------------------------------------------------------------------- roc(data = suicide, x = dsi, class = suicide, pos_class = "yes", neg_class = "no", direction = ">=") %>% add_metric(list(cohens_kappa, F1_score)) %>% select(x.sorted, tp, fp, tn, fn, cohens_kappa, F1_score) %>% head() ## ---- eval = FALSE------------------------------------------------------------ # mean_cut <- function(data, x, ...) { # oc <- mean(data[[x]]) # return(data.frame(optimal_cutpoint = oc)) # } ## ----------------------------------------------------------------------------- misclassification_cost ## ---- fig.width=4, fig.height=3----------------------------------------------- plot_cut_boot(opt_cut_b_g) plot_metric(opt_cut_b_g, conf_lvl = 0.9) plot_metric_boot(opt_cut_b_g) plot_precision_recall(opt_cut_b_g) plot_sensitivity_specificity(opt_cut_b_g) plot_roc(opt_cut_b_g) ## ---- fig.width=4, fig.height=3----------------------------------------------- p <- plot_x(opt_cut_b_g) p + ggtitle("Distribution of dsi") + theme_minimal() + xlab("Depression score") ## ---- fig.width=4, fig.height=3, cache=FALSE---------------------------------- plot_cutpointr(opt_cut_b, xvar = cutpoints, yvar = sum_sens_spec, conf_lvl = 0.9) plot_cutpointr(opt_cut_b, xvar = fpr, yvar = tpr, aspect_ratio = 1, conf_lvl = 0) plot_cutpointr(opt_cut_b, xvar = cutpoint, yvar = tp, conf_lvl = 0.9) + geom_point() ## ---- fig.width=4, fig.height=3----------------------------------------------- opt_cut_b_g %>% select(data, subgroup) %>% unnest(cols = data) %>% ggplot(aes(x = suicide, y = dsi)) + geom_boxplot(alpha = 0.3) + facet_grid(~subgroup) ## ---- eval = FALSE------------------------------------------------------------ # # Return cutpoint that maximizes the sum of sensitivity and specificiy # # ROCR package # rocr_sensspec <- function(x, class) { # pred <- ROCR::prediction(x, class) # perf <- ROCR::performance(pred, "sens", "spec") # sens <- slot(perf, "y.values")[[1]] # spec <- slot(perf, "x.values")[[1]] # cut <- slot(perf, "alpha.values")[[1]] # cut[which.max(sens + spec)] # } # # # pROC package # proc_sensspec <- function(x, class) { # r <- pROC::roc(class, x, algorithm = 2, levels = c(0, 1), direction = "<") # pROC::coords(r, "best", ret="threshold", transpose = FALSE)[1] # } ## ---- eval = FALSE, echo = FALSE---------------------------------------------- # library(OptimalCutpoints) # library(ThresholdROC) # n <- 100 # set.seed(123) # dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) # x_pos <- dat$x[dat$y == 1] # x_neg <- dat$x[dat$y == 0] # bench_100 <- microbenchmark::microbenchmark( # cutpointr(dat, x, y, pos_class = 1, neg_class = 0, # direction = ">=", metric = youden, break_ties = mean), # rocr_sensspec(dat$x, dat$y), # proc_sensspec(dat$x, dat$y), # optimal.cutpoints(X = "x", status = "y", tag.healthy = 0, methods = "Youden", # data = dat), # thres2(k1 = x_neg, k2 = x_pos, rho = 0.5, # method = "empirical", ci = FALSE), # times = 100, unit = "ms" # ) # # n <- 1000 # set.seed(123) # dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) # x_pos <- dat$x[dat$y == 1] # x_neg <- dat$x[dat$y == 0] # bench_1000 <- microbenchmark::microbenchmark( # cutpointr(dat, x, y, pos_class = 1, neg_class = 0, # direction = ">=", metric = youden, break_ties = mean), # rocr_sensspec(dat$x, dat$y), # proc_sensspec(dat$x, dat$y), # optimal.cutpoints(X = "x", status = "y", tag.healthy = 0, methods = "Youden", # data = dat), # thres2(k1 = x_neg, k2 = x_pos, rho = 0.5, # method = "empirical", ci = FALSE), # times = 100, unit = "ms" # ) # # n <- 10000 # set.seed(123) # dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) # x_pos <- dat$x[dat$y == 1] # x_neg <- dat$x[dat$y == 0] # bench_10000 <- microbenchmark::microbenchmark( # cutpointr(dat, x, y, pos_class = 1, neg_class = 0, # direction = ">=", metric = youden, break_ties = mean, silent = TRUE), # rocr_sensspec(dat$x, dat$y), # optimal.cutpoints(X = "x", status = "y", tag.healthy = 0, methods = "Youden", # data = dat), # proc_sensspec(dat$x, dat$y), # thres2(k1 = x_neg, k2 = x_pos, rho = 0.5, # method = "empirical", ci = FALSE), # times = 100 # ) # # n <- 1e5 # set.seed(123) # dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) # bench_1e5 <- microbenchmark::microbenchmark( # cutpointr(dat, x, y, pos_class = 1, neg_class = 0, # direction = ">=", metric = youden, break_ties = mean), # rocr_sensspec(dat$x, dat$y), # proc_sensspec(dat$x, dat$y), # times = 100, unit = "ms" # ) # # n <- 1e6 # set.seed(123) # dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) # bench_1e6 <- microbenchmark::microbenchmark( # cutpointr(dat, x, y, pos_class = 1, neg_class = 0, # direction = ">=", metric = youden, break_ties = mean), # rocr_sensspec(dat$x, dat$y), # proc_sensspec(dat$x, dat$y), # times = 30, unit = "ms" # ) # # n <- 1e7 # set.seed(123) # dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) # bench_1e7 <- microbenchmark::microbenchmark( # cutpointr(dat, x, y, pos_class = 1, neg_class = 0, # direction = ">=", metric = youden, break_ties = mean), # rocr_sensspec(dat$x, dat$y), # proc_sensspec(dat$x, dat$y), # times = 30, unit = "ms" # ) # # results <- rbind( # data.frame(time = summary(bench_100)$median, # Solution = summary(bench_100)$expr, # n = 100), # data.frame(time = summary(bench_1000)$median, # Solution = summary(bench_1000)$expr, # n = 1000), # data.frame(time = summary(bench_10000)$median, # Solution = summary(bench_10000)$expr, # n = 10000), # data.frame(time = summary(bench_1e5)$median, # Solution = summary(bench_1e5)$expr, # n = 1e5), # data.frame(time = summary(bench_1e6)$median, # Solution = summary(bench_1e6)$expr, # n = 1e6), # data.frame(time = summary(bench_1e7)$median, # Solution = summary(bench_1e7)$expr, # n = 1e7) # ) # results$Solution <- as.character(results$Solution) # results$Solution[grep(pattern = "cutpointr", x = results$Solution)] <- "cutpointr" # results$Solution[grep(pattern = "rocr", x = results$Solution)] <- "ROCR" # results$Solution[grep(pattern = "optimal", x = results$Solution)] <- "OptimalCutpoints" # results$Solution[grep(pattern = "proc", x = results$Solution)] <- "pROC" # results$Solution[grep(pattern = "thres", x = results$Solution)] <- "ThresholdROC" # # results$task <- "Cutpoint Estimation" ## ---- echo = FALSE------------------------------------------------------------ # These are the original results on our system # dput(results) results <- structure(list(time = c(4.5018015, 1.812802, 0.662101, 2.2887015, 1.194301, 4.839401, 2.1764015, 0.981001, 45.0568005, 36.2398515, 8.5662515, 5.667101, 2538.612001, 4.031701, 2503.8012505, 45.384501, 43.118751, 37.150151, 465.003201, 607.023851, 583.0950005, 5467.332801, 7850.2587, 7339.356101), Solution = c("cutpointr", "ROCR", "pROC", "OptimalCutpoints", "ThresholdROC", "cutpointr", "ROCR", "pROC", "OptimalCutpoints", "ThresholdROC", "cutpointr", "ROCR", "OptimalCutpoints", "pROC", "ThresholdROC", "cutpointr", "ROCR", "pROC", "cutpointr", "ROCR", "pROC", "cutpointr", "ROCR", "pROC"), n = c(100, 100, 100, 100, 100, 1000, 1000, 1000, 1000, 1000, 10000, 10000, 10000, 10000, 10000, 1e+05, 1e+05, 1e+05, 1e+06, 1e+06, 1e+06, 1e+07, 1e+07, 1e+07), task = c("Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation")), row.names = c(NA, -24L), class = "data.frame") ## ---- eval = FALSE------------------------------------------------------------ # # ROCR package # rocr_roc <- function(x, class) { # pred <- ROCR::prediction(x, class) # perf <- ROCR::performance(pred, "sens", "spec") # return(NULL) # } # # # pROC package # proc_roc <- function(x, class) { # r <- pROC::roc(class, x, algorithm = 2, levels = c(0, 1), direction = "<") # return(NULL) # } ## ---- eval = FALSE, echo = FALSE---------------------------------------------- # n <- 100 # set.seed(123) # dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) # bench_100 <- microbenchmark::microbenchmark( # cutpointr::roc(dat, "x", "y", pos_class = 1, # neg_class = 0, direction = ">="), # rocr_roc(dat$x, dat$y), # proc_roc(dat$x, dat$y), # times = 100, unit = "ms" # ) # n <- 1000 # set.seed(123) # dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) # bench_1000 <- microbenchmark::microbenchmark( # cutpointr::roc(dat, "x", "y", pos_class = 1, neg_class = 0, # direction = ">="), # rocr_roc(dat$x, dat$y), # proc_roc(dat$x, dat$y), # times = 100, unit = "ms" # ) # n <- 10000 # set.seed(123) # dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) # bench_10000 <- microbenchmark::microbenchmark( # cutpointr::roc(dat, "x", "y", pos_class = 1, neg_class = 0, # direction = ">="), # rocr_roc(dat$x, dat$y), # proc_roc(dat$x, dat$y), # times = 100, unit = "ms" # ) # n <- 1e5 # set.seed(123) # dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) # bench_1e5 <- microbenchmark::microbenchmark( # cutpointr::roc(dat, "x", "y", pos_class = 1, neg_class = 0, # direction = ">="), # rocr_roc(dat$x, dat$y), # proc_roc(dat$x, dat$y), # times = 100, unit = "ms" # ) # n <- 1e6 # set.seed(123) # dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) # bench_1e6 <- microbenchmark::microbenchmark( # cutpointr::roc(dat, "x", "y", pos_class = 1, neg_class = 0, # direction = ">="), # rocr_roc(dat$x, dat$y), # proc_roc(dat$x, dat$y), # times = 30, unit = "ms" # ) # n <- 1e7 # set.seed(123) # dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) # bench_1e7 <- microbenchmark::microbenchmark( # cutpointr::roc(dat, "x", "y", pos_class = 1, neg_class = 0, # direction = ">="), # rocr_roc(dat$x, dat$y), # proc_roc(dat$x, dat$y), # times = 30, unit = "ms" # ) # # results_roc <- rbind( # data.frame(time = summary(bench_100)$median, # Solution = summary(bench_100)$expr, # n = 100), # data.frame(time = summary(bench_1000)$median, # Solution = summary(bench_1000)$expr, # n = 1000), # data.frame(time = summary(bench_10000)$median, # Solution = summary(bench_10000)$expr, # n = 10000), # data.frame(time = summary(bench_1e5)$median, # Solution = summary(bench_1e5)$expr, # n = 1e5), # data.frame(time = summary(bench_1e6)$median, # Solution = summary(bench_1e6)$expr, # n = 1e6), # data.frame(time = summary(bench_1e7)$median, # Solution = summary(bench_1e7)$expr, # n = 1e7) # ) # results_roc$Solution <- as.character(results_roc$Solution) # results_roc$Solution[grep(pattern = "cutpointr", x = results_roc$Solution)] <- "cutpointr" # results_roc$Solution[grep(pattern = "rocr", x = results_roc$Solution)] <- "ROCR" # results_roc$Solution[grep(pattern = "proc", x = results_roc$Solution)] <- "pROC" # results_roc$task <- "ROC curve calculation" ## ---- echo = FALSE------------------------------------------------------------ # Our results results_roc <- structure(list(time = c(0.7973505, 1.732651, 0.447701, 0.859301, 2.0358515, 0.694802, 1.878151, 5.662151, 3.6580505, 11.099251, 42.8208515, 35.3293005, 159.8100505, 612.471901, 610.4337005, 2032.693551, 7806.3854515, 7081.897251), Solution = c("cutpointr", "ROCR", "pROC", "cutpointr", "ROCR", "pROC", "cutpointr", "ROCR", "pROC", "cutpointr", "ROCR", "pROC", "cutpointr", "ROCR", "pROC", "cutpointr", "ROCR", "pROC"), n = c(100, 100, 100, 1000, 1000, 1000, 10000, 10000, 10000, 1e+05, 1e+05, 1e+05, 1e+06, 1e+06, 1e+06, 1e+07, 1e+07, 1e+07), task = c("ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation")), row.names = c(NA, -18L), class = "data.frame") ## ---- echo = FALSE------------------------------------------------------------ results_all <- dplyr::bind_rows(results, results_roc) ggplot(results_all, aes(x = n, y = time, col = Solution, shape = Solution)) + geom_point(size = 3) + geom_line() + scale_y_log10(breaks = c(0.5, 1, 2, 3, 5, 10, 25, 100, 250, 1000, 5000, 1e4, 15000)) + scale_x_log10(breaks = c(100, 1000, 1e4, 1e5, 1e6, 1e7)) + ylab("Median Time (milliseconds, log scale)") + xlab("Sample Size (log scale)") + theme_bw() + theme(legend.position = "bottom", legend.key.width = unit(0.8, "cm"), panel.spacing = unit(1, "lines")) + facet_grid(~task) ## ---- echo = FALSE------------------------------------------------------------ res_table <- tidyr::spread(results_all, Solution, time) %>% arrange(task) knitr::kable(res_table) cutpointr/inst/doc/cutpointr.Rmd0000644000176200001440000017015713672457605016550 0ustar liggesusers--- title: "An introduction to cutpointr" author: "Christian Thiele" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{cutpointr} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set(fig.width = 6, fig.height = 5, fig.align = "center") options(rmarkdown.html_vignette.check_title = FALSE) load("vignettedata/vignettedata.Rdata") ``` **cutpointr** is an R package for tidy calculation of "optimal" cutpoints. It supports several methods for calculating cutpoints and includes several metrics that can be maximized or minimized by selecting a cutpoint. Some of these methods are designed to be more robust than the simple empirical optimization of a metric. Additionally, **cutpointr** can automatically bootstrap the variability of the optimal cutpoints and return out-of-bag estimates of various performance metrics. ## Installation You can install **cutpointr** from CRAN using the menu in RStudio or simply: ```{r CRAN, eval = FALSE} install.packages("cutpointr") ``` ## Example For example, the optimal cutpoint for the included data set is 2 when maximizing the sum of sensitivity and specificity. ```{r} library(cutpointr) data(suicide) head(suicide) cp <- cutpointr(suicide, dsi, suicide, method = maximize_metric, metric = sum_sens_spec) ``` ```{r} summary(cp) ``` ```{r} plot(cp) ``` When considering the optimality of a cutpoint, we can only make a judgement based on the sample at hand. Thus, the estimated cutpoint may not be optimal within the population or on unseen data, which is why we sometimes put the "optimal" in quotation marks. `cutpointr` makes assumptions about the direction of the dependency between `class` and `x`, if `direction` and / or `pos_class` or `neg_class` are not specified. The same result as above can be achieved by manually defining `direction` and the positive / negative classes which is slightly faster, since the classes and direction don't have to be determined: ```{r} opt_cut <- cutpointr(suicide, dsi, suicide, direction = ">=", pos_class = "yes", neg_class = "no", method = maximize_metric, metric = youden) ``` `opt_cut` is a data frame that returns the input data and the ROC curve (and optionally the bootstrap results) in a nested tibble. Methods for summarizing and plotting the data and results are included (e.g. `summary`, `plot`, `plot_roc`, `plot_metric`) To inspect the optimization, the function of metric values per cutpoint can be plotted using `plot_metric`, if an optimization function was used that returns a metric column in the `roc_curve` column. For example, the `maximize_metric` and `minimize_metric` functions do so: ```{r} plot_metric(opt_cut) ``` Predictions for new data can be made using `predict`: ```{r} predict(opt_cut, newdata = data.frame(dsi = 0:5)) ``` ## Features - Calculation of optimal cutpoints in binary classification tasks - Tidy output, integrates well with functions from the tidyverse - Functions for plotting ROC curves, metric distributions and more - Bootstrapping for simulating the cutpoint variability and for obtaining out-of-bag estimates of various metrics (as a form of internal validation) with optional parallelisation - Multiple methods for calculating cutpoints - Multiple metrics can be chosen for maximization / minimization - Tidyeval # Calculating cutpoints ## Method functions for cutpoint estimation The included methods for calculating cutpoints are: - `maximize_metric`: Maximize the metric function - `minimize_metric`: Minimize the metric function - `maximize_loess_metric`: Maximize the metric function after LOESS smoothing - `minimize_loess_metric`: Minimize the metric function after LOESS smoothing - `maximize_spline_metric`: Maximize the metric function after spline smoothing - `minimize_spline_metric`: Minimize the metric function after spline smoothing - `maximize_gam_metric`: Maximize the metric function after smoothing via Generalized Additive Models - `minimize_gam_metric`: Minimize the metric function after smoothing via Generalized Additive Models - `maximize_boot_metric`: Bootstrap the optimal cutpoint when maximizing a metric - `minimize_boot_metric`: Bootstrap the optimal cutpoint when minimizing a metric - `oc_manual`: Specify the cutoff value manually - `oc_mean`: Use the sample mean as the "optimal" cutpoint - `oc_median`: Use the sample median as the "optimal" cutpoint - `oc_youden_kernel`: Maximize the Youden-Index after kernel smoothing the distributions of the two classes - `oc_youden_normal`: Maximize the Youden-Index parametrically assuming normally distributed data in both classes ## Metric functions The included metrics to be used with the minimization and maximization methods are: - `accuracy`: Fraction correctly classified - `abs_d_sens_spec`: The absolute difference of sensitivity and specificity - `abs_d_ppv_npv`: The absolute difference between positive predictive value (PPV) and negative predictive value (NPV) - `roc01`: Distance to the point (0,1) on ROC space - `cohens_kappa`: Cohen's Kappa - `sum_sens_spec`: sensitivity + specificity - `sum_ppv_npv`: The sum of positive predictive value (PPV) and negative predictive value (NPV) - `prod_sens_spec`: sensitivity * specificity - `prod_ppv_npv`: The product of positive predictive value (PPV) and negative predictive value (NPV) - `youden`: Youden- or J-Index = sensitivity + specificity - 1 - `odds_ratio`: (Diagnostic) odds ratio - `risk_ratio`: risk ratio (relative risk) - `p_chisquared`: The p-value of a chi-squared test on the confusion matrix - `cost_misclassification`: The sum of the misclassification cost of false positives and false negatives. Additional arguments: cost_fp, cost_fn - `total_utility`: The total utility of true / false positives / negatives. Additional arguments: utility_tp, utility_tn, cost_fp, cost_fn - `F1_score`: The F1-score (2 * TP) / (2 * TP + FP + FN) - `metric_constrain`: Maximize a selected metric given a minimal value of another selected metric - `sens_constrain`: Maximize sensitivity given a minimal value of specificity - `spec_constrain`: Maximize specificity given a minimal value of sensitivity - `acc_constrain`: Maximize accuracy given a minimal value of sensitivity Furthermore, the following functions are included which can be used as metric functions but are more useful for plotting purposes, for example in `plot_cutpointr`, or for defining new metric functions: `tp`, `fp`, `tn`, `fn`, `tpr`, `fpr`, `tnr`, `fnr`, `false_omission_rate`, `false_discovery_rate`, `ppv`, `npv`, `precision`, `recall`, `sensitivity`, and `specificity`. The inputs to the arguments `method` and `metric` are functions so that user-defined functions can easily be supplied instead of the built-in ones. ## Separate subgroups and bootstrapping Cutpoints can be separately estimated on subgroups that are defined by a third variable, `gender` in this case. Additionally, if `boot_runs` is larger zero, `cutpointr` will carry out the usual cutpoint calculation on the full sample, just as before, and additionally on `boot_runs` bootstrap samples. This offers a way of gauging the out-of-sample performance of the cutpoint estimation method. If a subgroup is given, the bootstrapping is carried out separately for every subgroup which is also reflected in the plots and output. ```{r separate subgroups and bootstrapping, eval = FALSE} set.seed(12) opt_cut_b <- cutpointr(suicide, dsi, suicide, boot_runs = 1000) ``` ```{r} opt_cut_b ``` The returned object has the additional column `boot` which is a nested tibble that includes the cutpoints per bootstrap sample along with the metric calculated using the function in `metric` and various default metrics. The metrics are suffixed by `_b` to indicate in-bag results or `_oob` to indicate out-of-bag results: ```{r} opt_cut$boot ``` The summary and plots include additional elements that summarize or display the bootstrap results: ```{r} summary(opt_cut) plot(opt_cut) ``` ### Parallelized bootstrapping Using `foreach` and `doRNG` the bootstrapping can be parallelized easily. The **doRNG** package is being used to make the bootstrap sampling reproducible. ```{r, eval = FALSE} library(doParallel) cl <- makeCluster(2) # 2 cores registerDoParallel(cl) registerDoRNG(12) # Reproducible parallel loops using doRNG opt_cut <- cutpointr(suicide, dsi, suicide, gender, pos_class = "yes", direction = ">=", boot_runs = 1000, allowParallel = TRUE) stopCluster(cl) opt_cut ``` # More robust cutpoint estimation methods ## Bootstrapped cutpoints It has been shown that bagging can substantially improve performance of a wide range of types of models in regression as well as in classification tasks. This method is available for cutpoint estimation via the `maximize_boot_metric` and `minimize_boot_metric` functions. If one of these functions is used as `method`, `boot_cut` bootstrap samples are drawn, the cutpoint optimization is carried out in each one and a summary (e.g. the mean) of the resulting optimal cutpoints on the bootstrap samples is returned as the optimal cutpoint in `cutpointr`. Note that if bootstrap validation is run, i.e. if `boot_runs` is larger zero, an outer bootstrap will be executed. In the bootstrap validation routine `boot_runs` bootstrap samples are generated and each one is again bootstrapped `boot_cut` times. This may lead to long run times, so activating the built-in parallelization may be advisable. The advantages of bootstrapping the optimal cutpoint are that the procedure doesn't possess parameters that have to be tuned, unlike the LOESS smoothing, that it doesn't rely on assumptions, unlike the Normal method, and that it is applicable to any metric that can be used with `minimize_metric` or `maximize_metric`, unlike the Kernel method. Furthermore, like Random Forests cannot be overfit by increasing the number of trees, the bootstrapped cutpoints cannot be overfit by running an excessive amount of `boot_cut` repetitions. ```{r, cache=TRUE} set.seed(100) cutpointr(suicide, dsi, suicide, gender, method = maximize_boot_metric, boot_cut = 200, summary_func = mean, metric = accuracy, silent = TRUE) ``` ## LOESS smoothing for selecting a cutpoint When using `maximize_metric` and `minimize_metric` the optimal cutpoint is selected by searching the maximum or minimum of the metric function. For example, we may want to minimize the misclassification cost. Since false negatives (a suicide attempt was not anticipated) can be regarded as much more severe than false positives we can set the cost of a false negative `cost_fn` for example to ten times the cost of a false positive. ```{r} opt_cut <- cutpointr(suicide, dsi, suicide, gender, method = minimize_metric, metric = misclassification_cost, cost_fp = 1, cost_fn = 10) ``` ```{r} plot_metric(opt_cut) ``` As this "optimal" cutpoint may depend on minor differences between the possible cutoffs, smoothing of the function of metric values by cutpoint value might be desirable, especially in small samples. The `minimize_loess_metric` and `maximize_loess_metric` functions can be used to smooth the function so that the optimal cutpoint is selected based on the smoothed metric values. Options to modify the smoothing, which is implemented using `loess.as` from the **fANCOVA** package, include: - `criterion`: the criterion for automatic smoothing parameter selection: "aicc" denotes bias-corrected AIC criterion, "gcv" denotes generalized cross-validation. - `degree`: the degree of the local polynomials to be used. It can be 0, 1 or 2. - `family`: if "gaussian" fitting is by least-squares, and if "symmetric" a re-descending M estimator is used with Tukey's biweight function. - `user.span`: the user-defined parameter which controls the degree of smoothing. Using parameters for the LOESS smoothing of `criterion = "aicc"`, `degree = 2`, `family = "symmetric"`, and `user.span = 0.7` we get the following smoothed versions of the above metrics: ```{r, message = FALSE} opt_cut <- cutpointr(suicide, dsi, suicide, gender, method = minimize_loess_metric, criterion = "aicc", family = "symmetric", degree = 2, user.span = 0.7, metric = misclassification_cost, cost_fp = 1, cost_fn = 10) ``` ```{r} plot_metric(opt_cut) ``` The optimal cutpoint for the female subgroup changes to 3. Note, though, that there are no reliable rules for selecting the "best" smoothing parameters. Notably, the LOESS smoothing is sensitive to the number of unique cutpoints. A large number of unique cutpoints generally leads to a more volatile curve of metric values by cutpoint value, even after smoothing. Thus, the curve tends to be undersmoothed in that scenario. The unsmoothed metric values are returned in `opt_cut$roc_curve` in the column `m_unsmoothed`. ## Smoothing via Generalized Additive Models for selecting a cutpoint In a similar fashion, the function of metric values per cutpoint can be smoothed using Generalized Additive Models with smooth terms. Internally, `mgcv::gam` carries out the smoothing which can be customized via the arguments `formula` and `optimizer`, see `help("gam", package = "mgcv")`. Most importantly, the GAM can be specified by altering the default formula, for example the smoothing function could be configured to apply cubic regression splines (`"cr"`) as the smooth term. As the `suicide` data has only very few unique cutpoints, it is not very suitable for showcasing the GAM smoothing, so we will use two classes of the `iris` data here. In this case, the purely empirical method and the GAM smoothing lead to identical cutpoints, but in practice the GAM smoothing tends to be more robust, especially with larger data. An attractive feature of the GAM smoothing is that the default values tend to work quite well and usually require no tuning, eliminating researcher degrees of freedom. ```{r} library(ggplot2) exdat <- iris exdat <- exdat[exdat$Species != "setosa", ] opt_cut <- cutpointr(exdat, Petal.Length, Species, method = minimize_gam_metric, formula = m ~ s(x.sorted, bs = "cr"), metric = abs_d_sens_spec) plot_metric(opt_cut) ``` ## Spline smoothing for selecting a cutpoint Again in the same fashion the function of metric values per cutpoint can be smoothed using smoothing splines. By default, the number of knots is automatically chosen using the `cutpoint_knots` function. That function uses `stats::.nknots.smspl`, which is the default in `stats::smooth.spline` to pick the number of knots. Alternatively, the number of knots can be set manually and also the other smoothing parameters of `stats::smooth.spline` can be set as desired. For details see `?maximize_spline_metric`. ```{r} opt_cut <- cutpointr(suicide, dsi, suicide, gender, method = minimize_spline_metric, spar = 0.4, metric = misclassification_cost, cost_fp = 1, cost_fn = 10) plot_metric(opt_cut) ``` ### Parametric method assuming normality The Normal method in `oc_youden_normal` is a parametric method for maximizing the Youden-Index or equivalently the sum of $Se$ and $Sp$. It relies on the assumption that the predictor for both the negative and positive observations is normally distributed. In that case it can be shown that $$c^* = \frac{(\mu_P \sigma_N^2 - \mu_N \sigma_P^2) - \sigma_N \sigma_P \sqrt{(\mu_N - \mu_P)^2 + (\sigma_N^2 - \sigma_P^2) log(\sigma_N^2 / \sigma_P^2)}}{\sigma_N^2 - \sigma_P^2}$$ where the negative class is normally distributed with $\sim N(\mu_N, \sigma_N^2)$ and the positive class independently normally distributed with $\sim N(\mu_P, \sigma_P^2)$ provides the optimal cutpoint $c^*$ that maximizes the Youden-Index. If $\sigma_N$ and $\sigma_P$ are equal, the expression can be simplified to $c^* = \frac{\mu_N + \mu_P}{2}$. However, the `oc_youden_normal` method in cutpointr always assumes unequal standard deviations. Since this method does not select a cutpoint from the observed predictor values, it is questionable which values for $Se$ and $Sp$ should be reported. Here, the Youden-Index can be calculated as $$J = \Phi(\frac{c^* - \mu_N}{\sigma_N}) - \Phi(\frac{c^* - \mu_P}{\sigma_P})$$ if the assumption of normality holds. However, since there exist several methods that do not select cutpoints from the available observations and to unify the reporting of metrics for these methods, **cutpointr** reports all metrics, e.g. $Se$ and $Sp$, based on the empirical observations. ```{r} cutpointr(suicide, dsi, suicide, gender, method = oc_youden_normal) ``` ### Nonparametric kernel method A nonparametric alternative is the Kernel method [@fluss_estimation_2005]. Here, the empirical distribution functions are smoothed using the Gaussian kernel functions $\hat{F}_N(t) = \frac{1}{n} \sum^n_{i=1} \Phi(\frac{t - y_i}{h_y})$ and $\hat{G}_P(t) = \frac{1}{m} \sum^m_{i=1} \Phi(\frac{t - x_i}{h_x})$ for the negative and positive classes respectively. Following Silverman's plug-in "rule of thumb" the bandwidths are selected as $h_y = 0.9 * min\{s_y, iqr_y/1.34\} * n^{-0.2}$ and $h_x = 0.9 * min\{s_x, iqr_x/1.34\} * m^{-0.2}$ where $s$ is the sample standard deviation and $iqr$ is the inter quartile range. It has been demonstrated that AUC estimation is rather insensitive to the choice of the bandwidth procedure [@faraggi_estimation_2002] and thus the plug-in bandwidth estimator has also been recommended for cutpoint estimation. The `oc_youden_kernel` function in **cutpointr** uses a Gaussian kernel and the direct plug-in method for selecting the bandwidths. The kernel smoothing is done via the `bkde` function from the **KernSmooth** package [@wand_kernsmooth:_2013]. Again, there is a way to calculate the Youden-Index from the results of this method [@fluss_estimation_2005] which is $$\hat{J} = max_c \{\hat{F}_N(c) - \hat{G}_N(c) \}$$ but as before we prefer to report all metrics based on applying the cutpoint that was estimated using the Kernel method to the empirical observations. ```{r} cutpointr(suicide, dsi, suicide, gender, method = oc_youden_kernel) ``` # Additional features ## Calculating only the ROC curve When running `cutpointr`, a ROC curve is by default returned in the column `roc_curve`. This ROC curve can be plotted using `plot_roc`. Alternatively, if only the ROC curve is desired and no cutpoint needs to be calculated, the ROC curve can be created using `roc()` and plotted using `plot_cutpointr`. The `roc` function, unlike `cutpointr`, does not determine `direction`, `pos_class` or `neg_class` automatically. ```{r, fig.width=4, fig.height=3} roc_curve <- roc(data = suicide, x = dsi, class = suicide, pos_class = "yes", neg_class = "no", direction = ">=") auc(roc_curve) head(roc_curve) plot_roc(roc_curve) ``` ## Midpoints So far - which is the default in `cutpointr` - we have considered all unique values of the predictor as possible cutpoints. An alternative could be to use a sequence of equidistant values instead, for example in the case of the `suicide` data all integers in $[0, 10]$. However, with very sparse data and small intervals between the candidate cutpoints (i.e. a 'dense' sequence like `seq(0, 10, by = 0.01)`) this leads to the uninformative evaluation of large ranges of cutpoints that all result in the same metric value. A more elegant alternative, not only for the case of sparse data, that is supported by **cutpointr** is the use of a mean value of the optimal cutpoint and the next highest (if `direction = ">="`) or the next lowest (if `direction = "<="`) predictor value in the data. The result is an optimal cutpoint that is equal to the cutpoint that would be obtained using an infinitely dense sequence of candidate cutpoints and is thus usually more efficient computationally. This behavior can be activated by setting `use_midpoints = TRUE`, which is the default. If we use this setting, we obtain an optimal cutpoint of 1.5 for the complete sample on the `suicide` data instead of 2 when maximizing the sum of sensitivity and specificity. Assume the following small data set: ```{r} dat <- data.frame(outcome = c("neg", "neg", "neg", "pos", "pos", "pos", "pos"), pred = c(1, 2, 3, 8, 11, 11, 12)) ``` Since the distance of the optimal cutpoint (8) to the next lowest observation (3) is rather large we arrive at a range of possible cutpoints that all maximize the metric. In the case of this kind of sparseness it might for example be desirable to classify a new observation with a predictor value of 4 as belonging to the negative class. If `use_midpoints` is set to `TRUE`, the mean of the optimal cutpoint and the next lowest observation is returned as the optimal cutpoint, if direction is `>=`. The mean of the optimal cutpoint and the next highest observation is returned as the optimal cutpoint, if `direction = "<="`. ```{r} opt_cut <- cutpointr(dat, x = pred, class = outcome, use_midpoints = TRUE) plot_x(opt_cut) ``` A simulation demonstrates more clearly that setting `use_midpoints = TRUE` avoids biasing the cutpoints. To simulate the bias of the metric functions, the predictor values of both classes were drawn from normal distributions with constant standard deviations of 10, a constant mean of the negative class of 100 and higher mean values of the positive class that are selected in such a way that optimal Youden-Index values of 0.2, 0.4, 0.6, and 0.8 result in the population. Samples of 9 different sizes were drawn and the cutpoints that maximize the Youden-Index were estimated. The simulation was repeated 10000 times. As can be seen by the mean error, `use_midpoints = TRUE` eliminates the bias that is introduced by otherwise selecting the value of an observation as the optimal cutpoint. If `direction = ">="`, as in this case, the observation that represents the optimal cutpoint is the highest possible cutpoint that leads to the optimal metric value and thus the biases are positive. The methods `oc_youden_normal` and `oc_youden_kernel` are always unbiased, as they don't select a cutpoint based on the ROC-curve or the function of metric values per cutpoint. ```{r, echo = FALSE} plotdat_nomidpoints <- structure(list(sim_nr = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 16L, 16L, 16L, 16L, 16L, 16L, 16L, 16L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 18L, 18L, 18L, 18L, 18L, 18L, 18L, 18L, 19L, 19L, 19L, 19L, 19L, 19L, 19L, 19L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 22L, 22L, 22L, 22L, 22L, 22L, 22L, 22L, 23L, 23L, 23L, 23L, 23L, 23L, 23L, 23L, 24L, 24L, 24L, 24L, 24L, 24L, 24L, 24L, 25L, 25L, 25L, 25L, 25L, 25L, 25L, 25L, 26L, 26L, 26L, 26L, 26L, 26L, 26L, 26L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 28L, 28L, 28L, 28L, 28L, 28L, 28L, 28L, 29L, 29L, 29L, 29L, 29L, 29L, 29L, 29L, 30L, 30L, 30L, 30L, 30L, 30L, 30L, 30L, 31L, 31L, 31L, 31L, 31L, 31L, 31L, 31L, 32L, 32L, 32L, 32L, 32L, 32L, 32L, 32L, 33L, 33L, 33L, 33L, 33L, 33L, 33L, 33L, 34L, 34L, 34L, 34L, 34L, 34L, 34L, 34L, 35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L, 36L, 36L, 36L, 36L, 36L, 36L, 36L, 36L), method = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L), .Label = c("emp", "normal", "loess", "boot", "spline", "spline_20", "kernel", "gam" ), class = "factor"), n = c(30, 30, 30, 30, 30, 30, 30, 30, 50, 50, 50, 50, 50, 50, 50, 50, 75, 75, 75, 75, 75, 75, 75, 75, 100, 100, 100, 100, 100, 100, 100, 100, 150, 150, 150, 150, 150, 150, 150, 150, 250, 250, 250, 250, 250, 250, 250, 250, 500, 500, 500, 500, 500, 500, 500, 500, 750, 750, 750, 750, 750, 750, 750, 750, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 30, 30, 30, 30, 30, 30, 30, 30, 50, 50, 50, 50, 50, 50, 50, 50, 75, 75, 75, 75, 75, 75, 75, 75, 100, 100, 100, 100, 100, 100, 100, 100, 150, 150, 150, 150, 150, 150, 150, 150, 250, 250, 250, 250, 250, 250, 250, 250, 500, 500, 500, 500, 500, 500, 500, 500, 750, 750, 750, 750, 750, 750, 750, 750, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 30, 30, 30, 30, 30, 30, 30, 30, 50, 50, 50, 50, 50, 50, 50, 50, 75, 75, 75, 75, 75, 75, 75, 75, 100, 100, 100, 100, 100, 100, 100, 100, 150, 150, 150, 150, 150, 150, 150, 150, 250, 250, 250, 250, 250, 250, 250, 250, 500, 500, 500, 500, 500, 500, 500, 500, 750, 750, 750, 750, 750, 750, 750, 750, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 30, 30, 30, 30, 30, 30, 30, 30, 50, 50, 50, 50, 50, 50, 50, 50, 75, 75, 75, 75, 75, 75, 75, 75, 100, 100, 100, 100, 100, 100, 100, 100, 150, 150, 150, 150, 150, 150, 150, 150, 250, 250, 250, 250, 250, 250, 250, 250, 500, 500, 500, 500, 500, 500, 500, 500, 750, 750, 750, 750, 750, 750, 750, 750, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000), mean_err = c(0.532157164015659, 0.0344907054484091, 1.09430750651166, 0.847845162156675, 1.72337372126503, 0.893756658507988, 0.0430309247027736, 0.785821459035346, 0.368063404388512, 0.0256197760404459, 0.54480529648463, 0.54385597929651, 0.657325657699579, 0.578611116865437, 0.0400491342691897, 0.515688005217413, 0.256713912589642, 0.0444582875885996, 0.326975493112402, 0.371128780921122, 0.473515115741104, 0.389519558405289, 0.105044360789378, 0.301924717299333, 0.207750921776918, -0.00318128936770314, 0.215170156089776, 0.27218780048926, 0.260519564021842, 0.236792923882582, 0.0209319074923902, 0.232957055204834, 0.0726605917614469, -0.00282823355849125, 0.0753216783313991, 0.147121931849656, 0.0986417724955371, 0.10048009778446, -0.0117861260923649, 0.0650845904350442, 0.0985144485083747, 0.00601003227249322, 0.107439979908118, 0.120777421732797, 0.098470489820427, 0.0940946984227826, 0.0340166854141625, 0.107851118082414, 0.0249685210781582, -0.00275219600614378, 0.0258069390207201, 0.0303381972274654, -0.000994602151869198, 0.00196854833683764, -0.0172319489562159, 0.0230957871932473, 0.00787486424680835, -0.018438041997315, -0.000808033567394628, -0.00151904153864496, -0.0258118523805697, -0.020984156892953, -0.0411584927473141, -0.0462075435919094, 0.0481149217843661, -0.0115241085997692, 0.0278045708419731, 0.0358588316426625, 0.0424473909450939, 0.0379773233328197, 0.0298772985879321, 0.0494939492036379, 0.561286668337778, 0.0210874502384648, 0.607711822769155, 0.944733906256477, 1.32069801051061, 0.623604782428556, 0.0138075109769806, 0.640859854412358, 0.284873604303057, -0.0170357985365701, 0.273426417633118, 0.524432737895336, 0.355003110979807, 0.312837607951434, -0.0316296929553873, 0.270109834098986, 0.174110335581819, 0.0253101719615279, 0.199956222742702, 0.375485416120771, 0.278956745944806, 0.244245525945888, 0.0325126314233263, 0.253352659868514, 0.154840760004461, 0.00231589709639472, 0.154412480165179, 0.264847742842386, 0.196572744185608, 0.182934783774992, 0.0207139021497755, 0.17351041376412, 0.14190910348156, -0.000766834484010096, 0.159975205214477, 0.191222128926019, 0.119768252112669, 0.12033372914036, -0.00429047209392067, 0.120982527821078, 0.0756304869484406, -0.00890884219048113, 0.0727782693168392, 0.118690444738942, 0.0814898789647033, 0.0799724348001957, 0.0182926240912726, 0.0887155007804252, 0.00799604720502299, 0.000599148388616836, -0.00567769035990384, 0.0358412514670032, 0.0308474979074875, 0.0341668723768997, -0.000180318451026095, 0.0180733341290925, 0.00456876236626807, 0.00150574966485876, 0.011152095953916, 0.0176039119729626, 0.00608274255434991, 0.0146257828313115, -0.0108877417404102, 0.00341198000323035, -0.00198459880370283, 0.0026551895445694, 0.00199040664534129, 0.0150165794544221, 0.00646287144368147, 0.00999205240904708, -0.00850278571195971, 0.000833666619266177, 0.714730067273087, -0.00916546079360956, 0.662799490366986, 1.18552468844156, 1.25901933062308, 0.672701515532179, 0.0311066140197676, 0.699068058809396, 0.451908043813962, 0.0131716226592205, 0.429551369887738, 0.697928133235757, 0.445367768988423, 0.408463448982185, 0.0318707241721211, 0.406284953982951, 0.257736307754364, -0.00525924423719458, 0.236977000055322, 0.429144726596141, 0.291381752107184, 0.267557606428613, 0.0103657879176852, 0.254728590646094, 0.187783398487578, -0.00216064381479362, 0.209025103860707, 0.318293592390017, 0.216751610346408, 0.195630579126633, -0.00355723971644246, 0.174111826408428, 0.151010324964235, 0.0152409223899092, 0.159002511320467, 0.214643583389694, 0.136211731513269, 0.138948149207635, 0.00736196817594524, 0.115637867729083, 0.0491348055596302, -0.00133957946235943, 0.0507437758212659, 0.103956325245849, 0.0641182216839426, 0.0721933081297794, -0.0124376134651938, 0.0632317888879588, 0.0322195712438111, 0.00170122889182022, 0.0287526766624194, 0.0589662164030242, 0.0348535721709848, 0.039527944642463, -0.00617539706415593, 0.0274246010641889, 0.0325877909680824, 0.00530528253248245, 0.0221776555499961, 0.0389702052631117, 0.0221602091288215, 0.0254478639695596, -0.0016189234058987, 0.0197144417326668, -0.00632485262604172, -0.00364979854195596, -0.00276076468388984, 0.0126267527301874, 0.0123592498266038, 0.0154921632247644, -0.00591512196680815, 0.0098685016547149, 1.19276916750486, -0.0296831640401583, 0.99406393593888, 1.95758669445116, 1.45842790978446, 0.916899913902239, -0.0240222410217233, 1.00771193034927, 0.748151091428865, 0.001671855025917, 0.665180535306263, 1.1777049634557, 0.578603609273264, 0.546625362141714, 0.0292152981607387, 0.615230814912951, 0.417886753756131, 0.00324593885807739, 0.406076310942717, 0.732191741449251, 0.352684769616612, 0.326901376027897, -0.000759357576337989, 0.350075431324921, 0.310927617707656, -0.0107255472998434, 0.28102101085112, 0.514683023356017, 0.24913510139508, 0.235155452507568, -0.0220885572014814, 0.243370611433649, 0.209652330609093, -0.00502865663759991, 0.2172246261346, 0.356540958804122, 0.172121720418057, 0.17487914828986, 0.00365942442127361, 0.176594681455494, 0.126956927057327, -0.00270525933073803, 0.120116234221594, 0.210827536708082, 0.101520409193932, 0.101379097920023, 0.00238043252144371, 0.113027315928011, 0.0598624378953727, -0.00538838415690431, 0.0568400730102315, 0.0978115258288965, 0.0454207684906316, 0.0473140143579152, -0.00165813015281622, 0.0521772135812508, 0.0530224090961669, -0.000416993405198653, 0.0353236911458531, 0.0605493601241619, 0.0316204159297213, 0.0344789374555544, -0.00446984887315054, 0.0328807595695966, 0.0396438546423947, -0.00331466369719113, 0.0379029847219126, 0.0572435100638761, 0.0253269328104989, 0.0235663211070417, 0.00220241478536399, 0.0307132312422208), youden = c(0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8 )), row.names = c(NA, -288L), group_sizes = c(8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L ), biggest_group_size = 8L, class = c("grouped_df", "tbl_df", "tbl", "data.frame"), groups = structure(list(sim_nr = 1:36, .rows = list(1:8, 9:16, 17:24, 25:32, 33:40, 41:48, 49:56, 57:64, 65:72, 73:80, 81:88, 89:96, 97:104, 105:112, 113:120, 121:128, 129:136, 137:144, 145:152, 153:160, 161:168, 169:176, 177:184, 185:192, 193:200, 201:208, 209:216, 217:224, 225:232, 233:240, 241:248, 249:256, 257:264, 265:272, 273:280, 281:288)), row.names = c(NA, -36L), class = c("tbl_df", "tbl", "data.frame"), .drop = TRUE)) ``` ```{r, echo = FALSE} library(dplyr) ggplot(plotdat_nomidpoints %>% filter(!(method %in% c("spline_20"))), aes(x = n, y = mean_err, color = method, shape = method)) + geom_line() + geom_point() + facet_wrap(~ youden, scales = "fixed") + scale_shape_manual(values = 1:nlevels(plotdat_nomidpoints$method)) + scale_x_log10(breaks = c(30, 50, 75, 100, 150, 250, 500, 750, 1000)) + ggtitle("Bias of all methods when use_midpoints = FALSE", "normally distributed data, 10000 repetitions of simulation") ``` ## Finding all cutpoints with acceptable performance By default, most packages only return the "best" cutpoint and disregard other cutpoints with quite similar performance, even if the performance differences are minuscule. **cutpointr** makes this process more explicit via the `tol_metric` argument. For example, if all cutpoints are of interest that achieve at least an accuracy within `0.05` of the optimally achievable accuracy, `tol_metric` can be set to `0.05` and also those cutpoints will be returned. In the case of the `suicide` data and when maximizing the sum of sensitivity and specificity, empirically the cutpoints 2 and 3 lead to quite similar performances. If `tol_metric` is set to `0.05`, both will be returned. ```{r} opt_cut <- cutpointr(suicide, dsi, suicide, metric = sum_sens_spec, tol_metric = 0.05, break_ties = c) library(tidyr) opt_cut %>% select(optimal_cutpoint, sum_sens_spec) %>% unnest(cols = c(optimal_cutpoint, sum_sens_spec)) ``` ## Manual and mean / median cutpoints Using the `oc_manual` function the optimal cutpoint will not be determined based on, for example, a metric but is instead set manually using the `cutpoint` argument. This is useful for supplying and evaluating cutpoints that were found in the literature or in other external sources. The `oc_manual` function could also be used to set the cutpoint to the sample mean using `cutpoint = mean(data$x)`. However, this may introduce bias into the bootstrap validation procedure, since the actual mean of the population is not known and thus the mean to be used as the cutpoint should be automatically determined in every resample. To do so, the `oc_mean` and `oc_median` functions can be used. ```{r, eval = FALSE} set.seed(100) opt_cut_manual <- cutpointr(suicide, dsi, suicide, method = oc_manual, cutpoint = mean(suicide$dsi), boot_runs = 1000) set.seed(100) opt_cut_mean <- cutpointr(suicide, dsi, suicide, method = oc_mean, boot_runs = 1000) ``` ## Nonstandard evaluation via tidyeval The arguments to `cutpointr` do not need to be enclosed in quotes. This is possible thanks to nonstandard evaluation of the arguments, which are evaluated on `data`. Functions that use nonstandard evaluation are often not suitable for programming with. The use of nonstandard evaluation may lead to scoping problems and subsequent obvious as well as possibly subtle errors. **cutpointr** uses tidyeval internally and accordingly the same rules as for programming with `dplyr` apply. Arguments can be unquoted with `!!`: ```{r, eval = FALSE} myvar <- "dsi" cutpointr(suicide, !!myvar, suicide) ``` ## ROC curve and optimal cutpoint for multiple variables Alternatively, we can map the standard evaluation version `cutpointr` to the column names. If `direction` and / or `pos_class` and `neg_class` are unspecified, these parameters will automatically be determined by **cutpointr** so that the AUC values for all variables will be $> 0.5$. We could do this manually, e.g. using `purrr::map`, but to make this task more convenient `multi_cutpointr` can be used to achieve the same result. It maps multiple predictor columns to `cutpointr`, by default all numeric columns except for the class column. ```{r} mcp <- multi_cutpointr(suicide, class = suicide, pos_class = "yes", use_midpoints = TRUE, silent = TRUE) summary(mcp) ``` ## Accessing `data`, `roc_curve`, and `boot` The object returned by `cutpointr` is of the classes `cutpointr`, `tbl_df`, `tbl`, and `data.frame`. Thus, it can be handled like a usual data frame. The columns `data`, `roc_curve`, and `boot` consist of nested data frames, which means that these are list columns whose elements are data frames. They can either be accessed using `[` or by using functions from the tidyverse. If subgroups were given, the output contains one row per subgroup and the function that accesses the data should be mapped to every row or the data should be grouped by subgroup. ```{r, eval = FALSE, message = FALSE} set.seed(123) opt_cut_b_g <- cutpointr(suicide, dsi, suicide, gender, boot_runs = 1000) ``` ```{r, message = FALSE} # Using dplyr and tidyr library(tidyr) opt_cut_b_g %>% group_by(subgroup) %>% select(subgroup, boot) %>% unnest(cols = boot) %>% summarise(sd_oc_boot = sd(optimal_cutpoint), m_oc_boot = mean(optimal_cutpoint), m_acc_oob = mean(acc_oob)) ``` ## Adding metrics to the result of cutpointr() or roc() By default, the output of `cutpointr` includes the optimized metric and several other metrics. The `add_metric` function adds further metrics. Here, we're adding the negative predictive value (NPV) and the positive predictive value (PPV) at the optimal cutpoint per subgroup: ```{r} cutpointr(suicide, dsi, suicide, gender, metric = youden, silent = TRUE) %>% add_metric(list(ppv, npv)) %>% select(subgroup, optimal_cutpoint, youden, ppv, npv) ``` In the same fashion, additional metric columns can be added to a `roc_cutpointr` object: ```{r} roc(data = suicide, x = dsi, class = suicide, pos_class = "yes", neg_class = "no", direction = ">=") %>% add_metric(list(cohens_kappa, F1_score)) %>% select(x.sorted, tp, fp, tn, fn, cohens_kappa, F1_score) %>% head() ``` ## User-defined functions ### method User-defined functions can be supplied to `method`, which is the function that is responsible for returning the optimal cutpoint. To define a new method function, create a function that may take as input(s): - `data`: A `data.frame` or `tbl_df` - `x`: (character) The name of the predictor variable - `class`: (character) The name of the class variable - `metric_func`: A function for calculating a metric, e.g. accuracy. Note that the method function does not necessarily have to accept this argument - `pos_class`: The positive class - `neg_class`: The negative class - `direction`: `">="` if the positive class has higher x values, `"<="` otherwise - `tol_metric`: (numeric) In the built-in methods, all cutpoints will be returned that lead to a metric value in the interval [m_max - tol_metric, m_max + tol_metric] where m_max is the maximum achievable metric value. This can be used to return multiple decent cutpoints and to avoid floating-point problems. - `use_midpoints`: (logical) In the built-in methods, if TRUE (default FALSE) the returned optimal cutpoint will be the mean of the optimal cutpoint and the next highest observation (for direction = ">") or the next lowest observation (for direction = "<") which avoids biasing the optimal cutpoint. - `...`: Further arguments that are passed to `metric` or that can be captured inside of `method` The function should return a data frame or tibble with one row, the column `optimal_cutpoint`, and an optional column with an arbitrary name with the metric value at the optimal cutpoint. For example, a function for choosing the cutpoint as the mean of the independent variable could look like this: ```{r, eval = FALSE} mean_cut <- function(data, x, ...) { oc <- mean(data[[x]]) return(data.frame(optimal_cutpoint = oc)) } ``` If a `method` function does not return a metric column, the default `sum_sens_spec`, the sum of sensitivity and specificity, is returned as the extra metric column in addition to accuracy, sensitivity and specificity. Some `method` functions that make use of the additional arguments (that are captured by `...`) are already included in **cutpointr**, see the list at the top. Since these functions are arguments to `cutpointr` their code can be accessed by simply typing their name, see for example `oc_youden_normal`. ### metric User defined `metric` functions can be used as well. They are mainly useful in conjunction with `method = maximize_metric`, `method = minimize_metric`, or one of the other minimization and maximization functions. In case of a different `method` function `metric` will only be used as the main out-of-bag metric when plotting the result. The `metric` function should accept the following inputs as vectors: - `tp`: Vector of true positives - `fp`: Vector of false positives - `tn`: Vector of true negatives - `fn`: Vector of false negatives - `...`: Further arguments The function should return a numeric vector, a matrix, or a `data.frame` with one column. If the column is named, the name will be included in the output and plots. Avoid using names that are identical to the column names that are by default returned by **cutpointr**, as such names will be prefixed by `metric_` in the output. The inputs (`tp`, `fp`, `tn`, and `fn`) are vectors. The code of the included metric functions can be accessed by simply typing their name. For example, this is the `misclassification_cost` metric function: ```{r} misclassification_cost ``` # Plotting **cutpointr** includes several convenience functions for plotting data from a `cutpointr` object. These include: - `plot_cutpointr`: General purpose plotting function for cutpointr or roc_cutpointr objects - `plot_cut_boot`: Plot the bootstrapped distribution of optimal cutpoints - `plot_metric`: If `maximize_metric` or `minimize_metric` was used this function plots all possible cutoffs on the x-axis vs. the respective metric values on the y-axis. If bootstrapping was run, a confidence interval based on the bootstrapped distribution of metric values at each cutpoint can be displayed. To display no confidence interval set `conf_lvl = 0`. - `plot_metric_boot`: Plot the distribution of out-of-bag metric values - `plot_precision_recall`: Plot the precision recall curve - `plot_sensitivity_specificity`: Plot all cutpoints vs. sensitivity and specificity - `plot_roc`: Plot the ROC curve - `plot_x`: Plot the distribution of the predictor variable ```{r, fig.width=4, fig.height=3} plot_cut_boot(opt_cut_b_g) plot_metric(opt_cut_b_g, conf_lvl = 0.9) plot_metric_boot(opt_cut_b_g) plot_precision_recall(opt_cut_b_g) plot_sensitivity_specificity(opt_cut_b_g) plot_roc(opt_cut_b_g) ``` All plot functions, except for the standard plot method that returns a composed plot, return `ggplot` objects than can be further modified. For example, changing labels, title, and the theme can be achieved this way: ```{r, fig.width=4, fig.height=3} p <- plot_x(opt_cut_b_g) p + ggtitle("Distribution of dsi") + theme_minimal() + xlab("Depression score") ``` ## Flexible plotting function Using `plot_cutpointr` any metric can be chosen to be plotted on the x- or y-axis and results of `cutpointr()` as well as `roc()` can be plotted. If a `cutpointr` object is to be plotted, it is thus irrelevant which `metric` function was chosen for cutpoint estimation. Any metric that can be calculated based on the ROC curve can be subsequently plotted as only the true / false positives / negatives over all cutpoints are needed. That way, not only the above plots can be produced, but also any combination of two metrics (or metric functions) and / or cutpoints. The built-in metric functions as well as user-defined functions or anonymous functions can be supplied to `xvar` and `yvar`. If bootstrapping was run, confidence intervals can be plotted around the y-variable. This is especially useful if the cutpoints, available in the `cutpoints` function, are placed on the x-axis. Note that confidence intervals can only be correctly plotted if the values of `xvar` are constant across bootstrap samples. For example, confidence intervals for TPR by FPR (a ROC curve) cannot be plotted easily, as the values of the false positive rate vary per bootstrap sample. ```{r, fig.width=4, fig.height=3, cache=FALSE} plot_cutpointr(opt_cut_b, xvar = cutpoints, yvar = sum_sens_spec, conf_lvl = 0.9) plot_cutpointr(opt_cut_b, xvar = fpr, yvar = tpr, aspect_ratio = 1, conf_lvl = 0) plot_cutpointr(opt_cut_b, xvar = cutpoint, yvar = tp, conf_lvl = 0.9) + geom_point() ``` ## Manual plotting Since `cutpointr` returns a `data.frame` with the original data, bootstrap results, and the ROC curve in nested tibbles, these data can be conveniently extracted and plotted manually. The relevant nested tibbles are in the columns `data`, `roc_curve` and `boot`. The following is an example of accessing and plotting the grouped data. ```{r, fig.width=4, fig.height=3} opt_cut_b_g %>% select(data, subgroup) %>% unnest(cols = data) %>% ggplot(aes(x = suicide, y = dsi)) + geom_boxplot(alpha = 0.3) + facet_grid(~subgroup) ``` # Benchmarks To offer a comparison to established solutions, **cutpointr** will be benchmarked against `optimal.cutpoints` from the **OptimalCutpoints** package, **ThresholdROC** and custom functions based on the **ROCR** and **pROC** packages. By generating data of different sizes the benchmarks will offer a comparison of the scalability of the different solutions. Using `prediction` and `performance` from the **ROCR** package and `roc` from the **pROC** package, we can write functions for computing the cutpoint that maximizes the sum of sensitivity and specificity. **pROC** has a built-in function to optimize a few metrics: ```{r, eval = FALSE} # Return cutpoint that maximizes the sum of sensitivity and specificiy # ROCR package rocr_sensspec <- function(x, class) { pred <- ROCR::prediction(x, class) perf <- ROCR::performance(pred, "sens", "spec") sens <- slot(perf, "y.values")[[1]] spec <- slot(perf, "x.values")[[1]] cut <- slot(perf, "alpha.values")[[1]] cut[which.max(sens + spec)] } # pROC package proc_sensspec <- function(x, class) { r <- pROC::roc(class, x, algorithm = 2, levels = c(0, 1), direction = "<") pROC::coords(r, "best", ret="threshold", transpose = FALSE)[1] } ``` The benchmarking will be carried out using the **microbenchmark** package and randomly generated data. The values of the `x` predictor variable are drawn from a normal distribution which leads to a lot more unique values than were encountered before in the `suicide` data. Accordingly, the search for an optimal cutpoint is much more demanding, if all possible cutpoints are evaluated. Benchmarks are run for sample sizes of 100, 1000, 1e4, 1e5, 1e6, and 1e7. For low sample sizes **cutpointr** is slower than the other solutions. While this should be of low practical importance, **cutpointr** scales more favorably with increasing sample size. The speed disadvantage in small samples that leads to the lower limit of around 25ms is mainly due to the nesting of the original data and the results that makes the compact output of `cutpointr` possible. This observation is emphasized by the fact that `cutpointr::roc` is quite fast also in small samples. For sample sizes > 1e5 **cutpointr** is a little faster than the function based on **ROCR** and **pROC**. Both of these solutions are generally faster than **OptimalCutpoints** and **ThresholdROC** with the exception of small samples. **OptimalCutpoints** and **ThresholdROC** had to be excluded from benchmarks with more than 1e4 observations due to high memory requirements and/or excessive run times, rendering the use of these packages in larger samples impractical. ```{r, eval = FALSE, echo = FALSE} library(OptimalCutpoints) library(ThresholdROC) n <- 100 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) x_pos <- dat$x[dat$y == 1] x_neg <- dat$x[dat$y == 0] bench_100 <- microbenchmark::microbenchmark( cutpointr(dat, x, y, pos_class = 1, neg_class = 0, direction = ">=", metric = youden, break_ties = mean), rocr_sensspec(dat$x, dat$y), proc_sensspec(dat$x, dat$y), optimal.cutpoints(X = "x", status = "y", tag.healthy = 0, methods = "Youden", data = dat), thres2(k1 = x_neg, k2 = x_pos, rho = 0.5, method = "empirical", ci = FALSE), times = 100, unit = "ms" ) n <- 1000 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) x_pos <- dat$x[dat$y == 1] x_neg <- dat$x[dat$y == 0] bench_1000 <- microbenchmark::microbenchmark( cutpointr(dat, x, y, pos_class = 1, neg_class = 0, direction = ">=", metric = youden, break_ties = mean), rocr_sensspec(dat$x, dat$y), proc_sensspec(dat$x, dat$y), optimal.cutpoints(X = "x", status = "y", tag.healthy = 0, methods = "Youden", data = dat), thres2(k1 = x_neg, k2 = x_pos, rho = 0.5, method = "empirical", ci = FALSE), times = 100, unit = "ms" ) n <- 10000 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) x_pos <- dat$x[dat$y == 1] x_neg <- dat$x[dat$y == 0] bench_10000 <- microbenchmark::microbenchmark( cutpointr(dat, x, y, pos_class = 1, neg_class = 0, direction = ">=", metric = youden, break_ties = mean, silent = TRUE), rocr_sensspec(dat$x, dat$y), optimal.cutpoints(X = "x", status = "y", tag.healthy = 0, methods = "Youden", data = dat), proc_sensspec(dat$x, dat$y), thres2(k1 = x_neg, k2 = x_pos, rho = 0.5, method = "empirical", ci = FALSE), times = 100 ) n <- 1e5 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) bench_1e5 <- microbenchmark::microbenchmark( cutpointr(dat, x, y, pos_class = 1, neg_class = 0, direction = ">=", metric = youden, break_ties = mean), rocr_sensspec(dat$x, dat$y), proc_sensspec(dat$x, dat$y), times = 100, unit = "ms" ) n <- 1e6 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) bench_1e6 <- microbenchmark::microbenchmark( cutpointr(dat, x, y, pos_class = 1, neg_class = 0, direction = ">=", metric = youden, break_ties = mean), rocr_sensspec(dat$x, dat$y), proc_sensspec(dat$x, dat$y), times = 30, unit = "ms" ) n <- 1e7 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) bench_1e7 <- microbenchmark::microbenchmark( cutpointr(dat, x, y, pos_class = 1, neg_class = 0, direction = ">=", metric = youden, break_ties = mean), rocr_sensspec(dat$x, dat$y), proc_sensspec(dat$x, dat$y), times = 30, unit = "ms" ) results <- rbind( data.frame(time = summary(bench_100)$median, Solution = summary(bench_100)$expr, n = 100), data.frame(time = summary(bench_1000)$median, Solution = summary(bench_1000)$expr, n = 1000), data.frame(time = summary(bench_10000)$median, Solution = summary(bench_10000)$expr, n = 10000), data.frame(time = summary(bench_1e5)$median, Solution = summary(bench_1e5)$expr, n = 1e5), data.frame(time = summary(bench_1e6)$median, Solution = summary(bench_1e6)$expr, n = 1e6), data.frame(time = summary(bench_1e7)$median, Solution = summary(bench_1e7)$expr, n = 1e7) ) results$Solution <- as.character(results$Solution) results$Solution[grep(pattern = "cutpointr", x = results$Solution)] <- "cutpointr" results$Solution[grep(pattern = "rocr", x = results$Solution)] <- "ROCR" results$Solution[grep(pattern = "optimal", x = results$Solution)] <- "OptimalCutpoints" results$Solution[grep(pattern = "proc", x = results$Solution)] <- "pROC" results$Solution[grep(pattern = "thres", x = results$Solution)] <- "ThresholdROC" results$task <- "Cutpoint Estimation" ``` ```{r, echo = FALSE} # These are the original results on our system # dput(results) results <- structure(list(time = c(4.5018015, 1.812802, 0.662101, 2.2887015, 1.194301, 4.839401, 2.1764015, 0.981001, 45.0568005, 36.2398515, 8.5662515, 5.667101, 2538.612001, 4.031701, 2503.8012505, 45.384501, 43.118751, 37.150151, 465.003201, 607.023851, 583.0950005, 5467.332801, 7850.2587, 7339.356101), Solution = c("cutpointr", "ROCR", "pROC", "OptimalCutpoints", "ThresholdROC", "cutpointr", "ROCR", "pROC", "OptimalCutpoints", "ThresholdROC", "cutpointr", "ROCR", "OptimalCutpoints", "pROC", "ThresholdROC", "cutpointr", "ROCR", "pROC", "cutpointr", "ROCR", "pROC", "cutpointr", "ROCR", "pROC"), n = c(100, 100, 100, 100, 100, 1000, 1000, 1000, 1000, 1000, 10000, 10000, 10000, 10000, 10000, 1e+05, 1e+05, 1e+05, 1e+06, 1e+06, 1e+06, 1e+07, 1e+07, 1e+07), task = c("Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation")), row.names = c(NA, -24L), class = "data.frame") ``` ```{r, eval = FALSE} # ROCR package rocr_roc <- function(x, class) { pred <- ROCR::prediction(x, class) perf <- ROCR::performance(pred, "sens", "spec") return(NULL) } # pROC package proc_roc <- function(x, class) { r <- pROC::roc(class, x, algorithm = 2, levels = c(0, 1), direction = "<") return(NULL) } ``` ```{r, eval = FALSE, echo = FALSE} n <- 100 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) bench_100 <- microbenchmark::microbenchmark( cutpointr::roc(dat, "x", "y", pos_class = 1, neg_class = 0, direction = ">="), rocr_roc(dat$x, dat$y), proc_roc(dat$x, dat$y), times = 100, unit = "ms" ) n <- 1000 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) bench_1000 <- microbenchmark::microbenchmark( cutpointr::roc(dat, "x", "y", pos_class = 1, neg_class = 0, direction = ">="), rocr_roc(dat$x, dat$y), proc_roc(dat$x, dat$y), times = 100, unit = "ms" ) n <- 10000 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) bench_10000 <- microbenchmark::microbenchmark( cutpointr::roc(dat, "x", "y", pos_class = 1, neg_class = 0, direction = ">="), rocr_roc(dat$x, dat$y), proc_roc(dat$x, dat$y), times = 100, unit = "ms" ) n <- 1e5 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) bench_1e5 <- microbenchmark::microbenchmark( cutpointr::roc(dat, "x", "y", pos_class = 1, neg_class = 0, direction = ">="), rocr_roc(dat$x, dat$y), proc_roc(dat$x, dat$y), times = 100, unit = "ms" ) n <- 1e6 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) bench_1e6 <- microbenchmark::microbenchmark( cutpointr::roc(dat, "x", "y", pos_class = 1, neg_class = 0, direction = ">="), rocr_roc(dat$x, dat$y), proc_roc(dat$x, dat$y), times = 30, unit = "ms" ) n <- 1e7 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) bench_1e7 <- microbenchmark::microbenchmark( cutpointr::roc(dat, "x", "y", pos_class = 1, neg_class = 0, direction = ">="), rocr_roc(dat$x, dat$y), proc_roc(dat$x, dat$y), times = 30, unit = "ms" ) results_roc <- rbind( data.frame(time = summary(bench_100)$median, Solution = summary(bench_100)$expr, n = 100), data.frame(time = summary(bench_1000)$median, Solution = summary(bench_1000)$expr, n = 1000), data.frame(time = summary(bench_10000)$median, Solution = summary(bench_10000)$expr, n = 10000), data.frame(time = summary(bench_1e5)$median, Solution = summary(bench_1e5)$expr, n = 1e5), data.frame(time = summary(bench_1e6)$median, Solution = summary(bench_1e6)$expr, n = 1e6), data.frame(time = summary(bench_1e7)$median, Solution = summary(bench_1e7)$expr, n = 1e7) ) results_roc$Solution <- as.character(results_roc$Solution) results_roc$Solution[grep(pattern = "cutpointr", x = results_roc$Solution)] <- "cutpointr" results_roc$Solution[grep(pattern = "rocr", x = results_roc$Solution)] <- "ROCR" results_roc$Solution[grep(pattern = "proc", x = results_roc$Solution)] <- "pROC" results_roc$task <- "ROC curve calculation" ``` ```{r, echo = FALSE} # Our results results_roc <- structure(list(time = c(0.7973505, 1.732651, 0.447701, 0.859301, 2.0358515, 0.694802, 1.878151, 5.662151, 3.6580505, 11.099251, 42.8208515, 35.3293005, 159.8100505, 612.471901, 610.4337005, 2032.693551, 7806.3854515, 7081.897251), Solution = c("cutpointr", "ROCR", "pROC", "cutpointr", "ROCR", "pROC", "cutpointr", "ROCR", "pROC", "cutpointr", "ROCR", "pROC", "cutpointr", "ROCR", "pROC", "cutpointr", "ROCR", "pROC"), n = c(100, 100, 100, 1000, 1000, 1000, 10000, 10000, 10000, 1e+05, 1e+05, 1e+05, 1e+06, 1e+06, 1e+06, 1e+07, 1e+07, 1e+07), task = c("ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation")), row.names = c(NA, -18L), class = "data.frame") ``` ```{r, echo = FALSE} results_all <- dplyr::bind_rows(results, results_roc) ggplot(results_all, aes(x = n, y = time, col = Solution, shape = Solution)) + geom_point(size = 3) + geom_line() + scale_y_log10(breaks = c(0.5, 1, 2, 3, 5, 10, 25, 100, 250, 1000, 5000, 1e4, 15000)) + scale_x_log10(breaks = c(100, 1000, 1e4, 1e5, 1e6, 1e7)) + ylab("Median Time (milliseconds, log scale)") + xlab("Sample Size (log scale)") + theme_bw() + theme(legend.position = "bottom", legend.key.width = unit(0.8, "cm"), panel.spacing = unit(1, "lines")) + facet_grid(~task) ``` ```{r, echo = FALSE} res_table <- tidyr::spread(results_all, Solution, time) %>% arrange(task) knitr::kable(res_table) ```cutpointr/inst/doc/cutpointr.html0000644000176200001440000105664614066445216016772 0ustar liggesusers An introduction to cutpointr

An introduction to cutpointr

Christian Thiele

2021-06-29

cutpointr is an R package for tidy calculation of “optimal” cutpoints. It supports several methods for calculating cutpoints and includes several metrics that can be maximized or minimized by selecting a cutpoint. Some of these methods are designed to be more robust than the simple empirical optimization of a metric. Additionally, cutpointr can automatically bootstrap the variability of the optimal cutpoints and return out-of-bag estimates of various performance metrics.

Installation

You can install cutpointr from CRAN using the menu in RStudio or simply:

install.packages("cutpointr")

Example

For example, the optimal cutpoint for the included data set is 2 when maximizing the sum of sensitivity and specificity.

library(cutpointr)
data(suicide)
head(suicide)
##   age gender dsi suicide
## 1  29 female   1      no
## 2  26   male   0      no
## 3  26 female   0      no
## 4  27 female   0      no
## 5  28 female   0      no
## 6  53   male   2      no
cp <- cutpointr(suicide, dsi, suicide, 
                method = maximize_metric, metric = sum_sens_spec)
## Assuming the positive class is yes
## Assuming the positive class has higher x values
summary(cp)
## Method: maximize_metric 
## Predictor: dsi 
## Outcome: suicide 
## Direction: >= 
## 
##     AUC   n n_pos n_neg
##  0.9238 532    36   496
## 
##  optimal_cutpoint sum_sens_spec    acc sensitivity specificity tp fn fp  tn
##                 2        1.7518 0.8647      0.8889      0.8629 32  4 68 428
## 
## Predictor summary: 
##     Data Min.   5% 1st Qu. Median      Mean 3rd Qu.  95% Max.       SD NAs
##  Overall    0 0.00       0      0 0.9210526       1 5.00   11 1.852714   0
##       no    0 0.00       0      0 0.6330645       0 4.00   10 1.412225   0
##      yes    0 0.75       4      5 4.8888889       6 9.25   11 2.549821   0
plot(cp)

When considering the optimality of a cutpoint, we can only make a judgement based on the sample at hand. Thus, the estimated cutpoint may not be optimal within the population or on unseen data, which is why we sometimes put the “optimal” in quotation marks.

cutpointr makes assumptions about the direction of the dependency between class and x, if direction and / or pos_class or neg_class are not specified. The same result as above can be achieved by manually defining direction and the positive / negative classes which is slightly faster, since the classes and direction don’t have to be determined:

opt_cut <- cutpointr(suicide, dsi, suicide, direction = ">=", pos_class = "yes",
                     neg_class = "no", method = maximize_metric, metric = youden)

opt_cut is a data frame that returns the input data and the ROC curve (and optionally the bootstrap results) in a nested tibble. Methods for summarizing and plotting the data and results are included (e.g. summary, plot, plot_roc, plot_metric)

To inspect the optimization, the function of metric values per cutpoint can be plotted using plot_metric, if an optimization function was used that returns a metric column in the roc_curve column. For example, the maximize_metric and minimize_metric functions do so:

plot_metric(opt_cut)

Predictions for new data can be made using predict:

predict(opt_cut, newdata = data.frame(dsi = 0:5))
## [1] "no"  "no"  "yes" "yes" "yes" "yes"

Features

  • Calculation of optimal cutpoints in binary classification tasks
  • Tidy output, integrates well with functions from the tidyverse
  • Functions for plotting ROC curves, metric distributions and more
  • Bootstrapping for simulating the cutpoint variability and for obtaining out-of-bag estimates of various metrics (as a form of internal validation) with optional parallelisation
  • Multiple methods for calculating cutpoints
  • Multiple metrics can be chosen for maximization / minimization
  • Tidyeval

Calculating cutpoints

Method functions for cutpoint estimation

The included methods for calculating cutpoints are:

  • maximize_metric: Maximize the metric function
  • minimize_metric: Minimize the metric function
  • maximize_loess_metric: Maximize the metric function after LOESS smoothing
  • minimize_loess_metric: Minimize the metric function after LOESS smoothing
  • maximize_spline_metric: Maximize the metric function after spline smoothing
  • minimize_spline_metric: Minimize the metric function after spline smoothing
  • maximize_gam_metric: Maximize the metric function after smoothing via Generalized Additive Models
  • minimize_gam_metric: Minimize the metric function after smoothing via Generalized Additive Models
  • maximize_boot_metric: Bootstrap the optimal cutpoint when maximizing a metric
  • minimize_boot_metric: Bootstrap the optimal cutpoint when minimizing a metric
  • oc_manual: Specify the cutoff value manually
  • oc_mean: Use the sample mean as the “optimal” cutpoint
  • oc_median: Use the sample median as the “optimal” cutpoint
  • oc_youden_kernel: Maximize the Youden-Index after kernel smoothing the distributions of the two classes
  • oc_youden_normal: Maximize the Youden-Index parametrically assuming normally distributed data in both classes

Metric functions

The included metrics to be used with the minimization and maximization methods are:

  • accuracy: Fraction correctly classified
  • abs_d_sens_spec: The absolute difference of sensitivity and specificity
  • abs_d_ppv_npv: The absolute difference between positive predictive value (PPV) and negative predictive value (NPV)
  • roc01: Distance to the point (0,1) on ROC space
  • cohens_kappa: Cohen’s Kappa
  • sum_sens_spec: sensitivity + specificity
  • sum_ppv_npv: The sum of positive predictive value (PPV) and negative predictive value (NPV)
  • prod_sens_spec: sensitivity * specificity
  • prod_ppv_npv: The product of positive predictive value (PPV) and negative predictive value (NPV)
  • youden: Youden- or J-Index = sensitivity + specificity - 1
  • odds_ratio: (Diagnostic) odds ratio
  • risk_ratio: risk ratio (relative risk)
  • p_chisquared: The p-value of a chi-squared test on the confusion matrix
  • cost_misclassification: The sum of the misclassification cost of false positives and false negatives. Additional arguments: cost_fp, cost_fn
  • total_utility: The total utility of true / false positives / negatives. Additional arguments: utility_tp, utility_tn, cost_fp, cost_fn
  • F1_score: The F1-score (2 * TP) / (2 * TP + FP + FN)
  • metric_constrain: Maximize a selected metric given a minimal value of another selected metric
  • sens_constrain: Maximize sensitivity given a minimal value of specificity
  • spec_constrain: Maximize specificity given a minimal value of sensitivity
  • acc_constrain: Maximize accuracy given a minimal value of sensitivity

Furthermore, the following functions are included which can be used as metric functions but are more useful for plotting purposes, for example in plot_cutpointr, or for defining new metric functions: tp, fp, tn, fn, tpr, fpr, tnr, fnr, false_omission_rate, false_discovery_rate, ppv, npv, precision, recall, sensitivity, and specificity.

The inputs to the arguments method and metric are functions so that user-defined functions can easily be supplied instead of the built-in ones.

Separate subgroups and bootstrapping

Cutpoints can be separately estimated on subgroups that are defined by a third variable, gender in this case. Additionally, if boot_runs is larger zero, cutpointr will carry out the usual cutpoint calculation on the full sample, just as before, and additionally on boot_runs bootstrap samples. This offers a way of gauging the out-of-sample performance of the cutpoint estimation method. If a subgroup is given, the bootstrapping is carried out separately for every subgroup which is also reflected in the plots and output.

set.seed(12)
opt_cut_b <- cutpointr(suicide, dsi, suicide, boot_runs = 1000)
opt_cut_b
## # A tibble: 1 x 16
##   direction optimal_cutpoint method          sum_sens_spec      acc sensitivity
##   <chr>                <dbl> <chr>                   <dbl>    <dbl>       <dbl>
## 1 >=                       2 maximize_metric       1.75179 0.864662    0.888889
##   specificity      AUC pos_class neg_class prevalence outcome predictor
##         <dbl>    <dbl> <fct>     <fct>          <dbl> <chr>   <chr>    
## 1    0.862903 0.923779 yes       no         0.0676692 suicide dsi      
##   data               roc_curve                 boot                 
##   <list>             <list>                    <list>               
## 1 <tibble [532 x 2]> <roc_cutpointr [13 x 10]> <tibble [1,000 x 23]>

The returned object has the additional column boot which is a nested tibble that includes the cutpoints per bootstrap sample along with the metric calculated using the function in metric and various default metrics. The metrics are suffixed by _b to indicate in-bag results or _oob to indicate out-of-bag results:

opt_cut$boot
## [1] NA

The summary and plots include additional elements that summarize or display the bootstrap results:

summary(opt_cut)
## Method: maximize_metric 
## Predictor: dsi 
## Outcome: suicide 
## Direction: >= 
## 
##     AUC   n n_pos n_neg
##  0.9238 532    36   496
## 
##  optimal_cutpoint youden    acc sensitivity specificity tp fn fp  tn
##                 2 0.7518 0.8647      0.8889      0.8629 32  4 68 428
## 
## Predictor summary: 
##     Data Min.   5% 1st Qu. Median      Mean 3rd Qu.  95% Max.       SD NAs
##  Overall    0 0.00       0      0 0.9210526       1 5.00   11 1.852714   0
##       no    0 0.00       0      0 0.6330645       0 4.00   10 1.412225   0
##      yes    0 0.75       4      5 4.8888889       6 9.25   11 2.549821   0
plot(opt_cut)

Parallelized bootstrapping

Using foreach and doRNG the bootstrapping can be parallelized easily. The doRNG package is being used to make the bootstrap sampling reproducible.

library(doParallel)
cl <- makeCluster(2) # 2 cores
registerDoParallel(cl)
registerDoRNG(12) # Reproducible parallel loops using doRNG
opt_cut <- cutpointr(suicide, dsi, suicide, gender, pos_class = "yes",
                     direction = ">=", boot_runs = 1000, allowParallel = TRUE)
stopCluster(cl)
opt_cut

More robust cutpoint estimation methods

Bootstrapped cutpoints

It has been shown that bagging can substantially improve performance of a wide range of types of models in regression as well as in classification tasks. This method is available for cutpoint estimation via the maximize_boot_metric and minimize_boot_metric functions. If one of these functions is used as method, boot_cut bootstrap samples are drawn, the cutpoint optimization is carried out in each one and a summary (e.g. the mean) of the resulting optimal cutpoints on the bootstrap samples is returned as the optimal cutpoint in cutpointr. Note that if bootstrap validation is run, i.e. if boot_runs is larger zero, an outer bootstrap will be executed. In the bootstrap validation routine boot_runs bootstrap samples are generated and each one is again bootstrapped boot_cut times. This may lead to long run times, so activating the built-in parallelization may be advisable.

The advantages of bootstrapping the optimal cutpoint are that the procedure doesn’t possess parameters that have to be tuned, unlike the LOESS smoothing, that it doesn’t rely on assumptions, unlike the Normal method, and that it is applicable to any metric that can be used with minimize_metric or maximize_metric, unlike the Kernel method. Furthermore, like Random Forests cannot be overfit by increasing the number of trees, the bootstrapped cutpoints cannot be overfit by running an excessive amount of boot_cut repetitions.

set.seed(100)
cutpointr(suicide, dsi, suicide, gender, 
          method = maximize_boot_metric,
          boot_cut = 200, summary_func = mean,
          metric = accuracy, silent = TRUE)
## # A tibble: 2 x 18
##   subgroup direction optimal_cutpoint method               accuracy      acc
##   <chr>    <chr>                <dbl> <chr>                   <dbl>    <dbl>
## 1 female   >=                 5.73246 maximize_boot_metric 0.956633 0.956633
## 2 male     >=                 8.41026 maximize_boot_metric 0.95     0.95    
##   sensitivity specificity      AUC pos_class neg_class prevalence outcome
##         <dbl>       <dbl>    <dbl> <fct>     <fct>          <dbl> <chr>  
## 1    0.444444    0.994521 0.944647 yes       no         0.0688776 suicide
## 2    0.222222    1        0.861747 yes       no         0.0642857 suicide
##   predictor grouping data               roc_curve                boot 
##   <chr>     <chr>    <list>             <list>                   <lgl>
## 1 dsi       gender   <tibble [392 x 2]> <roc_cutpointr [11 x 9]> NA   
## 2 dsi       gender   <tibble [140 x 2]> <roc_cutpointr [11 x 9]> NA

LOESS smoothing for selecting a cutpoint

When using maximize_metric and minimize_metric the optimal cutpoint is selected by searching the maximum or minimum of the metric function. For example, we may want to minimize the misclassification cost. Since false negatives (a suicide attempt was not anticipated) can be regarded as much more severe than false positives we can set the cost of a false negative cost_fn for example to ten times the cost of a false positive.

opt_cut <- cutpointr(suicide, dsi, suicide, gender, method = minimize_metric,
                     metric = misclassification_cost, cost_fp = 1, cost_fn = 10)
## Assuming the positive class is yes
## Assuming the positive class has higher x values
plot_metric(opt_cut)

As this “optimal” cutpoint may depend on minor differences between the possible cutoffs, smoothing of the function of metric values by cutpoint value might be desirable, especially in small samples. The minimize_loess_metric and maximize_loess_metric functions can be used to smooth the function so that the optimal cutpoint is selected based on the smoothed metric values. Options to modify the smoothing, which is implemented using loess.as from the fANCOVA package, include:

  • criterion: the criterion for automatic smoothing parameter selection: “aicc” denotes bias-corrected AIC criterion, “gcv” denotes generalized cross-validation.
  • degree: the degree of the local polynomials to be used. It can be 0, 1 or 2.
  • family: if “gaussian” fitting is by least-squares, and if “symmetric” a re-descending M estimator is used with Tukey’s biweight function.
  • user.span: the user-defined parameter which controls the degree of smoothing.

Using parameters for the LOESS smoothing of criterion = "aicc", degree = 2, family = "symmetric", and user.span = 0.7 we get the following smoothed versions of the above metrics:

opt_cut <- cutpointr(suicide, dsi, suicide, gender, 
                     method = minimize_loess_metric,
                     criterion = "aicc", family = "symmetric", 
                     degree = 2, user.span = 0.7,
                     metric = misclassification_cost, cost_fp = 1, cost_fn = 10)
plot_metric(opt_cut)

The optimal cutpoint for the female subgroup changes to 3. Note, though, that there are no reliable rules for selecting the “best” smoothing parameters. Notably, the LOESS smoothing is sensitive to the number of unique cutpoints. A large number of unique cutpoints generally leads to a more volatile curve of metric values by cutpoint value, even after smoothing. Thus, the curve tends to be undersmoothed in that scenario. The unsmoothed metric values are returned in opt_cut$roc_curve in the column m_unsmoothed.

Smoothing via Generalized Additive Models for selecting a cutpoint

In a similar fashion, the function of metric values per cutpoint can be smoothed using Generalized Additive Models with smooth terms. Internally, mgcv::gam carries out the smoothing which can be customized via the arguments formula and optimizer, see help("gam", package = "mgcv"). Most importantly, the GAM can be specified by altering the default formula, for example the smoothing function could be configured to apply cubic regression splines ("cr") as the smooth term. As the suicide data has only very few unique cutpoints, it is not very suitable for showcasing the GAM smoothing, so we will use two classes of the iris data here. In this case, the purely empirical method and the GAM smoothing lead to identical cutpoints, but in practice the GAM smoothing tends to be more robust, especially with larger data. An attractive feature of the GAM smoothing is that the default values tend to work quite well and usually require no tuning, eliminating researcher degrees of freedom.

library(ggplot2)
exdat <- iris
exdat <- exdat[exdat$Species != "setosa", ]
opt_cut <- cutpointr(exdat, Petal.Length, Species,
                     method = minimize_gam_metric,
                     formula = m ~ s(x.sorted, bs = "cr"),
                     metric = abs_d_sens_spec)
## Assuming the positive class is virginica
## Assuming the positive class has higher x values
plot_metric(opt_cut)

Spline smoothing for selecting a cutpoint

Again in the same fashion the function of metric values per cutpoint can be smoothed using smoothing splines. By default, the number of knots is automatically chosen using the cutpoint_knots function. That function uses stats::.nknots.smspl, which is the default in stats::smooth.spline to pick the number of knots.

Alternatively, the number of knots can be set manually and also the other smoothing parameters of stats::smooth.spline can be set as desired. For details see ?maximize_spline_metric.

opt_cut <- cutpointr(suicide, dsi, suicide, gender, 
                     method = minimize_spline_metric, spar = 0.4,
                     metric = misclassification_cost, cost_fp = 1, cost_fn = 10)
## Assuming the positive class is yes
## Assuming the positive class has higher x values
## nknots: 10
## nknots: 10
plot_metric(opt_cut)

Parametric method assuming normality

The Normal method in oc_youden_normal is a parametric method for maximizing the Youden-Index or equivalently the sum of \(Se\) and \(Sp\). It relies on the assumption that the predictor for both the negative and positive observations is normally distributed. In that case it can be shown that

\[c^* = \frac{(\mu_P \sigma_N^2 - \mu_N \sigma_P^2) - \sigma_N \sigma_P \sqrt{(\mu_N - \mu_P)^2 + (\sigma_N^2 - \sigma_P^2) log(\sigma_N^2 / \sigma_P^2)}}{\sigma_N^2 - \sigma_P^2}\]

where the negative class is normally distributed with \(\sim N(\mu_N, \sigma_N^2)\) and the positive class independently normally distributed with \(\sim N(\mu_P, \sigma_P^2)\) provides the optimal cutpoint \(c^*\) that maximizes the Youden-Index. If \(\sigma_N\) and \(\sigma_P\) are equal, the expression can be simplified to \(c^* = \frac{\mu_N + \mu_P}{2}\). However, the oc_youden_normal method in cutpointr always assumes unequal standard deviations. Since this method does not select a cutpoint from the observed predictor values, it is questionable which values for \(Se\) and \(Sp\) should be reported. Here, the Youden-Index can be calculated as

\[J = \Phi(\frac{c^* - \mu_N}{\sigma_N}) - \Phi(\frac{c^* - \mu_P}{\sigma_P})\]

if the assumption of normality holds. However, since there exist several methods that do not select cutpoints from the available observations and to unify the reporting of metrics for these methods, cutpointr reports all metrics, e.g. \(Se\) and \(Sp\), based on the empirical observations.

cutpointr(suicide, dsi, suicide, gender, method = oc_youden_normal)
## Assuming the positive class is yes
## Assuming the positive class has higher x values
## # A tibble: 2 x 18
##   subgroup direction optimal_cutpoint method           sum_sens_spec      acc
##   <chr>    <chr>                <dbl> <chr>                    <dbl>    <dbl>
## 1 female   >=                 2.47775 oc_youden_normal       1.71618 0.895408
## 2 male     >=                 3.17226 oc_youden_normal       1.54453 0.864286
##   sensitivity specificity      AUC pos_class neg_class prevalence outcome
##         <dbl>       <dbl>    <dbl> <fct>     <fct>          <dbl> <chr>  
## 1    0.814815    0.901370 0.944647 yes       no         0.0688776 suicide
## 2    0.666667    0.877863 0.861747 yes       no         0.0642857 suicide
##   predictor grouping data               roc_curve                boot 
##   <chr>     <chr>    <list>             <list>                   <lgl>
## 1 dsi       gender   <tibble [392 x 2]> <roc_cutpointr [11 x 9]> NA   
## 2 dsi       gender   <tibble [140 x 2]> <roc_cutpointr [11 x 9]> NA

Nonparametric kernel method

A nonparametric alternative is the Kernel method [@fluss_estimation_2005]. Here, the empirical distribution functions are smoothed using the Gaussian kernel functions \(\hat{F}_N(t) = \frac{1}{n} \sum^n_{i=1} \Phi(\frac{t - y_i}{h_y})\) and \(\hat{G}_P(t) = \frac{1}{m} \sum^m_{i=1} \Phi(\frac{t - x_i}{h_x})\) for the negative and positive classes respectively. Following Silverman’s plug-in “rule of thumb” the bandwidths are selected as \(h_y = 0.9 * min\{s_y, iqr_y/1.34\} * n^{-0.2}\) and \(h_x = 0.9 * min\{s_x, iqr_x/1.34\} * m^{-0.2}\) where \(s\) is the sample standard deviation and \(iqr\) is the inter quartile range. It has been demonstrated that AUC estimation is rather insensitive to the choice of the bandwidth procedure [@faraggi_estimation_2002] and thus the plug-in bandwidth estimator has also been recommended for cutpoint estimation. The oc_youden_kernel function in cutpointr uses a Gaussian kernel and the direct plug-in method for selecting the bandwidths. The kernel smoothing is done via the bkde function from the KernSmooth package [@wand_kernsmooth:_2013].

Again, there is a way to calculate the Youden-Index from the results of this method [@fluss_estimation_2005] which is

\[\hat{J} = max_c \{\hat{F}_N(c) - \hat{G}_N(c) \}\]

but as before we prefer to report all metrics based on applying the cutpoint that was estimated using the Kernel method to the empirical observations.

cutpointr(suicide, dsi, suicide, gender, method = oc_youden_kernel)
## Assuming the positive class is yes
## Assuming the positive class has higher x values
## # A tibble: 2 x 18
##   subgroup direction optimal_cutpoint method           sum_sens_spec      acc
##   <chr>    <chr>                <dbl> <chr>                    <dbl>    <dbl>
## 1 female   >=                 1.18128 oc_youden_kernel       1.80812 0.885204
## 2 male     >=                 1.31636 oc_youden_kernel       1.58694 0.807143
##   sensitivity specificity      AUC pos_class neg_class prevalence outcome
##         <dbl>       <dbl>    <dbl> <fct>     <fct>          <dbl> <chr>  
## 1    0.925926    0.882192 0.944647 yes       no         0.0688776 suicide
## 2    0.777778    0.809160 0.861747 yes       no         0.0642857 suicide
##   predictor grouping data               roc_curve                boot 
##   <chr>     <chr>    <list>             <list>                   <lgl>
## 1 dsi       gender   <tibble [392 x 2]> <roc_cutpointr [11 x 9]> NA   
## 2 dsi       gender   <tibble [140 x 2]> <roc_cutpointr [11 x 9]> NA

Additional features

Calculating only the ROC curve

When running cutpointr, a ROC curve is by default returned in the column roc_curve. This ROC curve can be plotted using plot_roc. Alternatively, if only the ROC curve is desired and no cutpoint needs to be calculated, the ROC curve can be created using roc() and plotted using plot_cutpointr. The roc function, unlike cutpointr, does not determine direction, pos_class or neg_class automatically.

roc_curve <- roc(data = suicide, x = dsi, class = suicide,
    pos_class = "yes", neg_class = "no", direction = ">=")
auc(roc_curve)
## [1] 0.9237791
head(roc_curve)
## # A tibble: 6 x 9
##   x.sorted    tp    fp    tn    fn    tpr   tnr     fpr   fnr
##      <dbl> <dbl> <dbl> <int> <int>  <dbl> <dbl>   <dbl> <dbl>
## 1      Inf     0     0   496    36 0      1     0       1    
## 2       11     1     0   496    35 0.0278 1     0       0.972
## 3       10     2     1   495    34 0.0556 0.998 0.00202 0.944
## 4        9     3     1   495    33 0.0833 0.998 0.00202 0.917
## 5        8     4     1   495    32 0.111  0.998 0.00202 0.889
## 6        7     7     1   495    29 0.194  0.998 0.00202 0.806
plot_roc(roc_curve)

Midpoints

So far - which is the default in cutpointr - we have considered all unique values of the predictor as possible cutpoints. An alternative could be to use a sequence of equidistant values instead, for example in the case of the suicide data all integers in \([0, 10]\). However, with very sparse data and small intervals between the candidate cutpoints (i.e. a ‘dense’ sequence like seq(0, 10, by = 0.01)) this leads to the uninformative evaluation of large ranges of cutpoints that all result in the same metric value. A more elegant alternative, not only for the case of sparse data, that is supported by cutpointr is the use of a mean value of the optimal cutpoint and the next highest (if direction = ">=") or the next lowest (if direction = "<=") predictor value in the data. The result is an optimal cutpoint that is equal to the cutpoint that would be obtained using an infinitely dense sequence of candidate cutpoints and is thus usually more efficient computationally. This behavior can be activated by setting use_midpoints = TRUE, which is the default. If we use this setting, we obtain an optimal cutpoint of 1.5 for the complete sample on the suicide data instead of 2 when maximizing the sum of sensitivity and specificity.

Assume the following small data set:

dat <- data.frame(outcome = c("neg", "neg", "neg", "pos", "pos", "pos", "pos"),
                  pred    = c(1, 2, 3, 8, 11, 11, 12))

Since the distance of the optimal cutpoint (8) to the next lowest observation (3) is rather large we arrive at a range of possible cutpoints that all maximize the metric. In the case of this kind of sparseness it might for example be desirable to classify a new observation with a predictor value of 4 as belonging to the negative class. If use_midpoints is set to TRUE, the mean of the optimal cutpoint and the next lowest observation is returned as the optimal cutpoint, if direction is >=. The mean of the optimal cutpoint and the next highest observation is returned as the optimal cutpoint, if direction = "<=".

opt_cut <- cutpointr(dat, x = pred, class = outcome, use_midpoints = TRUE)
## Assuming the positive class is pos
## Assuming the positive class has higher x values
plot_x(opt_cut)

A simulation demonstrates more clearly that setting use_midpoints = TRUE avoids biasing the cutpoints. To simulate the bias of the metric functions, the predictor values of both classes were drawn from normal distributions with constant standard deviations of 10, a constant mean of the negative class of 100 and higher mean values of the positive class that are selected in such a way that optimal Youden-Index values of 0.2, 0.4, 0.6, and 0.8 result in the population. Samples of 9 different sizes were drawn and the cutpoints that maximize the Youden-Index were estimated. The simulation was repeated 10000 times. As can be seen by the mean error, use_midpoints = TRUE eliminates the bias that is introduced by otherwise selecting the value of an observation as the optimal cutpoint. If direction = ">=", as in this case, the observation that represents the optimal cutpoint is the highest possible cutpoint that leads to the optimal metric value and thus the biases are positive. The methods oc_youden_normal and oc_youden_kernel are always unbiased, as they don’t select a cutpoint based on the ROC-curve or the function of metric values per cutpoint.

## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union

Finding all cutpoints with acceptable performance

By default, most packages only return the “best” cutpoint and disregard other cutpoints with quite similar performance, even if the performance differences are minuscule. cutpointr makes this process more explicit via the tol_metric argument. For example, if all cutpoints are of interest that achieve at least an accuracy within 0.05 of the optimally achievable accuracy, tol_metric can be set to 0.05 and also those cutpoints will be returned.

In the case of the suicide data and when maximizing the sum of sensitivity and specificity, empirically the cutpoints 2 and 3 lead to quite similar performances. If tol_metric is set to 0.05, both will be returned.

opt_cut <- cutpointr(suicide, dsi, suicide, metric = sum_sens_spec, 
                     tol_metric = 0.05, break_ties = c)
## Assuming the positive class is yes
## Assuming the positive class has higher x values
## Multiple optimal cutpoints found, applying break_ties.
library(tidyr)
opt_cut %>% 
    select(optimal_cutpoint, sum_sens_spec) %>% 
    unnest(cols = c(optimal_cutpoint, sum_sens_spec))
## # A tibble: 2 x 2
##   optimal_cutpoint sum_sens_spec
##              <dbl>         <dbl>
## 1                2          1.75
## 2                1          1.70

Manual and mean / median cutpoints

Using the oc_manual function the optimal cutpoint will not be determined based on, for example, a metric but is instead set manually using the cutpoint argument. This is useful for supplying and evaluating cutpoints that were found in the literature or in other external sources.

The oc_manual function could also be used to set the cutpoint to the sample mean using cutpoint = mean(data$x). However, this may introduce bias into the bootstrap validation procedure, since the actual mean of the population is not known and thus the mean to be used as the cutpoint should be automatically determined in every resample. To do so, the oc_mean and oc_median functions can be used.

set.seed(100)
opt_cut_manual <- cutpointr(suicide, dsi, suicide, method = oc_manual, 
                       cutpoint = mean(suicide$dsi), boot_runs = 1000)
set.seed(100)
opt_cut_mean <- cutpointr(suicide, dsi, suicide, method = oc_mean, boot_runs = 1000)

Nonstandard evaluation via tidyeval

The arguments to cutpointr do not need to be enclosed in quotes. This is possible thanks to nonstandard evaluation of the arguments, which are evaluated on data.

Functions that use nonstandard evaluation are often not suitable for programming with. The use of nonstandard evaluation may lead to scoping problems and subsequent obvious as well as possibly subtle errors. cutpointr uses tidyeval internally and accordingly the same rules as for programming with dplyr apply. Arguments can be unquoted with !!:

myvar <- "dsi"
cutpointr(suicide, !!myvar, suicide)

ROC curve and optimal cutpoint for multiple variables

Alternatively, we can map the standard evaluation version cutpointr to the column names. If direction and / or pos_class and neg_class are unspecified, these parameters will automatically be determined by cutpointr so that the AUC values for all variables will be \(> 0.5\).

We could do this manually, e.g. using purrr::map, but to make this task more convenient multi_cutpointr can be used to achieve the same result. It maps multiple predictor columns to cutpointr, by default all numeric columns except for the class column.

mcp <- multi_cutpointr(suicide, class = suicide, pos_class = "yes", 
                use_midpoints = TRUE, silent = TRUE) 
summary(mcp)
## Method: maximize_metric 
## Predictor: age, dsi 
## Outcome: suicide 
## 
## Predictor: age 
## -------------------------------------------------------------------------------- 
##  direction    AUC   n n_pos n_neg
##         <= 0.5257 532    36   496
## 
##  optimal_cutpoint sum_sens_spec    acc sensitivity specificity tp fn  fp tn
##              55.5        1.1154 0.1992      0.9722      0.1431 35  1 425 71
## 
## Predictor summary: 
##     Data Min. 5% 1st Qu. Median    Mean 3rd Qu.   95% Max.      SD NAs
##  Overall   18 19      24   28.0 34.1259   41.25 65.00   83 15.0542   0
##       no   18 19      24   28.0 34.2218   41.25 65.50   83 15.1857   0
##      yes   18 18      22   27.5 32.8056   41.25 54.25   69 13.2273   0
## 
## Predictor: dsi 
## -------------------------------------------------------------------------------- 
##  direction    AUC   n n_pos n_neg
##         >= 0.9238 532    36   496
## 
##  optimal_cutpoint sum_sens_spec    acc sensitivity specificity tp fn fp  tn
##               1.5        1.7518 0.8647      0.8889      0.8629 32  4 68 428
## 
## Predictor summary: 
##     Data Min.   5% 1st Qu. Median   Mean 3rd Qu.  95% Max.     SD NAs
##  Overall    0 0.00       0      0 0.9211       1 5.00   11 1.8527   0
##       no    0 0.00       0      0 0.6331       0 4.00   10 1.4122   0
##      yes    0 0.75       4      5 4.8889       6 9.25   11 2.5498   0

Accessing data, roc_curve, and boot

The object returned by cutpointr is of the classes cutpointr, tbl_df, tbl, and data.frame. Thus, it can be handled like a usual data frame. The columns data, roc_curve, and boot consist of nested data frames, which means that these are list columns whose elements are data frames. They can either be accessed using [ or by using functions from the tidyverse. If subgroups were given, the output contains one row per subgroup and the function that accesses the data should be mapped to every row or the data should be grouped by subgroup.

set.seed(123)
opt_cut_b_g <- cutpointr(suicide, dsi, suicide, gender, boot_runs = 1000)
# Using dplyr and tidyr
library(tidyr)
opt_cut_b_g %>% 
  group_by(subgroup) %>% 
  select(subgroup, boot) %>%
  unnest(cols = boot) %>% 
  summarise(sd_oc_boot = sd(optimal_cutpoint),
            m_oc_boot  = mean(optimal_cutpoint),
            m_acc_oob  = mean(acc_oob))
## # A tibble: 2 x 4
##   subgroup sd_oc_boot m_oc_boot m_acc_oob
##   <chr>         <dbl>     <dbl>     <dbl>
## 1 female        0.766      2.17     0.880
## 2 male          1.51       2.92     0.806

Adding metrics to the result of cutpointr() or roc()

By default, the output of cutpointr includes the optimized metric and several other metrics. The add_metric function adds further metrics. Here, we’re adding the negative predictive value (NPV) and the positive predictive value (PPV) at the optimal cutpoint per subgroup:

cutpointr(suicide, dsi, suicide, gender, metric = youden, silent = TRUE) %>% 
    add_metric(list(ppv, npv)) %>% 
    select(subgroup, optimal_cutpoint, youden, ppv, npv)
## # A tibble: 2 x 5
##   subgroup optimal_cutpoint   youden      ppv      npv
##   <chr>               <dbl>    <dbl>    <dbl>    <dbl>
## 1 female                  2 0.808118 0.367647 0.993827
## 2 male                    3 0.625106 0.259259 0.982301

In the same fashion, additional metric columns can be added to a roc_cutpointr object:

roc(data = suicide, x = dsi, class = suicide, pos_class = "yes",
    neg_class = "no", direction = ">=") %>% 
  add_metric(list(cohens_kappa, F1_score)) %>% 
  select(x.sorted, tp, fp, tn, fn, cohens_kappa, F1_score) %>% 
  head()
## # A tibble: 6 x 7
##   x.sorted    tp    fp    tn    fn cohens_kappa F1_score
##      <dbl> <dbl> <dbl> <int> <int>        <dbl>    <dbl>
## 1      Inf     0     0   496    36       0        0     
## 2       11     1     0   496    35       0.0506   0.0541
## 3       10     2     1   495    34       0.0931   0.103 
## 4        9     3     1   495    33       0.138    0.15  
## 5        8     4     1   495    32       0.182    0.195 
## 6        7     7     1   495    29       0.301    0.318

User-defined functions

method

User-defined functions can be supplied to method, which is the function that is responsible for returning the optimal cutpoint. To define a new method function, create a function that may take as input(s):

  • data: A data.frame or tbl_df
  • x: (character) The name of the predictor variable
  • class: (character) The name of the class variable
  • metric_func: A function for calculating a metric, e.g. accuracy. Note that the method function does not necessarily have to accept this argument
  • pos_class: The positive class
  • neg_class: The negative class
  • direction: ">=" if the positive class has higher x values, "<=" otherwise
  • tol_metric: (numeric) In the built-in methods, all cutpoints will be returned that lead to a metric value in the interval [m_max - tol_metric, m_max + tol_metric] where m_max is the maximum achievable metric value. This can be used to return multiple decent cutpoints and to avoid floating-point problems.
  • use_midpoints: (logical) In the built-in methods, if TRUE (default FALSE) the returned optimal cutpoint will be the mean of the optimal cutpoint and the next highest observation (for direction = “>”) or the next lowest observation (for direction = “<”) which avoids biasing the optimal cutpoint.
  • ...: Further arguments that are passed to metric or that can be captured inside of method

The function should return a data frame or tibble with one row, the column optimal_cutpoint, and an optional column with an arbitrary name with the metric value at the optimal cutpoint.

For example, a function for choosing the cutpoint as the mean of the independent variable could look like this:

mean_cut <- function(data, x, ...) {
    oc <- mean(data[[x]])
    return(data.frame(optimal_cutpoint = oc))
}

If a method function does not return a metric column, the default sum_sens_spec, the sum of sensitivity and specificity, is returned as the extra metric column in addition to accuracy, sensitivity and specificity.

Some method functions that make use of the additional arguments (that are captured by ...) are already included in cutpointr, see the list at the top. Since these functions are arguments to cutpointr their code can be accessed by simply typing their name, see for example oc_youden_normal.

metric

User defined metric functions can be used as well. They are mainly useful in conjunction with method = maximize_metric, method = minimize_metric, or one of the other minimization and maximization functions. In case of a different method function metric will only be used as the main out-of-bag metric when plotting the result. The metric function should accept the following inputs as vectors:

  • tp: Vector of true positives
  • fp: Vector of false positives
  • tn: Vector of true negatives
  • fn: Vector of false negatives
  • ...: Further arguments

The function should return a numeric vector, a matrix, or a data.frame with one column. If the column is named, the name will be included in the output and plots. Avoid using names that are identical to the column names that are by default returned by cutpointr, as such names will be prefixed by metric_ in the output. The inputs (tp, fp, tn, and fn) are vectors. The code of the included metric functions can be accessed by simply typing their name.

For example, this is the misclassification_cost metric function:

misclassification_cost
## function (tp, fp, tn, fn, cost_fp = 1, cost_fn = 1, ...) 
## {
##     misclassification_cost <- cost_fp * fp + cost_fn * fn
##     misclassification_cost <- matrix(misclassification_cost, 
##         ncol = 1)
##     colnames(misclassification_cost) <- "misclassification_cost"
##     return(misclassification_cost)
## }
## <bytecode: 0x00000000247b08c0>
## <environment: namespace:cutpointr>

Plotting

cutpointr includes several convenience functions for plotting data from a cutpointr object. These include:

  • plot_cutpointr: General purpose plotting function for cutpointr or roc_cutpointr objects
  • plot_cut_boot: Plot the bootstrapped distribution of optimal cutpoints
  • plot_metric: If maximize_metric or minimize_metric was used this function plots all possible cutoffs on the x-axis vs. the respective metric values on the y-axis. If bootstrapping was run, a confidence interval based on the bootstrapped distribution of metric values at each cutpoint can be displayed. To display no confidence interval set conf_lvl = 0.
  • plot_metric_boot: Plot the distribution of out-of-bag metric values
  • plot_precision_recall: Plot the precision recall curve
  • plot_sensitivity_specificity: Plot all cutpoints vs. sensitivity and specificity
  • plot_roc: Plot the ROC curve
  • plot_x: Plot the distribution of the predictor variable
plot_cut_boot(opt_cut_b_g)

plot_metric(opt_cut_b_g, conf_lvl = 0.9)

plot_metric_boot(opt_cut_b_g)
## Warning: Removed 12 rows containing non-finite values (stat_density).

plot_precision_recall(opt_cut_b_g)

plot_sensitivity_specificity(opt_cut_b_g)

plot_roc(opt_cut_b_g)

All plot functions, except for the standard plot method that returns a composed plot, return ggplot objects than can be further modified. For example, changing labels, title, and the theme can be achieved this way:

p <- plot_x(opt_cut_b_g)
p + ggtitle("Distribution of dsi") + theme_minimal() + xlab("Depression score")

Flexible plotting function

Using plot_cutpointr any metric can be chosen to be plotted on the x- or y-axis and results of cutpointr() as well as roc() can be plotted. If a cutpointr object is to be plotted, it is thus irrelevant which metric function was chosen for cutpoint estimation. Any metric that can be calculated based on the ROC curve can be subsequently plotted as only the true / false positives / negatives over all cutpoints are needed. That way, not only the above plots can be produced, but also any combination of two metrics (or metric functions) and / or cutpoints. The built-in metric functions as well as user-defined functions or anonymous functions can be supplied to xvar and yvar. If bootstrapping was run, confidence intervals can be plotted around the y-variable. This is especially useful if the cutpoints, available in the cutpoints function, are placed on the x-axis. Note that confidence intervals can only be correctly plotted if the values of xvar are constant across bootstrap samples. For example, confidence intervals for TPR by FPR (a ROC curve) cannot be plotted easily, as the values of the false positive rate vary per bootstrap sample.

plot_cutpointr(opt_cut_b, xvar = cutpoints, yvar = sum_sens_spec, conf_lvl = 0.9)

plot_cutpointr(opt_cut_b, xvar = fpr, yvar = tpr, aspect_ratio = 1, conf_lvl = 0)

plot_cutpointr(opt_cut_b, xvar = cutpoint, yvar = tp, conf_lvl = 0.9) + geom_point()

Manual plotting

Since cutpointr returns a data.frame with the original data, bootstrap results, and the ROC curve in nested tibbles, these data can be conveniently extracted and plotted manually. The relevant nested tibbles are in the columns data, roc_curve and boot. The following is an example of accessing and plotting the grouped data.

opt_cut_b_g %>% 
    select(data, subgroup) %>% 
    unnest(cols = data) %>% 
    ggplot(aes(x = suicide, y = dsi)) + 
    geom_boxplot(alpha = 0.3) + facet_grid(~subgroup)

Benchmarks

To offer a comparison to established solutions, cutpointr will be benchmarked against optimal.cutpoints from the OptimalCutpoints package, ThresholdROC and custom functions based on the ROCR and pROC packages. By generating data of different sizes the benchmarks will offer a comparison of the scalability of the different solutions.

Using prediction and performance from the ROCR package and roc from the pROC package, we can write functions for computing the cutpoint that maximizes the sum of sensitivity and specificity. pROC has a built-in function to optimize a few metrics:

# Return cutpoint that maximizes the sum of sensitivity and specificiy
# ROCR package
rocr_sensspec <- function(x, class) {
    pred <- ROCR::prediction(x, class)
    perf <- ROCR::performance(pred, "sens", "spec")
    sens <- slot(perf, "y.values")[[1]]
    spec <- slot(perf, "x.values")[[1]]
    cut <- slot(perf, "alpha.values")[[1]]
    cut[which.max(sens + spec)]
}

# pROC package
proc_sensspec <- function(x, class) {
    r <- pROC::roc(class, x, algorithm = 2, levels = c(0, 1), direction = "<")
    pROC::coords(r, "best", ret="threshold", transpose = FALSE)[1]
}

The benchmarking will be carried out using the microbenchmark package and randomly generated data. The values of the x predictor variable are drawn from a normal distribution which leads to a lot more unique values than were encountered before in the suicide data. Accordingly, the search for an optimal cutpoint is much more demanding, if all possible cutpoints are evaluated.

Benchmarks are run for sample sizes of 100, 1000, 1e4, 1e5, 1e6, and 1e7. For low sample sizes cutpointr is slower than the other solutions. While this should be of low practical importance, cutpointr scales more favorably with increasing sample size. The speed disadvantage in small samples that leads to the lower limit of around 25ms is mainly due to the nesting of the original data and the results that makes the compact output of cutpointr possible. This observation is emphasized by the fact that cutpointr::roc is quite fast also in small samples. For sample sizes > 1e5 cutpointr is a little faster than the function based on ROCR and pROC. Both of these solutions are generally faster than OptimalCutpoints and ThresholdROC with the exception of small samples. OptimalCutpoints and ThresholdROC had to be excluded from benchmarks with more than 1e4 observations due to high memory requirements and/or excessive run times, rendering the use of these packages in larger samples impractical.

# ROCR package
rocr_roc <- function(x, class) {
    pred <- ROCR::prediction(x, class)
    perf <- ROCR::performance(pred, "sens", "spec")
    return(NULL)
}

# pROC package
proc_roc <- function(x, class) {
    r <- pROC::roc(class, x, algorithm = 2, levels = c(0, 1), direction = "<")
    return(NULL)
}

n task OptimalCutpoints ROCR ThresholdROC cutpointr pROC
1e+02 Cutpoint Estimation 2.288702 1.812802 1.194301 4.5018015 0.662101
1e+03 Cutpoint Estimation 45.056801 2.176401 36.239852 4.8394010 0.981001
1e+04 Cutpoint Estimation 2538.612001 5.667101 2503.801251 8.5662515 4.031701
1e+05 Cutpoint Estimation NA 43.118751 NA 45.3845010 37.150151
1e+06 Cutpoint Estimation NA 607.023851 NA 465.0032010 583.095000
1e+07 Cutpoint Estimation NA 7850.258700 NA 5467.3328010 7339.356101
1e+02 ROC curve calculation NA 1.732651 NA 0.7973505 0.447701
1e+03 ROC curve calculation NA 2.035852 NA 0.8593010 0.694802
1e+04 ROC curve calculation NA 5.662151 NA 1.8781510 3.658050
1e+05 ROC curve calculation NA 42.820852 NA 11.0992510 35.329301
1e+06 ROC curve calculation NA 612.471901 NA 159.8100505 610.433700
1e+07 ROC curve calculation NA 7806.385452 NA 2032.6935510 7081.897251
cutpointr/inst/CITATION0000644000176200001440000000121414066345362014422 0ustar liggesusersbibentry(bibtype = "Article", title = "{cutpointr}: Improved Estimation and Validation of Optimal Cutpoints in {R}", author = c(person(given = "Christian", family = "Thiele", email = "christian.thiele@fh-bielefeld.de"), person(given = "Gerrit", family = "Hirschfeld")), journal = "Journal of Statistical Software", year = "2021", volume = "98", number = "11", pages = "1--27", doi = "10.18637/jss.v098.i11", header = "To cite cutpointr in publications use:" )

YB9 3p ?ŁN8ǹL`9#pg=pZlCYg 5pYg %pY'I!@'g9pg )p'a:9 فz!2ȃη"O8g@5D8Gs8G쁳8an:kZ( 1ؽR3t5FtntKdHPueR.!$]כ)])]e%]߂+2tm28:C$?WTEbm)kqI]%I:qKյ%Ro/qژee]k{?>, !5U[nKuwu)]~"%ۘ24f~ YSI}yHP(]X}hJף$)]ɎKPWLl撮FgMҵA$]Wkc-]K#'UXW= k6C@)]/I}m%?CҵM``gk].b@blxSipQcNzRλYtmm.(]g{IH6fF!]Kڲ*SAQ0̎ҵic.It]\cNnEz3ڮۧt]';dIV'-]| k+>I׭WtfŶ gN{cW +u.ڦt=t=*0n%ۘ *zj+zϷyGw+3lS t$Q^JI^B},풒 օϋbmeKڒ-M4Μҵetm"bmtmuJșb uqkw)k$BJD:˔k|JyH[Jצ݂uquфI~kqt]]C tCAI6rHHI6fMII !]A̔AM*mSʐ뙙tmqKHK!$]mPʷm̫Jt4ttDt$zifNu*{QJXudUp^ $YLe&ĥ](*IH68YƜtm.as%lOP6K~!1k J+ {`JXIkk-]/q$]/e%]'Hz)%zj(zN ̔K3۔t=}Jt|k-]KS&OG&zh4"z(SҵF_.]C뮷w$=pqҵKt٬\LҵC &eҵl .]+uk¥ku}kO^}t=]Vҵ4 Wt- ".].]wݠʷK\tnu]V7ueHְGTۧ ̗J`N: x`_r(]|%lC-tmɐ`ӖP]˥ظm9!&(]إjӥiJCKJ\Mzp\ʣt#uCz.StN+uwIu̥ݮtݔu麩ͺtݪK&.][ɥ?Jז4I*;um.URvKR\ t]4s (].}t]nu?Υr'"wKyK:˻u^w[Ltv=st]:tM-]˭|u64~(].FҵLs:UMRNңkS]6~t}M/uu.][1lv}!]_ե=J-%SKWvtm@nci/- k چlc{֫P^%LLVuU\G׸\)j$m̗kЪץMzÕͼav!z3:4&fU9M"mY@Xf{]Mԧg\JyzVWQ62\\[6=lZ%ef9 ]&&.;7_bf`gz4gcNfJEzJ* =/УÒmNGf^`5ۇEGX٢OШjim_^bN.2֜nGg0`Tl~ݺF•TՄ?;U]ySOPAwv?; ҧ˓ .1_Xrz"/u}X1uW9?\槎$?t̷ ͏7r~|['||['||['||[﷜~-gG﷜o9?[Ύo9;z3-[B﷜rv~-g[z̷\jr~_׏w].}_w].}_w].}_wU_Q_a)QoHߢO'wyMGd 6~T}CDQ zMs|!}⇉_ty2+nM> t\Wn.z1qs.q.Rt>w#:򸠷A |q]zFL{%:E:Z}:|s;Nh>ǟ]`γ+@sr?'zPsY{8'a<Ӿh/^9S؛>x-<;fy#ph9[>{ 5777W)<77PQZ5>ϳg{eKgYb{n }wt챕kNNz$4LyGG/NjG KhI*}Y~+A}ڽ>~u}ݧmezbd]i3;56Ogcas[}lÇ i#&\MOԖpw%>",ټK>#&$O"P;7π;<r93b#;8] 7nteO|}}POlXlRO yefwx#[&T/T1jHEM9yE`tT>v&g Y e 7uniM"T鉚,ڡ[uzYCChz֯A`[P=LrJ4mHMOа\<ӡzLO?uS.!-rÉB\KFNv҄#.y:TDuK[K“;4SG|c]UAXC7uK>/vd!.›9KؒWcH5 9)l)+_M%^h\97$7$SդCx `r?<$;xKUC s!W %Ē?;dYu2[$ W6JjM=ĒܦC3ń>ܾ: O2㹛W}2}7dm:ev)sש4u #y2|[<6)Aqd(.,u8Ȑ iS`} uχ8Td6-\UbsGo{8(,oPYp)P(0c*ܹChg6:2*A∩e76= q$q̧SGoD8b"A 3'8LnS: e; dBv*)5'ҳ&-3= |1ߧi/hsx}8ge8qg6 +3: ل;}gIS卂5[~gKo_zq{*܏ O#!w헹QsZ 6 bЀ8rpӱYR7IHpB1 8b~Ǜ?MWX&3G;1; G5a}PG'౿G .Fl:ώcB"Ώi "IY#{qvmbwJxí u*_(%ɰ .5 ĜR>%5I6lIu6hS0tbb&. tEx?醰P'c75}*?..N~ _;[k59On_awc:81|󳿙HV}~ܦrN9Cd.ˑD/6s?i|0qpq=_=|w|> -=f͕ӂӦoI;6%U܅7]9XV2̩Sׂb<} ,yY8-zEEڷS-k1?82 WD8~\PYJ Z Cg+ B,t~8xW-;8_wa5]C U^u3b t:|l ?YMZƟ}[gIsTmC'}00kmM`~/:ּ 2/t=}cA3'N ?vh9'o3f?}^sacݟ76i8s<熍7<5w,06lM~L#eP߷6lM;[׵2ٷq6l-6/ۃ7\_7lUkb2Cbk/0ӃT5 䍿o\c/Ö*w_0U{ /^2/߱e 80 ~-͔ :͏^:xkXo?O0eo _߬S߽&ILc/7[o/n X+gu|"Ø2=]4|zd21>9ɛZdLkmx>ϔɯa'_`5 O'o!2&h%l>ްŌawsLG4Dž@u_0pZZo*S_#Ry^_y4k|o/#1@,ɟ:52 VM% Pͳ_2d f1af} ZrIO$0קIe?{xaDx g.6Vy tnd?> |ϟ\05ٰVA|#i'o\(%V[s]5MbxpWa25n\1PiK"ŴSlZF$\/pcL/ 31i;ˣ_o%l6޹ibݯ4!E\ɯ姙v@7r%ׇҜS} : J=|0Oav{rCOzd7[^ecMKy aK*V5>˃$O^_'oËЬ=N/Hp|aރy{ d*=O|ȟ_11`3%Ƿ))K_~(fX|V_||]aƧ?~~h>lKޗu3}S͒KGKJS/lIUO3օ3Q咬/[惙 q,OxaAZR_~$iX19o$o?1Iˣ{gLzKSɜCq~R_fhz4^+}Z9[e?M.Y2 KㅂD_>/0a]mYZH5ʅ? cs_UU-0/TNOJ-0'j̼>4dWfsW}N+Sҟ6. ^Y2Ǐ{ɰx򚑍h4fY;{W\cp* k 1d.;jz'l132{U'1:GdyDGdG{dG.U'l1s52\#s52\qs 92Ȝ#s92Ȝ"s)2Ȝ"3"18a9d05gdyFfNcp`yDGdG{dC1?a5kdFkdD1;a9_gp92Ȝ#s92Ȝ"s̘0) |E+03Yp“cp`Y\bpyDGdyD{dcu"s-2"s52\#s52#y\"3'180Ȝ#s92Ȝ#s)2Ȝ"3' WdwgOzOf&Ox23]s f ',18<"#2<"=2#30 a鄁E[dnFkdr sINbp9sdΑ9GsdN9Et*u9_g|E+2_:%Z`}sP.Ngyj [ .18<"#2<"=2?( ',18"sq]qXF]qXRNXbpΣ+ޱ+ޱ+ޱ00ǽc:a9ޱ+ޱ+ޱ+ޱ+ޱndqXNbpΣ3;ޱ3;ޱ3;ޱt=0;ޱꝰAg;vƽcg;vƽcg;vƽcg;vƽcg;kd{θw{θw{θw{θw{z[-bp`{θw{θw{θw{θw֡Oqqqqqq1"s;vĽcLjqqqqqX!8a%ޱ#;ޱ#;ޱ#;ޱ#;ޱ#;ޱ\3w{rA K qqqqX.9a5|2y K 32<#32<"#2<"sMVNÆZvs-2"s-2\#sawY??=iH:OII*h<ok{O$o~|V';t0K_}v:YIXj?ӖoDD!"t'['ΤJQo/HDLWz9%xz쥩"qi.JP= +@h؃]?Mw0 NZ`4[t _ dxDc) 0vM}OЦnD `T% e]I;L{K?/n Z0D]dX_Lw `U%QeXt:}po>miN \ /W&-|k0dkM[& > s*l"nn.^pr"l$ٻ;I&.CE\t(r$`vT&KJ.!r2vn0Q< O&Q 2MMZ27;$zhYL6x6!D&|HF@w 0<(Rw/|PK1 /?a0LM|u|M\4Xh pM6`OJli0&m&L>T>0x&kO2=,K czQ\8MDX&&ߡ'M}7I?I&rL&Y[T ]e2\ML_`ak1R[&{_`0X{H^irѿ/h /7`"hf ޿G K!h(ڻMEm7"c+7~ <> Sn `_.pndhd$l"}M48Mm<3M? 544/QȀi-z$F1ޏ|_pNg*LMo\!c6E|/Y~493~eI6h6~Z$D_`zlw;45a/nz? 1}v~|'|'|'|'|'|'|'|'|'|'|'|'|_r8W+ wB]!W+?+ wB]!6 wB\]!W+ą wB\]!Bce;sjEiJ?d8[>N7!|s~3\0y8W mj}}ر9? q>|h|/̐2oC9N#y87|?ן1c<|9RS~,_X?#x6O[)J_\_Rx=#O'|!><9l/^˧ =Mv߿}=-zqq\%w>l35H/??( }*m}D~~0Y,/?@?G@|?d7f=j~?{f=΂inVEA 䯾v3<nod;}|#Ė`Ώ=G'Dх%zÂqĎ_ОUl^Ṳِٟ'9L?L:3z"f*~k9O}b*r'+VK-ü~\9nV&'zjvPofsO(Gs۟?~s>?ꇏ_"}y\c~8~›ddK~o/~__wqb>wտC?7?M1q,Rs¥__/}G]o??takR֯%7e;vɓ\Ϟ+_\Ӈ5b>l}׮p5~o_4j^.b1UD? 'bqG Fgp~㸌wgQT;Br;|v_ysY1.)3#]DtHv\XY~֩;X<,]AC!q&=By61Rh~w!}s$dʄJmsKx V67Lυob~xn_|3]Y3uߋ e@+"{s/?W:7/t%:Wsu۽Xk5S4Kҿy[:)U׷0 a:0txQ,8_ 5ʱ/=qcǭP/Kn1z0=r]K{?sI/ˍj==Í5ޯO5)\v\K0<¶w.ygd~x^g<~}#S+O#*qZaaZӊ00'6]5+)l*g<7誙:S<7J8ݟ2?ֱ&<_//#GSmer`FbW{̛{[z{&,Ҟ.m?8qf֣Zt\-rOe <4ȦUkv3T7 l_^3C&y 2r}`n2^=3Gҷ^v&,jw#N\~DiNr&{J;u_+Wti_ViN\\bO7<10c|͸}lj꟯~Bendstream endobj 59 0 obj << /Type /Page /Parent 3 0 R /Contents 60 0 R /Resources 4 0 R >> endobj 60 0 obj << /Length 11120 /Filter /FlateDecode >> stream x}M6r^VQDDw)/Z72 -=ՓJǃE#&%A[}sß_v<-ǘoD#_z?n᣷Ƿoˆ:nx}a>_C}:}0SyVPn==pKk栏~=㱤wJ!D7!G ?=ZK5H02=rL|XC&kf GCHA(Sl#`Ci?&M@(\s:OH96+2{#Y^. Mt=oTJ*#I!Ɩ08)=梐Fp c=K37A 3'd f\dqʅkg(4 cQEayz -cUdc1DP8cW8zI8`NǡmBxlof4ڊhC8ؔ(,|׍ ܷrL"̣2)d)+dB0 sEw0˂B9< 2P̣ЄFa^wʀ<.s 3g2 faBf~%I  yGM$̣60ٛBfN9^-[oʁo?3":ui&AOO&=Xypϋ"%jR48kspI68*hp"gPus|<-t6j a:joZz j-àFE&zjI]jWkoƆjsNzjh93QDL:Q[ESVQwEM5`u^ԀQFjԱQFulԸQSGusQoG-?3/= _@og~ R=@?:~7}+?Ao Vӂ}2A zo> }@BOw$+ SBzW+x }\Bz,gs>5 }jaC9ӡ}ۇ?3D"ѻ^IQD%z:IDO'= SZN=E_*zV-gpY=Eo-zyk9}FϱUqgFgi9 8 8 8 8 8 8+pVYS=8nP "-g 83pf%L)ei9#pF3g8pJA"-d9<rjAS d !r6 Dfi9 8 8 8 8 8 8+pVR)2DFEMAdSw&}-L[P CcO=::1SC<}CCE Pi|MœuZggP=Ƚzꡬ3CS>9P6LycLs+31}y 8Or&%reꨤ^-)EՔU mTr5i^B[\hky}.υ>ڧ[>i>-ڧ[pk>{{g^1{Z ek-Zp/[=^V^B{څ ek.U^vlB{څ ekek/]h/[^vek}Q&/[2wQ.E(]y].\he.2EvQvQB(s].\he*EE L wQ(]i.ʴpeZ2-(Ջ>y>]U7 sV]g="->Elܞ[UʄܪkLUϭ:q=hUdޙ𻙿wn[slpW8 3"8#B-ssh(2 >[Cvg= @vnUa[E98cMdMsW; ?n9s<^}nO/\AvC[c끭a۪[cc۫;*q(u{F pl !唜}nT΂b{;^}dcUv_*v_*\}؟b[2쮂iQk d;[CjUk9scs9oؒ9ۖ=f[|;jRu$N?_zVW'~L|/Zy㾲yIg.뒲|ߑ_ؿԑO̓N~C!f]LdHE(68rFLl"Έ\Igu2]Kَ@fA}AzH:b:@ɒFm_ Fp~0mө|5btIrW)XiA{M&gBt|•}]>xǭ01ZX|c9=V&1aNz[]xU@~]dA9Ch{g&OI{c~x磨?>s 7cB/.c81󇶰Hb>>MyY]}; 7}{q<}yOb߱0?eu1슋dPG?~bOi1@qU#]j3sff>pQ(@?'AQ%qvy+CS$NI 9'f~v?tR)Rr^g1A9S|8E?N5qU;޾Ud~<A ubOj$]1?#x?:*:Kzò S& }M)A:VXC!i#.<}3b&n?` -NTlXRa $$x[PnkJzFt }t 6N(6GM b@(6 b@(6 b@(6P,@(6BPl BPl YBPl /@(6 b@(6 b@(6 bølrPl`p``FPlh(64 v4 W fؓ& .\1Qlh(64 vlC3 .\1Qlh(64 ņbCCPlЦ} ņ Plh(64 ņbCCPl`Jh; ^  (6t: ņbCGQl`+KX0bMw: ņbCGQl(6t 3v: cs$bC%{A+2Wd\"3!3„ !sC 27dܑ#sG]d fa9 s@2{0202'dNȜ9!sB32gdWI!0d.<0ap```\"sEUҵ'$d&d&[X0027dnܐ!sC;2w.02)2 s@2#2„ 9!sB 2'dȜ9d``f 2d.\ sA+2Wd\y܃ 020i a007dnܐ!sC% ba/ef  & 2d8y#-,L 2'dNȜ9!s@`Nq}$('T9IQNr2Ϝ2'9qIoNsA's""LDL'q:i N- n-<[g l-³[xp n-<[g l-³[xp n-<[g l-o-<=(ϼb- ^[p/xm^½൅{k - ^[p/xm^½൅{k - ^[p/x}½^½൅{k Dz.<ޅǻx]x w.<ޅǻ]xl.n.W&YOW?ce}w.A4 sB=vm)vWolg. kv]5Gx~?`lڮ<_|_`)vV`eqm׹:쟺[v'4>}*OGx|>߇KF_NI{w#kX]B՝}p5Δǫ/Ɋk.?^»mWܿ+Kr|:SK{_Y㙶^gc۷#n ?N8`'-ϓl{7۳LX/p6܇9t?o bI>y>ﻇGCCa#^N?˫l[X[][kVEVzk: &&,ߟ89[?Y4s;8k{v1\{3DQC].cMhv\'4u|nCˠ/d/sK:k3ޏWUfjo2ם wsW1t& 9pTE9ѝ wΜsڇ=sok?]8~ELl#d&"5\yzFLlo߾3ʾ1iW}%Ś^ܓetT.#M,ѮЮhӖoꈺ5`mΙzY'CLHkf{]ܮ}uc6 ݌WGwx?>^_`BSI/}S/xs?I~?|_ܾ~hi4qݏ?|ooo~f j26QkuȞݯ7~$W (1)\8IQnQKR )CM>ﷅM,&fy?-,f Ǩ%gHuM8k6q9ĕ5 S :󘴤ya-3x_]JpZҚ\ -6?Q/-%9I=ay,t8Kjs1`)2p$=>'y~1Ȗ I ;މf'MKd_;w`yfgmgFӣ5Wz1=u\)NAuozo'5AH>ٜMmٗđ%HF=M9ǑX#{鿤W~՚FH97iĊiL#VL+`1#pZӈӊD` MSYI۽㬜ߛ:g&6n2?~A۫|W_~GCyQٿLr7ȼɵro.Nl> endobj 62 0 obj << /Length 1729 /Filter /FlateDecode >> stream xYKo7>sI^mAEc=9](e7Swc(+JЃW%9odd_?oc eUďO޽Tֱûl$ vqvy[ֱO`7d ~5k˃gZ YKf$|,Zϸm/%n[k[)³A]p2(>ʦr(4 ^5@#M>d=w%KY(#H݁b^Ha,זXeb '26{f+ D3 nLUD^ŕ5JPs "4\3\lRVR.-g"g::vY (N[t 9 UY_IQYeAh(Ga :4`C^)@kedk.lKnl,v)t,vit,v)|,vi|,v),vïȌ pGH"ݖs ABcYSlZ"m Y܁JH=/-3G7T J^Nl䮷g˞_t7_u6"Ҿ=S3xc!D[xN)2tuE/{4l[vRnp EV۞/%TrqLqQwd㪧963#ǯӱ竇g)bG-'6¢ d,hu#u7tJP9}V$Nб+gz4ϐR4͐R4ːR]'Ii9{%],s0 1DyzЋ\LAPv?;!)GagXiT ;Z.Vmvf'k8(˝H? ME}) ZSѺʮ%VvE-skt4tO_Kct4vOOb3eыtk˺>c4}uS57[::77<f59?|;ekOoO?LvF u A7=>/V? qSsO[~|Zy8_̗d0/0`'ϫe;_/1X_&K!քi,nnn,'UWyWvrpcꍮ}._YPbVA%C5զqrY5^t[r*7j,S @ t$m,Hx}(2 P&#Ca+"1zeXgLmA]+{G"OCL#XezSrP mA Z@P;9f 5NK#*CAu71FXk $i=)M-cQw#:Sۗ;[ߍq+cgZk:C>b o/p~{0G_ n(m)Jw:s?n׹u.8NuBݦzG0r$DO}xE5>" xW.(irPaAt .fD`X]pbt;q Fbb00!Vendstream endobj 63 0 obj << /Type /Page /Parent 3 0 R /Contents 64 0 R /Resources 4 0 R >> endobj 64 0 obj << /Length 1728 /Filter /FlateDecode >> stream xYKo7>sI^mAEc=9](e7Swc(+JЃW%9odd_?BCY?0--w/un9- js9C`]\n]^ug& 2ȴ_yy9u֠MDk!"w P&g")RA(n-bF  {؊2E6ކ@ zG(wuP{oQ;(Sh A"^䔲#TlBuP02EH P$oFb?)"rY&zM1Dm@PPfM̴Ѱ2}a2I%FOzCX݈whJXp(Z<ΐOطy[#n%! G+!BjzGJ[ҝ܏yunoKa*S]~+ QS(ħ>^DO}>^╇)K0 F`X]paAt .DtnLN:P4ЏN:Ej3^ĺDcVc.2> endobj 66 0 obj << /Length 1729 /Filter /FlateDecode >> stream xYKo7>sI^mAEc=9](e7Swc(+JЃW%9odd_?oc eUďO޽Tֱûl$ vqvy[ֱO`7d ~5k˃gZ YKf$|,Zϸm/%n[k[)³A]p2(>ʦr(4 ^5@#M>d=w%KY(#H݁b^Ha,זXeb '26{f+ D3 nLUD^ŕ5JPs "4\3\lRVR.-g"g::vY (N[t 9 UY_IQYeAh(Ga :4`C^)@kedk.lKnl,v)t,vit,v)|,vi|,v),vïȌ pGH"ݖs ABcYSlZ"m Y܁JH=/-3G7T J^Nl䮷g˞_t7_u6"Ҿ=S3xc!D[xN)2tuE/{4l[vRnp EV۞/%TrqLqQwd㪧963#ǯӱ竇g)bG-'6¢ d,hu#u7tJP9}V$Nб+gz4ϐR4͐R4ːR]'Ii9{%],s0 1DyzЋ\LAPv?;!)GagXiT ;Z.Vmvf'k8(˝H? ME}) ZSѺʮ%VvE-skt4tO_Kct4vOOb3eыtk˺>c4}uS57[::77<f59?|;ekOoO?LvF u A7=>/V? qSsO[~|Zy8_̗d0/0`'ϫe;_/1X_&K!քi,nnn,'UWyWvrpcꍮ}._YPbVA%C5զqrY5^t[r*7j,S @ t$m,Hx}(2 P&#Ca+"1zeXgLmA]+{G"OCL#XezSrP mA Z@P;9f 5NK#*CAu71FXk $i=)M-cQw#:Sۗ;[ߍq+cgZk:C>b o/p~{0G_ n(m)Jw:s?n׹u.8NuBݦzG0r$DO}xE5>" xW.(irPaAt .fD`X]pbt;q Fbb00!Vendstream endobj 67 0 obj << /Type /Page /Parent 3 0 R /Contents 68 0 R /Resources 4 0 R >> endobj 68 0 obj << /Length 1728 /Filter /FlateDecode >> stream xYKo7>sI^mAEc=9](e7Swc(+JЃW%9odd_?BCY?0--w/un9- js9C`]\n]^ug& 2ȴ_yy9u֠MDk!"w P&g")RA(n-bF  {؊2E6ކ@ zG(wuP{oQ;(Sh A"^䔲#TlBuP02EH P$oFb?)"rY&zM1Dm@PPfM̴Ѱ2}a2I%FOzCX݈whJXp(Z<ΐOطy[#n%! G+!BjzGJ[ҝ܏yunoKa*S]~+ QS(ħ>^DO}>^╇)K0 F`X]paAt .DtnLN:P4ЏN:Ej3^ĺDcVc.2> endobj 70 0 obj << /Length 1729 /Filter /FlateDecode >> stream xYKo7>sI^mAEc=9](e7Swc(+JЃW%9odd_?oc eUďO޽Tֱûl$ vqvy[ֱO`7d ~5k˃gZ YKf$|,Zϸm/%n[k[)³A]p2(>ʦr(4 ^5@#M>d=w%KY(#H݁b^Ha,זXeb '26{f+ D3 nLUD^ŕ5JPs "4\3\lRVR.-g"g::vY (N[t 9 UY_IQYeAh(Ga :4`C^)@kedk.lKnl,v)t,vit,v)|,vi|,v),vïȌ pGH"ݖs ABcYSlZ"m Y܁JH=/-3G7T J^Nl䮷g˞_t7_u6"Ҿ=S3xc!D[xN)2tuE/{4l[vRnp EV۞/%TrqLqQwd㪧963#ǯӱ竇g)bG-'6¢ d,hu#u7tJP9}V$Nб+gz4ϐR4͐R4ːR]'Ii9{%],s0 1DyzЋ\LAPv?;!)GagXiT ;Z.Vmvf'k8(˝H? ME}) ZSѺʮ%VvE-skt4tO_Kct4vOOb3eыtk˺>c4}uS57[::77<f59?|;ekOoO?LvF u A7=>/V? qSsO[~|Zy8_̗d0/0`'ϫe;_/1X_&K!քi,nnn,'UWyWvrpcꍮ}._YPbVA%C5զqrY5^t[r*7j,S @ t$m,Hx}(2 P&#Ca+"1zeXgLmA]+{G"OCL#XezSrP mA Z@P;9f 5NK#*CAu71FXk $i=)M-cQw#:Sۗ;[ߍq+cgZk:C>b o/p~{0G_ n(m)Jw:s?n׹u.8NuBݦzG0r$DO}xE5>" xW.(irPaAt .fD`X]pbt;q Fbb00!Vendstream endobj 71 0 obj << /Type /Page /Parent 3 0 R /Contents 72 0 R /Resources 4 0 R >> endobj 72 0 obj << /Length 1728 /Filter /FlateDecode >> stream xYKo7>sI^mAEc=9](e7Swc(+JЃW%9odd_?BCY?0--w/un9- js9C`]\n]^ug& 2ȴ_yy9u֠MDk!"w P&g")RA(n-bF  {؊2E6ކ@ zG(wuP{oQ;(Sh A"^䔲#TlBuP02EH P$oFb?)"rY&zM1Dm@PPfM̴Ѱ2}a2I%FOzCX݈whJXp(Z<ΐOطy[#n%! G+!BjzGJ[ҝ܏yunoKa*S]~+ QS(ħ>^DO}>^╇)K0 F`X]paAt .DtnLN:P4ЏN:Ej3^ĺDcVc.2> endobj 74 0 obj << /Length 1945 /Filter /FlateDecode >> stream xYMo7 Wb+V`ء!sEtuڡ~*;qCyE)kFhIBIa^9B)/^ߛŋ/r V?7K"ګ-W(]{/ }Z:$]VˬE6ᴗޡ]v,IZMZBd5|8/B*#ANxy*Fc늜2"Qń8'UbbmԦ+iIYdb!8֢61sf1sf񚙋0)v} 1uCj$!Xqn `\a8ełAؘe]1p!,d'eYe%rB}4ܾʒZOHU#Kk+(0A|8h+ؽvo8 r}?l/]lNދ7̈́Yz5Î .1blT_MOQ|5)/XS)J.2c`,PCCWq'}b悚 ԐN!yڰ zqU~VyfGsO'5;`r~N?WAJR?5!e.?ıŰpR)[Z6Zxށa 22< 0s*}1:E^g^:c|y=;@m=#Oz'vS2@r;0z)w2EouK!:ϐ;gn#h=y-I)оAų˯D{lLhjGYeyfWf8^QU).5iMbmT@f60-MLm>RQ-5Yx9Rf+?|-1z)g9C8EK /ַcJSn)yOɺ2=%Ƙ\"BGW~?4S&yAlI% tOمWPx.N?_,WWۺ2vszqYݬm8Fߴ{༥WЍaccFgϮf)Wv'endstream endobj 75 0 obj << /Type /Page /Parent 3 0 R /Contents 76 0 R /Resources 4 0 R >> endobj 76 0 obj << /Length 1946 /Filter /FlateDecode >> stream xYMo7 Wb+V`ء!sEtuڡ~*;u_1("e-->J*E ~yS\/^>5>7_fAnDW[h~_wPb|\}]]gKjF 2{V2#E]ގ%;K)R+^hL`AHк*?<#uEE\(CbBL̪ 16Jjr´夬W2k^K3s1sf񚙋0)v} 1uCj$!Xqn `\a8ełAؘe]1p!,d'eYe%rB}4ܾʒZOHU#Kk+(0A|sqqVz'I{700 ˽{9d{r8{Lxe/|w)Ax~_=2z*FդWR^M 1$9tռgo`p'6;j.@ i|j z]g5;av47tRA.xP<­t*# QXc8] :-+bkmEa8 /3328|w3y^Sm]>u\3FzؓԆso?wB;_i7:p(sXh!GcQ ^oKr'SVg~3 yәxqn>9ֳa kH"ޛ+h^<;rK&;a:@CV38*˛/׷2W\Kqh%|]ϯ82cU_nW7עobyuH`YUTMp&gRO-Nu-ϫfW| v3lLl^@qnIȩ4B_2}ztfI*ȩKF cC`Tض: ֔[Ψd*C_a3f€r13oN;b΀/ #4:ڡg 0g@I1s@2a΀(]XG|us%9#q0f?œcŌ) HKPJㅭ5O 45䞮b؊ʻ]!kc59t}wAĮsWyիz// m_v bI:+ ,n 2쾔*80_,٠G,6)<0H?xnx#[^w)esΧO9rF˟s>=+Sdo}'yOɺ1=%Ƙ+cNSn)y?%."tt_C:ihY(jrGtΖ:?\RmA]HQ~E qrZn嘽 4V+vu1}؃-0n  6:Gj,m7endstream endobj 77 0 obj << /Type /Page /Parent 3 0 R /Contents 78 0 R /Resources 4 0 R >> endobj 78 0 obj << /Length 2329 /Filter /FlateDecode >> stream xZIo\7Q:\m$A  C"KAbI 離[J-AbkJ qxE/c_ΌA\>.4p)q}<[vk,~](y'д-C_M%^ _ y˚5o{)HHT6KB['cnfqVL02P`C4Jq[sQ&G䘥I\#k^!g0V:; Ӗ(c-PL܂ơ q  8c3T .Hz b d^\#g%䂸um`=. YgBCz89KK1`m Br@ñ=J3sVkOa$a:"'夌s)i2':"*H[Ɍisi\atJF :+l { ,٠0A5׫imU3c !Ђdb6qqCa; QwQx뛎h,M䷅è,s`aJ稘8@y ҈2T#WGRg(pckn.y즹&1]M/s/jR0psT\8j(@.WqBňrcz 9&+|خA>oUcs9ZٰPpN@\- )p/*5h7%TyӼ(%-ֿAU \/4Uo"B7͉nW6ҡ9av;sq^ %k*IkZ؇gmH^ ]/>7f${S_C&ۃ`X 9oTYp~4IWd[o[va)Rqrx8Txw_T^ZxnZI~ӽ(^1F-wh`EFMi!Xܹ>GWqm6 RLK{4>RoOVt:ìiaEM4Kw*=̇®tһ!qWt s(a.#5CyjjjZH\Pg̙Uu_AS?k~iGq~iGT޿љTGk uduN)G5KiY ?sL`tAt.:t:vJk[0,,Wʾ~[Y1ZӦx{Dڣ7~y$.>ǧdPR ??-DqgBR-[jʘh?}zT_E]˝{_`4dscAdV8r4ŚUKbQ;uDЖƋMkIU%r#N78Gywᮿ@X, sWz[i;rޞI*_lYƒmE&Bd;6!zwᮿh26VL7"yۺi(ˡ'͂!NnZbޱQU4em jψJjp۫AeP&+±:Xʭf1tTZ33p2y Ec5ر[ `8vqqCuliz)[sHEj /hD6Ls^TGCƝ Av :LWrq6g:2ۜGls-͙zӽg4kєzy|cv*`j'?{\>-^3ql~,Z_KsG蓱j ~sQGHenW{ I k#ڐ?zn7wT'uЧ\4jmG ,BKAP@iL 7P;LW^!ඏk > endobj 80 0 obj << /Length 1945 /Filter /FlateDecode >> stream xYMo7 Wb+V`ء!sEtuڡ~*;qCyE)kFhIBIa^9B)/^ߛŋ/r V?7K"ګ-W(]{/ }Z:$]VˬE6ᴗޡ]v,IZMZBd5|8/B*#ANxy*Fc늜2"Qń8'UbbmԦ+iIYdb!8֢61sf1sf񚙋0)v} 1uCj$!Xqn `\a8ełAؘe]1p!,d'eYe%rB}4ܾʒZOHU#Kk+(0A|8h+ؽvo8 r}?l/]lNދ7̈́Yz5Î .1blT_MOQ|5)/XS)J.2c`,PCCWq'}b悚 ԐN!yڰ zqU~VyfGsO'5;`r~N?WAJR?5!e.?ıŰpR)[Z6Zxށa 22< 0s*}1:E^g^:c|y=;@m=#Oz'vS2@r;0z)w2EouK!:ϐ;gn#h=y-I)оAų˯D{lLhjGYeyfWf8^QU).5iMbmT@f60-MLm>RQ-5Yx9Rf+?|-1z)g9C8EK /ַcJSn)yOɺ2=%Ƙ\"BGW~?4S&yAlI% tOمWPx.N?_,WWۺ2vszqYݬm8Fߴ{༥WЍaccFgϮf)Wv'endstream endobj 81 0 obj << /Type /Page /Parent 3 0 R /Contents 82 0 R /Resources 4 0 R >> endobj 82 0 obj << /Length 1944 /Filter /FlateDecode >> stream xYMo7 Wb+V`ء!sEtuڡ~*;q_1("e-->J*E ~y˅S\-^>5>7_fAnDW[h~_wPB7E_:$]VˬE6ᴗޡ]/v,IZMZBd5|8?0UF֝P 8!A >e+r.8FrbdV]LQR.-'e-XZE ~Ȏ03x\LKTX8%i5Ūtkdd"y. Du, Ƅ/.벌 a& =Y.wȂ]./ ,qUzEYZ[sԩ`6페wG =,(#E#:VVZ Na\4\F1,Y3*f !@,Fcf+ hr2pg:tQUYC{f9r$f9rWFDz rSqN ȗ []rq2$\!'VyCb.Xv V!`Wi=fRP-uO軍67_N@e0/ZެD|9LΤ/W.>_l;յ<]sl f٘t~B@Sid :w ͒^U@_S9| :Ƃ3muA1)QqTP ugcf 3ޜvFŜg_2A1fGh %vuC"[;axcց ZefœQbTq2rK1sF3an?6~9sNJ7[SԝA )P.ҕ-aa. [k,- hj=]ֱwBjr]W^.^nھ6*"-ĐtW8Y49e})Up*]axXӿXAo+,:#XlXS 0y`DvxcOQ\3֤]!FtmnShZ>xnx#[^w)esΧO9rF˟s>=+Sdo}+yOɺ1=%Ƙ+cNSn)y?%."tt_C:ihY(jrGtΖ:?\RmA]HQ~E rq\|1{/ʙinW:WۖcM- [ja~66@mt,-v'endstream endobj 83 0 obj << /Type /Page /Parent 3 0 R /Contents 84 0 R /Resources 4 0 R >> endobj 84 0 obj << /Length 1954 /Filter /FlateDecode >> stream xYn[7+a~lAEc]YS(4rR;cHd8Kr85>7_fnDW[h~_wPB7i~]fKjF 2;d6F'}wJJz;nMJKz3\VB*#aԝP 8!A >i+r.9Fr7bdVLQRn%z% 10ssa.#yb/!6")I;AOVe{ 'X%#sAFuY'Ƭ3> m6&x Ye 6lr62,v[@X>ja_mKHUwV?T`-($V By+0p MG҈ڇVVZ Aa\4\FA1,y3*f a^*.\ Vw*dnFa wEs:!svg#=a똪FcS N ȧ K_rq2`T9}b{.!a2F#!ྯ֌k̬Pm3< ӗ^@P(07ųqifzK~ٽv8s}?.6'ٛL{zNaG (F)W\l$_S1{5󔊱ԫy&6iX زy2:3$ rE?pWOݷ!\a߆l{4xԆm򧏧zUg5;hnf's'*$1x= űR1){\ 6Dށa 2ܳ s*ncF9uʭs=?u-<y;䯴Z@HY9-P qϷ%O)~3] {ԙxLW<}p;aAٱ5>Z{}͋g_/x~Yg(v.e\|Ty+z܌>-O h\(r*C^#]^R +r*/ᒧX3s135V3*.Jp]7l}F/ @N1ap:igTp%cPa>wBds'>7aȠUf!p%J(a? OA321s9y`#l+f ^o;FcK S&fXaŲ%96NJ1=6-!zwcRf#m[r-;b$w%@N7p}ä / N* k?Vk,z<\g\<;vDcO%QB3V!F @eJk ۤ&1:ڷHI|d=zg=%e+rFYO笧sC8Ikڰ%ޓX7$ޓX7$ޓXW,ޓX7$Or cE|?tYPo: I zMlЩ%ZotOY; ˯h8|\}\-W7o嘵< /8afu8ak}}X-0j  :{V5+vendstream endobj 85 0 obj << /Type /Page /Parent 3 0 R /Contents 86 0 R /Resources 4 0 R >> endobj 86 0 obj << /Length 1954 /Filter /FlateDecode >> stream xYn[7+Lf~lAEc]YS(4rR;cHBW8Kr89_[rCy4wB;_i5:(sh[(@QoKr'SVg~3 {әx n>ֳc k|е&%A ί\N(v.e> endobj 88 0 obj << /Length 2339 /Filter /FlateDecode >> stream xZIoc7Whp_H40Ll`A𖶝T,ɒ-c~ݟ,J>-> -9O(0I'7\2RW.(|X|OaK |XlQwB45}6IDPR{~2sV2#EWHIoNJڊfiYhd _/* F3* 6y`|FUT\9fiR'Zii}W9ôe1l dU?܂rC#-x0P12 u-M7y5rA wk@qa0:b`.ɑSkS`mqWX x % )8-'eHH9 v'࿌QAD߂Mf$-ML L CS2OpYaTT3hpͬFgՀ!-!Y5LkR43HC >`|(Y8{Aa/ QwQx盎h,M䷅è,s`aJ稘8 dL #ÒF41mB`=:C[us u#`704W0׋w%75KYrQq2r((F䯐3@#W0_;v zy-~SthۈPĕs ~m NOǀ{QIF-5B27 63MELmD(t1mzZ:4'hLQYE855-ó1u$~ٛ` x=)ί MӢۃ`X 9o7TYp~e/{io|~hoJSSqoҼsJ}E\4*o5FoѨ`E#O,:7Ho˜v Y &lU~a 1A }`WPC2{KL ZԆ9S-d25ΫV4T䰢yjN%λXZJG_aW:gk @k 8M+ xv`P9\a.ϡ<EWm@Q i"@u&ȜI48Zo_ Ks8z4OKs8z4OoƠU&PDgR9:P:uN) ٣4,9&QIt0: t:~:c/Jk[0,,Wʾ~Y1Zq[=⒫ڡʾ,qusq-OwGqqY|^=<~=)2VZquw+*&Q MSl)cZ|0˶S}ufw ^G&Ӑz#ϝ N&&'~V8v4ŚU@3-8 )3 a?.khI;Nx?e+w OwY.p̫y/2*N_,ew@Y6]DٌgNW]"zwΥHBci f -LhJ|޸CO 7_C𵆓c)b!`4=LgV=p `PYK,yMA ,'Ul  Pc=Эr0` pCuliz 4 A#ՎA_WiDJ40?tlܫtY*'ciލotz?F!O~nl&O&M#O #*=Ռu)X{ -A-]&h@'X`rx-p&'& ǡIzsu*w.o.^89<Nh=62/?endstream endobj 89 0 obj << /Type /Page /Parent 3 0 R /Contents 90 0 R /Resources 4 0 R >> endobj 90 0 obj << /Length 2339 /Filter /FlateDecode >> stream xZIoc7Whp_H40Ll`A𖶝T,ɒ-c~ݟ,J>-> -9O(0I'7\2RW.(|X|OaK |XlQwB45}6IDPR{~2sV2#EWHIoNJڊfiYhd _/* F3* 6y`|FUT\9fiR'Zii}W9ôe1l dU?܂rC#-x0P12 u-M7y5rA wk@qa0:b`.ɑSkS`mqWX x % )8-'eHH9 v'࿌QAD߂Mf$-ML L CS2OpYaTT3hpͬFgՀ!-!Y5LkR43HC >`|(Y8{Aa/ QwQx盎h,M䷅è,s`aJ稘8 dL #ÒF41mB`=:C[us u#`704W0׋w%75KYrQq2r((F䯐3@#W0_;v zy-~SthۈPĕs ~m NOǀ{QIF-5B27 63MELmD(t1mzZ:4'hLQYE855-ó1u$~ٛ` x=)ί MӢۃ`X 9o7TYp~e/{io|~hoJSSqoҼsJ}E\4*o5FoѨ`E#O,:7Ho˜v Y &lU~a 1A }`WPC2{KL ZԆ9S-d25ΫV4T䰢yjN%λXZJG_aW:gk @k 8M+ xv`P9\a.ϡ<EWm@Q i"@u&ȜI48Zo_ Ks8z4OKs8z4OoƠU&PDgR9:P:uN) ٣4,9&QIt0: t:~:c/Jk[0,,Wʾ~Y1Zq[=⒫ڡʾ,qusq-OwGqqY|^=<~=)2VZquw+*&Q MSl)cZ|0˶S}ufw ^G&Ӑz#ϝ N&&'~V8v4ŚU@3-8 )3 a?.khI;Nx?e+w OwY.p̫y/2*N_,ew@Y6]DٌgNW]"zwΥHBci f -LhJ|޸CO 7_C𵆓c)b!`4=LgV=p `PYK,yMA ,'Ul  Pc=Эr0` pCuliz 4 A#ՎA_WiDJ40?tlܫtY*'ciލotz?F!O~nl&O&M#O #*=Ռu)X{ -A-]&h@'X`rx-p&'& ǡIzsu*w.o.^89<Nh=6Z*4endstream endobj 91 0 obj << /Type /Page /Parent 3 0 R /Contents 92 0 R /Resources 4 0 R >> endobj 92 0 obj << /Length 1951 /Filter /FlateDecode >> stream xYMo7 Wb+V`ء!sEtuڡ~*;qC1WE>$jFhIBIa^9B)/^ߛŋ/r V?7KRjN ŻB -ߧ. u}9/m. e"plX^q-)ؒ%B+-녆ɔkrqZ Px(Xe$+T<P|\W\q2.&9ɬk6]^!WLl3^&f.\Cv\{f" z (0!&NIa B|*<U22sd y. Duχ, Ƅ/.벌 a& =Y.OȂS./ ,qUzZT5IS%gf~AOv6AwHQJk) қאQoqhT4,YkT4aT\4{]7ȝ7[GTvMB` #~*u͍.]4yb,G[.,G[.j9E#m|ѩ8FW ȷ G]rd$\!WUf8 \r# aF#!`Wi3fR`:A[ـ?8œ(Lg䩸kQxX1Z&S1v]!ttsUj6'\le?GE/& qej'j'*LPu^g>ubOPzϽaȓ ~F̡cGu({.yʝL[gt3NgsZφ%"ޛh^<;zK&{ =X@U_nv1w\Kqh-_Y/Ս8 >67_N``_T~Y]_ fs#5Z99RpvR}ue?c v3l$?]߳qnIȩ4B_zvϻtfI*ȩ$_¥N# cCШk`aaMj8ݮ>#  atƛӮQ1׀ܗ 4fGh %vuC";ax ̭:Nbe!@ 52 4s9y`#5;9V4xŖ@}[ S6fXnͲ%:6cEˢѕ<6m,!zw5r7!Ҧ^.^nڹ6*"-I:+ ,nbEv_JJW^A ~6X̟z<\w\<;QfQ\3֤]!F @mJ aR [ Bu}Z>Quk3Ο3rƟ32Ο3rƟ3)Y+-ȺiL=uӘ{"1DMc"'1"BGWt)iAgFt Ft.)$D6z[=e4F_AsqbZn^1{/u6_afueak>DAKZ_A7P= vendstream endobj 93 0 obj << /Type /Page /Parent 3 0 R /Contents 94 0 R /Resources 4 0 R >> endobj 94 0 obj << /Length 1952 /Filter /FlateDecode >> stream xYMo7 Wb+V`ء!sEtuڡ~*;u_1WE>$e-->J*E ~yS\/^>5>7_fAn8^nQ;}ſw -B8)'ۗ&钰Zf->E+Eݒގ-;[)R+^hLU! UFªBC1QuEE\(CbBL̪ 16Jjri^6CpE{-mb"?dE kf.¨L[nR cb┤ 72ӭA+X%#3A0WIOYg|bA lLh.m2ܓ2md,X<|8>n_eKHU#Kk+.~:;N/{Pio70ܻgߞۋgٛfl{~dp}7Qe2z*FդWR^MxbvH_5  Xe @@dcd{Ū}6,ȟޟj6s5]S5KM>ej'j'*LP<­t*# QXc8] :-+bkmEa 8 /3328|w3y^Sm]>u^g>ubOPzϽaȓ ~F̡cGu({.yʝL[gt3NgrZφ%"ޛ+h^<;rK&;akfq*˛/׷;84Ӗo>ݮWbV__sX2cU_nW7עobyuH`y-5ANδ_/.?]VNOn~4. 4 9!`Q סhHWhmJ%\40< if֔[Qqa*Ca32рrifNg9s }0 LcvfPbwX0;L!>7 :PA̬Ck@>J*.Q;a~\hFtan?6~r;NJoRԽA B`kaʆKalMXѲhgt.6iRiM^WZu// \v b$wAN 7pbEv_JJW^A/l[?x,0yw6U??!WFUKphZwXG_mnShZ>xn8x#[^whtk4itk47-C48otcX9jWgoendstream endobj 95 0 obj << /Type /Page /Parent 3 0 R /Contents 96 0 R /Resources 4 0 R >> endobj 96 0 obj << /Length 2353 /Filter /FlateDecode >> stream xZIo\7:\m$L$`A,mhK~['0=*>OB?-J*%L A|95>?V?>Gq>\t QwB/+->וe}o5m."i5e{֬d6F'yߋHIoDjC2Y,nV:s׫` M^&?*FU29",MY+- 9P g,7FXmL\c5`[`bdpA[[n j9+iM'ąwk@qa0:b`.ɑSkS`mqWX x % )8-'eHH9 v'࿌QAD߂Mf$-ML N CS2OpYaTT3hpͬwFgՀ!!]5LkifC >~'B?1/?1/w1b%3D-k udK:G'Fأ4,9&QIt0: t:~:b/Jk[0,,Wʾ%/^?1,hb@‹]"WG#/"?oίQ~_N`ɠ~z\݊ ( τZԔ1-RvʶS}uew ^G&Ӑz#ϝ N&&'~霵ч;KmNax!0Cj}~cv*`j'?}X?2ql~,Z_KsO'ciotz?F!O~nl&O&M#O #*='i:۞X]BKAP@iL 7P;&+pGLWLO & ǽH D\ޜpPs5XyJ5|x5?endstream endobj 97 0 obj << /Type /Page /Parent 3 0 R /Contents 98 0 R /Resources 4 0 R >> endobj 98 0 obj << /Length 2345 /Filter /FlateDecode >> stream xZIo\7:\m$L$`A,mhK~['0=*>OB?-J*%L A|95>?V?>Gq>\t QwB/+->וe}o5m."i5e{֬d6F'yߋHIoDjC2Y,nV:s׫` M^&?*FU29",MY+- 9P g,7FXmL\c5`[`bdpA[[n j9+iM'ąwk@qa0:b`.ɑSkS`mqWX x % )8-'eHH9 v'࿌QAD߂Mf$-ML N CS2OpYaTT3hpͬwFgՀ!!]5LkifC >Az dž1܂FcDo:Rshe‚7 npT9r3Md*bxY0- "h^!c0J5yz$uwGn o\\/ޕR0 L/3g!;GŅ#ʬb b+QPQ_!g0G쯐3`2wFV5hpvʘ5 5 52ŸRvW1*HwkIXbT…LS)P."zל~3ks-- :ZV  ::vD[(πPCxQo{,\aO8i=&Őxv#>ޝΎ&F67]q<~Rpp8TxwU^ZxZI~ӽ(^1F-wh`EFMi!X|q2h_5 :6:>H c`8t2-e62/ ,O[Qwqq}p%дT˖2%Zn\_Vvνh0d2PoszaAdV8q4ŚUKbQ;uDЖƋMkIUr#N78Gywᮿ@X, sWz[i;bޞI*_lYƒmE&Bd;6!zwᮿh26VL7"yۺi(f'7|dz(*GLǕ!`6=#*۪mm:?@ R0c)%MP}Rk0I*`džnm,p/đbFǁխvRki. dl9-ڂ> endobj 4 0 obj << /ProcSet [/PDF /Text] /Font <> /ExtGState << /GS1 101 0 R /GS2 102 0 R /GS257 103 0 R /GS258 104 0 R >> /ColorSpace << /sRGB 5 0 R >> >> endobj 5 0 obj [/ICCBased 6 0 R] endobj 6 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~endstream endobj 99 0 obj << /Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences [ 45/minus ] >> endobj 100 0 obj << /Type /Font /Subtype /Type1 /Name /F2 /BaseFont /Helvetica /Encoding 99 0 R >> endobj 101 0 obj << /Type /ExtGState /CA 0.502 >> endobj 102 0 obj << /Type /ExtGState /CA 1.000 >> endobj 103 0 obj << /Type /ExtGState /ca 1.000 >> endobj 104 0 obj << /Type /ExtGState /ca 0.600 >> endobj xref 0 105 0000000000 65535 f 0000000021 00000 n 0000000163 00000 n 0000309179 00000 n 0000309577 00000 n 0000309746 00000 n 0000309779 00000 n 0000000212 00000 n 0000000292 00000 n 0000000383 00000 n 0000000464 00000 n 0000002467 00000 n 0000002549 00000 n 0000004551 00000 n 0000004633 00000 n 0000012280 00000 n 0000012362 00000 n 0000019986 00000 n 0000020068 00000 n 0000027693 00000 n 0000027775 00000 n 0000035399 00000 n 0000035481 00000 n 0000043106 00000 n 0000043188 00000 n 0000050815 00000 n 0000050897 00000 n 0000073965 00000 n 0000074047 00000 n 0000097115 00000 n 0000097197 00000 n 0000120264 00000 n 0000120346 00000 n 0000135978 00000 n 0000136060 00000 n 0000137778 00000 n 0000137860 00000 n 0000139577 00000 n 0000139659 00000 n 0000148190 00000 n 0000148272 00000 n 0000156802 00000 n 0000156884 00000 n 0000165413 00000 n 0000165495 00000 n 0000174023 00000 n 0000174105 00000 n 0000182631 00000 n 0000182713 00000 n 0000191238 00000 n 0000191320 00000 n 0000196623 00000 n 0000196705 00000 n 0000202010 00000 n 0000202092 00000 n 0000220439 00000 n 0000220521 00000 n 0000238866 00000 n 0000238948 00000 n 0000257291 00000 n 0000257373 00000 n 0000268567 00000 n 0000268649 00000 n 0000270451 00000 n 0000270533 00000 n 0000272334 00000 n 0000272416 00000 n 0000274218 00000 n 0000274300 00000 n 0000276101 00000 n 0000276183 00000 n 0000277985 00000 n 0000278067 00000 n 0000279868 00000 n 0000279950 00000 n 0000281968 00000 n 0000282050 00000 n 0000284069 00000 n 0000284151 00000 n 0000286553 00000 n 0000286635 00000 n 0000288653 00000 n 0000288735 00000 n 0000290752 00000 n 0000290834 00000 n 0000292861 00000 n 0000292943 00000 n 0000294970 00000 n 0000295052 00000 n 0000297464 00000 n 0000297546 00000 n 0000299958 00000 n 0000300040 00000 n 0000302064 00000 n 0000302146 00000 n 0000304171 00000 n 0000304253 00000 n 0000306679 00000 n 0000306761 00000 n 0000312474 00000 n 0000312569 00000 n 0000312668 00000 n 0000312718 00000 n 0000312768 00000 n 0000312818 00000 n trailer << /Size 105 /Info 1 0 R /Root 2 0 R >> startxref 312868 %%EOF cutpointr/tests/testthat/test-cutpointr.R0000644000176200001440000020764113770652403020453 0ustar liggesuserscontext("test-cutpointr.R") library(cutpointr) library(ggplot2) test_plot.cutpointr <- function(cutpointr_object) { tempplot <- plot(cutpointr_object) expect_identical(class(tempplot), c("gtable", "gTree", "grob", "gDesc")) } test_ggplot_functions <- function(cutpointr_object, do_plot_metric = TRUE) { if (do_plot_metric) { tempplot <- plot_metric(cutpointr_object) expect_identical(class(tempplot), c("gg", "ggplot")) } tempplot2 <- plot_roc(cutpointr_object) expect_identical(class(tempplot2), c("gg", "ggplot")) tempplot3 <- plot_x(cutpointr_object) expect_identical(class(tempplot3), c("gg", "ggplot")) tempplot4 <- plot_precision_recall(cutpointr_object) expect_identical(class(tempplot4), c("gg", "ggplot")) tempplot5 <- plot_sensitivity_specificity(cutpointr_object) expect_identical(class(tempplot5), c("gg", "ggplot")) } test_that("Cutpointr standard application", { data(suicide) opt_cut <- cutpointr(suicide, dsi, suicide) expect_true("cutpointr" %in% class(opt_cut)) expect_that(nrow(opt_cut), equals(1)) expect_that(sum(is.na(opt_cut)), equals(1)) # boot is NA test_plot.cutpointr(opt_cut) test_ggplot_functions(opt_cut) }) test_that("Cutpointr works with different data types", { set.seed(456) tempdat <- data.frame(x = rnorm(10), y = sample(0:1, size = 10, replace = TRUE)) opt_cut <- cutpointr(tempdat, x, y) expect_silent(summary(opt_cut)) expect_that(nrow(opt_cut), equals(1)) expect_that(sum(is.na(opt_cut)), equals(1)) test_plot.cutpointr(opt_cut) tempdat$y <- factor(tempdat$y) opt_cut <- cutpointr(tempdat, x, y) expect_silent(summary(opt_cut)) expect_that(nrow(opt_cut), equals(1)) expect_that(sum(is.na(opt_cut)), equals(1)) test_plot.cutpointr(opt_cut) tempdat$y <- as.character(tempdat$y) opt_cut <- cutpointr(tempdat, x, y) expect_silent(summary(opt_cut)) expect_that(nrow(opt_cut), equals(1)) expect_that(sum(is.na(opt_cut)), equals(1)) test_plot.cutpointr(opt_cut) # With subgroup set.seed(567) tempdat <- data.frame(x = rnorm(30), y = sample(0:1, size = 30, replace = TRUE), g = sample(0:2, size = 30, replace = TRUE)) opt_cut <- cutpointr(tempdat, x, y, g) expect_silent(summary(opt_cut)) expect_that(nrow(opt_cut), equals(3)) expect_that(sum(is.na(opt_cut)), equals(3)) test_plot.cutpointr(opt_cut) test_ggplot_functions(opt_cut) tempdat$g <- factor(tempdat$g) opt_cut <- cutpointr(tempdat, x, y, g) expect_silent(summary(opt_cut)) expect_that(nrow(opt_cut), equals(3)) expect_that(sum(is.na(opt_cut)), equals(3)) test_plot.cutpointr(opt_cut) test_ggplot_functions(opt_cut) tempdat$g <- as.character(tempdat$g) opt_cut <- cutpointr(tempdat, x, y, g) expect_silent(summary(opt_cut)) expect_that(nrow(opt_cut), equals(3)) expect_that(sum(is.na(opt_cut)), equals(3)) test_plot.cutpointr(opt_cut) test_ggplot_functions(opt_cut) }) test_that("Bootstrap does not return duplicate colnames", { set.seed(456) tempdat <- data.frame(x = rnorm(100), y = sample(0:1, size = 100, replace = TRUE)) opt_cut <- cutpointr(tempdat, x, y, boot_runs = 20) expect_true(all(table(colnames(opt_cut$boot[[1]])) == 1)) # With subgroup set.seed(123) tempdat <- data.frame(x = rnorm(300), y = sample(0:1, size = 300, replace = TRUE), g = sample(0:2, size = 300, replace = TRUE)) opt_cut <- cutpointr(tempdat, x, y, g, boot_runs = 20) expect_true(all(table(colnames(opt_cut$boot[[1]])) == 1)) }) test_that("Plotting with bootstrapping is silent", { set.seed(456) tempdat <- data.frame(x = rnorm(100), y = sample(0:1, size = 100, replace = TRUE)) opt_cut <- cutpointr(tempdat, x, y, boot_runs = 20) test_plot.cutpointr(opt_cut) test_ggplot_functions(opt_cut) }) test_that("AUC calculation is correct and works with Inf and -Inf", { tempdat <- data.frame(x = c(-Inf, 0.3, Inf), y = factor(c(0, 1, 1))) roc_cutpointr <- cutpointr::roc(tempdat, x, y, pos_class = 1, neg_class = 0) auc_cutpointr <- cutpointr::auc(roc_cutpointr) expect_equal(auc_cutpointr, 1) cp <- cutpointr(tempdat, x, y) expect_equal(cp$AUC, 1) set.seed(123) tempdat <- data.frame(x = rnorm(100), y = factor(c(rep(0, 50), rep(1, 50)))) roc_cutpointr <- cutpointr::roc(tempdat, x, y, pos_class = 1, neg_class = 0) auc_cutpointr <- cutpointr::auc(roc_cutpointr) expect_equal(round(auc_cutpointr, 3), 0.541) cp <- cutpointr(tempdat, x, y, pos_class = 1, direction = ">=") expect_equal(round(cp$AUC, 3), 0.541) }) test_that("Plotting ROC curve from roc()", { set.seed(123) tempdat <- data.frame(x = rnorm(100), y = factor(c(rep(0, 50), rep(1, 50)))) roc_cutpointr <- cutpointr::roc(tempdat, x, y, pos_class = 1, neg_class = 0) tempplot <- plot_roc(roc_cutpointr) expect_identical(class(tempplot), c("gg", "ggplot")) }) test_that("Correct midpoints are found", { temp <- data.frame(x = c(-Inf, 1, 2, 3, 5, Inf), y = c(1, 1, 1, 0, 0, 0)) optcut <- cutpointr(temp, x, y, use_midpoints = TRUE, pos_class = 1) expect_equal(optcut$optimal_cutpoint, 2.5) expect_warning(plot(optcut)) optcut <- cutpointr(temp, x, y, use_midpoints = TRUE, pos_class = 0) expect_equal(optcut$optimal_cutpoint, 2.5) }) test_that("find_metric_name finds metric", { set.seed(123) tempdat <- data.frame(x = runif(100), y = factor(sample(0:1, size = 100, replace = TRUE))) optcut <- cutpointr(tempdat, x, y, method = maximize_metric, metric = youden) expect_equal(cutpointr:::find_metric_name(optcut), "youden") set.seed(1234) tempdat <- data.frame(x = runif(100), y = factor(sample(0:1, size = 100, replace = TRUE)), g = factor(sample(0:1, size = 100, replace = TRUE))) optcut <- cutpointr(tempdat, x, y, g, method = maximize_metric, metric = youden) expect_equal(cutpointr:::find_metric_name(optcut), "youden") }) test_that("no duplicate column names are returned", { set.seed(123) tempdat <- data.frame(x = runif(100), y = factor(sample(0:1, size = 100, replace = TRUE))) optcut <- cutpointr(tempdat, x, y, method = oc_youden_normal) expect_true(all(table(colnames(optcut)) == 1)) test_plot.cutpointr(optcut) test_ggplot_functions(optcut, do_plot_metric = FALSE) if (require(fANCOVA)) { optcut <- cutpointr(tempdat, x, y, method = oc_youden_kernel) expect_true(all(table(colnames(optcut)) == 1)) expect_silent(plot(optcut)) } optcut <- cutpointr(tempdat, x, y) expect_true(all(table(colnames(optcut)) == 1)) test_plot.cutpointr(optcut) test_ggplot_functions(optcut) optcut <- cutpointr(tempdat, x, y, method = oc_manual, cutpoint = 30) expect_true(all(table(colnames(optcut)) == 1)) test_plot.cutpointr(optcut) test_ggplot_functions(optcut, do_plot_metric = FALSE) set.seed(1234) tempdat <- data.frame(x = rnorm(100), y = factor(sample(0:1, size = 100, replace = TRUE)), g = factor(sample(0:1, size = 100, replace = TRUE))) optcut <- cutpointr(tempdat, x, y, g, method = oc_youden_normal) expect_true(all(table(colnames(optcut)) == 1)) test_plot.cutpointr(optcut) test_ggplot_functions(optcut, do_plot_metric = FALSE) if (require(fANCOVA)) { optcut <- cutpointr(tempdat, x, y, g, method = oc_youden_kernel) expect_true(all(table(colnames(optcut)) == 1)) test_plot.cutpointr(optcut) test_ggplot_functions(optcut, do_plot_metric = FALSE) } optcut <- cutpointr(tempdat, x, y, g) expect_true(all(table(colnames(optcut)) == 1)) test_plot.cutpointr(optcut) test_ggplot_functions(optcut, do_plot_metric = FALSE) optcut <- cutpointr(tempdat, x, y, g, method = oc_manual, cutpoint = 30) expect_true(all(table(colnames(optcut)) == 1)) test_plot.cutpointr(optcut) test_ggplot_functions(optcut, do_plot_metric = FALSE) }) test_that("Correct cutpoints with example data", { exdat <- data.frame(obs = c(0, 0, 1, 1), preds = c(0, 0, 1, 1)) optcut <- cutpointr(exdat, preds, obs, method = minimize_metric, metric = abs_d_sens_spec) expect_equal(optcut$optimal_cutpoint, 1) optcut <- cutpointr(exdat, preds, obs, method = maximize_metric, metric = accuracy) expect_equal(optcut$optimal_cutpoint, 1) optcut <- cutpointr(exdat, preds, obs, method = maximize_metric, metric = youden) expect_equal(optcut$optimal_cutpoint, 1) # With NA exdat <- data.frame(obs = c(NA, 0, 0, 1, 1), preds = c(1, 0, 0, 1, 1)) expect_error(cutpointr(exdat, preds, obs, method = minimize_metric, metric = abs_d_sens_spec)) optcut <- cutpointr(exdat, preds, obs, method = minimize_metric, metric = abs_d_sens_spec, na.rm = T) expect_equal(optcut$optimal_cutpoint, 1) test_plot.cutpointr(optcut) test_ggplot_functions(optcut) optcut <- cutpointr(exdat, preds, obs, method = maximize_metric, metric = accuracy, na.rm = T) expect_equal(optcut$optimal_cutpoint, 1) test_plot.cutpointr(optcut) test_ggplot_functions(optcut) optcut <- cutpointr(exdat, preds, obs, method = maximize_metric, metric = youden, na.rm = T) expect_equal(optcut$optimal_cutpoint, 1) test_plot.cutpointr(optcut) test_ggplot_functions(optcut) # With Inf and -Inf exdat <- data.frame(obs = c(rep(0, 20), 1, 1, 1, 1, 0, 0, 0, 0), preds = c(rep(-Inf, 10), rep(Inf, 10), 0, 0, 0, 0, 1, 1, 1, 1)) optcut <- cutpointr(exdat, preds, obs, method = maximize_metric, metric = cutpointr::youden) expect_equal(optcut$optimal_cutpoint, 1) expect_equal(as.numeric(optcut$specificity), 1) expect_equal(round(as.numeric(optcut$sensitivity), 2), 0.58) }) test_that("Metric colnames that are already in cutpointr are modified", { metricfunc <- function(tp, fp, tn, fn, ...) { res <- matrix(1:length(tp), ncol = 1) colnames(res) <- "sensitivity" return(res) } opt_cut <- cutpointr(suicide, dsi, suicide, metric = metricfunc, boot_runs = 5) expect_equal(colnames(opt_cut)[4], "metric_sensitivity") # test_plot.cutpointr(opt_cut) # test_ggplot_functions(opt_cut) expect_silent(summary(opt_cut)) opt_cut <- cutpointr(suicide, dsi, suicide, gender, metric = metricfunc, boot_runs = 5) expect_equal(colnames(opt_cut)[5], "metric_sensitivity") # test_plot.cutpointr(opt_cut) # test_ggplot_functions(opt_cut) expect_silent(summary(opt_cut)) metricfunc <- function(tp, fp, tn, fn, ...) { res <- matrix(1:length(tp), ncol = 1) colnames(res) <- "AUC" return(res) } opt_cut <- cutpointr(suicide, dsi, suicide, metric = metricfunc, boot_runs = 5) expect_equal(colnames(opt_cut)[4], "metric_AUC") # test_plot.cutpointr(opt_cut) # test_ggplot_functions(opt_cut) expect_silent(summary(opt_cut)) opt_cut <- cutpointr(suicide, dsi, suicide, gender, metric = metricfunc, boot_runs = 5) expect_equal(colnames(opt_cut)[5], "metric_AUC") # test_plot.cutpointr(opt_cut) # test_ggplot_functions(opt_cut) expect_silent(summary(opt_cut)) metricfunc <- function(tp, fp, tn, fn, ...) { res <- matrix(1:length(tp), ncol = 1) colnames(res) <- "roc_curve" return(res) } expect_error(cutpointr(suicide, dsi, suicide, metric = metricfunc, boot_runs = 5)) expect_error(cutpointr(suicide, dsi, suicide, gender, metric = metricfunc, boot_runs = 5)) opt_cut <- cutpointr(suicide, dsi, suicide, method = oc_youden_normal, metric = metricfunc, boot_runs = 5) expect_equal(colnames(opt_cut)[4], "metric_roc_curve") # test_plot.cutpointr(opt_cut) # test_ggplot_functions(opt_cut, do_plot_metric = FALSE) expect_silent(summary(opt_cut)) opt_cut <- cutpointr(suicide, dsi, suicide, gender, method = oc_youden_normal, metric = metricfunc, boot_runs = 5) expect_equal(colnames(opt_cut)[5], "metric_roc_curve") # test_plot.cutpointr(opt_cut) # test_ggplot_functions(opt_cut, do_plot_metric = FALSE) expect_silent(summary(opt_cut)) }) test_that("SE and NSE interface give identical results", { opt_cut_nse <- cutpointr(suicide, dsi, suicide) opt_cut_se <- suppressWarnings(cutpointr_(suicide, "dsi", "suicide")) expect_identical(opt_cut_se, opt_cut_nse) opt_cut_nse <- cutpointr(suicide, dsi, suicide) opt_cut_se <- suppressWarnings(cutpointr_(suicide, "dsi", "suicide", method = maximize_metric)) expect_identical(opt_cut_se, opt_cut_nse) opt_cut_nse <- cutpointr(suicide, dsi, suicide, gender) opt_cut_se <- suppressWarnings(cutpointr_(suicide, "dsi", "suicide", "gender")) expect_identical(opt_cut_se, opt_cut_nse) opt_cut_nse <- cutpointr(suicide, dsi, suicide, gender) opt_cut_se <- suppressWarnings(cutpointr_(suicide, "dsi", "suicide", "gender")) expect_identical(opt_cut_se, opt_cut_nse) }) test_that("cutpointr detects wrong number of classes", { tempdat <- data.frame(cl = factor(c("a", "b", "c")), x = 1:3) expect_error(cutpointr(tempdat, x, cl)) expect_error(cutpointr(tempdat, x, cl, pos_class = "a", neg_class = "b", direction = ">=")) tempdat <- data.frame(cl = factor(c("a", "a", "a")), x = 1:3) expect_error(cutpointr(tempdat, x, cl)) expect_error(cutpointr(tempdat, x, cl, pos_class = "a", neg_class = "b", direction = ">=")) }) test_that("Bootstrap returns plausible results", { set.seed(123) opt_cut <- suppressWarnings(cutpointr(suicide, dsi, suicide, boot_runs = 50, break_ties = mean)) expect_true(mean(opt_cut$boot[[1]]$sum_sens_spec_b) > 1.3 & mean(opt_cut$boot[[1]]$sum_sens_spec_b) < 3) expect_true(sd(opt_cut$boot[[1]]$sum_sens_spec_b) > 0.02 & sd(opt_cut$boot[[1]]$sum_sens_spec_b) < 1) expect_true(mean(opt_cut$boot[[1]]$sum_sens_spec_oob) > 1.3 & mean(opt_cut$boot[[1]]$sum_sens_spec_oob) < 3) expect_true(sd(opt_cut$boot[[1]]$sum_sens_spec_oob) > 0.02 & sd(opt_cut$boot[[1]]$sum_sens_spec_oob) < 1) set.seed(123) opt_cut <- suppressWarnings(cutpointr(suicide, dsi, suicide, boot_runs = 30, direction = "<=")) expect_true(mean(opt_cut$boot[[1]]$sum_sens_spec_b) > 1.3 & mean(opt_cut$boot[[1]]$sum_sens_spec_b) < 3) expect_true(sd(opt_cut$boot[[1]]$sum_sens_spec_b) > 0.02 & sd(opt_cut$boot[[1]]$sum_sens_spec_b) < 1) expect_true(mean(opt_cut$boot[[1]]$sum_sens_spec_oob) > 1.3 & mean(opt_cut$boot[[1]]$sum_sens_spec_oob) < 3) expect_true(sd(opt_cut$boot[[1]]$sum_sens_spec_oob) > 0.02 & sd(opt_cut$boot[[1]]$sum_sens_spec_oob) < 1) set.seed(123) opt_cut <- suppressWarnings(cutpointr(suicide, dsi, suicide, boot_runs = 30, pos_class = "no")) expect_true(mean(opt_cut$boot[[1]]$sum_sens_spec_b) > 1.3 & mean(opt_cut$boot[[1]]$sum_sens_spec_b) < 3) expect_true(sd(opt_cut$boot[[1]]$sum_sens_spec_b) > 0.02 & sd(opt_cut$boot[[1]]$sum_sens_spec_b) < 1) expect_true(mean(opt_cut$boot[[1]]$sum_sens_spec_oob) > 1.3 & mean(opt_cut$boot[[1]]$sum_sens_spec_oob) < 3) expect_true(sd(opt_cut$boot[[1]]$sum_sens_spec_oob) > 0.02 & sd(opt_cut$boot[[1]]$sum_sens_spec_oob) < 1) }) test_that("Summary by class returns correct stats", { digits <- 3 # No subgroup, no NA oc <- cutpointr(suicide, dsi, suicide) s <- summary(oc) my <- mean(suicide[suicide$suicide == "yes", "dsi"]) expect_equal(s$desc_by_class[[1]][2, "Mean"], my, tolerance = 1e-3) mn <- mean(suicide[suicide$suicide == "no", "dsi"]) expect_equal(s$desc_by_class[[1]][1, "Mean"], mn) # No subgroup, with NA tempdat <- suicide tempdat[10, 1] <- NA tempdat[20, 2] <- NA tempdat[30, 3] <- NA tempdat[40, 4] <- NA oc <- cutpointr(tempdat, dsi, suicide, na.rm = TRUE) s <- summary(oc) my <- mean(tempdat[tempdat$suicide == "yes", "dsi"], na.rm = TRUE) expect_equal(s$desc_by_class[[1]][2, "Mean"], my, tolerance = 1e-3) mn <- mean(tempdat[tempdat$suicide == "no", "dsi"], na.rm = TRUE) expect_equal(s$desc_by_class[[1]][1, "Mean"], mn) # With subgroup, no NA oc <- cutpointr(suicide, dsi, suicide, gender) s <- summary(oc) myf <- mean(suicide[suicide$suicide == "yes" & suicide$gender == "female", "dsi"]) expect_equal(s$desc_by_class[[1]][2, "Mean"], myf, tolerance = 1e-3) mnf <- mean(suicide[suicide$suicide == "no" & suicide$gender == "female", "dsi"]) expect_equal(s$desc_by_class[[1]][1, "Mean"], mnf) mym <- mean(suicide[suicide$suicide == "yes" & suicide$gender == "male", "dsi"]) expect_equal(s$desc_by_class[[2]][2, "Mean"], mym, tolerance = 1e-3) mnm <- mean(suicide[suicide$suicide == "no" & suicide$gender == "male", "dsi"]) expect_equal(s$desc_by_class[[2]][1, "Mean"], mnm) # With subgroup, with NA tempdat <- suicide tempdat[10, 1] <- NA tempdat[20, 2] <- NA tempdat[30, 3] <- NA tempdat[40, 4] <- NA oc <- cutpointr(tempdat, dsi, suicide, gender, na.rm = TRUE) s <- summary(oc) myf <- mean(tempdat[tempdat$suicide == "yes" & tempdat$gender == "female", "dsi"], na.rm = TRUE) expect_equal(s$desc_by_class[[1]][2, "Mean"], myf, tolerance = 1e-3) mnf <- mean(tempdat[tempdat$suicide == "no" & tempdat$gender == "female", "dsi"], na.rm = TRUE) expect_equal(s$desc_by_class[[1]][1, "Mean"], mnf) mym <- mean(tempdat[tempdat$suicide == "yes" & tempdat$gender == "male", "dsi"], na.rm = TRUE) expect_equal(s$desc_by_class[[2]][2, "Mean"], mym, tolerance = 1e-3) mnm <- mean(tempdat[tempdat$suicide == "no" & tempdat$gender == "male", "dsi"], na.rm = TRUE) expect_equal(s$desc_by_class[[2]][1, "Mean"], mnm) }) test_that("Results for youden are correct", { opt_cut_cp <- cutpointr(suicide, dsi, suicide, metric = youden) expect_equal(opt_cut_cp$optimal_cutpoint, 2) opt_cut_cp <- cutpointr(suicide, dsi, suicide, gender, metric = youden) expect_equal(opt_cut_cp$optimal_cutpoint, c(2, 3)) }) test_that("Results for p_chisquared are equal to results by OptimalCutpoints", { suppressWarnings(RNGversion("3.5.0")) set.seed(2839) tempdat <- data.frame(x = c(rnorm(50), rnorm(50, mean = 1)) , y = c(rep(0, 50), rep(1, 50)), group = sample(c("a", "b"), size = 100, replace = TRUE)) suppressWarnings( opt_cut_cp <- cutpointr(tempdat, x, y, method = minimize_metric, metric = p_chisquared, direction = ">=", pos_class = 1, tol_metric = 0) ) expect_equal(round(opt_cut_cp$optimal_cutpoint, 4), 0.9335) suppressWarnings( opt_cut_cp <- cutpointr(tempdat, x, y, group, method = minimize_metric, metric = p_chisquared, direction = ">=", pos_class = 1, tol_metric = 0) ) expect_equal(round(opt_cut_cp$optimal_cutpoint, 4), c(0.9335, 0.5676)) }) test_that("Results for prod_sens_spec are equal to results by OptimalCutpoints", { set.seed(839) tempdat <- data.frame(x = c(rnorm(50), rnorm(50, mean = 1)) , y = c(rep(0, 50), rep(1, 50)), group = sample(c("a", "b"), size = 100, replace = TRUE)) opt_cut_cp <- cutpointr(tempdat, x, y, method = maximize_metric, metric = prod_sens_spec, direction = ">=", pos_class = 1) expect_equal(round(opt_cut_cp$optimal_cutpoint, 4), 0.7783) opt_cut_cp <- cutpointr(tempdat, x, y, group, method = maximize_metric, metric = prod_sens_spec, direction = ">=", pos_class = 1) expect_equal(round(opt_cut_cp$optimal_cutpoint, 4), c(0.7998, 0.6371)) }) test_that("Results for abs_d_ppv_npv are equal to results by OptimalCutpoints", { set.seed(389) tempdat <- data.frame(x = c(rnorm(50), rnorm(50, mean = 1)) , y = c(rep(0, 50), rep(1, 50)), group = sample(c("a", "b"), size = 100, replace = TRUE)) opt_cut_cp <- cutpointr(tempdat, x, y, method = minimize_metric, metric = abs_d_ppv_npv, direction = ">=", pos_class = 1) expect_equal(round(opt_cut_cp$optimal_cutpoint, 4), 0.5677) opt_cut_cp <- cutpointr(tempdat, x, y, group, method = minimize_metric, metric = abs_d_ppv_npv, direction = ">=", pos_class = 1) expect_equal(round(opt_cut_cp$optimal_cutpoint, 4), c(0.2501, 0.6781)) }) test_that("Results for sum_ppv_npv are equal to results by OptimalCutpoints", { set.seed(389) tempdat <- data.frame(x = c(rnorm(50), rnorm(50, mean = 1)) , y = c(rep(0, 50), rep(1, 50)), group = sample(c("a", "b"), size = 100, replace = TRUE)) opt_cut_cp <- cutpointr(tempdat, x, y, method = maximize_metric, metric = sum_ppv_npv, direction = ">=", pos_class = 1) expect_equal(round(opt_cut_cp$optimal_cutpoint, 4), 1.7835) opt_cut_cp <- cutpointr(tempdat, x, y, group, method = maximize_metric, metric = sum_ppv_npv, direction = ">=", pos_class = 1) expect_equal(round(opt_cut_cp$optimal_cutpoint, 4), c(-0.7339, 1.7835)) }) test_that("Results for prod_ppv_npv are equal to results by OptimalCutpoints", { set.seed(389) tempdat <- data.frame(x = c(rnorm(50), rnorm(50, mean = 1)) , y = c(rep(0, 50), rep(1, 50)), group = sample(c("a", "b"), size = 100, replace = TRUE)) opt_cut_cp <- cutpointr(tempdat, x, y, method = maximize_metric, metric = prod_ppv_npv, direction = ">=", pos_class = 1) expect_equal(round(opt_cut_cp$optimal_cutpoint, 4), 1.7835) opt_cut_cp <- cutpointr(tempdat, x, y, group, method = maximize_metric, metric = prod_ppv_npv, direction = ">=", pos_class = 1) expect_equal(round(opt_cut_cp$optimal_cutpoint, 4), c(-0.7339, 1.7835)) }) test_that("Results for accuracy are equal to results by OptimalCutpoints", { set.seed(38429) tempdat <- data.frame(x = c(rnorm(100), rnorm(100, mean = 1)) , y = c(rep(0, 100), rep(1, 100)), group = sample(c("a", "b"), size = 200, replace = TRUE)) opt_cut_cp <- cutpointr(tempdat, x, y, method = maximize_metric, metric = accuracy, direction = ">=", pos_class = 1) expect_equal(round(opt_cut_cp$optimal_cutpoint, 4), 0.4312) opt_cut_cp <- cutpointr(tempdat, x, y, group, method = maximize_metric, metric = accuracy, direction = ">=", pos_class = 1) expect_equal(round(opt_cut_cp$optimal_cutpoint, 4), c(0.9771, 0.0744)) }) test_that("Results for roc01 are equal to results by OptimalCutpoints", { set.seed(1957) tempdat <- data.frame(x = c(rnorm(100), rnorm(100, mean = 1)) , y = c(rep(0, 100), rep(1, 100)), group = sample(c("a", "b"), size = 200, replace = TRUE)) opt_cut_cp <- cutpointr(tempdat, x, y, method = minimize_metric, metric = roc01, direction = ">=", pos_class = 1) expect_equal(round(opt_cut_cp$optimal_cutpoint, 4), 0.3255) opt_cut_cp <- cutpointr(tempdat, x, y, group, method = minimize_metric, metric = roc01, direction = ">=", pos_class = 1) expect_equal(round(opt_cut_cp$optimal_cutpoint, 4), c(0.5312, 0.3307)) }) test_that("Results for constrained metrics are equal to results by OptimalCutpoints", { set.seed(38129) tempdat <- data.frame(x = c(rnorm(100), rnorm(100, mean = 1)) , y = c(rep(0, 100), rep(1, 100)), group = sample(c("a", "b"), size = 200, replace = TRUE)) opt_cut_cp <- cutpointr(tempdat, x, y, metric = sens_constrain, min_constrain = 0.85, constrain_metric = specificity) expect_equal(round(opt_cut_cp$optimal_cutpoint, 4), 1.3018) expect_equal(round(opt_cut_cp$sens_constrain, 4), 0.44) expect_equal(round(as.numeric(opt_cut_cp$specificity), 4), 0.8500) expect_equal(as.numeric(opt_cut_cp$sensitivity), opt_cut_cp$sens_constrain) opt_cut_cp <- cutpointr(tempdat, x, y, metric = spec_constrain, min_constrain = 0.85, constrain_metric = sensitivity) expect_equal(round(opt_cut_cp$optimal_cutpoint, 4), 0.2775) expect_equal(round(opt_cut_cp$spec_constrain, 4), 0.54) expect_equal(round(as.numeric(opt_cut_cp$sensitivity), 4), 0.8500) expect_equal(as.numeric(opt_cut_cp$specificity), opt_cut_cp$spec_constrain) opt_cut_cp <- cutpointr(tempdat, x, y, metric = metric_constrain, min_constrain = 0.85, constrain_metric = npv, main_metric = ppv) %>% add_metric(list(npv, ppv)) expect_equal(round(opt_cut_cp$optimal_cutpoint, 4), 0.1435) expect_equal(round(opt_cut_cp$ppv_constrain, 4), 0.6500) expect_equal(round(opt_cut_cp$npv, 4), 0.8500) expect_equal(opt_cut_cp$ppv_constrain, opt_cut_cp$ppv) }) test_that("Results for F1_score are equal to results by ROCR", { set.seed(38429) tempdat <- data.frame(x = c(rnorm(100), rnorm(100, mean = 1)) , y = c(rep(0, 100), rep(1, 100)), group = sample(c("a", "b"), size = 200, replace = TRUE)) f1_cp <- cutpointr(tempdat, x, y, method = maximize_metric, metric = F1_score, direction = ">=", pos_class = 1) # rocr_pred <- ROCR::prediction(tempdat$x, tempdat$y) # f1_rocr <- ROCR::performance(rocr_pred, "f") # f1_rocr_yvals <- round(f1_rocr@y.values[[1]], 4) f1_rocr_yvals <- c(NaN, 0.0198, 0.0392, 0.0583, 0.0769, 0.0952, 0.1132, 0.1308, 0.1481, 0.1651, 0.1818, 0.1802, 0.1964, 0.2124, 0.2281, 0.2435, 0.2586, 0.2735, 0.2881, 0.3025, 0.3167, 0.3140, 0.3279, 0.3252, 0.3387, 0.3520, 0.3651, 0.3780, 0.3906, 0.3876, 0.4000, 0.4122, 0.4242, 0.4211, 0.4328, 0.4444, 0.4412, 0.4526, 0.4493, 0.4604, 0.4714, 0.4823, 0.4789, 0.4895, 0.5000, 0.5103, 0.5205, 0.5306, 0.5405, 0.5503, 0.5600, 0.5563, 0.5658, 0.5621, 0.5714, 0.5806, 0.5897, 0.5860, 0.5949, 0.6038, 0.6000, 0.5963, 0.6049, 0.6135, 0.6098, 0.6182, 0.6145, 0.6228, 0.6310, 0.6391, 0.6353, 0.6433, 0.6395, 0.6474, 0.6437, 0.6400, 0.6364, 0.6441, 0.6404, 0.6480, 0.6444, 0.6409, 0.6374, 0.6448, 0.6522, 0.6486, 0.6559, 0.6524, 0.6489, 0.6561, 0.6526, 0.6597, 0.6667, 0.6736, 0.6804, 0.6872, 0.6837, 0.6802, 0.6869, 0.6935, 0.7000, 0.6965, 0.7030, 0.7094, 0.7059, 0.7024, 0.6990, 0.7053, 0.7019, 0.6986, 0.6952, 0.7014, 0.7075, 0.7136, 0.7103, 0.7163, 0.7130, 0.7097, 0.7156, 0.7123, 0.7091, 0.7149, 0.7207, 0.7175, 0.7232, 0.7289, 0.7257, 0.7225, 0.7193, 0.7162, 0.7130, 0.7100, 0.7069, 0.7124, 0.7179, 0.7234, 0.7288, 0.7257, 0.7227, 0.7197, 0.7250, 0.7220, 0.7190, 0.7160, 0.7131, 0.7184, 0.7154, 0.7126, 0.7097, 0.7149, 0.7120, 0.7092, 0.7063, 0.7115, 0.7087, 0.7059, 0.7109, 0.7082, 0.7132, 0.7104, 0.7077, 0.7050, 0.7023, 0.6996, 0.6970, 0.7019, 0.6992, 0.7041, 0.7015, 0.7063, 0.7037, 0.7011, 0.7059, 0.7033, 0.7007, 0.6982, 0.6957, 0.6931, 0.6978, 0.6953, 0.6929, 0.6904, 0.6879, 0.6855, 0.6901, 0.6877, 0.6853, 0.6829, 0.6875, 0.6851, 0.6828, 0.6804, 0.6781, 0.6758, 0.6735, 0.6780, 0.6757, 0.6734, 0.6711, 0.6689, 0.6667) expect_identical(f1_rocr_yvals[-1], round(f1_cp$roc_curve[[1]]$m, 4)[-1]) }) test_that("Results for misclassification_cost are equal to results by OptimalCutpoints", { set.seed(429) tempdat <- data.frame(x = c(rnorm(100), rnorm(100, mean = 1)) , y = c(rep(0, 100), rep(1, 100)), group = sample(c("a", "b"), size = 200, replace = TRUE)) opt_cut_cp <- cutpointr(tempdat, x, y, method = minimize_metric, metric = misclassification_cost, direction = ">=", cost_fp = 1, cost_fn = 3, pos_class = 1) # oc_cont <- control.cutpoints(CFP = 1, CFN = 3) # opt_cut_oc <- OptimalCutpoints::optimal.cutpoints(X = "x", status = "y", # method = "MCT", # tag.healthy = 0, # direction = "<", # data = tempdat, # control = oc_cont) # opt_cut_oc <- opt_cut_oc$MCT$Global$optimal.cutoff$cutoff expect_equal(round(opt_cut_cp$optimal_cutpoint, 4), -0.2973) opt_cut_cp <- cutpointr(tempdat, x, y, group, method = minimize_metric, metric = misclassification_cost, direction = ">=", cost_fp = 1, cost_fn = 3, pos_class = 1) # oc_cont <- control.cutpoints(CFP = 1, CFN = 3) # opt_cut_oc <- OptimalCutpoints::optimal.cutpoints(X = "x", status = "y", # categorical.cov = "group", # method = "MCT", # tag.healthy = 0, # direction = "<", # data = tempdat, # control = oc_cont) # opt_cut_oc_a <- opt_cut_oc$MCT$a$optimal.cutoff$cutoff # opt_cut_oc_b <- opt_cut_oc$MCT$b$optimal.cutoff$cutoff expect_equal(round(opt_cut_cp$optimal_cutpoint, 4), c(-0.7498, -0.0824)) }) test_that("LOESS smoothing does not return warnings or errors", { set.seed(38429) tempdat <- data.frame(x = c(rnorm(100), rnorm(100, mean = 1)) , y = c(rep(0, 100), rep(1, 100)), group = sample(c("a", "b"), size = 200, replace = TRUE)) expect_silent( suppressMessages( cp <- cutpointr(tempdat, x, y, method = maximize_loess_metric, user.span = 1, metric = accuracy, direction = ">=", pos_class = 1, boot_runs = 10) ) ) expect_equal(round(cp$optimal_cutpoint, 3), 0.507) expect_equal(round(cp$loess_accuracy, 3), 0.690) set.seed(208) tempdat <- data.frame(x = c(rnorm(100), rnorm(100, mean = 2)) , y = c(rep(0, 100), rep(1, 100)), group = sample(c("a", "b"), size = 200, replace = TRUE)) expect_silent( suppressMessages( cp <- cutpointr(tempdat, x, y, method = maximize_loess_metric, metric = accuracy, direction = ">=", pos_class = 1, boot_runs = 10) ) ) expect_silent( suppressMessages( cutpointr(tempdat, x, y, group, method = maximize_loess_metric, user.span = 1, metric = accuracy, direction = ">=", pos_class = 1, boot_runs = 10) ) ) set.seed(3429) tempdat <- data.frame(x = c(rnorm(100), rnorm(100, mean = 1)) , y = c(rep(0, 100), rep(1, 100)), group = sample(c("a", "b"), size = 200, replace = TRUE)) expect_silent( suppressMessages( cp <- cutpointr(tempdat, x, y, method = minimize_loess_metric, user.span = 1, break_ties = mean, metric = abs_d_ppv_npv, direction = ">=", pos_class = 1, boot_runs = 10) ) ) expect_equal(round(cp$optimal_cutpoint, 3), -0.083) expect_equal(round(cp$loess_abs_d_ppv_npv, 3), 0.156) expect_silent( cp <- cutpointr(tempdat, x, y, group, method = minimize_loess_metric, user.span = 1, break_ties = mean, silent = TRUE, metric = abs_d_ppv_npv, direction = ">=", pos_class = 1, boot_runs = 100) ) expect_equal(round(cp$optimal_cutpoint, 2), c(-1.29, 1.01)) }) test_that("cutpointr returns same result with NSE interface and raw data", { oc1 <- cutpointr(suicide, dsi, suicide, metric = prod_sens_spec) oc2 <- cutpointr(x = suicide$dsi, class = suicide$suicide, metric = prod_sens_spec) expect_true(oc1$optimal_cutpoint == 2) expect_true(oc2$optimal_cutpoint == 2) expect_true(oc1$prod_sens_spec == oc2$prod_sens_spec) oc1 <- cutpointr(suicide, dsi, suicide, gender, metric = prod_sens_spec) oc2 <- cutpointr(x = suicide$dsi, class = suicide$suicide, subgroup = suicide$gender, metric = prod_sens_spec) expect_true(all(oc1$prod_sens_spec == oc2$prod_sens_spec)) expect_true(all(oc1$optimal_cutpoint == oc2$optimal_cutpoint)) }) test_that("Prevalence is correctly calculated", { tempdat <- data.frame(x = 1:100, y = c(rep(0, 10), rep(1, 90))) oc <- cutpointr(tempdat, x, y, pos_class = 1, direction = ">=") expect_equal(oc$prevalence, 0.9) tempdat <- data.frame(x = 100:1, y = c(rep(0, 10), rep(1, 90))) oc <- cutpointr(tempdat, x, y, pos_class = 1, direction = ">=") expect_equal(oc$prevalence, 0.9) tempdat <- data.frame(x = 1:100, y = c(rep(0, 10), rep(1, 90))) oc <- cutpointr(tempdat, x, y, pos_class = 1, direction = "<=") expect_equal(oc$prevalence, 0.9) tempdat <- data.frame(x = 100:1, y = c(rep(0, 10), rep(1, 90))) oc <- cutpointr(tempdat, x, y, pos_class = 1, direction = "<=") expect_equal(oc$prevalence, 0.9) }) test_that("multi_cutpointr runs without errors", { mc <- multi_cutpointr(suicide, x = c("age", "dsi"), class = "suicide", pos_class = "yes") expect_equal(mc$optimal_cutpoint, c(55, 2)) mc <- multi_cutpointr(suicide, x = c("age", "dsi"), class = "suicide", subgroup = NULL, pos_class = "yes") expect_equal(mc$optimal_cutpoint, c(55, 2)) mc2 <- multi_cutpointr(suicide, class = "suicide", pos_class = "yes") expect_identical(mc, mc2) mc3 <- multi_cutpointr(suicide, x = c("age", "dsi"), class = suicide, subgroup = NULL, pos_class = "yes") expect_identical(mc, mc3) mcg <- multi_cutpointr(suicide, x = c("age", "dsi"), class = "suicide", subgroup = "gender", pos_class = "yes") expect_equal(mcg$optimal_cutpoint, c(55, 21, 2, 3)) mcg2 <- multi_cutpointr(suicide, class = "suicide", subgroup = "gender", pos_class = "yes") expect_identical(mcg, mcg2) mcg3 <- multi_cutpointr(suicide, x = c("age", "dsi"), class = suicide, subgroup = gender, pos_class = "yes") expect_identical(mcg, mcg3) mcg4 <- multi_cutpointr(suicide, x = c("age", "dsi"), class = suicide, subgroup = "gender", pos_class = "yes") expect_identical(mcg, mcg4) my_group_var <- "gender" my_class_var <- "suicide" mcg_new <- multi_cutpointr(suicide, x = c("age", "dsi"), class = !!my_class_var, subgroup = !!my_group_var, pos_class = "yes") expect_identical(mcg, mcg_new) mcg_new <- multi_cutpointr(suicide, x = c("age", "dsi"), class = !!my_class_var, subgroup = "gender", pos_class = "yes") expect_identical(mcg, mcg_new) # We had a bug with cutpointr 1.0.32 where class had to be named suicide temp <- suicide temp$foo <- temp$suicide temp$suicide <- NULL temp_mc <- multi_cutpointr(temp, x = c("age", "dsi"), class = foo) expect_equal(temp_mc$optimal_cutpoint, c(56, 2)) }) test_that("AUC is always >= 0.5 with automatic assumptions", { tempdat <- data.frame(x = c(5:1, 100), y = c(2,2,2,1,1,1)) oc <- cutpointr(tempdat, x, y) expect_true(oc$AUC >= 0.5) oc <- cutpointr(tempdat, x, y, pos_class = 2) expect_true(oc$AUC >= 0.5) }) test_that("find_metric_name_boot finds correct metric", { oc <- cutpointr(x = suicide$dsi, class = suicide$suicide, metric = abs_d_sens_spec, method = minimize_metric, boot_runs = 3) expect_true(cutpointr:::find_metric_name_boot(oc$boot[[1]]) == "abs_d_sens_spec_oob") oc <- cutpointr(x = suicide$dsi, class = suicide$suicide, subgroup = suicide$gender, metric = abs_d_sens_spec, method = minimize_metric, boot_runs = 3) expect_true(cutpointr:::find_metric_name_boot(oc$boot[[1]]) == "abs_d_sens_spec_oob") }) test_that("error if NSE and raw interface are mixed", { expect_error(cutpointr(suicide, suicide$dsi, suicide$suicide)) expect_error(cutpointr(suicide, suicide$dsi, suicide)) expect_error(cutpointr(suicide, dsi, suicide$suicide)) expect_error(cutpointr(suicide, dsi, suicide, suicide$gender)) }) test_that("error if metric/method is not a function", { expect_error(cutpointr(suicide, dsi, suicide, metric = "accuracy")) expect_error(cutpointr(suicide, dsi, suicide, method = "oc_youden_kernel")) }) test_that("same results with or without silent", { expect_identical( cutpointr(suicide, dsi, suicide, gender), cutpointr(suicide, dsi, suicide, gender, silent = TRUE) ) }) test_that("plot_cutpointr runs", { oc <- cutpointr(suicide, dsi, suicide) expect_is(plot_cutpointr(oc), "ggplot") expect_is(plot_cutpointr(oc, cutpoints, fpr), "ggplot") expect_is(plot_cutpointr(oc, cutpoints, function(tp, fp, ...) tp + fp), "ggplot") oc <- cutpointr(suicide, dsi, suicide, gender) expect_is(plot_cutpointr(oc), "ggplot") expect_is(plot_cutpointr(oc, cutpoints, fpr), "ggplot") expect_is(plot_cutpointr(oc, cutpoints, function(tp, fp, ...) tp + fp), "ggplot") set.seed(100) oc <- cutpointr(suicide, dsi, suicide, boot_runs = 5) expect_is(plot_cutpointr(oc), "ggplot") expect_is(plot_cutpointr(oc, cutpoints, fpr), "ggplot") expect_is(plot_cutpointr(oc, cutpoints, function(tp, fp, ...) tp + fp), "ggplot") set.seed(100) oc <- cutpointr(suicide, dsi, suicide, gender, boot_runs = 5) expect_is(plot_cutpointr(oc), "ggplot") expect_is(plot_cutpointr(oc, cutpoints, fpr), "ggplot") expect_is(plot_cutpointr(oc, cutpoints, function(tp, fp, ...) tp + fp), "ggplot") set.seed(100) expect_warning(plot_cutpointr( cutpointr(suicide, dsi, suicide, boot_runs = 5), fpr, tpr )) set.seed(200) expect_warning(plot_cutpointr( cutpointr(suicide, dsi, suicide, gender, boot_runs = 5), fpr, tpr )) }) test_that("smoothing splines lead to plausible results", { cp <- cutpointr(suicide, dsi, suicide, method = maximize_spline_metric, nknots = 5, spar = 0.3) expect_equal(cp$optimal_cutpoint, 3) test_plot.cutpointr(cp) test_ggplot_functions(cp) expect_silent(summary(cp)) cp <- cutpointr(suicide, dsi, suicide, gender, method = maximize_spline_metric, nknots = 5, spar = 0.3) expect_equal(cp$optimal_cutpoint, c(3, 3)) test_plot.cutpointr(cp) test_ggplot_functions(cp) expect_silent(summary(cp)) cp <- cutpointr(suicide, dsi, suicide, method = minimize_spline_metric, nknots = 5, spar = 0.3, df = 5, metric = abs_d_sens_spec) expect_equal(cp$optimal_cutpoint, 3) test_plot.cutpointr(cp) test_ggplot_functions(cp) expect_silent(summary(cp)) }) test_that("gam smoothing leads to plausible results", { cp <- cutpointr(suicide, dsi, suicide, method = maximize_gam_metric, metric = youden) expect_equal(cp$optimal_cutpoint, 2) test_plot.cutpointr(cp) test_ggplot_functions(cp) expect_silent(summary(cp)) cp <- cutpointr(suicide, dsi, suicide, gender, method = maximize_gam_metric, metric = youden) expect_equal(cp$optimal_cutpoint, c(2, 2)) test_plot.cutpointr(cp) test_ggplot_functions(cp) expect_silent(summary(cp)) cp <- cutpointr(suicide, dsi, suicide, gender, method = minimize_gam_metric, metric = abs_d_sens_spec) expect_equal(cp$optimal_cutpoint, c(2, 2)) test_plot.cutpointr(cp) test_ggplot_functions(cp) expect_silent(summary(cp)) }) test_that("bootstrapped cutpoints lead to plausible results", { set.seed(914) cp <- cutpointr(suicide, dsi, suicide, method = maximize_boot_metric, metric = youden, boot_cut = 10) expect_equal(cp$optimal_cutpoint, 1.9) test_plot.cutpointr(cp) test_ggplot_functions(cp, do_plot_metric = FALSE) expect_silent(summary(cp)) set.seed(14) cp <- cutpointr(suicide, dsi, suicide, gender, method = maximize_boot_metric, metric = youden, boot_cut = 10) expect_equal(cp$optimal_cutpoint, c(2.2, 3.2)) test_plot.cutpointr(cp) test_ggplot_functions(cp, do_plot_metric = FALSE) expect_silent(summary(cp)) set.seed(15) cp <- cutpointr(suicide, dsi, suicide, gender, method = minimize_boot_metric, metric = abs_d_sens_spec, boot_cut = 10) expect_equal(cp$optimal_cutpoint, c(2.1, 2.2)) expect_error(plot_metric(cp)) test_plot.cutpointr(cp) test_ggplot_functions(cp, do_plot_metric = FALSE) expect_silent(summary(cp)) }) test_that("this led to an error with get_rev_dups Rcpp function", { dat <- rbind(data.frame(x = round(rnorm(5000), 1), y = 0), data.frame(x = round(rnorm(5000, mean = 0.05), 1), y = 1)) expect_silent(cutpointr(dat, x, y, method = maximize_spline_metric, nknots = 50, silent = TRUE)) }) test_that("cutpoint_knots returns correct results", { expect_equal(cutpoint_knots(suicide, "dsi"), 12) }) test_that("cutpointr handles multiple optimal cutpoints correctly", { tempdat <- data.frame(y = c(0,0,0,1,0,1,1,1), x = 1:8) expect_message(cp <- cutpointr(tempdat, x = x, class = y, break_ties = c, pos_class = 1, direction = ">=")) expect_equal(cp$optimal_cutpoint[[1]], c(6, 4)) expect_message(cp <- cutpointr(tempdat, x = x, class = y, break_ties = c, use_midpoints = TRUE, pos_class = 1, direction = ">=")) expect_equal(cp$optimal_cutpoint[[1]], c(5.5, 3.5)) tempdat_g <- data.frame(g = c(rep(1, 8), rep(2, 8)), y = c(tempdat$y, tempdat$y), x = c(tempdat$x, tempdat$x + 2)) expect_message(cp <- cutpointr(tempdat_g, x = x, class = y, pos_class = 1, direction = ">=", subgroup = g, break_ties = c)) preds <- predict(object = cp, newdata = data.frame(x = c(3,6,7,1), g = c(1,2,2,1)), cutpoint_nr = 2) expect_equal(preds, c(0,1,1,0)) preds <- predict(object = cp, newdata = data.frame(x = c(3,4,5,8), g = c(1,1,2,2)), cutpoint_nr = c(2, 1)) expect_equal(preds, c(0,1,0,1)) # 5 "optimal" cutpoints at 1.2. Only one is returned without # using a tolerance argument due to floating point problems dat <- structure(list(x = c(107.163316194991, 105.577309820546, 114.819340158769, 93.8701224510515, 111.161366154904, 110.365480099412, 98.3751686809715, 90.2407330717812, 89.1085480911548, 104.57786957945, 99.2887326627911, 117.791026668514, 105.351379604962, 96.280551248365, 89.7445775150289, 100.175983253947, 109.428883928973, 101.490653529433, 111.142301202307, 102.656619478302, 104.944400912055, 98.6949032719217, 125.050435849087, 109.326217314704, 108.306336404995, 89.0813758511593, 112.597918995493, 95.7637641112029, 97.084784256457, 115.183411710216), group = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("h", "d"), class = "factor")), .Names = c("x", "group"), row.names = c(NA, -30L), class = "data.frame") cp <- cutpointr(dat, x, group, break_ties = c, tol_metric = 1e-6) expect_equal(length(unlist(cp$optimal_cutpoint)), 5) }) test_that("Main metric gets replaced correctly when ties are broken", { dat <- structure(list(x = c(101.805229018197, 107.847340401023, 86.4683542621282, 119.832982062599, 112.384717044928, 112.006173961394, 108.961498842131, 102.536897550745, 105.496003408587, 119.033710510161, 124.445336141903, 111.152957581359, 103.727459196182, 97.3051126961894, 107.721798530394, 107.3951172956, 94.2585671912768, 127.544243110669, 93.2168880188317, 115.311444925151), group = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("h", "d"), class = "factor")), .Names = c("x", "group"), row.names = c(NA, -20L), class = "data.frame") cp <- cutpointr(dat, x, group, break_ties = c) cp2 <- cutpointr(dat, x, group, break_ties = mean) expect_equal(unlist(cp$sum_sens_spec), c(1.2, 1.2)) expect_equal(cp2$sum_sens_spec, 1.1) # Different metric cp <- cutpointr(dat, x, group, metric = accuracy, method = maximize_metric, break_ties = c) cp2 <- cutpointr(dat, x, group, metric = accuracy, method = maximize_metric, break_ties = mean) expect_equal(unlist(cp$accuracy), c(0.6, 0.6)) expect_equal(as.numeric(unlist(cp$accuracy)), unlist(cp$acc)) expect_equal(cp2$accuracy, 0.55) expect_equal(as.numeric(cp2$accuracy), as.numeric(cp2$acc)) # With subgroup dat <- structure(list(x = c(112.154869479653, 85.0195562661719, 93.9648809281475, 111.629388719907, 93.6448243724487, 117.357328029692, 98.3663682555138, 105.201729160301, 98.7939462917362, 103.013183787135, 106.178862160569, 108.635928791856, 93.964291812696, 99.9357423611922, 106.763495052307, 114.17384726262, 127.593415952213, 95.1459299909085, 124.619049508866, 103.578770674126, 118.606425125718, 117.882345070528, 113.320440921296, 115.780191821353, 99.4794449460106, 115.080791705234, 104.429126735958, 119.686460888845, 106.942508474107, 119.110377570583, 121.929559539621, 121.503911629438, 116.669635368185, 106.99542786452, 106.089271831433, 119.975572786775, 120.126938685093, 98.1659607850261, 110.128131439393, 108.365631379854), group = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("h", "d"), class = "factor"), subgroup = c(0L, 1L, 0L, 1L, 0L, 0L, 1L, 1L, 0L, 0L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 1L, 1L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 1L, 0L)), .Names = c("x", "group", "subgroup" ), row.names = c(NA, -40L), class = "data.frame") cp <- cutpointr(dat, x, group, subgroup, break_ties = c) cp2 <- cutpointr(dat, x, group, subgroup, break_ties = function(x) mean(x) - 10) expect_equal(round(cp$optimal_cutpoint[[2]], 4), c(113.3204, 110.1281)) expect_equal(round(cp$sum_sens_spec[[2]], 3), rep(1.667, 2)) expect_equal(round(cp2$optimal_cutpoint[[2]], 2), 101.72) expect_equal(round(cp2$sum_sens_spec[[2]], 3), 1.222) }) test_that("stratification works", { set.seed(9174) cps <- cutpointr(suicide, dsi, suicide, metric = youden, boot_runs = 30, boot_stratify = TRUE) expect_true(all(cps$boot[[1]]$TP_b + cps$boot[[1]]$FN_b == 36)) set.seed(174) cps <- cutpointr(suicide, dsi, suicide, metric = youden, boot_runs = 30, boot_stratify = FALSE) expect_true(any(cps$boot[[1]]$TP_b + cps$boot[[1]]$FN_b != 36)) # maximize_boot_metric will produce errors without stratification # if one class is missing in the bootstrap sample tempdat <- head(suicide, 130) set.seed(1234) expect_warning( expect_error( cutpointr(tempdat, dsi, suicide, method = maximize_boot_metric, boot_stratify = FALSE, boot_cut = 10) ) ) set.seed(1234) cp <- cutpointr(tempdat, dsi, suicide, method = maximize_boot_metric, boot_stratify = TRUE, boot_cut = 10) expect_identical(cp$optimal_cutpoint, 4.2) }) test_that("cutpointr works with custom method function", { CutOff_Optimised <- function(data, x, class, pos_class, neg_class, direction, ...){ stopifnot(direction == ">=") Obs <- data[[class]] == pos_class Fit <- data[[x]] SumObs <- sum(Obs) LengObs <- length(Obs) tt <- c(0) Cut <- c(0,0,0) if(length(unique(Fit))==1){ Cut[1] <- unique(Fit) Cut[2] <- 100*sum((Fit>=Cut[1])[Obs==1])/SumObs Cut[3] <- 100*sum((Fit=i)[Obs==1])/SumObs sp <- sum((Fit=b)[Obs==1])/SumObs sp <- sum((Fit=") expect_output(print(scp), "Nr. of bootstraps: 10") expect_output(print(scp), "accuracy_oob [0-9]*") set.seed(83) cp <- cutpointr(suicide, dsi, suicide, gender, method = oc_youden_normal, metric = accuracy, boot_runs = 10) scp <- summary(cp) expect_output(print(scp), "Bootstrap summary:") expect_output(print(scp), "Predictor summary:") expect_output(print(scp), "Method: oc_youden_normal") expect_output(print(scp), "Predictor: dsi") expect_output(print(scp), "Subgroup: female") expect_output(print(scp), "Subgroup: male") expect_output(print(scp), "Outcome: suicide") expect_output(print(scp), "Direction: >=") expect_output(print(scp), "Nr. of bootstraps: 10") expect_output(print(scp), "accuracy_oob [0-9]*") set.seed(8213) cp <- cutpointr(suicide$dsi, suicide$suicide, suicide$gender, method = oc_youden_normal, metric = accuracy, boot_runs = 10) scp <- summary(cp) expect_output(print(scp), "Bootstrap summary:") expect_output(print(scp), "Predictor summary:") expect_output(print(scp), "Method: oc_youden_normal") expect_output(print(scp), "Predictor: x") expect_output(print(scp), "Outcome: class") expect_output(print(scp), "Subgroup: female") expect_output(print(scp), "Subgroup: male") expect_output(print(scp), "Direction: >=") expect_output(print(scp), "Nr. of bootstraps: 10") expect_output(print(scp), "accuracy_oob [0-9]*") }) test_that("add_metric adds metrics correctly", { oc <- cutpointr(suicide, dsi, suicide, gender) oc <- add_metric(oc, list(ppv, npv)) expect_equal(oc$ppv, c(0.3676471, 0.2592593), tolerance = 1e-5) expect_equal(oc$npv, c(0.9938272, 0.9823009), tolerance = 1e-5) oc <- cutpointr(suicide, dsi, suicide) oc <- add_metric(oc, list(F1_score, precision)) expect_equal(oc$F1_score, 0.470588, tolerance = 1e-5) expect_equal(oc$precision, 0.32, tolerance = 1e-5) oc <- cutpointr(suicide, dsi, suicide, use_midpoints = T) oc <- add_metric(oc, list(abs_d_ppv_npv, abs_d_sens_spec)) expect_equal(oc$abs_d_ppv_npv, 0.670741, tolerance = 1e-5) expect_equal(oc$abs_d_sens_spec, 0.0259857, tolerance = 1e-5) rcp <- roc(data = suicide, x = dsi, class = suicide, pos_class = "yes", neg_class = "no", direction = ">=") %>% add_metric(list(cohens_kappa, F1_score)) expect_equal(rcp$cohens_kappa, c(0.00000000, 0.05058128, 0.09312293, 0.13833841, 0.18161477, 0.30098108, 0.52746652, 0.52329749, 0.47076829, 0.42463778, 0.41208251, 0.27878034, 0.00000000), tolerance = 1e-5) tempdat <- data.frame(y = c(0,0,0,1,0,1,1,1), x = 1:8) oc <- cutpointr(tempdat, x, y, break_ties = c) oc <- add_metric(oc, list(recall, youden)) expect_equal(oc$recall[[1]], c(0.75, 1)) expect_equal(oc$youden[[1]], c(0.75, 0.75)) tempdat_g <- data.frame(g = c(rep(1, 8), rep(2, 8)), y = c(tempdat$y, tempdat$y), x = c(tempdat$x, tempdat$x + 2)) oc <- cutpointr(tempdat_g, x = x, class = y, pos_class = 1, direction = ">=", subgroup = g, break_ties = c) oc <- add_metric(oc, list(false_omission_rate, prod_sens_spec)) expect_equal(oc$false_omission_rate[[1]], c(0.2, 0)) expect_equal(oc$prod_sens_spec[[1]], c(0.75, 0.75)) mymetric <- function(...) return(42) oc <- cutpointr(suicide, dsi, suicide) oc <- add_metric(oc, list(mymetric)) expect_equal(oc$added_metric, 42) mymetric <- function(...) return(data.frame(mymet = 42)) oc <- cutpointr(suicide, dsi, suicide) oc <- add_metric(oc, list(mymetric)) expect_equal(oc$mymet, 42) set.seed(8623) mcp <- multi_cutpointr(suicide, x = c("age", "dsi"), class = suicide, subgroup = gender, pos_class = "yes", boot_runs = 3) mcp <- mcp %>% add_metric(list(ppv)) expect_equal(mcp$ppv, c(0.07386364, 0.50000000, 0.36764706, 0.25925926)) }) test_that("cutpointr works if method / metric are called with ::", { expect_silent(cutpointr(suicide, dsi, suicide, method = cutpointr::maximize_boot_metric, metric = cutpointr::accuracy, silent = TRUE)) expect_silent(cutpointr(suicide$dsi, suicide$suicide, method = cutpointr::maximize_boot_metric, metric = cutpointr::cohens_kappa, silent = TRUE)) }) test_that("Plotting with multi_cutpointr throws error", { expect_error(plot( multi_cutpointr(suicide, x = c("age", "dsi"), class = "suicide", pos_class = "yes") )) expect_error(plot( multi_cutpointr(suicide, x = c("age", "dsi"), subgroup = "gender", class = "suicide", pos_class = "yes") )) }) test_that("Summary(multi_cutpointr) is silent", { expect_silent( smcp <- summary( multi_cutpointr(suicide, x = c("age", "dsi"), class = "suicide", pos_class = "yes", silent = TRUE) ) ) expect_silent( smcp <- summary( multi_cutpointr(suicide, x = c("age", "dsi"), class = "suicide", subgroup = "gender", pos_class = "yes", silent = TRUE) ) ) expect_silent( smcp <- summary( multi_cutpointr(suicide, x = c("age", "dsi"), class = "suicide", boot_runs = 5, pos_class = "yes", silent = TRUE) ) ) expect_silent( smcp <- summary( multi_cutpointr(suicide, x = c("age", "dsi"), class = "suicide", subgroup = "gender", boot_runs = 5, pos_class = "yes", silent = TRUE) ) ) }) test_that("multi_cutpointr fetches numeric columns correctly", { tempdat <- iris[1:99, ] tempdat$char <- "XYZ" set.seed(734) tempdat$g <- sample(0:1, size = 99, replace = TRUE) expect_silent( mcp <- multi_cutpointr(tempdat, class = "Species", silent = TRUE) ) expect_equal(nrow(mcp), 5) expect_silent( mcp <- multi_cutpointr(tempdat, class = "Species", subgroup = "g", silent = TRUE) ) expect_equal(nrow(mcp), 8) expect_silent( mcp <- multi_cutpointr(tempdat, class = "Species", subgroup = "g", silent = TRUE, boot_runs = 10) ) expect_equal(nrow(mcp), 8) }) test_that("tidyeval works with cutpointr", { myvar <- "dsi" myclass <- "suicide" mygroup <- "gender" cp <- cutpointr(suicide, !!myvar, !!myclass, !!mygroup) cp2 <- cutpointr(suicide, dsi, suicide, gender) expect_identical(cp %>% dplyr::select(-data, -roc_curve), cp2 %>% dplyr::select(-data, -roc_curve)) expect_silent(summary(cp)) }) test_that("tidyeval works with roc", { myvar <- "dsi" myclass <- "suicide" r <- roc(suicide, !!myvar, !!myclass, pos_class = "yes", neg_class = "no") expect_identical( roc(suicide, dsi, suicide, pos_class = "yes", neg_class = "no"), r ) expect_silent(auc(r)) }) test_that("boot_ci works correctly", { set.seed(1349) cp <- cutpointr(suicide, dsi, suicide, boot_runs = 30) bci <- boot_ci(x = cp, variable = optimal_cutpoint, alpha = 0.05) expect_equal(round(as.numeric(bci$values), 3), c(1, 3.275)) set.seed(1349) cp <- cutpointr(suicide, dsi, suicide, gender, boot_runs = 30) bci <- boot_ci(x = cp, variable = optimal_cutpoint, alpha = 0.05) expect_equal(as.numeric(round(bci$values, 3)), c(2, 2, 1, 4.55)) expect_equal(bci$subgroup, c("female", "female", "male", "male")) }) test_that("boot_test works correctly", { set.seed(123) cp_f <- cutpointr(suicide %>% dplyr::filter(gender == "female"), dsi, suicide, boot_runs = 10, boot_stratify = T) set.seed(924) cp_m <- cutpointr(suicide %>% dplyr::filter(gender == "male"), dsi, suicide, boot_runs = 10, boot_stratify = T) bt <- boot_test(cp_f, cp_m, AUC, in_bag = TRUE) expect_equal(round(as.numeric(bt$p), 3), 0.175) expect_equal(round(as.numeric(bt$z), 2), 1.36) set.seed(9184) cp <- cutpointr(suicide, dsi, suicide, gender, boot_runs = 10) btg <- boot_test(cp, variable = AUC, in_bag = TRUE) expect_equal(as.numeric(round(btg$p, 3)), 0.139) expect_equal(btg$subgroup1, "female") expect_equal(as.numeric(btg$d), as.numeric(bt$d)) dat <- suicide set.seed(765) dat$g <- sample(c("a", "b", "c"), size = nrow(suicide), replace = TRUE) set.seed(745) cp <- cutpointr(dat, dsi, suicide, g, boot_runs = 15, boot_stratify = TRUE, metric = youden) bt <- boot_test(cp, variable = youden) expect_equal(nrow(bt), 3) expect_equal(as.numeric(round(bt$p, 3)), c(0.731, 0.274, 0.378)) expect_equal(as.numeric(round(bt$p_adj, 3)), c(0.821, 0.821, 0.821)) bt <- boot_test(cp, variable = youden, correction = "bonferroni") expect_equal(as.numeric(round(bt$p_adj, 3)), c(1, 0.821, 1)) }) ## runtime too long # test_that("Bootstrap works with multiple cutpoints when not breaking ties", { # set.seed(827) # tempdat <- data.frame(x = rnorm(1000), # y = sample(0:1, size = 1000, replace = TRUE), # g = sample(0:1, size = 1000, replace = TRUE)) # set.seed(73) # cp <- cutpointr(tempdat, x, y, break_ties = c, boot_runs = 200) # expect_silent(summary(cp)) # # set.seed(73) # cp <- cutpointr(tempdat, x, y, g, break_ties = c, boot_runs = 100) # expect_silent(summary(cp)) # }) cutpointr/tests/testthat.R0000644000176200001440000000007613475240564015443 0ustar liggesuserslibrary(testthat) library(cutpointr) test_check("cutpointr") cutpointr/src/0000755000176200001440000000000014066445216013100 5ustar liggesuserscutpointr/src/any_inf.cpp0000644000176200001440000000033613475240564015233 0ustar liggesusers#include using namespace Rcpp; // [[Rcpp::export]] bool any_inf(NumericVector x) { int len = x.size(); for(int i=0; i using namespace Rcpp; // [[Rcpp::export]] LogicalVector get_rev_dups(NumericVector x) { return rev(duplicated(rev(x))); } cutpointr/src/is_equal_cpp.cpp0000644000176200001440000000070113475240564016250 0ustar liggesusers#include using namespace Rcpp; // [[Rcpp::export]] LogicalVector is_equal_cpp_char(CharacterVector x, String y){ Rcpp::LogicalVector r(x.size()); for(int i=0; i using namespace Rcpp; // [[Rcpp::export]] LogicalVector one_unique_num(NumericVector x) { int n = x.size(); double first_val = x[0]; for(int i = 1; i < n; ++i) { if (x[i] != first_val) return false; } return true; } // [[Rcpp::export]] LogicalVector one_unique_char(CharacterVector x) { int n = x.size(); String first_val = x[0]; for(int i = 1; i < n; ++i) { if (x[i] != first_val) return false; } return true; } cutpointr/src/which.cpp0000644000176200001440000000103513475240564014707 0ustar liggesusers#include using namespace Rcpp; // [[Rcpp::export]] IntegerVector which_are_num(NumericVector x, double a) { int nx = x.size(); std::vector y; y.reserve(nx); for(int i = 0; i < nx; i++) { if (x[i] == a) y.push_back(i+1); } return wrap(y); } // [[Rcpp::export]] IntegerVector which_are_char(CharacterVector x, String a) { int nx = x.size(); std::vector y; y.reserve(nx); for(int i = 0; i < nx; i++) { if (x[i] == a) y.push_back(i+1); } return wrap(y); } cutpointr/src/RcppExports.cpp0000644000176200001440000001020613475240564016076 0ustar liggesusers// Generated by using Rcpp::compileAttributes() -> do not edit by hand // Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 #include using namespace Rcpp; // any_inf bool any_inf(NumericVector x); RcppExport SEXP _cutpointr_any_inf(SEXP xSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< NumericVector >::type x(xSEXP); rcpp_result_gen = Rcpp::wrap(any_inf(x)); return rcpp_result_gen; END_RCPP } // get_rev_dups LogicalVector get_rev_dups(NumericVector x); RcppExport SEXP _cutpointr_get_rev_dups(SEXP xSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< NumericVector >::type x(xSEXP); rcpp_result_gen = Rcpp::wrap(get_rev_dups(x)); return rcpp_result_gen; END_RCPP } // is_equal_cpp_char LogicalVector is_equal_cpp_char(CharacterVector x, String y); RcppExport SEXP _cutpointr_is_equal_cpp_char(SEXP xSEXP, SEXP ySEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< CharacterVector >::type x(xSEXP); Rcpp::traits::input_parameter< String >::type y(ySEXP); rcpp_result_gen = Rcpp::wrap(is_equal_cpp_char(x, y)); return rcpp_result_gen; END_RCPP } // is_equal_cpp_num LogicalVector is_equal_cpp_num(NumericVector x, double y); RcppExport SEXP _cutpointr_is_equal_cpp_num(SEXP xSEXP, SEXP ySEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< NumericVector >::type x(xSEXP); Rcpp::traits::input_parameter< double >::type y(ySEXP); rcpp_result_gen = Rcpp::wrap(is_equal_cpp_num(x, y)); return rcpp_result_gen; END_RCPP } // one_unique_num LogicalVector one_unique_num(NumericVector x); RcppExport SEXP _cutpointr_one_unique_num(SEXP xSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< NumericVector >::type x(xSEXP); rcpp_result_gen = Rcpp::wrap(one_unique_num(x)); return rcpp_result_gen; END_RCPP } // one_unique_char LogicalVector one_unique_char(CharacterVector x); RcppExport SEXP _cutpointr_one_unique_char(SEXP xSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< CharacterVector >::type x(xSEXP); rcpp_result_gen = Rcpp::wrap(one_unique_char(x)); return rcpp_result_gen; END_RCPP } // which_are_num IntegerVector which_are_num(NumericVector x, double a); RcppExport SEXP _cutpointr_which_are_num(SEXP xSEXP, SEXP aSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< NumericVector >::type x(xSEXP); Rcpp::traits::input_parameter< double >::type a(aSEXP); rcpp_result_gen = Rcpp::wrap(which_are_num(x, a)); return rcpp_result_gen; END_RCPP } // which_are_char IntegerVector which_are_char(CharacterVector x, String a); RcppExport SEXP _cutpointr_which_are_char(SEXP xSEXP, SEXP aSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< CharacterVector >::type x(xSEXP); Rcpp::traits::input_parameter< String >::type a(aSEXP); rcpp_result_gen = Rcpp::wrap(which_are_char(x, a)); return rcpp_result_gen; END_RCPP } static const R_CallMethodDef CallEntries[] = { {"_cutpointr_any_inf", (DL_FUNC) &_cutpointr_any_inf, 1}, {"_cutpointr_get_rev_dups", (DL_FUNC) &_cutpointr_get_rev_dups, 1}, {"_cutpointr_is_equal_cpp_char", (DL_FUNC) &_cutpointr_is_equal_cpp_char, 2}, {"_cutpointr_is_equal_cpp_num", (DL_FUNC) &_cutpointr_is_equal_cpp_num, 2}, {"_cutpointr_one_unique_num", (DL_FUNC) &_cutpointr_one_unique_num, 1}, {"_cutpointr_one_unique_char", (DL_FUNC) &_cutpointr_one_unique_char, 1}, {"_cutpointr_which_are_num", (DL_FUNC) &_cutpointr_which_are_num, 2}, {"_cutpointr_which_are_char", (DL_FUNC) &_cutpointr_which_are_char, 2}, {NULL, NULL, 0} }; RcppExport void R_init_cutpointr(DllInfo *dll) { R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); R_useDynamicSymbols(dll, FALSE); } cutpointr/vignettes/0000755000176200001440000000000014066445216014321 5ustar liggesuserscutpointr/vignettes/cutpointr.Rmd0000644000176200001440000017015713672457605017036 0ustar liggesusers--- title: "An introduction to cutpointr" author: "Christian Thiele" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{cutpointr} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set(fig.width = 6, fig.height = 5, fig.align = "center") options(rmarkdown.html_vignette.check_title = FALSE) load("vignettedata/vignettedata.Rdata") ``` **cutpointr** is an R package for tidy calculation of "optimal" cutpoints. It supports several methods for calculating cutpoints and includes several metrics that can be maximized or minimized by selecting a cutpoint. Some of these methods are designed to be more robust than the simple empirical optimization of a metric. Additionally, **cutpointr** can automatically bootstrap the variability of the optimal cutpoints and return out-of-bag estimates of various performance metrics. ## Installation You can install **cutpointr** from CRAN using the menu in RStudio or simply: ```{r CRAN, eval = FALSE} install.packages("cutpointr") ``` ## Example For example, the optimal cutpoint for the included data set is 2 when maximizing the sum of sensitivity and specificity. ```{r} library(cutpointr) data(suicide) head(suicide) cp <- cutpointr(suicide, dsi, suicide, method = maximize_metric, metric = sum_sens_spec) ``` ```{r} summary(cp) ``` ```{r} plot(cp) ``` When considering the optimality of a cutpoint, we can only make a judgement based on the sample at hand. Thus, the estimated cutpoint may not be optimal within the population or on unseen data, which is why we sometimes put the "optimal" in quotation marks. `cutpointr` makes assumptions about the direction of the dependency between `class` and `x`, if `direction` and / or `pos_class` or `neg_class` are not specified. The same result as above can be achieved by manually defining `direction` and the positive / negative classes which is slightly faster, since the classes and direction don't have to be determined: ```{r} opt_cut <- cutpointr(suicide, dsi, suicide, direction = ">=", pos_class = "yes", neg_class = "no", method = maximize_metric, metric = youden) ``` `opt_cut` is a data frame that returns the input data and the ROC curve (and optionally the bootstrap results) in a nested tibble. Methods for summarizing and plotting the data and results are included (e.g. `summary`, `plot`, `plot_roc`, `plot_metric`) To inspect the optimization, the function of metric values per cutpoint can be plotted using `plot_metric`, if an optimization function was used that returns a metric column in the `roc_curve` column. For example, the `maximize_metric` and `minimize_metric` functions do so: ```{r} plot_metric(opt_cut) ``` Predictions for new data can be made using `predict`: ```{r} predict(opt_cut, newdata = data.frame(dsi = 0:5)) ``` ## Features - Calculation of optimal cutpoints in binary classification tasks - Tidy output, integrates well with functions from the tidyverse - Functions for plotting ROC curves, metric distributions and more - Bootstrapping for simulating the cutpoint variability and for obtaining out-of-bag estimates of various metrics (as a form of internal validation) with optional parallelisation - Multiple methods for calculating cutpoints - Multiple metrics can be chosen for maximization / minimization - Tidyeval # Calculating cutpoints ## Method functions for cutpoint estimation The included methods for calculating cutpoints are: - `maximize_metric`: Maximize the metric function - `minimize_metric`: Minimize the metric function - `maximize_loess_metric`: Maximize the metric function after LOESS smoothing - `minimize_loess_metric`: Minimize the metric function after LOESS smoothing - `maximize_spline_metric`: Maximize the metric function after spline smoothing - `minimize_spline_metric`: Minimize the metric function after spline smoothing - `maximize_gam_metric`: Maximize the metric function after smoothing via Generalized Additive Models - `minimize_gam_metric`: Minimize the metric function after smoothing via Generalized Additive Models - `maximize_boot_metric`: Bootstrap the optimal cutpoint when maximizing a metric - `minimize_boot_metric`: Bootstrap the optimal cutpoint when minimizing a metric - `oc_manual`: Specify the cutoff value manually - `oc_mean`: Use the sample mean as the "optimal" cutpoint - `oc_median`: Use the sample median as the "optimal" cutpoint - `oc_youden_kernel`: Maximize the Youden-Index after kernel smoothing the distributions of the two classes - `oc_youden_normal`: Maximize the Youden-Index parametrically assuming normally distributed data in both classes ## Metric functions The included metrics to be used with the minimization and maximization methods are: - `accuracy`: Fraction correctly classified - `abs_d_sens_spec`: The absolute difference of sensitivity and specificity - `abs_d_ppv_npv`: The absolute difference between positive predictive value (PPV) and negative predictive value (NPV) - `roc01`: Distance to the point (0,1) on ROC space - `cohens_kappa`: Cohen's Kappa - `sum_sens_spec`: sensitivity + specificity - `sum_ppv_npv`: The sum of positive predictive value (PPV) and negative predictive value (NPV) - `prod_sens_spec`: sensitivity * specificity - `prod_ppv_npv`: The product of positive predictive value (PPV) and negative predictive value (NPV) - `youden`: Youden- or J-Index = sensitivity + specificity - 1 - `odds_ratio`: (Diagnostic) odds ratio - `risk_ratio`: risk ratio (relative risk) - `p_chisquared`: The p-value of a chi-squared test on the confusion matrix - `cost_misclassification`: The sum of the misclassification cost of false positives and false negatives. Additional arguments: cost_fp, cost_fn - `total_utility`: The total utility of true / false positives / negatives. Additional arguments: utility_tp, utility_tn, cost_fp, cost_fn - `F1_score`: The F1-score (2 * TP) / (2 * TP + FP + FN) - `metric_constrain`: Maximize a selected metric given a minimal value of another selected metric - `sens_constrain`: Maximize sensitivity given a minimal value of specificity - `spec_constrain`: Maximize specificity given a minimal value of sensitivity - `acc_constrain`: Maximize accuracy given a minimal value of sensitivity Furthermore, the following functions are included which can be used as metric functions but are more useful for plotting purposes, for example in `plot_cutpointr`, or for defining new metric functions: `tp`, `fp`, `tn`, `fn`, `tpr`, `fpr`, `tnr`, `fnr`, `false_omission_rate`, `false_discovery_rate`, `ppv`, `npv`, `precision`, `recall`, `sensitivity`, and `specificity`. The inputs to the arguments `method` and `metric` are functions so that user-defined functions can easily be supplied instead of the built-in ones. ## Separate subgroups and bootstrapping Cutpoints can be separately estimated on subgroups that are defined by a third variable, `gender` in this case. Additionally, if `boot_runs` is larger zero, `cutpointr` will carry out the usual cutpoint calculation on the full sample, just as before, and additionally on `boot_runs` bootstrap samples. This offers a way of gauging the out-of-sample performance of the cutpoint estimation method. If a subgroup is given, the bootstrapping is carried out separately for every subgroup which is also reflected in the plots and output. ```{r separate subgroups and bootstrapping, eval = FALSE} set.seed(12) opt_cut_b <- cutpointr(suicide, dsi, suicide, boot_runs = 1000) ``` ```{r} opt_cut_b ``` The returned object has the additional column `boot` which is a nested tibble that includes the cutpoints per bootstrap sample along with the metric calculated using the function in `metric` and various default metrics. The metrics are suffixed by `_b` to indicate in-bag results or `_oob` to indicate out-of-bag results: ```{r} opt_cut$boot ``` The summary and plots include additional elements that summarize or display the bootstrap results: ```{r} summary(opt_cut) plot(opt_cut) ``` ### Parallelized bootstrapping Using `foreach` and `doRNG` the bootstrapping can be parallelized easily. The **doRNG** package is being used to make the bootstrap sampling reproducible. ```{r, eval = FALSE} library(doParallel) cl <- makeCluster(2) # 2 cores registerDoParallel(cl) registerDoRNG(12) # Reproducible parallel loops using doRNG opt_cut <- cutpointr(suicide, dsi, suicide, gender, pos_class = "yes", direction = ">=", boot_runs = 1000, allowParallel = TRUE) stopCluster(cl) opt_cut ``` # More robust cutpoint estimation methods ## Bootstrapped cutpoints It has been shown that bagging can substantially improve performance of a wide range of types of models in regression as well as in classification tasks. This method is available for cutpoint estimation via the `maximize_boot_metric` and `minimize_boot_metric` functions. If one of these functions is used as `method`, `boot_cut` bootstrap samples are drawn, the cutpoint optimization is carried out in each one and a summary (e.g. the mean) of the resulting optimal cutpoints on the bootstrap samples is returned as the optimal cutpoint in `cutpointr`. Note that if bootstrap validation is run, i.e. if `boot_runs` is larger zero, an outer bootstrap will be executed. In the bootstrap validation routine `boot_runs` bootstrap samples are generated and each one is again bootstrapped `boot_cut` times. This may lead to long run times, so activating the built-in parallelization may be advisable. The advantages of bootstrapping the optimal cutpoint are that the procedure doesn't possess parameters that have to be tuned, unlike the LOESS smoothing, that it doesn't rely on assumptions, unlike the Normal method, and that it is applicable to any metric that can be used with `minimize_metric` or `maximize_metric`, unlike the Kernel method. Furthermore, like Random Forests cannot be overfit by increasing the number of trees, the bootstrapped cutpoints cannot be overfit by running an excessive amount of `boot_cut` repetitions. ```{r, cache=TRUE} set.seed(100) cutpointr(suicide, dsi, suicide, gender, method = maximize_boot_metric, boot_cut = 200, summary_func = mean, metric = accuracy, silent = TRUE) ``` ## LOESS smoothing for selecting a cutpoint When using `maximize_metric` and `minimize_metric` the optimal cutpoint is selected by searching the maximum or minimum of the metric function. For example, we may want to minimize the misclassification cost. Since false negatives (a suicide attempt was not anticipated) can be regarded as much more severe than false positives we can set the cost of a false negative `cost_fn` for example to ten times the cost of a false positive. ```{r} opt_cut <- cutpointr(suicide, dsi, suicide, gender, method = minimize_metric, metric = misclassification_cost, cost_fp = 1, cost_fn = 10) ``` ```{r} plot_metric(opt_cut) ``` As this "optimal" cutpoint may depend on minor differences between the possible cutoffs, smoothing of the function of metric values by cutpoint value might be desirable, especially in small samples. The `minimize_loess_metric` and `maximize_loess_metric` functions can be used to smooth the function so that the optimal cutpoint is selected based on the smoothed metric values. Options to modify the smoothing, which is implemented using `loess.as` from the **fANCOVA** package, include: - `criterion`: the criterion for automatic smoothing parameter selection: "aicc" denotes bias-corrected AIC criterion, "gcv" denotes generalized cross-validation. - `degree`: the degree of the local polynomials to be used. It can be 0, 1 or 2. - `family`: if "gaussian" fitting is by least-squares, and if "symmetric" a re-descending M estimator is used with Tukey's biweight function. - `user.span`: the user-defined parameter which controls the degree of smoothing. Using parameters for the LOESS smoothing of `criterion = "aicc"`, `degree = 2`, `family = "symmetric"`, and `user.span = 0.7` we get the following smoothed versions of the above metrics: ```{r, message = FALSE} opt_cut <- cutpointr(suicide, dsi, suicide, gender, method = minimize_loess_metric, criterion = "aicc", family = "symmetric", degree = 2, user.span = 0.7, metric = misclassification_cost, cost_fp = 1, cost_fn = 10) ``` ```{r} plot_metric(opt_cut) ``` The optimal cutpoint for the female subgroup changes to 3. Note, though, that there are no reliable rules for selecting the "best" smoothing parameters. Notably, the LOESS smoothing is sensitive to the number of unique cutpoints. A large number of unique cutpoints generally leads to a more volatile curve of metric values by cutpoint value, even after smoothing. Thus, the curve tends to be undersmoothed in that scenario. The unsmoothed metric values are returned in `opt_cut$roc_curve` in the column `m_unsmoothed`. ## Smoothing via Generalized Additive Models for selecting a cutpoint In a similar fashion, the function of metric values per cutpoint can be smoothed using Generalized Additive Models with smooth terms. Internally, `mgcv::gam` carries out the smoothing which can be customized via the arguments `formula` and `optimizer`, see `help("gam", package = "mgcv")`. Most importantly, the GAM can be specified by altering the default formula, for example the smoothing function could be configured to apply cubic regression splines (`"cr"`) as the smooth term. As the `suicide` data has only very few unique cutpoints, it is not very suitable for showcasing the GAM smoothing, so we will use two classes of the `iris` data here. In this case, the purely empirical method and the GAM smoothing lead to identical cutpoints, but in practice the GAM smoothing tends to be more robust, especially with larger data. An attractive feature of the GAM smoothing is that the default values tend to work quite well and usually require no tuning, eliminating researcher degrees of freedom. ```{r} library(ggplot2) exdat <- iris exdat <- exdat[exdat$Species != "setosa", ] opt_cut <- cutpointr(exdat, Petal.Length, Species, method = minimize_gam_metric, formula = m ~ s(x.sorted, bs = "cr"), metric = abs_d_sens_spec) plot_metric(opt_cut) ``` ## Spline smoothing for selecting a cutpoint Again in the same fashion the function of metric values per cutpoint can be smoothed using smoothing splines. By default, the number of knots is automatically chosen using the `cutpoint_knots` function. That function uses `stats::.nknots.smspl`, which is the default in `stats::smooth.spline` to pick the number of knots. Alternatively, the number of knots can be set manually and also the other smoothing parameters of `stats::smooth.spline` can be set as desired. For details see `?maximize_spline_metric`. ```{r} opt_cut <- cutpointr(suicide, dsi, suicide, gender, method = minimize_spline_metric, spar = 0.4, metric = misclassification_cost, cost_fp = 1, cost_fn = 10) plot_metric(opt_cut) ``` ### Parametric method assuming normality The Normal method in `oc_youden_normal` is a parametric method for maximizing the Youden-Index or equivalently the sum of $Se$ and $Sp$. It relies on the assumption that the predictor for both the negative and positive observations is normally distributed. In that case it can be shown that $$c^* = \frac{(\mu_P \sigma_N^2 - \mu_N \sigma_P^2) - \sigma_N \sigma_P \sqrt{(\mu_N - \mu_P)^2 + (\sigma_N^2 - \sigma_P^2) log(\sigma_N^2 / \sigma_P^2)}}{\sigma_N^2 - \sigma_P^2}$$ where the negative class is normally distributed with $\sim N(\mu_N, \sigma_N^2)$ and the positive class independently normally distributed with $\sim N(\mu_P, \sigma_P^2)$ provides the optimal cutpoint $c^*$ that maximizes the Youden-Index. If $\sigma_N$ and $\sigma_P$ are equal, the expression can be simplified to $c^* = \frac{\mu_N + \mu_P}{2}$. However, the `oc_youden_normal` method in cutpointr always assumes unequal standard deviations. Since this method does not select a cutpoint from the observed predictor values, it is questionable which values for $Se$ and $Sp$ should be reported. Here, the Youden-Index can be calculated as $$J = \Phi(\frac{c^* - \mu_N}{\sigma_N}) - \Phi(\frac{c^* - \mu_P}{\sigma_P})$$ if the assumption of normality holds. However, since there exist several methods that do not select cutpoints from the available observations and to unify the reporting of metrics for these methods, **cutpointr** reports all metrics, e.g. $Se$ and $Sp$, based on the empirical observations. ```{r} cutpointr(suicide, dsi, suicide, gender, method = oc_youden_normal) ``` ### Nonparametric kernel method A nonparametric alternative is the Kernel method [@fluss_estimation_2005]. Here, the empirical distribution functions are smoothed using the Gaussian kernel functions $\hat{F}_N(t) = \frac{1}{n} \sum^n_{i=1} \Phi(\frac{t - y_i}{h_y})$ and $\hat{G}_P(t) = \frac{1}{m} \sum^m_{i=1} \Phi(\frac{t - x_i}{h_x})$ for the negative and positive classes respectively. Following Silverman's plug-in "rule of thumb" the bandwidths are selected as $h_y = 0.9 * min\{s_y, iqr_y/1.34\} * n^{-0.2}$ and $h_x = 0.9 * min\{s_x, iqr_x/1.34\} * m^{-0.2}$ where $s$ is the sample standard deviation and $iqr$ is the inter quartile range. It has been demonstrated that AUC estimation is rather insensitive to the choice of the bandwidth procedure [@faraggi_estimation_2002] and thus the plug-in bandwidth estimator has also been recommended for cutpoint estimation. The `oc_youden_kernel` function in **cutpointr** uses a Gaussian kernel and the direct plug-in method for selecting the bandwidths. The kernel smoothing is done via the `bkde` function from the **KernSmooth** package [@wand_kernsmooth:_2013]. Again, there is a way to calculate the Youden-Index from the results of this method [@fluss_estimation_2005] which is $$\hat{J} = max_c \{\hat{F}_N(c) - \hat{G}_N(c) \}$$ but as before we prefer to report all metrics based on applying the cutpoint that was estimated using the Kernel method to the empirical observations. ```{r} cutpointr(suicide, dsi, suicide, gender, method = oc_youden_kernel) ``` # Additional features ## Calculating only the ROC curve When running `cutpointr`, a ROC curve is by default returned in the column `roc_curve`. This ROC curve can be plotted using `plot_roc`. Alternatively, if only the ROC curve is desired and no cutpoint needs to be calculated, the ROC curve can be created using `roc()` and plotted using `plot_cutpointr`. The `roc` function, unlike `cutpointr`, does not determine `direction`, `pos_class` or `neg_class` automatically. ```{r, fig.width=4, fig.height=3} roc_curve <- roc(data = suicide, x = dsi, class = suicide, pos_class = "yes", neg_class = "no", direction = ">=") auc(roc_curve) head(roc_curve) plot_roc(roc_curve) ``` ## Midpoints So far - which is the default in `cutpointr` - we have considered all unique values of the predictor as possible cutpoints. An alternative could be to use a sequence of equidistant values instead, for example in the case of the `suicide` data all integers in $[0, 10]$. However, with very sparse data and small intervals between the candidate cutpoints (i.e. a 'dense' sequence like `seq(0, 10, by = 0.01)`) this leads to the uninformative evaluation of large ranges of cutpoints that all result in the same metric value. A more elegant alternative, not only for the case of sparse data, that is supported by **cutpointr** is the use of a mean value of the optimal cutpoint and the next highest (if `direction = ">="`) or the next lowest (if `direction = "<="`) predictor value in the data. The result is an optimal cutpoint that is equal to the cutpoint that would be obtained using an infinitely dense sequence of candidate cutpoints and is thus usually more efficient computationally. This behavior can be activated by setting `use_midpoints = TRUE`, which is the default. If we use this setting, we obtain an optimal cutpoint of 1.5 for the complete sample on the `suicide` data instead of 2 when maximizing the sum of sensitivity and specificity. Assume the following small data set: ```{r} dat <- data.frame(outcome = c("neg", "neg", "neg", "pos", "pos", "pos", "pos"), pred = c(1, 2, 3, 8, 11, 11, 12)) ``` Since the distance of the optimal cutpoint (8) to the next lowest observation (3) is rather large we arrive at a range of possible cutpoints that all maximize the metric. In the case of this kind of sparseness it might for example be desirable to classify a new observation with a predictor value of 4 as belonging to the negative class. If `use_midpoints` is set to `TRUE`, the mean of the optimal cutpoint and the next lowest observation is returned as the optimal cutpoint, if direction is `>=`. The mean of the optimal cutpoint and the next highest observation is returned as the optimal cutpoint, if `direction = "<="`. ```{r} opt_cut <- cutpointr(dat, x = pred, class = outcome, use_midpoints = TRUE) plot_x(opt_cut) ``` A simulation demonstrates more clearly that setting `use_midpoints = TRUE` avoids biasing the cutpoints. To simulate the bias of the metric functions, the predictor values of both classes were drawn from normal distributions with constant standard deviations of 10, a constant mean of the negative class of 100 and higher mean values of the positive class that are selected in such a way that optimal Youden-Index values of 0.2, 0.4, 0.6, and 0.8 result in the population. Samples of 9 different sizes were drawn and the cutpoints that maximize the Youden-Index were estimated. The simulation was repeated 10000 times. As can be seen by the mean error, `use_midpoints = TRUE` eliminates the bias that is introduced by otherwise selecting the value of an observation as the optimal cutpoint. If `direction = ">="`, as in this case, the observation that represents the optimal cutpoint is the highest possible cutpoint that leads to the optimal metric value and thus the biases are positive. The methods `oc_youden_normal` and `oc_youden_kernel` are always unbiased, as they don't select a cutpoint based on the ROC-curve or the function of metric values per cutpoint. ```{r, echo = FALSE} plotdat_nomidpoints <- structure(list(sim_nr = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 16L, 16L, 16L, 16L, 16L, 16L, 16L, 16L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 18L, 18L, 18L, 18L, 18L, 18L, 18L, 18L, 19L, 19L, 19L, 19L, 19L, 19L, 19L, 19L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 22L, 22L, 22L, 22L, 22L, 22L, 22L, 22L, 23L, 23L, 23L, 23L, 23L, 23L, 23L, 23L, 24L, 24L, 24L, 24L, 24L, 24L, 24L, 24L, 25L, 25L, 25L, 25L, 25L, 25L, 25L, 25L, 26L, 26L, 26L, 26L, 26L, 26L, 26L, 26L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 28L, 28L, 28L, 28L, 28L, 28L, 28L, 28L, 29L, 29L, 29L, 29L, 29L, 29L, 29L, 29L, 30L, 30L, 30L, 30L, 30L, 30L, 30L, 30L, 31L, 31L, 31L, 31L, 31L, 31L, 31L, 31L, 32L, 32L, 32L, 32L, 32L, 32L, 32L, 32L, 33L, 33L, 33L, 33L, 33L, 33L, 33L, 33L, 34L, 34L, 34L, 34L, 34L, 34L, 34L, 34L, 35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L, 36L, 36L, 36L, 36L, 36L, 36L, 36L, 36L), method = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L), .Label = c("emp", "normal", "loess", "boot", "spline", "spline_20", "kernel", "gam" ), class = "factor"), n = c(30, 30, 30, 30, 30, 30, 30, 30, 50, 50, 50, 50, 50, 50, 50, 50, 75, 75, 75, 75, 75, 75, 75, 75, 100, 100, 100, 100, 100, 100, 100, 100, 150, 150, 150, 150, 150, 150, 150, 150, 250, 250, 250, 250, 250, 250, 250, 250, 500, 500, 500, 500, 500, 500, 500, 500, 750, 750, 750, 750, 750, 750, 750, 750, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 30, 30, 30, 30, 30, 30, 30, 30, 50, 50, 50, 50, 50, 50, 50, 50, 75, 75, 75, 75, 75, 75, 75, 75, 100, 100, 100, 100, 100, 100, 100, 100, 150, 150, 150, 150, 150, 150, 150, 150, 250, 250, 250, 250, 250, 250, 250, 250, 500, 500, 500, 500, 500, 500, 500, 500, 750, 750, 750, 750, 750, 750, 750, 750, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 30, 30, 30, 30, 30, 30, 30, 30, 50, 50, 50, 50, 50, 50, 50, 50, 75, 75, 75, 75, 75, 75, 75, 75, 100, 100, 100, 100, 100, 100, 100, 100, 150, 150, 150, 150, 150, 150, 150, 150, 250, 250, 250, 250, 250, 250, 250, 250, 500, 500, 500, 500, 500, 500, 500, 500, 750, 750, 750, 750, 750, 750, 750, 750, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 30, 30, 30, 30, 30, 30, 30, 30, 50, 50, 50, 50, 50, 50, 50, 50, 75, 75, 75, 75, 75, 75, 75, 75, 100, 100, 100, 100, 100, 100, 100, 100, 150, 150, 150, 150, 150, 150, 150, 150, 250, 250, 250, 250, 250, 250, 250, 250, 500, 500, 500, 500, 500, 500, 500, 500, 750, 750, 750, 750, 750, 750, 750, 750, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000), mean_err = c(0.532157164015659, 0.0344907054484091, 1.09430750651166, 0.847845162156675, 1.72337372126503, 0.893756658507988, 0.0430309247027736, 0.785821459035346, 0.368063404388512, 0.0256197760404459, 0.54480529648463, 0.54385597929651, 0.657325657699579, 0.578611116865437, 0.0400491342691897, 0.515688005217413, 0.256713912589642, 0.0444582875885996, 0.326975493112402, 0.371128780921122, 0.473515115741104, 0.389519558405289, 0.105044360789378, 0.301924717299333, 0.207750921776918, -0.00318128936770314, 0.215170156089776, 0.27218780048926, 0.260519564021842, 0.236792923882582, 0.0209319074923902, 0.232957055204834, 0.0726605917614469, -0.00282823355849125, 0.0753216783313991, 0.147121931849656, 0.0986417724955371, 0.10048009778446, -0.0117861260923649, 0.0650845904350442, 0.0985144485083747, 0.00601003227249322, 0.107439979908118, 0.120777421732797, 0.098470489820427, 0.0940946984227826, 0.0340166854141625, 0.107851118082414, 0.0249685210781582, -0.00275219600614378, 0.0258069390207201, 0.0303381972274654, -0.000994602151869198, 0.00196854833683764, -0.0172319489562159, 0.0230957871932473, 0.00787486424680835, -0.018438041997315, -0.000808033567394628, -0.00151904153864496, -0.0258118523805697, -0.020984156892953, -0.0411584927473141, -0.0462075435919094, 0.0481149217843661, -0.0115241085997692, 0.0278045708419731, 0.0358588316426625, 0.0424473909450939, 0.0379773233328197, 0.0298772985879321, 0.0494939492036379, 0.561286668337778, 0.0210874502384648, 0.607711822769155, 0.944733906256477, 1.32069801051061, 0.623604782428556, 0.0138075109769806, 0.640859854412358, 0.284873604303057, -0.0170357985365701, 0.273426417633118, 0.524432737895336, 0.355003110979807, 0.312837607951434, -0.0316296929553873, 0.270109834098986, 0.174110335581819, 0.0253101719615279, 0.199956222742702, 0.375485416120771, 0.278956745944806, 0.244245525945888, 0.0325126314233263, 0.253352659868514, 0.154840760004461, 0.00231589709639472, 0.154412480165179, 0.264847742842386, 0.196572744185608, 0.182934783774992, 0.0207139021497755, 0.17351041376412, 0.14190910348156, -0.000766834484010096, 0.159975205214477, 0.191222128926019, 0.119768252112669, 0.12033372914036, -0.00429047209392067, 0.120982527821078, 0.0756304869484406, -0.00890884219048113, 0.0727782693168392, 0.118690444738942, 0.0814898789647033, 0.0799724348001957, 0.0182926240912726, 0.0887155007804252, 0.00799604720502299, 0.000599148388616836, -0.00567769035990384, 0.0358412514670032, 0.0308474979074875, 0.0341668723768997, -0.000180318451026095, 0.0180733341290925, 0.00456876236626807, 0.00150574966485876, 0.011152095953916, 0.0176039119729626, 0.00608274255434991, 0.0146257828313115, -0.0108877417404102, 0.00341198000323035, -0.00198459880370283, 0.0026551895445694, 0.00199040664534129, 0.0150165794544221, 0.00646287144368147, 0.00999205240904708, -0.00850278571195971, 0.000833666619266177, 0.714730067273087, -0.00916546079360956, 0.662799490366986, 1.18552468844156, 1.25901933062308, 0.672701515532179, 0.0311066140197676, 0.699068058809396, 0.451908043813962, 0.0131716226592205, 0.429551369887738, 0.697928133235757, 0.445367768988423, 0.408463448982185, 0.0318707241721211, 0.406284953982951, 0.257736307754364, -0.00525924423719458, 0.236977000055322, 0.429144726596141, 0.291381752107184, 0.267557606428613, 0.0103657879176852, 0.254728590646094, 0.187783398487578, -0.00216064381479362, 0.209025103860707, 0.318293592390017, 0.216751610346408, 0.195630579126633, -0.00355723971644246, 0.174111826408428, 0.151010324964235, 0.0152409223899092, 0.159002511320467, 0.214643583389694, 0.136211731513269, 0.138948149207635, 0.00736196817594524, 0.115637867729083, 0.0491348055596302, -0.00133957946235943, 0.0507437758212659, 0.103956325245849, 0.0641182216839426, 0.0721933081297794, -0.0124376134651938, 0.0632317888879588, 0.0322195712438111, 0.00170122889182022, 0.0287526766624194, 0.0589662164030242, 0.0348535721709848, 0.039527944642463, -0.00617539706415593, 0.0274246010641889, 0.0325877909680824, 0.00530528253248245, 0.0221776555499961, 0.0389702052631117, 0.0221602091288215, 0.0254478639695596, -0.0016189234058987, 0.0197144417326668, -0.00632485262604172, -0.00364979854195596, -0.00276076468388984, 0.0126267527301874, 0.0123592498266038, 0.0154921632247644, -0.00591512196680815, 0.0098685016547149, 1.19276916750486, -0.0296831640401583, 0.99406393593888, 1.95758669445116, 1.45842790978446, 0.916899913902239, -0.0240222410217233, 1.00771193034927, 0.748151091428865, 0.001671855025917, 0.665180535306263, 1.1777049634557, 0.578603609273264, 0.546625362141714, 0.0292152981607387, 0.615230814912951, 0.417886753756131, 0.00324593885807739, 0.406076310942717, 0.732191741449251, 0.352684769616612, 0.326901376027897, -0.000759357576337989, 0.350075431324921, 0.310927617707656, -0.0107255472998434, 0.28102101085112, 0.514683023356017, 0.24913510139508, 0.235155452507568, -0.0220885572014814, 0.243370611433649, 0.209652330609093, -0.00502865663759991, 0.2172246261346, 0.356540958804122, 0.172121720418057, 0.17487914828986, 0.00365942442127361, 0.176594681455494, 0.126956927057327, -0.00270525933073803, 0.120116234221594, 0.210827536708082, 0.101520409193932, 0.101379097920023, 0.00238043252144371, 0.113027315928011, 0.0598624378953727, -0.00538838415690431, 0.0568400730102315, 0.0978115258288965, 0.0454207684906316, 0.0473140143579152, -0.00165813015281622, 0.0521772135812508, 0.0530224090961669, -0.000416993405198653, 0.0353236911458531, 0.0605493601241619, 0.0316204159297213, 0.0344789374555544, -0.00446984887315054, 0.0328807595695966, 0.0396438546423947, -0.00331466369719113, 0.0379029847219126, 0.0572435100638761, 0.0253269328104989, 0.0235663211070417, 0.00220241478536399, 0.0307132312422208), youden = c(0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8 )), row.names = c(NA, -288L), group_sizes = c(8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L ), biggest_group_size = 8L, class = c("grouped_df", "tbl_df", "tbl", "data.frame"), groups = structure(list(sim_nr = 1:36, .rows = list(1:8, 9:16, 17:24, 25:32, 33:40, 41:48, 49:56, 57:64, 65:72, 73:80, 81:88, 89:96, 97:104, 105:112, 113:120, 121:128, 129:136, 137:144, 145:152, 153:160, 161:168, 169:176, 177:184, 185:192, 193:200, 201:208, 209:216, 217:224, 225:232, 233:240, 241:248, 249:256, 257:264, 265:272, 273:280, 281:288)), row.names = c(NA, -36L), class = c("tbl_df", "tbl", "data.frame"), .drop = TRUE)) ``` ```{r, echo = FALSE} library(dplyr) ggplot(plotdat_nomidpoints %>% filter(!(method %in% c("spline_20"))), aes(x = n, y = mean_err, color = method, shape = method)) + geom_line() + geom_point() + facet_wrap(~ youden, scales = "fixed") + scale_shape_manual(values = 1:nlevels(plotdat_nomidpoints$method)) + scale_x_log10(breaks = c(30, 50, 75, 100, 150, 250, 500, 750, 1000)) + ggtitle("Bias of all methods when use_midpoints = FALSE", "normally distributed data, 10000 repetitions of simulation") ``` ## Finding all cutpoints with acceptable performance By default, most packages only return the "best" cutpoint and disregard other cutpoints with quite similar performance, even if the performance differences are minuscule. **cutpointr** makes this process more explicit via the `tol_metric` argument. For example, if all cutpoints are of interest that achieve at least an accuracy within `0.05` of the optimally achievable accuracy, `tol_metric` can be set to `0.05` and also those cutpoints will be returned. In the case of the `suicide` data and when maximizing the sum of sensitivity and specificity, empirically the cutpoints 2 and 3 lead to quite similar performances. If `tol_metric` is set to `0.05`, both will be returned. ```{r} opt_cut <- cutpointr(suicide, dsi, suicide, metric = sum_sens_spec, tol_metric = 0.05, break_ties = c) library(tidyr) opt_cut %>% select(optimal_cutpoint, sum_sens_spec) %>% unnest(cols = c(optimal_cutpoint, sum_sens_spec)) ``` ## Manual and mean / median cutpoints Using the `oc_manual` function the optimal cutpoint will not be determined based on, for example, a metric but is instead set manually using the `cutpoint` argument. This is useful for supplying and evaluating cutpoints that were found in the literature or in other external sources. The `oc_manual` function could also be used to set the cutpoint to the sample mean using `cutpoint = mean(data$x)`. However, this may introduce bias into the bootstrap validation procedure, since the actual mean of the population is not known and thus the mean to be used as the cutpoint should be automatically determined in every resample. To do so, the `oc_mean` and `oc_median` functions can be used. ```{r, eval = FALSE} set.seed(100) opt_cut_manual <- cutpointr(suicide, dsi, suicide, method = oc_manual, cutpoint = mean(suicide$dsi), boot_runs = 1000) set.seed(100) opt_cut_mean <- cutpointr(suicide, dsi, suicide, method = oc_mean, boot_runs = 1000) ``` ## Nonstandard evaluation via tidyeval The arguments to `cutpointr` do not need to be enclosed in quotes. This is possible thanks to nonstandard evaluation of the arguments, which are evaluated on `data`. Functions that use nonstandard evaluation are often not suitable for programming with. The use of nonstandard evaluation may lead to scoping problems and subsequent obvious as well as possibly subtle errors. **cutpointr** uses tidyeval internally and accordingly the same rules as for programming with `dplyr` apply. Arguments can be unquoted with `!!`: ```{r, eval = FALSE} myvar <- "dsi" cutpointr(suicide, !!myvar, suicide) ``` ## ROC curve and optimal cutpoint for multiple variables Alternatively, we can map the standard evaluation version `cutpointr` to the column names. If `direction` and / or `pos_class` and `neg_class` are unspecified, these parameters will automatically be determined by **cutpointr** so that the AUC values for all variables will be $> 0.5$. We could do this manually, e.g. using `purrr::map`, but to make this task more convenient `multi_cutpointr` can be used to achieve the same result. It maps multiple predictor columns to `cutpointr`, by default all numeric columns except for the class column. ```{r} mcp <- multi_cutpointr(suicide, class = suicide, pos_class = "yes", use_midpoints = TRUE, silent = TRUE) summary(mcp) ``` ## Accessing `data`, `roc_curve`, and `boot` The object returned by `cutpointr` is of the classes `cutpointr`, `tbl_df`, `tbl`, and `data.frame`. Thus, it can be handled like a usual data frame. The columns `data`, `roc_curve`, and `boot` consist of nested data frames, which means that these are list columns whose elements are data frames. They can either be accessed using `[` or by using functions from the tidyverse. If subgroups were given, the output contains one row per subgroup and the function that accesses the data should be mapped to every row or the data should be grouped by subgroup. ```{r, eval = FALSE, message = FALSE} set.seed(123) opt_cut_b_g <- cutpointr(suicide, dsi, suicide, gender, boot_runs = 1000) ``` ```{r, message = FALSE} # Using dplyr and tidyr library(tidyr) opt_cut_b_g %>% group_by(subgroup) %>% select(subgroup, boot) %>% unnest(cols = boot) %>% summarise(sd_oc_boot = sd(optimal_cutpoint), m_oc_boot = mean(optimal_cutpoint), m_acc_oob = mean(acc_oob)) ``` ## Adding metrics to the result of cutpointr() or roc() By default, the output of `cutpointr` includes the optimized metric and several other metrics. The `add_metric` function adds further metrics. Here, we're adding the negative predictive value (NPV) and the positive predictive value (PPV) at the optimal cutpoint per subgroup: ```{r} cutpointr(suicide, dsi, suicide, gender, metric = youden, silent = TRUE) %>% add_metric(list(ppv, npv)) %>% select(subgroup, optimal_cutpoint, youden, ppv, npv) ``` In the same fashion, additional metric columns can be added to a `roc_cutpointr` object: ```{r} roc(data = suicide, x = dsi, class = suicide, pos_class = "yes", neg_class = "no", direction = ">=") %>% add_metric(list(cohens_kappa, F1_score)) %>% select(x.sorted, tp, fp, tn, fn, cohens_kappa, F1_score) %>% head() ``` ## User-defined functions ### method User-defined functions can be supplied to `method`, which is the function that is responsible for returning the optimal cutpoint. To define a new method function, create a function that may take as input(s): - `data`: A `data.frame` or `tbl_df` - `x`: (character) The name of the predictor variable - `class`: (character) The name of the class variable - `metric_func`: A function for calculating a metric, e.g. accuracy. Note that the method function does not necessarily have to accept this argument - `pos_class`: The positive class - `neg_class`: The negative class - `direction`: `">="` if the positive class has higher x values, `"<="` otherwise - `tol_metric`: (numeric) In the built-in methods, all cutpoints will be returned that lead to a metric value in the interval [m_max - tol_metric, m_max + tol_metric] where m_max is the maximum achievable metric value. This can be used to return multiple decent cutpoints and to avoid floating-point problems. - `use_midpoints`: (logical) In the built-in methods, if TRUE (default FALSE) the returned optimal cutpoint will be the mean of the optimal cutpoint and the next highest observation (for direction = ">") or the next lowest observation (for direction = "<") which avoids biasing the optimal cutpoint. - `...`: Further arguments that are passed to `metric` or that can be captured inside of `method` The function should return a data frame or tibble with one row, the column `optimal_cutpoint`, and an optional column with an arbitrary name with the metric value at the optimal cutpoint. For example, a function for choosing the cutpoint as the mean of the independent variable could look like this: ```{r, eval = FALSE} mean_cut <- function(data, x, ...) { oc <- mean(data[[x]]) return(data.frame(optimal_cutpoint = oc)) } ``` If a `method` function does not return a metric column, the default `sum_sens_spec`, the sum of sensitivity and specificity, is returned as the extra metric column in addition to accuracy, sensitivity and specificity. Some `method` functions that make use of the additional arguments (that are captured by `...`) are already included in **cutpointr**, see the list at the top. Since these functions are arguments to `cutpointr` their code can be accessed by simply typing their name, see for example `oc_youden_normal`. ### metric User defined `metric` functions can be used as well. They are mainly useful in conjunction with `method = maximize_metric`, `method = minimize_metric`, or one of the other minimization and maximization functions. In case of a different `method` function `metric` will only be used as the main out-of-bag metric when plotting the result. The `metric` function should accept the following inputs as vectors: - `tp`: Vector of true positives - `fp`: Vector of false positives - `tn`: Vector of true negatives - `fn`: Vector of false negatives - `...`: Further arguments The function should return a numeric vector, a matrix, or a `data.frame` with one column. If the column is named, the name will be included in the output and plots. Avoid using names that are identical to the column names that are by default returned by **cutpointr**, as such names will be prefixed by `metric_` in the output. The inputs (`tp`, `fp`, `tn`, and `fn`) are vectors. The code of the included metric functions can be accessed by simply typing their name. For example, this is the `misclassification_cost` metric function: ```{r} misclassification_cost ``` # Plotting **cutpointr** includes several convenience functions for plotting data from a `cutpointr` object. These include: - `plot_cutpointr`: General purpose plotting function for cutpointr or roc_cutpointr objects - `plot_cut_boot`: Plot the bootstrapped distribution of optimal cutpoints - `plot_metric`: If `maximize_metric` or `minimize_metric` was used this function plots all possible cutoffs on the x-axis vs. the respective metric values on the y-axis. If bootstrapping was run, a confidence interval based on the bootstrapped distribution of metric values at each cutpoint can be displayed. To display no confidence interval set `conf_lvl = 0`. - `plot_metric_boot`: Plot the distribution of out-of-bag metric values - `plot_precision_recall`: Plot the precision recall curve - `plot_sensitivity_specificity`: Plot all cutpoints vs. sensitivity and specificity - `plot_roc`: Plot the ROC curve - `plot_x`: Plot the distribution of the predictor variable ```{r, fig.width=4, fig.height=3} plot_cut_boot(opt_cut_b_g) plot_metric(opt_cut_b_g, conf_lvl = 0.9) plot_metric_boot(opt_cut_b_g) plot_precision_recall(opt_cut_b_g) plot_sensitivity_specificity(opt_cut_b_g) plot_roc(opt_cut_b_g) ``` All plot functions, except for the standard plot method that returns a composed plot, return `ggplot` objects than can be further modified. For example, changing labels, title, and the theme can be achieved this way: ```{r, fig.width=4, fig.height=3} p <- plot_x(opt_cut_b_g) p + ggtitle("Distribution of dsi") + theme_minimal() + xlab("Depression score") ``` ## Flexible plotting function Using `plot_cutpointr` any metric can be chosen to be plotted on the x- or y-axis and results of `cutpointr()` as well as `roc()` can be plotted. If a `cutpointr` object is to be plotted, it is thus irrelevant which `metric` function was chosen for cutpoint estimation. Any metric that can be calculated based on the ROC curve can be subsequently plotted as only the true / false positives / negatives over all cutpoints are needed. That way, not only the above plots can be produced, but also any combination of two metrics (or metric functions) and / or cutpoints. The built-in metric functions as well as user-defined functions or anonymous functions can be supplied to `xvar` and `yvar`. If bootstrapping was run, confidence intervals can be plotted around the y-variable. This is especially useful if the cutpoints, available in the `cutpoints` function, are placed on the x-axis. Note that confidence intervals can only be correctly plotted if the values of `xvar` are constant across bootstrap samples. For example, confidence intervals for TPR by FPR (a ROC curve) cannot be plotted easily, as the values of the false positive rate vary per bootstrap sample. ```{r, fig.width=4, fig.height=3, cache=FALSE} plot_cutpointr(opt_cut_b, xvar = cutpoints, yvar = sum_sens_spec, conf_lvl = 0.9) plot_cutpointr(opt_cut_b, xvar = fpr, yvar = tpr, aspect_ratio = 1, conf_lvl = 0) plot_cutpointr(opt_cut_b, xvar = cutpoint, yvar = tp, conf_lvl = 0.9) + geom_point() ``` ## Manual plotting Since `cutpointr` returns a `data.frame` with the original data, bootstrap results, and the ROC curve in nested tibbles, these data can be conveniently extracted and plotted manually. The relevant nested tibbles are in the columns `data`, `roc_curve` and `boot`. The following is an example of accessing and plotting the grouped data. ```{r, fig.width=4, fig.height=3} opt_cut_b_g %>% select(data, subgroup) %>% unnest(cols = data) %>% ggplot(aes(x = suicide, y = dsi)) + geom_boxplot(alpha = 0.3) + facet_grid(~subgroup) ``` # Benchmarks To offer a comparison to established solutions, **cutpointr** will be benchmarked against `optimal.cutpoints` from the **OptimalCutpoints** package, **ThresholdROC** and custom functions based on the **ROCR** and **pROC** packages. By generating data of different sizes the benchmarks will offer a comparison of the scalability of the different solutions. Using `prediction` and `performance` from the **ROCR** package and `roc` from the **pROC** package, we can write functions for computing the cutpoint that maximizes the sum of sensitivity and specificity. **pROC** has a built-in function to optimize a few metrics: ```{r, eval = FALSE} # Return cutpoint that maximizes the sum of sensitivity and specificiy # ROCR package rocr_sensspec <- function(x, class) { pred <- ROCR::prediction(x, class) perf <- ROCR::performance(pred, "sens", "spec") sens <- slot(perf, "y.values")[[1]] spec <- slot(perf, "x.values")[[1]] cut <- slot(perf, "alpha.values")[[1]] cut[which.max(sens + spec)] } # pROC package proc_sensspec <- function(x, class) { r <- pROC::roc(class, x, algorithm = 2, levels = c(0, 1), direction = "<") pROC::coords(r, "best", ret="threshold", transpose = FALSE)[1] } ``` The benchmarking will be carried out using the **microbenchmark** package and randomly generated data. The values of the `x` predictor variable are drawn from a normal distribution which leads to a lot more unique values than were encountered before in the `suicide` data. Accordingly, the search for an optimal cutpoint is much more demanding, if all possible cutpoints are evaluated. Benchmarks are run for sample sizes of 100, 1000, 1e4, 1e5, 1e6, and 1e7. For low sample sizes **cutpointr** is slower than the other solutions. While this should be of low practical importance, **cutpointr** scales more favorably with increasing sample size. The speed disadvantage in small samples that leads to the lower limit of around 25ms is mainly due to the nesting of the original data and the results that makes the compact output of `cutpointr` possible. This observation is emphasized by the fact that `cutpointr::roc` is quite fast also in small samples. For sample sizes > 1e5 **cutpointr** is a little faster than the function based on **ROCR** and **pROC**. Both of these solutions are generally faster than **OptimalCutpoints** and **ThresholdROC** with the exception of small samples. **OptimalCutpoints** and **ThresholdROC** had to be excluded from benchmarks with more than 1e4 observations due to high memory requirements and/or excessive run times, rendering the use of these packages in larger samples impractical. ```{r, eval = FALSE, echo = FALSE} library(OptimalCutpoints) library(ThresholdROC) n <- 100 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) x_pos <- dat$x[dat$y == 1] x_neg <- dat$x[dat$y == 0] bench_100 <- microbenchmark::microbenchmark( cutpointr(dat, x, y, pos_class = 1, neg_class = 0, direction = ">=", metric = youden, break_ties = mean), rocr_sensspec(dat$x, dat$y), proc_sensspec(dat$x, dat$y), optimal.cutpoints(X = "x", status = "y", tag.healthy = 0, methods = "Youden", data = dat), thres2(k1 = x_neg, k2 = x_pos, rho = 0.5, method = "empirical", ci = FALSE), times = 100, unit = "ms" ) n <- 1000 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) x_pos <- dat$x[dat$y == 1] x_neg <- dat$x[dat$y == 0] bench_1000 <- microbenchmark::microbenchmark( cutpointr(dat, x, y, pos_class = 1, neg_class = 0, direction = ">=", metric = youden, break_ties = mean), rocr_sensspec(dat$x, dat$y), proc_sensspec(dat$x, dat$y), optimal.cutpoints(X = "x", status = "y", tag.healthy = 0, methods = "Youden", data = dat), thres2(k1 = x_neg, k2 = x_pos, rho = 0.5, method = "empirical", ci = FALSE), times = 100, unit = "ms" ) n <- 10000 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) x_pos <- dat$x[dat$y == 1] x_neg <- dat$x[dat$y == 0] bench_10000 <- microbenchmark::microbenchmark( cutpointr(dat, x, y, pos_class = 1, neg_class = 0, direction = ">=", metric = youden, break_ties = mean, silent = TRUE), rocr_sensspec(dat$x, dat$y), optimal.cutpoints(X = "x", status = "y", tag.healthy = 0, methods = "Youden", data = dat), proc_sensspec(dat$x, dat$y), thres2(k1 = x_neg, k2 = x_pos, rho = 0.5, method = "empirical", ci = FALSE), times = 100 ) n <- 1e5 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) bench_1e5 <- microbenchmark::microbenchmark( cutpointr(dat, x, y, pos_class = 1, neg_class = 0, direction = ">=", metric = youden, break_ties = mean), rocr_sensspec(dat$x, dat$y), proc_sensspec(dat$x, dat$y), times = 100, unit = "ms" ) n <- 1e6 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) bench_1e6 <- microbenchmark::microbenchmark( cutpointr(dat, x, y, pos_class = 1, neg_class = 0, direction = ">=", metric = youden, break_ties = mean), rocr_sensspec(dat$x, dat$y), proc_sensspec(dat$x, dat$y), times = 30, unit = "ms" ) n <- 1e7 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) bench_1e7 <- microbenchmark::microbenchmark( cutpointr(dat, x, y, pos_class = 1, neg_class = 0, direction = ">=", metric = youden, break_ties = mean), rocr_sensspec(dat$x, dat$y), proc_sensspec(dat$x, dat$y), times = 30, unit = "ms" ) results <- rbind( data.frame(time = summary(bench_100)$median, Solution = summary(bench_100)$expr, n = 100), data.frame(time = summary(bench_1000)$median, Solution = summary(bench_1000)$expr, n = 1000), data.frame(time = summary(bench_10000)$median, Solution = summary(bench_10000)$expr, n = 10000), data.frame(time = summary(bench_1e5)$median, Solution = summary(bench_1e5)$expr, n = 1e5), data.frame(time = summary(bench_1e6)$median, Solution = summary(bench_1e6)$expr, n = 1e6), data.frame(time = summary(bench_1e7)$median, Solution = summary(bench_1e7)$expr, n = 1e7) ) results$Solution <- as.character(results$Solution) results$Solution[grep(pattern = "cutpointr", x = results$Solution)] <- "cutpointr" results$Solution[grep(pattern = "rocr", x = results$Solution)] <- "ROCR" results$Solution[grep(pattern = "optimal", x = results$Solution)] <- "OptimalCutpoints" results$Solution[grep(pattern = "proc", x = results$Solution)] <- "pROC" results$Solution[grep(pattern = "thres", x = results$Solution)] <- "ThresholdROC" results$task <- "Cutpoint Estimation" ``` ```{r, echo = FALSE} # These are the original results on our system # dput(results) results <- structure(list(time = c(4.5018015, 1.812802, 0.662101, 2.2887015, 1.194301, 4.839401, 2.1764015, 0.981001, 45.0568005, 36.2398515, 8.5662515, 5.667101, 2538.612001, 4.031701, 2503.8012505, 45.384501, 43.118751, 37.150151, 465.003201, 607.023851, 583.0950005, 5467.332801, 7850.2587, 7339.356101), Solution = c("cutpointr", "ROCR", "pROC", "OptimalCutpoints", "ThresholdROC", "cutpointr", "ROCR", "pROC", "OptimalCutpoints", "ThresholdROC", "cutpointr", "ROCR", "OptimalCutpoints", "pROC", "ThresholdROC", "cutpointr", "ROCR", "pROC", "cutpointr", "ROCR", "pROC", "cutpointr", "ROCR", "pROC"), n = c(100, 100, 100, 100, 100, 1000, 1000, 1000, 1000, 1000, 10000, 10000, 10000, 10000, 10000, 1e+05, 1e+05, 1e+05, 1e+06, 1e+06, 1e+06, 1e+07, 1e+07, 1e+07), task = c("Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation", "Cutpoint Estimation")), row.names = c(NA, -24L), class = "data.frame") ``` ```{r, eval = FALSE} # ROCR package rocr_roc <- function(x, class) { pred <- ROCR::prediction(x, class) perf <- ROCR::performance(pred, "sens", "spec") return(NULL) } # pROC package proc_roc <- function(x, class) { r <- pROC::roc(class, x, algorithm = 2, levels = c(0, 1), direction = "<") return(NULL) } ``` ```{r, eval = FALSE, echo = FALSE} n <- 100 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) bench_100 <- microbenchmark::microbenchmark( cutpointr::roc(dat, "x", "y", pos_class = 1, neg_class = 0, direction = ">="), rocr_roc(dat$x, dat$y), proc_roc(dat$x, dat$y), times = 100, unit = "ms" ) n <- 1000 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) bench_1000 <- microbenchmark::microbenchmark( cutpointr::roc(dat, "x", "y", pos_class = 1, neg_class = 0, direction = ">="), rocr_roc(dat$x, dat$y), proc_roc(dat$x, dat$y), times = 100, unit = "ms" ) n <- 10000 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) bench_10000 <- microbenchmark::microbenchmark( cutpointr::roc(dat, "x", "y", pos_class = 1, neg_class = 0, direction = ">="), rocr_roc(dat$x, dat$y), proc_roc(dat$x, dat$y), times = 100, unit = "ms" ) n <- 1e5 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) bench_1e5 <- microbenchmark::microbenchmark( cutpointr::roc(dat, "x", "y", pos_class = 1, neg_class = 0, direction = ">="), rocr_roc(dat$x, dat$y), proc_roc(dat$x, dat$y), times = 100, unit = "ms" ) n <- 1e6 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) bench_1e6 <- microbenchmark::microbenchmark( cutpointr::roc(dat, "x", "y", pos_class = 1, neg_class = 0, direction = ">="), rocr_roc(dat$x, dat$y), proc_roc(dat$x, dat$y), times = 30, unit = "ms" ) n <- 1e7 set.seed(123) dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE)) bench_1e7 <- microbenchmark::microbenchmark( cutpointr::roc(dat, "x", "y", pos_class = 1, neg_class = 0, direction = ">="), rocr_roc(dat$x, dat$y), proc_roc(dat$x, dat$y), times = 30, unit = "ms" ) results_roc <- rbind( data.frame(time = summary(bench_100)$median, Solution = summary(bench_100)$expr, n = 100), data.frame(time = summary(bench_1000)$median, Solution = summary(bench_1000)$expr, n = 1000), data.frame(time = summary(bench_10000)$median, Solution = summary(bench_10000)$expr, n = 10000), data.frame(time = summary(bench_1e5)$median, Solution = summary(bench_1e5)$expr, n = 1e5), data.frame(time = summary(bench_1e6)$median, Solution = summary(bench_1e6)$expr, n = 1e6), data.frame(time = summary(bench_1e7)$median, Solution = summary(bench_1e7)$expr, n = 1e7) ) results_roc$Solution <- as.character(results_roc$Solution) results_roc$Solution[grep(pattern = "cutpointr", x = results_roc$Solution)] <- "cutpointr" results_roc$Solution[grep(pattern = "rocr", x = results_roc$Solution)] <- "ROCR" results_roc$Solution[grep(pattern = "proc", x = results_roc$Solution)] <- "pROC" results_roc$task <- "ROC curve calculation" ``` ```{r, echo = FALSE} # Our results results_roc <- structure(list(time = c(0.7973505, 1.732651, 0.447701, 0.859301, 2.0358515, 0.694802, 1.878151, 5.662151, 3.6580505, 11.099251, 42.8208515, 35.3293005, 159.8100505, 612.471901, 610.4337005, 2032.693551, 7806.3854515, 7081.897251), Solution = c("cutpointr", "ROCR", "pROC", "cutpointr", "ROCR", "pROC", "cutpointr", "ROCR", "pROC", "cutpointr", "ROCR", "pROC", "cutpointr", "ROCR", "pROC", "cutpointr", "ROCR", "pROC"), n = c(100, 100, 100, 1000, 1000, 1000, 10000, 10000, 10000, 1e+05, 1e+05, 1e+05, 1e+06, 1e+06, 1e+06, 1e+07, 1e+07, 1e+07), task = c("ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation", "ROC curve calculation")), row.names = c(NA, -18L), class = "data.frame") ``` ```{r, echo = FALSE} results_all <- dplyr::bind_rows(results, results_roc) ggplot(results_all, aes(x = n, y = time, col = Solution, shape = Solution)) + geom_point(size = 3) + geom_line() + scale_y_log10(breaks = c(0.5, 1, 2, 3, 5, 10, 25, 100, 250, 1000, 5000, 1e4, 15000)) + scale_x_log10(breaks = c(100, 1000, 1e4, 1e5, 1e6, 1e7)) + ylab("Median Time (milliseconds, log scale)") + xlab("Sample Size (log scale)") + theme_bw() + theme(legend.position = "bottom", legend.key.width = unit(0.8, "cm"), panel.spacing = unit(1, "lines")) + facet_grid(~task) ``` ```{r, echo = FALSE} res_table <- tidyr::spread(results_all, Solution, time) %>% arrange(task) knitr::kable(res_table) ```cutpointr/vignettes/vignettedata/0000755000176200001440000000000013672457605017007 5ustar liggesuserscutpointr/vignettes/vignettedata/vignettedata.Rdata0000644000176200001440000476006013672457605022460 0ustar liggesusers \M]?ND2EdPB%"C*4Qƨ"S!"S22%Je,:gSQL_k{x~ޟ>Z=~B7 UTVZ [@KVUTV*իZ~z-G@GвJWۿQǢsfO:gZ /r8(kd->$z\9xZ^.wNisfX8#O[iy͘>Ëu_yWXi\^k̞plw-~U[G5#?=ݝޭSׯտ]Q)c76Y3`{O\;`~5~]IUS[^_߽?OGxOzxʎs#z :>]l+;gk[5>+/+؋WeףWxWٖC=pyǵ㩜;7{o4oQQ-v߿xp).Q?+?ռVy~*_xFWʎNCm:_]Wϧx;~?܁S~?{I?UY>|>n[݇˟čH;j/^Uv?sZZG=k7O&sv;Ol`g{O\dZȵ=gON{̙ԙ+Z׿/rݹϾg?@;s}?}+#}:r#O7st_q yDKWiϭjcῖ6VK5_*qB̯'p:~iͧM|N^' Q_쩾o+, y_v_hA 16jS` YFxG?@/Ɗѝ=AU [fMzqɇCןWB O/GGoNF];cǩsB}'G@73{.w܂/NEC9tpi<(jtyP46ܣ3<EZ2钧:N&8tsl.EyNҪs~\gy X;ͅy~3%d Rtā8ozRzfvUr?Vz=~Su:7w?W?+?u}'!|_JX?[~.%.r?+O?nCΫ7ϫ2||揮xJz?ԟϗe~Ow??_%new֯_O>??*^%<'WGyoV麐+KzeTgOy|%xgU}ZewOo?߮wSΧڟy_>_#SCYq_ge[cOC=^E:?屿OѸSWr|eQzwooVឣ֟A2Bhi hrH z]AlQkv 5h'HNƼ'Yw$|ĹgWl}s}C`lPm@sIW7¬:M'&h'HJ:k\7$3 a#$*ưDeH 7x^*0=<}0ww Rz5wc5IiY5>gh5HWެwg0KGL3|-ϝ7i[X [7> 5Ee 4Z'*0?^yAaw+΃ds 3 xVH@]Aukv$G=ܘx1$ɓ^V|I6/T8~SyG}ҹ OgY=t45^g$}Z}A|'>H"$}&]Ţhc7տ?H[4zwUO<@ClCH;:z ׋߁tvjm; hemSxv1H! ]r?*)$+t}&>PZ/i0iƲ*5D mL'ÚM}zr烤e m fZ5Hhii8-E!Hn_Vci02߻郂𸐞k/WDUk %)v3;tU"..~]'^RǑIG9)x;{ޛJς:Ǜ }{M|k H:֯ϯVڡHny|H$HdږMC;47$rPWQ_WP'yk$ރdę][sfķ|bHF쯓Y YD  ~GA^aZ]sZGtp&CgA:UA ws[<υ;6:},*qWg5Az 8wt8_;vd&0e~ONwx\'}p<[5]F}N7~5aġsM 9ڨ.rj/H\ b;gW`<: $Ώp R"Aja 6vM<^. t6'$d7H^4L\Ky^=qy*[1sv9=n@so y0TQӼw^zAyZv'#nqhE9wnjwU"ΔG=|I ^Ι xsW\S=~t*ہ 5+Fʶu4)t騪nI1?d=?q닆R?/ ( q)ygw7&XxrC }Wvo|A퀒 uW3|l03Hv:)7ğIW,l_eOŸ6egmNS\S#^@a[礡. A2.uؗ k9TC_ݚ3mMASgh ~F. Y7ԌhL Z_/Z7oiLάOֺjyW޻ ti5^U>vs<9̺<9?e@}0$>4$K]HdgD|{mZ-nl_ @ZwW-ki3H>Y;f'k@d Ļ DQM̡M;c^mZ=o,H~lSV`{؂ Y3rmI]cei 0hǛo ڀ4~z&4x\U|$EV`=*n][?| t 3W8_|$l+'4+CVGP}"G?H RY9AwnGg$ovf!^Sy<)c©w~̨bK`_vp`,R$kU$`~ni1S4u s-5L~nnfd wloUiMx1Hfgox_hX=C/w $_r{GQkvUrw% 1yfHm}ƘBvUJYwbp\Op6H{A%P.|pƊV݀q$@^) 0os.҂;K\Ҥ`1H[6 zG0_.ɡG&E"ՑnKq]G/[]ke\v(<JX\En-: % '[[3eᗺi:$l«aԛnnjKoV9zyQOwt֭%g`]`yᄎH<9WMHӚOkna>}?1C>ODfֈn,bf 5')?[qyEh]OidSPe j}UkԻ 2ZU 1Sr 1:Yl~8f1ѿWx) 3HWJOݬV;ߩ1yu|녶GowϘ@2'e;o7>|Y'0̿UU]#kА%gXyE NSa ѿwrH6)sF 0y4w߇kۋacU=ہ{ޏoܟfƒ tY)M0f~kbG4Ľmd^ydί[Ģ?]p=Ǿ;7'x/*ڟ7t@G9,sO-@N7;ڛo^}cOy5x|LxƗˬCXZA4ij31 @L6yöv37r-Aoc( Ǵͽ-):8D$.]>|'[rJjQf}VґW2haj/E0~$KdK Aޛ9,-⵴QGcU"=;ֲ뼂PeԨR8y 0o_rWۮ8N#O[OygW},"HÿF{>z}4a_\rn"XLjmһ65D^7mqΈvwnckQUC%.3EF?qha ë F^@꽸؉߾ |:9j/`N5f-dt;2Z߉gz-fmvȇY;k~Q>zs;uMc}ף \Ë%^O=F*AoYә]{Jסܾ,Z Du1ny+>|#mO>1>魏 c~"XyE`9'QeMK ߎ5i.W+,Xb^d>(E^2}\-g1kFV[&㳢Kwtc 2gfgjiVۆk=Ӱ_;VHy#)26sUf^{xڙkf}@~?z0#ºx55NGrr*ǦEC K[*gi_ mB݂Y5UA$#5&rH8mb' $`\vr Y۠/wiT89䁇$䅯*vC(:ȨeMшO>C>R< eϟ-0lZwp\ϔi LSMѯ_sRƟFe ^,eP x7.U0!K>EnOE?${/0Ĺ#iG2^ziz7>enuȷ,M MA$z9oW9S֩ES'͢җݳFQ֠?}~KNG[^`)߁] ]<~Ğ{wCu9c/۴WΘރerCѮ<ݪRس==kӘ=fC:c~xZ7}FER+"ġqvckj}v_oE/] EYȳ>BF78OOV8m&?}R7m- UI^6_A2Zx=UCknNCf>:.Nx?n  K66Nߎb?VweIU< k LQWy]znC2\q]JH=u_Rw!c?kTi.qq\깦c)Z.' k$wM+;Nǧfo1?$©Xg]kT*ty˛$zzu1^>[.I)zc(E cG3Dc<;ˮ_;B<ߤg|`b[Y6kyP?ͮcM UZxo"kcvdݣs81NmKνz{h>)f`?0;_T 9 }/bw./{ 7mXHj2cD =-M\faȇJu Pr,t&Mј;y az}<~8p6$+{l'5N]A9X;Othp<&qVu= C?a}ոս Yf \c5΁}a}\11_dG3 &7zUΦXyU<: }4kҽO)T4kӦE׷xeuN)I=?{Xt<l`\7#8Q1Ρڪ5i$c?;\uck K@a7L8iyאwE0yoFs#'K\CVyVXLt^?oyڥm-I$֫O BkfcʼZXhGLzަ'0OZֻ&0w[??qy9{6×  _aT{w0.-|'eW z CX'MX僷&oNFV&afQw{c3}a.X=N`ՃEi W}]o}y/#@U~_.M9+0jd6yxfdz}iK'ޞۯ V>]o6xf[0ح:0e| \U`Ģ(O A3oj׻'Oyj6q|QMNag5c}1'Z#K1_>|q8A>ޓZƼssE2'_x̜!X7. ҙ$W7_ƺzk90 )~!m[\}+Z|IKIV߇kUHo(Hdǃ FmB7„S)ؘx|wB.I._q6nC{oi,f݂/y&¶B862|t>@Yjd_1;Z̩ǻG=ląo=3YA*[ybUf} j{|/\k>:m[w;-c-n>~OZVܺ6( Zm$jm,iRo=8Z?90^xeXuc7y&`ˬJBbaW> Cu|]1 ƃ!DXw7|}uoj]wCgu7a31BZ*m|VRGoX{z Skx[$Uvc0/5zX{ L68sF{N0Fإ_DZq|kWv]~QvQy6Ƕ<]pv E7okcYηȗϴ_f ,3=a~8bu'-Lw!OZMki7ySލ&CUsFw9=Gstfh#oؾ*I1.c RLژ1u $k> ^(#7S(aZ6h[G^ƕ`\:ky~x9湳:J zްςF@2H IFsw8ã?>!n<5@r㦵1nP[woL,üTTƞ߲qm珒nYs+۷^7,DWG^h2ӆsk`^m˳ +,1_wX=ffzCܷ6nwv8`wYl3r;d|qBht쒣4=*B郹C)c;gnh~6}AX?<,0}^RxU As7F|Wqj=El* Zk=37.ztc"g<7l΄uW:?s(\#pֹ'8e~ߴeg0otz7fa]ߣ ޑZako(7\޲|}_@^{ZYOW}(qѣ5o|duc}R/Wv).?])S U>hV mk0=Uo苐k}*>5(8 S3@'I_{!W clwļ9149L{} =GzviX?=jX-1vW7A̾߁ hf,\}5WJYƬ7fɁ3%sAr}º :"zDC, 沓 `_8pD6b8 7b!_>gҤa-+ mF<4]qlчyCZȏ#lz[4;VcҺgoZ\q!G0N|tu^y&l15ze况`XtE{|Q'a&/ac"30SO\\*Ӏ=)آ ;uީ`J_5_cU:va/>:[`؆l7'ev.E>\e]$F5NضZ;Hz趪}t1K->f1OK}_FsE^q * #)6YNM Ǎw-ۂ|[Oکv k6]֬ĺ!k)I~l6 5kqT?aj9L-B}_8j2 bĵ2zr}3C~w1r^y+X.X٬i͓gƀͬXUk C/uxňN}x:cAt~O3޶Nb1ou+уdjIС"E.Sf0guBkנXҋ/u:<͑xݽ _|Ƙ#&Q5@z֏o>k 1 5QlLH.ZZs uzlbJGmG]i]. :~gc&"c*(W{zxG铯V@vx` 6R;ö0ī5w'ZKϫyYˑqʹSYXɤ dIMlkR3 b%u89lݞA|Z۴YN κooEP8Ms[ :%y؄S 5>8~ (ѠŃ7<ŬIOv#9\~S}M2[u87c[yE(b˶ZY1ANuNQ]^Ga |˩y=3ТƿJm:x:qkc}{,^{(P8*?~D v?-HmΆB#XQ l>6ue̽C71C¸ Ail'0k]8[0+٬iz/S<]kP8YT)s&:i 9g1yXI^ ސnl/amׯ-R^ 8b&֑]Rρ} K|b)V+AzBPq -ߖy  vmh}떏KjvVuYa^)C_>jZ6ᫎp#~wO z1wmisoſ '7qeg^& LPڀ6v =yFI =SC~ ceQ~ӠRF(u:)iV,swزz>/ԆQgMLoUۂ*۳oDp4sɶsAuxÆ- )lep͢&g'vpHBޘ̴xH$k{]:Euwv[n7a]~S_6?o>tف%Y0$_?img;kݚxMZԸW}=0kOgb~zf$g{|uLoulbZ~0ߺ$w[o ЮFզb]X8̩ a]?@yݨH\qO^;A(4:iyˬ^,<|s(n'^Wo wB{u&A{u0eֻ {5}l[w>`جSi܁l]W[]/'Lċ_d$G/(eH{ {7kXϵ<}6Oפ$//9o߇i 1( G84Kֻg#pyټ⍣@|}J/a}%k"F6s'~\rҚBqikUMD}O7FrQcGu<Үm2HYwsyƒ<[A֬f'tobV^-%0't6y U_'.z5l~ǹ)tnE\ [A ͜#?mwĉˇs== hkD{|) 3GUtMO"UƸ qS&WgSf>FޚI?׼/u_ ӢsğhҊ{@$k;fR_ęO5º-ˍYfmnǧM'eu?kszct9, Gne9d֏ޅk46]Y*3NCVg j"/-/Ꭸ+3̑p.y0u^|Rm ?3Q,lǮA>b]e6kw!0ƊXGyuүy)qc@-apwC)H׵;"ޅup fb}oRs8>v y%9c>m-x|MT剖[^:@'e _3qD =WºGvuů5kLB L- j\1wPEdGYSҼ nTB)w 'ecjs }zb"xM{ P:ޱC;B_A"oy#AZTsDE}%{DEMibAgb< J Nqz o~Nc7; `0R1o/ջޏ+u@ekWű6@>ל_5qq.mUk2 S"Ǖ 9ݶi6vK1:ewץ>}M]|!3pM/7$?o\؂$!VFzvCg}?V(?[<Ψv;Jx1v-ށ;0zZw07DnC#4 G:~XE^ c_F~H=zu.x^ }_wU#`ىޗtqyxm|[E/_qus.`e]'7޺ ››JP&Z輵e ꣏D+@1oɠn2(հ.weOB2zR)Q߻U}׎ɑܻwx]z t*kXkVl JjÙ@Y92{gݠ~0sloXvOPLԨpB Kj(t ʆ+wLCF}/%^9&->̘Jv RbvWP.OZrz?(_?7հf9@ɽ@}g(A  Y:wEsMp/F᪵Cbu=í'}}-A,#r P*-PpWV|[6Ky:n o\'~xqoi7_P\ :Mt[n0hX+Џ67Fیj tJ_{k)ξ(+c?vuqu?O{xc9(t0P\rTEǭ^ p@Jy E{?PQs$({|kj>z{$b@ŖWSA.{h, S~.LvG@d}oPMnbO("/OnT.՘QQZnѣu E OZsjjPʟv9k9}:u;(u |qnC&eK=z@4[vK/y_jgs *{PWTo4>v cl_]FA:PYsUP/mxk(<Խ1o۳J }WƝb;ukebO鹽+jl_ St|]ϳz՝8<@r=Aycgb|N4(lt[9Aiathܢ&8ޡb;2Is@[q.'ʙ~#O >7(8+9(٧'uS@)_R [ID Od'Y}qPmXvQ{փGE֠mW6SuT~a!P5Z=1%B7*鳹_[JmPN kE|[nkf Fg0GPk2[*8}|:$cD34\+Q|cU'[%"T/ci<IPT9(s@8*l``PYOw84c~VTMdt"55޾Mݐf *jW |)뷺mf|y~qWokpѫqYP 7״syIgOۡ_&,<qebRP\M\P,8#7=a6aR=7t!n76|?EYw/,(cNX`{a 6X PjɴԂf.^CḌWR C\P>{Ѡ s\o<2`tt#cyNe4쯺ٺSLv ͳ!.}bΎfk<_=l֢]]j5Z#2r~6π`oMASKt䒹F`^[6wXDO,˨1v\hq( ܪ / F\c>n6K-IE_=ܢEE ]ŃpU ۢ=D+zhca}?yKpw^xjxICQv]j)!jRW&AxDj0)g^tnwXO _>b\y[ _|`%vJyk>"=~[L|*qbP:b2_-~fϮZ uՄ[|i=oޤOkyT:nU+@qǫ!ײc-do˳4h=Fo`g ʪǣ0'L"fEЧQ6 [-A.=pJϠp[zˣfMC༬>SfRP1XcI .@\^Bﱏ SFu< sAg# {^{i54?$.u0(G,T}R#gwgtKysUl;·6S| ;.vfyCAN%(Ew܍yf@"6rL~CN)0/"1[ KL3x+lfj hPC_eβB?QvƷy`Nu~._\g#Ea\$:YAbطnD;OYt{ >{PVMw؅_GS]v㛞;rj^U0 S9d)P>P.k:Ș!e4?q㼙3u Ygy!%5 :*ם- /YwON9?$ͷ^jkRl?P|xORѯ욯Jjb&F ;oE.#Aaceris[حA: /jmůsrueO/t|ui<*&k=(j˪H-јo/ ~yW WLאθ@Eºr?]&YutR\ºXiuyi69A(][ODaQJudρ`Pܘ甇d{λd1Ԫ<`AG.kGIsW 1د6(R&4ŅYf!Nj?Z׻n{fy?d|Q&:hi C+N$a1.F6sD?VG_q~JPwɫ U250֋1yzk3+DP,iA\Nu2v  S%,y]ceږ t(T.>p17bk'{r|{{ @C2M5IѢ:tuI=5Qk&sP|4.ɭ^?yS}/R(_&2x1ӱ8x~۰{޾>*:dTh1ZMA_y?(ZVlX?yIل M : SgWVzT7"%r;(L{\l(ǧ1z ZyFʃ/XgSoE;.E O O50[TkϷ땝Ng_yrŐq]{-}0X7#ۖ ;-l,f~kv<Ͻ1D:/H%qe?z/c)9Ƭ8UY*Upb=rפmo4|̜fO'gΖ{>F1o@h[ #@yH>Q,%֏u@5{q_ņ'<%lԱ" ~QOT b!v uG`t.9xd;ay'͸ɼ#Tu@B\;lKE!^T~3(焺_\z4y!RwH\Zo*,~ֹWZ]ЋZPQ也{>؁p'mmM(ڤT܋|gGewAU{Gu4c't!oucqtij/mHU`0Or>y}LGdPl枫X¢ Tc}c] .|}{?jar*!Os=;F9_au8soK@~5fI s/ar+@,=ـEHviRD֗^3 dO\|0I?vi:jT5rF"}ql%7C<{i@=TabB;q{=ü^GA9ХMӓO*OҺ7U@ҁ[Os*w'!onbbWoX32|n v=GUW'`X0gjSMP BA( P BA( P BA( P BA( P BA( P BA( P BA( P BA( P BA( P BA( J _kݾEǞ) AqvTv@ٲ{}_[Jܑ Qhx(_[9tyk/bk~3(J7 U{Ff.v2礈\mK#޻oEom JF]VzE@(%W\oJ/{V:xKIJ d#}o7nGʭ_Rq?5L۰: z969(xuԈA^EC.x (6-qj_{eo \.(n'Y>yQRi(Pnk*] sړpEŵ:vxY<~`Px~qKsPeO U-Ĕ_A1}|SkmʐqҴsm_qqzT>Z>?@Q`U` #WWz!(G~߳ArAƾƶ} !&cBZyRjQ~ś}:@ 2kٳ/nvU%4gΡ7u5ü-(q.366݊v=ePf>:]*\wLe$I@uw2/e3Op[&( e^NpAtȾv]9w pm.,nଝS@Q=3ȼd5,Nidžo/ҽܶ Q 6_ 2[RsF9}Es"*e77`p+(MRkt<1cZTNȉ\ՉE&S \D^B(%u?8}8.F;P{(9v[ȹPDv1y20}ٍ"[/3|ʯdž3]{W{;_%SbΜX3+䢤x߳ k ޡ=V6^ʈ- _M7駗~Ue@rLǡGa@_iV'q(ȼkٝxv1m/tj{;K=&߇k 2[ G\r;튖 ʶ漚 J]ӗ6e$Ai%O ݪײy&Dn Dܩ׹ƧgUiJM@1.rdvźl@fDÜEPtГ)7 KYE ~=[/ vCMcrc6pzz݊g71#e"ɡӟ|p{AQhaաv #P6#[x97vP4w'%$i+j~+Z&+Wz47r_o6*SȧקHeAv`I?Z>ZÊwPaZaOZ+Aˑӿ>{1m(zd>Rt# T={EAqM@~9h¬A>g0ޘW׆.wFAYtN;uPå^#P |('vnZ\Aή sFyK+nO-ޣ";@;C@%JU6pE9=r_P g};.-rJ$c}8\}uoP>ʻȹwR uG6~_ 5z~ŷ T =-$V 5k׾(7D~ٻv[(M;xz5%fu.䟞HZʀ;@^>@{k=e.'y9ruZxZcNfA`G WNLF7W/Y3m0UPn^@Y'2˂q|m r1<'b^QrAy\#ġT7AœcifWSPl('vL'ˍAAn1N_ ĺn 5JywhE lιi~mTz.(}Pw҇v鹈/;0H"@9YȧLsP( :@+(h q!"146d軜Ɵjzǖpxh%(k;嗊f{-w2kYW9Vt~d+xUJPwA^pPPk뱾ȃ>KL?m&c>mjFWZꖆG>R>}G-Pa~$8QtmE-9G jXU5<(<2#@RwV~} QtPbrCPId~[]s&p̗_YC9K]Sa/ߧ"_^jBv'ڝpW_rCv|t0'3pv/[2}`ޠ,I%:!0PuieP-eoriΫUOAqYw y|vļQS?zu^6\`vՙrñgGg<8dx';Hw s 5Wntق|Q]jx}|ʶ9#7`!.z*;(d'‹c|dg=%_߲.б[Z/ĸ,z]o. ǼZ~ 0eu՞lBid~EPSɝe}K<ݰ.~ųw o.j;;Z7Pi}^]?z<;LۊXm5",ʐՑ7.}M!/z}& ԻKa @>zʝ]fPŹ"E lwo(PhtP<̾bClPMk`[GM{B9>I?#q!k޳;3zSv1_d7ֳ ;*6\GwP.>mm)@c'>X;(nj ^JJs .F>)P;X%vPݩ<3r7gz-yP,BEC]Ca])bClTwSvzWߞyT,zǿז{欝{Lhӏ}-Ap9ΙaX=Oɕ|yBĿkvrI-ps80<߼/fҿ"ůA}OmAۭcZmw;K_mzCjͬs yprz-Ŕu^&cV(5u|\U,i+:@So K-K7;xĊos%peGTlWf豆A!s|7W5QM6!ϊ͜s郹C)֍ \#[prː79[crb GO1J>6m7\i<}WӶE\ot*0AwhW|kаǨ7|*B|cB1:EG]rm{TlN_Qϗz┍y A?M &UtWv7v܀O OK;E~,Fr8q} t\'wMJ~ly ֡8.EjxPz0lary%n؇`}A^/c] XǏt?CSSyr&AuaolZiѓ@kt)V>%We;mRdv]1Au/}A@IT~<~86]z {!:%ud ND;^r﬌ s 8 mĸw\fu_VwMm/sz ? nPhYQ)6r1@ ]*e74ɧ2sN+$Kk¯A'+[_ק;׾VX_48]: "wՐ7E?{Ob5?8T# P}7fwV8lA\AҪ~[.vjTt(BwI]oh&-~HW*źy^ڀ]u@=vۓ8.]-dnI nA^}ȅ85EڿrXg(z5vM#g_m[g=yY߈X'P?DAeTtPU[uTkin6Eҳw} e.slnwPRoP20!̩";Xj<,RU3'YdG>PNviڲ 3) 5nV񔋋WIuj~vc3{A>VBv3Z7<}qrbMUU?Mcӫ0UJ(2դ A% 1mxЀWt@m֠89_䣼YUKN)(ܑy:_A~Y7O\h8:.Mq3!?)(dpۼ ~5&NnT> jrn^Dd>JPёB7ͺmES"OM, J ?/./an#(\w(%<'U|v! p@:%>>E=^|&CF_gPW%^7AU{kWo WOO"I4yxkcn(e.cMpG|4?N q9P+,y]@9ga]{78aӪxzdS2 gZpm"(/k KG~[$|y9 /G~|;n7?Gl<|I߮//)e=AE=+[r1R g6EƗIc}\:ACr DMh>}>QlOF|0DPsP5sv=7g $R >>p$֯篊nW@I]`?F*i{z+A8tmX{xD 팕'cl؏f Am'r쏔 _Ȟ]ǃ\Cg+ZW<v7]lvxJV|śƙyP BA( P BA( P BA( P BA( P BA( P BA( P BA( P BA( P BA( P BA( Eqc>ӫ^nfd'{ `Ɯol>h8kISNg oaL96 ƿ&^*q%i\S X / L͋U'CAq{_$ل e$C#算^tVs=_ @mg;o'0ڡD.f/k^`~wf N5+MCB[9Kn{vxIM~=qv cw~Uv<7>w#GOcd_`PyR6';* `ˤq2)f|]ĐϪFM5ʩ}՗+ڥ4Yyä:DV .4v"v$$֡t@wC5'mr_OvT_ğ'{i\_O gϏQ{};> I?U !~L}H|n|4%u)ܗW~]K'?W" ɗ$OqxF-kI1#Ο>GyuSɯqezأI}qELgS%O߼:g2" Qjw^~J /Q>BEi?;؍ '72>#8%qF Ox"sSqy \O|~D_Ei#o2.Wpz Cx7ҼJ+QOi܇$O|Α:7;g<\~CH7:| g:nv2^O^]BxO% 4q"z!m۸xQ%=7/G&?$a ɯ}$zH.w?:~>>dܼxI*COA:N.)'KOxy6|&'h>_g2ޏڃWgXmMG_~?$xG{C؃7OOȟ#xƍΗyu?wq凼z;pHV^N N?x~MG5do8|"f>WᏟoh>'O8| /"xIVn>AEjyxEO{Vy.͟x뼸v' Y<'I\FCC@ؑo^ΛFg.P{"<ܟ7B7<^BH?et|H>uys<٧QM$qKxï~WE/^B[h m-B[h m-B[h m-B[h m-B[h m-B[h m-B[h m-B[hkJy'cf:i .u/X j+c7 f Ѹ>CAԻEf7G.S cܜ+MUo ښ,AGF[ *Wl$iY.RR_tuK >x8`&Ô}}cǃØ֧"@T41߼43Ml}5rbK/.MrݘXTTɹ~:t@|QG3 nxSyտMQg@~Nӓ U0X}zksYb׎ɛ]g٧7x2ۡ ?$[t>KgXoGC#;wwX[N)@_l1 M{\l ˆC=)]3ϲ>jR[c@<\Q?xUt|}`')qNjr)8_\]Ga 872~Y!xjuuKմ i5 l4y(?} :DuRfqzf "fbkk&!$ʾl ξT6,n ◺~ 1@\\^b.ExHHkj贘]|yŋIm6*Vxq]sg'Sdv5iZ>NKW{+s~-0#Y ywoKꇜ 8Ȼ]udw:0a y6k`e3@u?ֳ5xse?/0:]qD˸/ e7 CrAkv Kğ= FkuIf4`VG^h2w>, >`zWr&/zṴn3oΉ@γ:Ad5ǐgݑm5׷=tf8]xu(U 6w=w^%3دv_jݙ9'Rˬ_b}p״9&q΄gw;,5?KT}@lo­!=@RM~F;z4~) 햿|c\{ovާ-c=οC6&lh[EvDq {XDRdž;n@tofR0OoKݴt?Fq{ [6jq#͢Yk55Gb^梖HAn܄^'{ݪt 2yǫsEH62"5ZAr/n]DaYWʾze. .h]3Nqq~k=d]p*үL5p{uu$_zꓴ-];tY& \vr1=ቒlb4Nݐ<jh-DoOH\gѴQ?pkuE>z6O?3ˮ7aC6vL5Óo)6g3,V7oX'H>,zn@ܱM +5÷:CApa3HKcsqu4yV5ˣ7=b&Of ~:E6Vu[p 5|:K>?lyLȻRjHG.tO:Lٓi`8&HՄY整%WҖjx'E߽.Q=ZgY\V [874_h~ 3~ 5;?m$4ߒ3N}gZ'Hjo\^%S q|_ wHU۽p <WR~JekxI%4GϤ.R\zO);^tɫ|ݦ0k6_CyHAFyy44x$&|&;Mof*W(xN:Z|hvAj >FF Vo^]yBG;ם4u*:Q/TcN$oP >2 峁UPw0``0X]26F+wF7㐻_qyZHyם5~MxG.h̝O.s浫H.|K'{\\>Kg;FMD\ \Յ286?-o|ֵ׬-١Ӕĺ*F,êy%i*#sxitn\Lkio/o# KьO@gϮjSv'ڝ8C ~qxF颜sA# Q'4`x{G8~C#  Vۉ~Aw? _| nL -~}smZQi/'IY+kn^>~ta3I j ډz#.Y yW.?V6:Xm>GpPɭ%gV 3[*#/fWUd'{:Dl'Ѧz~IQyESd^$;"l۬:}G3I27bzO.yg0k5xAg7 B:+ ~r5G==;BZsK4!UFR~N-ג `>i`_v[eI4Ϣi㌝:qkx'FoZG yt̗f=&ښ K32f~d~؏%79"VaR>cds\I G;ϰkk]¯ h|;d;b3X/nsekn#oW؉{\,qt7ykIu`hx]72ʷIqy"z$6KEe zK.Z4~qDE2¿H^Ώx9τNd^!_^5N4mw~\ϔv'A^pϚWJqu=͏w-Egy(9Nz+g߂j_vo@7I\ݤL^<| w'cXdt~r]UW:z:V4@z߰^4?t? Fby5s?sC ꚯj_SdUys/̓?!64y ?I'لs|!xCp<'݅B[h m-B[h m-B[h m-B[h m-B[h m-B[h m-B[h m-B[h]]nAxu{wݫ} ֌(fjv8K͐Npk`C$vY-q"1ڦ`ڨkH l ^vʽ;H7ܚddmkr?nC2>Qz.zQp\7KqY^~E'#1Cx z#yOʆӜ+Z:R<([F.ep:>ω?)Q\'x̍\%~t bҿ惔~~r%7/幜]hq$IVdkWp8IEp3'SGrp8 $PB9..x#,#/7)O$yxB܇\V?zҺI%rvu8'#M_q5L}9{S7ɻH\rN5幜)_" \ܐQx [I=O|!N.ɷ,8r<n(oxri=Ώ$7'Ԏ8qLq;0Cbr>C_%z%u bp <PR^;AAaEz]|My*5~OA8/I=/~kr̷??Ӽ7ݏG ?Kή ʠ~Cx_< #xHB}5'ߐΞ}ՁSH:OJ% /&Ck~ߜR|}2G1g?︺]|^28~AqAuI=H]<KDR^ٵײd &f.iȼg#_u67GO'cNN xr:Nywx8HqsN߅ٗxSopqC&Cc/#D&+ߤhNxN\|AN.ni'r!k5W ܼ:NxyGi$7K֪qEpDydϒS^E8>I'-MO:;A %K07 /yÛ/qG# ;Y~cxT[[\9Cu(^ww $!8ϻt\#;N/?<_kϤ+~?z r$. nEg=yv㯍M&ӵ6)tMvIh]<CenMeל^(XIH^a~|| <}G4qq jg;4~MΣu g'~ORCJRW{~Iw_n伏W!;D/_sLɫc~w?P||;8E_o]įɻE{~&z?Pُ?_A9bǐwxqrx<}%g~ߩ'q؉s%ɟ/!~MOG|_؍w1=?_by38|wON_xAC?~|_z]ڿ<»/xW4W:E7z$?6.+;'ͣ8_^yJgğy7>>? qKލG9/䏛O+/'~ASv{;>z"Ǔ+>{eIίHy9;ghzC}agFjwz⍋0#$;ȼ2<O-xu&Sƫ~c#~ěCx8J-yo< ?F,9y~ECb'?D?#}yrOp<+?˓|#:Opy*#>U?d*Ï}Ԇ-~m!QA\z)Z̹t@t7{A,Of5KOYIށAX!Won_*q%Q /AE zك@J 9>-.0#5+F8{:8{`gt1`\uZbn-] N2*_:9-8BA57xɉZM5o`X >3&ӥY`/<$;8eY;M?Wv;'`jtnĸmk}.fӵ+?,kD@ 1e+*ح( "*""**e`I4ib9^g^y8YgZks܃ծI: m< ZKG8rWłRr@0hߨx F|66!zdUAn|LQJIӬ\PL~[z{?y8+1~^Qߣ]ɎFbq{D yi;ȟ1eM ?eFA϶.Mr z| #NS.h++ ?3tr@ǵA紥-w]agPyRuM-?S&y2Q4DPt 3`p*e>J0 ȍU ?ظ>Q@a:ǷEj;~LиݦNy7?ddt=瀢K=HXJ(,wC]C^59i'A۱EV(f߹%8yoBcl[ΜV滋8Rx̬JMxsj>rq#b7P͇1ڛm Jr8{Pu_7{Z,uZb깃#q ĺwPx`ʬ=QeK=@^QtXP43v16 dmx%w5@|gOP`ޜYc*AyP Qa^r{sWо⧐' O%3']j90hj_pd_N9zB7g93['~wP.#/F -g?żq=yܯƥ6 .+ ;~W^?XC}sqHiCwAI].u j9hPfwFOyH:{l;LC~A?_X1tUҘX٭=4N7M-Ι H¸GMi|ЧrPd)8XdM|[Y eeʃ|5> ,Ž?|Ugb[doyUe@~?T(ګaɿeٓn~+Oy^P`psfCP=nL~gɹ\M;aχ1ɱ{9o(3vYjX2PA(]lYs5gb_8F?LjտPη7m=da]#}kzqA {{ ?Fl;xW sqӯMIGDQDv[}bcNRC^vGRT;p(;|5AtҼ{ +ސwf[qk"Pg|Q*m]"Ñ?UsF>G(oDefsvSYj-i5GZ ss*ZT-ւ9y%n+9k߫5A>],u͡Χ~3&d[oZPVWXPX5\w-aƞo}ޥ_Oe?c4+I~O#kj94~EkgEuPU c$]KϿe'2vJf{YЮ"gSă%!~87{:t 'N3M3~vyRK]d(:}8WɢY|&מ;:ݯ{ Ta8_v\;)(z/߭"C>{үĖ'V=ۋ1vui\.-e }/z1(D_$xkˎj>Y_9'(ΰ>=g|.T[| LS׃9[D#=vo#IE㢠7m@1e;(qdҊBÇo넟Yń]C;pw>ge{}JF1qGyR;rH@~`hzqM oN[{P|-gQ%8˔U*u N @ghq$S nLx˛PƿVmme{N򿳂KO=OM)k6vCwq e&;(()&ɯ%E̛7YQ^>qq#b7e͉ I-u#B@Fr~[ZC&<6}\R'.o(C8(ܮz|`& |N)qCA Lmy-6o%c51%YMg2U m0AS6Zk݃;A>&OrÿrKP4%i*(_Ju} g5le$Gâ\Oi7LBns}%?(Yk4Z# )_3DzNF/:W[[-%^B05U8#tb+v-5 d[wxSS7;ȷ/m=|y?"9~խruPUm9V\S$9pqLF\%u{P[xG9h _v|2EY/\9~= g=Yb~$gA^} /J'd_@gp `T r\Vؠ|{7ܢ/79ݥHMpd[<+4׶:&>D F\qS o# XN@;!{;[5go.eHEqƅjy#8]&yrCथm7ȡr*L1Ώ8buN)? qKbZkPT{ ]YP|aTnVB)ܳ>/Ӥ~~wYX aW8މ=յ kۙ S׏{JS3KL4SdzG2/Q4ˤ-ۙxdsvRE%_3ɰV׃ obrR Əд`xZ$V!l*Z>۔{{#.eg҃]vQ99NC~Eu@^Ceؘ,˷ O7=H]!(fpuR p1>&snj?0&9uTQm!NJ}=-{|e. ŭ닚;>rv=?",ΏqyJam:{\mooqW&`$ƵrrxToC>8ek(?ѫC"ۛH9=2w2d&9 _d mu6΀Mog [n}rJqs9rz_\hg0^)yR9#m~V͠H7WwDLN1Aio/a[̿O')[7jQ{^N4oֳ:HYqPQ99c촬W7&%B?߬WՔ gӫNeUWÛ|'Uăa>`= K;suBgٗ7m.ofhד ߉ tQ\I\.S^Dhys+(Xbk{YV4)[Д\lWW#uBŎȫ\L<,gIOpj7=Y߼Sf=ԟm~}qM]a3)"ٱԟ\d L3ڶ w2uM/R;P1m܉> 358lX|]af3uBxŬݟU&_Do~j}&yK. @:@:@:@:@:@:@:@:@:@:@:@:@:@:@:@:@:@:|&3ފ;cԮMϚizrcfoAzt5#E~|E3(myR~~>xO>,UWڬ+ EpBU[4 =udEvn> f3ŮMA/xl~Hf4Ža=[3Mpm u9/K[M.gA.1my1Erd Nyfݖ?YR|I='w8+e(:٫6(d Wn7"z?b5 ƼA>e&s8~e jW/B}ϝ&Z.  l#zpmz`FUgܽG_֮GrOżSw`c/yV/ި't*[o7ƩpPE֚|ռ-$&I1|>$(ș-.~ 3M6 =;ILZUpd1߷y~G+@ޡeﲈݐ8u }3u(|~PaFwMcGt ד5A<^({`<2-]yA1;c`o.2\PvyvnPHti3?ogy>'l NV?s'H5(o o=)TQAE[Sw[Y?y{UL/Ϩ=7 . 䅃m䤖g K=Oln#G=KȹJgm^f7Dz 2&v,9NO2oH[n &Qs@Rv.H?;y֘g>b"f{5>ÿ\rz&4 ٷ3o3̈R40 ' ֬ucdvylGBG _uoU +|ַ (.9+ խD[|ϣeۜwnsZ{^Ɠ89W,a> *t 1S8)u yxwsl?G7}ƏLmP3= we㑟Y8}!8>2j.E]qoddTG'{sMvj=R!A~(UEGLt9| rFk Ch-N@>Ἠ  ͯk`:+vdoD}Rl7haZLz_íg0G{^5]zQ(id-F.  ^?I^?vL?QCnno]o ƽ~mᩘR!x]qC{C>k;@~=r7Ϟ^}7ӳeGrSps>fJ:YqBUoAikEHP>~>82#iZ,p 3KPlH9k#5]佞2mpzX,NDZOtV?ۊ;ϛ8NfMϮkZο)Ϙ8kȐzs+g8TbN-Y !<[X2V{\|Yep!+jN~4^6} [- O΂lO͞j=pT o\䣋ښsrŒL^#/G^fpyg_S6QhNٌ*rF,Eluĝ  ظ (6Nr.'>X23zQ^k-!憌^m2Ƚ9G#~aXk\u!e]duA(D嬖;WEU[ J7b|ZX] g8AYp8 d:(xO9T>s8?3(8b\:BAW~Dq}C~ωjFP~ٹ l9:'yq;qGH+֋[~/zm[> U77񋨧JUzUǣn5bS n(X)R]}sdj~U3+嫟~*s&:py DfZɽbb5PvU Q! ~[3JDwr}P.oX,c z7Rߠ3('\އ-NHYvv+=Vׂ\ҡdl>E;/= &ceͷ}Lh|Ux iȹ{B&Ջʺ6/} r.2Hxa ^5D8;63{g^š\&a_R;7f7{Y~&C( ,'ֱuN ri޷ڪ5wqr7hK/WD%C.u('hedP:o)Aكshy\v(긎į&M?a\I7qqc<*SXW"$o^lm\h }>f0b|O^WGʛRq\uF~Vx#Q/| a{ЎɘI7P,6t] [ee|{;WzMněW x꥖b90?ƺ!|[o3PH*|<=>[G*ҌQ79hU8_}.2d0Rb& eGnx:@PbލB^wYf8v5c%|x\`{r&h&9Zv,!#@u=_,|SQuj?'!+!_8>F%B.Qvi͘7~ub]0HmIߙ5-8x~c\Gg+z⏟|qcn/ ySEqqg'c@]s|f?1R$؎\H :Rh2\ݍX_8d*\قΎۧ_ފWHvY߈3ޙ`8]"T/J+{ɤ@:@:@:@:@:@:@:@:@:@:@:@:@:@:@:@:@:@: g2-|3ٸkY 2[õ^ck= 1>*&!;\v9] 9&g/njq2v z |cAm{ Ӎ>v U޸DG͘a;ÛnCt770;3a@QP߇ 6t$Wܜ0~/H  wRzIӃW[4ܣ.y;}C x'[@pm?t~3wEO;x6zTe=S|25kֿF[tv~yأg@R1L.pQ#|E 𭞟]Hr(5*j QQ%d:Ho{@֢.BI M8qW!;{VwM-ԃA-oO1TOAMP+PD]Fbz3AkCvCF❅?f|9@L71Wȧk&$hdf-WBvCǦ- Mt⤹F&Ƭ|@ON|u$Unq_7ncYob@ͷ=0G!}ޥ7l!cÂ7CBfBj}"jm*[cG Ykv}k?HYg1pHtFPn8 lh4^}sCVFz;Ar#,T069o@Ǎ:ì ^ gЛw|} \ǫLB c@|Ɛ[͐b>wf=۶;m2毻9.X\Cʾv=vC| |k :Azņfk:ҾqAKY]ll|勾 -}}'? 2TaϿ+6,6%o89Mm}gwU*xeW;;AOض'J8&#no@_rAf[& rg:^ik>ȹcc@d>dL\qú7uS-S2]kG݁MTDZVY g4~/U4e= #DeG6,Z ;jHKw}zi H.)W*=!c#OBAz19}~^p 2'ɋ'` CƖqs0eɾAY߽ҽo\P J5r3IdRҮW6 mTfuZMlv;Vdn= / BC( So2gҌy3_B5]>DFȱ ᡣbAB(\(?26e,j '{F[K&| "+߆̤:.e x쮡>o|\V}d(I̝Wη5+/w΅Lm|| iO^xi^Z+@$S ">dT8a{.Dy`! dGWk݀|J[Fށokێ mlQKzjfҕS !H}*7'H,5 DU;x0H*)@ƳM=l| ]#M@tʼn͸y5?ΗN u;I4p*2Ѓ.-E!6kӆe唊q.{&H\R:,ƞ1g$iԬ$vxelSbk@KKjBjbwzrqF͇/W'!Q̵n"]BטiG@l{+T;T|uH[.8`5CBl D6b[P>27?|o-u lj3o7E= 96):޳9Z|>3Lqic%iȅO]WW QoM_h2N.Hw=H~&erdQ .WզBo5(&ql0rfy< ٛxdz[>!/kognX5f}>pbr1ޅ: r{At'}@>) 2>2Z*6 s^ɴo/Y鱱GG-mnS9@膗7 Ŝˋ-4^Cz@<>0uWa7MBVjqM!+fm[oׯ۹8N:d*,U26Au&d^G@ߺß cÜ;Sn~ud>a9vjLؽFX$s;eڼ-fxݬpH6P9d;` H(d/tN=zԽdjxwb(d긜IKk@iދwL`R  j ~KGp+C@(1q03$kFCojAj{!{LR2'hVc+Uku'@l믫@TIr- ⏟7w< z;C̴-FaGs&PnxKw_ePE/p[Ec-]:ml]FIќf)r{I*raA(ȘP; ]+ Orq`>'~ .nC4ѐ]vlSٱ Hfh8t/W|$Q%…ϤW1=v?@.+^C@U@Z.ftܛWc=ϝ]Y;Weh㫅L|n /A+~tԈ' q1{b[[g96;!);AN@O ӿ۾??A< lUӡcGG1vgG }71Wc lFZ}ɛVs_ ܘd8}׃wq;F@v/5CNĎuwAp=Cs>dMH~uF~he-?}IÓR-_^@Tr,H¡q1*L{x3cЛ43I/\[dk!Om 7/[B:FΪ`.^y d4L'+Tus ;5 fՁw.`zoUj36WѦuwl h ()ޚG7]!n rtiC@BjG^cAƠ6ygWb'Z'CƄG .'k;!#wO/ǺBfÆ}v)ǻ']NzoL~3uu';48ok| %O1}q`Rnߟl0$?O~#dֵI=lI?Nϲz r3zܱ]\IeA^ $Qw.ĵ6Kj cSu 3rpy9 f5de9CN{eMһүGkqO@VUk@3kD]7' ˂nق_W37 /m);ӧHU] #~ObM0zW}ÚvĪACxkT{\u g VO0r:վgS k/R z=iP׻dEx3A\Ӽc t~oĝ7jB|{iq)2q쫮!M 36ݶYx=i $?{ؼc-/;_zjs __u-H4m;‡qg#@xsL᤻N&HBfdG\9 #w?Jl^(5ӯ}yq+%sKA܆k@)ZB法LlHԽ8 -bjIa^@BFL~֮ƭcA8ʭsAmϭi} ]]sDF>փv9ik#Ah˒cDSmu͞ ? x+ }^ nC;<҂3-B/j>jZ(bץfm Dѽ,d1WGN^?P4Bo2|4r3$WͤkP Y`{8H^nd<:S2qCiAAPr}}Y &)^2&Ytm7BW1C,s@dz LkUhA:#y6?q-qӻOQ۶F3@%z$O>t7=d>N @6.ӭe HεIW sA^R^H#XYtSmp)Yx{[vu#M\H⒄Ggn7_rɑqAj*mnIsrr&Ne򕝫ֆ$W;Cړ̯wf2mDNƮ 6Hm#LTᓉu wɡLI^ xW)q*}w#Lc}uL}3gѿSAAι`_߭ \Ҽa1 :@#'ϩHU};LWэuGi 9~7c'ktE2=l ?jۼ'gkֹӀ?n }PtcCQw@\K|SXm—60vCq=}PCVAʋɖ/39XN#W1q5j@Ή{!-67r?;syhoWΓw6 ÿ;釷OCAn}m 7ky)|/ qPP\widft9BvhF) ~бKM.>w<#$'(AR$2k5zVK:b3A.wz ~Jz4fSc ˊ6υ!Kd$i3Gxz5$_Z2>2&wv}!'9Z1?u|oYu--pžxȠOqg'&zB|)_^yo6Qm9|vftEH~ؚ\~iambJ.Pd5xѤ d9~>>lLT /nwO?Fs.9 lK.,[~,m#ݞTie_śL}Mc%ꮵAIѷNS}J&>=Ш;6[ Wq4V72WgП雧 ;:jJ;x;-d2jkg-:Gt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0Lt0L|rٛAzRIg䛣ǩo!CDsm ~k/@fЫAag fou =~Z*.L YٿܶUхmCƗ&e}$>߀0lg#C@һcrxy.PTOx}H?9p_ ͭ2w& /E草vUh3R/u`ċʏU# k|so=Yg: :Ç߄4. @FNi)=.;2jp bAz  >']eNCrt{tpH_ATܧez[K^{}f\k)A_8H/3$ONق?))Z2߽qR(}|#rGҶ6==8|(d ꐼk8d p[S-\A8^F#1JA޻!eSEL'SB&-7RAP P?hS_YSy۰I<aN>A  D7{ZH[~lr&~C-¤îw_ ]uƪ-ZBҦxewXiTb2_u;"yH.~;M-dbM~N| 9%!*u.A[nW!{~Y P#AhViH8~KH}}9GI[=vVk\:W,{1Fk{ƂǏt 7#Is_b̘ؼO)%rXG-_.#K~i ٝ՘D=)$>,k>9 wO~Qx5*Q͏ўJOtY5aH-d}ɐ x˖nS 7 66Oz6m@0wloH8z_`<Uiv7}ה׆؏m 0+i3H9{w+#wf M?~oKʞ %m/ͭ@KX`Î2tL) DG6|t$$y\_W-G ]N;XA6\k"Z_aP]c \ч4+gAz2gT|yU/DJ73R/_v 2bNv7$N q5@smJ|$&} d>pm!mGiUHmj5 V?j2'0n4SH vh[L|d?Xu"/u:,+9OӝJH75gI/ _73E۔2V@~y;@rB@0 cݏ٣ 㻀+4PU HVf w7HPa> ץ*#{a-M[!ؿR]S7/ Kv3fm 3 Rupa4/,0dv<Ͷ;.³ [Wύ4!H28$.g%5!lA^a!k/ 5>]r cH/S'q-EuRt펰8}4S>t\ȡ ?nz]IaV~?˳d;d8dͬ.>dlo<\q/. j3ܢ֝3W#]7h兼3 `- \Դ{jkKFᶌYt? n(+~*HW/|76Vi?al ̍cۜwns!d,2]>yeT7uW$ltr /kMRp%q̒6~H]E˝4dMkvYvO&w-oiw@RbQ$wVf yQHvQARG@r :z͌}TncA̦M_,)0cg> .qn˳8i-mQ׷ZQ9V5?O578|{\S=Ns/ @e>]ByK;+ u6֐L>L7!5ڢ?H5c=AX-.>655[fɾk^@[[ϾW?߁IKn/h$S@m&22BrKVAᚹ&փ￀7>kӐ+` z>G.&}1UBjdu?@GA <~\f ǠOg.O>qԪXHn泹;X8RVn\u;HDY~#7w藰I. .^d[עc)Prz,}rv OHʫm Ju|J.6II(+k!pj<^M5|p ލ {d@Ӻ2&^z` ǎS E3~-qPR'!$0waȘ?==r7 Uqc p/& A7Ø8ŠF7U@n^ 7% Tj]$Ór;_Nwz˅ POsQO 93}o RZLH;uiͦZB_ Cһu=71+@"qf~gg1N;WݦtHWL_kd"R=&x9H]2;\~ š1qVCu=Hm~ы3 ~ʢO! q|V6 $MNe-b_K}`nb9H2 Tm Is5>i.Rh+m%='@ԓ_ kڦ-D@_9|8]xn&?R塏/(=Y9Xe;FAs;*d-[xqFӷL^R'i "G\!on)rۖAvaDayTsTKO|*cF?@t\<NT}?!i" =XۭL\ll/9Y |-M3~wCi= h͐6dxwH߱\C!zJ3@b'f7Hok/'$Ot4n8Wg: W{ڥ7H6ydR^@ج_Dצ<I=l( s{W {ݓ凜 =N^ ;{ޡ!|ynj X8n֘1p/{x–.W {AU | BJu^>\,k@s Iqx lؽcoR&`EI!F߇g@KM[)7~FwFI9 pzFLx<]'޷jo_~t43]6NTM'6m>QHP"Ȭ^mf&|<W+KySBjV+fleKkB*d_tE/>+AReGMeD}Ag:~e'\=+}C~2o d_