rlang/0000755000176200001440000000000013614116052011354 5ustar liggesusersrlang/NAMESPACE0000644000176200001440000002506713612354377012621 0ustar liggesusers# Generated by roxygen2: do not edit by hand S3method("$",rlang_ctxt_pronoun) S3method("$",rlang_data_pronoun) S3method("$",rlang_fake_data_pronoun) S3method("$<-",quosures) S3method("$<-",rlang_ctxt_pronoun) S3method("$<-",rlang_data_pronoun) S3method("[",quosure) S3method("[",quosures) S3method("[",rlang_data_pronoun) S3method("[",rlang_envs) S3method("[",stack) S3method("[<-",quosures) S3method("[[",quosure) S3method("[[",rlang_ctxt_pronoun) S3method("[[",rlang_data_pronoun) S3method("[[",rlang_fake_data_pronoun) S3method("[[<-",quosures) S3method("[[<-",rlang_ctxt_pronoun) S3method("[[<-",rlang_data_pronoun) S3method(Math,quosure) S3method(Ops,quosure) S3method(Summary,quosure) S3method(as.character,quosure) S3method(as.list,quosures) S3method(c,quosures) S3method(c,rlang_envs) S3method(cnd_body,default) S3method(cnd_footer,default) S3method(cnd_header,default) S3method(conditionMessage,rlang_error) S3method(format,rlang_error) S3method(format,rlang_trace) S3method(length,rlang_ctxt_pronoun) S3method(length,rlang_data_pronoun) S3method(length,rlang_fake_data_pronoun) S3method(mean,quosure) S3method(median,quosure) S3method(names,rlang_ctxt_pronoun) S3method(names,rlang_data_pronoun) S3method(names,rlang_fake_data_pronoun) S3method(print,frame) S3method(print,quosure) S3method(print,quosures) S3method(print,rlang_box_done) S3method(print,rlang_box_splice) S3method(print,rlang_data_pronoun) S3method(print,rlang_envs) S3method(print,rlang_error) S3method(print,rlang_fake_data_pronoun) S3method(print,rlang_lambda_function) S3method(print,rlang_trace) S3method(print,rlang_zap) S3method(quantile,quosure) S3method(str,quosure) S3method(str,rlang_data_pronoun) S3method(str,rlang_envs) S3method(summary,rlang_error) S3method(summary,rlang_trace) export("!!!") export("!!") export("%@%") export("%@%<-") export("%|%") export("%||%") export(":=") export("f_env<-") export("f_lhs<-") export("f_rhs<-") export("fn_body<-") export("fn_env<-") export("fn_fmls<-") export("fn_fmls_names<-") export(.data) export(.env) export(UQ) export(UQS) export(abort) export(are_na) export(arg_match) export(as_box) export(as_box_if) export(as_bytes) export(as_character) export(as_closure) export(as_complex) export(as_data_mask) export(as_data_pronoun) export(as_double) export(as_env) export(as_environment) export(as_function) export(as_integer) export(as_label) export(as_list) export(as_logical) export(as_name) export(as_overscope) export(as_pairlist) export(as_quosure) export(as_quosures) export(as_string) export(as_utf8_character) export(base_env) export(bytes) export(bytes_along) export(bytes_len) export(call2) export(call_args) export(call_args_names) export(call_depth) export(call_fn) export(call_frame) export(call_inspect) export(call_modify) export(call_name) export(call_ns) export(call_stack) export(call_standardise) export(caller_env) export(caller_fn) export(caller_frame) export(calling) export(catch_cnd) export(child_env) export(chr) export(chr_along) export(chr_len) export(chr_unserialise_unicode) export(cnd) export(cnd_body) export(cnd_entrace) export(cnd_footer) export(cnd_header) export(cnd_message) export(cnd_muffle) export(cnd_signal) export(cnd_type) export(coerce_class) export(coerce_type) export(cpl) export(cpl_along) export(cpl_len) export(ctxt_depth) export(ctxt_frame) export(ctxt_stack) export(current_env) export(current_fn) export(current_frame) export(dbl) export(dbl_along) export(dbl_len) export(done) export(dots_definitions) export(dots_list) export(dots_n) export(dots_splice) export(dots_values) export(duplicate) export(empty_env) export(enexpr) export(enexprs) export(enquo) export(enquos) export(ensym) export(ensyms) export(entrace) export(env) export(env_bind) export(env_bind_active) export(env_bind_exprs) export(env_bind_fns) export(env_bind_lazy) export(env_binding_are_active) export(env_binding_are_lazy) export(env_binding_are_locked) export(env_binding_lock) export(env_binding_unlock) export(env_bury) export(env_clone) export(env_depth) export(env_get) export(env_get_list) export(env_has) export(env_inherits) export(env_is_locked) export(env_label) export(env_length) export(env_lock) export(env_name) export(env_names) export(env_parent) export(env_parents) export(env_poke) export(env_poke_parent) export(env_print) export(env_tail) export(env_unbind) export(env_unlock) export(error_cnd) export(eval_bare) export(eval_tidy) export(exec) export(exiting) export(expr) export(expr_deparse) export(expr_interp) export(expr_label) export(expr_name) export(expr_print) export(expr_text) export(exprs) export(exprs_auto_name) export(f_env) export(f_label) export(f_lhs) export(f_name) export(f_rhs) export(f_text) export(flatten) export(flatten_chr) export(flatten_cpl) export(flatten_dbl) export(flatten_if) export(flatten_int) export(flatten_lgl) export(flatten_raw) export(fn_body) export(fn_env) export(fn_fmls) export(fn_fmls_names) export(fn_fmls_syms) export(format_error_bullets) export(frame_position) export(friendly_type) export(get_env) export(get_expr) export(global_env) export(global_frame) export(has_length) export(has_name) export(have_name) export(inform) export(inherits_all) export(inherits_any) export(inherits_only) export(int) export(int_along) export(int_len) export(interrupt) export(invoke) export(is_atomic) export(is_attached) export(is_bare_atomic) export(is_bare_bytes) export(is_bare_character) export(is_bare_double) export(is_bare_env) export(is_bare_environment) export(is_bare_formula) export(is_bare_integer) export(is_bare_integerish) export(is_bare_list) export(is_bare_logical) export(is_bare_numeric) export(is_bare_raw) export(is_bare_string) export(is_bare_vector) export(is_binary_lang) export(is_bool) export(is_box) export(is_bytes) export(is_call) export(is_call_stack) export(is_callable) export(is_character) export(is_chr_na) export(is_closure) export(is_condition) export(is_copyable) export(is_cpl_na) export(is_dbl_na) export(is_definition) export(is_dictionaryish) export(is_done_box) export(is_double) export(is_empty) export(is_env) export(is_environment) export(is_eval_stack) export(is_expr) export(is_expression) export(is_false) export(is_formula) export(is_formulaish) export(is_frame) export(is_function) export(is_installed) export(is_int_na) export(is_integer) export(is_integerish) export(is_interactive) export(is_lambda) export(is_lang) export(is_lgl_na) export(is_list) export(is_logical) export(is_missing) export(is_na) export(is_named) export(is_namespace) export(is_node) export(is_node_list) export(is_null) export(is_pairlist) export(is_primitive) export(is_primitive_eager) export(is_primitive_lazy) export(is_quosure) export(is_quosures) export(is_raw) export(is_reference) export(is_scalar_atomic) export(is_scalar_bytes) export(is_scalar_character) export(is_scalar_double) export(is_scalar_integer) export(is_scalar_integerish) export(is_scalar_list) export(is_scalar_logical) export(is_scalar_raw) export(is_scalar_vector) export(is_scoped) export(is_spliced) export(is_spliced_bare) export(is_stack) export(is_string) export(is_symbol) export(is_symbolic) export(is_syntactic_literal) export(is_true) export(is_unary_lang) export(is_vector) export(is_weakref) export(is_zap) export(lang) export(lang_args) export(lang_args_names) export(lang_fn) export(lang_head) export(lang_modify) export(lang_name) export(lang_standardise) export(lang_tail) export(last_error) export(last_trace) export(lgl) export(lgl_along) export(lgl_len) export(list2) export(list_along) export(list_len) export(ll) export(local_bindings) export(local_interactive) export(local_options) export(locally) export(maybe_missing) export(message_cnd) export(missing_arg) export(modify) export(mut_attrs) export(mut_node_caar) export(mut_node_cadr) export(mut_node_car) export(mut_node_cdar) export(mut_node_cddr) export(mut_node_cdr) export(mut_node_tag) export(na_chr) export(na_cpl) export(na_dbl) export(na_int) export(na_lgl) export(names2) export(new_box) export(new_call) export(new_character) export(new_character_along) export(new_complex) export(new_complex_along) export(new_data_mask) export(new_definition) export(new_double) export(new_double_along) export(new_environment) export(new_formula) export(new_function) export(new_integer) export(new_integer_along) export(new_language) export(new_list) export(new_list_along) export(new_logical) export(new_logical_along) export(new_node) export(new_overscope) export(new_quosure) export(new_quosures) export(new_raw) export(new_raw_along) export(new_weakref) export(node) export(node_caar) export(node_cadr) export(node_car) export(node_cdar) export(node_cddr) export(node_cdr) export(node_poke_caar) export(node_poke_cadr) export(node_poke_car) export(node_poke_cdar) export(node_poke_cddr) export(node_poke_cdr) export(node_poke_tag) export(node_tag) export(ns_env) export(ns_env_name) export(ns_imports_env) export(overscope_clean) export(overscope_eval_next) export(pairlist2) export(parse_expr) export(parse_exprs) export(parse_quo) export(parse_quos) export(parse_quosure) export(parse_quosures) export(peek_option) export(peek_options) export(pkg_env) export(pkg_env_name) export(prepend) export(prim_name) export(push_options) export(qq_show) export(quo) export(quo_expr) export(quo_get_env) export(quo_get_expr) export(quo_is_call) export(quo_is_lang) export(quo_is_missing) export(quo_is_null) export(quo_is_symbol) export(quo_is_symbolic) export(quo_label) export(quo_name) export(quo_set_env) export(quo_set_expr) export(quo_squash) export(quo_text) export(quos) export(quos_auto_name) export(raw_along) export(raw_len) export(rep_along) export(rep_named) export(restarting) export(return_from) export(return_to) export(rst_abort) export(rst_exists) export(rst_jump) export(rst_list) export(rst_maybe_jump) export(scoped_bindings) export(scoped_env) export(scoped_envs) export(scoped_interactive) export(scoped_names) export(scoped_options) export(search_env) export(search_envs) export(seq2) export(seq2_along) export(set_attrs) export(set_env) export(set_expr) export(set_names) export(signal) export(splice) export(squash) export(squash_chr) export(squash_cpl) export(squash_dbl) export(squash_if) export(squash_int) export(squash_lgl) export(squash_raw) export(stack_trim) export(string) export(switch_class) export(switch_type) export(sym) export(syms) export(trace_back) export(trace_length) export(type_of) export(unbox) export(vec_poke_n) export(vec_poke_range) export(warn) export(warning_cnd) export(with_abort) export(with_bindings) export(with_env) export(with_handlers) export(with_interactive) export(with_options) export(with_restarts) export(wref_key) export(wref_value) export(zap) importFrom(stats,median) importFrom(stats,quantile) importFrom(utils,str) useDynLib(rlang, .registration = TRUE) rlang/tools/0000755000176200001440000000000013366255562012532 5ustar liggesusersrlang/tools/hasmacros.sh0000755000176200001440000000017213361376453015047 0ustar liggesusers#!/usr/bin/env sh CODE="if (getRversion() < '3.3') stop('No macro support')" "${R_HOME}/bin/R" -e "${CODE}" > /dev/null rlang/README.md0000644000176200001440000000425513567443762012663 0ustar liggesusersrlang ======================================================= [![R build status](https://github.com/r-lib/rlang/workflows/R-CMD-check/badge.svg)](https://github.com/r-lib/rlang) [![Coverage Status](https://codecov.io/gh/r-lib/rlang/branch/master/graph/badge.svg)](https://codecov.io/github/r-lib/rlang?branch=master) [![Lifecycle Status](https://img.shields.io/badge/lifecycle-maturing-blue.svg)](https://www.tidyverse.org/lifecycle/) **Important**: The rlang API is still maturing. Please see `?rlang::lifecycle` for the list of functions that are considered stable. ## Overview The rlang package provides tools to work with core language features of R and the tidyverse: * The __tidy eval__ framework, which is a well-founded system for non-standard evaluation built on quasiquotation (`!!`) and quoted arguments (`enquo()`). See . * User-friendly __error reporting__ with backtraces and chained errors (`abort()`, `trace_back()`, `with_abort()`). * A consistent API for working with __base types__. Note that overall this is a work in progress that is still in flux: * Environments, e.g. `env()`, `env_has()`, `env_get()`, `env_bind()`, `env_unbind()`, `env_print()`. * Calls and symbols, e.g. `call2()`, `is_call()`, `sym()`, `syms()`. * Functions, e.g. `new_function()`, `as_function()`. The latter supports the purrr-style formula notation for lambda functions. * Vectors, including construction (`lgl()`, `int()`, ...) and predicates (`is_logical()`, `is_character()`). * Attributes, e.g. `set_names()`. ## Installation You can install the released version of rlang from CRAN with: ```r install.packages("rlang") ``` Or install the development version from github with: ```r # install.packages("remotes") remotes::install_github("r-lib/rlang") ``` ## Cheatsheet tidy eval cheatsheet rlang/man/0000755000176200001440000000000013614040227012127 5ustar liggesusersrlang/man/prim_name.Rd0000644000176200001440000000051613553606424014400 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/fn.R \name{prim_name} \alias{prim_name} \title{Name of a primitive function} \usage{ prim_name(prim) } \arguments{ \item{prim}{A primitive function such as \code{\link[base:c]{base::c()}}.} } \description{ Name of a primitive function } \keyword{internal} rlang/man/scoped_interactive.Rd0000644000176200001440000000246213604124170016273 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{scoped_interactive} \alias{scoped_interactive} \alias{scoped_options} \alias{scoped_bindings} \title{Questioning \code{scoped_} functions} \usage{ scoped_interactive(value = TRUE, frame = caller_env()) scoped_options(..., .frame = caller_env()) scoped_bindings(..., .env = .frame, .frame = caller_env()) } \arguments{ \item{value}{A single \code{TRUE} or \code{FALSE}. This overrides the return value of \code{is_interactive()}.} \item{frame}{The environment of a running function which defines the scope of the temporary options. When the function returns, the options are reset to their original values.} \item{...}{For \code{local_options()} and \code{push_options()}, named values defining new option values. For \code{peek_options()}, strings or character vectors of option names.} \item{.frame}{The environment of a running function which defines the scope of the temporary options. When the function returns, the options are reset to their original values.} \item{.env}{An environment.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} These functions have been renamed to use the conventional \code{local_} prefix. They will be deprecated in the next minor version of rlang. } rlang/man/env_inherits.Rd0000644000176200001440000000065513405732277015134 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env.R \name{env_inherits} \alias{env_inherits} \title{Does environment inherit from another environment?} \usage{ env_inherits(env, ancestor) } \arguments{ \item{env}{An environment.} \item{ancestor}{Another environment from which \code{x} might inherit.} } \description{ This returns \code{TRUE} if \code{x} has \code{ancestor} among its parents. } rlang/man/f_text.Rd0000644000176200001440000000132013604124170013702 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/formula.R \name{f_text} \alias{f_text} \alias{f_name} \alias{f_label} \title{Turn RHS of formula into a string or label} \usage{ f_text(x, width = 60L, nlines = Inf) f_name(x) f_label(x) } \arguments{ \item{x}{A formula.} \item{width}{Width of each line.} \item{nlines}{Maximum number of lines to extract.} } \description{ Equivalent of \code{\link[=expr_text]{expr_text()}} and \code{\link[=expr_label]{expr_label()}} for formulas. } \examples{ f <- ~ a + b + bc f_text(f) f_label(f) # Names a quoted with `` f_label(~ x) # Strings are encoded f_label(~ "a\nb") # Long expressions are collapsed f_label(~ foo({ 1 + 2 print(x) })) } rlang/man/env_binding_lock.Rd0000644000176200001440000000302713405732277015725 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env-binding.R \name{env_binding_lock} \alias{env_binding_lock} \alias{env_binding_unlock} \alias{env_binding_are_locked} \title{Lock or unlock environment bindings} \usage{ env_binding_lock(env, nms = NULL) env_binding_unlock(env, nms = NULL) env_binding_are_locked(env, nms = NULL) } \arguments{ \item{env}{An environment.} \item{nms}{Names of bindings. Defaults to all bindings in \code{env}.} } \value{ \code{env_binding_are_unlocked()} returns a logical vector as long as \code{nms} and named after it. \code{env_binding_lock()} and \code{env_binding_unlock()} return the old value of \code{env_binding_are_unlocked()} invisibly. } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} Locked environment bindings trigger an error when an attempt is made to redefine the binding. } \examples{ # Bindings are unlocked by default: env <- env(a = "A", b = "B") env_binding_are_locked(env) # But can optionally be locked: env_binding_lock(env, "a") env_binding_are_locked(env) # If run, the following would now return an error because `a` is locked: # env_bind(env, a = "foo") # with_env(env, a <- "bar") # Let's unlock it. Note that the return value indicate which # bindings were locked: were_locked <- env_binding_unlock(env) were_locked # Now that it is unlocked we can modify it again: env_bind(env, a = "foo") with_env(env, a <- "bar") env$a } \seealso{ \code{\link[=env_lock]{env_lock()}} for locking an environment. } \keyword{internal} rlang/man/env_name.Rd0000644000176200001440000000237413405732277014227 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env-special.R \name{env_name} \alias{env_name} \alias{env_label} \title{Label of an environment} \usage{ env_name(env) env_label(env) } \arguments{ \item{env}{An environment.} } \description{ Special environments like the global environment have their own names. \code{env_name()} returns: \itemize{ \item "global" for the global environment. \item "empty" for the empty environment. \item "base" for the base package environment (the last environment on the search path). \item "namespace:pkg" if \code{env} is the namespace of the package "pkg". \item The \code{name} attribute of \code{env} if it exists. This is how the \link[=search_envs]{package environments} and the \link[=ns_imports_env]{imports environments} store their names. The name of package environments is typically "package:pkg". \item The empty string \code{""} otherwise. } \code{env_label()} is exactly like \code{env_name()} but returns the memory address of anonymous environments as fallback. } \examples{ # Some environments have specific names: env_name(global_env()) env_name(ns_env("rlang")) # Anonymous environments don't have names but are labelled by their # address in memory: env_name(env()) env_label(env()) } rlang/man/stack.Rd0000644000176200001440000001200513604124170013520 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{stack} \alias{stack} \alias{global_frame} \alias{current_frame} \alias{ctxt_frame} \alias{call_frame} \alias{ctxt_depth} \alias{call_depth} \alias{ctxt_stack} \alias{call_stack} \title{Call stack information} \usage{ global_frame() current_frame() ctxt_frame(n = 1) call_frame(n = 1, clean = TRUE) ctxt_depth() call_depth() ctxt_stack(n = NULL, trim = 0) call_stack(n = NULL, clean = TRUE) } \arguments{ \item{n}{The number of frames to go back in the stack.} \item{clean}{Whether to post-process the call stack to clean non-standard frames. If \code{TRUE}, suboptimal call-stack entries by \code{\link[base:eval]{base::eval()}} will be cleaned up: the duplicate frame created by \code{eval()} is eliminated.} \item{trim}{The number of layers of intervening frames to trim off the stack. See \code{\link[=stack_trim]{stack_trim()}} and examples.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} The \code{eval_} and \code{call_} families of functions provide a replacement for the base R functions prefixed with \code{sys.} (which are all about the context stack), as well as for \code{\link[=parent.frame]{parent.frame()}} (which is the only base R function for querying the call stack). The context stack includes all R-level evaluation contexts. It is linear in terms of execution history but due to lazy evaluation it is potentially nonlinear in terms of call history. The call stack history, on the other hand, is homogenous. } \details{ \code{ctxt_frame()} and \code{call_frame()} return a \code{frame} object containing the following fields: \code{expr} and \code{env} (call expression and evaluation environment), \code{pos} and \code{caller_pos} (position of current frame in the context stack and position of the caller), and \code{fun} (function of the current frame). \code{ctxt_stack()} and \code{call_stack()} return a list of all context or call frames on the stack. Finally, \code{ctxt_depth()} and \code{call_depth()} report the current context position or the number of calling frames on the stack. The base R functions take two sorts of arguments to indicate which frame to query: \code{which} and \code{n}. The \code{n} argument is straightforward: it's the number of frames to go down the stack, with \code{n = 1} referring to the current context. The \code{which} argument is more complicated and changes meaning for values lower than 1. For the sake of consistency, the rlang functions all take the same kind of argument \code{n}. This argument has a single meaning (the number of frames to go down the stack) and cannot be lower than 1. Note finally that \code{parent.frame(1)} corresponds to \code{call_frame(2)$env}, as \code{n = 1} always refers to the current frame. This makes the \verb{_frame()} and \verb{_stack()} functions consistent: \code{ctxt_frame(2)} is the same as \code{ctxt_stack()[[2]]}. Also, \code{ctxt_depth()} returns one more frame than \code{\link[base:sys.nframe]{base::sys.nframe()}} because it counts the global frame. That is consistent with the \verb{_stack()} functions which return the global frame as well. This way, \code{call_stack(call_depth())} is the same as \code{global_frame()}. } \section{Life cycle}{ These functions are soft-deprecated and replaced by \code{\link[=trace_back]{trace_back()}}. } \examples{ # Expressions within arguments count as contexts identity(identity(ctxt_depth())) # returns 2 # But they are not part of the call stack because arguments are # evaluated within the calling function (or the global environment # if called at top level) identity(identity(call_depth())) # returns 0 # The context stacks includes all intervening execution frames. The # call stack doesn't: f <- function(x) identity(x) f(f(ctxt_stack())) f(f(call_stack())) g <- function(cmd) cmd() f(g(ctxt_stack)) f(g(call_stack)) # The rlang _stack() functions return a list of frame # objects. Use purrr::transpose() or index a field with # purrr::map()'s to extract a particular field from a stack: # stack <- f(f(call_stack())) # purrr::map(stack, "env") # purrr::transpose(stack)$expr # current_frame() is an alias for ctxt_frame(1) fn <- function() list(current = current_frame(), first = ctxt_frame(1)) fn() # While current_frame() is the top of the stack, global_frame() is # the bottom: fn <- function() { n <- ctxt_depth() ctxt_frame(n) } identical(fn(), global_frame()) # ctxt_stack() returns a stack with all intervening frames. You can # trim layers of intervening frames with the trim argument: identity(identity(ctxt_stack())) identity(identity(ctxt_stack(trim = 1))) # ctxt_stack() is called within fn() with intervening frames: fn <- function(trim) identity(identity(ctxt_stack(trim = trim))) fn(0) # We can trim the first layer of those: fn(1) # The outside intervening frames (at the fn() call site) are still # returned, but can be trimmed as well: identity(identity(fn(1))) identity(identity(fn(2))) g <- function(trim) identity(identity(fn(trim))) g(2) g(3) } \keyword{internal} rlang/man/env_bind.Rd0000644000176200001440000001341413604124167014212 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env-binding.R \name{env_bind} \alias{env_bind} \alias{env_bind_lazy} \alias{env_bind_active} \title{Bind symbols to objects in an environment} \usage{ env_bind(.env, ...) env_bind_lazy(.env, ..., .eval_env = caller_env()) env_bind_active(.env, ...) } \arguments{ \item{.env}{An environment.} \item{...}{<\link[=dyn-dots]{dynamic}> Named objects (\code{env_bind()}), expressions \code{env_bind_lazy()}, or functions (\code{env_bind_active()}). Use \code{\link[=zap]{zap()}} to remove bindings.} \item{.eval_env}{The environment where the expressions will be evaluated when the symbols are forced.} } \value{ The input object \code{.env}, with its associated environment modified in place, invisibly. } \description{ These functions create bindings in an environment. The bindings are supplied through \code{...} as pairs of names and values or expressions. \code{env_bind()} is equivalent to evaluating a \verb{<-} expression within the given environment. This function should take care of the majority of use cases but the other variants can be useful for specific problems. \itemize{ \item \code{env_bind()} takes named \emph{values} which are bound in \code{.env}. \code{env_bind()} is equivalent to \code{\link[base:assign]{base::assign()}}. \item \code{env_bind_active()} takes named \emph{functions} and creates active bindings in \code{.env}. This is equivalent to \code{\link[base:makeActiveBinding]{base::makeActiveBinding()}}. An active binding executes a function each time it is evaluated. The arguments are passed to \code{\link[=as_function]{as_function()}} so you can supply formulas instead of functions. Remember that functions are scoped in their own environment. These functions can thus refer to symbols from this enclosure that are not actually in scope in the dynamic environment where the active bindings are invoked. This allows creative solutions to difficult problems (see the implementations of \code{dplyr::do()} methods for an example). \item \code{env_bind_lazy()} takes named \emph{expressions}. This is equivalent to \code{\link[base:delayedAssign]{base::delayedAssign()}}. The arguments are captured with \code{\link[=exprs]{exprs()}} (and thus support call-splicing and unquoting) and assigned to symbols in \code{.env}. These expressions are not evaluated immediately but lazily. Once a symbol is evaluated, the corresponding expression is evaluated in turn and its value is bound to the symbol (the expressions are thus evaluated only once, if at all). } } \section{Side effects}{ Since environments have reference semantics (see relevant section in \code{\link[=env]{env()}} documentation), modifying the bindings of an environment produces effects in all other references to that environment. In other words, \code{env_bind()} and its variants have side effects. Like other side-effecty functions like \code{par()} and \code{options()}, \code{env_bind()} and variants return the old values invisibly. } \section{Life cycle}{ Passing an environment wrapper like a formula or a function instead of an environment is soft-deprecated as of rlang 0.3.0. This internal genericity was causing confusion (see issue #427). You should now extract the environment separately before calling these functions. } \examples{ # env_bind() is a programmatic way of assigning values to symbols # with `<-`. We can add bindings in the current environment: env_bind(current_env(), foo = "bar") foo # Or modify those bindings: bar <- "bar" env_bind(current_env(), bar = "BAR") bar # You can remove bindings by supplying zap sentinels: env_bind(current_env(), foo = zap()) try(foo) # Unquote-splice a named list of zaps zaps <- rep_named(c("foo", "bar"), list(zap())) env_bind(current_env(), !!!zaps) try(bar) # It is most useful to change other environments: my_env <- env() env_bind(my_env, foo = "foo") my_env$foo # A useful feature is to splice lists of named values: vals <- list(a = 10, b = 20) env_bind(my_env, !!!vals, c = 30) my_env$b my_env$c # You can also unquote a variable referring to a symbol or a string # as binding name: var <- "baz" env_bind(my_env, !!var := "BAZ") my_env$baz # The old values of the bindings are returned invisibly: old <- env_bind(my_env, a = 1, b = 2, baz = "baz") old # You can restore the original environment state by supplying the # old values back: env_bind(my_env, !!!old) # env_bind_lazy() assigns expressions lazily: env <- env() env_bind_lazy(env, name = { cat("forced!\n"); "value" }) # Referring to the binding will cause evaluation: env$name # But only once, subsequent references yield the final value: env$name # You can unquote expressions: expr <- quote(message("forced!")) env_bind_lazy(env, name = !!expr) env$name # By default the expressions are evaluated in the current # environment. For instance we can create a local binding and refer # to it, even though the variable is bound in a different # environment: who <- "mickey" env_bind_lazy(env, name = paste(who, "mouse")) env$name # You can specify another evaluation environment with `.eval_env`: eval_env <- env(who = "minnie") env_bind_lazy(env, name = paste(who, "mouse"), .eval_env = eval_env) env$name # Or by unquoting a quosure: quo <- local({ who <- "fievel" quo(paste(who, "mouse")) }) env_bind_lazy(env, name = !!quo) env$name # You can create active bindings with env_bind_active(). Active # bindings execute a function each time they are evaluated: fn <- function() { cat("I have been called\n") rnorm(1) } env <- env() env_bind_active(env, symbol = fn) # `fn` is executed each time `symbol` is evaluated or retrieved: env$symbol env$symbol eval_bare(quote(symbol), env) eval_bare(quote(symbol), env) # All arguments are passed to as_function() so you can use the # formula shortcut: env_bind_active(env, foo = ~ runif(1)) env$foo env$foo } rlang/man/dots_definitions.Rd0000644000176200001440000000237113604124167015772 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dots.R \name{dots_definitions} \alias{dots_definitions} \title{Capture definition objects} \usage{ dots_definitions( ..., .named = FALSE, .ignore_empty = c("trailing", "none", "all") ) } \arguments{ \item{...}{For \code{enexprs()}, \code{ensyms()} and \code{enquos()}, names of arguments to capture without evaluation (including \code{...}). For \code{exprs()} and \code{quos()}, the expressions to capture unevaluated (including expressions contained in \code{...}).} \item{.named}{Whether to ensure all dots are named. Unnamed elements are processed with \code{\link[=quo_name]{quo_name()}} to build a default name. See also \code{\link[=quos_auto_name]{quos_auto_name()}}.} \item{.ignore_empty}{Whether to ignore empty arguments. Can be one of \code{"trailing"}, \code{"none"}, \code{"all"}. If \code{"trailing"}, only the last argument is ignored if it is empty. Note that \code{"trailing"} applies only to arguments passed in \code{...}, not to named arguments. On the other hand, \code{"all"} also applies to named arguments.} } \description{ Capture definition objects } \section{Life cycle}{ \code{dots_definitions()} is experimental. Expect API changes. } \keyword{internal} rlang/man/call_modify.Rd0000644000176200001440000000637713604124167014722 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/call.R \name{call_modify} \alias{call_modify} \title{Modify the arguments of a call} \usage{ call_modify( .call, ..., .homonyms = c("keep", "first", "last", "error"), .standardise = NULL, .env = caller_env() ) } \arguments{ \item{.call}{Can be a call, a formula quoting a call in the right-hand side, or a frame object from which to extract the call expression.} \item{...}{<\link[=dyn-dots]{dynamic}> Named or unnamed expressions (constants, names or calls) used to modify the call. Use \code{\link[=zap]{zap()}} to remove arguments. Empty arguments are preserved.} \item{.homonyms}{How to treat arguments with the same name. The default, \code{"keep"}, preserves these arguments. Set \code{.homonyms} to \code{"first"} to only keep the first occurrences, to \code{"last"} to keep the last occurrences, and to \code{"error"} to raise an informative error and indicate what arguments have duplicated names.} \item{.standardise, .env}{Soft-deprecated as of rlang 0.3.0. Please call \code{\link[=call_standardise]{call_standardise()}} manually.} } \value{ A quosure if \code{.call} is a quosure, a call otherwise. } \description{ If you are working with a user-supplied call, make sure the arguments are standardised with \code{\link[=call_standardise]{call_standardise()}} before modifying the call. } \section{Life cycle}{ \itemize{ \item The \code{.standardise} argument is deprecated as of rlang 0.3.0. \item In rlang 0.2.0, \code{lang_modify()} was deprecated and renamed to \code{call_modify()}. See lifecycle section in \code{\link[=call2]{call2()}} for more about this change. } } \examples{ call <- quote(mean(x, na.rm = TRUE)) # Modify an existing argument call_modify(call, na.rm = FALSE) call_modify(call, x = quote(y)) # Remove an argument call_modify(call, na.rm = zap()) # Add a new argument call_modify(call, trim = 0.1) # Add an explicit missing argument: call_modify(call, na.rm = ) # Supply a list of new arguments with `!!!` newargs <- list(na.rm = NULL, trim = 0.1) call <- call_modify(call, !!!newargs) call # Remove multiple arguments by splicing zaps: newargs <- rep_named(c("na.rm", "trim"), list(zap())) call <- call_modify(call, !!!newargs) call # Modify the `...` arguments as if it were a named argument: call <- call_modify(call, ... = ) call call <- call_modify(call, ... = zap()) call # When you're working with a user-supplied call, standardise it # beforehand because it might contain unmatched arguments: user_call <- quote(matrix(x, nc = 3)) call_modify(user_call, ncol = 1) # Standardising applies the usual argument matching rules: user_call <- call_standardise(user_call) user_call call_modify(user_call, ncol = 1) # You can also modify quosures inplace: f <- quo(matrix(bar)) call_modify(f, quote(foo)) # By default, arguments with the same name are kept. This has # subtle implications, for instance you can move an argument to # last position by removing it and remapping it: call <- quote(foo(bar = , baz)) call_modify(call, bar = NULL, bar = missing_arg()) # You can also choose to keep only the first or last homonym # arguments: args <- list(bar = NULL, bar = missing_arg()) call_modify(call, !!!args, .homonyms = "first") call_modify(call, !!!args, .homonyms = "last") } rlang/man/zap.Rd0000644000176200001440000000152213405732277013223 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/s3.R \name{zap} \alias{zap} \alias{is_zap} \title{Create zap objects} \usage{ zap() is_zap(x) } \arguments{ \item{x}{An object to test.} } \description{ \code{zap()} creates a sentinel object that indicates that an object should be removed. For instance, named zaps instruct \code{\link[=env_bind]{env_bind()}} and \code{\link[=call_modify]{call_modify()}} to remove those objects from the environment or the call. The advantage of zap objects is that they unambiguously signal the intent of removing an object. Sentinels like \code{NULL} or \code{\link[=missing_arg]{missing_arg()}} are ambiguous because they represent valid R objects. } \examples{ # Create one zap object: zap() # Create a list of zaps: rep(list(zap()), 3) rep_named(c("foo", "bar"), list(zap())) } rlang/man/is_condition.Rd0000644000176200001440000000043313553606252015107 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cnd.R \name{is_condition} \alias{is_condition} \title{Is object a condition?} \usage{ is_condition(x) } \arguments{ \item{x}{An object to test.} } \description{ Is object a condition? } \keyword{internal} rlang/man/scoped_env.Rd0000644000176200001440000000126313500223442014541 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{scoped_env} \alias{scoped_env} \alias{is_scoped} \alias{scoped_envs} \alias{scoped_names} \title{Retired \code{scoped} functions} \usage{ scoped_env(nm) is_scoped(nm) scoped_envs() scoped_names() } \arguments{ \item{nm}{The name of an environment attached to the search path. Call \code{\link[base:search]{base::search()}} to see what is currently on the path.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} These functions are deprecated as of rlang 0.3.0. They are replaced by \code{\link[=is_attached]{is_attached()}}, ... } \keyword{internal} rlang/man/cnd_message.Rd0000644000176200001440000000416013565200230014664 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cnd-message.R \name{cnd_message} \alias{cnd_message} \alias{cnd_header} \alias{cnd_body} \alias{cnd_footer} \title{Build an error message from parts} \usage{ cnd_message(cnd) cnd_header(cnd, ...) cnd_body(cnd, ...) cnd_footer(cnd, ...) } \arguments{ \item{cnd}{A condition object.} \item{...}{Arguments passed to methods.} } \description{ \code{cnd_message()} assembles an error message from three generics: \itemize{ \item \code{cnd_header()} \item \code{cnd_body()} \item \code{cnd_footer()} } The default method for the error header returns the \code{message} field of the condition object. The default methods for the body and footer return empty character vectors. In general, methods for these generics should return a character vector. The elements are combined into a single string with a newline separator. \code{cnd_message()} is automatically called by the \code{conditionMessage()} for rlang errors. Error classes created with \code{\link[=abort]{abort()}} only need to implement header, body or footer methods. This provides a lot of flexibility for hierarchies of error classes, for instance you could inherit the body of an error message from a parent class while overriding the header and footer. } \section{Overriding \code{cnd_body()}}{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} Sometimes the contents of an error message depends on the state of your checking routine. In that case, it can be tricky to lazily generate error messages with \code{cnd_body()}: you have the choice between overspecifying your error class hierarchies with one class per state, or replicating the type-checking control flow within the \code{cnd_body()} method. None of these options are ideal. A better option is to define a \code{body} field in your error object containing a static string, a \link[=as_function]{lambda-formula}, or a function with the same signature as \code{cnd_body()}. This field overrides the \code{cnd_body()} generic and makes it easy to generate an error message tailored to the state in which the error was constructed. } rlang/man/mut_node_car.Rd0000644000176200001440000000213713500223442015054 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{mut_node_car} \alias{mut_node_car} \alias{mut_node_cdr} \alias{mut_node_caar} \alias{mut_node_cadr} \alias{mut_node_cdar} \alias{mut_node_cddr} \alias{mut_node_tag} \title{Mutate node components} \usage{ mut_node_car(x, newcar) mut_node_cdr(x, newcdr) mut_node_caar(x, newcar) mut_node_cadr(x, newcar) mut_node_cdar(x, newcdr) mut_node_cddr(x, newcdr) mut_node_tag(x, newtag) } \arguments{ \item{x}{A language or pairlist node. Note that these functions are barebones and do not perform any type checking.} \item{newcar}{The new CAR or CDR for the node. These can be any R objects.} \item{newcdr}{The new CAR or CDR for the node. These can be any R objects.} \item{newtag}{The new tag for the node. This should be a symbol.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} These functions were deprecated and renamed with \code{node_poke_} prefix in rlang 0.2.0. This change follows a new naming convention where mutation is referred to as "poking". } \keyword{internal} rlang/man/f_rhs.Rd0000644000176200001440000000154313351410454013523 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/formula.R \name{f_rhs} \alias{f_rhs} \alias{f_rhs<-} \alias{f_lhs} \alias{f_lhs<-} \alias{f_env} \alias{f_env<-} \title{Get or set formula components} \usage{ f_rhs(f) f_rhs(x) <- value f_lhs(f) f_lhs(x) <- value f_env(f) f_env(x) <- value } \arguments{ \item{f, x}{A formula} \item{value}{The value to replace with.} } \value{ \code{f_rhs} and \code{f_lhs} return language objects (i.e. atomic vectors of length 1, a name, or a call). \code{f_env} returns an environment. } \description{ \code{f_rhs} extracts the righthand side, \code{f_lhs} extracts the lefthand side, and \code{f_env} extracts the environment. All functions throw an error if \code{f} is not a formula. } \examples{ f_rhs(~ 1 + 2 + 3) f_rhs(~ x) f_rhs(~ "A") f_rhs(1 ~ 2) f_lhs(~ y) f_lhs(x ~ y) f_env(~ x) } rlang/man/caller_fn.Rd0000644000176200001440000000152213554012136014344 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/stack.R \name{caller_fn} \alias{caller_fn} \alias{current_fn} \title{Get properties of the current or caller frame} \usage{ caller_fn(n = 1) current_fn() } \arguments{ \item{n}{The number of generations to go back.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} \itemize{ \item The current frame is the execution context of the function that is currently being evaluated. \item The caller frame is the execution context of the function that called the function currently being evaluated. } See the \link[=stack]{call stack} topic for more information. } \section{Life cycle}{ These functions are experimental. } \seealso{ \code{\link[=caller_env]{caller_env()}} and \code{\link[=current_env]{current_env()}} } \keyword{internal} rlang/man/sym.Rd0000644000176200001440000000111313500434414013221 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/sym.R \name{sym} \alias{sym} \alias{syms} \title{Create a symbol or list of symbols} \usage{ sym(x) syms(x) } \arguments{ \item{x}{A string or list of strings.} } \value{ A symbol for \code{sym()} and a list of symbols for \code{syms()}. } \description{ These functions take strings as input and turn them into symbols. } \examples{ # The empty string returns the missing argument: sym("") # This way sym() and as_string() are inverse of each other: as_string(missing_arg()) sym(as_string(missing_arg())) } rlang/man/names2.Rd0000644000176200001440000000125313405732277013617 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/attr.R \name{names2} \alias{names2} \title{Get names of a vector} \usage{ names2(x) } \arguments{ \item{x}{A vector.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("stable")} This names getter always returns a character vector, even when an object does not have a \code{names} attribute. In this case, it returns a vector of empty names \code{""}. It also standardises missing names to \code{""}. } \section{Life cycle}{ \code{names2()} is stable. } \examples{ names2(letters) # It also takes care of standardising missing names: x <- set_names(1:3, c("a", NA, "b")) names2(x) } rlang/man/is_environment.Rd0000644000176200001440000000061413351410763015462 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/types.R \name{is_environment} \alias{is_environment} \alias{is_bare_environment} \title{Is object an environment?} \usage{ is_environment(x) is_bare_environment(x) } \arguments{ \item{x}{object to test} } \description{ \code{is_bare_environment()} tests whether \code{x} is an environment without a s3 or s4 class. } rlang/man/call_standardise.Rd0000644000176200001440000000154413500223442015712 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/call.R \name{call_standardise} \alias{call_standardise} \title{Standardise a call} \usage{ call_standardise(call, env = caller_env()) } \arguments{ \item{call}{Can be a call or a quosure that wraps a call.} \item{env}{The environment where to find the definition of the function quoted in \code{call} in case \code{call} is not wrapped in a quosure.} } \value{ A quosure if \code{call} is a quosure, a raw call otherwise. } \description{ This is essentially equivalent to \code{\link[base:match.call]{base::match.call()}}, but with experimental handling of primitive functions. } \section{Life cycle}{ In rlang 0.2.0, \code{lang_standardise()} was deprecated and renamed to \code{call_standardise()}. See lifecycle section in \code{\link[=call2]{call2()}} for more about this change. } rlang/man/call_name.Rd0000644000176200001440000000220613500223442014325 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/call.R \name{call_name} \alias{call_name} \alias{call_ns} \title{Extract function name or namespaced of a call} \usage{ call_name(call) call_ns(call) } \arguments{ \item{call}{Can be a call or a quosure that wraps a call.} } \value{ A string with the function name, or \code{NULL} if the function is anonymous. } \description{ Extract function name or namespaced of a call } \section{Life cycle}{ In rlang 0.2.0, \code{lang_name()} was deprecated and renamed to \code{call_name()}. See lifecycle section in \code{\link[=call2]{call2()}} for more about this change. } \examples{ # Extract the function name from quoted calls: call_name(quote(foo(bar))) call_name(quo(foo(bar))) # Namespaced calls are correctly handled: call_name(~base::matrix(baz)) # Anonymous and subsetted functions return NULL: call_name(quote(foo$bar())) call_name(quote(foo[[bar]]())) call_name(quote(foo()())) # Extract namespace of a call with call_ns(): call_ns(quote(base::bar())) # If not namespaced, call_ns() returns NULL: call_ns(quote(bar())) } \seealso{ \code{\link[=call_fn]{call_fn()}} } rlang/man/eval_tidy.Rd0000644000176200001440000001211713604124170014377 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/eval-tidy.R \name{eval_tidy} \alias{eval_tidy} \title{Evaluate an expression with quosures and pronoun support} \usage{ eval_tidy(expr, data = NULL, env = caller_env()) } \arguments{ \item{expr}{An expression or quosure to evaluate.} \item{data}{A data frame, or named list or vector. Alternatively, a data mask created with \code{\link[=as_data_mask]{as_data_mask()}} or \code{\link[=new_data_mask]{new_data_mask()}}. Objects in \code{data} have priority over those in \code{env}. See the section about data masking.} \item{env}{The environment in which to evaluate \code{expr}. This environment is not applicable for quosures because they have their own environments.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("stable")} \code{eval_tidy()} is a variant of \code{\link[base:eval]{base::eval()}} that powers the tidy evaluation framework. Like \code{eval()} it accepts user data as argument. Whereas \code{eval()} simply transforms the data to an environment, \code{eval_tidy()} transforms it to a \strong{data mask} with \code{\link[=as_data_mask]{as_data_mask()}}. Evaluating in a data mask enables the following features: \itemize{ \item \link[=nse-defuse]{Quosures}. Quosures are expressions bundled with an environment. If \code{data} is supplied, objects in the data mask always have precedence over the quosure environment, i.e. the data masks the environment. \item \link[=.data]{Pronouns}. If \code{data} is supplied, the \code{.env} and \code{.data} pronouns are installed in the data mask. \code{.env} is a reference to the calling environment and \code{.data} refers to the \code{data} argument. These pronouns lets you be explicit about where to find values and throw errors if you try to access non-existent values. } } \section{Data masking}{ Data masking refers to how columns or objects inside \code{data} have priority over objects defined in \code{env} (or in the quosure environment, if applicable). If there is a column \code{var} in \code{data} and an object \code{var} in \code{env}, and \code{expr} refers to \code{var}, the column has priority:\preformatted{var <- "this one?" data <- data.frame(var = rep("Or that one?", 3)) within <- function(data, expr) \{ eval_tidy(enquo(expr), data) \} within(data, toupper(var)) #> [1] "OR THAT ONE?" "OR THAT ONE?" "OR THAT ONE?" } Because the columns or objects in \code{data} are always found first, before objects from \code{env}, we say that the data "masks" the environment. } \section{When should eval_tidy() be used instead of eval()?}{ \code{base::eval()} is sufficient for simple evaluation. Use \code{eval_tidy()} when you'd like to support expressions referring to the \code{.data} pronoun, or when you need to support quosures. If you're evaluating an expression captured with quasiquotation support, it is recommended to use \code{eval_tidy()} because users will likely unquote quosures. Note that unwrapping a quosure with \code{\link[=quo_get_expr]{quo_get_expr()}} does not guarantee that there is no quosures inside the expression. Quosures might be unquoted anywhere. For instance, the following does not work reliably in the presence of nested quosures:\preformatted{my_quoting_fn <- function(x) \{ x <- enquo(x) expr <- quo_get_expr(x) env <- quo_get_env(x) eval(expr, env) \} # Works: my_quoting_fn(toupper(letters)) # Fails because of a nested quosure: my_quoting_fn(toupper(!!quo(letters))) } } \section{Life cycle}{ \strong{rlang 0.3.0} Passing an environment to \code{data} is deprecated. Please construct an rlang data mask with \code{\link[=new_data_mask]{new_data_mask()}}. } \examples{ # With simple quoted expressions eval_tidy() works the same way as # eval(): apple <- "apple" kiwi <- "kiwi" expr <- quote(paste(apple, kiwi)) expr eval(expr) eval_tidy(expr) # Both accept a data mask as argument: data <- list(apple = "CARROT", kiwi = "TOMATO") eval(expr, data) eval_tidy(expr, data) # In addition eval_tidy() has support for quosures: with_data <- function(data, expr) { quo <- enquo(expr) eval_tidy(quo, data) } with_data(NULL, apple) with_data(data, apple) with_data(data, list(apple, kiwi)) # Secondly eval_tidy() installs handy pronouns that allow users to # be explicit about where to find symbols: with_data(data, .data$apple) with_data(data, .env$apple) # Note that instead of using `.env` it is often equivalent and may # be preferred to unquote a value. There are two differences. First # unquoting happens earlier, when the quosure is created. Secondly, # subsetting `.env` with the `$` operator may be brittle because # `$` does not look through the parents of the environment. # # For instance using `.env$name` in a magrittr pipeline is an # instance where this poses problem, because the magrittr pipe # currently (as of v1.5.0) evaluates its operands in a *child* of # the current environment (this child environment is where it # defines the pronoun `.`). \dontrun{ data \%>\% with_data(!!kiwi) # "kiwi" data \%>\% with_data(.env$kiwi) # NULL } } \seealso{ \link{nse-force} for the second leg of the tidy evaluation framework. } rlang/man/rlang_backtrace_on_error.Rd0000644000176200001440000000274413554012432017434 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cnd-abort.R \name{rlang_backtrace_on_error} \alias{rlang_backtrace_on_error} \alias{add_backtrace} \title{Display backtrace on error} \description{ Errors thrown with \code{\link[=abort]{abort()}} automatically save a backtrace that can be inspected by calling \code{\link[=last_error]{last_error()}}. Optionally, you can also display the backtrace alongside the error message by setting the option \code{rlang_backtrace_on_error} to one of the following values: \itemize{ \item \code{"reminder"}: Display a reminder that the backtrace can be inspected by calling \code{\link[rlang:last_error]{rlang::last_error()}}. \item \code{"branch"}: Display a simplified backtrace. \item \code{"collapse"}: Display a collapsed backtrace tree. \item \code{"full"}: Display the full backtrace tree. } } \section{Promote base errors to rlang errors}{ Call \code{options(error = rlang::entrace)} to instrument base errors with rlang features. This handler does two things: \itemize{ \item It saves the base error as an rlang object. This allows you to call \code{\link[=last_error]{last_error()}} to print the backtrace or inspect its data. \item It prints the backtrace for the current error according to the \code{rlang_backtrace_on_error} option. } } \examples{ # Display a simplified backtrace on error for both base and rlang # errors: # options( # rlang_backtrace_on_error = "branch", # error = rlang::entrace # ) # stop("foo") } rlang/man/is_symbol.Rd0000644000176200001440000000052613351410763014425 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/sym.R \name{is_symbol} \alias{is_symbol} \title{Is object a symbol?} \usage{ is_symbol(x, name = NULL) } \arguments{ \item{x}{An object to test.} \item{name}{An optional name or vector of names that the symbol should match.} } \description{ Is object a symbol? } rlang/man/op-na-default.Rd0000644000176200001440000000126213517571557015074 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/operators.R \name{op-na-default} \alias{op-na-default} \alias{\%|\%} \title{Replace missing values} \usage{ x \%|\% y } \arguments{ \item{x}{The original values.} \item{y}{The replacement values. Must be of length 1 or the same length as \code{x}.} } \description{ This infix function is similar to \code{\%||\%} but is vectorised and provides a default value for missing elements. It is faster than using \code{\link[base:ifelse]{base::ifelse()}} and does not perform type conversions. } \examples{ c("a", "b", NA, "c") \%|\% "default" c(1L, NA, 3L, NA, NA) \%|\% (6L:10L) } \seealso{ \link{op-null-default} } rlang/man/is_empty.Rd0000644000176200001440000000052413351410454014251 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/types.R \name{is_empty} \alias{is_empty} \title{Is object an empty vector or NULL?} \usage{ is_empty(x) } \arguments{ \item{x}{object to test} } \description{ Is object an empty vector or NULL? } \examples{ is_empty(NULL) is_empty(list()) is_empty(list(NULL)) } rlang/man/exprs_auto_name.Rd0000644000176200001440000000172413561023554015620 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nse-defuse.R \name{exprs_auto_name} \alias{exprs_auto_name} \alias{quos_auto_name} \title{Ensure that all elements of a list of expressions are named} \usage{ exprs_auto_name(exprs, width = NULL, printer = NULL) quos_auto_name(quos, width = NULL) } \arguments{ \item{exprs}{A list of expressions.} \item{width}{Deprecated. Maximum width of names.} \item{printer}{Deprecated. A function that takes an expression and converts it to a string. This function must take an expression as the first argument and \code{width} as the second argument.} \item{quos}{A list of quosures.} } \description{ This gives default names to unnamed elements of a list of expressions (or expression wrappers such as formulas or quosures). \code{exprs_auto_name()} deparses the expressions with \code{\link[=expr_name]{expr_name()}} by default. \code{quos_auto_name()} deparses with \code{\link[=quo_name]{quo_name()}}. } rlang/man/local_bindings.Rd0000644000176200001440000000301013563536306015372 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env-binding.R \name{local_bindings} \alias{local_bindings} \alias{with_bindings} \title{Temporarily change bindings of an environment} \usage{ local_bindings(..., .env = .frame, .frame = caller_env()) with_bindings(.expr, ..., .env = caller_env()) } \arguments{ \item{...}{Pairs of names and values. These dots support splicing (with value semantics) and name unquoting.} \item{.env}{An environment.} \item{.frame}{The frame environment that determines the scope of the temporary bindings. When that frame is popped from the call stack, bindings are switched back to their original values.} \item{.expr}{An expression to evaluate with temporary bindings.} } \value{ \code{local_bindings()} returns the values of old bindings invisibly; \code{with_bindings()} returns the value of \code{expr}. } \description{ \itemize{ \item \code{local_bindings()} temporarily changes bindings in \code{.env} (which is by default the caller environment). The bindings are reset to their original values when the current frame (or an arbitrary one if you specify \code{.frame}) goes out of scope. \item \code{with_bindings()} evaluates \code{expr} with temporary bindings. When \code{with_bindings()} returns, bindings are reset to their original values. It is a simple wrapper around \code{local_bindings()}. } } \examples{ foo <- "foo" bar <- "bar" # `foo` will be temporarily rebinded while executing `expr` with_bindings(paste(foo, bar), foo = "rebinded") paste(foo, bar) } rlang/man/cnd.Rd0000644000176200001440000000467013604124167013176 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cnd-error.R, R/cnd.R \name{error_cnd} \alias{error_cnd} \alias{cnd} \alias{warning_cnd} \alias{message_cnd} \title{Create a condition object} \usage{ error_cnd(.subclass = NULL, ..., message = "", trace = NULL, parent = NULL) cnd(class, ..., message = "", .subclass) warning_cnd(class = NULL, ..., message = "", .subclass) message_cnd(class = NULL, ..., message = "", .subclass) } \arguments{ \item{.subclass}{This argument was renamed to \code{class} in rlang 0.4.2. It will be deprecated in the next major version. This is for consistency with our conventions for class constructors documented in \url{https://adv-r.hadley.nz/s3.html#s3-subclassing}.} \item{...}{<\link[=dyn-dots]{dynamic}> Named data fields stored inside the condition object.} \item{message}{A default message to inform the user about the condition when it is signalled.} \item{trace}{A \code{trace} object created by \code{\link[=trace_back]{trace_back()}}.} \item{parent}{A parent condition object created by \code{\link[=abort]{abort()}}.} \item{class}{The condition subclass.} } \description{ These constructors make it easy to create subclassed conditions. Conditions are objects that power the error system in R. They can also be used for passing messages to pre-established handlers. } \details{ \code{cnd()} creates objects inheriting from \code{condition}. Conditions created with \code{error_cnd()}, \code{warning_cnd()} and \code{message_cnd()} inherit from \code{error}, \code{warning} or \code{message}. } \section{Lifecycle}{ The \code{.type} and \code{.msg} arguments have been renamed to \code{.subclass} and \code{message}. They are deprecated as of rlang 0.3.0. } \examples{ # Create a condition inheriting from the s3 type "foo": cnd <- cnd("foo") # Signal the condition to potential handlers. Since this is a bare # condition the signal has no effect if no handlers are set up: cnd_signal(cnd) # When a relevant handler is set up, the signal causes the handler # to be called: with_handlers(cnd_signal(cnd), foo = exiting(function(c) "caught!")) # Handlers can be thrown or executed inplace. See with_handlers() # documentation for more on this. # Signalling an error condition aborts the current computation: err <- error_cnd("foo", message = "I am an error") try(cnd_signal(err)) } \seealso{ \code{\link[=cnd_signal]{cnd_signal()}}, \code{\link[=with_handlers]{with_handlers()}}. } \keyword{internal} rlang/man/lang.Rd0000644000176200001440000000136713563531434013356 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{lang} \alias{lang} \alias{new_language} \title{Create a call} \usage{ lang(.fn, ..., .ns = NULL) new_language(head, tail = NULL) } \arguments{ \item{.fn}{Function to call. Must be a callable object: a string, symbol, call, or a function.} \item{...}{<\link[=dyn-dots]{dynamic}> Arguments for the function call. Empty arguments are preserved.} \item{.ns}{Namespace with which to prefix \code{.fn}. Must be a string or symbol.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} These functions are deprecated, please use \code{\link[=call2]{call2()}} and \code{\link[=new_call]{new_call()}} instead. } \keyword{internal} rlang/man/is_callable.Rd0000644000176200001440000000226313553606252014663 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/call.R \name{is_callable} \alias{is_callable} \title{Is an object callable?} \usage{ is_callable(x) } \arguments{ \item{x}{An object to test.} } \description{ A callable object is an object that can appear in the function position of a call (as opposed to argument position). This includes \link[=is_symbolic]{symbolic objects} that evaluate to a function or literal functions embedded in the call. } \details{ Note that strings may look like callable objects because expressions of the form \code{"list"()} are valid R code. However, that's only because the R parser transforms strings to symbols. It is not legal to manually set language heads to strings. } \examples{ # Symbolic objects and functions are callable: is_callable(quote(foo)) is_callable(base::identity) # node_poke_car() lets you modify calls without any checking: lang <- quote(foo(10)) node_poke_car(lang, current_env()) # Use is_callable() to check an input object is safe to put as CAR: obj <- base::identity if (is_callable(obj)) { lang <- node_poke_car(lang, obj) } else { abort("`obj` must be callable") } eval_bare(lang) } \keyword{internal} rlang/man/are_na.Rd0000644000176200001440000000316013554012136013644 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/vec-na.R \name{are_na} \alias{are_na} \alias{is_na} \alias{is_lgl_na} \alias{is_int_na} \alias{is_dbl_na} \alias{is_chr_na} \alias{is_cpl_na} \title{Test for missing values} \usage{ are_na(x) is_na(x) is_lgl_na(x) is_int_na(x) is_dbl_na(x) is_chr_na(x) is_cpl_na(x) } \arguments{ \item{x}{An object to test} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} \code{are_na()} checks for missing values in a vector and is equivalent to \code{\link[base:is.na]{base::is.na()}}. It is a vectorised predicate, meaning that its output is always the same length as its input. On the other hand, \code{is_na()} is a scalar predicate and always returns a scalar boolean, \code{TRUE} or \code{FALSE}. If its input is not scalar, it returns \code{FALSE}. Finally, there are typed versions that check for particular \link[=missing]{missing types}. } \details{ The scalar predicates accept non-vector inputs. They are equivalent to \code{\link[=is_null]{is_null()}} in that respect. In contrast the vectorised predicate \code{are_na()} requires a vector input since it is defined over vector values. } \section{Life cycle}{ These functions might be moved to the vctrs package at some point. This is why they are marked as questioning. } \examples{ # are_na() is vectorised and works regardless of the type are_na(c(1, 2, NA)) are_na(c(1L, NA, 3L)) # is_na() checks for scalar input and works for all types is_na(NA) is_na(na_dbl) is_na(character(0)) # There are typed versions as well: is_lgl_na(NA) is_lgl_na(na_dbl) } \keyword{internal} rlang/man/overscope_eval_next.Rd0000644000176200001440000000152113604124170016466 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{overscope_eval_next} \alias{overscope_eval_next} \title{Evaluate next quosure in a data mask} \usage{ overscope_eval_next(overscope, quo, env = base_env()) } \arguments{ \item{overscope}{A valid overscope containing bindings for \code{~}, \code{.top_env} and \verb{_F} and whose parents contain overscoped bindings for tidy evaluation.} \item{quo}{A quosure.} \item{env}{The lexical enclosure in case \code{quo} is not a validly scoped quosure. This is the \link[=base_env]{base environment} by default.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} \code{overscope_eval_next()} is deprecated as of rlang 0.2.0. Please use \code{eval_tidy()} to which you can now supply an overscope. } \keyword{internal} rlang/man/op-get-attr.Rd0000644000176200001440000000147213517627023014574 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/operators.R \name{op-get-attr} \alias{op-get-attr} \alias{\%@\%} \alias{\%@\%<-} \title{Infix attribute accessor and setter} \usage{ x \%@\% name x \%@\% name <- value } \arguments{ \item{x}{Object} \item{name}{Attribute name} \item{value}{New value for attribute \code{name}.} } \description{ This operator extracts or sets attributes for regular objects and S4 fields for S4 objects. } \examples{ # Unlike `@`, this operator extracts attributes for any kind of # objects: factor(1:3) \%@\% "levels" mtcars \%@\% class mtcars \%@\% class <- NULL mtcars # It also works on S4 objects: .Person <- setClass("Person", slots = c(name = "character", species = "character")) fievel <- .Person(name = "Fievel", species = "mouse") fievel \%@\% name } rlang/man/cnd_type.Rd0000644000176200001440000000100513553605761014233 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cnd.R \name{cnd_type} \alias{cnd_type} \title{What type is a condition?} \usage{ cnd_type(cnd) } \arguments{ \item{cnd}{A condition object.} } \value{ A string, either \code{"condition"}, \code{"message"}, \code{"warning"}, \code{"error"} or \code{"interrupt"}. } \description{ Use \code{cnd_type()} to check what type a condition is. } \examples{ cnd_type(catch_cnd(abort("Abort!"))) cnd_type(catch_cnd(interrupt())) } \keyword{internal} rlang/man/new_formula.Rd0000644000176200001440000000074413351410454014742 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/formula.R \name{new_formula} \alias{new_formula} \title{Create a formula} \usage{ new_formula(lhs, rhs, env = caller_env()) } \arguments{ \item{lhs, rhs}{A call, name, or atomic vector.} \item{env}{An environment.} } \value{ A formula object. } \description{ Create a formula } \examples{ new_formula(quote(a), quote(b)) new_formula(NULL, quote(b)) } \seealso{ \code{\link[=new_quosure]{new_quosure()}} } rlang/man/caller_env.Rd0000644000176200001440000000231113405732277014540 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env-special.R \name{caller_env} \alias{caller_env} \alias{current_env} \title{Get the current or caller environment} \usage{ caller_env(n = 1) current_env() } \arguments{ \item{n}{Number of frames to go back.} } \description{ \itemize{ \item The current environment is the execution environment of the current function (the one currently being evaluated). \item The caller environment is the execution environment of the function that called the current function. } } \examples{ # Let's create a function that returns its current environment and # its caller environment: fn <- function() list(current = current_env(), caller = caller_env()) # The current environment is an unique execution environment # created when `fn()` was called. The caller environment is the # global env because that's where we called `fn()`. fn() # Let's call `fn()` again but this time within a function: g <- function() fn() # Now the caller environment is also an unique execution environment. # This is the exec env created by R for our call to g(): g() } \seealso{ \code{\link[=caller_frame]{caller_frame()}} and \code{\link[=current_frame]{current_frame()}} } rlang/man/empty_env.Rd0000644000176200001440000000073213405732277014441 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env-special.R \name{empty_env} \alias{empty_env} \title{Get the empty environment} \usage{ empty_env() } \description{ The empty environment is the only one that does not have a parent. It is always used as the tail of an environment chain such as the search path (see \code{\link[=search_envs]{search_envs()}}). } \examples{ # Create environments with nothing in scope: child_env(empty_env()) } rlang/man/quosure.Rd0000644000176200001440000001023513561023554014127 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/quo.R \name{quosure} \alias{quosure} \alias{is_quosure} \alias{quo_is_missing} \alias{quo_is_symbol} \alias{quo_is_call} \alias{quo_is_symbolic} \alias{quo_is_null} \alias{quo_get_expr} \alias{quo_get_env} \alias{quo_set_expr} \alias{quo_set_env} \title{Quosure getters, setters and testers} \usage{ is_quosure(x) quo_is_missing(quo) quo_is_symbol(quo, name = NULL) quo_is_call(quo, name = NULL, n = NULL, ns = NULL) quo_is_symbolic(quo) quo_is_null(quo) quo_get_expr(quo) quo_get_env(quo) quo_set_expr(quo, expr) quo_set_env(quo, env) } \arguments{ \item{x}{An object to test.} \item{quo}{A quosure to test.} \item{name}{The name of the symbol or function call. If \code{NULL} the name is not tested.} \item{n}{An optional number of arguments that the call should match.} \item{ns}{The namespace of the call. If \code{NULL}, the namespace doesn't participate in the pattern-matching. If an empty string \code{""} and \code{x} is a namespaced call, \code{is_call()} returns \code{FALSE}. If any other string, \code{is_call()} checks that \code{x} is namespaced within \code{ns}. Can be a character vector of namespaces, in which case the call has to match at least one of them, otherwise \code{is_call()} returns \code{FALSE}.} \item{expr}{A new expression for the quosure.} \item{env}{A new environment for the quosure.} } \description{ A quosure is a type of \link[=nse-defuse]{quoted expression} that includes a reference to the context where it was created. A quosure is thus guaranteed to evaluate in its original environment and can refer to local objects. You can access the quosure components (its expression and its environment) with: \itemize{ \item \code{\link[=get_expr]{get_expr()}} and \code{\link[=get_env]{get_env()}}. These getters also support other kinds of objects such as formulas. \item \code{quo_get_expr()} and \code{quo_get_env()}. These getters only work with quosures and throw an error with other types of input. } Test if an object is a quosure with \code{is_quosure()}. If you know an object is a quosure, use the \code{quo_} prefixed predicates to check its contents, \code{quo_is_missing()}, \code{quo_is_symbol()}, etc. } \section{Quosured constants}{ A quosure usually does not carry environments for \link[=is_syntactic_literal]{constant objects} like strings or numbers. \code{\link[=quo]{quo()}} and \code{\link[=enquo]{enquo()}} only capture an environment for \link[=is_symbolic]{symbolic expressions}. For instance, all of these return the \link[=empty_env]{empty environment}:\preformatted{quo_get_env(quo("constant")) quo_get_env(quo(100)) quo_get_env(quo(NA)) } On the other hand, quosures capture the environment of symbolic expressions, i.e. expressions whose meaning depends on the environment in which they are evaluated and what objects are defined there:\preformatted{quo_get_env(quo(some_object)) quo_get_env(quo(some_function())) } } \section{Empty quosures}{ When missing arguments are captured as quosures, either through \code{\link[=enquo]{enquo()}} or \code{\link[=quos]{quos()}}, they are returned as an empty quosure. These quosures contain the \link[=missing_arg]{missing argument} and typically have the \link[=empty_env]{empty environment} as enclosure. } \section{Life cycle}{ \itemize{ \item \code{is_quosure()} is stable. \item \code{quo_get_expr()} and \code{quo_get_env()} are stable. } } \examples{ quo <- quo(my_quosure) quo # Access and set the components of a quosure: quo_get_expr(quo) quo_get_env(quo) quo <- quo_set_expr(quo, quote(baz)) quo <- quo_set_env(quo, empty_env()) quo # Test wether an object is a quosure: is_quosure(quo) # If it is a quosure, you can use the specialised type predicates # to check what is inside it: quo_is_symbol(quo) quo_is_call(quo) quo_is_null(quo) # quo_is_missing() checks for a special kind of quosure, the one # that contains the missing argument: quo() quo_is_missing(quo()) fn <- function(arg) enquo(arg) fn() quo_is_missing(fn()) } \seealso{ \code{\link[=quo]{quo()}} for creating quosures by quotation; \code{\link[=as_quosure]{as_quosure()}} and \code{\link[=new_quosure]{new_quosure()}} for constructing quosures manually. } rlang/man/is_weakref.Rd0000644000176200001440000000042013500531447014534 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/weakref.R \name{is_weakref} \alias{is_weakref} \title{Is object a weak reference?} \usage{ is_weakref(x) } \arguments{ \item{x}{An object to test.} } \description{ Is object a weak reference? } rlang/man/call_fn.Rd0000644000176200001440000000172313500223442014013 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/call.R \name{call_fn} \alias{call_fn} \title{Extract function from a call} \usage{ call_fn(call, env = caller_env()) } \arguments{ \item{call}{Can be a call or a quosure that wraps a call.} \item{env}{The environment where to find the definition of the function quoted in \code{call} in case \code{call} is not wrapped in a quosure.} } \description{ If a frame or formula, the function will be retrieved from the associated environment. Otherwise, it is looked up in the calling frame. } \section{Life cycle}{ In rlang 0.2.0, \code{lang_fn()} was deprecated and renamed to \code{call_fn()}. See lifecycle section in \code{\link[=call2]{call2()}} for more about this change. } \examples{ # Extract from a quoted call: call_fn(quote(matrix())) call_fn(quo(matrix())) # Extract the calling function test <- function() call_fn(call_frame()) test() } \seealso{ \code{\link[=call_name]{call_name()}} } rlang/man/rst_list.Rd0000644000176200001440000000232113563532074014270 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cnd-restarts.R \name{rst_list} \alias{rst_list} \alias{rst_exists} \alias{rst_jump} \alias{rst_maybe_jump} \title{Restarts utilities} \usage{ rst_list() rst_exists(.restart) rst_jump(.restart, ...) rst_maybe_jump(.restart, ...) } \arguments{ \item{.restart}{The name of a restart.} \item{...}{<\link[=dyn-dots]{dynamic}> Arguments passed on to the restart function.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} Restarts are named jumping points established by \code{\link[=with_restarts]{with_restarts()}}. \code{rst_list()} returns the names of all restarts currently established. \code{rst_exists()} checks if a given restart is established. \code{rst_jump()} stops execution of the current function and jumps to a restart point. If the restart does not exist, an error is thrown. \code{rst_maybe_jump()} first checks that a restart exists before jumping. } \section{Life cycle}{ All the restart functions are in the questioning stage. It is not clear yet whether we want to recommend restarts as a style of programming in R. } \seealso{ \code{\link[=with_restarts]{with_restarts()}} } \keyword{internal} rlang/man/invoke.Rd0000644000176200001440000000514013604124170013710 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/eval.R \name{invoke} \alias{invoke} \title{Invoke a function with a list of arguments} \usage{ invoke(.fn, .args = list(), ..., .env = caller_env(), .bury = c(".fn", "")) } \arguments{ \item{.fn}{A function to invoke. Can be a function object or the name of a function in scope of \code{.env}.} \item{.args, ...}{List of arguments (possibly named) to be passed to \code{.fn}.} \item{.env}{The environment in which to call \code{.fn}.} \item{.bury}{A character vector of length 2. The first string specifies which name should the function have in the call recorded in the evaluation stack. The second string specifies a prefix for the argument names. Set \code{.bury} to \code{NULL} if you prefer to inline the function and its arguments in the call.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("soft-deprecated")} Normally, you invoke a R function by typing arguments manually. A powerful alternative is to call a function with a list of arguments assembled programmatically. This is the purpose of \code{invoke()}. } \details{ Technically, \code{invoke()} is basically a version of \code{\link[base:do.call]{base::do.call()}} that creates cleaner call traces because it does not inline the function and the arguments in the call (see examples). To achieve this, \code{invoke()} creates a child environment of \code{.env} with \code{.fn} and all arguments bound to new symbols (see \code{\link[=env_bury]{env_bury()}}). It then uses the same strategy as \code{\link[=eval_bare]{eval_bare()}} to evaluate with minimal noise. } \section{Life cycle}{ \code{invoke()} is soft-deprecated in favour of \code{\link[=exec]{exec()}}. Now that we understand better the interaction between unquoting and dots capture, we can take a simpler approach in \code{exec()}. If you need finer control over the generated call, you should construct an environment and call yourself, manually burying large objects or complex expressions. } \examples{ # invoke() has the same purpose as do.call(): invoke(paste, letters) # But it creates much cleaner calls: invoke(call_inspect, mtcars) # and stacktraces: fn <- function(...) sys.calls() invoke(fn, list(mtcars)) # Compare to do.call(): do.call(call_inspect, mtcars) do.call(fn, list(mtcars)) # Specify the function name either by supplying a string # identifying the function (it should be visible in .env): invoke("call_inspect", letters) # Or by changing the .bury argument, with which you can also change # the argument prefix: invoke(call_inspect, mtcars, .bury = c("inspect!", "col")) } \keyword{internal} rlang/man/as_environment.Rd0000644000176200001440000000276013500404445015452 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env.R \name{as_environment} \alias{as_environment} \title{Coerce to an environment} \usage{ as_environment(x, parent = NULL) } \arguments{ \item{x}{An object to coerce.} \item{parent}{A parent environment, \code{\link[=empty_env]{empty_env()}} by default. This argument is only used when \code{x} is data actually coerced to an environment (as opposed to data representing an environment, like \code{NULL} representing the empty environment).} } \description{ \code{as_environment()} coerces named vectors (including lists) to an environment. The names must be unique. If supplied an unnamed string, it returns the corresponding package environment (see \code{\link[=pkg_env]{pkg_env()}}). } \details{ If \code{x} is an environment and \code{parent} is not \code{NULL}, the environment is duplicated before being set a new parent. The return value is therefore a different environment than \code{x}. } \section{Life cycle}{ \code{as_env()} was soft-deprecated and renamed to \code{as_environment()} in rlang 0.2.0. This is for consistency as type predicates should not be abbreviated. } \examples{ # Coerce a named vector to an environment: env <- as_environment(mtcars) # By default it gets the empty environment as parent: identical(env_parent(env), empty_env()) # With strings it is a handy shortcut for pkg_env(): as_environment("base") as_environment("rlang") # With NULL it returns the empty environment: as_environment(NULL) } rlang/man/is_true.Rd0000644000176200001440000000071013351410454014067 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/types.R \name{is_true} \alias{is_true} \alias{is_false} \title{Is object identical to TRUE or FALSE?} \usage{ is_true(x) is_false(x) } \arguments{ \item{x}{object to test} } \description{ These functions bypass R's automatic conversion rules and check that \code{x} is literally \code{TRUE} or \code{FALSE}. } \examples{ is_true(TRUE) is_true(1) is_false(FALSE) is_false(0) } rlang/man/expr_print.Rd0000644000176200001440000000370613604124170014615 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/expr.R \name{expr_print} \alias{expr_print} \alias{expr_deparse} \title{Print an expression} \usage{ expr_print(x, width = peek_option("width")) expr_deparse(x, width = peek_option("width")) } \arguments{ \item{x}{An object or expression to print.} \item{width}{The width of the deparsed or printed expression. Defaults to the global option \code{width}.} } \description{ \code{expr_print()}, powered by \code{expr_deparse()}, is an alternative printer for R expressions with a few improvements over the base R printer. \itemize{ \item It colourises \link[=nse-defuse]{quosures} according to their environment. Quosures from the global environment are printed normally while quosures from local environments are printed in unique colour (or in italic when all colours are taken). \item It wraps inlined objects in angular brackets. For instance, an integer vector unquoted in a function call (e.g. \code{expr(foo(!!(1:3)))}) is printed like this: \verb{foo()} while by default R prints the code to create that vector: \code{foo(1:3)} which is ambiguous. \item It respects the width boundary (from the global option \code{width}) in more cases. } } \examples{ # It supports any object. Non-symbolic objects are always printed # within angular brackets: expr_print(1:3) expr_print(function() NULL) # Contrast this to how the code to create these objects is printed: expr_print(quote(1:3)) expr_print(quote(function() NULL)) # The main cause of non-symbolic objects in expressions is # quasiquotation: expr_print(expr(foo(!!(1:3)))) # Quosures from the global environment are printed normally: expr_print(quo(foo)) expr_print(quo(foo(!!quo(bar)))) # Quosures from local environments are colourised according to # their environments (if you have crayon installed): local_quo <- local(quo(foo)) expr_print(local_quo) wrapper_quo <- local(quo(bar(!!local_quo, baz))) expr_print(wrapper_quo) } rlang/man/expr_interp.Rd0000644000176200001440000000334313561023554014765 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nse-force.R \name{expr_interp} \alias{expr_interp} \title{Process unquote operators in a captured expression} \usage{ expr_interp(x, env = NULL) } \arguments{ \item{x}{A function, raw expression, or formula to interpolate.} \item{env}{The environment in which unquoted expressions should be evaluated. By default, the formula or closure environment if a formula or a function, or the current environment otherwise.} } \description{ While all capturing functions in the tidy evaluation framework perform unquote on capture (most notably \code{\link[=quo]{quo()}}), \code{expr_interp()} manually processes unquoting operators in expressions that are already captured. \code{expr_interp()} should be called in all user-facing functions expecting a formula as argument to provide the same quasiquotation functionality as NSE functions. } \examples{ # All tidy NSE functions like quo() unquote on capture: quo(list(!!(1 + 2))) # expr_interp() is meant to provide the same functionality when you # have a formula or expression that might contain unquoting # operators: f <- ~list(!!(1 + 2)) expr_interp(f) # Note that only the outer formula is unquoted (which is a reason # to use expr_interp() as early as possible in all user-facing # functions): f <- ~list(~!!(1 + 2), !!(1 + 2)) expr_interp(f) # Another purpose for expr_interp() is to interpolate a closure's # body. This is useful to inline a function within another. The # important limitation is that all formal arguments of the inlined # function should be defined in the receiving function: other_fn <- function(x) toupper(x) fn <- expr_interp(function(x) { x <- paste0(x, "_suffix") !!! body(other_fn) }) fn fn("foo") } rlang/man/env_get.Rd0000644000176200001440000000235213405732277014062 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env-binding.R \name{env_get} \alias{env_get} \alias{env_get_list} \title{Get an object in an environment} \usage{ env_get(env = caller_env(), nm, default, inherit = FALSE) env_get_list(env = caller_env(), nms, default, inherit = FALSE) } \arguments{ \item{env}{An environment.} \item{nm, nms}{Names of bindings. \code{nm} must be a single string.} \item{default}{A default value in case there is no binding for \code{nm} in \code{env}.} \item{inherit}{Whether to look for bindings in the parent environments.} } \value{ An object if it exists. Otherwise, throws an error. } \description{ \code{env_get()} extracts an object from an enviroment \code{env}. By default, it does not look in the parent environments. \code{env_get_list()} extracts multiple objects from an environment into a named list. } \examples{ parent <- child_env(NULL, foo = "foo") env <- child_env(parent, bar = "bar") # This throws an error because `foo` is not directly defined in env: # env_get(env, "foo") # However `foo` can be fetched in the parent environment: env_get(env, "foo", inherit = TRUE) # You can also avoid an error by supplying a default value: env_get(env, "foo", default = "FOO") } rlang/man/last_error.Rd0000644000176200001440000000101513552300110014556 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cnd-abort.R \name{last_error} \alias{last_error} \alias{last_trace} \title{Last \code{abort()} error} \usage{ last_error() last_trace() } \description{ \itemize{ \item \code{last_error()} returns the last error thrown with \code{\link[=abort]{abort()}}. The error is printed with a backtrace in simplified form. \item \code{last_trace()} is a shortcut to return the backtrace stored in the last error. This backtrace is printed in full form. } } rlang/man/new_call.Rd0000644000176200001440000000074313351410763014212 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/node.R \name{new_call} \alias{new_call} \title{Create a new call from components} \usage{ new_call(car, cdr = NULL) } \arguments{ \item{car}{The head of the call. It should be a \link[=is_callable]{callable} object: a symbol, call, or literal function.} \item{cdr}{The tail of the call, i.e. a \link[=node]{node list} of arguments.} } \description{ Create a new call from components } \keyword{internal} rlang/man/splice.Rd0000644000176200001440000001045013604124167013702 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dots.R \name{splice} \alias{splice} \alias{is_spliced} \alias{is_spliced_bare} \alias{dots_splice} \title{Splice lists} \usage{ splice(x) is_spliced(x) is_spliced_bare(x) dots_splice( ..., .ignore_empty = c("trailing", "none", "all"), .preserve_empty = FALSE, .homonyms = c("keep", "first", "last", "error"), .check_assign = FALSE ) } \arguments{ \item{x}{A list to splice.} \item{...}{Arguments to collect in a list. These dots are \link[=dyn-dots]{dynamic}.} \item{.ignore_empty}{Whether to ignore empty arguments. Can be one of \code{"trailing"}, \code{"none"}, \code{"all"}. If \code{"trailing"}, only the last argument is ignored if it is empty.} \item{.preserve_empty}{Whether to preserve the empty arguments that were not ignored. If \code{TRUE}, empty arguments are stored with \code{\link[=missing_arg]{missing_arg()}} values. If \code{FALSE} (the default) an error is thrown when an empty argument is detected.} \item{.homonyms}{How to treat arguments with the same name. The default, \code{"keep"}, preserves these arguments. Set \code{.homonyms} to \code{"first"} to only keep the first occurrences, to \code{"last"} to keep the last occurrences, and to \code{"error"} to raise an informative error and indicate what arguments have duplicated names.} \item{.check_assign}{Whether to check for \verb{<-} calls passed in dots. When \code{TRUE} and a \verb{<-} call is detected, a warning is issued to advise users to use \code{=} if they meant to match a function parameter, or wrap the \verb{<-} call in braces otherwise. This ensures assignments are explicit.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} \itemize{ \item \code{splice} marks an object to be spliced. It is equivalent to using \verb{!!!} in a function taking \link[=dyn-dots]{dynamic dots}. \item \code{dots_splice()} is like \code{\link[=dots_list]{dots_list()}} but automatically splices list inputs. } } \section{Standard splicing versus quoting splicing}{ The \verb{!!!} operator works differently in \emph{standard} functions taking dots with \code{dots_list()} than in \emph{quoting} functions taking dots with \code{\link[=enexprs]{enexprs()}} or \code{\link[=enquos]{enquos()}}. \itemize{ \item In quoting functions \verb{!!!} disaggregates its argument (let's call it \code{x}) into as many objects as there are elements in \code{x}. E.g. \code{quo(foo(!!! c(1, 2)))} is completely equivalent to \code{quo(foo(1, 2))}. The creation of those separate objects has an overhead but is typically not important when manipulating calls because function calls typically take a small number of arguments. \item In standard functions, disaggregating the spliced collection would have a negative performance impact in cases where \code{dots_list()} is used to build up data structures from user inputs. To avoid this spliced inputs are marked with \code{\link[=splice]{splice()}} and the final list is built with (the equivalent of) \code{flatten_if(dots, is_spliced)}. } Most of the time you should not care about the difference. However if you use a standard function taking tidy dots within a quoting function, the \verb{!!!} operator will disaggregate its argument because the behaviour of the quasiquoting function has priority. You might then observe some performance cost in edge cases. Here is one example where this would happen:\preformatted{purrr::rerun(10, dplyr::bind_rows(!!! x)) } \code{purrr::rerun()} is a quoting function and \code{dplyr::bind_rows()} is a standard function. Because \code{bind_rows()} is called \emph{inside} \code{rerun()}, the list \code{x} will be disaggregated into a pairlist of arguments. To avoid this you can use \code{splice()} instead:\preformatted{purrr::rerun(10, dplyr::bind_rows(splice(x))) } } \section{Life cycle}{ \itemize{ \item \code{dots_splice()} is in the questioning stage. It is part of our experiments with dots semantics. Compared to \code{dots_list()}, \code{dots_splice()} automatically splices lists. We now lean towards adopting a single type of dots semantics (those of \code{dots_list()}) where splicing is explicit. \item \code{splice()} is in the questioning stage. It is not clear whether it is really needed as there are other ways to avoid the performance issue discussed above. } } \keyword{internal} rlang/man/new_weakref.Rd0000644000176200001440000000505413500531447014722 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/weakref.R \name{new_weakref} \alias{new_weakref} \title{Create a weak reference} \usage{ new_weakref(key, value = NULL, finalizer = NULL, on_quit = FALSE) } \arguments{ \item{key}{The key for the weak reference. Must be a reference object -- that is, an environment or external pointer.} \item{value}{The value for the weak reference. This can be \code{NULL}, if you want to use the weak reference like a weak pointer.} \item{finalizer}{A function that is run after the key becomes unreachable.} \item{on_quit}{Should the finalizer be run when R exits?} } \description{ A weak reference is a special R object which makes it possible to keep a reference to an object without preventing garbage collection of that object. It can also be used to keep data about an object without preventing GC of the object, similar to WeakMaps in JavaScript. Objects in R are considered \emph{reachable} if they can be accessed by following a chain of references, starting from a \emph{root node}; root nodes are specially-designated R objects, and include the global environment and base environment. As long as the key is reachable, the value will not be garbage collected. This is true even if the weak reference object becomes unreachable. The key effectively prevents the weak reference and its value from being collected, according to the following chain of ownership: \code{weakref <- key -> value}. When the key becomes unreachable, the key and value in the weak reference object are replaced by \code{NULL}, and the finalizer is scheduled to execute. } \examples{ e <- env() # Create a weak reference to e w <- new_weakref(e, finalizer = function(e) message("finalized")) # Get the key object from the weak reference identical(wref_key(w), e) # When the regular reference (the `e` binding) is removed and a GC occurs, # the weak reference will not keep the object alive. rm(e) gc() identical(wref_key(w), NULL) # A weak reference with a key and value. The value contains data about the # key. k <- env() v <- list(1, 2, 3) w <- new_weakref(k, v) identical(wref_key(w), k) identical(wref_value(w), v) # When v is removed, the weak ref keeps it alive because k is still reachable. rm(v) gc() identical(wref_value(w), list(1, 2, 3)) # When k is removed, the weak ref does not keep k or v alive. rm(k) gc() identical(wref_key(w), NULL) identical(wref_value(w), NULL) } \seealso{ \code{\link[=is_weakref]{is_weakref()}}, \code{\link[=wref_key]{wref_key()}} and \code{\link[=wref_value]{wref_value()}}. } \keyword{experimental} rlang/man/catch_cnd.Rd0000644000176200001440000000147713607306553014346 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cnd-handlers.R \name{catch_cnd} \alias{catch_cnd} \title{Catch a condition} \usage{ catch_cnd(expr, classes = "condition") } \arguments{ \item{expr}{Expression to be evaluated with a catching condition handler.} \item{classes}{A character vector of condition classes to catch. By default, catches all conditions.} } \value{ A condition if any was signalled, \code{NULL} otherwise. } \description{ This is a small wrapper around \code{tryCatch()} that captures any condition signalled while evaluating its argument. It is useful for situations where you expect a specific condition to be signalled, for debugging, and for unit testing. } \examples{ catch_cnd(10) catch_cnd(abort("an error")) catch_cnd(signal("my_condition", message = "a condition")) } rlang/man/vector-coercion.Rd0000644000176200001440000001017213500437433015523 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{vector-coercion} \alias{vector-coercion} \alias{as_logical} \alias{as_integer} \alias{as_double} \alias{as_complex} \alias{as_character} \alias{as_list} \title{Coerce an object to a base type} \usage{ as_logical(x) as_integer(x) as_double(x) as_complex(x) as_character(x, encoding = NULL) as_list(x) } \arguments{ \item{x}{An object to coerce to a base type.} \item{encoding}{If non-null, set an encoding mark. This is only declarative, no encoding conversion is performed.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("soft-deprecated")} These are equivalent to the base functions (e.g. \code{\link[=as.logical]{as.logical()}}, \code{\link[=as.list]{as.list()}}, etc), but perform coercion rather than conversion. This means they are not generic and will not call S3 conversion methods. They only attempt to coerce the base type of their input. In addition, they have stricter implicit coercion rules and will never attempt any kind of parsing. E.g. they will not try to figure out if a character vector represents integers or booleans. Finally, they treat attributes consistently, unlike the base R functions: all attributes except names are removed. } \section{Lifecycle}{ These functions are deprecated in favour of \code{vctrs::vec_cast()}. } \section{Coercion to logical and numeric atomic vectors}{ \itemize{ \item To logical vectors: Integer and integerish double vectors. See \code{\link[=is_integerish]{is_integerish()}}. \item To integer vectors: Logical and integerish double vectors. \item To double vectors: Logical and integer vectors. \item To complex vectors: Logical, integer and double vectors. } } \section{Coercion to character vectors}{ \code{as_character()} and \code{as_string()} have an optional \code{encoding} argument to specify the encoding. R uses this information for internal handling of strings and character vectors. Note that this is only declarative, no encoding conversion is attempted. Note that only \code{as_string()} can coerce symbols to a scalar character vector. This makes the code more explicit and adds an extra type check. } \section{Coercion to lists}{ \code{as_list()} only coerces vector and dictionary types (environments are an example of dictionary type). Unlike \code{\link[base:as.list]{base::as.list()}}, \code{as_list()} removes all attributes except names. } \section{Effects of removing attributes}{ A technical side-effect of removing the attributes of the input is that the underlying objects has to be copied. This has no performance implications in the case of lists because this is a shallow copy: only the list structure is copied, not the contents (see \code{\link[=duplicate]{duplicate()}}). However, be aware that atomic vectors containing large amounts of data will have to be copied. In general, any attribute modification creates a copy, which is why it is better to avoid using attributes with heavy atomic vectors. Uncopyable objects like environments and symbols are an exception to this rule: in this case, attributes modification happens in place and has side-effects. } \examples{ # Coercing atomic vectors removes attributes with both base R and rlang: x <- structure(TRUE, class = "foo", bar = "baz") as.logical(x) # But coercing lists preserves attributes in base R but not rlang: l <- structure(list(TRUE), class = "foo", bar = "baz") as.list(l) as_list(l) # Implicit conversions are performed in base R but not rlang: as.logical(l) \dontrun{ as_logical(l) } # Conversion methods are bypassed, making the result of the # coercion more predictable: as.list.foo <- function(x) "wrong" as.list(l) as_list(l) # The input is never parsed. E.g. character vectors of numbers are # not converted to numeric types: as.integer("33") \dontrun{ as_integer("33") } # With base R tools there is no way to convert an environment to a # list without either triggering method dispatch, or changing the # original environment. as_list() makes it easy: x <- structure(as_environment(mtcars[1:2]), class = "foobar") as.list.foobar <- function(x) abort("dont call me") as_list(x) } \keyword{internal} rlang/man/env_print.Rd0000644000176200001440000000144713604124170014427 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env.R \name{env_print} \alias{env_print} \title{Pretty-print an environment} \usage{ env_print(env = caller_env()) } \arguments{ \item{env}{An environment, or object that can be converted to an environment by \code{\link[=get_env]{get_env()}}.} } \description{ This prints: \itemize{ \item The \link[=env_label]{label} and the parent label. \item Whether the environment is \link[=env_lock]{locked}. \item The bindings in the environment (up to 20 bindings). They are printed succintly using \code{pillar::type_sum()} (if available, otherwise uses an internal version of that generic). In addition \link[=env_bind_lazy]{fancy bindings} (actives and promises) are indicated as such. \item Locked bindings get a \verb{[L]} tag } } rlang/man/dots_n.Rd0000644000176200001440000000065313553606643013724 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dots.R \name{dots_n} \alias{dots_n} \title{How many arguments are currently forwarded in dots?} \usage{ dots_n(...) } \arguments{ \item{...}{Forwarded arguments.} } \description{ This returns the number of arguments currently forwarded in \code{...} as an integer. } \examples{ fn <- function(...) dots_n(..., baz) fn(foo, bar) } \keyword{internal} rlang/man/as_string.Rd0000644000176200001440000000356413413472702014423 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/sym.R \name{as_string} \alias{as_string} \title{Cast symbol to string} \usage{ as_string(x) } \arguments{ \item{x}{A string or symbol. If a string, the attributes are removed, if any.} } \value{ A character vector of length 1. } \description{ \code{as_string()} converts \link[=sym]{symbols} to character strings. } \section{Unicode tags}{ Unlike \code{\link[base:as.symbol]{base::as.symbol()}} and \code{\link[base:as.name]{base::as.name()}}, \code{as_string()} automatically transforms unicode tags such as \code{""} to the proper UTF-8 character. This is important on Windows because: \itemize{ \item R on Windows has no UTF-8 support, and uses native encoding instead. \item The native encodings do not cover all Unicode characters. For example, Western encodings do not support CKJ characters. \item When a lossy UTF-8 -> native transformation occurs, uncovered characters are transformed to an ASCII unicode tag like \code{""}. \item Symbols are always encoded in native. This means that transforming the column names of a data frame to symbols might be a lossy operation. \item This operation is very common in the tidyverse because of data masking APIs like dplyr where data frames are transformed to environments. While the names of a data frame are stored as a character vector, the bindings of environments are stored as symbols. } Because it reencodes the ASCII unicode tags to their UTF-8 representation, the string -> symbol -> string roundtrip is more stable with \code{as_string()}. } \examples{ # Let's create some symbols: foo <- quote(foo) bar <- sym("bar") # as_string() converts symbols to strings: foo as_string(foo) typeof(bar) typeof(as_string(bar)) } \seealso{ \code{\link[=as_name]{as_name()}} for a higher-level variant of \code{as_string()} that automatically unwraps quosures. } rlang/man/is_namespace.Rd0000644000176200001440000000045613405732277015065 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env-special.R \name{is_namespace} \alias{is_namespace} \title{Is an object a namespace environment?} \usage{ is_namespace(x) } \arguments{ \item{x}{An object to test.} } \description{ Is an object a namespace environment? } rlang/man/dots_values.Rd0000644000176200001440000000411413604124167014753 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dots.R \name{dots_values} \alias{dots_values} \title{Evaluate dots with preliminary splicing} \usage{ dots_values( ..., .ignore_empty = c("trailing", "none", "all"), .preserve_empty = FALSE, .homonyms = c("keep", "first", "last", "error"), .check_assign = FALSE ) } \arguments{ \item{...}{Arguments to evaluate and process splicing operators.} \item{.ignore_empty}{Whether to ignore empty arguments. Can be one of \code{"trailing"}, \code{"none"}, \code{"all"}. If \code{"trailing"}, only the last argument is ignored if it is empty.} \item{.preserve_empty}{Whether to preserve the empty arguments that were not ignored. If \code{TRUE}, empty arguments are stored with \code{\link[=missing_arg]{missing_arg()}} values. If \code{FALSE} (the default) an error is thrown when an empty argument is detected.} \item{.homonyms}{How to treat arguments with the same name. The default, \code{"keep"}, preserves these arguments. Set \code{.homonyms} to \code{"first"} to only keep the first occurrences, to \code{"last"} to keep the last occurrences, and to \code{"error"} to raise an informative error and indicate what arguments have duplicated names.} \item{.check_assign}{Whether to check for \verb{<-} calls passed in dots. When \code{TRUE} and a \verb{<-} call is detected, a warning is issued to advise users to use \code{=} if they meant to match a function parameter, or wrap the \verb{<-} call in braces otherwise. This ensures assignments are explicit.} } \description{ This is a tool for advanced users. It captures dots, processes unquoting and splicing operators, and evaluates them. Unlike \code{\link[=dots_list]{dots_list()}}, it does not flatten spliced objects, instead they are attributed a \code{spliced} class (see \code{\link[=splice]{splice()}}). You can process spliced objects manually, perhaps with a custom predicate (see \code{\link[=flatten_if]{flatten_if()}}). } \examples{ dots <- dots_values(!!! list(1, 2), 3) dots # Flatten the objects marked as spliced: flatten_if(dots, is_spliced) } \keyword{internal} rlang/man/op-definition.Rd0000644000176200001440000000337113604124170015165 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/operators.R \name{op-definition} \alias{op-definition} \alias{is_definition} \alias{new_definition} \alias{is_formulaish} \title{Definition operator} \usage{ is_definition(x) new_definition(lhs, rhs, env = caller_env()) is_formulaish(x, scoped = NULL, lhs = NULL) } \arguments{ \item{x}{An object to test.} \item{lhs, rhs}{Expressions for the LHS and RHS of the definition.} \item{env}{The evaluation environment bundled with the definition.} } \description{ The definition operator is typically used in DSL packages like \code{ggvis} and \code{data.table}. It is also used in the tidyverse as a way of unquoting names (see \link{nse-force}). \itemize{ \item \code{is_definition()} returns \code{TRUE} for calls to \verb{:=}. \item \code{is_formulaish()} returns \code{TRUE} for both formulas and colon-equals operators. } } \details{ The recommended way to use it is to capture arguments as expressions or quosures. You can then give a special function definition for the \verb{:=} symbol in an overscope. Note that if you capture dots with \code{\link[=exprs]{exprs()}} or \code{\link[=quos]{quos()}}, you need to disable interpretation of \verb{:=} by setting \code{.unquote_names} to \code{FALSE}. From rlang and data.table perspectives, this operator is not meant to be evaluated directly at top-level which is why the exported definitions issue an error. } \section{Life cycle}{ These functions are experimental. } \examples{ # A predicate is provided to distinguish formulas from the # colon-equals operator: is_definition(quote(a := b)) is_definition(a ~ b) # is_formulaish() tests for both definitions and formulas: is_formulaish(a ~ b) is_formulaish(quote(a := b)) } \keyword{internal} rlang/man/env_names.Rd0000644000176200001440000000325413604124167014402 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env-binding.R \name{env_names} \alias{env_names} \alias{env_length} \title{Names and numbers of symbols bound in an environment} \usage{ env_names(env) env_length(env) } \arguments{ \item{env}{An environment.} } \value{ A character vector of object names. } \description{ \code{env_names()} returns object names from an enviroment \code{env} as a character vector. All names are returned, even those starting with a dot. \code{env_length()} returns the number of bindings. } \section{Names of symbols and objects}{ Technically, objects are bound to symbols rather than strings, since the R interpreter evaluates symbols (see \code{\link[=is_expression]{is_expression()}} for a discussion of symbolic objects versus literal objects). However it is often more convenient to work with strings. In rlang terminology, the string corresponding to a symbol is called the \emph{name} of the symbol (or by extension the name of an object bound to a symbol). } \section{Encoding}{ There are deep encoding issues when you convert a string to symbol and vice versa. Symbols are \emph{always} in the native encoding. If that encoding (let's say latin1) cannot support some characters, these characters are serialised to ASCII. That's why you sometimes see strings looking like \verb{}, especially if you're running Windows (as R doesn't support UTF-8 as native encoding on that platform). To alleviate some of the encoding pain, \code{env_names()} always returns a UTF-8 character vector (which is fine even on Windows) with ASCII unicode points translated back to UTF-8. } \examples{ env <- env(a = 1, b = 2) env_names(env) } rlang/man/missing.Rd0000644000176200001440000000375613553606252014112 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/vec-na.R \docType{data} \name{missing} \alias{missing} \alias{na_lgl} \alias{na_int} \alias{na_dbl} \alias{na_chr} \alias{na_cpl} \title{Missing values} \format{An object of class \code{logical} of length 1.} \usage{ na_lgl na_int na_dbl na_chr na_cpl } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} Missing values are represented in R with the general symbol \code{NA}. They can be inserted in almost all data containers: all atomic vectors except raw vectors can contain missing values. To achieve this, R automatically converts the general \code{NA} symbol to a typed missing value appropriate for the target vector. The objects provided here are aliases for those typed \code{NA} objects. } \details{ Typed missing values are necessary because R needs sentinel values of the same type (i.e. the same machine representation of the data) as the containers into which they are inserted. The official typed missing values are \code{NA_integer_}, \code{NA_real_}, \code{NA_character_} and \code{NA_complex_}. The missing value for logical vectors is simply the default \code{NA}. The aliases provided in rlang are consistently named and thus simpler to remember. Also, \code{na_lgl} is provided as an alias to \code{NA} that makes intent clearer. Since \code{na_lgl} is the default \code{NA}, expressions such as \code{c(NA, NA)} yield logical vectors as no data is available to give a clue of the target type. In the same way, since lists and environments can contain any types, expressions like \code{list(NA)} store a logical \code{NA}. } \section{Life cycle}{ These shortcuts might be moved to the vctrs package at some point. This is why they are marked as questioning. } \examples{ typeof(NA) typeof(na_lgl) typeof(na_int) # Note that while the base R missing symbols cannot be overwritten, # that's not the case for rlang's aliases: na_dbl <- NA typeof(na_dbl) } \keyword{datasets} \keyword{internal} rlang/man/list2.Rd0000644000176200001440000000751213604132570013462 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dots.R \name{list2} \alias{list2} \alias{ll} \alias{dots_list} \title{Collect dots in a list} \usage{ list2(...) dots_list( ..., .ignore_empty = c("trailing", "none", "all"), .preserve_empty = FALSE, .homonyms = c("keep", "first", "last", "error"), .check_assign = FALSE ) } \arguments{ \item{...}{Arguments to collect in a list. These dots are \link[=dyn-dots]{dynamic}.} \item{.ignore_empty}{Whether to ignore empty arguments. Can be one of \code{"trailing"}, \code{"none"}, \code{"all"}. If \code{"trailing"}, only the last argument is ignored if it is empty.} \item{.preserve_empty}{Whether to preserve the empty arguments that were not ignored. If \code{TRUE}, empty arguments are stored with \code{\link[=missing_arg]{missing_arg()}} values. If \code{FALSE} (the default) an error is thrown when an empty argument is detected.} \item{.homonyms}{How to treat arguments with the same name. The default, \code{"keep"}, preserves these arguments. Set \code{.homonyms} to \code{"first"} to only keep the first occurrences, to \code{"last"} to keep the last occurrences, and to \code{"error"} to raise an informative error and indicate what arguments have duplicated names.} \item{.check_assign}{Whether to check for \verb{<-} calls passed in dots. When \code{TRUE} and a \verb{<-} call is detected, a warning is issued to advise users to use \code{=} if they meant to match a function parameter, or wrap the \verb{<-} call in braces otherwise. This ensures assignments are explicit.} } \value{ A list containing the \code{...} inputs. } \description{ \code{list2(...)} is equivalent to \code{list(...)} with a few additional features, collectively called \link[=dyn-dots]{dynamic dots}. While \code{list2()} hard-code these features, \code{dots_list()} is a lower-level version that offers more control. } \examples{ # Let's create a function that takes a variable number of arguments: numeric <- function(...) { dots <- list2(...) num <- as.numeric(dots) set_names(num, names(dots)) } numeric(1, 2, 3) # The main difference with list(...) is that list2(...) enables # the `!!!` syntax to splice lists: x <- list(2, 3) numeric(1, !!! x, 4) # As well as unquoting of names: nm <- "yup!" numeric(!!nm := 1) # One useful application of splicing is to work around exact and # partial matching of arguments. Let's create a function taking # named arguments and dots: fn <- function(data, ...) { list2(...) } # You normally cannot pass an argument named `data` through the dots # as it will match `fn`'s `data` argument. The splicing syntax # provides a workaround: fn("wrong!", data = letters) # exact matching of `data` fn("wrong!", dat = letters) # partial matching of `data` fn(some_data, !!!list(data = letters)) # no matching # Empty arguments trigger an error by default: try(fn(, )) # You can choose to preserve empty arguments instead: list3 <- function(...) dots_list(..., .preserve_empty = TRUE) # Note how the last empty argument is still ignored because # `.ignore_empty` defaults to "trailing": list3(, ) # The list with preserved empty arguments is equivalent to: list(missing_arg()) # Arguments with duplicated names are kept by default: list2(a = 1, a = 2, b = 3, b = 4, 5, 6) # Use the `.homonyms` argument to keep only the first of these: dots_list(a = 1, a = 2, b = 3, b = 4, 5, 6, .homonyms = "first") # Or the last: dots_list(a = 1, a = 2, b = 3, b = 4, 5, 6, .homonyms = "last") # Or raise an informative error: try(dots_list(a = 1, a = 2, b = 3, b = 4, 5, 6, .homonyms = "error")) # dots_list() can be configured to warn when a `<-` call is # detected: my_list <- function(...) dots_list(..., .check_assign = TRUE) my_list(a <- 1) # There is no warning if the assignment is wrapped in braces. # This requires users to be explicit about their intent: my_list({ a <- 1 }) } rlang/man/pairlist2.Rd0000644000176200001440000000144513563532074014344 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/call.R \name{pairlist2} \alias{pairlist2} \title{Create pairlists with splicing support} \usage{ pairlist2(...) } \arguments{ \item{...}{<\link[=dyn-dots]{dynamic}> Arguments stored in the pairlist. Empty arguments are preserved.} } \description{ This pairlist constructor uses \link[=dyn-dots]{dynamic dots}. Use it to manually create argument lists for calls or parameter lists for functions. } \examples{ # Unlike `exprs()`, `pairlist2()` evaluates its arguments. new_function(pairlist2(x = 1, y = 3 * 6), quote(x * y)) new_function(exprs(x = 1, y = 3 * 6), quote(x * y)) # It preserves missing arguments, which is useful for creating # parameters without defaults: new_function(pairlist2(x = , y = 3 * 6), quote(x * y)) } rlang/man/vector-construction.Rd0000644000176200001440000000374313604124170016456 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/vec-new.R \name{vector-construction} \alias{vector-construction} \alias{lgl} \alias{int} \alias{dbl} \alias{cpl} \alias{chr} \alias{bytes} \title{Create vectors} \usage{ lgl(...) int(...) dbl(...) cpl(...) chr(...) bytes(...) } \arguments{ \item{...}{Components of the new vector. Bare lists and explicitly spliced lists are spliced.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} The atomic vector constructors are equivalent to \code{\link[=c]{c()}} but: \itemize{ \item They allow you to be more explicit about the output type. Implicit coercions (e.g. from integer to logical) follow the rules described in \link{vector-coercion}. \item They use \link[=dyn-dots]{dynamic dots}. } } \section{Life cycle}{ \itemize{ \item All the abbreviated constructors such as \code{lgl()} will probably be moved to the vctrs package at some point. This is why they are marked as questioning. \item Automatic splicing is soft-deprecated and will trigger a warning in a future version. Please splice explicitly with \verb{!!!}. } } \examples{ # These constructors are like a typed version of c(): c(TRUE, FALSE) lgl(TRUE, FALSE) # They follow a restricted set of coercion rules: int(TRUE, FALSE, 20) # Lists can be spliced: dbl(10, !!! list(1, 2L), TRUE) # They splice names a bit differently than c(). The latter # automatically composes inner and outer names: c(a = c(A = 10), b = c(B = 20, C = 30)) # On the other hand, rlang's ctors use the inner names and issue a # warning to inform the user that the outer names are ignored: dbl(a = c(A = 10), b = c(B = 20, C = 30)) dbl(a = c(1, 2)) # As an exception, it is allowed to provide an outer name when the # inner vector is an unnamed scalar atomic: dbl(a = 1) # Spliced lists behave the same way: dbl(!!! list(a = 1)) dbl(!!! list(a = c(A = 1))) # bytes() accepts integerish inputs bytes(1:10) bytes(0x01, 0xff, c(0x03, 0x05), list(10, 20, 30L)) } rlang/man/quo_label.Rd0000644000176200001440000000526013413472574014377 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/quo.R \name{quo_label} \alias{quo_label} \alias{quo_text} \alias{quo_name} \title{Format quosures for printing or labelling} \usage{ quo_label(quo) quo_text(quo, width = 60L, nlines = Inf) quo_name(quo) } \arguments{ \item{quo}{A quosure or expression.} \item{width}{Width of each line.} \item{nlines}{Maximum number of lines to extract.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} \strong{Note:} You should now use \code{\link[=as_label]{as_label()}} or \code{\link[=as_name]{as_name()}} instead of \code{quo_name()}. See life cycle section below. These functions take an arbitrary R object, typically an \link[=is_expression]{expression}, and represent it as a string. \itemize{ \item \code{quo_name()} returns an abbreviated representation of the object as a single line string. It is suitable for default names. \item \code{quo_text()} returns a multiline string. For instance block expressions like \code{{ foo; bar }} are represented on 4 lines (one for each symbol, and the curly braces on their own lines). } These deparsers are only suitable for creating default names or printing output at the console. The behaviour of your functions should not depend on deparsed objects. If you are looking for a way of transforming symbols to strings, use \code{\link[=as_string]{as_string()}} instead of \code{quo_name()}. Unlike deparsing, the transformation between symbols and strings is non-lossy and well defined. } \section{Life cycle}{ These functions are in the questioning life cycle stage. \itemize{ \item \code{\link[=as_label]{as_label()}} and \code{\link[=as_name]{as_name()}} should be used instead of \code{quo_name()}. \code{as_label()} transforms any R object to a string but should only be used to create a default name. Labelisation is not a well defined operation and no assumption should be made about the label. On the other hand, \code{as_name()} only works with (possibly quosured) symbols, but is a well defined and deterministic operation. \item We don't have a good replacement for \code{quo_text()} yet. See \url{https://github.com/r-lib/rlang/issues/636} to follow discussions about a new deparsing API. } } \examples{ # Quosures can contain nested quosures: quo <- quo(foo(!! quo(bar))) quo # quo_squash() unwraps all quosures and returns a raw expression: quo_squash(quo) # This is used by quo_text() and quo_label(): quo_text(quo) # Compare to the unwrapped expression: expr_text(quo) # quo_name() is helpful when you need really short labels: quo_name(quo(sym)) quo_name(quo(!! sym)) } \seealso{ \code{\link[=expr_label]{expr_label()}}, \code{\link[=f_label]{f_label()}} } rlang/man/has_length.Rd0000644000176200001440000000136113553605761014547 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/attr.R \name{has_length} \alias{has_length} \title{How long is an object?} \usage{ has_length(x, n = NULL) } \arguments{ \item{x}{A R object.} \item{n}{A specific length to test \code{x} with. If \code{NULL}, \code{has_length()} returns \code{TRUE} if \code{x} has length greater than zero, and \code{FALSE} otherwise.} } \description{ This is a function for the common task of testing the length of an object. It checks the length of an object in a non-generic way: \code{\link[base:length]{base::length()}} methods are ignored. } \examples{ has_length(list()) has_length(list(), 0) has_length(letters) has_length(letters, 20) has_length(letters, 26) } \keyword{internal} rlang/man/tidyeval-data.Rd0000644000176200001440000000253213610366361015156 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/eval-tidy.R \docType{data} \name{tidyeval-data} \alias{tidyeval-data} \alias{.data} \alias{.env} \title{Data pronouns for tidy evaluation} \format{An object of class \code{rlang_fake_data_pronoun} of length .} \usage{ .data .env } \description{ These pronouns allow you to be explicit about where to find objects when programming with data masked functions.\preformatted{m <- 10 mtcars \%>\% mutate(disp = .data$disp * .env$m) } \itemize{ \item \code{.data} retrieves data-variables from the data frame. \item \code{.env} retrieves env-variables from the environment. } Because the lookup is explicit, there is no ambiguity between both kinds of variables. Compare:\preformatted{disp <- 10 mtcars \%>\% mutate(disp = .data$disp * .env$disp) mtcars \%>\% mutate(disp = disp * disp) } The \code{.data} object exported from rlang is also useful to import in your package namespace to avoid a \verb{R CMD check} note when referring to objects from the data mask. Note that \code{.data} is only a pronoun, it is not a real data frame. This means that you can't take its names or map a function over the contents of \code{.data}. Similarly, \code{.env} is not an actual R environment. For instance, it doesn't have a parent and the subsetting operators behave differently. } \keyword{datasets} rlang/man/wref_key.Rd0000644000176200001440000000066313500531447014241 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/weakref.R \name{wref_key} \alias{wref_key} \alias{wref_value} \title{Get key/value from a weak reference object} \usage{ wref_key(x) wref_value(x) } \arguments{ \item{x}{A weak reference object.} } \description{ Get key/value from a weak reference object } \seealso{ \code{\link[=is_weakref]{is_weakref()}} and \code{\link[=new_weakref]{new_weakref()}}. } rlang/man/bare-type-predicates.Rd0000644000176200001440000000304313500416332016425 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/types.R \name{bare-type-predicates} \alias{bare-type-predicates} \alias{is_bare_list} \alias{is_bare_atomic} \alias{is_bare_vector} \alias{is_bare_double} \alias{is_bare_integer} \alias{is_bare_numeric} \alias{is_bare_character} \alias{is_bare_logical} \alias{is_bare_raw} \alias{is_bare_string} \alias{is_bare_bytes} \title{Bare type predicates} \usage{ is_bare_list(x, n = NULL) is_bare_atomic(x, n = NULL) is_bare_vector(x, n = NULL) is_bare_double(x, n = NULL) is_bare_integer(x, n = NULL) is_bare_numeric(x, n = NULL) is_bare_character(x, n = NULL, encoding = NULL) is_bare_logical(x, n = NULL) is_bare_raw(x, n = NULL) is_bare_string(x, n = NULL) is_bare_bytes(x, n = NULL) } \arguments{ \item{x}{Object to be tested.} \item{n}{Expected length of a vector.} \item{encoding}{Defunct as of rlang 0.4.0.} } \description{ These predicates check for a given type but only return \code{TRUE} for bare R objects. Bare objects have no class attributes. For example, a data frame is a list, but not a bare list. } \details{ \itemize{ \item The predicates for vectors include the \code{n} argument for pattern-matching on the vector length. \item Like \code{\link[=is_atomic]{is_atomic()}} and unlike base R \code{is.atomic()}, \code{is_bare_atomic()} does not return \code{TRUE} for \code{NULL}. \item Unlike base R \code{is.numeric()}, \code{is_bare_double()} only returns \code{TRUE} for floating point numbers. } } \seealso{ \link{type-predicates}, \link{scalar-type-predicates} } rlang/man/as_box.Rd0000644000176200001440000000147713407134203013700 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/s3.R \name{as_box} \alias{as_box} \alias{as_box_if} \title{Convert object to a box} \usage{ as_box(x, class = NULL) as_box_if(.x, .p, .class = NULL, ...) } \arguments{ \item{x}{An R object.} \item{class, .class}{A box class. If the input is already a box of that class, it is returned as is. If the input needs to be boxed, \code{class} is passed to \code{\link[=new_box]{new_box()}}.} \item{.x}{An R object.} \item{.p}{A predicate function.} \item{...}{Arguments passed to \code{.p}.} } \description{ \itemize{ \item \code{as_box()} boxes its input only if it is not already a box. The class is also checked if supplied. \item \code{as_box_if()} boxes its input only if it not already a box, or if the predicate \code{.p} returns \code{TRUE}. } } rlang/man/inherits_any.Rd0000644000176200001440000000304513351410654015117 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/s3.R \name{inherits_any} \alias{inherits_any} \alias{inherits_all} \alias{inherits_only} \title{Does an object inherit from a set of classes?} \usage{ inherits_any(x, class) inherits_all(x, class) inherits_only(x, class) } \arguments{ \item{x}{An object to test for inheritance.} \item{class}{A character vector of classes.} } \description{ \itemize{ \item \code{inherits_any()} is like \code{\link[base:inherits]{base::inherits()}} but is more explicit about its behaviour with multiple classes. If \code{classes} contains several elements and the object inherits from at least one of them, \code{inherits_any()} returns \code{TRUE}. \item \code{inherits_all()} tests that an object inherits from all of the classes in the supplied order. This is usually the best way to test for inheritance of multiple classes. \item \code{inherits_only()} tests that the class vectors are identical. It is a shortcut for \code{identical(class(x), class)}. } } \examples{ obj <- structure(list(), class = c("foo", "bar", "baz")) # With the _any variant only one class must match: inherits_any(obj, c("foobar", "bazbaz")) inherits_any(obj, c("foo", "bazbaz")) # With the _all variant all classes must match: inherits_all(obj, c("foo", "bazbaz")) inherits_all(obj, c("foo", "baz")) # The order of classes must match as well: inherits_all(obj, c("baz", "foo")) # inherits_only() checks that the class vectors are identical: inherits_only(obj, c("foo", "baz")) inherits_only(obj, c("foo", "bar", "baz")) } rlang/man/env_lock.Rd0000644000176200001440000000260613553605761014236 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env.R \name{env_lock} \alias{env_lock} \alias{env_is_locked} \title{Lock an environment} \usage{ env_lock(env) env_is_locked(env) } \arguments{ \item{env}{An environment.} } \value{ The old value of \code{env_is_locked()} invisibly. } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} Locked environments cannot be modified. An important example is namespace environments which are locked by R when loaded in a session. Once an environment is locked it normally cannot be unlocked. Note that only the environment as a container is locked, not the individual bindings. You can't remove or add a binding but you can still modify the values of existing bindings. See \code{\link[=env_binding_lock]{env_binding_lock()}} for locking individual bindings. } \examples{ # New environments are unlocked by default: env <- env(a = 1) env_is_locked(env) # Use env_lock() to lock them: env_lock(env) env_is_locked(env) # Now that `env` is locked, it is no longer possible to remove or # add bindings. If run, the following would fail: # env_unbind(env, "a") # env_bind(env, b = 2) # Note that even though the environment as a container is locked, # the individual bindings are still unlocked and can be modified: env$a <- 10 } \seealso{ \code{\link[=env_binding_lock]{env_binding_lock()}} } \keyword{internal} rlang/man/env_clone.Rd0000644000176200001440000000101113405732277014372 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env.R \name{env_clone} \alias{env_clone} \title{Clone an environment} \usage{ env_clone(env, parent = env_parent(env)) } \arguments{ \item{env}{An environment.} \item{parent}{The parent of the cloned environment.} } \description{ This creates a new environment containing exactly the same objects, optionally with a new parent. } \examples{ env <- env(!!! mtcars) clone <- env_clone(env) identical(env, clone) identical(env$cyl, clone$cyl) } rlang/man/as_bytes.Rd0000644000176200001440000000076613500441351014235 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils-encoding.R \name{as_bytes} \alias{as_bytes} \title{Coerce to a raw vector} \usage{ as_bytes(x) } \arguments{ \item{x}{A string.} } \value{ A raw vector of bytes. } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} This currently only works with strings, and returns its hexadecimal representation. } \section{Life cycle}{ Raw vector functions are experimental. } \keyword{internal} rlang/man/with_env.Rd0000644000176200001440000000372213553606424014256 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/eval.R \name{with_env} \alias{with_env} \alias{locally} \title{Evaluate an expression within a given environment} \usage{ with_env(env, expr) locally(expr) } \arguments{ \item{env}{An environment within which to evaluate \code{expr}. Can be an object with a \code{\link[=get_env]{get_env()}} method.} \item{expr}{An expression to evaluate.} } \description{ These functions evaluate \code{expr} within a given environment (\code{env} for \code{with_env()}, or the child of the current environment for \code{locally}). They rely on \code{\link[=eval_bare]{eval_bare()}} which features a lighter evaluation mechanism than base R \code{\link[base:eval]{base::eval()}}, and which also has some subtle implications when evaluting stack sensitive functions (see help for \code{\link[=eval_bare]{eval_bare()}}). } \details{ \code{locally()} is equivalent to the base function \code{\link[base:local]{base::local()}} but it produces a much cleaner evaluation stack, and has stack-consistent semantics. It is thus more suited for experimenting with the R language. } \section{Life cycle}{ These functions are experimental. Expect API changes. } \examples{ # with_env() is handy to create formulas with a given environment: env <- child_env("rlang") f <- with_env(env, ~new_formula()) identical(f_env(f), env) # Or functions with a given enclosure: fn <- with_env(env, function() NULL) identical(get_env(fn), env) # Unlike eval() it doesn't create duplicates on the evaluation # stack. You can thus use it e.g. to create non-local returns: fn <- function() { g(current_env()) "normal return" } g <- function(env) { with_env(env, return("early return")) } fn() # Since env is passed to as_environment(), it can be any object with an # as_environment() method. For strings, the pkg_env() is returned: with_env("base", ~mtcars) # This can be handy to put dictionaries in scope: with_env(mtcars, cyl) } \keyword{internal} rlang/man/type_of.Rd0000644000176200001440000000300313500520041014046 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{type_of} \alias{type_of} \title{Base type of an object} \usage{ type_of(x) } \arguments{ \item{x}{An R object.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("soft-deprecated")} \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} This is equivalent to \code{\link[base:typeof]{base::typeof()}} with a few differences that make dispatching easier: \itemize{ \item The type of one-sided formulas is "quote". \item The type of character vectors of length 1 is "string". \item The type of special and builtin functions is "primitive". } } \section{Life cycle}{ \code{type_of()} is an experimental function. Expect API changes. } \examples{ type_of(10L) # Quosures are treated as a new base type but not formulas: type_of(quo(10L)) type_of(~10L) # Compare to base::typeof(): typeof(quo(10L)) # Strings are treated as a new base type: type_of(letters) type_of(letters[[1]]) # This is a bit inconsistent with the core language tenet that data # types are vectors. However, treating strings as a different # scalar type is quite helpful for switching on function inputs # since so many arguments expect strings: switch_type("foo", character = abort("vector!"), string = "result") # Special and builtin primitives are both treated as primitives. # That's because it is often irrelevant which type of primitive an # input is: typeof(list) typeof(`$`) type_of(list) type_of(`$`) } \keyword{internal} rlang/man/type-predicates.Rd0000644000176200001440000000323513500416332015521 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/types.R \name{type-predicates} \alias{type-predicates} \alias{is_list} \alias{is_atomic} \alias{is_vector} \alias{is_integer} \alias{is_double} \alias{is_character} \alias{is_logical} \alias{is_raw} \alias{is_bytes} \alias{is_null} \title{Type predicates} \usage{ is_list(x, n = NULL) is_atomic(x, n = NULL) is_vector(x, n = NULL) is_integer(x, n = NULL) is_double(x, n = NULL, finite = NULL) is_character(x, n = NULL, encoding = NULL) is_logical(x, n = NULL) is_raw(x, n = NULL) is_bytes(x, n = NULL) is_null(x) } \arguments{ \item{x}{Object to be tested.} \item{n}{Expected length of a vector.} \item{finite}{Whether all values of the vector are finite. The non-finite values are \code{NA}, \code{Inf}, \code{-Inf} and \code{NaN}. Setting this to something other than \code{NULL} can be expensive because the whole vector needs to be traversed and checked.} \item{encoding}{Defunct as of rlang 0.4.0.} } \description{ These type predicates aim to make type testing in R more consistent. They are wrappers around \code{\link[base:typeof]{base::typeof()}}, so operate at a level beneath S3/S4 etc. } \details{ Compared to base R functions: \itemize{ \item The predicates for vectors include the \code{n} argument for pattern-matching on the vector length. \item Unlike \code{is.atomic()}, \code{is_atomic()} does not return \code{TRUE} for \code{NULL}. \item Unlike \code{is.vector()}, \code{is_vector()} tests if an object is an atomic vector or a list. \code{is.vector} checks for the presence of attributes (other than name). } } \seealso{ \link{bare-type-predicates} \link{scalar-type-predicates} } rlang/man/as_function.Rd0000644000176200001440000000426413563530577014753 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/fn.R \name{as_function} \alias{as_function} \alias{is_lambda} \alias{as_closure} \title{Convert to function or closure} \usage{ as_function(x, env = caller_env()) is_lambda(x) as_closure(x, env = caller_env()) } \arguments{ \item{x}{A function or formula. If a \strong{function}, it is used as is. If a \strong{formula}, e.g. \code{~ .x + 2}, it is converted to a function with up to two arguments: \code{.x} (single argument) or \code{.x} and \code{.y} (two arguments). The \code{.} placeholder can be used instead of \code{.x}. This allows you to create very compact anonymous functions (lambdas) with up to two inputs. Functions created from formulas have a special class. Use \code{is_lambda()} to test for it. Lambdas currently do not support \link{nse-force}, due to the way the arguments are handled internally.} \item{env}{Environment in which to fetch the function in case \code{x} is a string.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("stable")} \itemize{ \item \code{as_function()} transforms a one-sided formula into a function. This powers the lambda syntax in packages like purrr. \item \code{as_closure()} first passes its argument to \code{as_function()}. If the result is a primitive function, it regularises it to a proper \link{closure} (see \code{\link[=is_function]{is_function()}} about primitive functions). Some special control flow primitives like \code{if}, \code{for}, or \code{break} can't be coerced to a closure. } } \examples{ f <- as_function(~ .x + 1) f(10) g <- as_function(~ -1 * .) g(4) h <- as_function(~ .x - .y) h(6, 3) # Functions created from a formula have a special class: is_lambda(f) is_lambda(as_function(function() "foo")) # Primitive functions are regularised as closures as_closure(list) as_closure("list") # Operators have `.x` and `.y` as arguments, just like lambda # functions created with the formula syntax: as_closure(`+`) as_closure(`~`) # Use a regular function for tidy evaluation, also when calling functions # that use tidy evaluation: ## Bad: e <- as_function(~ as_label(ensym(.x))) ## Good: e <- as_function(function(x) as_label(ensym(x))) e(y) } rlang/man/trace_back.Rd0000644000176200001440000000551313522760342014505 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/trace.R \name{trace_back} \alias{trace_back} \alias{trace_length} \title{Capture a backtrace} \usage{ trace_back(top = NULL, bottom = NULL) trace_length(trace) } \arguments{ \item{top}{The first frame environment to be included in the backtrace. This becomes the top of the backtrace tree and represents the oldest call in the backtrace. This is needed in particular when you call \code{trace_back()} indirectly or from a larger context, for example in tests or inside an RMarkdown document where you don't want all of the knitr evaluation mechanisms to appear in the backtrace.} \item{bottom}{The last frame environment to be included in the backtrace. This becomes the rightmost leaf of the backtrace tree and represents the youngest call in the backtrace. Set this when you would like to capture a backtrace without the capture context. Can also be an integer that will be passed to \code{\link[=caller_env]{caller_env()}}.} \item{trace}{A backtrace created by \code{trace_back()}.} } \description{ A backtrace captures the sequence of calls that lead to the current function, sometimes called the call stack. Because of lazy evaluation, the call stack in R is actually a tree, which the \code{summary()} method of this object will reveal. } \details{ \code{trace_length()} returns the number of frames in a backtrace. } \examples{ # Trim backtraces automatically (this improves the generated # documentation for the rlang website and the same trick can be # useful within knitr documents): options(rlang_trace_top_env = current_env()) f <- function() g() g <- function() h() h <- function() trace_back() # When no lazy evaluation is involved the backtrace is linear # (i.e. every call has only one child) f() # Lazy evaluation introduces a tree like structure identity(identity(f())) identity(try(f())) try(identity(f())) # When printing, you can request to simplify this tree to only show # the direct sequence of calls that lead to `trace_back()` x <- try(identity(f())) x print(x, simplify = "branch") # With a little cunning you can also use it to capture the # tree from within a base NSE function x <- NULL with(mtcars, {x <<- f(); 10}) x # Restore default top env for next example options(rlang_trace_top_env = NULL) # When code is executed indirectly, i.e. via source or within an # RMarkdown document, you'll tend to get a lot of guff at the beginning # related to the execution environment: conn <- textConnection("summary(f())") source(conn, echo = TRUE, local = TRUE) close(conn) # To automatically strip this off, specify which frame should be # the top of the backtrace. This will automatically trim off calls # prior to that frame: top <- current_env() h <- function() trace_back(top) conn <- textConnection("summary(f())") source(conn, echo = TRUE, local = TRUE) close(conn) } rlang/man/with_abort.Rd0000644000176200001440000000274113552030327014565 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cnd-entrace.R \name{with_abort} \alias{with_abort} \title{Promote all errors to rlang errors} \usage{ with_abort(expr, classes = "error") } \arguments{ \item{expr}{An expression run in a context where errors are promoted to rlang errors.} \item{classes}{Character vector of condition classes that should be promoted to rlang errors.} } \description{ \code{with_abort()} promotes conditions as if they were thrown with \code{\link[=abort]{abort()}}. These errors embed a \link[=trace_back]{backtrace}. They are particularly suitable to be set as \emph{parent errors} (see \code{parent} argument of \code{\link[=abort]{abort()}}). } \details{ \code{with_abort()} installs a \link[=calling]{calling handler} for errors and rethrows non-rlang errors with \code{\link[=abort]{abort()}}. However, error handlers installed \emph{within} \code{with_abort()} have priority. For this reason, you should use \code{\link[=tryCatch]{tryCatch()}} and \link{exiting} handlers outside \code{with_abort()} rather than inside. } \examples{ # with_abort() automatically casts simple errors thrown by stop() # to rlang errors. It is is handy for rethrowing low level # errors. The backtraces are then segmented between the low level # and high level contexts. f <- function() g() g <- function() stop("Low level error") high_level <- function() { with_handlers( with_abort(f()), error = ~ abort("High level error", parent = .) ) } } rlang/man/as_utf8_character.Rd0000644000176200001440000000333313604124170016004 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils-encoding.R \name{as_utf8_character} \alias{as_utf8_character} \title{Coerce to a character vector and attempt encoding conversion} \usage{ as_utf8_character(x) } \arguments{ \item{x}{An object to coerce.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} Unlike specifying the \code{encoding} argument in \code{as_string()} and \code{as_character()}, which is only declarative, these functions actually attempt to convert the encoding of their input. There are two possible cases: \itemize{ \item The string is tagged as UTF-8 or latin1, the only two encodings for which R has specific support. In this case, converting to the same encoding is a no-op, and converting to native always works as expected, as long as the native encoding, the one specified by the \code{LC_CTYPE} locale has support for all characters occurring in the strings. Unrepresentable characters are serialised as unicode points: "". \item The string is not tagged. R assumes that it is encoded in the native encoding. Conversion to native is a no-op, and conversion to UTF-8 should work as long as the string is actually encoded in the locale codeset. } When translating to UTF-8, the strings are parsed for serialised unicode points (e.g. strings looking like "U+xxxx") with \code{\link[=chr_unserialise_unicode]{chr_unserialise_unicode()}}. This helps to alleviate the effects of character-to-symbol-to-character roundtrips on systems with non-UTF-8 native encoding. } \examples{ # Let's create a string marked as UTF-8 (which is guaranteed by the # Unicode escaping in the string): utf8 <- "caf\uE9" Encoding(utf8) as_bytes(utf8) } \keyword{internal} rlang/man/env_has.Rd0000644000176200001440000000170313405732277014055 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env-binding.R \name{env_has} \alias{env_has} \title{Does an environment have or see bindings?} \usage{ env_has(env = caller_env(), nms, inherit = FALSE) } \arguments{ \item{env}{An environment.} \item{nms}{A character vector containing the names of the bindings to remove.} \item{inherit}{Whether to look for bindings in the parent environments.} } \value{ A named logical vector as long as \code{nms}. } \description{ \code{env_has()} is a vectorised predicate that queries whether an environment owns bindings personally (with \code{inherit} set to \code{FALSE}, the default), or sees them in its own environment or in any of its parents (with \code{inherit = TRUE}). } \examples{ parent <- child_env(NULL, foo = "foo") env <- child_env(parent, bar = "bar") # env does not own `foo` but sees it in its parent environment: env_has(env, "foo") env_has(env, "foo", inherit = TRUE) } rlang/man/cnd_muffle.Rd0000644000176200001440000000525313553606643014541 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cnd-handlers.R \name{cnd_muffle} \alias{cnd_muffle} \title{Muffle a condition} \usage{ cnd_muffle(cnd) } \arguments{ \item{cnd}{A condition to muffle.} } \description{ Unlike \code{\link[=exiting]{exiting()}} handlers, \code{\link[=calling]{calling()}} handlers must be explicit that they have handled a condition to stop it from propagating to other handlers. Use \code{cnd_muffle()} within a calling handler (or as a calling handler, see examples) to prevent any other handlers from being called for that condition. } \section{Mufflable conditions}{ Most conditions signalled by base R are muffable, although the name of the restart varies. cnd_muffle() will automatically call the correct restart for you. It is compatible with the following conditions: \itemize{ \item \code{warning} and \code{message} conditions. In this case \code{cnd_muffle()} is equivalent to \code{\link[base:suppressMessages]{base::suppressMessages()}} and \code{\link[base:suppressWarnings]{base::suppressWarnings()}}. \item Bare conditions signalled with \code{signal()} or \code{\link[=cnd_signal]{cnd_signal()}}. Note that conditions signalled with \code{\link[base:signalCondition]{base::signalCondition()}} are not mufflable. \item Interrupts are sometimes signalled with a \code{resume} restart on recent R versions. When this is the case, you can muffle the interrupt with \code{cnd_muffle()}. Check if a restart is available with \code{base::findRestart("resume")}. } If you call \code{cnd_muffle()} with a condition that is not mufflable you will cause a new error to be signalled. \itemize{ \item Errors are not mufflable since they are signalled in critical situations where execution cannot continue safely. \item Conditions captured with \code{\link[base:tryCatch]{base::tryCatch()}}, \code{\link[=with_handlers]{with_handlers()}} or \code{\link[=catch_cnd]{catch_cnd()}} are no longer mufflable. Muffling restarts \emph{must} be called from a \link{calling} handler. } } \examples{ fn <- function() { inform("Beware!", "my_particular_msg") inform("On your guard!") "foobar" } # Let's install a muffling handler for the condition thrown by `fn()`. # This will suppress all `my_particular_wng` warnings but let other # types of warnings go through: with_handlers(fn(), my_particular_msg = calling(function(cnd) { inform("Dealt with this particular message") cnd_muffle(cnd) }) ) # Note how execution of `fn()` continued normally after dealing # with that particular message. # cnd_muffle() can also be passed to with_handlers() as a calling # handler: with_handlers(fn(), my_particular_msg = calling(cnd_muffle) ) } \keyword{internal} rlang/man/call2.Rd0000644000176200001440000000610613604124167013423 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/call.R \name{call2} \alias{call2} \title{Create a call} \usage{ call2(.fn, ..., .ns = NULL) } \arguments{ \item{.fn}{Function to call. Must be a callable object: a string, symbol, call, or a function.} \item{...}{<\link[=dyn-dots]{dynamic}> Arguments for the function call. Empty arguments are preserved.} \item{.ns}{Namespace with which to prefix \code{.fn}. Must be a string or symbol.} } \description{ Quoted function calls are one of the two types of \link[=is_symbolic]{symbolic} objects in R. They represent the action of calling a function, possibly with arguments. There are two ways of creating a quoted call: \itemize{ \item By \link[=nse-defuse]{quoting} it. Quoting prevents functions from being called. Instead, you get the description of the function call as an R object. That is, a quoted function call. \item By constructing it with \code{\link[base:call]{base::call()}}, \code{\link[base:as.call]{base::as.call()}}, or \code{call2()}. In this case, you pass the call elements (the function to call and the arguments to call it with) separately. } See section below for the difference between \code{call2()} and the base constructors. } \section{Difference with base constructors}{ \code{call2()} is more flexible and convenient than \code{base::call()}: \itemize{ \item The function to call can be a string or a \link[=is_callable]{callable} object: a symbol, another call (e.g. a \code{$} or \code{[[} call), or a function to inline. \code{base::call()} only supports strings and you need to use \code{base::as.call()} to construct a call with a callable object.\preformatted{call2(list, 1, 2) as.call(list(list, 1, 2)) } \item The \code{.ns} argument is convenient for creating namespaced calls.\preformatted{call2("list", 1, 2, .ns = "base") ns_call <- as.call(list(as.name("::"), as.name("list"), as.name("base"))) as.call(list(ns_call, 1, 2)) } \item \code{call2()} has \link[=list2]{tidy dots} support and you can splice lists of arguments with \verb{!!!}. With base R, you need to use \code{as.call()} instead of \code{call()} if the arguments are in a list.\preformatted{args <- list(na.rm = TRUE, trim = 0) call2("mean", 1:10, !!!args) as.call(c(list(as.name("mean"), 1:10), args)) } } } \section{Life cycle}{ In rlang 0.2.0 \code{lang()} was soft-deprecated and renamed to \code{call2()}. In early versions of rlang calls were called "language" objects in order to follow the R type nomenclature as returned by \code{\link[base:typeof]{base::typeof()}}. The goal was to avoid adding to the confusion between S modes and R types. With hindsight we find it is better to use more meaningful type names. } \examples{ # fn can either be a string, a symbol or a call call2("f", a = 1) call2(quote(f), a = 1) call2(quote(f()), a = 1) #' Can supply arguments individually or in a list call2(quote(f), a = 1, b = 2) call2(quote(f), !!!list(a = 1, b = 2)) # Creating namespaced calls is easy: call2("fun", arg = quote(baz), .ns = "mypkg") # Empty arguments are preserved: call2("[", quote(x), , drop = ) } \seealso{ call_modify } rlang/man/is_stack.Rd0000644000176200001440000000063013554012136014216 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{is_stack} \alias{is_stack} \alias{is_eval_stack} \alias{is_call_stack} \title{Is object a stack?} \usage{ is_stack(x) is_eval_stack(x) is_call_stack(x) } \arguments{ \item{x}{An object to test} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("soft-deprecated")} } \keyword{internal} rlang/man/env.Rd0000644000176200001440000001245313604124167013220 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env.R \name{env} \alias{env} \alias{child_env} \alias{new_environment} \title{Create a new environment} \usage{ env(...) child_env(.parent, ...) new_environment(data = list(), parent = empty_env()) } \arguments{ \item{..., data}{<\link[=dyn-dots]{dynamic}> Named values. You can supply one unnamed to specify a custom parent, otherwise it defaults to the current environment.} \item{.parent, parent}{A parent environment. Can be an object supported by \code{\link[=as_environment]{as_environment()}}.} } \description{ These functions create new environments. \itemize{ \item \code{env()} creates a child of the current environment by default and takes a variable number of named objects to populate it. \item \code{new_environment()} creates a child of the empty environment by default and takes a named list of objects to populate it. } } \section{Environments as objects}{ Environments are containers of uniquely named objects. Their most common use is to provide a scope for the evaluation of R expressions. Not all languages have first class environments, i.e. can manipulate scope as regular objects. Reification of scope is one of the most powerful features of R as it allows you to change what objects a function or expression sees when it is evaluated. Environments also constitute a data structure in their own right. They are a collection of uniquely named objects, subsettable by name and modifiable by reference. This latter property (see section on reference semantics) is especially useful for creating mutable OO systems (cf the \href{https://github.com/wch/R6}{R6 package} and the \href{http://ggplot2.tidyverse.org/articles/extending-ggplot2.html}{ggproto system} for extending ggplot2). } \section{Inheritance}{ All R environments (except the \link[=empty_env]{empty environment}) are defined with a parent environment. An environment and its grandparents thus form a linear hierarchy that is the basis for \href{https://en.wikipedia.org/wiki/Scope_(computer_science)}{lexical scoping} in R. When R evaluates an expression, it looks up symbols in a given environment. If it cannot find these symbols there, it keeps looking them up in parent environments. This way, objects defined in child environments have precedence over objects defined in parent environments. The ability of overriding specific definitions is used in the tidyeval framework to create powerful domain-specific grammars. A common use of masking is to put data frame columns in scope. See for example \code{\link[=as_data_mask]{as_data_mask()}}. } \section{Reference semantics}{ Unlike regular objects such as vectors, environments are an \link[=is_copyable]{uncopyable} object type. This means that if you have multiple references to a given environment (by assigning the environment to another symbol with \verb{<-} or passing the environment as argument to a function), modifying the bindings of one of those references changes all other references as well. } \section{Life cycle}{ \itemize{ \item \code{child_env()} is in the questioning stage. It is redundant now that \code{env()} accepts parent environments. } } \examples{ # env() creates a new environment which has the current environment # as parent env <- env(a = 1, b = "foo") env$b identical(env_parent(env), current_env()) # Supply one unnamed argument to override the default: env <- env(base_env(), a = 1, b = "foo") identical(env_parent(env), base_env()) # child_env() lets you specify a parent: child <- child_env(env, c = "bar") identical(env_parent(child), env) # This child environment owns `c` but inherits `a` and `b` from `env`: env_has(child, c("a", "b", "c", "d")) env_has(child, c("a", "b", "c", "d"), inherit = TRUE) # `parent` is passed to as_environment() to provide handy # shortcuts. Pass a string to create a child of a package # environment: child_env("rlang") env_parent(child_env("rlang")) # Or `NULL` to create a child of the empty environment: child_env(NULL) env_parent(child_env(NULL)) # The base package environment is often a good default choice for a # parent environment because it contains all standard base # functions. Also note that it will never inherit from other loaded # package environments since R keeps the base package at the tail # of the search path: base_child <- child_env("base") env_has(base_child, c("lapply", "("), inherit = TRUE) # On the other hand, a child of the empty environment doesn't even # see a definition for `(` empty_child <- child_env(NULL) env_has(empty_child, c("lapply", "("), inherit = TRUE) # Note that all other package environments inherit from base_env() # as well: rlang_child <- child_env("rlang") env_has(rlang_child, "env", inherit = TRUE) # rlang function env_has(rlang_child, "lapply", inherit = TRUE) # base function # Both env() and child_env() support tidy dots features: objs <- list(b = "foo", c = "bar") env <- env(a = 1, !!! objs) env$c # You can also unquote names with the definition operator `:=` var <- "a" env <- env(!!var := "A") env$a # Use new_environment() to create containers with the empty # environment as parent: env <- new_environment() env_parent(env) # Like other new_ constructors, it takes an object rather than dots: new_environment(list(a = "foo", b = "bar")) } \seealso{ \code{\link[=env_has]{env_has()}}, \code{\link[=env_bind]{env_bind()}}. } rlang/man/missing_arg.Rd0000644000176200001440000000775613446672557014763 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/arg.R \name{missing_arg} \alias{missing_arg} \alias{is_missing} \alias{maybe_missing} \title{Generate or handle a missing argument} \usage{ missing_arg() is_missing(x) maybe_missing(x, default = missing_arg()) } \arguments{ \item{x}{An object that might be the missing argument.} \item{default}{The object to return if the input is missing, defaults to \code{missing_arg()}.} } \description{ These functions help using the missing argument as a regular R object. \itemize{ \item \code{missing_arg()} generates a missing argument. \item \code{is_missing()} is like \code{\link[base:missing]{base::missing()}} but also supports testing for missing arguments contained in other objects like lists. \item \code{maybe_missing()} is useful to pass down an input that might be missing to another function, potentially substituting by a default value. It avoids triggering an "argument is missing" error. } } \section{Other ways to reify the missing argument}{ \itemize{ \item \code{base::quote(expr = )} is the canonical way to create a missing argument object. \item \code{expr()} called without argument creates a missing argument. \item \code{quo()} called without argument creates an empty quosure, i.e. a quosure containing the missing argument object. } } \section{Fragility of the missing argument object}{ The missing argument is an object that triggers an error if and only if it is the result of evaluating a symbol. No error is produced when a function call evaluates to the missing argument object. This means that expressions like \code{x[[1]] <- missing_arg()} are perfectly safe. Likewise, \code{x[[1]]} is safe even if the result is the missing object. However, as soon as the missing argument is passed down between functions through an argument, you're at risk of triggering a missing error. This is because arguments are passed through symbols. To work around this, \code{is_missing()} and \code{maybe_missing(x)} use a bit of magic to determine if the input is the missing argument without triggering a missing error. \code{maybe_missing()} is particularly useful for prototyping meta-programming algorithms in R. The missing argument is a likely input when computing on the language because it is a standard object in formals lists. While C functions are always allowed to return the missing argument and pass it to other C functions, this is not the case on the R side. If you're implementing your meta-programming algorithm in R, use \code{maybe_missing()} when an input might be the missing argument object. } \section{Life cycle}{ \itemize{ \item \code{missing_arg()} and \code{is_missing()} are stable. \item Like the rest of rlang, \code{maybe_missing()} is maturing. } } \examples{ # The missing argument usually arises inside a function when the # user omits an argument that does not have a default: fn <- function(x) is_missing(x) fn() # Creating a missing argument can also be useful to generate calls args <- list(1, missing_arg(), 3, missing_arg()) quo(fn(!!! args)) # Other ways to create that object include: quote(expr = ) expr() # It is perfectly valid to generate and assign the missing # argument in a list. x <- missing_arg() l <- list(missing_arg()) # Just don't evaluate a symbol that contains the empty argument. # Evaluating the object `x` that we created above would trigger an # error. # x # Not run # On the other hand accessing a missing argument contained in a # list does not trigger an error because subsetting is a function # call: l[[1]] is.null(l[[1]]) # In case you really need to access a symbol that might contain the # empty argument object, use maybe_missing(): maybe_missing(x) is.null(maybe_missing(x)) is_missing(maybe_missing(x)) # Note that base::missing() only works on symbols and does not # support complex expressions. For this reason the following lines # would throw an error: #> missing(missing_arg()) #> missing(l[[1]]) # while is_missing() will work as expected: is_missing(missing_arg()) is_missing(l[[1]]) } rlang/man/as_data_mask.Rd0000644000176200001440000002100313604124170015020 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/eval-tidy.R \name{as_data_mask} \alias{as_data_mask} \alias{as_data_pronoun} \alias{new_data_mask} \title{Create a data mask} \usage{ as_data_mask(data, parent = NULL) as_data_pronoun(data) new_data_mask(bottom, top = bottom, parent = NULL) } \arguments{ \item{data}{A data frame or named vector of masking data.} \item{parent}{Deprecated. This argument no longer has any effect. The parent of the data mask is determined from either: \itemize{ \item The \code{env} argument of \code{eval_tidy()} \item Quosure environments when applicable }} \item{bottom}{The environment containing masking objects if the data mask is one environment deep. The bottom environment if the data mask comprises multiple environment. If you haven't supplied \code{top}, this \strong{must} be an environment that you own, i.e. that you have created yourself.} \item{top}{The last environment of the data mask. If the data mask is only one environment deep, \code{top} should be the same as \code{bottom}. This \strong{must} be an environment that you own, i.e. that you have created yourself. The parent of \code{top} will be changed by the tidy eval engine and should be considered undetermined. Never make assumption about the parent of \code{top}.} } \value{ A data mask that you can supply to \code{\link[=eval_tidy]{eval_tidy()}}. } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("stable")} A data mask is an environment (or possibly multiple environments forming an ancestry) containing user-supplied objects. Objects in the mask have precedence over objects in the environment (i.e. they mask those objects). Many R functions evaluate quoted expressions in a data mask so these expressions can refer to objects within the user data. These functions let you construct a tidy eval data mask manually. They are meant for developers of tidy eval interfaces rather than for end users. } \section{Why build a data mask?}{ Most of the time you can just call \code{\link[=eval_tidy]{eval_tidy()}} with a list or a data frame and the data mask will be constructed automatically. There are three main use cases for manual creation of data masks: \itemize{ \item When \code{\link[=eval_tidy]{eval_tidy()}} is called with the same data in a tight loop. Because there is some overhead to creating tidy eval data masks, constructing the mask once and reusing it for subsequent evaluations may improve performance. \item When several expressions should be evaluated in the exact same environment because a quoted expression might create new objects that can be referred in other quoted expressions evaluated at a later time. One example of this is \code{tibble::lst()} where new columns can refer to previous ones. \item When your data mask requires special features. For instance the data frame columns in dplyr data masks are implemented with \link[base:delayedAssign]{active bindings}. } } \section{Building your own data mask}{ Unlike \code{\link[base:eval]{base::eval()}} which takes any kind of environments as data mask, \code{\link[=eval_tidy]{eval_tidy()}} has specific requirements in order to support \link[=nse-defuse]{quosures}. For this reason you can't supply bare environments. There are two ways of constructing an rlang data mask manually: \itemize{ \item \code{as_data_mask()} transforms a list or data frame to a data mask. It automatically installs the data pronoun \code{\link{.data}}. \item \code{new_data_mask()} is a bare bones data mask constructor for environments. You can supply a bottom and a top environment in case your data mask comprises multiple environments (see section below). Unlike \code{as_data_mask()} it does not install the \code{.data} pronoun so you need to provide one yourself. You can provide a pronoun constructed with \code{as_data_pronoun()} or your own pronoun class. \code{as_data_pronoun()} will create a pronoun from a list, an environment, or an rlang data mask. In the latter case, the whole ancestry is looked up from the bottom to the top of the mask. Functions stored in the mask are bypassed by the pronoun. } Once you have built a data mask, simply pass it to \code{\link[=eval_tidy]{eval_tidy()}} as the \code{data} argument. You can repeat this as many times as needed. Note that any objects created there (perhaps because of a call to \verb{<-}) will persist in subsequent evaluations. } \section{Top and bottom of data mask}{ In some cases you'll need several levels in your data mask. One good reason is when you include functions in the mask. It's a good idea to keep data objects one level lower than function objects, so that the former cannot override the definitions of the latter (see examples). In that case, set up all your environments and keep track of the bottom child and the top parent. You'll need to pass both to \code{new_data_mask()}. Note that the parent of the top environment is completely undetermined, you shouldn't expect it to remain the same at all times. This parent is replaced during evaluation by \code{\link[=eval_tidy]{eval_tidy()}} to one of the following environments: \itemize{ \item The default environment passed as the \code{env} argument of \code{eval_tidy()}. \item The environment of the current quosure being evaluated, if applicable. } Consequently, all masking data should be contained between the bottom and top environment of the data mask. } \section{Life cycle}{ The \code{parent} argument no longer has any effect and is defunct as of rlang 0.4.0. The parent of the data mask is determined from either: \itemize{ \item The \code{env} argument of \code{eval_tidy()} \item Quosure environments when applicable } Passing environments to \code{as_data_mask()} is deprecated as of rlang 0.3.0. Please use \code{new_data_mask()} instead. \strong{rlang 0.2.0} In early versions of rlang data masks were called overscopes. We think data mask is a more natural name in R. It makes reference to masking in the search path which occurs through the same mechanism (in technical terms, lexical scoping with hierarchically nested environments). We say that objects from user data mask objects in the current environment. Following this change in terminology, \code{as_overscope()} and \code{new_overscope()} were deprecated in rlang 0.2.0 in favour of \code{as_data_mask()} and \code{new_data_mask()}. } \examples{ # Evaluating in a tidy evaluation environment enables all tidy # features: mask <- as_data_mask(mtcars) eval_tidy(quo(letters), mask) # You can install new pronouns in the mask: mask$.pronoun <- as_data_pronoun(list(foo = "bar", baz = "bam")) eval_tidy(quo(.pronoun$foo), mask) # In some cases the data mask can leak to the user, for example if # a function or formula is created in the data mask environment: cyl <- "user variable from the context" fn <- eval_tidy(quote(function() cyl), mask) fn() # If new objects are created in the mask, they persist in the # subsequent calls: eval_tidy(quote(new <- cyl + am), mask) eval_tidy(quote(new * 2), mask) # In some cases your data mask is a whole chain of environments # rather than a single environment. You'll have to use # `new_data_mask()` and let it know about the bottom of the mask # (the last child of the environment chain) and the topmost parent. # A common situation where you'll want a multiple-environment mask # is when you include functions in your mask. In that case you'll # put functions in the top environment and data in the bottom. This # will prevent the data from overwriting the functions. top <- new_environment(list(`+` = base::paste, c = base::paste)) # Let's add a middle environment just for sport: middle <- env(top) # And finally the bottom environment containing data: bottom <- env(middle, a = "a", b = "b", c = "c") # We can now create a mask by supplying the top and bottom # environments: mask <- new_data_mask(bottom, top = top) # This data mask can be passed to eval_tidy() instead of a list or # data frame: eval_tidy(quote(a + b + c), data = mask) # Note how the function `c()` and the object `c` are looked up # properly because of the multi-level structure: eval_tidy(quote(c(a, b, c)), data = mask) # new_data_mask() does not create data pronouns, but # data pronouns can be added manually: mask$.fns <- as_data_pronoun(top) # The `.data` pronoun should generally be created from the # mask. This will ensure data is looked up throughout the whole # ancestry. Only non-function objects are looked up from this # pronoun: mask$.data <- as_data_pronoun(mask) mask$.data$c # Now we can reference the values with the pronouns: eval_tidy(quote(c(.data$a, .data$b, .data$c)), data = mask) } rlang/man/op-null-default.Rd0000644000176200001440000000100013563526752015434 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/operators.R \name{op-null-default} \alias{op-null-default} \alias{\%||\%} \title{Default value for \code{NULL}} \usage{ x \%||\% y } \arguments{ \item{x, y}{If \code{x} is NULL, will return \code{y}; otherwise returns \code{x}.} } \description{ This infix function makes it easy to replace \code{NULL}s with a default value. It's inspired by the way that Ruby's or operation (\code{||}) works. } \examples{ 1 \%||\% 2 NULL \%||\% 2 } rlang/man/fn_fmls.Rd0000644000176200001440000000251713457603056014061 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/fn.R \name{fn_fmls} \alias{fn_fmls} \alias{fn_fmls_names} \alias{fn_fmls_syms} \alias{fn_fmls<-} \alias{fn_fmls_names<-} \title{Extract arguments from a function} \usage{ fn_fmls(fn = caller_fn()) fn_fmls_names(fn = caller_fn()) fn_fmls_syms(fn = caller_fn()) fn_fmls(fn) <- value fn_fmls_names(fn) <- value } \arguments{ \item{fn}{A function. It is lookep up in the calling frame if not supplied.} \item{value}{New formals or formals names for \code{fn}.} } \description{ \code{fn_fmls()} returns a named list of formal arguments. \code{fn_fmls_names()} returns the names of the arguments. \code{fn_fmls_syms()} returns formals as a named list of symbols. This is especially useful for forwarding arguments in \link[=lang]{constructed calls}. } \details{ Unlike \code{formals()}, these helpers throw an error with primitive functions instead of returning \code{NULL}. } \examples{ # Extract from current call: fn <- function(a = 1, b = 2) fn_fmls() fn() # fn_fmls_syms() makes it easy to forward arguments: call2("apply", !!! fn_fmls_syms(lapply)) # You can also change the formals: fn_fmls(fn) <- list(A = 10, B = 20) fn() fn_fmls_names(fn) <- c("foo", "bar") fn() } \seealso{ \code{\link[=call_args]{call_args()}} and \code{\link[=call_args_names]{call_args_names()}} } rlang/man/chr_unserialise_unicode.Rd0000644000176200001440000000263513604124170017310 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils-encoding.R \name{chr_unserialise_unicode} \alias{chr_unserialise_unicode} \title{Translate unicode points to UTF-8} \usage{ chr_unserialise_unicode(chr) } \arguments{ \item{chr}{A character vector.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} For historical reasons, R translates strings to the native encoding when they are converted to symbols. This string-to-symbol conversion is not a rare occurrence and happens for instance to the names of a list of arguments converted to a call by \code{do.call()}. If the string contains unicode characters that cannot be represented in the native encoding, R serialises those as an ASCII sequence representing the unicode point. This is why Windows users with western locales often see strings looking like \verb{}. To alleviate some of the pain, rlang parses strings and looks for serialised unicode points to translate them back to the proper UTF-8 representation. This transformation occurs automatically in functions like \code{\link[=env_names]{env_names()}} and can be manually triggered with \code{as_utf8_character()} and \code{chr_unserialise_unicode()}. } \section{Life cycle}{ This function is experimental. } \examples{ ascii <- "" chr_unserialise_unicode(ascii) identical(chr_unserialise_unicode(ascii), "\u5e78") } \keyword{internal} rlang/man/env_unbind.Rd0000644000176200001440000000233213500432472014546 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env-binding.R \name{env_unbind} \alias{env_unbind} \title{Remove bindings from an environment} \usage{ env_unbind(env = caller_env(), nms, inherit = FALSE) } \arguments{ \item{env}{An environment.} \item{nms}{A character vector containing the names of the bindings to remove.} \item{inherit}{Whether to look for bindings in the parent environments.} } \value{ The input object \code{env} with its associated environment modified in place, invisibly. } \description{ \code{env_unbind()} is the complement of \code{\link[=env_bind]{env_bind()}}. Like \code{env_has()}, it ignores the parent environments of \code{env} by default. Set \code{inherit} to \code{TRUE} to track down bindings in parent environments. } \examples{ data <- set_names(as.list(letters), letters) env_bind(environment(), !!! data) env_has(environment(), letters) # env_unbind() removes bindings: env_unbind(environment(), letters) env_has(environment(), letters) # With inherit = TRUE, it removes bindings in parent environments # as well: parent <- child_env(NULL, foo = "a") env <- child_env(parent, foo = "b") env_unbind(env, "foo", inherit = TRUE) env_has(env, "foo", inherit = TRUE) } rlang/man/is_expression.Rd0000644000176200001440000000775513351410654015331 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/expr.R \name{is_expression} \alias{is_expression} \alias{is_syntactic_literal} \alias{is_symbolic} \title{Is an object an expression?} \usage{ is_expression(x) is_syntactic_literal(x) is_symbolic(x) } \arguments{ \item{x}{An object to test.} } \description{ \code{is_expression()} tests for expressions, the set of objects that can be obtained from parsing R code. An expression can be one of two things: either a symbolic object (for which \code{is_symbolic()} returns \code{TRUE}), or a syntactic literal (testable with \code{is_syntactic_literal()}). Technically, calls can contain any R object, not necessarily symbolic objects or syntactic literals. However, this only happens in artificial situations. Expressions as we define them only contain numbers, strings, \code{NULL}, symbols, and calls: this is the complete set of R objects that can be created when R parses source code (e.g. from using \code{\link[=parse_expr]{parse_expr()}}). Note that we are using the term expression in its colloquial sense and not to refer to \code{\link[=expression]{expression()}} vectors, a data type that wraps expressions in a vector and which isn't used much in modern R code. } \details{ \code{is_symbolic()} returns \code{TRUE} for symbols and calls (objects with type \code{language}). Symbolic objects are replaced by their value during evaluation. Literals are the complement of symbolic objects. They are their own value and return themselves during evaluation. \code{is_syntactic_literal()} is a predicate that returns \code{TRUE} for the subset of literals that are created by R when parsing text (see \code{\link[=parse_expr]{parse_expr()}}): numbers, strings and \code{NULL}. Along with symbols, these literals are the terminating nodes in an AST. Note that in the most general sense, a literal is any R object that evaluates to itself and that can be evaluated in the empty environment. For instance, \code{quote(c(1, 2))} is not a literal, it is a call. However, the result of evaluating it in \code{\link[=base_env]{base_env()}} is a literal(in this case an atomic vector). Pairlists are also a kind of language objects. However, since they are mostly an internal data structure, \code{is_expression()} returns \code{FALSE} for pairlists. You can use \code{is_pairlist()} to explicitly check for them. Pairlists are the data structure for function arguments. They usually do not arise from R code because subsetting a call is a type-preserving operation. However, you can obtain the pairlist of arguments by taking the CDR of the call object from C code. The rlang function \code{\link[=node_cdr]{node_cdr()}} will do it from R. Another way in which pairlist of arguments arise is by extracting the argument list of a closure with \code{\link[base:formals]{base::formals()}} or \code{\link[=fn_fmls]{fn_fmls()}}. } \examples{ q1 <- quote(1) is_expression(q1) is_syntactic_literal(q1) q2 <- quote(x) is_expression(q2) is_symbol(q2) q3 <- quote(x + 1) is_expression(q3) is_call(q3) # Atomic expressions are the terminating nodes of a call tree: # NULL or a scalar atomic vector: is_syntactic_literal("string") is_syntactic_literal(NULL) is_syntactic_literal(letters) is_syntactic_literal(quote(call())) # Parsable literals have the property of being self-quoting: identical("foo", quote("foo")) identical(1L, quote(1L)) identical(NULL, quote(NULL)) # Like any literals, they can be evaluated within the empty # environment: eval_bare(quote(1L), empty_env()) # Whereas it would fail for symbolic expressions: # eval_bare(quote(c(1L, 2L)), empty_env()) # Pairlists are also language objects representing argument lists. # You will usually encounter them with extracted formals: fmls <- formals(is_expression) typeof(fmls) # Since they are mostly an internal data structure, is_expression() # returns FALSE for pairlists, so you will have to check explicitly # for them: is_expression(fmls) is_pairlist(fmls) } \seealso{ \code{\link[=is_call]{is_call()}} for a call predicate. } rlang/man/is_call.Rd0000644000176200001440000000563213604124167014037 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/call.R \name{is_call} \alias{is_call} \title{Is object a call?} \usage{ is_call(x, name = NULL, n = NULL, ns = NULL) } \arguments{ \item{x}{An object to test. If a formula, the right-hand side is extracted.} \item{name}{An optional name that the call should match. It is passed to \code{\link[=sym]{sym()}} before matching. This argument is vectorised and you can supply a vector of names to match. In this case, \code{is_call()} returns \code{TRUE} if at least one name matches.} \item{n}{An optional number of arguments that the call should match.} \item{ns}{The namespace of the call. If \code{NULL}, the namespace doesn't participate in the pattern-matching. If an empty string \code{""} and \code{x} is a namespaced call, \code{is_call()} returns \code{FALSE}. If any other string, \code{is_call()} checks that \code{x} is namespaced within \code{ns}. Can be a character vector of namespaces, in which case the call has to match at least one of them, otherwise \code{is_call()} returns \code{FALSE}.} } \description{ This function tests if \code{x} is a \link[=call2]{call}. This is a pattern-matching predicate that returns \code{FALSE} if \code{name} and \code{n} are supplied and the call does not match these properties. } \section{Life cycle}{ \code{is_lang()} has been soft-deprecated and renamed to \code{is_call()} in rlang 0.2.0 and similarly for \code{is_unary_lang()} and \code{is_binary_lang()}. This renaming follows the general switch from "language" to "call" in the rlang type nomenclature. See lifecycle section in \code{\link[=call2]{call2()}}. } \examples{ is_call(quote(foo(bar))) # You can pattern-match the call with additional arguments: is_call(quote(foo(bar)), "foo") is_call(quote(foo(bar)), "bar") is_call(quote(foo(bar)), quote(foo)) # Match the number of arguments with is_call(): is_call(quote(foo(bar)), "foo", 1) is_call(quote(foo(bar)), "foo", 2) # By default, namespaced calls are tested unqualified: ns_expr <- quote(base::list()) is_call(ns_expr, "list") # You can also specify whether the call shouldn't be namespaced by # supplying an empty string: is_call(ns_expr, "list", ns = "") # Or if it should have a namespace: is_call(ns_expr, "list", ns = "utils") is_call(ns_expr, "list", ns = "base") # You can supply multiple namespaces: is_call(ns_expr, "list", ns = c("utils", "base")) is_call(ns_expr, "list", ns = c("utils", "stats")) # If one of them is "", unnamespaced calls will match as well: is_call(quote(list()), "list", ns = "base") is_call(quote(list()), "list", ns = c("base", "")) is_call(quote(base::list()), "list", ns = c("base", "")) # The name argument is vectorised so you can supply a list of names # to match with: is_call(quote(foo(bar)), c("bar", "baz")) is_call(quote(foo(bar)), c("bar", "foo")) is_call(quote(base::list), c("::", ":::", "$", "@")) } \seealso{ \code{\link[=is_expression]{is_expression()}} } rlang/man/caller_frame.Rd0000644000176200001440000000053413500223442015030 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{caller_frame} \alias{caller_frame} \title{Get caller frame} \usage{ caller_frame(n = 1) } \arguments{ \item{n}{Number of frames to go back.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} } \keyword{internal} rlang/man/friendly_type.Rd0000644000176200001440000000113213504161362015272 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/types.R \name{friendly_type} \alias{friendly_type} \title{Format a type for error messages} \usage{ friendly_type(type) } \arguments{ \item{type}{A type as returned by \code{\link[=typeof]{typeof()}}.} } \value{ A string of the prettified type, qualified with an indefinite article. } \description{ Format a type for error messages } \section{Life cycle}{ \itemize{ \item \code{friendly_type()} is experimental. } } \examples{ friendly_type("logical") friendly_type("integer") friendly_type("string") } \keyword{internal} rlang/man/set_names.Rd0000644000176200001440000000276413500131074014400 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/attr.R \name{set_names} \alias{set_names} \title{Set names of a vector} \usage{ set_names(x, nm = x, ...) } \arguments{ \item{x}{Vector to name.} \item{nm, ...}{Vector of names, the same length as \code{x}. You can specify names in the following ways: \itemize{ \item If you do nothing, \code{x} will be named with itself. \item If \code{x} already has names, you can provide a function or formula to transform the existing names. In that case, \code{...} is passed to the function. \item If \code{nm} is \code{NULL}, the names are removed (if present). \item In all other cases, \code{nm} and \code{...} are coerced to character. }} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("stable")} This is equivalent to \code{\link[stats:setNames]{stats::setNames()}}, with more features and stricter argument checking. } \section{Life cycle}{ \code{set_names()} is stable and exported in purrr. } \examples{ set_names(1:4, c("a", "b", "c", "d")) set_names(1:4, letters[1:4]) set_names(1:4, "a", "b", "c", "d") # If the second argument is ommitted a vector is named with itself set_names(letters[1:5]) # Alternatively you can supply a function set_names(1:10, ~ letters[seq_along(.)]) set_names(head(mtcars), toupper) # If the input vector is unnamed, it is first named after itself # before the function is applied: set_names(letters, toupper) # `...` is passed to the function: set_names(head(mtcars), paste0, "_foo") } rlang/man/is_function.Rd0000644000176200001440000001025113517571557014756 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/fn.R \name{is_function} \alias{is_function} \alias{is_closure} \alias{is_primitive} \alias{is_primitive_eager} \alias{is_primitive_lazy} \title{Is object a function?} \usage{ is_function(x) is_closure(x) is_primitive(x) is_primitive_eager(x) is_primitive_lazy(x) } \arguments{ \item{x}{Object to be tested.} } \description{ The R language defines two different types of functions: primitive functions, which are low-level, and closures, which are the regular kind of functions. } \details{ Closures are functions written in R, named after the way their arguments are scoped within nested environments (see https://en.wikipedia.org/wiki/Closure_(computer_programming)). The root environment of the closure is called the closure environment. When closures are evaluated, a new environment called the evaluation frame is created with the closure environment as parent. This is where the body of the closure is evaluated. These closure frames appear on the evaluation stack (see \code{\link[=ctxt_stack]{ctxt_stack()}}), as opposed to primitive functions which do not necessarily have their own evaluation frame and never appear on the stack. Primitive functions are more efficient than closures for two reasons. First, they are written entirely in fast low-level code. Second, the mechanism by which they are passed arguments is more efficient because they often do not need the full procedure of argument matching (dealing with positional versus named arguments, partial matching, etc). One practical consequence of the special way in which primitives are passed arguments is that they technically do not have formal arguments, and \code{\link[=formals]{formals()}} will return \code{NULL} if called on a primitive function. Finally, primitive functions can either take arguments lazily, like R closures do, or evaluate them eagerly before being passed on to the C code. The former kind of primitives are called "special" in R terminology, while the latter is referred to as "builtin". \code{is_primitive_eager()} and \code{is_primitive_lazy()} allow you to check whether a primitive function evaluates arguments eagerly or lazily. You will also encounter the distinction between primitive and internal functions in technical documentation. Like primitive functions, internal functions are defined at a low level and written in C. However, internal functions have no representation in the R language. Instead, they are called via a call to \code{\link[base:.Internal]{base::.Internal()}} within a regular closure. This ensures that they appear as normal R function objects: they obey all the usual rules of argument passing, and they appear on the evaluation stack as any other closures. As a result, \code{\link[=fn_fmls]{fn_fmls()}} does not need to look in the \code{.ArgsEnv} environment to obtain a representation of their arguments, and there is no way of querying from R whether they are lazy ('special' in R terminology) or eager ('builtin'). You can call primitive functions with \code{\link[=.Primitive]{.Primitive()}} and internal functions with \code{\link[=.Internal]{.Internal()}}. However, calling internal functions in a package is forbidden by CRAN's policy because they are considered part of the private API. They often assume that they have been called with correctly formed arguments, and may cause R to crash if you call them with unexpected objects. } \examples{ # Primitive functions are not closures: is_closure(base::c) is_primitive(base::c) # On the other hand, internal functions are wrapped in a closure # and appear as such from the R side: is_closure(base::eval) # Both closures and primitives are functions: is_function(base::c) is_function(base::eval) # Primitive functions never appear in evaluation stacks: is_primitive(base::`[[`) is_primitive(base::list) list(ctxt_stack())[[1]] # While closures do: identity(identity(ctxt_stack())) # Many primitive functions evaluate arguments eagerly: is_primitive_eager(base::c) is_primitive_eager(base::list) is_primitive_eager(base::`+`) # However, primitives that operate on expressions, like quote() or # substitute(), are lazy: is_primitive_lazy(base::quote) is_primitive_lazy(base::substitute) } rlang/man/frame_position.Rd0000644000176200001440000000363013500223442015432 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{frame_position} \alias{frame_position} \title{Find the position or distance of a frame on the evaluation stack} \usage{ frame_position(frame, from = c("global", "current")) } \arguments{ \item{frame}{The environment of a frame. Can be any object with a \code{\link[=get_env]{get_env()}} method. Note that for frame objects, the position from the global frame is simply \code{frame$pos}. Alternatively, \code{frame} can be an integer that represents the position on the stack (and is thus returned as is if \code{from} is "global".} \item{from}{Whether to compute distance from the global frame (the bottom of the evaluation stack), or from the current frame (the top of the evaluation stack).} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} The frame position on the stack can be computed by counting frames from the global frame (the bottom of the stack, the default) or from the current frame (the top of the stack). } \details{ While this function returns the position of the frame on the evaluation stack, it can safely be called with intervening frames as those will be discarded. } \section{Life cycle}{ These functions are deprecated and replaced by \code{\link[=trace_back]{trace_back()}}. } \examples{ fn <- function() g(environment()) g <- function(env) frame_position(env) # frame_position() returns the position of the frame on the evaluation stack: fn() identity(identity(fn())) # Note that it trims off intervening calls before counting so you # can safely nest it within other calls: g <- function(env) identity(identity(frame_position(env))) fn() # You can also ask for the position from the current frame rather # than the global frame: fn <- function() g(environment()) g <- function(env) h(env) h <- function(env) frame_position(env, from = "current") fn() } \keyword{internal} rlang/man/is_pairlist.Rd0000644000176200001440000000171013351410654014742 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/node.R \name{is_pairlist} \alias{is_pairlist} \alias{is_node} \alias{is_node_list} \title{Is object a node or pairlist?} \usage{ is_pairlist(x) is_node(x) is_node_list(x) } \arguments{ \item{x}{Object to test.} } \description{ \itemize{ \item \code{is_pairlist()} checks that \code{x} has type \code{pairlist}. \item \code{is_node()} checks that \code{x} has type \code{pairlist} or \code{language}. It tests whether \code{x} is a node that has a CAR and a CDR, including callable nodes (language objects). \item \code{is_node_list()} checks that \code{x} has type \code{pairlist} or \code{NULL}. \code{NULL} is the empty node list. } } \section{Life cycle}{ These functions are experimental. We are still figuring out a good naming convention to refer to the different lisp-like lists in R. } \seealso{ \code{\link[=is_call]{is_call()}} tests for language nodes. } \keyword{internal} rlang/man/format_error_bullets.Rd0000644000176200001440000000257613565177531016701 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cnd-message.R \name{format_error_bullets} \alias{format_error_bullets} \title{Format bullets for error messages} \usage{ format_error_bullets(x) } \arguments{ \item{x}{A named character vector of messages. Elements named as \code{x} or \code{i} are prefixed with the corresponding bullet.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} \code{format_error_bullets()} takes a character vector and returns a single string (or an empty vector if the input is empty). The elements of the input vector are assembled as a list of bullets, depending on their names: \itemize{ \item Elements named \code{"i"} are bulleted with a blue "info" symbol. \item Elements named \code{"x"} are bulleted with a red "cross" symbol. \item Unnamed elements are bulleted with a "*" symbol. } This experimental infrastructure is based on the idea that sentences in error messages are best kept short and simple. From this point of view, the best way to present the information is in the \code{\link[=cnd_body]{cnd_body()}} method of an error conditon, as a bullet list of simple sentences containing a single clause. The info and cross symbols of the bullets provide hints on how to interpret the bullet relative to the general error issue, which should be supplied as \code{\link[=cnd_header]{cnd_header()}}. } rlang/man/fn_env.Rd0000644000176200001440000000201513351410454013670 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/fn.R \name{fn_env} \alias{fn_env} \alias{fn_env<-} \title{Return the closure environment of a function} \usage{ fn_env(fn) fn_env(x) <- value } \arguments{ \item{fn, x}{A function.} \item{value}{A new closure environment for the function.} } \description{ Closure environments define the scope of functions (see \code{\link[=env]{env()}}). When a function call is evaluated, R creates an evaluation frame (see \code{\link[=ctxt_stack]{ctxt_stack()}}) that inherits from the closure environment. This makes all objects defined in the closure environment and all its parents available to code executed within the function. } \details{ \code{fn_env()} returns the closure environment of \code{fn}. There is also an assignment method to set a new closure environment. } \examples{ env <- child_env("base") fn <- with_env(env, function() NULL) identical(fn_env(fn), env) other_env <- child_env("base") fn_env(fn) <- other_env identical(fn_env(fn), other_env) } rlang/man/with_restarts.Rd0000644000176200001440000001022613604124167015326 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cnd-restarts.R \name{with_restarts} \alias{with_restarts} \title{Establish a restart point on the stack} \usage{ with_restarts(.expr, ...) } \arguments{ \item{.expr}{An expression to execute with new restarts established on the stack. This argument is passed by expression and supports \link[=nse-force]{unquoting}. It is evaluated in a context where restarts are established.} \item{...}{<\link[=dyn-dots]{dynamic}> Named restart functions. The name is taken as the restart name and the function is executed after the jump.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} Restart points are named functions that are established with \code{with_restarts()}. Once established, you can interrupt the normal execution of R code, jump to the restart, and resume execution from there. Each restart is established along with a restart function that is executed after the jump and that provides a return value from the establishing point (i.e., a return value for \code{with_restarts()}). } \details{ Restarts are not the only way of jumping to a previous call frame (see \code{\link[=return_from]{return_from()}} or \code{\link[=return_to]{return_to()}}). However, they have the advantage of being callable by name once established. } \section{Life cycle}{ All the restart functions are in the questioning stage. It is not clear yet whether we want to recommend restarts as a style of programming in R. } \examples{ # Restarts are not the only way to jump to a previous frame, but # they have the advantage of being callable by name: fn <- function() with_restarts(g(), my_restart = function() "returned") g <- function() h() h <- function() { rst_jump("my_restart"); "not returned" } fn() # Whereas a non-local return requires to manually pass the calling # frame to the return function: fn <- function() g(current_env()) g <- function(env) h(env) h <- function(env) { return_from(env, "returned"); "not returned" } fn() # rst_maybe_jump() checks that a restart exists before trying to jump: fn <- function() { g() cat("will this be called?\n") } g <- function() { rst_maybe_jump("my_restart") cat("will this be called?\n") } # Here no restart are on the stack: fn() # If a restart point called `my_restart` was established on the # stack before calling fn(), the control flow will jump there: rst <- function() { cat("restarting...\n") "return value" } with_restarts(fn(), my_restart = rst) # Restarts are particularly useful to provide alternative default # values when the normal output cannot be computed: fn <- function(valid_input) { if (valid_input) { return("normal value") } # We decide to return the empty string "" as default value. An # altenative strategy would be to signal an error. In any case, # we want to provide a way for the caller to get a different # output. For this purpose, we provide two restart functions that # returns alternative defaults: restarts <- list( rst_empty_chr = function() character(0), rst_null = function() NULL ) with_restarts(splice(restarts), .expr = { # Signal a typed condition to let the caller know that we are # about to return an empty string as default value: cnd_signal("default_empty_string") # If no jump to with_restarts, return default value: "" }) } # Normal value for valid input: fn(TRUE) # Default value for bad input: fn(FALSE) # Change the default value if you need an empty character vector by # defining a calling handler that jumps to the restart. It has to # be calling because exiting handlers jump to the place where they # are established before being executed, and the restart is not # defined anymore at that point: rst_handler <- calling(function(c) rst_jump("rst_empty_chr")) with_handlers(fn(FALSE), default_empty_string = rst_handler) # You can use restarting() to create restarting handlers easily: with_handlers(fn(FALSE), default_empty_string = restarting("rst_null")) } \seealso{ \code{\link[=return_from]{return_from()}} and \code{\link[=return_to]{return_to()}} for a more flexible way of performing a non-local jump to an arbitrary call frame. } \keyword{internal} rlang/man/nse-defuse.Rd0000644000176200001440000002140213604124170014452 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nse-defuse.R \name{nse-defuse} \alias{nse-defuse} \alias{quotation} \alias{expr} \alias{enexpr} \alias{exprs} \alias{enexprs} \alias{ensym} \alias{ensyms} \alias{quo} \alias{enquo} \alias{quos} \alias{enquos} \title{Defuse R expressions} \usage{ expr(expr) enexpr(arg) exprs( ..., .named = FALSE, .ignore_empty = c("trailing", "none", "all"), .unquote_names = TRUE ) enexprs( ..., .named = FALSE, .ignore_empty = c("trailing", "none", "all"), .unquote_names = TRUE, .homonyms = c("keep", "first", "last", "error"), .check_assign = FALSE ) ensym(arg) ensyms( ..., .named = FALSE, .ignore_empty = c("trailing", "none", "all"), .unquote_names = TRUE, .homonyms = c("keep", "first", "last", "error"), .check_assign = FALSE ) quo(expr) enquo(arg) quos( ..., .named = FALSE, .ignore_empty = c("trailing", "none", "all"), .unquote_names = TRUE ) enquos( ..., .named = FALSE, .ignore_empty = c("trailing", "none", "all"), .unquote_names = TRUE, .homonyms = c("keep", "first", "last", "error"), .check_assign = FALSE ) } \arguments{ \item{expr}{An expression.} \item{arg}{A symbol representing an argument. The expression supplied to that argument will be captured instead of being evaluated.} \item{...}{For \code{enexprs()}, \code{ensyms()} and \code{enquos()}, names of arguments to capture without evaluation (including \code{...}). For \code{exprs()} and \code{quos()}, the expressions to capture unevaluated (including expressions contained in \code{...}).} \item{.named}{Whether to ensure all dots are named. Unnamed elements are processed with \code{\link[=quo_name]{quo_name()}} to build a default name. See also \code{\link[=quos_auto_name]{quos_auto_name()}}.} \item{.ignore_empty}{Whether to ignore empty arguments. Can be one of \code{"trailing"}, \code{"none"}, \code{"all"}. If \code{"trailing"}, only the last argument is ignored if it is empty. Note that \code{"trailing"} applies only to arguments passed in \code{...}, not to named arguments. On the other hand, \code{"all"} also applies to named arguments.} \item{.unquote_names}{Whether to treat \verb{:=} as \code{=}. Unlike \code{=}, the \verb{:=} syntax supports \verb{!!} unquoting on the LHS.} \item{.homonyms}{How to treat arguments with the same name. The default, \code{"keep"}, preserves these arguments. Set \code{.homonyms} to \code{"first"} to only keep the first occurrences, to \code{"last"} to keep the last occurrences, and to \code{"error"} to raise an informative error and indicate what arguments have duplicated names.} \item{.check_assign}{Whether to check for \verb{<-} calls passed in dots. When \code{TRUE} and a \verb{<-} call is detected, a warning is issued to advise users to use \code{=} if they meant to match a function parameter, or wrap the \verb{<-} call in braces otherwise. This ensures assignments are explicit.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("stable")} The defusing operators \code{expr()} and \code{enquo()} prevent the evaluation of R code. Defusing is also known as \emph{quoting}, and is done in base R by \code{\link[=quote]{quote()}} and \code{\link[=substitute]{substitute()}}. When a function argument is defused, R doesn't return its value like it normally would but it returns the R expression describing how to make the value. These defused expressions are like blueprints for computing values. There are two main ways to defuse expressions, to which correspond the two functions \code{expr()} and \code{enquo()}. Whereas \code{expr()} defuses your own expression, \code{enquo()} defuses expressions supplied as argument by the user of a function. See section on function arguments for more on this distinction. The main purpose of defusing evaluation of an expression is to enable data-masking, where an expression is evaluated in the context of a data frame so that you can write \code{var} instead of \code{data$var}. The expression is defused so it can be resumed later on, in a context where the data-variables have been defined. Defusing prevents the evaluation of R code, but you can still force evaluation inside a defused expression with the \link[=nse-force]{forcing operators} \verb{!!} and \verb{!!!}. } \section{Types of defused expressions}{ \itemize{ \item \strong{Calls}, like \code{f(1, 2, 3)} or \code{1 + 1} represent the action of calling a function to compute a new value, such as a vector. \item \strong{Symbols}, like \code{x} or \code{df}, represent named objects. When the object pointed to by the symbol was defined in a function or in the global environment, we call it an environment-variable. When the object is a column in a data frame, we call it a data-variable. } You can create new call or symbol objects by using the defusing function \code{expr()}:\preformatted{# Create a symbol representing objects called `foo` expr(foo) # Create a call representing the computation of the mean of `foo` expr(mean(foo, na.rm = TRUE)) } Defusing is not the only way to create defused expressions. You can also assemble them from data:\preformatted{# Assemble a symbol from a string var <- "foo" sym(var) # Assemble a call from strings, symbols, and other objects call("mean", sym(var), na.rm = TRUE) } } \section{Defusing function arguments}{ There are two points of view when it comes to defusing an expression: \itemize{ \item You can defuse expressions that \emph{you} supply with \code{expr()}. This is one way of creating symbols and calls (see previous section). \item You can defuse the expressions supplied by \emph{the user} of your function with the operators starting with \code{en} like \code{ensym()}, \code{enquo()} and their plural variants. They defuse function arguments . } } \section{Defused arguments and quosures}{ If you inspect the return values of \code{expr()} and \code{enquo()}, you'll notice that the latter doesn't return a raw expression like the former. Instead it returns a \strong{quosure}, a wrapper containing an expression and an environment. R needs information about the environment to properly evaluate the argument expression because it comes from a different context than the current function. See the \link{quosure} help topic about tools to work with quosures. } \section{Comparison to base R}{ \itemize{ \item The defusing operator \code{expr()} is similar to \code{\link[=quote]{quote()}}. Like \code{\link[=bquote]{bquote()}}, it allows \link[=nse-defuse]{forcing} evaluation of parts of an expression. \item The plural variant \code{exprs()} is similar to \code{\link[=alist]{alist()}}. \item The argument-defusing operator \code{enquo()} is similar to \code{\link[=substitute]{substitute()}}. } } \examples{ # expr() and exprs() capture expressions that you supply: expr(symbol) exprs(several, such, symbols) # enexpr() and enexprs() capture expressions that your user supplied: expr_inputs <- function(arg, ...) { user_exprs <- enexprs(arg, ...) user_exprs } expr_inputs(hello) expr_inputs(hello, bonjour, ciao) # ensym() and ensyms() provide additional type checking to ensure # the user calling your function has supplied bare object names: sym_inputs <- function(...) { user_symbols <- ensyms(...) user_symbols } sym_inputs(hello, "bonjour") ## sym_inputs(say(hello)) # Error: Must supply symbols or strings expr_inputs(say(hello)) # All these quoting functions have quasiquotation support. This # means that you can unquote (evaluate and inline) part of the # captured expression: what <- sym("bonjour") expr(say(what)) expr(say(!!what)) # This also applies to expressions supplied by the user. This is # like an escape hatch that allows control over the captured # expression: expr_inputs(say(!!what), !!what) # Finally, you can capture expressions as quosures. A quosure is an # object that contains both the expression and its environment: quo <- quo(letters) quo get_expr(quo) get_env(quo) # Quosures can be evaluated with eval_tidy(): eval_tidy(quo) # They have the nice property that you can pass them around from # context to context (that is, from function to function) and they # still evaluate in their original environment: multiply_expr_by_10 <- function(expr) { # We capture the user expression and its environment: expr <- enquo(expr) # Then create an object that only exists in this function: local_ten <- 10 # Now let's create a multiplication expression that (a) inlines # the user expression as LHS (still wrapped in its quosure) and # (b) refers to the local object in the RHS: quo(!!expr * local_ten) } quo <- multiply_expr_by_10(2 + 3) # The local parts of the quosure are printed in colour if your # terminal is capable of displaying colours: quo # All the quosures in the expression evaluate in their original # context. The local objects are looked up properly and we get the # expected result: eval_tidy(quo) } rlang/man/local_options.Rd0000644000176200001440000000421313563535650015277 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/state.R \name{local_options} \alias{local_options} \alias{with_options} \alias{push_options} \alias{peek_options} \alias{peek_option} \title{Change global options} \usage{ local_options(..., .frame = caller_env()) with_options(.expr, ...) push_options(...) peek_options(...) peek_option(name) } \arguments{ \item{...}{For \code{local_options()} and \code{push_options()}, named values defining new option values. For \code{peek_options()}, strings or character vectors of option names.} \item{.frame}{The environment of a stack frame which defines the scope of the temporary options. When the frame returns, the options are set back to their original values.} \item{.expr}{An expression to evaluate with temporary options.} \item{name}{An option name as string.} } \value{ For \code{local_options()} and \code{push_options()}, the old option values. \code{peek_option()} returns the current value of an option while the plural \code{peek_options()} returns a list of current option values. } \description{ \itemize{ \item \code{local_options()} changes options for the duration of a stack frame (by default the current one). Options are set back to their old values when the frame returns. \item \code{with_options()} changes options while an expression is evaluated. Options are restored when the expression returns. \item \code{push_options()} adds or changes options permanently. \item \code{peek_option()} and \code{peek_options()} return option values. The former returns the option directly while the latter returns a list. } } \section{Life cycle}{ These functions are experimental. } \examples{ # Store and retrieve a global option: push_options(my_option = 10) peek_option("my_option") # Change the option temporarily: with_options(my_option = 100, peek_option("my_option")) peek_option("my_option") # The scoped variant is useful within functions: fn <- function() { local_options(my_option = 100) peek_option("my_option") } fn() peek_option("my_option") # The plural peek returns a named list: peek_options("my_option") peek_options("my_option", "digits") } \keyword{experimental} rlang/man/figures/0000755000176200001440000000000013407134203013571 5ustar liggesusersrlang/man/figures/lifecycle-defunct.svg0000644000176200001440000000170413405732277017716 0ustar liggesuserslifecyclelifecycledefunctdefunct rlang/man/figures/lifecycle-maturing.svg0000644000176200001440000000170613405732277020116 0ustar liggesuserslifecyclelifecyclematuringmaturing rlang/man/figures/lifecycle-archived.svg0000644000176200001440000000170713405732277020056 0ustar liggesusers lifecyclelifecyclearchivedarchived rlang/man/figures/lifecycle-soft-deprecated.svg0000644000176200001440000000172613405732277021343 0ustar liggesuserslifecyclelifecyclesoft-deprecatedsoft-deprecated rlang/man/figures/lifecycle-questioning.svg0000644000176200001440000000171413405732277020634 0ustar liggesuserslifecyclelifecyclequestioningquestioning rlang/man/figures/rlang.png0000644000176200001440000006236413351410654015422 0ustar liggesusers‰PNG  IHDRx‹ªb]e /iCCPICC profileHÇ–wTTׇϽwz¡Í0Òz“.0€ô. QfÊà Mlˆ¨@DE €£¡H¬ˆb!(¨`HPb0Ѝ¨dFÖJ|yyïåå÷ǽßÚgïs÷Ù{Ÿµ.$O./– ™'àz8ÓW…Gбýx€¦0Y驾AîÁ@$/7zºÈ ü‹Þ Hü¾eèéO§ƒÿOÒ¬T¾È_ÄælN:KÄù"NʤŠí3"¦Æ$ŠF‰™/JPÄrbŽ[䥟}ÙQÌìd[ÄâœSÙÉl1÷ˆx{†#bÄGÄ\N¦ˆo‹X3I˜Ìñ[ql2‡™Š$¶ 8¬x›ˆ˜Ätñrp¤¸/8æ p²âC¹¤¤fó¹qñº.KnjmÍ {r2“8¡?“•Èä³é.)É©L^6‹gþ,qmé¢"[šZ[Zš™~Q¨ÿºø7%îí"½ øÜ3ˆÖ÷‡í¯üRê`ÌŠj³ë[Ì~:¶ wÿ›æ!$E}k¿ñÅyhây‰RmŒ333¸–‘¸ ¿ë:ü }ñ=#ñv¿—‡îʉe “tqÝX)I)B>==•ÉâÐ ÿ<Äÿ8ð¯óXȉåð9€¢yPÜõßûæƒâ›¦:±8÷Ÿýû®p‰ø‘ÎûçLg ù‹kâk Ѐ$È t!0VÀ87°ø`ֈɀ2A.Ø @Øö‚JPêA#h'@8 .€Ëà:¸ î€`Œƒç`¼óa!2Dä!UH 2€Ì d¹A>P ECqB¹Ð¨*…*¡Z¨ú:]€®BÐ=hš‚~…ÞÃL‚©°2¬ Ã Ø ö†ƒá5pœçÀùðN¸®ƒÁíðø:|ŸÃ³@ˆ QC â‚ø!H,ÂG6 …H9R‡´ ]H/r A¦‘w( Š‚¢£ Q¶(OTŠ…JCm@£*QGQí¨Ô-Ô(jõ MF+¡ Ð6h/ô*t:]€.G7 ÛЗÐwÐãè7 ††ÑÁXa<1á˜Ì:L1æ¦s3€ÃÌb±Xy¬Öë‡ebØì~ì1ì9ì vûGÄ©âÌp‡+Ç5áÎâq¸y¼^ oƒ÷óñÙø|=¾ ?ŽŸ'Htv„`Ba3¡‚ÐB¸DxHxE$Õ‰ÖÄ"—¸‰XAàPð4Ð407°7ˆÔô&Ø9¸$øAˆnˆ0¤;T242´1t.Ì5¬4ld•ñªõ«®‡+„sÃ;#°¡ ³«ÝVï]=iY9´FgMÖš«kÖ&­=%ÅŒ:Ž‹nŠþÀôcÖ1gc¼bªcfX.¬}¬çlGv{ŠcÇ)åLÄÚÅ–ÆNÆÙÅ퉛Šwˆ/Ÿæºp+¹/<jæý$.$…%µ&ã’£“Oñdx‰¼ž•”¬”TƒÔ‚Ô‘4›´½i3|o~C:”¾&½S@ýLõ u…[…£öUo3C3OfIgñ²ú²õ³wdOä¸ç|½µŽµ®;W-wsîèz§õµ  1º7jlÌß8¾ÉcÓÑ͉̈́›È3É+Í{½%lKW¾rþ¦ü±­[› $ øÃÛl·ÕlGmçnïßa¾cÿŽO…ìÂkE&EåEŠYÅ×¾2ýªâ«…±;ûK,KîÂìâíÚí°ûh©tiNéØß=íeô²Â²×{£ö^-_V^³°O¸o¤Â§¢s¿æþ]û?TÆWÞ©r®j­VªÞQ=w€}`ð ãÁ–嚢š÷‡¸‡îÖzÔ¶×iוÆÎ8ü´>´¾÷kÆ× E ðŽŒ <ÚÓhÕØØ¤ÔTÒ 7 ›§ŽE»ùë7-†-µ­´Ö¢ãà¸ðø³o£¿:á}¢û$ãdËwZßU·QÚ Û¡öìö™ŽøŽ‘ÎðÎS+NuwÙvµ}oôý‘Ój§«ÎÈž)9K8›vá\ιÙó©ç§/Ä]ëŽê~pqÕÅÛ==ý—¼/]¹ì~ùb¯Sï¹+vWN_µ¹zêãZÇuËëí}}m?XüÐÖoÙß~ÃêFçMë›]ËÎ: ^¸åzëòm¯Û×לּ302tw8rxä.ûî佤{/ïgÜŸ°é!úaá#©Gå•×ý¨÷cëˆåÈ™Q×Ѿ'AOŒ±Æžÿ”þÓ‡ñü§ä§åª“f“§§Ü§n>[ýlüyêóù邟¥®~¡ûâ»_é›Y53þ’ÿrá×âWò¯Ž¼^öº{Ööñ›ä7ós…oåß}Çx×û>ìýÄ|æ쇊z»>yz¸¼°ð÷„óûÌ;¼lbKGDÿÿÿ ½§“ pHYs!7!73XŸztIMEá çD†« IDATxÚì½wœœWuÿÿ¾O›^¶kµ’vTmu¹ÈÆöbŒmLI¥™âP†„Ð[?z 8!ôB°M `ƒ ØÆÝ²Š%[]«ímv§—§ÝïÏÌhw5»Ú•E(¯ß}½$¦>Ï=÷žó9ŸS®àOlôôôL&=öÏZ’ÉäLÿôQ{ÿŸÊŠÂíé逬>6€s.«¾õ!àÀC Þÿ'%hñ§"ØiCM&“NõùMÀ›«¯™Õ{Ö«ÿÿðd2¹»ú~pj‚þS²øSlU  $“I»§§§ øàM@;àV?¢Tÿu hÀð-àËÉdr´§§GÜÚ"ùÿüûWǾd2Y©>ÿ&à-À¦ê[Ýš`¥”ÞM‹úm;€Z}¼øR2™üzõ{tÀúc·Íâ\¸  %“I³§§çBà ÀVÀW}«¬Ý£” j8¶ô^8ùî%ð0ð–d2¹³§§G«îf÷Õ6‹?6ÁN¿öd2){zzbÀçWLÛ' ÛvèË ¥dYw†®Öwt! à?¿еçÿm³øcÙ­ÕÇ"™LÊêã0ð’ê® vUÀ‚êî”\W’šÈ32œŸ±c;:"²¹5(4M¡œ­*3«êþæi&àÊ­$;WT'Söôô€K€OV… Nß½Š"pl—\®"‡‡²¢R¶Q5e† ¶m@—Q ûÐu×!éé@lðnà¾d2é̺ž?hA‹?Ô];‡ÛsQÕí¹ašÛcÔl¬¢„€l¦,S‘N—Q¢pÒ.B ¥Äq\âMAZZƒD"~„Ç‘µÝ.«š¡æV}øJ2™|¸z=`ÿ!«nñ‡(ØnO;ð>àµ@lºÛSœ®+äsR2™2–å0‡ú%hO Š*hj ÒÚ"4p)ë@lº›5Ü Ü”L&«DŠ3mþA Zü! wšÛc$“I³úü;€·+¹=ªªà8’Ñ‘,™t™JÅFQß–ªzjz–*¦¦¤”†FSS€ŽÎ(B€ëºÓÝ*wš/}øz2™ülõ: Àª©í?!ÿ¡íàénÏåÀ—uÓTäÌ‹Wé©£ÃYLÓAQDCáÕF¥b¡( †¡Í… =U/@3T–,‰Êæ– °mgºg'7%“É«L˜¬¹UBV~ßêxº½M&“.ïééùðk`Ã\Â5M‡£‡RôõNbšN]8 oRH óª®~Îfò…2ÊÂ3¼–éÐß7%òܹnCV •zzz¾Ä«÷0]5º;x·'¼ø×*"¶«–énm»LŒçÍW” R±Øº¹›·Ýø<>öé108YQÓG4Àu]²Ùr]»RB 5vUu·wDhi ¡ë* §/&Yu«Œ*ò~{Õ­JOó~o>´ú)ØÞÞ^z{{ééé‰DB©¹=‰DâU„zCu’˜.\Eض$“)Ñw|Š\¶‚ª*Õײ¹¯zÙe¼ñµW²{ÏqöìíGo@d”Ë6¦yÂFK ~ŸŽ®©Ø¶;ÃOöT²8ñÙ2ÙLUSÐu]¯8QG§úçÀ‹‰Ä`"‘8žL&íD"!‰„¨ ¹··÷OkÏPz2™´ªÏ_‰xq#·GU½ËKO•H¥ d3eE9Éí‘Rð\º}ÉûŸÆueC[ ÷ÝÞÂxëß^¦©üû—~A$ÀqŸŽ”P1-Îߺ’•+Û¹íÇà÷¸®;íRUA$ê§½=L8âöÜéüvý~€ ðà£Éd²¿Š¶íÿ+~[üví?UÉŠÎYÜ/RJEÁu]†‡²d3å::ž= … €1㵚ÝLËÁ2mcN,T*Þ†òù´:YR,š\wÍ9l;où䉄ý ŠëJt]%÷Ó¹4ZuÙæt««nÕGg»UT;xY!ªL”ÝÓÓsðµª?+O¸`r² G‡s¶çÚy BHÞú·×rË÷îgl<{¡Q1m.8o—]r6ß¾å×äòå9}ã9Á‰ª (Ër¯“Þ¯)tvFeSsP¸®dŽ5%cU·êžªVs«ÏÿNv²r¦ÛàB;{zz~ܬ˜Ë.VÊ6‡Ó<=§pkïB°´3ŽáÓ«¶væl:ŽKKK„s¶tÏëóÎ7\×¥ÑuÌõU®ãÒß7%¯k…9ÆJàîžžžŸ]ÉdR&“ÉnUOOÏs«Ä™lÕÆÖÜžvàõÀ'€‚­8¤Æ r|5¡NGÇ®ë¢(ʼ¨^ÓOµO[ÈBxÃq] ];éwÇ%ÔéZÇï×êQ¯Y–Õ9¾/ÛsÿX¨á®‹p{–WyãÌæ§OL¹d11Q 5‘¯’üÎ…;}´¶FX±¬…>D `œ–<[ÍÆbAÒéB Ÿì>M¥ ¼éõWÑÞåó_½« °Nä !êTg£Eé8’¶¶-m!ü~ ó¹U¾•L&Uå¢ÔB”T·º·'œH$^üðüi¨N«¥´¨ª‡`SE22—+ MSOŠÖcŸòùr=XqºàÚ«¶ðáüãiÆ0ôÈÚfËÆø?qô¤E=×"‚:ÈçM2é’çâù´¹Ü*x6ðÂD"a%‰£Éd²ØÓÓ£Öܪ†;x·çexu=µ¢­zŒ¶–.㺒TªÀÔd‰RѪªÉïk¸®Äu݆»m±T¥m»|úc/çuo¹›>ñeÞõ·ÐÞ;)kDQÙ\ ËrhЇ¼€* Ó´ ‡ýuU/]I0dÐÜ-­aÑ Z5=Nþk¼$ÀïWå¥OãH&“'TtÕ€«Õt™­À§€ËÐ4/¦ïÚl¦ÌèhŽB¾x¬i*š¦,Úvþ_ŒZ0`1££=Æ–Í+x|ÇQ&R¹9Q~#Û=—ŠVAj2Ï{ÞþB"áÿöÅŸÏPë®ëE«ƒöŽ0ñ¦@=«dZ¶gmƒÚÀ]À{’ÉäSUœ$«é½ˆê®­¹=ðoÀ+èÉnçÛ9¶dp -³Ù²p]` >ðî?£¥%›ßö´·Å°íßOýV-"ÕÈžÎLœ*ËqÜ:óµX®&,3@Z a_rñY<±ëXÃ…^ӒሥËbÒÐU1-¥wö(ßþ¡êåh€-¦ñŸ/®¢ãÖYþØŒ‘š(ȑᬘ~-BxäÃÒ%M„‚>ö:%É_K>_³ªƒ£½ã s—Ÿ)¢žþŸOç/^´[¿÷À Tÿ»B ŠϾl—_¶žÏùNLÓ>mm¥(¢ž64O¤ ܘL&¿×ÓÓ£(===g¿¾—sìL®7YPÈ›òàþ1†3b¶ì½LDÁÈhš#ÇF¦Ë4R—¥’Éõ/}¡¯!<ýÿ®+±mgN­ 8eú·Ï¼ µð ɪD;xçŸÑÖ­Ûé¥KšxÇß=ÛqgìNq‚¨RJBA÷?´Ÿì”ËV}N~£Î†-Ä×®Q¨½ÇR:0F¡`"Ý“‚&¢*ä0ðß===àÀ³ª[\¯!k!Šð‚ß}iŽž¹|…B¡ÒÀŸno2lÛ! ðÎ÷ßL¾P®&·Íd§²ÙR]…†C>º–6ÓÕÕ<¯Gïóé„‚¾ª¡š¾»öô’Øø6†G§<[ìJü~h$PÿáZt&SšWm/FÈ~ŸN<¬k ]×xÝ =\}åfòùò‚Ô‡ãHÂa[6­@…CÆÈP,š³ys¥*C ¸ø/˜ª¾XgÏUM¡\¶ÎpìhŠ©©"®ë²iý2^öâKêt_£:ÕÎõœ‡B±‚í¸´·Fg¤°zªÛeãúe\ÿÒK)MÊe“ž+6òå/¾Žo|õoBœäjÙ ó/ÿ ÅÊŒkôùtâ± >CÇu%†®±ÿàoyç¢ë*ŽãÅ㱯»¡‡X40Ç^¼ ®Å•k hïSýôö{šnßaš6Îîâc~1K—4’©É"GL02œ£R±gペ/7¡4 8Œçèëbd8‡ëxi)•ŠÅúõËxÕËž…mŸ¸®\ iY]K›¹îêsøõ“Ra”jÕ†³»¸áúË)+H Kb\tá¶_¼v^ÕfmÍ'-ÀZRmJ)ñù4:ZcõÇq‰F¼ñµÏ! žÆ Å ó%#,Ls¹Üqç.ßy ¿ßXÐg Cãàáþù³?ed,]Ï6‘Œ çè=šb|,ßhsiZ#K=1žÇ²NÑ£Ô|Üó«=<ôðA C«Sp‘p€·ÿÝu|õ÷šÌ/Xu9®l¨éÇ£õî¾÷IzôÍM!²Ù¶íR*Y§Tµ€û®éÖëºÆðHšW¾îK¤R¹únBÏ—¹ú9[8px˜ÑÑÌ¢S€¦k°pØr¦K¥i –Õ˜^UÁÔTž‡F3>í„Æ^¶T²˜LˆFýèÆLºSkx× vˆ‚b±B¡P®g2¨Š”>÷…;(•­¡ZMSÏ2>‘›—á©ý–ªNl‚gá95˜qžš¡ò¤”ø;v›‘W}ú¶ùäçò… ¿ÑЮEåü~eN„ímΓ¿XY܈“Hw)å¼;«–ƒ<].rún¦½SåVÔìðéº"Þg‡,•jÐlíPûÌ3!_\Wò±z ©Éšzúir–Ýi}›ÄK7­M¤;Ç*Š7)Wõlª»Bs ¦T2)+u‚¢T2QÕ䂘׮ÛK& Ñu­Ê{4`#!–J&…B¥¾(Ëe/KÃs]$¥²Ùp‘Ôž’Êe³þ!¼ë­ ?_(S*™ BâŽãÖ÷|ðVZ["uLR#VÞøÚ+ ŒÓvß´ÓQcª¢pöæë£R±æT›®+ }Üö“G|sª6]W¹ô’̓ï8J*•ãÚkÎáâ ×22–æ¦ÏýpFÒûÌßpY™hgÆå¬[»„––•ŠEïñqzè ‡ŒÎÈÛ }\véÙC>xð“S.½dçlMÐÕÕL&Sb÷ž^î½o_¿Ü ñ¹RrÙ³Ö³es7K—6‘Ë—xúéA~ý›§(M^ú×Û™JÙ½ç8¹\é¤ûö\)O$î·´D°,§úš·ˆuk:‰F µryæu=gm\Î žÿI6oºˆÿÓ_ãÆØ·ó7}îÔ‹£T2¹ú¹[ùô'¯gíÆuÕ}^@…Oå]ï½…‡>xÂikòÙϼŠÕëW±ýÂwpë¯à]o‘–®jÔ"?™áÖïþ–~è{hšZ%ûO ï÷¼ëÏxÙK¶³dŲª¢ynÿñC¼ç}·òí[>À‘ýxÅ«¿ÈÔT¾žT_›KÓ´ÉæòÄ¢zPÄKš®)$Ùl‰7¼õUbD=-Ó£-D¸¥²‰R¥û\×¥P,óÎ÷ÝÂèXMSçTgù|¿_?¥jqÉèX†x<̵לÃK_¼JÅæîÞÏ‘#£€¯á±m‡%KbEð±}›]{z)—-Z[#¼î5Ïæòçláóÿö®}þ'™œÊÓ²ËÐÝãoßxó7ÏæÎ_ìäž_ކϧñâ¿Þκµ¼ñ WqèÐßú¯ûê¬S¡PáSŸ¼žW¿ârTUð½›ïæwí²žÝ³7¼ùy(Š‚•O‘Í–(ˈY Ó´lV¯lç/ÿìBþçGÓןš38£ª ±hYÕŒgVÀ¥²É%¯£T2Ùýäq ]Ã4î¾w>ŸÞPí:ŽK<䥵{½ÑñÌœõ¸5ôgÙ.~¿ÆË_z)ÇzÇxëÛ¾ÅØXÇqQE¨¡ëûùÙí;øÕ¯ö29•§T2A€c»ôõOð¹h­¬ãÊ+7qÛ®òÝÞdU*7¼ê >õ©ñµoü’|Þ³ÿ?ùÙþó›ofãúe¼ã/àkßü%Á ññ,¯zÅeüù ·!¥äSŸù _úòÝ”Jž½¾ûžÝ9:Ƈ>ø—TL E\Gž„¤+  V%Úñ7Ð|0Ãl\Sº æœdéšJoï8CCSõlG!<>u.¡å ^ñ²gñů¿ƒßø\tM=¥{ãÚ.>ŸŽß¯óî÷ÞÊCd³EŠÅJ½(»‘v)—-R“¹ªª÷ ø‡ý<ùd;wõ.Û/Z[§ô¤ë¥Õøý:;wã+_»§NùéºÊÁƒCüïO£Xªø9gk7¥’I4àù×G<âɽýÜô¯·×ñƒahºÆ¿þçì{jгծ¬.Ê™~©GZ óö÷Ý̱ãc'¥îž ÿÔzTLkaAŠ…ÀøÉ©<™lqÁþŸ®«ìÝ×Oï¾ìØy¬z£r^Xî¸.þ°Ÿ»îÙM_ÿx5Ýgaܶ<ðúk„Ã>š›Ã47G<“ì¸tvÆßåº5àçç¿Ø5i{ÀÆ`×®^J% )¡;ÑN¡Pfýú.Ýmh~o'‰®k3B’®”ø|:?ÿÅuS¶˜¹hR&Sâ•/ý¾È¾ûŠ%ó” d^m;.Š‹Nš }ü*¹U›þpØÊj…w¡qôè¹\yA.À«"li sÅåøó]À%Û×Ѻ´0•)r險5pôÒéB@M%O¥‹8ާþü††m;ttÄim€¢òÄGçR>_½v9÷’–rñB`Ú&¿T…Ë.9 ˲Qeñ®­ô Î[Å¡##õ¨Îì57¹! t"?¶ížr5Ÿf JÅ ¶íÌ›ÅXÓfݺNþù×óœk/"3>Á£fðŽŒç¸øâµ\²}Ý¢Ù)Ý×åJI0hà÷ë€`"•«fiȱT´Í©Bªµ Ë:×àJ¢á_úÆÝ¸Ròà# ø Êek^–`ÞlÙNÃ:ŽK¡h ûç²ëʆDÃÂ}êá8.­->úá—ðœk·qï]ò…/ÝÉ®]½ŒŽ¥)UÆùÐ^ÇeWniHáÍõk¢Qœ¹êbÕ²3Â!?™LqÑ÷溒HÄO0裯o‚`Ð×PÈŠ"(–L/ý©êÿ˪ xro?¯¿ñë€déÒftMe|"˽jÛàÚîxâ™»·½-Ê žwùu·Ï”§eÞ´i9Ï»îB‡¼ù³)^AKs˜¯áõ¼ã­×±jeGà àeX–¹âÒõ¬J´Ï`°<Íh‰ÅB¬ìngËæ”+ÖÜEsóݘϧÍ÷MmÜEnzæÂïrhšJ"Ñš†š"ôÕ›ùü:Á QÕ™§¿è$`*‡ŒÐ?Â)[Üðê+(*ø|Zy2 B¡Ìó¯;·ÚŒíä©Õt•s¶t“èn#à׸@ ¶í°2ÑÎg>q=wÜönLÓF›ô“õ$ûò𣇠|sιv:7=9•çž{Ÿ$:A@Ôlòó®ÞÊ¢TªüN#?5Ÿ\ššBÓØ4/OyÓ†e\ºý,ì’É3U*º®qìØ?z˜ ¶­æ²KÏæÕ¯¼Œ[ÿûª]†T*ÇûÞûç¬ZÕqo\ó½Çdz<ûº ø8phxÃU{Ÿªª Oñëß>]ï^0ÃL¿×}À™.ZÀ5¾T×µYåÞãß>|JÙZ¼p²ë§Ër8tx3_dýÆeüå_\È-ß½Ûvik‹òñ¼” —Q(TÐ µqÐà”—ãå¹RÒÔæ«_»›Ë.=› ¶­â_?{ÛÎ_ÍÏîØëJ®Ù¥¼ðç³sw/œ¿Ú+£ið½yÆÜìIô®ª*<÷9›)—,~~×NÞóÁï¢(ÃÐêö?ò±fU SY ¾Y°€ky»ëÖ.Áq$ÇûÆÕÒP)[‹ß"‚j½mŸOo8Ù†®z¶Õ¯Õ}í}O pó­¿á5¯îáC½žW½â2²¹2[Ï_ɮǎpË-÷óÒ—lgÅòÖ?¥ˆjd+xR½Pí·EŽø‰DèºÕä½|¾Ìßÿ÷ø—O¿’­[¼æWóš7¾pIñå¯ÜÍCC\²ý,Ï{²®ÂÝj’œ”nÃYÇq¹ã;ÑT…`ÐW§€k žã¸47…¹òŠô¤Î¬€kQ”Ë[øÌÇ_m9¼émÿA&[<#‰ë¶írß}ûÈåJìÙs|Vî“Gð<4Ì÷¾ÿ^IŒD ÈdŠ|êÓÿK:]à‚m«ikb[6_ÿÊÝ|íë÷xdÉôRÑjXïž_î!•ÊqðÐð,åá 2›-ñãÿ}”h$@ïññz¼aèï›à•7|‘¿øó‹XöR|>tºÀcá§wìàíŽí`[ÅB¥ÞPÍqlÛ·^jzÎv­>ùÄokôöó¡ßF<\p޶èé鹯æÈ)%ž›‘{äQo.]Kšø×O¿ Ë´¹ñß&Ÿ/Í™W<Û[H°=`Û¥²y²Š—g-§µB`Y6–å°jU‘°Ÿ\®Äñ¾ /Í(äÃi («í …sâ/9-ÅS̺/Ç‘ärE¤ô’ùJe“`µ¥Ó§>þrÞðú«Hþz×½ðŸio1<2Å÷¿ó÷ì{j€Ï|îv¢s´ejL)—-"‘@½=T#ÿ»Æ;$V6£3JvîÕ:ùŠ ¤yû{¿ƒ[½ÁF*º®ª«m}gçË9ò°š›Â|æ×óÃ?ÂoœÐ¬ rÚwL¿.MSÑuÃGF¼‘t ]×ðùD5wxŽÆ+¤85¾Ì…¡ÒÜ®£ÙPȇ߯3>žãš«Ï!—+qøÈ–ãxé>~ƒ;ïÞÃÀP CWçL˜­1W­lçÂmk¸ù»÷ûg$ .ØÅ[¬­šbd,]OˆŸË†]qÙzÖ®YRxÔzq4Â^^[Á"ÿôÑÿá¡GhmX[½³åu¿)ñ×v—n? MSfÀy]àOöWŬÙh’gζ½xr±hbšN5Ó{ÏÀÀ$ŸøøËhi‰P*™üäg;ˆ„ü^?€ÁÿÞþ?qMSO™é¡(Ëv8oëJþá-Ï£P*ŸVÙÌi¡èSý×TÛàמÇà©ýƒhšJ `ÐÖáð‘цß!%õD¼Å%Š¢P®”ù«?¿£ÇF«“(ê=0ΔKîµ>4ùî-G¥bóý<Èž'û(ä+,]ÚÄ_w%Û·¯CJ¸÷¾}üêWOÒÒ©/ðÅxŽãâ34~ø“Gùþ¢µ9ŠÏåˋۓ ±Ás­p¥j› 9Ÿ/cÑH€t¶ÈÀ/<ûycßÓ ³@æ»áFUòÓ'*]@‚H$P§Y»—·pÞ¹«øÕ}{½Xñ´ë+—­*‘sêáUZ8¬Y³„ÏÝt[·¬ ÒáÄ!/’R&ÇØx–_ÿæiþîmß"ö/šª­Ñ»†¡Õë†UÕ+BèhÑÞeÿÁ!f -ÚŸj±I)iЇ8wk‚äýOÔXQŠà IDATEASS×uq\¯Bî÷ì&òy͸±`ÖÙu%í1š›B>:J£ê:Ç‘´6GÈzëÇvhmrñ¶5ÜÿÀþº€Ýj9ɳ¶ŸÅ¾ýƒLMåçÜ]5òÆSû÷ñÖ·}‹ç]s7.'ñ£* Óf` Å=¿ÜÃ]w玲-:o®Z @MÞ»R‹X·¶“ý†ê;Õu½üôѱ ƒÃSøªI~ÏHE×6¥Tµ* yâ_°Ç‹ 3Ç Ô.Ðgè¼öÍ_££-ÊøD–ðLäд“‹éTÕ«á­t{ „ÇóÙý¶ë…Ñ5•l®DÅ4 ü´¶Ö’çÄ<‹Ö¥½-J©lU¼c€Ým|øÅ;ß {Ÿ˜ÑóKÓ”9Ó£æ5©‰Dâz¼s¤”E|¶€iJlW0‘–ËP¶À´À•àJY19Þ7 º&PUï¬E¡xE=üæ¹åŠYmÍ+ecS“yž|ªŸt¦¸¨Õ«ª >Ÿ6 +ÂkñðÀC9Ú;vR<¸6™ù|™·¿õ:vîîá-¨ªJ0h êÝï7ˆ„hú©T­JäæoÞˆ¦©<þÄÑz)J>_á‘ÇŽÐ70Ѩzp’ “,âMÙøæØI6X’‹VŒ£Ú6+—©T\ÓŒMJ&2’qÈ$#“’tÎ%† (•A×<õ©kÕƒ-TOðšzd¸ÕC/d]#Èúós±–®ëQugªï‡w&ƒ¦©söºôj——p´wìŒÖ.ׯ¦ ËIM枪§>¹Rb[ºÞ8ÅévÐO꿹`ì¸póÝÛáη9.4Eð²«`i³ÎÖu~Ífª(éóS2Ž «dò’1‡þ‹á”CÅrñi¿é‚DUNìpwxÕ wèD±kmÕ6l~·Ny.ßv¾nuµÊú£½£sºƒsúÌ ,(r_ fäµ)B4¼®Ú‚‹FÜø†çòƒ?ÂÄ)¾Íoƒ¥g‡ëqÈi³˜Ê¸ŒMÁƒ{À•.Žk⸂XÖ®¨ )¬X"XÒ¢±~¥N$$Qðk‚D§ÀuÇÇ%Ã)—|IA:S9É‘!]ÆÒ.éœK®$©T¯íH\×[á®ëiוÈúù„5õ7m‘ÔÀbuÁÔz,&²Ø€‰¢x«v!Åo ýn! ò1•. é*K:âU[¼°J‡9AV5yaÆÕ ÈT0´iäàH8ÐkáJÉý»<¡8Nõ»Ü[MÕ- ,k÷Ñ3Ù¸:À•øY×íÇA%¨;øCý:.‚rÅ»SÅ-21Y&ð12V d *¦ÅxÚCºƒ£Še—bÉ¥P˜‡rIR( tEàù èªô8jQk(3›![<7Îy˯Æï×øÂWï&0fº\±ðúŒæ¸^ÎÛ|(^ÓT^{óùçÏþ„L¦È?¼ç;„Ãþ ":\×Å´œ*DÕ²ËF7êI:P¦1EbZ¦'ì² ¥Š``¬¨Ü–Ìã:¹ê‚òºàw¶«´7AG[ˆÕ+tu…YÝa³1!Htéê!":lˆhà–A©àÚ:CC%§,&G³¤ú&]®¤P²yèˆN® ‘+¸‹¥ŠÊä”C± š® )¿Ï‹îb’A¤DÓ”zôi¶ ÎÝšàÀÁ¡zlØË± P1­99וT*þØhi‰ ¥¤¥%²(ÊR;µp%ÑH€¥K›9~|œrÅžS5H ÍMa2Ùâ´É‘s„º»âÕ÷ºõ•­­š»æìÍkøÁæ7”ËCø}*í-+—Œ±bE„+. sÍE~¢‘n$Šª†åIÚZ‚t¶åQ·-‡B š"`Yà¨dÓ&ãYÌH’-Èg-&&]Üå/1šÖØu2Y‡HX­ïòÚý¹spé±XÏ}鸮ÇÔ¸×u‰FCüàæ·qÅ5%.‚SS9Þôúç°cç1vì<6'O/„ ­5Z'”Û¹h†›Tà ©‰µs²¹/ûëKøáO?ÂO~ü#£éÆé(UŽõÛ_3ý)ñÒeü¨¡kŒ¥RüêŽøÍƒÐ5 §jk¥E´6‡Jé„‚*ºî©ë Ø{°Ìowxxw™mg›, —¾Ârq…«ù°Ý–Ã,éØei*ø4qÝ¢£C¥{EÕ+‚lY¯ð¬m®ºTãÊ‹5^z]ˆPS˜ƒGÊTL ˜–kdšl°¸ý~ã¤_/p ÙñÄQzû&ê IUUÎIW3#ç'–NuÒØMšWÀu¿Ñv:>ÌC¢4G¶Fíöìë«ÇYçÔ R¢©:»ŸìãÁ‡VÏ8˜y¦iÓ70Y‘ž¨ÍQ”*ÐŽ £w=èpùvƒµˆÞÑRÁ­TÐâapt„tPt²\%ˆã\)°Ë`Y:¶D‘’@8L4$hk‡k. ðð‡ .=ßÇ*T•Á1*$º¾ðLŽãräØè \Ó&&r”O#û¥¸™.øûÁ å¢ÿP†" d ž}N…›>ÒI[Ô Žæ#¥…ˆb,”Jµ¹kl(ë¢F:¨êGj%Œ¶8åÁqü+[H?ÞKpe_[ B(ØCø•QôxˆÛþ7ÏwïÓyâi1£3ÐïsÌç/ŠÕšf>“!„ ½-zZtÛ|ÈÖ•0$=í㊗§Ðà •L§T@ñÅpMæSQbq¤+Q¢Q¤ì@kÝ„,]1´¶8v¦H`ã6(‡.ëD öSžšBt.í¢"–ð’ןÏŸô3|3ß»)ÆÆõ¾º+wºc¡ IÓTR“y>öO/æ]o{w”Á)ÚF* ÜgÒ7Êë/¡óù›þ†Ë[OÉÕÎå2Ì­ò=×ÇvàÎûm¡0®bàØ6ÒU@A"MP ¡«`™¸ªŠZŽ߀â_…2G ¯EhQ‚>ü±8š Ô@-•(§Èw¬$“’\ºÖá¾ÿéàM×Ç0|:ÓEQ³è½ymo‹Î™?Û›ñûu}ü»÷G=EÆS‚¬ù&{q›Ðë‰üÔÓï_ô.W¼£æÚZ¢ŒMdï׳Í÷<àð®·¶Pœr0‚*vÑ© 4óx?Âè>i¹XS£(ŒcçÇ ”G6“- 0¢(Z NÑE Çq+),TÓBU5ôX[—TR%.»ÀÏ¦Õ ýÃO* (ÞäËù‰UU(+Üø†«1M‹ÞêA!sMOí0ÍÇwãÀ¡aGž&Èj4Š%}‘¼°”’þÔ‚XœF„º¡kõVû Q¤&˜L»|à-¶­.QÉWÐãM`Ú¸å2"?†ÖÞ$Ò’PÌ µtaN•!ЄíÄp²9*éZ8ŽãN !|\éChì‚‹ÑÞŠ3™CæóhQ?BÑØÔYæY—w³jeŒÇw—O[ÄÂJ]›s+‚L¶ÈÐÐTpZ›üúI9ÕgDÀŠðVåÕÏÙLÿÀļ»XQʬ.9^©£8¥*ÎdKõKMà'JXtÀQÀ²$W\æ#¯“ˆ@#Åu ´H;šb „šq-Åœš@ø|hñvìÉ,j|Fl ª¡£–²££Õà¸W`Pz¡æ)§,ôæ8J¼“òp·"`i‚ 3ÎE«S\~… *]î|È!̧EUU0<œ®6QDm6ws XY¸½E¹õ[oeõª%õ u#Ûâ8îŒíB(@EQ˜œ*ð¶7_Ã’%ñƒ×‡Z“äw\AK|±Nl7B¹`€ÚŒS.aZWõaÛ&Ц¢k9:ŠpuŒ¶Õ¨š7—B D1–¯Dd¨ì½“Jÿo¨Œ=Œ;ùÖÄa„¢£”m”ôª¡¢ˆmÁÂ]tŠÕbv°®2ùÜ—îœÖŸãä/µ,‡çôlâÙ—odÿ¡¡E€*‰¦ªŒŒe˜Hå‘r >CplÐá ׯE‘1œR…b®€ê×ðÇÂŒ?ú°@¨6¶«“;| Ýo£è6B¨îCo‰¡h!,7Â@_v>z|ùÁzË2"«6Pœ(’Ì\ÑŠ4Š+å)CG1Gq­IŠS,ÙÄ9›uVtØìÞï/‚,vÄãAº—·2<šžs!<ã<}5©ª˜s7yl"¼íÆkù—Ï¿ƒU‰öEµÔ4…¡á)lÛY0r¯µÛ­T†ŽÂÉ Ü®o jM0y| T¥a쉃0ð(ñ•ËQÂ]½ô¾' ­½ÛìÀ˜Ãýè«‘¶†]‘¤ŽOhiéX(øðw¯CQšp#‚M×]Jy$‡í†´£7·âÓ'hkÑxÉVÉM78«ÃÁ§¸H)¨Øó«íZSÞüúçò™O\Z ÖO dÍ÷Zí`HÓ´9rà(÷ܻӲÜYJ‡ü¼ú—qðÐÈ)ÄkGÈ…ý’w¾¡“^¦bEÑ„Gú&ËDZÂ(ÅÁµWc—ø–­A’Rïn²c)Â+V£(erýL8J|å:=Hql˜`[ ͉.\"”ûÇ vw“›,n‰’=4ˆ?¢ È,"3Åñ»î'¶¼É)?j¼ i©”óã,UÆxÑÆ2-¡ k;m¢~ÉxFP¶EÃöP³CÞ¿}ðwÞ½›ryn¿w®¬q†‡¨F½oþïßR6-šã¡e.ž°¦^™ÆÙë–bø´j•Ã\D<¨Š@×àœ-Müí+¤².¹Á>JÑ Ë|L Žà¤ãè­ë°Ki¤¢Pœ'uà :V(”&'q‹&V©D¸máöV\ËÁ)¦;|MLbe'zQÊcõ?…31N.´-,±Ši¦ŽMlh]aô%~:Z‚sRZH"¼©&r\«ô2ÑŸ"½L£½yw>iP(–æí@T{%5™?­£r~G# ÐÑ;¥põjºšW¯EÂû>ôߤR¹†½ •jZ0‘¶É]^yMÅìǯO¢)J“#HÕO|Õ:0ZÉ8†ê‹¢ÇZТËq,?–š }ùHe9½OfQ)#ì~ŸÉ®Ûƒ/Å’A´¦e„Z;<š!5­ëÖ£ êl£œ¶°Maøè¾h3é#£¤Žäpd;–/­8ò› Ê•tŸE¹m-•Pˆ­küt´P«Üú©Y,åwÓít‡;;c`Ž‘šÌûOtL­ÚaÛv禅œdi›à#oicåÊV®Þnqð‘ÃH­‰U[ÏAvêCÓ+;ºˆ57ce0üAÆöDMÑV±‚B‰‘t˜¶Iˆ·K¤ªtótmZ]šÂˆµ2yhŒx÷:¶ž…[È`ËLìî§eãZ‚vU+Ò{Ï“V'hY¿ ÍÐ9~×ýøbYVœ+ñEŠLöe˜Ì1–5ɸ}” mŒO‚®Czé”Ñ#:~Ã%Ô¢’9v”¾û¢kŽîÓq‹&#»s æTÂa—`›Aw"ÊÕÛuÞôò0›W¹Üýˆ‹ß€Óö3†¢ÏHô£ú—#%GzǦ‰>wן¡h}’î…k·æ8»%G!oíj%ÚÚJa¬@6'Q´/`h@A ù±-‡¿zñY8ù>îx€ì±Çˆ‡†1ÜAÄØavßñ tEÒ–XI ÇÊæIíÙ‹“—Äb>üáGwô3vdW]JtùYôí6yô¥uËyøÚºpŠvQ%Üf奨¸­ íI#Ãít\´‘5k—SrhB%dUˆéE¾w{|Ã&k YJ¯…ÃB=“ÓÚÁ‹ñ»kg4Ì.æªõŒþUrï¼Ç® Å’Ãs/_É|ú<^så—Ÿ«ñÈ›ö¶0®k09^¢km7•²EkwÒ´± ôXDˆHs;8ŽOsˆ/i"Ø¥iÙrFÇÆFòœsù:TŸÀ̤8úàN,:Ï=Û2(<ð£ß_gåùk°Í)49ÊÀž^Ö\± Ÿ¡àšvܽ—ÖåÅ\Ž_¡8i’Θ¨QŸ_ÅÓЕ<:¶Y"Wiï ³f¥ÃÚeÑ0ì>(0ôùÕ±¦©\|áZü>É©|½9û㢽ÐÖ‚j‹Å;µå×G_ªá…Æ)í‹ß¯òÈý f:¹æ¹›pì"kV·¢*e['•©ÐÒê§¥-Àh_ MQ™Ê¹d3YÚ–6‘ŸÌ"ŒVIoŽEȧÊLôö’/¦hm69Ö7E45Œ-Ut%G9ÛG¬Õ myÅR‘¦`™ô˜K ¹_ÇRŽíK¡¹i Ù,›¶-Ãg„˜*µ35[7Òº¼«((gHfG|´·Ht,RÙ OìNÓ?'ê«Ð;¬ñT¯Ž¡UO,uÔ"¼ÖJ=—mà3¿ž—üåÅ|þ+w ùp÷̨èZ‘×¹ç¬db"wÊ.k5[j[NÕhÐ1vª¦Tr¸d['ÏÞ:AÐ_&‚ÑÁ)Žî#ÞÑÆªu Œ` E· 5 ‰jt,iÁ*8²ë+V…ˆ/ д¤…ñÑ»~’Ö¥Vn:›\^gÏ#Gp•&–n>Ÿuçob`ç8NEEÕÂ1Ï7/ZQ„¯©7Ñܵœ¥Ë[ë+£;püKpÃËi :Y*9_$Bß±¾`Ëõ±kw‘ǘ$WÑiK´Ñº´™x[”½ý!tÕkÊÚÚaYWóIO×UŽå—÷íåÖï?€®k§TÕ FÑ^9G…[¿õV.Ú¶šŸÜ¾ƒwðVâñМ?âV;«ÞqçNã´8U! R8Ö—%èo"h÷âøÄZû¦°I8¨R(º¸v‘þ£“l\ºŠX“ˆ0ÖÛGkgìŠj128Lvbœå Í­*º6ÉãOŽsî9 â-1*¥1´ Ÿ²]Á×´‹fìJ™\É¢\*ïôƒ9‰YGfY±a)c})\E'Rª¸,]·šƒï$ØÝI¼MÁñ•9º/ϳ^¼„æ'ÞdÝJ‹ýÇMÞùïÙd ^’^6Wæú—\Ê–ÍÝ|ä·aZNý˜]×8v|œýÂÏÉf‹õã€Îˆ öÊMnþæÄb!:ÚcÜôÅŸŸÔí®‘ u];mÂÜu!S¤3pÑÙWl ¡ C­°b¹ÕNqÿ¯÷Ó5iŠYÄÛCR)öí¦½I€´E‚òwo]Í9B†Ck‹Wi_¬øÙ±Óby‡ŽO±1‹e6¥’‰/&36N[wÁ€àø‘AZVœMÓÒ5¸"J´¥‹#;1r¼ŸuÛ6 ¸>Â-Q†çÿó(ëÖÚ, ¦ië iR2Èo ò‰oÃ?}Å¡wH0>å•þ(Š×l¦o`’G;L¾P9É ªªB±T©ŸôvÆÂ…¢*œLå9km'ÿø±ÿáXïøœ‡3ãKÃæU’G¾R᯴¸|s™ŸýèiâmKˆ´t¢è1\£Cû‡h[ÒI´­Ë{ÎQ9úÄ!$mÝíè~]—¬Þ°„Ñá2-«ÎÆß´ dŸOci{Œ#Oõ³æâͨšƒƒBKgœ÷ìféêNüäÈOæ(5²ã9ÆGG‰G|8f…þýÇQD™Î•-äÒi„[$_´)ö±jó ÈI¬´K¾(?4I®,ÊS*8 å|LfäŒQë?½ž¹QØvö†yÆ®ÕëìØy”ûÂ/8Þ?¡k3Ž£Ó4•ÍW0:–yFBµ/€oè ÏÚäðœ‹#˜¢W‹³dÝp%{ÞKâì”rYV¬îâéÇ÷ÓÞêCS-tŸÊY¬áÐÞaïéeÅÊ(®£à:.þ€Aïþ!ZºV ù£Xn_À¡2ÚKÇŠÌBžÂd«"¡lÒ½mé)ØG÷ª‡ŸzŠÕ ¿Q$à/{…qV‰¦á ÀÐB é‘+7tcëÁÖ Z´™;DKWÝ«[Ù²9Ä^D8‚Ã}.‘‚eKlûôß8c(Z×5Âa¿W&§“‚Î%1þùc/ç—÷î¥P,/˜ƒ.–½UÇ…XHpÅù~®º0Àó/ °y}g¯Ž36VF wò¤óº×¯el¼Èž„t…Õë—ãH ³¢22˜f¤w­¬¢{íRTÕÇѽ½ÙwŒp<βÕí|pÿ2ôôn–µ 5GPqúóãŸdÍ–Í4¯[Kv|ŒGï{«" fY¿©ï~{?‰ ë°ˆÒÔ&ÒÜÂ}·ï"ÞAÑu]¡{}·þç>L©°dYaZ¬Z×ÂØh»nÛ‡j%• ±4nò¶×®fí2É‘A—ó¤zå†À³lbLëý;O›­ù››ÂL¤r :»¬/Ù¢³®['œ³VgeW™–xŒ¦¸©hŒLJöcåò&:[|hªM:cqÏ}¬IÄÙ~n;¶i²c×c%V'üt6«¾ ÅB)m¦&+ gü´¶Gik €ªòÔÓ)tÍ$34Âù-£¥½‰á‘ Y[åéÇŽ²þÂsñ tE²Çaš› ûìv&†2´.‰rxÿ$ÇöNrÍK/"U(ÓÖä§ïPŠRzKž»’©)Ë´hoSøÅ­ûÙrŽkÃØT™¶&3] ‚Ÿ¯>|·Ý~Wñ/¨AKÅ´yÓë®â‹_»‹pµÑË3j£´ÐX®¢(L¤ò§®RMÃU Båï_¢±ª«„Ϥr~zïçmRXð „" ‡$ù©1­¾C‡S$–ª¬éRybçq|‘&Œhˆf]E‹†Ø}`Œx\!ÖÈ™ E[G¨&ËÚU\acæÓ\º­‰;~5@…£…0©>¤‚S*Ò¾¤ŽÖ8º01ü·ý ¥{uœîUíK6Ë£”iZ;¢þ(ñvM•ìx`€@SŒ%KC¤Ó¦„NNpŠ–¯ 32T¡ì_J*×ÁïDh~KžZ=WòÏxòTY2gÍ>a»VÆYûWž*.–Ʀ$ï~I‘õ]ˆJš\:E6=…ªÁÚD„xÄ%4‰hyÎ]çã‘]#¸å,KÂ6¬°}sŒGŸâа¤£ÝÏYk;ؼ¡“üd–±‰4ŸWúøì-&R%R§q ôI)ÂúïÛÂïÓ6Á9Tå©çªªõ¹rZ{{]‡M+]^zM/¿Ö༳rí-1–†î%MŒä–´Ç±¦2Ó9HÓ¾j %e -­m¬]³ŒFZ%ô@¬$Ú¢3jóÓÛŸöz,ã¬9;?! Jnúæ^6tkœ¿!L<æ§%`3zµ‹ÚZµJÕº‚,‚?–I[B²N˜Ì¾9s¶ßöýÞ?ΙxZÛ¢xý=ÏVÇ:Y‡ÌP©G'¤+¹ç»†ŸÜ¿ƒ”gíºïÎÕAÎxšß¬èKbE_Î`ë³_¼}šOüÖRºs6㳂Z­i(VþîÖ#\~ázN9¡·NÇ’r ð,Á=›÷196ÎMo:Û6ƒ*ž Ÿøú!^»a'¬í‡¨B‹ Éx&·ß7ȳ‡K¼çÆ3p-Hg\Ûààþi¾vÇNÞõ–³H¥\¢ZD&Q¢ù§ÞÌ)§ösþºN´4ð\›Ã£Uî¼{7½s# 1žk ¢Kº|øS÷ñ†MKÙtþJâ8ÃÀ2$÷Oðùoíä¿¿ó4²¦f¢T!ˆb²))Mî½ÿ0íâ­—ub‰m ¤4I´¦jŒTŠéÑ"O>5EÙêç+w)¢X¿Lž¸®xÛÚ<-i=V‚ïd­\ÝÁäd‰Ùé •JÔIÏј»vS M‚šà¼ÓŸú ¦#mãÊ´>y.IDATØ6µ(ä³?Åu4o9¯%m½acceö*±eOåHN]™¦TJxóݬZ²}Û“¸®C¶Åâñ½3<7\¢«'Íï¿s‡'ªôg Ò¶Ëc»§Y±$Ëź82Y¢³Ýf¾$‚(Vœ}jóóÜ6‡âÌ–e°}Ï(=}9:Ò’$*bY&å‚æÎŸa¼*9uU;…Š¢TèÈFÜùÀaÊXR£BE©(ˆDZ1S†©Šfÿqjµ„´gÐÚbqÛýCËÏI84b6–×BYhK0TŒX²Èaãé­LÍi ÀvÒ¸–F EP Y–5Ù¸ÂåÁ¾:u»yœEZ-ìb´Èu¤éìLQßÑô¼Û MÀ](” ¾æ]$‰¦»»…l›ÇÌT™éé aP/ø E¥4Ç;.U¤=Òðæ mNÌ]Y²¨•§—I»š\Þ ‰d¦aŠ„SWØ<~8¤¯Ëá’sºhëLÑî*vìæáÇ‘$š×œ´ˆþÞ4m꥘®qëæa–õçXj§q Ŧ³=Ö­.rû½{X·n1ƒ–Œm ®yý ¾ø¯»yv°À o\ƒe*l3`h¢ÀX¡Êôd'­-Ùtă óà#üïºE&Ž’R5¡6'›*0WÌÍΡ“˜H›( ŒcÖ,ñHYŠáñQÓÞž¢PÑœwV/c…€Ï|mËz a`èL›A,\<3dj^ðÇŸá¤þ K{\ Y&6<æ ó€çšÕ ûÆëVÂà(”ªÇ¦_Žcê\GJt´§´ãZ¢i7•bê[:ZLà俆šŽ…ÀJ…eôöµÒšõ˜©0>Zdýº6–÷âW§HbºKý‹[fÉeà¬LN8Ç"—qèt߸†=GBÞñún„i2Ð#YÝçâyа\æÏ¿5ͯYh¯qÆ"“t‹ÃXÙâÎÏÔTM™®vƒN§B2SBÛ‚¡iƒ½Ã%ªqĵvjh6ï›fÇs%^f/8&#Ó!{ÖxxwSVº\tŽGu¦B%d³Oî©1]¬qÓo¬d ;®w0vJp?Ų>‡«.î-¤.R¦`ïÎ åB•Õë=6œ Ib“V[‘ö,bi0•2¹åþ ³UƒM×uБ¶‰´I5TJ&q¨0=¥ZY·:ä-•xß§%ÛŸmdå…RÐÕ¡½=%Ri­µX˜î×V4À}ø°Èçóà*às@;5@ ä:I4¶ yÏ•9w„¿¼e†—Ú¬XœFZ.“s ¯;Õbn®LD´µ¤˜“~º¯Æ¹Ëú[5årÝ&uæL‚Xpû£%ÞpîÎ<­»>˜„R9ä›wícõ@;OÎ"u„%†—åéCsÜzïN®:ߣ«UD BhÒ¶…ð—·ŒsÃ×Ò×f’²5J[D‰Ò wo=¡‘ mè Í“tgM*1Tç"nùÉ$7^½ž®Î,ZÅDÊ`~¾Ä#ÛàÉ€Mgg)WO=[&—2©(ƒáéúdøR$q-Í¡ƒs á¼eP,T¥g D¤H§-¦ [÷l\×ÎÕõR(E(!éj5PqBÊŠñ<Û‘ÌÍ…ÄdyÛŸN³cP’²bRi‡¾ÅYR)ëØpݤgßîò}îyÚ=ŸÏ·>Øä—‰ç(`i{‘óÖLñ– ;ãzš+ c¾ñà,Ós5n~ãJ²i¥b%±LƒOÞ²‹´ò»—wá9’R¨)a3:¥øÖF¹âœ “¹P‘v%YÏfv>bײ20 “;™¦³ED!¹”ah<[P ß¹¿ÈÛ¯^Ái«[Ða•8P[dR6÷?2Â?Ü9̼­›–f0…ãZ’}œü¹+Èo Ñ&H‰k›lÞ6Èg¿ô$õ>‡6¯¾ï×;ülÁßÞÑÓiqÃ…YŠ…¤N#ÆfŸ¼e–/IsÆ—Z ‘â(fb6æö‡ú<ÎÝØA¡!„f:É0?[fp°Ä®½%Ö-3Øxö †f<Ø2N‹§¹ggÙ6ï¸Ôx!Ü|ø3`Þ÷}òùüÏòÁù|^Uß÷?”Ïçÿø2p&`7S!˜Ìr¤ÐÊîç†isg9u¥Åc+ M%üÖe‹+ÔÇ)XÚÓ§¾{˜žLÈ»/ë¢iÂ0ÁšûfÙ¼WóG7.¢Ý«Ï˜’OD|÷¡iÞqyÙ“­QJð»W÷ðÙoOàfÝiŠ`¼¤yv°LWΠP¨ñÈS!$Ôê†kl6bßhÀo_Þ…©àÙ½ṡõ‡³±dÕòVR¢ÄÝ?zœÎv—ƒCótu¶òãgæié5™š ›ô´[ •jLµ¦yvRóö‹MF&ëSï ‘öly&dq·$ZŠB1Â3´" $LÔ4o9«ƒnƒ¾ÖÓ¶0Œ­möô´28TâÒ Z9qYÈúZ ×Jóùeɶ‰— V= Üäûþ¾|>ÿ³¸ Ò™Ïçñ}h H|ßWù|þíÀŸk›TA-iM¤,N¨ð¶ã¬ë¯rÇÖ ·o«ñþ+3 t”kÓÐ$šHؾ7bY¯G6Uo™¯ÔMF«k³¸Ëdq§ËDYpûö—®w1 éí²‘†Ãàp•ýGŠ\pjŽR9fh¤Œa´eLLCS©%HÛ¢¯¯ÙBÌWodlªÊŸß¼‚5Kê‹.õµìµ ÁuM0 ­+\¼i1hb¶€DðáÏï§3gsU~)®¡™**Bé"mÉøx‰[oÛÅkm–zØÄ”c“±‰'¬îV,îõ°\5?ËŠ9:Ü|m/–TDA‚PµXbéˆíOì+qý¦ ±ðøÂ½]ìJÑ–JhÚᢚ"»€ÿíûþ×òù< Û{t¢‹ïû«¢iˆ¶,ß÷Ã|>o7±›€ÅͿĚr ÁÙ˧Ø58̇¯ ´$J’Mi¦Ëš¡é#šó×åH»’0ÒdS’Í»*LÍk.9«ƒþNƒXÕ‡‹X-’Âx[7O…’sÖgðlˆcMbZÈ$àû÷O ¿yE?+<¦'˵@1WÜ7ÉþÑ'¯LsÒ²Q¨Èx’(ÌWcµ›XŽT þŽ*7_ÕÇþÑÇHSàš&[öøÁƒ“|â½+Èè*´hÏ¥‘N 'Üþã#ÌWËÜø¦Nj…ì:Pá»÷ÎQM ®½¬ÓOëÂI¥øö÷°õ‰QÞzårVŸÔM[¸2âßÛÅÐh‰k/_†0]¶ïޏg+œi'í‚c)âDÐðæ‚™‡€[€Oú¾_Éçóù¾¯^¬3ây 7‡2}ßOŸŸ¼øoM´ÊªOé×TB“ŽLÀ@÷œ8ÚÅ?ÞÑ’1è±h‡r(1 ƒ®VÍ}O•Ù¶·Æ_× B°¨ÕÕ A ¹k{-$ﺴ‹É¢&cƒNZ+îøé …rÌÆuYVö· µA:íN™ŒùÌ×qÂ2—/ë`x¸ˆ—v0 ‹8N¸åG“\znk–z”C¡zÚm~ðÀŸ+ðæ‹Ú¨*×0š‹Ù3Rcf^Ó‘M±¨­žS¶,ÇPìØ7G{Ö&eÂDh<1>§Y¾8ͦÓÛ q “/ÿh,ÁG?°¨£Â*iGð¹ÞÏÚn:‘où‚ûŸŒÌ8f‚ª÷7Óü-ðEß÷w6piÆè¨&~Q€_DšECeK`cCm_ѸUª4JÕÇ-íèËÎðºµÎ?1M:cÿlÕ}òÍŸynZó– Rô¶ÙD€Žk ÓÅ„~k–E].¿ui¦©cÂP#Q÷ý NYÆ1)Wòš5CSG&c–ö¹ÜûXÂÎC1«û¡ÍƒlFbZšCCŠTÚ¤¿×ehZãHÍ‘Ä\Ìþ‘4R$Øf½¢¥q&²ÁžF`é³¾ï×Ô4nÍÏìàZ.p±†Ú¾¹!Ñâ(­¡´&V&‹sŠ««\³a–¶t‘ÇvÃØœà’sZèî¶Á„è @x[žN¸ëÉy.;Å¡'g€NêCÆ…b>Hp\ƒ>RedFñÛ¥™¯iÒ®Dš’ÙRÂöý!ŽkÒÓæÔ=þD±~¹ÉîÃJYBrÇ£,3â´MO«Äu5}Y‰eÁ\5¢Pr¸í§1Ëû Î>Aá˜×Ó”k#Ó ¦•ðÈÞ;‡»ID'µÀĶÔBíšjH¥ À§€¯ú¾¿÷ßB{^q€ÃŸEpÝìõ GìÚÆ‹éÐÄ âD°¸=¢Óç”ÞaÖ¤èïs98¦ è]$ɦ ÙzPñGפXÕcb»hI%Äq„mhnÛVã¡}ï¿4MG¦.ެÛyE]%ÚRsÛã!ß~4æ}ohç´˜)Ö;bâX‘¦VKøîCsTÁúIÖ“d¬„‡`ªªYÒ¥XÙ[/HÛM›ÌUbàï€×éfZeHÖõˆØ›6L³éÄ)‚  £Íel"áïî,rÉ6ýYA*c°j±ƒŽ#’0 Xƒ¸'dM¿ÃMJæiYX”KU2i›j˜ð™[+¤2o;ßAª€=£Š±bÌ|b3†˜ˆÑ¢¦PH0´Ä±5#¥„®,ÏIªóŠP»<3ÑÅtuQ"0ú¬æ U Ü ¼×÷ýɆ-Оÿl‰}Å>ØÍ¼î àÕ$Ïó,¥Ð”ƒÎ–+:Fèm)âR&”’Õ=6ó¡"ŽÁ2-n}œÒà$ì~.áÊ ím&†a‘rLl“N $G•ï˜ãÎ}”¢ ¦ˆåÁ/H <Р=w/Ðß÷ãWØWà— U¢‘Äx/pJ³3"¥&I$±’´{Ó\¹aŒ«Ïœ¡T”+’J3óš©"ܹfç4ox­A)zÓ ¤ƒeDQ‚’ÄpÏS1zZ-IÎ3èj5ê*»Ç`dN±²×¡·Çå±g*ܵe–?¼Þ$í&Hà©Á÷?ÛÍÃû;° …G¥¶9nü4ð÷À?6µšÌWØ_ˆ¿ ­Z ¼£Q‘à4Ó*ÄÊÀ³BN^Rà’“Ðß>O%²˜*Â=Ûàà°æ¢³g®Jhu®„Q]œæB80.Ù²[²wHsÂbƒ“WHÚÒÇÔ˜fæåªUÍÎ!0µ ©%ä7H®Üóìp†>µ˜Çç(ÕL<;9Ö¾:@µQóMß÷hO#Ä/âü‚žc<ÇæDÆêÈ76O-P ¥ë›Óré€U]S¬í~Žý㊭{%'.Ö\»)¡P!5ž Q Ž)YÑ+ù‹oÂļÁ’nÁ».©×J¥ƒ0’”#ÅÞ±È0H‚§÷ר¶Ö.±¸úì­ƒlÙßE¡Z§=†Ð ŽT³Ô~½áDímªÑÿUÞñ/=À/•ix™ç_i´Õ4äѵn‚¨vˆ$š¢-c M”À@ºÛCÓæÁž!“jv*ƒK‰®vÁL±N›º²&Ý9“D%hÃ$#ž9hêAÜÁT­ŸXÙõÎ ñÏXû€wù¾ÿÓ¹¼ü¢¤÷ðKðfÙ8•Ïç?ü9}a¶JDë–9}ÅaúZb–-6™˜Ô‚Ûöű`xBs`HaXš®vI§db6!Œ T•$Ð -)ƒP9”£eDd16ö8Ô§|Ô÷ýO7¤Uþ"Uñ/=À/“­ÊÿxÐòüú0M 4‚Î⵫gYÔP3Õ„Ñyŗ©$œ{²Éu] dcì©&ÑPª%´Øðµ÷>ÑN.·´Ñ¤j¡šiÏ,pðß÷gAœð•¢=¯z€£ºMß÷ãÆçùFîùŠ&oÛ¨£×*&ý¹*Wœ6ÉÒì$3âo~¬Ø=¦8}•Áϲh•¦ ®#I;‚ Š"‡Í{[Ør°‡é²‡$jTTˆFéQÚsðW¾ï?и€Æ+M{~%>àÍÒ,€÷7ìôÑš¥zÖHR‹ýmsxrœÑ®#H»=)ƒ¹Š¦X…®¬"ãŠú@ðZ7»†[°M!ÕÑj°Ÿñ}ÿ–¦4^òóæh ðKØæ&ZÕ \|hmÐ*SP׿Qb T„k8eé'tÍaš6ÏMkƦCöŒä(ÇK°í6 ÃÄ1Uó¾é….r#ömß÷Ç›“ÿ‘í¯~yZÕ ú’­zwsîyáõ„SÆôç&YÒv“Ñâ':A5}l¶G6¾¾| nò ô/; ¯Z€$96‘qðU`ϯ’hz´ŠÒå8)GêÉíyêE´¯&_U¿„ê6Á’8ŸÏÿõBµîcßO,¤ï~F{š½ã‘íùBã" mðªPÅ¿r¿­Zˆo{Ô+%Þ äx!˜Í>Ü ü¡ïûs/Õ%ðk€ùhÕÙÀÿ®o|/j» ßixÇ6œ'Ùô³¯Z©ý•øE¤y£JàJàCÀÂMxøkß÷o}µÑžÿ¯~ZÕI½£øß÷ËM[¿Úmí‹=ÿ/á*k=IEND®B`‚rlang/man/figures/lifecycle-stable.svg0000644000176200001440000000167413405732277017546 0ustar liggesuserslifecyclelifecyclestablestable rlang/man/figures/lifecycle-experimental.svg0000644000176200001440000000171613405732277020766 0ustar liggesuserslifecyclelifecycleexperimentalexperimental rlang/man/figures/lifecycle-deprecated.svg0000644000176200001440000000171213405732277020365 0ustar liggesuserslifecyclelifecycledeprecateddeprecated rlang/man/figures/lifecycle-retired.svg0000644000176200001440000000170513407134203017710 0ustar liggesusers lifecyclelifecycleretiredretired rlang/man/is_integerish.Rd0000644000176200001440000000325013405732277015265 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/types.R \name{is_integerish} \alias{is_integerish} \alias{is_bare_integerish} \alias{is_scalar_integerish} \title{Is a vector integer-like?} \usage{ is_integerish(x, n = NULL, finite = NULL) is_bare_integerish(x, n = NULL, finite = NULL) is_scalar_integerish(x, finite = NULL) } \arguments{ \item{x}{Object to be tested.} \item{n}{Expected length of a vector.} \item{finite}{Whether all values of the vector are finite. The non-finite values are \code{NA}, \code{Inf}, \code{-Inf} and \code{NaN}. Setting this to something other than \code{NULL} can be expensive because the whole vector needs to be traversed and checked.} } \description{ These predicates check whether R considers a number vector to be integer-like, according to its own tolerance check (which is in fact delegated to the C library). This function is not adapted to data analysis, see the help for \code{\link[base:is.integer]{base::is.integer()}} for examples of how to check for whole numbers. Things to consider when checking for integer-like doubles: \itemize{ \item This check can be expensive because the whole double vector has to be traversed and checked. \item Large double values may be integerish but may still not be coercible to integer. This is because integers in R only support values up to \code{2^31 - 1} while numbers stored as double can be much larger. } } \examples{ is_integerish(10L) is_integerish(10.0) is_integerish(10.0, n = 2) is_integerish(10.000001) is_integerish(TRUE) } \seealso{ \code{\link[=is_bare_numeric]{is_bare_numeric()}} for testing whether an object is a base numeric type (a bare double or integer vector). } rlang/man/cnd_signal.Rd0000644000176200001440000000435613552030327014530 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cnd-signal.R \name{cnd_signal} \alias{cnd_signal} \title{Signal a condition object} \usage{ cnd_signal(cnd, .cnd, .mufflable) } \arguments{ \item{cnd}{A condition object (see \code{\link[=cnd]{cnd()}}).} \item{.cnd, .mufflable}{These arguments are deprecated.} } \description{ The type of signal depends on the class of the condition: \itemize{ \item A message is signalled if the condition inherits from \code{"message"}. This is equivalent to signalling with \code{\link[=inform]{inform()}} or \code{\link[base:message]{base::message()}}. \item A warning is signalled if the condition inherits from \code{"warning"}. This is equivalent to signalling with \code{\link[=warn]{warn()}} or \code{\link[base:warning]{base::warning()}}. \item An error is signalled if the condition inherits from \code{"error"}. This is equivalent to signalling with \code{\link[=abort]{abort()}} or \code{\link[base:stop]{base::stop()}}. \item An interrupt is signalled if the condition inherits from \code{"interrupt"}. This is equivalent to signalling with \code{\link[=interrupt]{interrupt()}}. } Use \code{\link[=cnd_type]{cnd_type()}} to determine the type of a condition. } \section{Lifecycle}{ \itemize{ \item \code{.cnd} has been renamed to \code{cnd} and is deprecated as of rlang 0.3.0. \item The \code{.mufflable} argument is deprecated as of rlang 0.3.0 and no longer has any effect. Non-critical conditions are always signalled with a muffle restart. \item Creating a condition object with \code{\link[=cnd_signal]{cnd_signal()}} is deprecated as of rlang 0.3.0. Please use \code{\link[=signal]{signal()}} instead. } } \examples{ # The type of signal depends on the class. If the condition # inherits from "warning", a warning is issued: cnd <- warning_cnd("my_warning_class", message = "This is a warning") cnd_signal(cnd) # If it inherits from "error", an error is raised: cnd <- error_cnd("my_error_class", message = "This is an error") try(cnd_signal(cnd)) } \seealso{ \code{\link[=abort]{abort()}}, \code{\link[=warn]{warn()}} and \code{\link[=inform]{inform()}} for creating and signalling structured R conditions. See \code{\link[=with_handlers]{with_handlers()}} for establishing condition handlers. } rlang/man/exiting.Rd0000644000176200001440000000055313500125350014063 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{exiting} \alias{exiting} \title{Exiting handler} \usage{ exiting(handler) } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("soft-deprecated")} \code{exiting()} is no longer necessary as handlers are exiting by default. } \keyword{internal} rlang/man/as_overscope.Rd0000644000176200001440000000315513563530577015131 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{as_overscope} \alias{as_overscope} \alias{new_overscope} \alias{overscope_clean} \title{Create an overscope} \usage{ as_overscope(quo, data = NULL) new_overscope(bottom, top = NULL, enclosure = NULL) overscope_clean(overscope) } \arguments{ \item{quo}{A \link[=nse-defuse]{quosure}.} \item{data}{A data frame or named vector of masking data.} \item{bottom}{The environment containing masking objects if the data mask is one environment deep. The bottom environment if the data mask comprises multiple environment. If you haven't supplied \code{top}, this \strong{must} be an environment that you own, i.e. that you have created yourself.} \item{top}{The last environment of the data mask. If the data mask is only one environment deep, \code{top} should be the same as \code{bottom}. This \strong{must} be an environment that you own, i.e. that you have created yourself. The parent of \code{top} will be changed by the tidy eval engine and should be considered undetermined. Never make assumption about the parent of \code{top}.} \item{enclosure}{The \code{parent} argument of \code{\link[=new_data_mask]{new_data_mask()}}.} \item{overscope}{A data mask.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} These functions have been deprecated in rlang 0.2.0. Please use \code{\link[=as_data_mask]{as_data_mask()}} and \code{\link[=new_data_mask]{new_data_mask()}} instead. We no longer require the mask to be cleaned up so \code{overscope_clean()} does not have a replacement. } \keyword{internal} rlang/man/env_binding_are_active.Rd0000644000176200001440000000112713405732277017076 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env-binding.R \name{env_binding_are_active} \alias{env_binding_are_active} \alias{env_binding_are_lazy} \title{What kind of environment binding?} \usage{ env_binding_are_active(env, nms = NULL) env_binding_are_lazy(env, nms = NULL) } \arguments{ \item{env}{An environment.} \item{nms}{Names of bindings. Defaults to all bindings in \code{env}.} } \value{ A logical vector as long as \code{nms} and named after it. } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} } \keyword{internal} rlang/man/env_depth.Rd0000644000176200001440000000122713405732277014407 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env.R \name{env_depth} \alias{env_depth} \title{Depth of an environment chain} \usage{ env_depth(env) } \arguments{ \item{env}{An environment.} } \value{ An integer. } \description{ This function returns the number of environments between \code{env} and the \link[=empty_env]{empty environment}, including \code{env}. The depth of \code{env} is also the number of parents of \code{env} (since the empty environment counts as a parent). } \examples{ env_depth(empty_env()) env_depth(pkg_env("rlang")) } \seealso{ The section on inheritance in \code{\link[=env]{env()}} documentation. } rlang/man/is_frame.Rd0000644000176200001440000000050013500223442014172 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{is_frame} \alias{is_frame} \title{Is object a frame?} \usage{ is_frame(x) } \arguments{ \item{x}{Object to test} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} } \keyword{internal} rlang/man/scalar-type-predicates.Rd0000644000176200001440000000250213500416332016760 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/types.R \name{scalar-type-predicates} \alias{scalar-type-predicates} \alias{is_scalar_list} \alias{is_scalar_atomic} \alias{is_scalar_vector} \alias{is_scalar_integer} \alias{is_scalar_double} \alias{is_scalar_character} \alias{is_scalar_logical} \alias{is_scalar_raw} \alias{is_string} \alias{is_scalar_bytes} \alias{is_bool} \title{Scalar type predicates} \usage{ is_scalar_list(x) is_scalar_atomic(x) is_scalar_vector(x) is_scalar_integer(x) is_scalar_double(x) is_scalar_character(x, encoding = NULL) is_scalar_logical(x) is_scalar_raw(x) is_string(x, string = NULL) is_scalar_bytes(x) is_bool(x) } \arguments{ \item{x}{object to be tested.} \item{encoding}{Defunct as of rlang 0.4.0.} \item{string}{A string to compare to \code{x}. If a character vector, returns \code{TRUE} if at least one element is equal to \code{x}.} } \description{ These predicates check for a given type and whether the vector is "scalar", that is, of length 1. In addition to the length check, \code{is_string()} and \code{is_bool()} return \code{FALSE} if their input is missing. This is useful for type-checking arguments, when your function expects a single string or a single \code{TRUE} or \code{FALSE}. } \seealso{ \link{type-predicates}, \link{bare-type-predicates} } rlang/man/fn_body.Rd0000644000176200001440000000156013604124170014037 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/fn.R \name{fn_body} \alias{fn_body} \alias{fn_body<-} \title{Get or set function body} \usage{ fn_body(fn = caller_fn()) fn_body(fn) <- value } \arguments{ \item{fn}{A function. It is lookep up in the calling frame if not supplied.} \item{value}{New formals or formals names for \code{fn}.} } \description{ \code{fn_body()} is a simple wrapper around \code{\link[base:body]{base::body()}}. It always returns a \verb{\\\{} expression and throws an error when the input is a primitive function (whereas \code{body()} returns \code{NULL}). The setter version preserves attributes, unlike \verb{body<-}. } \examples{ # fn_body() is like body() but always returns a block: fn <- function() do() body(fn) fn_body(fn) # It also throws an error when used on a primitive function: try(fn_body(base::list)) } rlang/man/is_interactive.Rd0000644000176200001440000000255713563535650015453 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/state.R \name{is_interactive} \alias{is_interactive} \alias{local_interactive} \alias{with_interactive} \title{Is R running interactively?} \usage{ is_interactive() local_interactive(value = TRUE, frame = caller_env()) with_interactive(expr, value = TRUE) } \arguments{ \item{value}{A single \code{TRUE} or \code{FALSE}. This overrides the return value of \code{is_interactive()}.} \item{frame}{The environment of a running function which defines the scope of the temporary options. When the function returns, the options are reset to their original values.} \item{expr}{An expression to evaluate with interactivity set to \code{value}.} } \description{ Like \code{\link[base:interactive]{base::interactive()}}, \code{is_interactive()} returns \code{TRUE} when the function runs interactively and \code{FALSE} when it runs in batch mode. It also checks, in this order: \itemize{ \item The \code{rlang_interactive} global option. If set to a single \code{TRUE} or \code{FALSE}, \code{is_interactive()} returns that value immediately. This escape hatch is useful in unit tests or to manually turn on interactive features in RMarkdown outputs. \item Whether knitr, an RStudio notebook, or testthat is in progress. } \code{with_interactive()} and \code{local_interactive()} set the global option conveniently. } rlang/man/done.Rd0000644000176200001440000000143213407134203013341 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/s3.R \name{done} \alias{done} \alias{is_done_box} \title{Box a final value for early termination} \usage{ done(x) is_done_box(x, empty = NULL) } \arguments{ \item{x}{For \code{done()}, a value to box. For \code{is_done_box()}, a value to test.} \item{empty}{Whether the box is empty. If \code{NULL}, \code{is_done_box()} returns \code{TRUE} for all done boxes. If \code{TRUE}, it returns \code{TRUE} only for empty boxes. Otherwise it returns \code{TRUE} only for non-empty boxes.} } \value{ A \link[rlang:new_box]{boxed} value. } \description{ A value boxed with \code{done()} signals to its caller that it should stop iterating. Use it to shortcircuit a loop. } \examples{ done(3) x <- done(3) is_done_box(x) } rlang/man/as_env.Rd0000644000176200001440000000063213500223442013666 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{as_env} \alias{as_env} \title{Coerce to an environment} \usage{ as_env(x, parent = NULL) } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} This function is deprecated as it was renamed to \code{\link[=as_environment]{as_environment()}} in rlang 0.2.0. } \keyword{internal} rlang/man/box.Rd0000644000176200001440000000277413407134203013216 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/s3.R \name{box} \alias{box} \alias{new_box} \alias{is_box} \alias{unbox} \title{Box a value} \usage{ new_box(.x, class = NULL, ...) is_box(x, class = NULL) unbox(box) } \arguments{ \item{class}{For \code{new_box()}, an additional class for the boxed value (in addition to \code{rlang_box}). For \code{is_box()}, a class or vector of classes passed to \code{\link[=inherits_all]{inherits_all()}}.} \item{...}{Additional attributes passed to \code{\link[base:structure]{base::structure()}}.} \item{x, .x}{An R object.} \item{box}{A boxed value to unbox.} } \description{ \code{new_box()} is similar to \code{\link[base:I]{base::I()}} but it protects a value by wrapping it in a scalar list rather than by adding an attribute. \code{unbox()} retrieves the boxed value. \code{is_box()} tests whether an object is boxed with optional class. \code{as_box()} ensures that a value is wrapped in a box. \code{as_box_if()} does the same but only if the value matches a predicate. } \examples{ boxed <- new_box(letters, "mybox") is_box(boxed) is_box(boxed, "mybox") is_box(boxed, "otherbox") unbox(boxed) # as_box() avoids double-boxing: boxed2 <- as_box(boxed, "mybox") boxed2 unbox(boxed2) # Compare to: boxed_boxed <- new_box(boxed, "mybox") boxed_boxed unbox(unbox(boxed_boxed)) # Use `as_box_if()` with a predicate if you need to ensure a box # only for a subset of values: as_box_if(NULL, is_null, "null_box") as_box_if("foo", is_null, "null_box") } rlang/man/prepend.Rd0000644000176200001440000000153013563532074014063 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{prepend} \alias{prepend} \alias{modify} \title{Prepend a vector} \usage{ prepend(x, values, before = 1) modify(.x, ...) } \arguments{ \item{x}{the vector to be modified.} \item{values}{to be included in the modified vector.} \item{before}{a subscript, before which the values are to be appended.} \item{.x}{A vector to modify.} \item{...}{<\link[=dyn-dots]{dynamic}> List of elements to merge into \code{.x}. Named elements already existing in \code{.x} are used as replacements. Elements that have new or no names are inserted at the end.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} Vector functions are now out of scope for rlang. They might be revived in the vctrs or funs packages. } \keyword{internal} rlang/man/quo_expr.Rd0000644000176200001440000000140513504161362014262 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{quo_expr} \alias{quo_expr} \title{Squash a quosure} \usage{ quo_expr(quo, warn = FALSE) } \arguments{ \item{quo}{A quosure or expression.} \item{warn}{Whether to warn if the quosure contains other quosures (those will be collapsed). This is useful when you use \code{quo_squash()} in order to make a non-tidyeval API compatible with quosures. In that case, getting rid of the nested quosures is likely to cause subtle bugs and it is good practice to warn the user about it.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} This function is deprecated, please use \code{\link[=quo_squash]{quo_squash()}} instead. } \keyword{internal} rlang/man/is_named.Rd0000644000176200001440000000340413405732277014211 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/attr.R \name{is_named} \alias{is_named} \alias{is_dictionaryish} \alias{have_name} \title{Is object named?} \usage{ is_named(x) is_dictionaryish(x) have_name(x) } \arguments{ \item{x}{An object to test.} } \value{ \code{is_named()} and \code{is_dictionaryish()} are scalar predicates and return \code{TRUE} or \code{FALSE}. \code{have_name()} is vectorised and returns a logical vector as long as the input. } \description{ \code{is_named()} checks that \code{x} has names attributes, and that none of the names are missing or empty (\code{NA} or \code{""}). \code{is_dictionaryish()} checks that an object is a dictionary: that it has actual names and in addition that there are no duplicated names. \code{have_name()} is a vectorised version of \code{is_named()}. } \examples{ # A data frame usually has valid, unique names is_named(mtcars) have_name(mtcars) is_dictionaryish(mtcars) # But data frames can also have duplicated columns: dups <- cbind(mtcars, cyl = seq_len(nrow(mtcars))) is_dictionaryish(dups) # The names are still valid: is_named(dups) have_name(dups) # For empty objects the semantics are slightly different. # is_dictionaryish() returns TRUE for empty objects: is_dictionaryish(list()) # But is_named() will only return TRUE if there is a names # attribute (a zero-length character vector in this case): x <- set_names(list(), character(0)) is_named(x) # Empty and missing names are invalid: invalid <- dups names(invalid)[2] <- "" names(invalid)[5] <- NA # is_named() performs a global check while have_name() can show you # where the problem is: is_named(invalid) have_name(invalid) # have_name() will work even with vectors that don't have a names # attribute: have_name(letters) } rlang/man/is_copyable.Rd0000644000176200001440000000176013604124170014712 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/types.R \name{is_copyable} \alias{is_copyable} \title{Is an object copyable?} \usage{ is_copyable(x) } \arguments{ \item{x}{An object to test.} } \description{ When an object is modified, R generally copies it (sometimes lazily) to enforce \href{https://en.wikipedia.org/wiki/Value_semantics}{value semantics}. However, some internal types are uncopyable. If you try to copy them, either with \verb{<-} or by argument passing, you actually create references to the original object rather than actual copies. Modifying these references can thus have far reaching side effects. } \examples{ # Let's add attributes with structure() to uncopyable types. Since # they are not copied, the attributes are changed in place: env <- env() structure(env, foo = "bar") env # These objects that can only be changed with side effect are not # copyable: is_copyable(env) structure(base::list, foo = "bar") str(base::list) } \keyword{internal} rlang/man/is_env.Rd0000644000176200001440000000114413500223442013675 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{is_env} \alias{is_env} \alias{is_bare_env} \title{Is an object an environment?} \usage{ is_env(x) is_bare_env(x) } \arguments{ \item{x}{object to test} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} These functions were deprecated and renamed to \code{\link[=is_environment]{is_environment()}} and \code{\link[=is_bare_environment]{is_bare_environment()}} in rlang 0.2.0. This is for consistency with other type predicates which are not abbreviated. } \keyword{internal} rlang/man/duplicate.Rd0000644000176200001440000000237113604124170014372 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/sexp.R \name{duplicate} \alias{duplicate} \title{Duplicate an R object} \usage{ duplicate(x, shallow = FALSE) } \arguments{ \item{x}{Any R object. However, uncopyable types like symbols and environments are returned as is (just like with \verb{<-}).} \item{shallow}{This is relevant for recursive data structures like lists, calls and pairlists. A shallow copy only duplicates the top-level data structure. The objects contained in the list are still the same.} } \description{ In R semantics, objects are copied by value. This means that modifying the copy leaves the original object intact. Since copying data in memory is an expensive operation, copies in R are as lazy as possible. They only happen when the new object is actually modified. However, some operations (like \code{\link[=node_poke_car]{node_poke_car()}} or \code{\link[=node_poke_cdr]{node_poke_cdr()}}) do not support copy-on-write. In those cases, it is necessary to duplicate the object manually in order to preserve copy-by-value semantics. } \details{ Some objects are not duplicable, like symbols and environments. \code{duplicate()} returns its input for these unique objects. } \seealso{ pairlist } \keyword{internal} rlang/man/set_expr.Rd0000644000176200001440000000271113351410654014253 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/expr.R \name{set_expr} \alias{set_expr} \alias{get_expr} \title{Set and get an expression} \usage{ set_expr(x, value) get_expr(x, default = x) } \arguments{ \item{x}{An expression, closure, or one-sided formula. In addition, \code{set_expr()} accept frames.} \item{value}{An updated expression.} \item{default}{A default expression to return when \code{x} is not an expression wrapper. Defaults to \code{x} itself.} } \value{ The updated original input for \code{set_expr()}. A raw expression for \code{get_expr()}. } \description{ These helpers are useful to make your function work generically with quosures and raw expressions. First call \code{get_expr()} to extract an expression. Once you're done processing the expression, call \code{set_expr()} on the original object to update the expression. You can return the result of \code{set_expr()}, either a formula or an expression depending on the input type. Note that \code{set_expr()} does not change its input, it creates a new object. } \examples{ f <- ~foo(bar) e <- quote(foo(bar)) frame <- identity(identity(ctxt_frame())) get_expr(f) get_expr(e) get_expr(frame) set_expr(f, quote(baz)) set_expr(e, quote(baz)) } \seealso{ \code{\link[=quo_get_expr]{quo_get_expr()}} and \code{\link[=quo_set_expr]{quo_set_expr()}} for versions of \code{\link[=get_expr]{get_expr()}} and \code{\link[=set_expr]{set_expr()}} that only work on quosures. } rlang/man/nse-force.Rd0000644000176200001440000002127713610376546014324 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nse-force.R \name{nse-force} \alias{nse-force} \alias{quasiquotation} \alias{UQ} \alias{UQS} \alias{{{}}} \alias{\{\{} \alias{!!} \alias{!!!} \alias{:=} \alias{qq_show} \title{Force parts of an expression} \usage{ qq_show(expr) } \arguments{ \item{expr}{An expression to be quasiquoted.} } \description{ It is sometimes useful to force early evaluation of part of an expression before it gets fully evaluated. The tidy eval framework provides several forcing operators for different use cases. \itemize{ \item The bang-bang operator \verb{!!} forces a \emph{single} object. One common case for \verb{!!} is to substitute an environment-variable (created with \verb{<-}) with a data-variable (inside a data frame).\preformatted{library(dplyr) # The environment variable `var` refers to the data-variable # `height` var <- sym("height") # We force `var`, which substitutes it with `height` starwars \%>\% summarise(avg = mean(!!var, na.rm = TRUE)) } \item The big-bang operator \verb{!!!} forces-splice a \emph{list} of objects. The elements of the list are spliced in place, meaning that they each become one single argument.\preformatted{vars <- syms(c("height", "mass")) # Force-splicing is equivalent to supplying the elements separately starwars \%>\% select(!!!vars) starwars \%>\% select(height, mass) } \item The curly-curly operator \code{{{ }}} for function arguments is a bit special because it forces the function argument and immediately defuses it. The defused expression is substituted in place, ready to be evaluated in another context, such as the data frame. In practice, this is useful when you have a data-variable in an env-variable (such as a function argument).\preformatted{# Force-defuse all function arguments that might contain # data-variables by embracing them with \{\{ \}\} mean_by <- function(data, by, var) \{ data \%>\% group_by(\{\{ by \}\}) \%>\% summarise(avg = mean(\{\{ var \}\}, na.rm = TRUE)) \} # The env-variables `by` and `var` are forced but defused. # The data-variables they contain are evaluated by dplyr later on # in data context. iris \%>\% mean_by(by = Species, var = Sepal.Width) } } Use \code{qq_show()} to experiment with forcing operators. \code{qq_show()} defuses its input, processes all forcing operators, and prints the result with \code{\link[=expr_print]{expr_print()}} to reveal objects inlined in the expression by the forcing operators. } \section{Forcing names}{ When a function takes multiple named arguments (e.g. \code{dplyr::mutate()}), it is difficult to supply a variable as name. Since the LHS of \code{=} is \link[=nse-defuse]{defused}, giving the name of a variable results in the argument having the name of the variable rather than the name stored in that variable. This problem of forcing evaluation of names is exactly what the \verb{!!} operator is for. Unfortunately R is very strict about the kind of expressions supported on the LHS of \code{=}. This is why rlang interprets the walrus operator \verb{:=} as an alias of \code{=}. You can use it to supply names, e.g. \code{a := b} is equivalent to \code{a = b}. Since its syntax is more flexible you can also force names on its LHS:\preformatted{name <- "Jane" list2(!!name := 1 + 2) exprs(!!name := 1 + 2) } Like \code{=}, the \verb{:=} operator expects strings or symbols on its LHS. Since unquoting names is related to interpolating within a string with the glue package, we have made the glue syntax available on the LHS of \verb{:=}:\preformatted{list2("\{name\}" := 1) tibble("\{name\}" := 1) } You can also interpolate defused function arguments with double braces \verb{\{\{}, similar to the curly-curly syntax:\preformatted{wrapper <- function(data, var) \{ data \%>\% mutate("\{\{ var \}\}_foo" := \{\{ var \}\} * 2) \} } Currently, forcing names with \verb{:=} only works in top level expressions. These are all valid:\preformatted{exprs("\{name\}" := x) tibble("\{name\}" := x) } But deep-forcing names isn't supported:\preformatted{exprs(this(is(deep("\{name\}" := x)))) } } \section{Theory}{ Formally, \code{quo()} and \code{expr()} are quasiquotation functions, \verb{!!} is the unquote operator, and \verb{!!!} is the unquote-splice operator. These terms have a rich history in Lisp languages, and live on in modern languages like \href{https://docs.julialang.org/en/v1/manual/metaprogramming/}{Julia} and \href{https://docs.racket-lang.org/reference/quasiquote.html}{Racket}. } \section{Life cycle}{ \itemize{ \item Calling \code{UQ()} and \code{UQS()} with the rlang namespace qualifier is deprecated as of rlang 0.3.0. Just use the unqualified forms instead:\preformatted{# Bad rlang::expr(mean(rlang::UQ(var) * 100)) # Ok rlang::expr(mean(UQ(var) * 100)) # Good rlang::expr(mean(!!var * 100)) } Supporting namespace qualifiers complicates the implementation of unquotation and is misleading as to the nature of unquoting operators (which are syntactic operators that operates at quotation-time rather than function calls at evaluation-time). \item \code{UQ()} and \code{UQS()} were soft-deprecated in rlang 0.2.0 in order to make the syntax of quasiquotation more consistent. The prefix forms are now \code{`!!`()} and \code{`!!!`()} which is consistent with other R operators (e.g. \code{`+`(a, b)} is the prefix form of \code{a + b}). Note that the prefix forms are not as relevant as before because \verb{!!} now has the right operator precedence, i.e. the same as unary \code{-} or \code{+}. It is thus safe to mingle it with other operators, e.g. \code{!!a + !!b} does the right thing. In addition the parser now strips one level of parentheses around unquoted expressions. This way \code{(!!"foo")(...)} expands to \code{foo(...)}. These changes make the prefix forms less useful. Finally, the named functional forms \code{UQ()} and \code{UQS()} were misleading because they suggested that existing knowledge about functions is applicable to quasiquotation. This was reinforced by the visible definitions of these functions exported by rlang and by the tidy eval parser interpreting \code{rlang::UQ()} as \verb{!!}. In reality unquoting is \emph{not} a function call, it is a syntactic operation. The operator form makes it clearer that unquoting is special. } } \examples{ # Interpolation with {{ }} is the easiest way to forward # arguments to tidy eval functions: if (is_attached("package:dplyr")) { # Forward all arguments involving data frame columns by # interpolating them within other data masked arguments. # Here we interpolate `arg` in a `summarise()` call: my_function <- function(data, arg) { summarise(data, avg = mean({{ arg }}, na.rm = TRUE)) } my_function(mtcars, cyl) my_function(mtcars, cyl * 10) # The operator is just a shortcut for `!!enquo()`: my_function <- function(data, arg) { summarise(data, avg = mean(!!enquo(arg), na.rm = TRUE)) } my_function(mtcars, cyl) } # Quasiquotation functions quote expressions like base::quote() quote(how_many(this)) expr(how_many(this)) quo(how_many(this)) # In addition, they support unquoting. Let's store symbols # (i.e. object names) in variables: this <- sym("apples") that <- sym("oranges") # With unquotation you can insert the contents of these variables # inside the quoted expression: expr(how_many(!!this)) expr(how_many(!!that)) # You can also insert values: expr(how_many(!!(1 + 2))) quo(how_many(!!(1 + 2))) # Note that when you unquote complex objects into an expression, # the base R printer may be a bit misleading. For instance compare # the output of `expr()` and `quo()` (which uses a custom printer) # when we unquote an integer vector: expr(how_many(!!(1:10))) quo(how_many(!!(1:10))) # This is why it's often useful to use qq_show() to examine the # result of unquotation operators. It uses the same printer as # quosures but does not return anything: qq_show(how_many(!!(1:10))) # Use `!!!` to add multiple arguments to a function. Its argument # should evaluate to a list or vector: args <- list(1:3, na.rm = TRUE) quo(mean(!!!args)) # You can combine the two var <- quote(xyz) extra_args <- list(trim = 0.9, na.rm = TRUE) quo(mean(!!var , !!!extra_args)) # The plural versions have support for the `:=` operator. # Like `=`, `:=` creates named arguments: quos(mouse1 := bernard, mouse2 = bianca) # The `:=` is mainly useful to unquote names. Unlike `=` it # supports `!!` on its LHS: var <- "unquote me!" quos(!!var := bernard, mouse2 = bianca) # All these features apply to dots captured by enquos(): fn <- function(...) enquos(...) fn(!!!args, !!var := penny) # Unquoting is especially useful for building an expression by # expanding around a variable part (the unquoted part): quo1 <- quo(toupper(foo)) quo1 quo2 <- quo(paste(!!quo1, bar)) quo2 quo3 <- quo(list(!!quo2, !!!syms(letters[1:5]))) quo3 } rlang/man/quo_squash.Rd0000644000176200001440000000316313604124170014610 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/quo.R \name{quo_squash} \alias{quo_squash} \title{Squash a quosure} \usage{ quo_squash(quo, warn = FALSE) } \arguments{ \item{quo}{A quosure or expression.} \item{warn}{Whether to warn if the quosure contains other quosures (those will be collapsed). This is useful when you use \code{quo_squash()} in order to make a non-tidyeval API compatible with quosures. In that case, getting rid of the nested quosures is likely to cause subtle bugs and it is good practice to warn the user about it.} } \description{ \code{quo_squash()} flattens all nested quosures within an expression. For example it transforms \verb{^foo(^bar(), ^baz)} to the bare expression \code{foo(bar(), baz)}. This operation is safe if the squashed quosure is used for labelling or printing (see \code{\link[=quo_label]{quo_label()}} or \code{\link[=quo_name]{quo_name()}}). However if the squashed quosure is evaluated, all expressions of the flattened quosures are resolved in a single environment. This is a source of bugs so it is good practice to set \code{warn} to \code{TRUE} to let the user know about the lossy squashing. } \section{Life cycle}{ This function replaces \code{quo_expr()} which was deprecated in rlang 0.2.0. \code{quo_expr()} was a misnomer because it implied that it was a mere expression acccessor for quosures whereas it was really a lossy operation that squashed all nested quosures. } \examples{ # Quosures can contain nested quosures: quo <- quo(wrapper(!!quo(wrappee))) quo # quo_squash() flattens all the quosures and returns a simple expression: quo_squash(quo) } rlang/man/get_env.Rd0000644000176200001440000000642613500223442014051 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env.R \name{get_env} \alias{get_env} \alias{set_env} \alias{env_poke_parent} \title{Get or set the environment of an object} \usage{ get_env(env, default = NULL) set_env(env, new_env = caller_env()) env_poke_parent(env, new_env) } \arguments{ \item{env}{An environment.} \item{default}{The default environment in case \code{env} does not wrap an environment. If \code{NULL} and no environment could be extracted, an error is issued.} \item{new_env}{An environment to replace \code{env} with.} } \description{ These functions dispatch internally with methods for functions, formulas and frames. If called with a missing argument, the environment of the current evaluation frame (see \code{\link[=ctxt_stack]{ctxt_stack()}}) is returned. If you call \code{get_env()} with an environment, it acts as the identity function and the environment is simply returned (this helps simplifying code when writing generic functions for environments). } \details{ While \code{set_env()} returns a modified copy and does not have side effects, \code{env_poke_parent()} operates changes the environment by side effect. This is because environments are \link[=is_copyable]{uncopyable}. Be careful not to change environments that you don't own, e.g. a parent environment of a function from a package. } \section{Life cycle}{ \itemize{ \item Using \code{get_env()} without supplying \code{env} is deprecated as of rlang 0.3.0. Please use \code{\link[=current_env]{current_env()}} to retrieve the current environment. \item Passing environment wrappers like formulas or functions instead of bare environments is deprecated as of rlang 0.3.0. This internal genericity was causing confusion (see issue #427). You should now extract the environment separately before calling these functions. } } \examples{ # Environment of closure functions: fn <- function() "foo" get_env(fn) # Or of quosures or formulas: get_env(~foo) get_env(quo(foo)) # Provide a default in case the object doesn't bundle an environment. # Let's create an unevaluated formula: f <- quote(~foo) # The following line would fail if run because unevaluated formulas # don't bundle an environment (they didn't have the chance to # record one yet): # get_env(f) # It is often useful to provide a default when you're writing # functions accepting formulas as input: default <- env() identical(get_env(f, default), default) # set_env() can be used to set the enclosure of functions and # formulas. Let's create a function with a particular environment: env <- child_env("base") fn <- set_env(function() NULL, env) # That function now has `env` as enclosure: identical(get_env(fn), env) identical(get_env(fn), current_env()) # set_env() does not work by side effect. Setting a new environment # for fn has no effect on the original function: other_env <- child_env(NULL) set_env(fn, other_env) identical(get_env(fn), other_env) # Since set_env() returns a new function with a different # environment, you'll need to reassign the result: fn <- set_env(fn, other_env) identical(get_env(fn), other_env) } \seealso{ \code{\link[=quo_get_env]{quo_get_env()}} and \code{\link[=quo_set_env]{quo_set_env()}} for versions of \code{\link[=get_env]{get_env()}} and \code{\link[=set_env]{set_env()}} that only work on quosures. } rlang/man/as_name.Rd0000644000176200001440000000333213413472702014026 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/deparse.R \name{as_name} \alias{as_name} \title{Extract names from symbols} \usage{ as_name(x) } \arguments{ \item{x}{A string or symbol, possibly wrapped in a \link{quosure}. If a string, the attributes are removed, if any.} } \value{ A character vector of length 1. } \description{ \code{as_name()} converts \link[=sym]{symbols} to character strings. The conversion is deterministic. That is, the roundtrip symbol -> name -> symbol always gets the same result. \itemize{ \item Use \code{as_name()} when you need to transform a symbol to a string to \emph{refer} to an object by its name. \item Use \code{\link[=as_label]{as_label()}} when you need to transform any kind of object to a string to \emph{represent} that object with a short description. } Expect \code{as_name()} to gain \href{https://principles.tidyverse.org/names-attribute.html#minimal-unique-universal}{name-repairing} features in the future. Note that \code{rlang::as_name()} is the \emph{opposite} of \code{\link[base:as.name]{base::as.name()}}. If you're writing base R code, we recommend using \code{\link[base:as.symbol]{base::as.symbol()}} which is an alias of \code{as.name()} that follows a more modern terminology (R types instead of S modes). } \examples{ # Let's create some symbols: foo <- quote(foo) bar <- sym("bar") # as_name() converts symbols to strings: foo as_name(foo) typeof(bar) typeof(as_name(bar)) # as_name() unwraps quosured symbols automatically: as_name(quo(foo)) } \seealso{ \code{\link[=as_label]{as_label()}} for converting any object to a single string suitable as a label. \code{\link[=as_string]{as_string()}} for a lower-level version that doesn't unwrap quosures. } rlang/man/new-vector.Rd0000644000176200001440000000233113553606424014517 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/vec-new.R \name{new-vector} \alias{new-vector} \alias{new_logical} \alias{new_integer} \alias{new_double} \alias{new_character} \alias{new_complex} \alias{new_raw} \alias{new_list} \title{Create vectors matching a given length} \usage{ new_logical(n, names = NULL) new_integer(n, names = NULL) new_double(n, names = NULL) new_character(n, names = NULL) new_complex(n, names = NULL) new_raw(n, names = NULL) new_list(n, names = NULL) } \arguments{ \item{n}{The vector length.} \item{names}{Names for the new vector.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} These functions construct vectors of a given length, with attributes specified via dots. Except for \code{new_list()} and \code{new_raw()}, the empty vectors are filled with typed \link{missing} values. This is in contrast to the base function \code{\link[base:vector]{base::vector()}} which creates zero-filled vectors. } \section{Lifecycle}{ These functions are likely to be replaced by a vctrs equivalent in the future. They are in the questioning lifecycle stage. } \examples{ new_list(10) new_logical(10) } \seealso{ rep_along } \keyword{internal} rlang/man/exec.Rd0000644000176200001440000000315613604124170013346 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/eval.R \name{exec} \alias{exec} \title{Execute a function} \usage{ exec(.fn, ..., .env = caller_env()) } \arguments{ \item{.fn}{A function, or function name as a string.} \item{...}{<\link[=dyn-dots]{dynamic}> Arguments for \code{.fn}.} \item{.env}{Environment in which to evaluate the call. This will be most useful if \code{f} is a string, or the function has side-effects.} } \description{ This function constructs and evaluates a call to \code{.fn}. It has two primary uses: \itemize{ \item To call a function with arguments stored in a list (if the function doesn't support \link[=dyn-dots]{dynamic dots}). Splice the list of arguments with \verb{!!!}. \item To call every function stored in a list (in conjunction with \code{map()}/ \code{\link[=lapply]{lapply()}}) } } \examples{ args <- list(x = c(1:10, 100, NA), na.rm = TRUE) exec("mean", !!!args) exec("mean", !!!args, trim = 0.2) fs <- list(a = function() "a", b = function() "b") lapply(fs, exec) # Compare to do.call it will not automatically inline expressions # into the evaluated call. x <- 10 args <- exprs(x1 = x + 1, x2 = x * 2) exec(list, !!!args) do.call(list, args) # exec() is not designed to generate pretty function calls. This is # most easily seen if you call a function that captures the call: f <- disp ~ cyl exec("lm", f, data = mtcars) # If you need finer control over the generated call, you'll need to # construct it yourself. This may require creating a new environment # with carefully constructed bindings data_env <- env(data = mtcars) eval(expr(lm(!!f, data)), data_env) } rlang/man/eval_bare.Rd0000644000176200001440000000740613405732277014360 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/eval.R \name{eval_bare} \alias{eval_bare} \title{Evaluate an expression in an environment} \usage{ eval_bare(expr, env = parent.frame()) } \arguments{ \item{expr}{An expression to evaluate.} \item{env}{The environment in which to evaluate the expression.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("stable")} \code{eval_bare()} is a lower-level version of function \code{\link[base:eval]{base::eval()}}. Technically, it is a simple wrapper around the C function \code{Rf_eval()}. You generally don't need to use \code{eval_bare()} instead of \code{eval()}. Its main advantage is that it handles stack-sensitive (calls such as \code{return()}, \code{on.exit()} or \code{parent.frame()}) more consistently when you pass an enviroment of a frame on the call stack. } \details{ These semantics are possible because \code{eval_bare()} creates only one frame on the call stack whereas \code{eval()} creates two frames, the second of which has the user-supplied environment as frame environment. When you supply an existing frame environment to \code{base::eval()} there will be two frames on the stack with the same frame environment. Stack-sensitive functions only detect the topmost of these frames. We call these evaluation semantics "stack inconsistent". Evaluating expressions in the actual frame environment has useful practical implications for \code{eval_bare()}: \itemize{ \item \code{return()} calls are evaluated in frame environments that might be burried deep in the call stack. This causes a long return that unwinds multiple frames (triggering the \code{on.exit()} event for each frame). By contrast \code{eval()} only returns from the \code{eval()} call, one level up. \item \code{on.exit()}, \code{parent.frame()}, \code{sys.call()}, and generally all the stack inspection functions \code{sys.xxx()} are evaluated in the correct frame environment. This is similar to how this type of calls can be evaluated deep in the call stack because of lazy evaluation, when you force an argument that has been passed around several times. } The flip side of the semantics of \code{eval_bare()} is that it can't evaluate \code{break} or \code{next} expressions even if called within a loop. } \examples{ # eval_bare() works just like base::eval() but you have to create # the evaluation environment yourself: eval_bare(quote(foo), env(foo = "bar")) # eval() has different evaluation semantics than eval_bare(). It # can return from the supplied environment even if its an # environment that is not on the call stack (i.e. because you've # created it yourself). The following would trigger an error with # eval_bare(): ret <- quote(return("foo")) eval(ret, env()) # eval_bare(ret, env()) # "no function to return from" error # Another feature of eval() is that you can control surround loops: bail <- quote(break) while (TRUE) { eval(bail) # eval_bare(bail) # "no loop for break/next" error } # To explore the consequences of stack inconsistent semantics, let's # create a function that evaluates `parent.frame()` deep in the call # stack, in an environment corresponding to a frame in the middle of # the stack. For consistency with R's lazy evaluation semantics, we'd # expect to get the caller of that frame as result: fn <- function(eval_fn) { list( returned_env = middle(eval_fn), actual_env = current_env() ) } middle <- function(eval_fn) { deep(eval_fn, current_env()) } deep <- function(eval_fn, eval_env) { expr <- quote(parent.frame()) eval_fn(expr, eval_env) } # With eval_bare(), we do get the expected environment: fn(rlang::eval_bare) # But that's not the case with base::eval(): fn(base::eval) } \seealso{ \code{\link[=eval_tidy]{eval_tidy()}} for evaluation with data mask and quosure support. } rlang/man/new_node.Rd0000644000176200001440000000343213361376453014232 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/node.R \name{new_node} \alias{new_node} \alias{node_car} \alias{node_cdr} \alias{node_caar} \alias{node_cadr} \alias{node_cdar} \alias{node_cddr} \alias{node_poke_car} \alias{node_poke_cdr} \alias{node_poke_caar} \alias{node_poke_cadr} \alias{node_poke_cdar} \alias{node_poke_cddr} \alias{node_tag} \alias{node_poke_tag} \title{Helpers for pairlist and language nodes} \usage{ new_node(car, cdr = NULL) node_car(x) node_cdr(x) node_caar(x) node_cadr(x) node_cdar(x) node_cddr(x) node_poke_car(x, newcar) node_poke_cdr(x, newcdr) node_poke_caar(x, newcar) node_poke_cadr(x, newcar) node_poke_cdar(x, newcdr) node_poke_cddr(x, newcdr) node_tag(x) node_poke_tag(x, newtag) } \arguments{ \item{car, newcar, cdr, newcdr}{The new CAR or CDR for the node. These can be any R objects.} \item{x}{A language or pairlist node. Note that these functions are barebones and do not perform any type checking.} \item{newtag}{The new tag for the node. This should be a symbol.} } \value{ Setters like \code{node_poke_car()} invisibly return \code{x} modified in place. Getters return the requested node component. } \description{ \strong{Important}: These functions are for expert R programmers only. You should only use them if you feel comfortable manipulating low level R data structures at the C level. We export them at the R level in order to make it easy to prototype C code. They don't perform any type checking and can crash R very easily (try to take the CAR of an integer vector --- save any important objects beforehand!). } \seealso{ \code{\link[=duplicate]{duplicate()}} for creating copy-safe objects and \code{\link[base:pairlist]{base::pairlist()}} for an easier way of creating a linked list of nodes. } \keyword{internal} rlang/man/is_installed.Rd0000644000176200001440000000102513405732277015101 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env-special.R \name{is_installed} \alias{is_installed} \title{Is a package installed in the library?} \usage{ is_installed(pkg) } \arguments{ \item{pkg}{The name of a package.} } \value{ \code{TRUE} if the package is installed, \code{FALSE} otherwise. } \description{ This checks that a package is installed with minimal side effects. If installed, the package will be loaded but not attached. } \examples{ is_installed("utils") is_installed("ggplot5") } rlang/man/parse_expr.Rd0000644000176200001440000000516313604124170014572 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/parse.R \name{parse_expr} \alias{parse_expr} \alias{parse_exprs} \alias{parse_quo} \alias{parse_quos} \title{Parse R code} \usage{ parse_expr(x) parse_exprs(x) parse_quo(x, env) parse_quos(x, env) } \arguments{ \item{x}{Text containing expressions to parse_expr for \code{parse_expr()} and \code{parse_exprs()}. Can also be an R connection, for instance to a file. If the supplied connection is not open, it will be automatically closed and destroyed.} \item{env}{The environment for the quosures. Depending on the use case, a good default might be the \link[=global_env]{global environment} but you might also want to evaluate the R code in an isolated context (perhaps a child of the global environment or of the \link[=base_env]{base environment}).} } \value{ \code{parse_expr()} returns an \link[=is_expression]{expression}, \code{parse_exprs()} returns a list of expressions. Note that for the plural variants the length of the output may be greater than the length of the input. This would happen is one of the strings contain several expressions (such as \code{"foo; bar"}). } \description{ These functions parse and transform text into R expressions. This is the first step to interpret or evaluate a piece of R code written by a programmer. } \details{ \code{parse_expr()} returns one expression. If the text contains more than one expression (separated by semicolons or new lines), an error is issued. On the other hand \code{parse_exprs()} can handle multiple expressions. It always returns a list of expressions (compare to \code{\link[base:parse]{base::parse()}} which returns a base::expression vector). All functions also support R connections. The versions suffixed with \verb{_quo} and \verb{_quos} return \link[=nse-defuse]{quosures} rather than raw expressions. } \section{Life cycle}{ \itemize{ \item \code{parse_quosure()} and \code{parse_quosures()} were soft-deprecated in rlang 0.2.0 and renamed to \code{parse_quo()} and \code{parse_quos()}. This is consistent with the rule that abbreviated suffixes indicate the return type of a function. } } \examples{ # parse_expr() can parse any R expression: parse_expr("mtcars \%>\% dplyr::mutate(cyl_prime = cyl / sd(cyl))") # A string can contain several expressions separated by ; or \n parse_exprs("NULL; list()\n foo(bar)") # You can also parse source files by passing a R connection. Let's # create a file containing R code: path <- tempfile("my-file.R") cat("1; 2; mtcars", file = path) # We can now parse it by supplying a connection: parse_exprs(file(path)) } \seealso{ \code{\link[base:parse]{base::parse()}} } rlang/man/restarting.Rd0000644000176200001440000000466013563532074014617 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cnd-handlers.R \name{restarting} \alias{restarting} \title{Create a restarting handler} \usage{ restarting(.restart, ..., .fields = NULL) } \arguments{ \item{.restart}{The name of a restart.} \item{...}{<\link[=dyn-dots]{dynamic}> Additional arguments passed on the restart function. These arguments are evaluated only once and immediately, when creating the restarting handler.} \item{.fields}{A character vector specifying the fields of the condition that should be passed as arguments to the restart. If named, the names (except empty names \code{""}) are used as argument names for calling the restart function. Otherwise the the fields themselves are used as argument names.} } \description{ This constructor automates the common task of creating an \code{\link[=calling]{calling()}} handler that invokes a restart. } \details{ Jumping to a restart point from a calling handler has two effects. First, the control flow jumps to wherever the restart was established, and the restart function is called (with \code{...}, or \code{.fields} as arguments). Execution resumes from the \code{\link[=with_restarts]{with_restarts()}} call. Secondly, the transfer of the control flow out of the function that signalled the condition means that the handler has dealt with the condition. Thus the condition will not be passed on to other potential handlers established on the stack. } \examples{ # This is a restart that takes a data frame and names as arguments rst_bar <- function(df, nms) { stats::setNames(df, nms) } # This restart is simpler and does not take arguments rst_baz <- function() "baz" # Signalling a condition parameterised with a data frame fn <- function() { with_restarts(signal("A foobar condition occurred", "foo", foo_field = mtcars), rst_bar = rst_bar, rst_baz = rst_baz ) } # Creating a restarting handler that passes arguments `nms` and # `df`, the latter taken from a data field of the condition object restart_bar <- restarting("rst_bar", nms = LETTERS[1:11], .fields = c(df = "foo_field") ) # The restarting handlers jumps to `rst_bar` when `foo` is signalled: with_handlers(fn(), foo = restart_bar) # The restarting() constructor is especially nice to use with # restarts that do not need arguments: with_handlers(fn(), foo = restarting("rst_baz")) } \seealso{ \code{\link[=calling]{calling()}} and \code{\link[=exiting]{exiting()}}. } \keyword{internal} rlang/man/env_bury.Rd0000644000176200001440000000252713563532074014266 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env-binding.R \name{env_bury} \alias{env_bury} \title{Mask bindings by defining symbols deeper in a scope} \usage{ env_bury(.env, ...) } \arguments{ \item{.env}{An environment.} \item{...}{<\link[=dyn-dots]{dynamic}> Named objects (\code{env_bind()}), expressions \code{env_bind_lazy()}, or functions (\code{env_bind_active()}). Use \code{\link[=zap]{zap()}} to remove bindings.} } \value{ A copy of \code{.env} enclosing the new environment containing bindings to \code{...} arguments. } \description{ \code{env_bury()} is like \code{\link[=env_bind]{env_bind()}} but it creates the bindings in a new child environment. This makes sure the new bindings have precedence over old ones, without altering existing environments. Unlike \code{env_bind()}, this function does not have side effects and returns a new environment (or object wrapping that environment). } \examples{ orig_env <- env(a = 10) fn <- set_env(function() a, orig_env) # fn() currently sees `a` as the value `10`: fn() # env_bury() will bury the current scope of fn() behind a new # environment: fn <- env_bury(fn, a = 1000) fn() # Even though the symbol `a` is still defined deeper in the scope: orig_env$a } \seealso{ \code{\link[=env_bind]{env_bind()}}, \code{\link[=env_unbind]{env_unbind()}} } \keyword{internal} rlang/man/env_unlock.Rd0000644000176200001440000000057413351410763014573 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env.R \name{env_unlock} \alias{env_unlock} \title{Unlock an environment} \usage{ env_unlock(env) } \arguments{ \item{env}{An environment.} } \value{ Whether the environment has been unlocked. } \description{ This function should only be used in development tools or interactively. } \keyword{internal} rlang/man/dyn-dots.Rd0000644000176200001440000000250313604124167014164 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dots.R \name{dyn-dots} \alias{dyn-dots} \alias{tidy-dots} \title{Dynamic dots} \description{ The \code{...} syntax of base R allows you to: \itemize{ \item \strong{Forward} arguments from function to function, matching them along the way to function parameters. \item \strong{Collect} arguments inside data structures, e.g. with \code{\link[=c]{c()}} or \code{\link[=list]{list()}}. } Dynamic dots offer a few additional features: \enumerate{ \item You can \strong{splice} arguments saved in a list with the \link[=quasiquotation]{big bang} operator \verb{!!!}. \item You can \strong{unquote} names by using the \link[=quasiquotation]{bang bang} operator \verb{!!} on the left-hand side of \verb{:=}. \item Trailing commas are ignored, making it easier to copy and paste lines of arguments. } } \section{Add dynamic dots support in your functions}{ If your function takes dots, adding support for dynamic features is as easy as collecting the dots with \code{\link[=list2]{list2()}} instead of \code{\link[=list]{list()}}. Other dynamic dots collectors are \code{\link[=dots_list]{dots_list()}}, which is more configurable than \code{\link[=list2]{list2()}}, \code{vars()} which doesn't force its arguments, and \code{\link[=call2]{call2()}} for creating calls. } rlang/man/abort.Rd0000644000176200001440000001412713610366361013540 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cnd-abort.R, R/cnd-signal.R \name{abort} \alias{abort} \alias{warn} \alias{inform} \alias{signal} \alias{interrupt} \title{Signal an error, warning, or message} \usage{ abort( message = NULL, class = NULL, ..., trace = NULL, call, parent = NULL, msg, type, .subclass ) warn(message = NULL, class = NULL, ..., call, msg, type, .subclass) inform( message = NULL, class = NULL, ..., file = NULL, call, msg, type, .subclass ) signal(message, class, ..., .subclass) interrupt() } \arguments{ \item{message}{The message to display. If not supplied, it is expected that the message is generated lazily through \link[=cnd_message]{conditionMessage()}. In that case, \code{class} must be supplied. Only \code{inform()} allows empty messages as it is occasionally useful to build user output incrementally.} \item{class}{Subclass of the condition. This allows your users to selectively handle the conditions signalled by your functions.} \item{...}{Additional data to be stored in the condition object.} \item{trace}{A \code{trace} object created by \code{\link[=trace_back]{trace_back()}}.} \item{call}{Defunct as of rlang 0.4.0. Storing the full backtrace is now preferred to storing a simple call.} \item{parent}{A parent condition object created by \code{\link[=abort]{abort()}}.} \item{msg, type}{These arguments were renamed to \code{message} and \code{.subclass} and are defunct as of rlang 0.4.0.} \item{.subclass}{This argument was renamed to \code{class} in rlang 0.4.2. It will be deprecated in the next major version. This is for consistency with our conventions for class constructors documented in \url{https://adv-r.hadley.nz/s3.html#s3-subclassing}.} \item{file}{Where the message is printed. This should be a connection or character string which will be passed to \code{\link[=cat]{cat()}}. By default, \code{inform()} prints to standard output in interactive sessions and standard error otherwise. This way IDEs can treat messages distinctly from warnings and errors, and R scripts can still filter out the messages easily by redirecting \code{stderr}.} } \description{ These functions are equivalent to base functions \code{\link[base:stop]{base::stop()}}, \code{\link[base:warning]{base::warning()}} and \code{\link[base:message]{base::message()}}, but make it easy to supply condition metadata: \itemize{ \item Supply \code{.subclass} to create a classed condition. Typed conditions can be captured or handled selectively, allowing for finer-grained error handling. \item Supply metadata with named \code{...} arguments. This data will be stored in the condition object and can be examined by handlers. } \code{interrupt()} allows R code to simulate a user interrupt of the kind that is signalled with \code{Ctrl-C}. It is currently not possible to create custom interrupt condition objects. } \section{Backtrace}{ Unlike \code{stop()} and \code{warning()}, these functions don't include call information by default. This saves you from typing \code{call. = FALSE} and produces cleaner error messages. A backtrace is always saved into error objects. You can print a simplified backtrace of the last error by calling \code{\link[=last_error]{last_error()}} and a full backtrace with \code{summary(last_error())}. You can also display a backtrace with the error message by setting the option \code{\link{rlang_backtrace_on_error}}. It supports the following values: \itemize{ \item \code{"reminder"}: Invite users to call \code{rlang::last_error()} to see a backtrace. \item \code{"branch"}: Display a simplified backtrace. \item \code{"collapse"}: Display a collapsed backtrace tree. \item \code{"full"}: Display a full backtrace tree. \item \code{"none"}: Display nothing. } } \section{Mufflable conditions}{ Signalling a condition with \code{inform()} or \code{warn()} causes a message to be displayed in the console. These messages can be muffled with \code{\link[base:suppressMessages]{base::suppressMessages()}} or \code{\link[base:suppressWarnings]{base::suppressWarnings()}}. On recent R versions (>= R 3.5.0), interrupts are typically signalled with a \code{"resume"} restart. This is however not guaranteed. } \section{Lifecycle}{ These functions were changed in rlang 0.3.0 to take condition metadata with \code{...}. Consequently: \itemize{ \item All arguments were renamed to be prefixed with a dot, except for \code{type} which was renamed to \code{.subclass}. \item \code{.call} (previously \code{call}) can no longer be passed positionally. } } \examples{ # These examples are guarded to avoid throwing errors if (FALSE) { # Signal an error with a message just like stop(): abort("Something bad happened") # Give a class to the error: abort("Something bad happened", "somepkg_bad_error") # This will allow your users to handle the error selectively tryCatch( somepkg_function(), somepkg_bad_error = function(err) { warn(conditionMessage(err)) # Demote the error to a warning NA # Return an alternative value } ) # You can also specify metadata that will be stored in the condition: abort("Something bad happened", "somepkg_bad_error", data = 1:10) # This data can then be consulted by user handlers: tryCatch( somepkg_function(), somepkg_bad_error = function(err) { # Compute an alternative return value with the data: recover_error(err$data) } ) # If you call low-level APIs it is good practice to catch technical # errors and rethrow them with a more meaningful message. Pass on # the caught error as `parent` to get a nice decomposition of # errors and backtraces: file <- "http://foo.bar/baz" tryCatch( download(file), error = function(err) { msg <- sprintf("Can't download `\%s`", file) abort(msg, parent = err) }) # Unhandled errors are saved automatically by `abort()` and can be # retrieved with `last_error()`. The error prints with a simplified # backtrace: abort("Saved error?") last_error() # Use `summary()` to print the full backtrace and the condition fields: summary(last_error()) } } \seealso{ \code{\link[=with_abort]{with_abort()}} to convert all errors to rlang errors. } rlang/man/expr_label.Rd0000644000176200001440000000243113604124170014532 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/expr.R \name{expr_label} \alias{expr_label} \alias{expr_name} \alias{expr_text} \title{Turn an expression to a label} \usage{ expr_label(expr) expr_name(expr) expr_text(expr, width = 60L, nlines = Inf) } \arguments{ \item{expr}{An expression to labellise.} \item{width}{Width of each line.} \item{nlines}{Maximum number of lines to extract.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} \code{expr_text()} turns the expression into a single string, which might be multi-line. \code{expr_name()} is suitable for formatting names. It works best with symbols and scalar types, but also accepts calls. \code{expr_label()} formats the expression nicely for use in messages. } \section{Life cycle}{ These functions are in the questioning stage because they are redundant with the \code{quo_} variants and do not handle quosures. } \examples{ # To labellise a function argument, first capture it with # substitute(): fn <- function(x) expr_label(substitute(x)) fn(x:y) # Strings are encoded expr_label("a\nb") # Names and expressions are quoted with `` expr_label(quote(x)) expr_label(quote(a + b + c)) # Long expressions are collapsed expr_label(quote(foo({ 1 + 2 print(x) }))) } rlang/man/flatten.Rd0000644000176200001440000000564213405732277014075 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/vec-squash.R \name{flatten} \alias{flatten} \alias{flatten_lgl} \alias{flatten_int} \alias{flatten_dbl} \alias{flatten_cpl} \alias{flatten_chr} \alias{flatten_raw} \alias{squash} \alias{squash_lgl} \alias{squash_int} \alias{squash_dbl} \alias{squash_cpl} \alias{squash_chr} \alias{squash_raw} \alias{flatten_if} \alias{squash_if} \title{Flatten or squash a list of lists into a simpler vector} \usage{ flatten(x) flatten_lgl(x) flatten_int(x) flatten_dbl(x) flatten_cpl(x) flatten_chr(x) flatten_raw(x) squash(x) squash_lgl(x) squash_int(x) squash_dbl(x) squash_cpl(x) squash_chr(x) squash_raw(x) flatten_if(x, predicate = is_spliced) squash_if(x, predicate = is_spliced) } \arguments{ \item{x}{A list to flatten or squash. The contents of the list can be anything for unsuffixed functions \code{flatten()} and \code{squash()} (as a list is returned), but the contents must match the type for the other functions.} \item{predicate}{A function of one argument returning whether it should be spliced.} } \value{ \code{flatten()} returns a list, \code{flatten_lgl()} a logical vector, \code{flatten_int()} an integer vector, \code{flatten_dbl()} a double vector, and \code{flatten_chr()} a character vector. Similarly for \code{squash()} and the typed variants (\code{squash_lgl()} etc). } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} \code{flatten()} removes one level hierarchy from a list, while \code{squash()} removes all levels. These functions are similar to \code{\link[=unlist]{unlist()}} but they are type-stable so you always know what the type of the output is. } \section{Life cycle}{ These functions are in the questioning stage. They have slightly different semantics than the flattening functions in purrr and we are currently rethinking our approach to flattening with the new typing facilities of the vctrs package. } \examples{ x <- replicate(2, sample(4), simplify = FALSE) x flatten(x) flatten_int(x) # With flatten(), only one level gets removed at a time: deep <- list(1, list(2, list(3))) flatten(deep) flatten(flatten(deep)) # But squash() removes all levels: squash(deep) squash_dbl(deep) # The typed flatten functions remove one level and coerce to an atomic # vector at the same time: flatten_dbl(list(1, list(2))) # Only bare lists are flattened, but you can splice S3 lists # explicitly: foo <- set_attrs(list("bar"), class = "foo") str(flatten(list(1, foo, list(100)))) str(flatten(list(1, splice(foo), list(100)))) # Instead of splicing manually, flatten_if() and squash_if() let # you specify a predicate function: is_foo <- function(x) inherits(x, "foo") || is_bare_list(x) str(flatten_if(list(1, foo, list(100)), is_foo)) # squash_if() does the same with deep lists: deep_foo <- list(1, list(foo, list(foo, 100))) str(deep_foo) str(squash(deep_foo)) str(squash_if(deep_foo, is_foo)) } \keyword{internal} rlang/man/lifecycle.Rd0000644000176200001440000003050413604124170014356 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle.R \name{lifecycle} \alias{lifecycle} \title{Life cycle of the rlang package} \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("maturing")} The rlang package is currently maturing. Unless otherwise stated, this applies to all its exported functions. Maturing functions are susceptible to API changes. Only use these in packages if you're prepared to make changes as the package evolves. See sections below for a list of functions marked as stable. The documentation pages of retired functions contain life cycle sections that explain the reasons for their retirements. } \section{Stable functions}{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("stable")} \itemize{ \item \code{\link[=eval_tidy]{eval_tidy()}} \item \link{!!}, \link{!!!} \item \code{\link[=enquo]{enquo()}}, \code{\link[=quo]{quo()}}, \code{\link[=quos]{quos()}} \item \code{\link[=enexpr]{enexpr()}}, \code{\link[=expr]{expr()}}, \code{\link[=exprs]{exprs()}} \item \code{\link[=sym]{sym()}}, \code{\link[=syms]{syms()}} \item \code{\link[=new_quosure]{new_quosure()}}, \code{\link[=is_quosure]{is_quosure()}} \item \code{\link[=missing_arg]{missing_arg()}}, \code{\link[=is_missing]{is_missing()}} \item \code{\link[=quo_get_expr]{quo_get_expr()}}, \code{\link[=quo_set_expr]{quo_set_expr()}} \item \code{\link[=quo_get_env]{quo_get_env()}}, \code{\link[=quo_set_env]{quo_set_env()}} \item \code{\link[=eval_bare]{eval_bare()}} \item \code{\link[=set_names]{set_names()}}, \code{\link[=names2]{names2()}} \item \code{\link[=as_function]{as_function()}}, \code{\link[=new_function]{new_function()}} } } \section{Experimental functions}{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} These functions are not yet part of the rlang API. Expect breaking changes. \itemize{ \item \code{\link[=with_env]{with_env()}}, \code{\link[=locally]{locally()}}, \code{\link[=env_poke]{env_poke()}} \item \code{\link[=pkg_env]{pkg_env()}}, \code{\link[=pkg_env_name]{pkg_env_name()}}, \code{\link[=ns_env]{ns_env()}}, \code{\link[=ns_imports_env]{ns_imports_env()}}, \code{\link[=ns_env_name]{ns_env_name()}} \item \code{\link[=is_pairlist]{is_pairlist()}}, \code{\link[=as_pairlist]{as_pairlist()}}, \code{\link[=is_node]{is_node()}}, \code{\link[=is_node_list]{is_node_list()}} \item \code{\link[=is_definition]{is_definition()}}, \code{\link[=new_definition]{new_definition()}}, \code{\link[=is_formulaish]{is_formulaish()}}, \code{\link[=dots_definitions]{dots_definitions()}} \item \code{\link[=local_options]{local_options()}}, \code{\link[=with_options]{with_options()}}, \code{\link[=push_options]{push_options()}}, \code{\link[=peek_options]{peek_options()}}, \code{\link[=peek_option]{peek_option()}} \item \code{\link[=as_bytes]{as_bytes()}}, \code{\link[=chr_unserialise_unicode]{chr_unserialise_unicode()}} \item \code{\link[=caller_fn]{caller_fn()}}, \code{\link[=current_fn]{current_fn()}} } } \section{Questioning stage}{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} \strong{In the questioning stage as of rlang 0.4.0} These functions are likely to be moved to the vctrs package: \itemize{ \item \code{\link[=lgl]{lgl()}}, \code{\link[=int]{int()}}, etc. \item \code{\link[=new_logical]{new_logical()}}, \code{\link[=new_integer]{new_integer()}}, etc. \item \link{na_lgl}, \link{na_int}, \code{\link[=is_lgl_na]{is_lgl_na()}}, \code{\link[=is_int_na]{is_int_na()}}, etc. } \strong{In the questioning stage as of rlang 0.3.0} \itemize{ \item \code{\link[=child_env]{child_env()}} \item \code{\link[=flatten]{flatten()}}, \code{\link[=squash]{squash()}}, and their atomic vector variants \item \code{\link[=modify]{modify()}} and \code{\link[=prepend]{prepend()}} \item \code{\link[=with_restarts]{with_restarts()}}, \code{\link[=rst_list]{rst_list()}}, \code{\link[=rst_exists]{rst_exists()}}, \code{\link[=rst_jump]{rst_jump()}}, \code{\link[=rst_maybe_jump]{rst_maybe_jump()}}, \code{\link[=rst_abort]{rst_abort()}}. It is not clear yet whether we want to recommend restarts as a style of programming in R. \item \code{\link[=return_from]{return_from()}} and \code{\link[=return_to]{return_to()}}. \item \code{\link[=expr_label]{expr_label()}}, \code{\link[=expr_name]{expr_name()}}, and \code{\link[=expr_text]{expr_text()}}. } \strong{In the questioning stage as of rlang 0.2.0} \itemize{ \item \code{\link[=UQ]{UQ()}}, \code{\link[=UQS]{UQS()}} \item \code{\link[=dots_splice]{dots_splice()}}, \code{\link[=splice]{splice()}} } } \section{Soft-deprecated functions and arguments}{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("soft-deprecated")} \strong{Soft-deprecated in rlang 0.4.0} \itemize{ \item \code{\link[=exiting]{exiting()}}: Handlers are now treated as exiting by default. \item \code{\link[=invoke]{invoke()}}: Use the simpler \code{\link[=exec]{exec()}} instead. \item \code{\link[=as_logical]{as_logical()}}, \code{\link[=as_integer]{as_integer()}}, etc. => \code{vctrs::vec_cast()}. \item \code{\link[=type_of]{type_of()}}, \code{\link[=switch_type]{switch_type()}}, \code{\link[=coerce_type]{coerce_type()}}, \code{\link[=switch_class]{switch_class()}}, \code{\link[=coerce_class]{coerce_class()}} } } \section{Deprecated functions and arguments}{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} \strong{Bumped to deprecated in rlang 0.4.0} \itemize{ \item \code{\link[=modify]{modify()}} and \code{\link[=prepend]{prepend()}}. \item \code{new_logical_along()}, \code{new_integer_along()}, \code{new_double_along()}, \code{new_complex_along()}, \code{new_character_along()}, \code{new_raw_along()}, \code{new_list_along()}. \item \code{\link[=lang_modify]{lang_modify()}} => \code{\link[=call_modify]{call_modify()}} \item \code{\link[=lang_standardise]{lang_standardise()}} => \code{\link[=call_standardise]{call_standardise()}} \item \code{\link[=lang_fn]{lang_fn()}} => \code{\link[=call_fn]{call_fn()}} \item \code{\link[=lang_name]{lang_name()}} => \code{\link[=call_name]{call_name()}} \item \code{\link[=lang_args]{lang_args()}} => \code{\link[=call_args]{call_args()}} \item \code{\link[=lang_args_names]{lang_args_names()}} => \code{\link[=call_args_names]{call_args_names()}} \item \code{\link[=lang_head]{lang_head()}}, \code{\link[=lang_tail]{lang_tail()}} \item \code{\link[=lang]{lang()}} => \code{\link[=call2]{call2()}} \item \code{\link[=new_language]{new_language()}} => \code{\link[=new_call]{new_call()}} \item \code{\link[=is_lang]{is_lang()}} => \code{\link[=is_call]{is_call()}} \item \code{\link[=is_unary_lang]{is_unary_lang()}} => Use the \code{n} argument of \code{\link[=is_call]{is_call()}} \item \code{\link[=is_binary_lang]{is_binary_lang()}} => Use the \code{n} argument of \code{\link[=is_call]{is_call()}} \item \code{\link[=quo_is_lang]{quo_is_lang()}} => \code{\link[=quo_is_call]{quo_is_call()}} \item \code{\link[=call_modify]{call_modify()}}: \code{.standardise} and \code{.env} arguments. \item \code{\link[=is_expr]{is_expr()}} => \code{\link[=is_expression]{is_expression()}} \item \code{quo_expr()} => \code{\link[=quo_squash]{quo_squash()}} \item \code{\link[=parse_quosure]{parse_quosure()}} => \code{\link[=parse_quo]{parse_quo()}} \item \code{\link[=parse_quosures]{parse_quosures()}} => \code{\link[=parse_quos]{parse_quos()}} \item Assigning non-quosure objects to quosure lists. \item \code{as.character()} on quosures. \item \code{\link[=cnd_signal]{cnd_signal()}}: \code{.cnd} => \code{cnd} \item \code{\link[=cnd_signal]{cnd_signal()}}: The \code{.mufflable} argument no longer has any effect \item \code{scoped_names()} => \code{\link[base:search]{base::search()}} \item \code{is_scoped()} => \code{\link[=is_attached]{is_attached()}} \item \code{scoped_env()} => \code{\link[=search_env]{search_env()}} \item \code{scoped_envs()} => \code{\link[=search_envs]{search_envs()}} \item \code{env_bind_exprs()} => \code{\link[=env_bind_lazy]{env_bind_lazy()}} \item \code{env_bind_fns()} => \code{\link[=env_bind_active]{env_bind_active()}} \item Passing a function or formula to \code{env_depth()}, \code{env_poke_parent()}, \verb{env_parent<-}, \code{env_tail()}, \code{set_env()}, \code{env_clone()}, \code{env_inherits()}, \code{env_bind()}, \code{local_bindings()}, \code{with_bindings()}, \code{env_poke()}, \code{env_has()}, \code{env_get()}, \code{env_names()}, \code{env_bind_exprs()} and \code{env_bind_fns()}. This internal genericity was causing confusion (see issue #427). You should now extract the environment separately before calling these functions. \item \code{\link[=get_env]{get_env()}}: The \code{env} argument no longer has a default and must be supplied \item \code{\link[=is_frame]{is_frame()}}, \code{\link[=global_frame]{global_frame()}}, \code{\link[=current_frame]{current_frame()}}, \code{\link[=ctxt_frame]{ctxt_frame()}}, \code{\link[=call_frame]{call_frame()}}, \code{\link[=frame_position]{frame_position()}}, \code{\link[=caller_frame]{caller_frame()}} \item \code{\link[=ctxt_depth]{ctxt_depth()}}, \code{\link[=call_depth]{call_depth()}}, \code{\link[=ctxt_stack]{ctxt_stack()}}, \code{\link[=call_stack]{call_stack()}}, \code{\link[=stack_trim]{stack_trim()}} \item \code{\link[=set_attrs]{set_attrs()}}, \code{\link[=mut_attrs]{mut_attrs()}} \item The \code{width} and \code{printer} arguments of \code{\link[=exprs_auto_name]{exprs_auto_name()}} and \code{\link[=quos_auto_name]{quos_auto_name()}} no longer have any effect. For the same reason, passing a width as \code{.named} argument of dots collectors like \code{quos()} is deprecated. \item \code{as_overscope()} => \code{\link[=as_data_mask]{as_data_mask()}} \item \code{new_overscope()} => \code{\link[=new_data_mask]{new_data_mask()}} \item \code{overscope_eval_next()} => \code{\link[=eval_tidy]{eval_tidy()}} \item \code{overscope_clean()} } } \section{Defunct functions and arguments}{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("defunct")} \strong{Defunct as of rlang 0.4.0} \itemize{ \item \code{length()} and \code{names()} on tidy eval \code{.data} pronouns. \item Supplying a named \verb{!!!} call. \item \code{\link[=as_data_mask]{as_data_mask()}}: \code{parent} argument \item \code{\link[=new_data_mask]{new_data_mask()}}: \code{parent} argument \item \code{\link[=env_tail]{env_tail()}}: \code{sentinel} => \code{last} \item \code{\link[=abort]{abort()}}, \code{\link[=warn]{warn()}}, \code{\link[=inform]{inform()}}: \code{msg}, \code{type} => \code{.msg}, \code{.type} \item \code{\link[=abort]{abort()}}, \code{\link[=warn]{warn()}}, \code{\link[=inform]{inform()}}, \code{\link[=cnd]{cnd()}}, \code{\link[=error_cnd]{error_cnd()}}, \code{\link[=warning_cnd]{warning_cnd()}}, \code{\link[=message_cnd]{message_cnd()}}: \code{call} argument. \item \code{\link[=is_character]{is_character()}}, \code{\link[=is_string]{is_string()}}, and variants: The \code{encoding} argument. } } \section{Archived}{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("archived")} These functions were entirely removed from the package. You will find them in the commit history and previous releases. \strong{Archived as of rlang 0.4.0} \itemize{ \item \code{UQE()} \item \code{as_dictionary()}, \code{is_dictionary()} \item \code{as_quosureish()}, \code{is_quosureish()} \item \code{eval_tidy_()} \item \code{mut_utf8_locale()}, \code{mut_latin1_locale()}, \code{mut_mbcs_locale()} \item \code{set_chr_encoding()}, \code{chr_encoding()}, \code{set_str_encoding()}, \code{str_encoding()} \item \code{as_native_character()}, \code{as_utf8_string()}, \code{as_native_string()} \item \code{lang_type_of()}, \code{switch_lang()}, \code{coerce_lang()} } \strong{Archived as of rlang 0.3.0:} \itemize{ \item \code{cnd_inform()}, \code{cnd_warn()} and \code{cnd_abort()} \item \code{new_cnd()} => \code{\link[=cnd]{cnd()}} \item \code{cnd_message()} => \code{\link[=message_cnd]{message_cnd()}} \item \code{cnd_warning()} => \code{\link[=warning_cnd]{warning_cnd()}} \item \code{cnd_error()} => \code{\link[=error_cnd]{error_cnd()}} \item \code{rst_muffle()} => \code{\link[=cnd_muffle]{cnd_muffle()}} \item \code{inplace()} => \code{\link[=calling]{calling()}}. The \code{muffle} argument of \code{inplace()} has not been implemented in \code{calling()} and is now defunct. \item \code{\link[=cnd_signal]{cnd_signal()}}: \code{.msg} and \code{.call}. \item \code{\link[=cnd]{cnd()}}, \code{\link[=error_cnd]{error_cnd()}}, \code{\link[=warning_cnd]{warning_cnd()}} and \code{\link[=message_cnd]{message_cnd()}}: \code{.msg} => \code{message}. } } \keyword{internal} rlang/man/string.Rd0000644000176200001440000000260313604124170013724 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils-encoding.R \name{string} \alias{string} \title{Create a string} \usage{ string(x, encoding = NULL) } \arguments{ \item{x}{A character vector or a vector or list of string-like objects.} \item{encoding}{If non-null, set an encoding mark. This is only declarative, no encoding conversion is performed.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} These base-type constructors allow more control over the creation of strings in R. They take character vectors or string-like objects (integerish or raw vectors), and optionally set the encoding. The string version checks that the input contains a scalar string. } \examples{ # As everywhere in R, you can specify a string with Unicode # escapes. The characters corresponding to Unicode codepoints will # be encoded in UTF-8, and the string will be marked as UTF-8 # automatically: cafe <- string("caf\uE9") Encoding(cafe) as_bytes(cafe) # In addition, string() provides useful conversions to let # programmers control how the string is represented in memory. For # encodings other than UTF-8, you'll need to supply the bytes in # hexadecimal form. If it is a latin1 encoding, you can mark the # string explicitly: cafe_latin1 <- string(c(0x63, 0x61, 0x66, 0xE9), "latin1") Encoding(cafe_latin1) as_bytes(cafe_latin1) } \keyword{internal} rlang/man/new_quosures.Rd0000644000176200001440000000174113563526752015177 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/quo.R \name{new_quosures} \alias{new_quosures} \alias{as_quosures} \alias{is_quosures} \title{Create a list of quosures} \usage{ new_quosures(x) as_quosures(x, env, named = FALSE) is_quosures(x) } \arguments{ \item{x}{A list of quosures or objects to coerce to quosures.} \item{env}{The default environment for the new quosures.} \item{named}{Whether to name the list with \code{\link[=quos_auto_name]{quos_auto_name()}}.} } \description{ This small S3 class provides methods for \code{[} and \code{c()} and ensures the following invariants: \itemize{ \item The list only contains quosures. \item It is always named, possibly with a vector of empty strings. } \code{new_quosures()} takes a list of quosures and adds the \code{quosures} class and a vector of empty names if needed. \code{as_quosures()} calls \code{\link[=as_quosure]{as_quosure()}} on all elements before creating the \code{quosures} object. } rlang/man/search_envs.Rd0000644000176200001440000000564213604124167014732 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env-special.R \name{search_envs} \alias{search_envs} \alias{search_env} \alias{pkg_env} \alias{pkg_env_name} \alias{is_attached} \alias{base_env} \alias{global_env} \title{Search path environments} \usage{ search_envs() search_env(name) pkg_env(pkg) pkg_env_name(pkg) is_attached(x) base_env() global_env() } \arguments{ \item{name}{The name of an environment attached to the search path. Call \code{\link[base:search]{base::search()}} to get the names of environments currently attached to the search path. Note that the search name of a package environment is prefixed with \code{"package:"}.} \item{pkg}{The name of a package.} \item{x}{An environment or a search name.} } \description{ The search path is a chain of environments containing exported functions of attached packages. The API includes: \itemize{ \item \code{\link[base:search]{base::search()}} to get the names of environments attached to the search path. \item \code{search_envs()} returns the environments on the search path as a list. \item \code{pkg_env_name()} takes a bare package name and prefixes it with \code{"package:"}. Attached package environments have search names of the form \code{package:name}. \item \code{pkg_env()} takes a bare package name and returns the scoped environment of packages if they are attached to the search path, and throws an error otherwise. It is a shortcut for \code{search_env(pkg_env_name("pkgname"))}. \item \code{is_attached()} returns \code{TRUE} when its argument (a search name or a package environment) is attached to the search path. } } \section{The search path}{ This chain of environments determines what objects are visible from the global workspace. It contains the following elements: \itemize{ \item The chain always starts with \code{global_env()} and finishes with \code{base_env()} (technically, it finishes with the \code{empty_env()} which the base package environment inherits from). \item Each \code{\link[base:library]{base::library()}} call attaches a new package environment to the search path. Attached packages are associated with a \link[=env_name]{search name}. \item In addition, any list, data frame, or environment can be attached to the search path with \code{\link[base:attach]{base::attach()}}. } } \examples{ # List the search names of environments attached to the search path: search() # Get the corresponding environments: search_envs() # The global environment and the base package are always first and # last in the chain, respectively: envs <- search_envs() envs[[1]] envs[[length(envs)]] # These two environments have their own shortcuts: global_env() base_env() # Packages appear in the search path with a special name. Use # pkg_env_name() to create that name: pkg_env_name("rlang") search_env(pkg_env_name("rlang")) # Alternatively, get the scoped environment of a package with # pkg_env(): pkg_env("utils") } \keyword{internal} rlang/man/rst_abort.Rd0000644000176200001440000000326313604124167014426 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cnd-restarts.R \name{rst_abort} \alias{rst_abort} \title{Jump to the abort restart} \usage{ rst_abort() } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} The abort restart is the only restart that is established at top level. It is used by R as a top-level target, most notably when an error is issued (see \code{\link[=abort]{abort()}}) that no handler is able to deal with (see \code{\link[=with_handlers]{with_handlers()}}). } \section{Life cycle}{ All the restart functions are in the questioning stage. It is not clear yet whether we want to recommend restarts as a style of programming in R. } \examples{ # The `abort` restart is a bit special in that it is always # registered in a R session. You will always find it on the restart # stack because it is established at top level: rst_list() # You can use the `above` restart to jump to top level without # signalling an error: \dontrun{ fn <- function() { cat("aborting...\n") rst_abort() cat("This is never called\n") } { fn() cat("This is never called\n") } } # The `above` restart is the target that R uses to jump to top # level when critical errors are signalled: \dontrun{ { abort("error") cat("This is never called\n") } } # If another `abort` restart is specified, errors are signalled as # usual but then control flow resumes with from the new restart: \dontrun{ out <- NULL { out <- with_restarts(abort("error"), abort = function() "restart!") cat("This is called\n") } cat("`out` has now become:", out, "\n") } } \seealso{ \code{\link[=rst_jump]{rst_jump()}}, \code{\link[=abort]{abort()}} } \keyword{internal} rlang/man/as_pairlist.Rd0000644000176200001440000000100613351410654014730 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/node.R \name{as_pairlist} \alias{as_pairlist} \title{Coerce to pairlist} \usage{ as_pairlist(x) } \arguments{ \item{x}{An object to coerce.} } \description{ This transforms vector objects to a linked pairlist of nodes. See the \link[=node]{pairlist} type help page. } \section{Life cycle}{ \code{as_pairlist()} is experimental because we are still figuring out the naming scheme for pairlists and node-like objects. } \keyword{internal} rlang/man/env_parent.Rd0000644000176200001440000000456213500414125014562 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env.R \name{env_parent} \alias{env_parent} \alias{env_tail} \alias{env_parents} \title{Get parent environments} \usage{ env_parent(env = caller_env(), n = 1) env_tail(env = caller_env(), last = global_env(), sentinel = NULL) env_parents(env = caller_env(), last = global_env()) } \arguments{ \item{env}{An environment.} \item{n}{The number of generations to go up.} \item{last}{The environment at which to stop. Defaults to the global environment. The empty environment is always a stopping condition so it is safe to leave the default even when taking the tail or the parents of an environment on the search path. \code{env_tail()} returns the environment which has \code{last} as parent and \code{env_parents()} returns the list of environments up to \code{last}.} \item{sentinel}{This argument is defunct, please use \code{last} instead.} } \value{ An environment for \code{env_parent()} and \code{env_tail()}, a list of environments for \code{env_parents()}. } \description{ \itemize{ \item \code{env_parent()} returns the parent environment of \code{env} if called with \code{n = 1}, the grandparent with \code{n = 2}, etc. \item \code{env_tail()} searches through the parents and returns the one which has \code{\link[=empty_env]{empty_env()}} as parent. \item \code{env_parents()} returns the list of all parents, including the empty environment. This list is named using \code{\link[=env_name]{env_name()}}. } See the section on \emph{inheritance} in \code{\link[=env]{env()}}'s documentation. } \section{Life cycle}{ The \code{sentinel} argument of \code{env_tail()} has been deprecated in rlang 0.2.0 and renamed to \code{last}. It is defunct as of rlang 0.4.0. } \examples{ # Get the parent environment with env_parent(): env_parent(global_env()) # Or the tail environment with env_tail(): env_tail(global_env()) # By default, env_parent() returns the parent environment of the # current evaluation frame. If called at top-level (the global # frame), the following two expressions are equivalent: env_parent() env_parent(base_env()) # This default is more handy when called within a function. In this # case, the enclosure environment of the function is returned # (since it is the parent of the evaluation frame): enclos_env <- env() fn <- set_env(function() env_parent(), enclos_env) identical(enclos_env, fn()) } rlang/man/stack_trim.Rd0000644000176200001440000000356613500223442014564 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{stack_trim} \alias{stack_trim} \title{Trim top call layers from the evaluation stack} \usage{ stack_trim(stack, n = 1) } \arguments{ \item{stack}{An evaluation stack.} \item{n}{The number of call frames (not eval frames) to trim off the top of the stack. In other words, the number of layers of intervening frames to trim.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} \code{\link[=ctxt_stack]{ctxt_stack()}} can be tricky to use in real code because all intervening frames are returned with the stack, including those at \code{ctxt_stack()} own call site. \code{stack_trim()} makes it easy to remove layers of intervening calls. } \section{Life cycle}{ These functions are deprecated and replaced by \code{\link[=trace_back]{trace_back()}}. } \examples{ # Intervening frames appear on the evaluation stack: identity(identity(ctxt_stack())) # stack_trim() will trim the first n layers of calls: stack_trim(identity(identity(ctxt_stack()))) # Note that it also takes care of calls intervening at its own call # site: identity(identity( stack_trim(identity(identity(ctxt_stack()))) )) # It is especially useful when used within a function that needs to # inspect the evaluation stack but should nonetheless be callable # within nested calls without side effects: stack_util <- function() { # n = 2 means that two layers of intervening calls should be # removed: The layer at ctxt_stack()'s call site (including the # stack_trim() call), and the layer at stack_util()'s call. stack <- stack_trim(ctxt_stack(), n = 2) stack } user_fn <- function() { # A user calls your stack utility with intervening frames: identity(identity(stack_util())) } # These intervening frames won't appear in the evaluation stack identity(user_fn()) } \keyword{internal} rlang/man/as_quosure.Rd0000644000176200001440000000275313405732277014626 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/quo.R \name{as_quosure} \alias{as_quosure} \alias{new_quosure} \title{Coerce object to quosure} \usage{ as_quosure(x, env = NULL) new_quosure(expr, env = caller_env()) } \arguments{ \item{x}{An object to convert. Either an \link[=is_expression]{expression} or a formula.} \item{env}{The environment in which the expression should be evaluated. Only used for symbols and calls. This should typically be the environment in which the expression was created.} \item{expr}{The expression wrapped by the quosure.} } \description{ While \code{new_quosure()} wraps any R object (including expressions, formulas, or other quosures) into a quosure, \code{as_quosure()} converts formulas and quosures and does not double-wrap. } \section{Life cycle}{ \itemize{ \item \code{as_quosure()} now requires an explicit default environment for creating quosures from symbols and calls. \item \code{as_quosureish()} is deprecated as of rlang 0.2.0. This function assumes that quosures are formulas which is currently true but might not be in the future. } } \examples{ # as_quosure() converts expressions or any R object to a validly # scoped quosure: env <- env(var = "thing") as_quosure(quote(var), env) # The environment is ignored for formulas: as_quosure(~foo, env) as_quosure(~foo) # However you must supply it for symbols and calls: try(as_quosure(quote(var))) } \seealso{ \code{\link[=quo]{quo()}}, \code{\link[=is_quosure]{is_quosure()}} } rlang/man/ns_env.Rd0000644000176200001440000000220513460040301013675 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env-special.R \name{ns_env} \alias{ns_env} \alias{ns_imports_env} \alias{ns_env_name} \title{Get the namespace of a package} \usage{ ns_env(x = caller_env()) ns_imports_env(x = caller_env()) ns_env_name(x = caller_env()) } \arguments{ \item{x}{\itemize{ \item For \code{ns_env()}, the name of a package or an environment as a string. \itemize{ \item An environment (the current environment by default). \item A function. } In the latter two cases, the environment ancestry is searched for a namespace with \code{\link[base:topenv]{base::topenv()}}. If the environment doesn't inherit from a namespace, this is an error. }} \item{env}{A namespace environment.} } \description{ Namespaces are the environment where all the functions of a package live. The parent environments of namespaces are the \code{imports} environments, which contain all the functions imported from other packages. } \section{Life cycle}{ These functions are experimental and may not belong to the rlang package. Expect API changes. } \seealso{ \code{\link[=pkg_env]{pkg_env()}} } \keyword{internal} rlang/man/is_formula.Rd0000644000176200001440000000320713563526752014577 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/formula.R \name{is_formula} \alias{is_formula} \alias{is_bare_formula} \title{Is object a formula?} \usage{ is_formula(x, scoped = NULL, lhs = NULL) is_bare_formula(x, scoped = NULL, lhs = NULL) } \arguments{ \item{x}{An object to test.} \item{scoped}{A boolean indicating whether the quosure is scoped, that is, has a valid environment attribute. If \code{NULL}, the scope is not inspected.} \item{lhs}{A boolean indicating whether the \link[=is_formula]{formula} or \link[=is_definition]{definition} has a left-hand side. If \code{NULL}, the LHS is not inspected.} } \description{ \code{is_formula()} tests if \code{x} is a call to \code{~}. \code{is_bare_formula()} tests in addition that \code{x} does not inherit from anything else than \code{"formula"}. } \details{ The \code{scoped} argument patterns-match on whether the scoped bundled with the quosure is valid or not. Invalid scopes may happen in nested quotations like \code{~~expr}, where the outer quosure is validly scoped but not the inner one. This is because \code{~} saves the environment when it is evaluated, and quoted formulas are by definition not evaluated. } \examples{ x <- disp ~ am is_formula(x) is_formula(~10) is_formula(10) is_formula(quo(foo)) is_bare_formula(quo(foo)) # Note that unevaluated formulas are treated as bare formulas even # though they don't inherit from "formula": f <- quote(~foo) is_bare_formula(f) # However you can specify `scoped` if you need the predicate to # return FALSE for these unevaluated formulas: is_bare_formula(f, scoped = TRUE) is_bare_formula(eval(f), scoped = TRUE) } rlang/man/call_args.Rd0000644000176200001440000000210313500223442014335 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/call.R \name{call_args} \alias{call_args} \alias{call_args_names} \title{Extract arguments from a call} \usage{ call_args(call) call_args_names(call) } \arguments{ \item{call}{Can be a call or a quosure that wraps a call.} } \value{ A named list of arguments. } \description{ Extract arguments from a call } \section{Life cycle}{ In rlang 0.2.0, \code{lang_args()} and \code{lang_args_names()} were deprecated and renamed to \code{call_args()} and \code{call_args_names()}. See lifecycle section in \code{\link[=call2]{call2()}} for more about this change. } \examples{ call <- quote(f(a, b)) # Subsetting a call returns the arguments converted to a language # object: call[-1] # On the other hand, call_args() returns a regular list that is # often easier to work with: str(call_args(call)) # When the arguments are unnamed, a vector of empty strings is # supplied (rather than NULL): call_args_names(call) } \seealso{ \code{\link[=fn_fmls]{fn_fmls()}} and \code{\link[=fn_fmls_names]{fn_fmls_names()}} } rlang/man/lang_modify.Rd0000644000176200001440000000217613563532074014725 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{lang_modify} \alias{lang_modify} \alias{lang_standardise} \alias{lang_fn} \alias{lang_name} \alias{lang_args} \alias{lang_args_names} \title{Manipulate or access a call} \usage{ lang_modify(.lang, ..., .standardise = FALSE) lang_standardise(lang) lang_fn(lang) lang_name(lang) lang_args(lang) lang_args_names(lang) } \arguments{ \item{...}{<\link[=dyn-dots]{dynamic}> Named or unnamed expressions (constants, names or calls) used to modify the call. Use \code{\link[=zap]{zap()}} to remove arguments. Empty arguments are preserved.} \item{.standardise}{Soft-deprecated as of rlang 0.3.0. Please call \code{\link[=call_standardise]{call_standardise()}} manually.} \item{lang, .lang}{The \code{call} or \code{.call} argument of the renamed functions.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} These functions are deprecated, please use \code{\link[=call_modify]{call_modify()}}, \code{\link[=call_standardise]{call_standardise()}}, or \code{\link[=call_fn]{call_fn()}} instead. } \keyword{internal} rlang/man/as_label.Rd0000644000176200001440000000436413604124167014174 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/deparse.R \name{as_label} \alias{as_label} \title{Create a default name for an R object} \usage{ as_label(x) } \arguments{ \item{x}{An object.} } \description{ \code{as_label()} transforms R objects into a short, human-readable description. You can use labels to: \itemize{ \item Display an object in a concise way, for example to labellise axes in a graphical plot. \item Give default names to columns in a data frame. In this case, labelling is the first step before name repair. } See also \code{\link[=as_name]{as_name()}} for transforming symbols back to a string. Unlike \code{as_label()}, \code{as_string()} is a well defined operation that guarantees the roundtrip symbol -> string -> symbol. In general, if you don't know for sure what kind of object you're dealing with (a call, a symbol, an unquoted constant), use \code{as_label()} and make no assumption about the resulting string. If you know you have a symbol and need the name of the object it refers to, use \code{\link[=as_string]{as_string()}}. For instance, use \code{as_label()} with objects captured with \code{enquo()} and \code{as_string()} with symbols captured with \code{ensym()}. } \section{Transformation to string}{ \itemize{ \item Quosures are \link[=quo_squash]{squashed} before being labelled. \item Symbols are transformed to string with \code{as_string()}. \item Calls are abbreviated. \item Numbers are represented as such. \item Other constants are represented by their type, such as \verb{} or \verb{}. } Note that simple symbols should generally be transformed to strings with \code{\link[=as_name]{as_name()}}. Labelling is not a well defined operation and no assumption should be made about how the label is created. On the other hand, \code{as_name()} only works with symbols and is a well defined, deterministic operation. } \examples{ # as_label() is useful with quoted expressions: as_label(expr(foo(bar))) as_label(expr(foobar)) # It works with any R object. This is also useful for quoted # arguments because the user might unquote constant objects: as_label(1:3) as_label(base::list) } \seealso{ \code{\link[=as_name]{as_name()}} for transforming symbols back to a string deterministically. } rlang/man/lang_head.Rd0000644000176200001440000000100313553606252014322 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{lang_head} \alias{lang_head} \alias{lang_tail} \title{Return the head or tail of a call} \usage{ lang_head(lang) lang_tail(lang) } \arguments{ \item{lang}{A call.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} As of rlang 0.2.0 these functions are retired (deprecated for now) because they are low level accessors that are rarely needed for end users. } \keyword{internal} rlang/man/is_lang.Rd0000644000176200001440000000275513500223442014037 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{is_lang} \alias{is_lang} \alias{is_unary_lang} \alias{is_binary_lang} \alias{quo_is_lang} \title{Is object a call?} \usage{ is_lang(x, name = NULL, n = NULL, ns = NULL) is_unary_lang(x, name = NULL, ns = NULL) is_binary_lang(x, name = NULL, ns = NULL) quo_is_lang(quo) } \arguments{ \item{x}{An object to test. If a formula, the right-hand side is extracted.} \item{name}{An optional name that the call should match. It is passed to \code{\link[=sym]{sym()}} before matching. This argument is vectorised and you can supply a vector of names to match. In this case, \code{is_call()} returns \code{TRUE} if at least one name matches.} \item{n}{An optional number of arguments that the call should match.} \item{ns}{The namespace of the call. If \code{NULL}, the namespace doesn't participate in the pattern-matching. If an empty string \code{""} and \code{x} is a namespaced call, \code{is_call()} returns \code{FALSE}. If any other string, \code{is_call()} checks that \code{x} is namespaced within \code{ns}. Can be a character vector of namespaces, in which case the call has to match at least one of them, otherwise \code{is_call()} returns \code{FALSE}.} \item{quo}{A quosure to test.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} These functions are deprecated, please use \code{\link[=is_call]{is_call()}} and its \code{n} argument instead. } \keyword{internal} rlang/man/vector-old-ctors.Rd0000644000176200001440000000203713604124170015625 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{node} \alias{node} \alias{vector-old-ctors} \alias{lgl_len} \alias{int_len} \alias{dbl_len} \alias{chr_len} \alias{cpl_len} \alias{raw_len} \alias{bytes_len} \alias{list_len} \alias{lgl_along} \alias{int_along} \alias{dbl_along} \alias{chr_along} \alias{cpl_along} \alias{raw_along} \alias{bytes_along} \alias{list_along} \title{Retired vector construction by length} \usage{ node(car, cdr = NULL) lgl_len(.n) int_len(.n) dbl_len(.n) chr_len(.n) cpl_len(.n) raw_len(.n) bytes_len(.n) list_len(.n) lgl_along(.x) int_along(.x) dbl_along(.x) chr_along(.x) cpl_along(.x) raw_along(.x) bytes_along(.x) list_along(.x) } \arguments{ \item{.n}{The vector length.} \item{.x}{A vector.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} These functions were deprecated and renamed with \code{new_} prefix in rlang 0.2.0. This is for consistency with other non-variadic object constructors. } \keyword{internal} rlang/man/seq2.Rd0000644000176200001440000000147013500441351013267 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/vec.R \name{seq2} \alias{seq2} \alias{seq2_along} \title{Increasing sequence of integers in an interval} \usage{ seq2(from, to) seq2_along(from, x) } \arguments{ \item{from}{The starting point of the sequence.} \item{to}{The end point.} \item{x}{A vector whose length is the end point.} } \value{ An integer vector containing a strictly increasing sequence. } \description{ These helpers take two endpoints and return the sequence of all integers within that interval. For \code{seq2_along()}, the upper endpoint is taken from the length of a vector. Unlike \code{base::seq()}, they return an empty vector if the starting point is a larger integer than the end point. } \examples{ seq2(2, 10) seq2(10, 2) seq(10, 2) seq2_along(10, letters) } rlang/man/is_expr.Rd0000644000176200001440000000100313500223442014055 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{is_expr} \alias{is_expr} \title{Is an object an expression?} \usage{ is_expr(x) } \arguments{ \item{x}{An object to test.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} This function was deprecated and renamed to \code{\link[=is_expression]{is_expression()}} in rlang 0.2.0. This is for consistency with other type predicates which are not abbreviated. } \keyword{internal} rlang/man/switch_type.Rd0000644000176200001440000000423413504161362014765 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{switch_type} \alias{switch_type} \alias{coerce_type} \alias{switch_class} \alias{coerce_class} \title{Dispatch on base types} \usage{ switch_type(.x, ...) coerce_type(.x, .to, ...) switch_class(.x, ...) coerce_class(.x, .to, ...) } \arguments{ \item{.x}{An object from which to dispatch.} \item{...}{Named clauses. The names should be types as returned by \code{\link[=type_of]{type_of()}}.} \item{.to}{This is useful when you switchpatch within a coercing function. If supplied, this should be a string indicating the target type. A catch-all clause is then added to signal an error stating the conversion failure. This type is prettified unless \code{.to} inherits from the S3 class \code{"AsIs"} (see \code{\link[base:I]{base::I()}}).} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("soft-deprecated")} \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} \code{switch_type()} is equivalent to \code{\link[base]{switch}(\link{type_of}(x, ...))}, while \code{switch_class()} switchpatches based on \code{class(x)}. The \code{coerce_} versions are intended for type conversion and provide a standard error message when conversion fails. } \examples{ switch_type(3L, double = "foo", integer = "bar", "default" ) # Use the coerce_ version to get standardised error handling when no # type matches: to_chr <- function(x) { coerce_type(x, "a chr", integer = as.character(x), double = as.character(x) ) } to_chr(3L) # Strings have their own type: switch_type("str", character = "foo", string = "bar", "default" ) # Use a fallthrough clause if you need to dispatch on all character # vectors, including strings: switch_type("str", string = , character = "foo", "default" ) # special and builtin functions are treated as primitive, since # there is usually no reason to treat them differently: switch_type(base::list, primitive = "foo", "default" ) switch_type(base::`$`, primitive = "foo", "default" ) # closures are not primitives: switch_type(rlang::switch_type, primitive = "foo", "default" ) } \keyword{internal} rlang/man/env_poke.Rd0000644000176200001440000000364513604124167014241 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/env-binding.R \name{env_poke} \alias{env_poke} \title{Poke an object in an environment} \usage{ env_poke(env = caller_env(), nm, value, inherit = FALSE, create = !inherit) } \arguments{ \item{env}{An environment.} \item{nm}{Names of bindings. \code{nm} must be a single string.} \item{value}{The value for a new binding.} \item{inherit}{Whether to look for bindings in the parent environments.} \item{create}{Whether to create a binding if it does not already exist in the environment.} } \value{ The old value of \code{nm} or a \link[=zap]{zap sentinel} if the binding did not exist yet. } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} \code{env_poke()} will assign or reassign a binding in \code{env} if \code{create} is \code{TRUE}. If \code{create} is \code{FALSE} and a binding does not already exists, an error is issued. } \details{ If \code{inherit} is \code{TRUE}, the parents environments are checked for an existing binding to reassign. If not found and \code{create} is \code{TRUE}, a new binding is created in \code{env}. The default value for \code{create} is a function of \code{inherit}: \code{FALSE} when inheriting, \code{TRUE} otherwise. This default makes sense because the inheriting case is mostly for overriding an existing binding. If not found, something probably went wrong and it is safer to issue an error. Note that this is different to the base R operator \verb{<<-} which will create a binding in the global environment instead of the current environment when no existing binding is found in the parents. } \section{Life cycle}{ \code{env_poke()} is experimental. We are still experimenting with reducing the number of redundant functions by using quasiquotation. It is possible \code{env_poke()} will be deprecated in favour of \code{env_bind()} and name-unquoting with \verb{:=}. } \keyword{internal} rlang/man/return_from.Rd0000644000176200001440000000416113604124170014761 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/stack.R \name{return_from} \alias{return_from} \alias{return_to} \title{Jump to or from a frame} \usage{ return_from(frame, value = NULL) return_to(frame, value = NULL) } \arguments{ \item{frame}{An environment, a frame object, or any object with an \code{\link[=get_env]{get_env()}} method. The environment should be an evaluation environment currently on the stack.} \item{value}{The return value.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} While \code{\link[base:return]{base::return()}} can only return from the current local frame, these two functions will return from any frame on the current evaluation stack, between the global and the currently active context. They provide a way of performing arbitrary non-local jumps out of the function currently under evaluation. } \details{ \code{return_from()} will jump out of \code{frame}. \code{return_to()} is a bit trickier. It will jump out of the frame located just before \code{frame} in the evaluation stack, so that control flow ends up in \code{frame}, at the location where the previous frame was called from. These functions should only be used rarely. These sort of non-local gotos can be hard to reason about in casual code, though they can sometimes be useful. Also, consider to use the condition system to perform non-local jumps. } \section{Life cycle}{ The support for \code{frame} object is soft-deprecated. Please pass simple environments to \code{return_from()} and \code{return_to()}. These functions are in the questioning lifecycle because we are considering simpler alternatives. } \examples{ # Passing fn() evaluation frame to g(): fn <- function() { val <- g(current_env()) cat("g returned:", val, "\n") "normal return" } g <- function(env) h(env) # Here we return from fn() with a new return value: h <- function(env) return_from(env, "early return") fn() # Here we return to fn(). The call stack unwinds until the last frame # called by fn(), which is g() in that case. h <- function(env) return_to(env, "early return") fn() } \keyword{internal} rlang/man/env_bind_exprs.Rd0000644000176200001440000000166713563532074015446 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{env_bind_exprs} \alias{env_bind_exprs} \alias{env_bind_fns} \title{Bind a promise or active binding} \usage{ env_bind_exprs(.env, ..., .eval_env = caller_env()) env_bind_fns(.env, ...) } \arguments{ \item{.env}{An environment.} \item{...}{<\link[=dyn-dots]{dynamic}> Named objects (\code{env_bind()}), expressions \code{env_bind_lazy()}, or functions (\code{env_bind_active()}). Use \code{\link[=zap]{zap()}} to remove bindings.} \item{.eval_env}{The environment where the expressions will be evaluated when the symbols are forced.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} As of rlang 0.3.0, \code{env_bind_exprs()} and \code{env_bind_fns()} have been renamed to \code{\link[=env_bind_lazy]{env_bind_lazy()}} and \code{\link[=env_bind_active]{env_bind_active()}} for consistency. } \keyword{internal} rlang/man/rep_along.Rd0000644000176200001440000000156313405732277014404 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/vec-new.R \name{rep_along} \alias{rep_along} \alias{rep_named} \title{Create vectors matching the length of a given vector} \usage{ rep_along(along, x) rep_named(names, x) } \arguments{ \item{along}{Vector whose length determine how many times \code{x} is repeated.} \item{x}{Values to repeat.} \item{names}{Names for the new vector. The length of \code{names} determines how many times \code{x} is repeated.} } \description{ These functions take the idea of \code{\link[=seq_along]{seq_along()}} and apply it to repeating values. } \examples{ x <- 0:5 rep_along(x, 1:2) rep_along(x, 1) # Create fresh vectors by repeating missing values: rep_along(x, na_int) rep_along(x, na_chr) # rep_named() repeats a value along a names vectors rep_named(c("foo", "bar"), list(letters)) } \seealso{ new-vector } rlang/man/set_attrs.Rd0000644000176200001440000000330413563532074014437 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{set_attrs} \alias{set_attrs} \alias{mut_attrs} \title{Add attributes to an object} \usage{ set_attrs(.x, ...) mut_attrs(.x, ...) } \arguments{ \item{.x}{An object to decorate with attributes.} \item{...}{<\link[=dyn-dots]{dynamic}> A list of named attributes. Pass a single unnamed \code{NULL} argument to zap all attributes from \code{.x}.} } \value{ \code{set_attrs()} returns a modified \link[=duplicate]{shallow copy} of \code{.x}. \code{mut_attrs()} invisibly returns the original \code{.x} modified in place. } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} \code{set_attrs()} adds, changes, or zaps attributes of objects. Pass a single unnamed \code{NULL} argument to zap all attributes. For \link[=is_copyable]{uncopyable} types, use \code{mut_attrs()}. } \details{ Unlike \code{\link[=structure]{structure()}}, these setters have no special handling of internal attributes names like \code{.Dim}, \code{.Dimnames} or \code{.Names}. } \section{Life cycle}{ These functions are deprecated since rlang 0.3.0. } \examples{ set_attrs(letters, names = 1:26, class = "my_chr") # Splice a list of attributes: attrs <- list(attr = "attr", names = 1:26, class = "my_chr") obj <- set_attrs(letters, splice(attrs)) obj # Zap attributes by passing a single unnamed NULL argument: set_attrs(obj, NULL) set_attrs(obj, !!! list(NULL)) # Note that set_attrs() never modifies objects in place: obj # For uncopyable types, mut_attrs() lets you modify in place: env <- env() mut_attrs(env, foo = "bar") env } \keyword{internal} rlang/man/is_reference.Rd0000644000176200001440000000254213553606252015062 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/types.R \name{is_reference} \alias{is_reference} \title{Is an object referencing another?} \usage{ is_reference(x, y) } \arguments{ \item{x, y}{R objects.} } \description{ There are typically two situations where two symbols may refer to the same object. \itemize{ \item R objects usually have copy-on-write semantics. This is an optimisation that ensures that objects are only copied if needed. When you copy a vector, no memory is actually copied until you modify either the original object or the copy is modified. Note that the copy-on-write optimisation is an implementation detail that is not guaranteed by the specification of the R language. \item Assigning an \link[=is_copyable]{uncopyable} object (like an environment) creates a reference. These objects are never copied even if you modify one of the references. } } \examples{ # Reassigning an uncopyable object such as an environment creates a # reference: env <- env() ref <- env is_reference(ref, env) # Due to copy-on-write optimisation, a copied vector can # temporarily reference the original vector: vec <- 1:10 copy <- vec is_reference(copy, vec) # Once you modify on of them, the copy is triggered in the # background and the objects cease to reference each other: vec[[1]] <- 100 is_reference(copy, vec) } \keyword{internal} rlang/man/call_inspect.Rd0000644000176200001440000000117213405732277015072 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/stack.R \name{call_inspect} \alias{call_inspect} \title{Inspect a call} \usage{ call_inspect(...) } \arguments{ \item{...}{Arguments to display in the returned call.} } \description{ This function is useful for quick testing and debugging when you manipulate expressions and calls. It lets you check that a function is called with the right arguments. This can be useful in unit tests for instance. Note that this is just a simple wrapper around \code{\link[base:match.call]{base::match.call()}}. } \examples{ call_inspect(foo(bar), "" \%>\% identity()) } rlang/man/arg_match.Rd0000644000176200001440000000157113405732277014362 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/arg.R \name{arg_match} \alias{arg_match} \title{Match an argument to a character vector} \usage{ arg_match(arg, values = NULL) } \arguments{ \item{arg}{A symbol referring to an argument accepting strings.} \item{values}{The possible values that \code{arg} can take. If \code{NULL}, the values are taken from the function definition of the \link[=caller_frame]{caller frame}.} } \value{ The string supplied to \code{arg}. } \description{ This is equivalent to \code{\link[base:match.arg]{base::match.arg()}} with a few differences: \itemize{ \item Partial matches trigger an error. \item Error messages are a bit more informative and obey the tidyverse standards. } } \examples{ fn <- function(x = c("foo", "bar")) arg_match(x) fn("bar") # This would throw an informative error if run: # fn("b") # fn("baz") } rlang/man/with_handlers.Rd0000644000176200001440000000704113604124167015260 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cnd-handlers.R \name{with_handlers} \alias{with_handlers} \alias{calling} \title{Establish handlers on the stack} \usage{ with_handlers(.expr, ...) calling(handler) } \arguments{ \item{.expr}{An expression to execute in a context where new handlers are established. The underscored version takes a quoted expression or a quoted formula.} \item{...}{<\link[=dyn-dots]{dynamic}> Named handlers. These should be functions of one argument, or \link[=as_function]{formula functions}. The handlers are considered exiting by default, use \code{\link[=calling]{calling()}} to specify a calling handler.} \item{handler}{A handler function that takes a condition as argument. This is passed to \code{\link[=as_function]{as_function()}} and can thus be a formula describing a lambda function.} } \description{ Condition handlers are functions established on the evaluation stack (see \code{\link[=ctxt_stack]{ctxt_stack()}}) that are called by R when a condition is signalled (see \code{\link[=cnd_signal]{cnd_signal()}} and \code{\link[=abort]{abort()}} for two common signal functions). They come in two types: \itemize{ \item Exiting handlers aborts all code currently run between \code{with_handlers()} and the point where the condition has been raised. \code{with_handlers()} passes the return value of the handler to its caller. \item Calling handlers, which are executed from inside the signalling functions. Their return values are ignored, only their side effects matters. Valid side effects are writing a log message, or jumping out of the signalling context by \link[=with_restarts]{invoking a restart} or using \code{\link[=return_from]{return_from()}}. If the raised condition was an error, this interrupts the aborting process. If a calling handler returns normally, it effectively declines to handle the condition and other handlers on the stack (calling or exiting) are given a chance to handle the condition. } Handlers are exiting by default, use \code{\link[=calling]{calling()}} to create a calling handler. } \section{Life cycle}{ \code{exiting()} is soft-deprecated as of rlang 0.4.0 because \code{\link[=with_handlers]{with_handlers()}} now treats handlers as exiting by default. } \examples{ # Signal a condition with signal(): fn <- function() { g() cat("called?\n") "fn() return value" } g <- function() { h() cat("called?\n") } h <- function() { signal("A foobar condition occurred", "foo") cat("called?\n") } # Exiting handlers jump to with_handlers() before being # executed. Their return value is handed over: handler <- function(c) "handler return value" with_handlers(fn(), foo = handler) # Calling handlers are called in turn and their return value is # ignored. Returning just means they are declining to take charge of # the condition. However, they can produce side-effects such as # displaying a message: some_handler <- function(c) cat("some handler!\n") other_handler <- function(c) cat("other handler!\n") with_handlers(fn(), foo = calling(some_handler), foo = calling(other_handler)) # If a calling handler jumps to an earlier context, it takes # charge of the condition and no other handler gets a chance to # deal with it. The canonical way of transferring control is by # jumping to a restart. See with_restarts() and restarting() # documentation for more on this: exiting_handler <- function(c) rst_jump("rst_foo") fn2 <- function() { with_restarts(g(), rst_foo = function() "restart value") } with_handlers(fn2(), foo = calling(exiting_handler), foo = calling(other_handler)) } rlang/man/new-vector-along-retired.Rd0000644000176200001440000000202413553606252017247 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{new-vector-along-retired} \alias{new-vector-along-retired} \alias{new_logical_along} \alias{new_integer_along} \alias{new_double_along} \alias{new_character_along} \alias{new_complex_along} \alias{new_raw_along} \alias{new_list_along} \title{Create vectors matching the length of a given vector} \usage{ new_logical_along(x, names = base::names(x)) new_integer_along(x, names = base::names(x)) new_double_along(x, names = base::names(x)) new_character_along(x, names = base::names(x)) new_complex_along(x, names = base::names(x)) new_raw_along(x, names = base::names(x)) new_list_along(x, names = base::names(x)) } \arguments{ \item{x}{A vector.} \item{names}{Names for the new vector.} } \description{ These functions are deprecated as of rlang 0.3.0 because they are longer to type than the equivalent \code{\link[=rep_along]{rep_along()}} or \code{\link[=rep_named]{rep_named()}} calls without added clarity. } \keyword{internal} rlang/man/has_name.Rd0000644000176200001440000000151413477741174014212 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/attr.R \name{has_name} \alias{has_name} \title{Does an object have an element with this name?} \usage{ has_name(x, name) } \arguments{ \item{x}{A data frame or another named object} \item{name}{Element name(s) to check} } \value{ A logical vector of the same length as \code{name} } \description{ This function returns a logical value that indicates if a data frame or another named object contains an element with a specific name. Note that \code{has_name()} only works with vectors. For instance, environments need the specialised function \code{\link[=env_has]{env_has()}}. } \details{ Unnamed objects are treated as if all names are empty strings. \code{NA} input gives \code{FALSE} as output. } \examples{ has_name(iris, "Species") has_name(mtcars, "gears") } rlang/man/vec_poke_n.Rd0000644000176200001440000000211613500127670014530 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/vec.R \name{vec_poke_n} \alias{vec_poke_n} \alias{vec_poke_range} \title{Poke values into a vector} \usage{ vec_poke_n(x, start, y, from = 1L, n = length(y)) vec_poke_range(x, start, y, from = 1L, to = length(y) - from + 1L) } \arguments{ \item{x}{The destination vector.} \item{start}{The index indicating where to start modifying \code{x}.} \item{y}{The source vector.} \item{from}{The index indicating where to start copying from \code{y}.} \item{n}{How many elements should be copied from \code{y} to \code{x}.} \item{to}{The index indicating the end of the range to copy from \code{y}.} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} These tools are for R experts only. They copy elements from \code{y} into \code{x} by mutation. You should only do this if you own \code{x}, i.e. if you have created it or if you are certain that it doesn't exist in any other context. Otherwise you might create unintended side effects that have undefined consequences. } \keyword{internal} rlang/man/new_function.Rd0000644000176200001440000000316313477752102015130 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/fn.R \name{new_function} \alias{new_function} \title{Create a function} \usage{ new_function(args, body, env = caller_env()) } \arguments{ \item{args}{A named list or pairlist of default arguments. Note that if you want arguments that don't have defaults, you'll need to use the special function \code{\link[=pairlist2]{pairlist2()}}. If you need quoted defaults, use \code{\link[=exprs]{exprs()}}.} \item{body}{A language object representing the code inside the function. Usually this will be most easily generated with \code{\link[base:quote]{base::quote()}}} \item{env}{The parent environment of the function, defaults to the calling environment of \code{new_function()}} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("stable")} This constructs a new function given its three components: list of arguments, body code and parent environment. } \examples{ f <- function() letters g <- new_function(NULL, quote(letters)) identical(f, g) # Pass a list or pairlist of named arguments to create a function # with parameters. The name becomes the parameter name and the # argument the default value for this parameter: new_function(list(x = 10), quote(x)) new_function(pairlist2(x = 10), quote(x)) # Use `exprs()` to create quoted defaults. Compare: new_function(pairlist2(x = 5 + 5), quote(x)) new_function(exprs(x = 5 + 5), quote(x)) # Pass empty arguments to omit defaults. `list()` doesn't allow # empty arguments but `pairlist2()` does: new_function(pairlist2(x = , y = 5 + 5), quote(x + y)) new_function(exprs(x = , y = 5 + 5), quote(x + y)) } rlang/man/entrace.Rd0000644000176200001440000000441313554012432014041 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cnd-entrace.R \name{entrace} \alias{entrace} \alias{cnd_entrace} \title{Add backtrace from error handler} \usage{ entrace(cnd, ..., top = NULL, bottom = NULL) cnd_entrace(cnd, ..., top = NULL, bottom = NULL) } \arguments{ \item{cnd}{When \code{entrace()} is used as a calling handler, \code{cnd} is the condition to handle.} \item{...}{Unused. These dots are for future extensions.} \item{top}{The first frame environment to be included in the backtrace. This becomes the top of the backtrace tree and represents the oldest call in the backtrace. This is needed in particular when you call \code{trace_back()} indirectly or from a larger context, for example in tests or inside an RMarkdown document where you don't want all of the knitr evaluation mechanisms to appear in the backtrace.} \item{bottom}{The last frame environment to be included in the backtrace. This becomes the rightmost leaf of the backtrace tree and represents the youngest call in the backtrace. Set this when you would like to capture a backtrace without the capture context. Can also be an integer that will be passed to \code{\link[=caller_env]{caller_env()}}.} } \description{ \code{entrace()} interrupts an error throw to add an \link[=trace_back]{rlang backtrace} to the error. The error throw is immediately resumed. \code{cnd_entrace()} adds a backtrace to a condition object, without any other effect. Both functions should be called directly from an error handler. Set the \code{error} global option to \code{quote(rlang::entrace())} to transform base errors to rlang errors. These enriched errors include a backtrace. The RProfile is a good place to set the handler. See \code{\link{rlang_backtrace_on_error}} for details. \code{entrace()} also works as a \link{calling} handler, though it is often more practical to use the higher-level function \code{\link[=with_abort]{with_abort()}}. } \examples{ if (FALSE) { # Not run # Set the error handler in your RProfile like this: if (requireNamespace("rlang", quietly = TRUE)) { options(error = rlang::entrace) } } } \seealso{ \code{\link[=with_abort]{with_abort()}} to promote conditions to rlang errors. \code{\link[=cnd_entrace]{cnd_entrace()}} to manually add a backtrace to a condition. } rlang/man/parse_quosure.Rd0000644000176200001440000000224713500223442015314 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lifecycle-retired.R \name{parse_quosure} \alias{parse_quosure} \alias{parse_quosures} \title{Parse text into a quosure} \usage{ parse_quosure(x, env = caller_env()) parse_quosures(x, env = caller_env()) } \arguments{ \item{x}{Text containing expressions to parse_expr for \code{parse_expr()} and \code{parse_exprs()}. Can also be an R connection, for instance to a file. If the supplied connection is not open, it will be automatically closed and destroyed.} \item{env}{The environment for the quosures. Depending on the use case, a good default might be the \link[=global_env]{global environment} but you might also want to evaluate the R code in an isolated context (perhaps a child of the global environment or of the \link[=base_env]{base environment}).} } \description{ \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} These functions were deprecated and renamed to \code{\link[=parse_quo]{parse_quo()}} and \code{\link[=parse_quos]{parse_quos()}} in rlang 0.2.0. This is for consistency with the convention that suffixes indicating return types are not abbreviated. } \keyword{internal} rlang/DESCRIPTION0000644000176200001440000000176213614116052013070 0ustar liggesusersPackage: rlang Version: 0.4.4 Title: Functions for Base Types and Core R and 'Tidyverse' Features Description: A toolbox for working with base types, core R features like the condition system, and core 'Tidyverse' features like tidy evaluation. Authors@R: c( person("Lionel", "Henry", ,"lionel@rstudio.com", c("aut", "cre")), person("Hadley", "Wickham", ,"hadley@rstudio.com", "aut"), person("RStudio", role = "cph") ) License: GPL-3 LazyData: true ByteCompile: true Biarch: true Depends: R (>= 3.2.0) Suggests: cli, covr, crayon, glue, magrittr, methods, pillar, rmarkdown, testthat (>= 2.3.0) Encoding: UTF-8 RoxygenNote: 7.0.2 URL: http://rlang.r-lib.org, https://github.com/r-lib/rlang BugReports: https://github.com/r-lib/rlang/issues NeedsCompilation: yes Packaged: 2020-01-28 14:09:27 UTC; lionel Author: Lionel Henry [aut, cre], Hadley Wickham [aut], RStudio [cph] Maintainer: Lionel Henry Repository: CRAN Date/Publication: 2020-01-28 20:40:10 UTC rlang/build/0000755000176200001440000000000013614040224012450 5ustar liggesusersrlang/build/rlang.pdf0000644000176200001440000131264213614040224014257 0ustar liggesusers%PDF-1.5 %ÐÔÅØ 2 0 obj << /Type /ObjStm /N 100 /First 804 /Length 1064 /Filter /FlateDecode >> stream xÚ…–ËŽ£:†÷'«!¡ð“$4~ø;Að$…ÄŸ¤q™ÄÈ9 I‰@Ò’R–d å ä¤<†Š´t¤4i¸WŽ´˜ 0d”Ë´$c$iCVÒ–,[²V“ÉÉ:¨Èå0Óäœqä XOÎ:@ˆÙeV’G<Ö·€,y§È ‚¥Ÿ‚æà;Êžó¸jOˆKäÁd{Ø®G –òWï„D6$•€G\¡$Gz×ÈÒ<ç P‡ÊºL r¡Ò2p©0­±6ěؖЧÝä<€_ÃwœzN`Ò`gƒ„Ím&°aaù%ÖòÓÖ± <;öB |¾œåÂr99”CxÆQáÇÂ%v>(ŠðË ¤>€Ó A 4"xŽ%'™ç¦Â€›’¹Á<ò&EŽ• 7Œà Ð2ˆ>C¼8Þ!‰9ƒ8š}…èàYZžïE“ŠÃä~Sܤ؀TœtNj…˜Q9©‚@餿Fí¤á%PqœáX[ÆŽñN â øQ gEzIœ8ˆ©¹Š¹7Ñëëòsб6ƒý©VgkŒç¬íð¦+Ž}óµf<ÎxÌ>¨Ldžé«öpíaèV 7Ÿ'ráƒà Þ–pjˆßð½uÉè:\sù‘«3d fO’XïwÝ-ÁÊ Ò´øHÖiÛfØÛû¯çËó7ؤ•Ù$=X> stream xÚ–K“Ú8…÷ü -“´õ–ªRYMÕì{f95Ú°Ý~t¿Ÿs…mØ&‹.ì£û]I÷\É-2Á2&2äÁeÊ2Á3æ~8ó¹b\Ò«f<:ÆéX!˜Pr%„dÂp¼cÌcLX&9ÆdƤ†.9æÐøULa!5S’~&E~é™òÈ¡ÓR­“iqe˜ö4‡e&C^hFã9ŸVÌbBkf%x혵¿žY_#˜“v%ŒdŽÖa sñÆ2OëCOù,mûÃZx–a¡ΰ[lÔV¤‚q‰)$üàÒ‹•ÌYe¨¼á Åp‡+ƒj¢z\c\Â!®bÈ#Ù%™¤±:I.A 2…øÄS+ £¸ñpNq‹²KXÅ-j#áw4)ÌâÉ$܂ۆ]Üa»~q/IAfªÓ¸÷|%±J´b5“ÂìÔ0­™œÌP€Ô <£ê)ŠA 4–çµBN=‰ÒmVæ rHÂ=A‹’d•„wô‡^Á†…Ò ¨›4”d•Èœú–a©h;¨‘02;j[!êiC1pÍ¢;èS{` ê«{ê‹R‡9”_RË;ÔOeÔ Ö­¾}c/ÿ°—¿ËKöòûòº/6ûÍkwÜÔï͆eß¿¯¾ìÿãÒâýëBxµ7ñ$L‡Ø&$Ÿ‰(ÓÈ{hR„ShÄ4 åÅ{¬óöB†â<€ƒN4äø‚mÃñ8r‰ e‰§ª=ß2IZ†ŠÏ¼.‹S,Ú;ô:°œàWUǦÉËâŽõE|_Ö§înÙ^\»bÛ>Ì:¨‹h^4-Šw·ì(?Ûx€Íû==èOñ:`Ÿñ‘ïPÛÝ-Ó`ïý@ô¯³±iŠcx‹Çßš!iËXóÑ…ëmÞsq¬cu9DzO$ÄtI›ÁŽ¡?Èoaû£­é:N÷Bñxƒ¥Øt¹ ¡é¦(žÜj ®”P÷þ¶çjhW|Šwù6´×#v‰\SÌú::—µ¬ðÍ™ù|]FÿèÖıqèy.ª}蘦ÿ?m¶_(]swTÒf°ói >Ÿ¦cÚ|wŽŸa<6¡oÈahMâ =úLVŽà`)‰3à’}¾ý«’ø endstream endobj 444 0 obj << /Length 1079 /Filter /FlateDecode >> stream xÚíX]o£8}ï¯àmA*®?°‘v¥í´iT­FÙt^fV]\‚Jp¦3Ù_¿6&4¤)¡Úî[T©q°}Ͻçžk_ÌΧ3øÊçåüìâ†0CÀ¦ÎüÁÁ„3‡á°8óÔùæ~ñtyòÈ3áù˜B÷ïªàeö‹÷×ü³6:˜R܈CÌñq"ÛýŸyÙðjc÷âè¼@ …ÞÖ—Ä 3cÉGLÛ`Ú µ–¾jO +ª:—åþÞpg/ Š‘žiwA€`ª[ï# "‚í®¹‡"7W…Òa†8ÜÝ4e¢´kµðAVvpÉ뎹¹Aw³Ý ^¦vðQVÝŠÙÞÌwH¹G¨›§›'Q½0íô઩´½±ð:/mx]R¯DTùZa’@kbàïTIY,äϽ(™Èê1/³îA®–v´è P&øNÉ~Ð;Áh¯c@p¬½nÕe(òGƒ²5¶[Keš·¡´_ëM­Äê|Ég¸#œön´ßö õ–Ö=8tLx˜ºOæ/n\ÇRÃp¨¸Û<e-ŽF½°?}¹õÉ1a›õCþÏæŠ+>†0D}ÚUÕˆQ˜nùær£ÄG¹ZçãÄ Îr0©[>òeÎ+S¬Ér”:h4¨[>éJ¬E™Ö£Ä!@Q2ÛêÂß~µc0€ú'Ôš ÿÙd™¨Õà“"?·µ„`­Üv$›H#ý§êüž“Šodyp*+1œ`vbų*Wê°Á•PK™Öç´F ~x[µâÕc*Maý8ìŽÒœ¨%W/©Æ€L zP‰¢®ËD¦æ£š‚žè»ù'Ô¬¤s&n2Qþ!Õx}èPÃh ¤Ëàñ±ëAF£UÉð¦Èke˜Ü%ßrÚQ;Ÿytï® ÙÚõQ BØõw³ÛÁÌ Jí†3c “Ý›–ˆÈÖÁ¥Rëm*ßóÛƒzd5š3„ >ûûúÜ®¯Eò|îôZÃgú‚k ‘«‹g¬SÃ_ëpt¹Úãy‡Ë&›‰µ¬ö }’—”‚ø N^äuݼèè €µ ßÚlCÝBt§šmüØî:D@Ðþx•ë<é.ÐT&ÍJ”J¤úŽq'¯zŸÎ«1À¬;HøB‡ïù$¦.0ÃÓÇëA¿x8ŸþQ+œn¨…ã|ó!Ð  uÿŒµ÷kv¿âJ_²2<‘,ÓsŽç`[õ}Ûsv"ÿ+‡pZ9Ô÷©n u9Ô#>qÿŸôM%]·0ºëxÊ+Yš ÅÓoøÄù[94åMåü¡ûMÃóÃ(8éü¨ÇS©/øBZä!9þîY S³Pò•Ð(ø~÷$î>ûd Fõ[‡y9 CdS2<¹®çgÿ¼Ôâ% endstream endobj 514 0 obj << /Length 1010 /Filter /FlateDecode >> stream xÚíœÁŽ›0†ïy Žp€î±R[©Ç*·ª²p$b¨qªæík‡lwµ­º¦5é¡sdÅ’èÿfÆþ=&(:D(z¿y³Ý¼zGªˆe¬Äe´ÝG9B)ʨ*QF ޶mô)ÆÉçí‡Wï ôäB‚‹Œ los½äãíúä–•5y¸À c×LIŠ)ŠÛ¡9Ÿ¤2²}íþmƒn_çÙwI1+³WöEåþ8ßHLüËy˜ÎZ&)£yœ%)EN×SÁØã»§Ò"{DYi÷v~ùñý&ú”ÖÅ9}ví|¶‡4ÇYN‹ÊOFw꤄0P<8†ò÷ÈŒa'´LÍe”é¨eÛ5ÂH—WuõŸ«î§3fq^ûé<|sbzí°g^Õ§}ÝÍKP{] yå‡"5—*)PüÕ~JEAö—XøCȽ!p¡“¼Žv ´¹ƒçö.P|¯ì§`z¯Å‚ø§E§¦Q6&IË €„(I…¿ö§¡íö+}^Ø÷•^‰“µÆ”Ôõ/ý‡€ÉÕ Ýv“À þÿLñÊ3âMsäjm©)ÀhýL²UžŸä4‰ƒ öº„Ùç_Å|íWe¬æSwP¢·þêKÀ g^AßJÂJÄx¿•ˆö¢Òv0Öÿ°\·…Ü«,ÉÓh.ËA˜AzÜÁ-¤2Z4¶8‘,ïj,°' È„{“!~•j&Ãwó f­+ Kr„7ýuJUP= ƒzƒVŽæèÚ8¨Ž[T‘ÒXÀÝAÊU'k( !ô÷ë'ww¨ÙÛ×0#]öeqÝ/ï~¸¬Zx ~…y`îô N×F?ô7ÿÐ-”…wäßÖìä4uƒ²’W0 üU´{+ïüð¹ðÜ``¿6ÊÏÏo·›ïZ— endstream endobj 611 0 obj << /Length 996 /Filter /FlateDecode >> stream xÚíœMoã6†ïù:Zj)RÉ t‹ö¸ðmQ´D;BdI!©fÝ__Ò©·MÉZÉv.–¦ñ¼Ôpæ%mšìšüz÷óúîÃÇ‚&*S«’õ6É)ÍxQ%¢¢YÉY²n“Ï«OéëßCÃòª¡Ê*Y„96ðãÔ5.%¬¤«vlæ½¼i:uãâªW"£B^:òØäŽž¿NBx%3E‹„0»œu®ÞÎCã»qH‰ Cd)))^N—B©î®iÒðJ3™Øx{zû)0þL$§«Jü«íYšœgŒæÏè»ÁyÝ÷¦M‰TBÿ_ à윽7i^®vÆvî>%¼DÞ]«CèIY¹ú3JaÂcP2ä~~A¡ø½?ÆJ éÅB¿È_ƒßMº s¾**„~ËœgPèî°ßŒ}GJD½Ü¤ó÷vó½HÿÍ´àP-žŒ~°fŸœ#ò÷ ×ÎׯÚÑÆ%Ÿ‡(`t㔆éÏ÷ä,ÇØè¾ÞtCÛ ;ƒRŽÐoɉ*ØSpÄ>NÑÿ Ô%R¿:ÌùÙwÎ…i^k›ærµ £ …Àˆ4„ÿXz±h¹•ˆ{i $Ì€Lt}žêíh÷s¯£˜…ÞÄ=÷gÓ_0tÞüã<ºÙÇAÃù&ðìUàŸë]Éq±½%É‘° wp†´f;»èø0œê Nü,@X^£Ã¬$_?,Í'²3žhïmô<1è,§€bPƒPšÓ•ž{‚?Ã4ó–à¯8˜üÜ÷_³Wº ßâ Mº³gS³¸‰¾|Ì­º“¶ÎÔÇ“%_¦ø9CsAJç"+·ÏåE¨ "Ô½Þ˜>ÈP¢Ç°  æïg· ŒB·’ç|Naî¦5S­ûqØò“žï @¯‡]½Ñ̓·º1õ8\6Û¹øô€qe*p…¹˜®Ñ½¶)£+â“!“5m×hýÌâÇ=Æö Î ÈyœLûòY¥NÐp+WyŒeSŽgAÞ<~CñW5T)P˜7¢KqÜ1#p¬¦–V̺Ã>²è[¾¹Àfó]{0§å8¼èž´Úë”0ô÷—Y°aÞÂ)«ù}Èè+D¿¤°3lÿIÿe…î7‡ýdî”ÿ7~<Õ_Í88oçË)ª7wóž:_ëÍh}Œ1˜.¸Òæ9\{=´½±˜~.0ñaæÃ“5Ûú!îÛK°CJTKì’ÓVÿ¥§øCÜË}/Y^.ˆ?|äÕÕ¿l.2YÊ„0ž)Uœ¤úmhÍ—sï‡àªÊ„R—ÿæÈó—k¿Ëõ—õÝßNñ; endstream endobj 404 0 obj << /Type /ObjStm /N 100 /First 893 /Length 2417 /Filter /FlateDecode >> stream xÚÅZQo¹~ׯàcòp\É’…q@îi´ÀÁI¶©[—çJ,·¹þú~#¼'æ|+÷ÁæîŠ;ó‘CÎ7Ô§’ .‡â8¢©®d—‰£Ž¡eGEïÅQÓÏ›‹)¹ƒ‹¹ M.–²È1»Xõyq 6r¬hÚæ’šOÁ1ã}Ø,öRtUô>9 è”S†cÁ› cK‹œà2Gí[1ÃYªŽ¤V\4Gr€Åx+³‹Adq‘€"]¤×ø8â O€5J\0á"±à >ªU/¢K`1, žÄŠ×%¹” P71Ìga—¤hgq©’vƨ[Ž‹,U'T;ëØ:— ƒÄã¢(õN1IÀ¿’ôõ…*Ú£mM;‹Jí¬Ñæ œ4¥a&#:WL©0:Wr\:.·˘ :Ý5;!`e'IˆÉ:ÀZÞ†eL¨`mNª¶¤é¢E:À]‰˜¤Ü’+IñJa`cWDØÄ•¢lÅ,c$5è[s•0@ÁÕˆÇÈÕÝ¢ÀDTÆd3VcXå]­Q;³«µ³¸šv.ãC±Z‚'Í5eÃPqÁ®.".šN>ª˜ZÖÅV‹^é€Õ5‰:—º Ã:"M¡bî0¿X•&è‰(ë»XŽXaú.Ö#é–a„Û Œ1XÇê­èVªº½q¢†9b„œ°,ÚâäÄ ¯ÝðÇõ›µ~pÏNZù//¶ë?½<¿ùà/Ö«›íæöb{µ^yzî¾ývñlßá›éGÏ¿jé?WÛþôöÚŸ¿[o¶‡×õé?)•ÝÃ_yñÃùêòz¹¹¹ÿîáù¯o–?í^ÿyùËÝ›x¦oâÑ×_úïùÇC_\~Ùçju¹üäþÇ+½ù¢Ï[Í3ÁºáåÕöL;žœ,†7¿|\ºáÇó÷ËÅðýzµ]®¶7؃Y{.†ÓåÍúvs±¼Ù%†Ý£¿,/¯Î¿[ropc±k&_ÛÙ–60„bÝ_¬VkX|»Ënê]³Û¾Ö&k³µl­X[¬­ÖîG¡iMÛ³Åg#Ùù[ ß­7—ËÍb8þ4¼¾Ç Û™êbëÞRdŸ°°£4ƒfìâ5ÅaÑúŠ^¯oßmaqøóÕêçáÅÉÉÎþðb· †×Ã_O_éß³ÛíÇ? Ãæú|õÞo¾¹¾zç×›÷Ïéq°b^§è+µ˜ôX7ÀõKòö6Ê¿†¸=ÐÇÃÇxÐMÌ@‡=rôÈ@Q‚m.tÃÕÍÍíòæ!æÃíœ|3ín˜‘=iZÃZU6iøP• ³§ª“úÂÝßO±!|Þm§y1ÔäÓ.ï1P#ß$?Œ¡C¡Ý»ÃP½PŸ7o¾Ç Õ§ÆPçÄ@Õ xÊ+§°`£•‡Í!±áCÎUeCœCL^&‹!EŸ¹7 i~D¾h¡rÀƒGÍÓÁðÙΜRÛßþþךOYë¬äµ€[Ý^_Ÿ=Ô—BØwF"c0Òüc/à²Ï:¿Óî†ö2ia]—“à’Æ©AkÐý È.óž0abøq³¾x½Ä ‚ºxé†7ËOÛûLxÓ™¾àt­þ~§gãòl\.v/‡{ãv1nãv1nãv1nãöbµB1{Åì³WÌ^1{Åì³WÌ^1{ÕìU³WÍ^5{ÕìU³WÍ^5{ÕìU³×Ì^3{Íì5³×Ì^3{Íì5³×Ì^ÛÛÓ’ß’µÑÚdm¶–­k‹µÕZ³G½Úè±Û´$ðF·iA©’"u¶)Ïž* 5õ9bˆÕS7kËüBQŸ#¨Ãá4?yሽ9‰EH¾J/m~ 5ªÏ; ‚Zsó0†æÇP‚ßP&3wbçgqáêeB_"8I„N,âü,.YÔçˆAëôÜ‹Åü4.)ƒñ&±Èh[/y~ 1zšì IÁ·LO‹!4õ9b êKíÅbþÅ­¨ÏCÐ*¤‹2?†Êêó#g;æÏ“¼+ÇX0rVŠåi1!õÕr•^,æÏÕŒ;M¸›‘³B»Óü¹šSQŸ#†Ìàι3ÍŸ«9fõ9bHÉ—wEõ9bˆä¹ÇÝi~¾@Å©>G ÈY¹÷@šŸ/PU«Ï; ¨Ž}ìqwš¿žÄÉA}޳¨ÇÝiþü€S’o“…Óø£‹ùóCfœõâ$|éq÷10¤¦>G uU»óü9*Gðæ„»3Nï¹ûáüù!{žpwFÎJ=î>œ'ò„»3rõ¸;ÏŸ£Î4ÝÈY!öb1ŽJ8O¨RzÀjñµÇÝyþz2‰ø6áîTØ—wgõ9b@ÎâwçùsµŠ <á…½ÒÁ0M›pžˆmüÆ6!gÅwçùódÂy"N¸õ,8« ž?O&ýÂ݉²o܉ÏŸ£bKêsÄ¢¯=îæùsT¬¤>GM©pV/óç(• ásÄPPWµ^,æÏ‘‹ú1 g¥wóüù!â<‘¦úÿоw 8OÀçˆAÒÔ‹Åügÿˆó|ŽbóµÇÝ<žÄyW}ŽuU»ù_/“êªÒ‹Åü¹šjVŸ½uU»eþ\M8Oä8Õ{ üщ…AéÄy"N¸›³¨ÇÝr¥ç ýÝÞTñmÒ‘%EñmSÕ9gðG/ù(Šoì •|¥ÇÝÇÀ@¤>»ä+rOòÕ(þ&Éw¢µNåÕ‰¢ŠE"¿G^¢ûòªìÕ¸ÇË«L&Ê¡5YÐdU6Y•MVe“UÙdU6Y•MVe“UÙdU6Y•MVe“UÙdU6Y•MVe“UÙdU6Y•MVe“UÙdU6Y•MVe“UÙdU6Y•MVe“UÙdU6Y•MVe“UÙdU6Y•MVe“UÙdU1YULV“UÅdU1YULVý?Ë¥RŽ —"åqšÈ¥8*ôvY;‚Zª'ƒ8QKQµS{R ªLÖ2QCð˜šÎ/žŽ¡TV?¥œ‰:BD9‚P)ìõ'£Xš}"é`8‚PÉñ³B@„ú…À10àЦ±ÈK²÷#¼#ˆ¥QÅ™•!OO‹@üS *DôÒCÉG*›Ï“ŸÀ¡`Çš¤§ÅPkr*T²ïB£è”AÒD§D}Ô[‘GkÇÄIiŠêy°—$ïŽlÿÛÔm. endstream endobj 654 0 obj << /Length 1141 /Filter /FlateDecode >> stream xÚ­WßoÛ6~÷_ÁG ¨X’õ#@¶n-VÖ¸OIh›q´Ê’+JËòßïx¤ÉVR+‚„Ôñx¼»ïî#ÃÈž0ò~õëzõú]œ‘‚©HÉúŽpÆhœ¤$K•± ë¹ ’ðËúÃëw‰œ(Ƨ"+¨¡6MÛY­ó¦_¯¾­8LáOVELYÌÉö°ºùÂÈ?X*rò€ª’pN³$†yE®WöNGt]ÄS×9£iÂIÆ$MeþœcÇ,`.h‘ó!ër_«*Œ„dªÝ¨Û6Ldд!ç›Íßt 3ÊøÛª®º¾ßø¦Ð£Õá)Ý›ÇI®ukèB"lá–Q§ PÖ@Õ»iCŸ$g¬ä±l6ò8ød±í´`©ƒÄ”‡¾rÅR儽ѭŒ»ÏæÎ)¸dàk‰á£Hy%DMÛ»°Âàs_ ­Êbˆs$η][EoÂÀéy>Ö‡_¤"x2B?,0}ÛB‰ ,T7~ýØSn*='¬±÷q'TÊÁ[›dâœË\• €ÎnØÁ,àá’:ÿ>[f^¼WÏïÙ“{m~ÏâãÄV&ÃꆿBìÎ7nøóóÇŽå™Wön9†|YUŽÝ¹(ïZµÕ—™ØBe,.U‹¯KŒÌ~1”¸xÙñéM@¢…” ÍewÂk³ð/"{“ÛL?ŸQœ>—CœbÖœS gÎi§9¸yæ ø¸ýðÿ¡—? ú»²º´ÎžCþ MùóÑôùsÔ4tŠß\ÏÃñ2;¿È¿´øÆw·×‹lð~ùqYäão}¯'ÿiìOøoWšc¥ðaAÝ‚ÿEþÀ| endstream endobj 678 0 obj << /Length 2721 /Filter /FlateDecode >> stream xÚ¥ZëÛ6ÿž¿ÂÈ}8ˆ‰Ôs\’Ã- 4{(É!%z­V–|¢”­û×ß ‡ÔËòÖN¦øÎó7ÃuW+wõ¯o^¼þà«„%!W»•çºLøá* ]¾zÈWŸœt[7íú¿ß¿þ ¢Ñdß YrØJO pÊ ×ì½ÚÏcQ¼ÚðWМûÝzÃcîTuK Õe!óWð™¸N¡»…S(–k/p~?ʬ•9õ´û´µ-IƒT*}4´R8²’MÚ/+Ó?Šòd6u÷¸7äÂ?¯¤šš?ñŸôĬ®68 6p™$èyÑuõ#ûÙ \øïMoÿÉaëïEÎ}…‡†=Ý“¥J¾"vr1æ=ç,NBËάL•Zà:°3 „uèTKl%mo9jÎÿ©‚kŸ–D,v)ª]ÝÆ7™‹š³p --ËzÍçIÓ·Bɱ$‰ “Bš$ǸV@оRó«e¿æ»Î€3ÀWØÝ¬ë”Üu%µÛš~·kE™÷S³¼kݲÊyU«÷ ÆX:3^l¢%1ò}æsoÆþѪ KÌ"Ã’Ý–Vlx:5ª9K*  I¤4 DÎþ0SG¼Ôß§ºkh1^ÍtêËï’%˜Bó¿¢eHÍ)اU^ÊóCŸQ_ÃuU<"Ç¥áçÖ°Þ­]Wezþí…HÕJó ò¹~žöE¶'ƒ6ú;ÂCG`¦õùdN×ù|¡ëõ¾ à‡–™¸S„¤rH8zvÁ>£ÛÂêÿ `„º{œöR†=g/ÐDïäPæžÎ–4xr½!½£Ï¼®þŽÁ…êêDºìr3Uc{ÓVš ŠþîD#[gXÑñmìƒ1•bêNö¦¬ßàÌ4QH=Mæ©Ü@ÃeµnŃ CD®W|G?ÞüðñýWBÎ Cž‚/ô¤Mw™-Td¥L+[^0¶=.gôÎ`­‡H,ç7 vß›ä"¾©MA7¤¸À$㹓Ó4ðS5µìá0оҠ&rþ³ö<,}Ð4²V˜¤ý¢9‹~tâR éÒîÓ< &hèè›Ø‡ã¢Ûñé ¦j‹È÷!š_yÀ‰»CáOú¢¹&iÑEg¢Kmµ¢Ž£ûé°Ùî—ÌÉ…ÈÕ+ꇴ9!çD]00ÏõYèÆ³ˆ(\˜†OJaÉ -„[ZZØHKUDV¨c‰±AwÓÏèøIØ[ZRØ0ÚͰè•f#%ÛVgÌ“UõQ›ïÕ2È©¨‡ eé‰ûRW_z=¹è8=°”À›±ÊçXkžjÖ½Ég±˜ ™¨šyvµ­š6ÏùŠŸiÙIu7­Ä$ñí°}ׄÄÏœÏÁI˜ö}ÙÈCQA¼y¹ä]!Þ yÊ%øž zÑÊ¡F©¦¥,[&™ì1ùßÝ-›ÇŒQTïÐì1Jʉuôâb³Z=! oŠŸocÓ¶I«l¿Ä$L¤n˜ôΪúˆ¼™“zŽ`?fBŽo¦7JJ^-Ö%Ší&ù¢Ï(wFx3{Ódû6ÂÑŽ¼„}â+ˆ¾è#—èÀèybu½U]Éo£· ¾ãBX öL(ÎÐõc·åé¶œƒÕ7àºT')xÚgâ}õ-.ÆB\’ÜöÀÒ—›ÅÁ“1ð{IrñhÀEà‚Ôä£7³€ÜüÚ'$†¨jPÞÛ‡bªKiñO< fI‘)Ïb’šE½­îvèºQp¶ayzméTs@ÛTÉ»;  léÔ5ÈÂãóý`*…+ip™—ðe~!Œ~ ‹R$áðLü¤³Ù’©ŒÊlQ¨S¸(W õàÙÿøn2I°€iz^™‡SÌŠ›ŽR?§B$4|gæQ–Œ¢ÀÖªpÁ‚Ò К+F± ֲ˅¼>BŸ„¤»ÁBÄ!åÄ u”D³ŒÑ×=A9¤õMïG¨ñØ¥¥Z‰Õ›¥Ô0žf…?;™²ò[²B[Ÿ¿ $JµitO{ðó—¬IíV0w ÚÔ¤šK/٦óÙÏis‡2¶y£›_ÆgÉðÀÈ7ÿ® ÿ×¶•§»y˜pcð?Y«O›Á7:üˆø¬p/"˪Äð¡¯Ã[3†…0á÷>]‚>£‰0+¥Ž¼nQ·}×üA&-ì=,‡˜h¾Qæ=b¶@£“^£maÏïkÜ":£þü44:–ðYòûì‹Á$•?‚‰¿¦ÙIÏ({çŠ~x¯-¬¨;µø·ø²Á½qR¾¤aдPûEƒŒ+k´ô[Ö`#ÍåŠç±VæÝxé©ßþ¾xñ"SâÏ endstream endobj 693 0 obj << /Length 1245 /Filter /FlateDecode >> stream xÚÕX[oãD~﯈º iãø;vB¥´«E€VÛìT&ñ86{¬™q²ñß™«o±›,û„ªÊ·ã3çûÎwÎÇžì&öäÍÕwë«Åƒ·šDV¸ÁdLÛ¶¼e0Y¶å{îdO~³ß×?,–~ËЋË]q/Òl0aÂêÊÖ®¹ß e>×ösw%î©·!œÍ]ßžÞ"Š;o7Gþg…".Õé{áÛõÚ1‡Ü-× ”ÛCÆÒ'Ño¶oó§YqàZnPaXE´ÅÅliO÷3ÇŸBMÞ©H&T›7Å®ýØR¬uim¹ÚÜs¬Ð‹Ôš÷A^"HGè%ö; –»qìÚ׫ÙÜ·íé:…ªSh¼Ë+@ôí]H cu!0ȧ{œ™[)Á‡L ’N` bîØVäë³DYªn|¼—|Ë[{×±"h;ÀÇlW¤W-Z‹¨S‘BýPrH)ØéØÿ¬(Sg({Ö÷(Ã¥I÷ÍP µ ®qYZcÛ 9e _ÉŒÄþ&ÛÃNp[(í2ÉRØÕ (üä€^«ëkÊ ËçÝ·x’ŽÏ…ºN3jE†n„ðAq¥ ¯($=)(b‡àhÆ!‚[ƹ@Ç!¾9Þ¶MBù\ˆvÕµ1x’ªàžpaøzÈá xÆ7êÐvÁŸöU(+¦ëæ¥gâÕŸ”ÆZ/šÏïaŽÙ œÔ…¤IçKˆ´ ùùv6w<»qý²ŠÝŠˆARV nP¥»ù¢š'=¢Od²êÈä\i%7+S …–p›%GS† Ä€Ã`}umšz$¦½dE±šòÏ­ÔñÂÐOš`µNœǾ¸hš·kb8†¢‹”ƒ¡O”Žmsl*ª]H„Þü/ËD“r‡ó²2ÒÕ'i‰Xiµ×Îk j !p‹÷¨Øu˜_ë:kJ?‘~7Ùo“ºšL)ó69G÷7uyûî­–E¦Uod²ÃX'¿$€Ó»…Ýn° Ö·à6-2¾ÆôWa«™ŽkfÅD®YÌÇ%6>‡@4Ÿ¤Bj©«wõÈâ;ñXš’Õ.e' PµËñíÖ¦$ ­ÀsÌ–êeÑÙ¶,­e胒oJ 6àÇ ¬0Š^ò£”ÐÚ»Ét@Ö¡¤¨små%¦²÷hô‰RŽãq_«èò„lÀö™ñtÃáºN23;¿žë&•2VÞ, ÆÖÅüuý_;BŒ 6b¥ÑnðY@WJNw]$´$YÁÙ¢ï@1¹Ð·œ°VÀWç óeP 8\F–çøKêË!Y*/ua&ˆ¡WËÄx qGgJ¿¥5Ý&Þ­üðÏ Ïëõ°3­êC¡&I< JSôìÍsP1œóÞ,Ú±žMUf–ë^NÌÉ—UÏÿ´ñë³U[T=b7z‡ãúŽeûÃ%ÉÛ!É`U¶ÁÓPVÙ'¨†oãY3wFàùžµŠÂ‹}ZõÙIï”UDGú8ÍøW[–d0>ߟêVtn;ÕˆC†ñmçó¡ýÎ0#»Ç7ïèb–h•ç€_ })~—Ï©jÕŸ’ãÞ(ãõˆëõöÓªéźߋOù {›¯Ç)…'¿D˜ãýúê_ºd“˜ endstream endobj 704 0 obj << /Length 1262 /Filter /FlateDecode >> stream xÚµWÛnã6}÷Wé‹ Ä II”´Û6Yt±[´[§/É" eÊV+K^JÎ¥@ÿ½Ã›,)r’R )rf8—Ãà öÖöÞO~\LÎ.ƒÐKPÂ(ó™G0F~À¼ˆaúÔ[¬¼ë)—3O×·[Þ¤›Ù—Ň³K?ê(˜¡ˆQ0©Å#%2ÁöŒ³Kê{1Ȳ@ÉÎý8ÖÂs)Få_­r±˜|ÐÂi=a (ãÈK·“ë/Ø[Áæ¶’Ø»×¢[/ EóÂûcò{{ôpÔá‚7p F, ‹ÁBL\¸P;qQO“¢$&.æO ?#át3›ÓOyiG9ó£éz¿ecVšÊî˜Á(©‡Sž6Bšå;‘6•|&),A!œþ IÑÁûl¤ÖÌQ`ÂøYÔ©ÌwM^•½àIèžÄÞœ$G‰Q_lòÚàFñuŸÏh8½SxÑMƒ±?(öäÚsÓÏï‡EŠ}8!v™^òZœŸëú ¨Ô 1ü’A­znÆ"‘ï ÜçͦWƒL(çîÍÇ*ÏÔW&¤(SQŸ÷ìB´!C1&€^ (ŽŒÅJþÜõ<Äxú›®ªlr^ãÚkaSÓÈ|½vw€RBÝÃpŠú1ÍÏÈó'^hus–¨k¾v‡q)z1/s[ˆmåvò2«$xhë®;•re&ÕR¨åGëÿÆî7ùêÑÈËÚ.Õ (q¹ª‘¥‹.îæ>A@:ŠXl àJù: ¹§ìßàÛË«€§3˜;^ìU.Ôü3üzõñ£CÎÐCeµëÞ;¸ ØÞãúY7¸·Þ=Ôˆ§´<úÎæòq»¬,€¤`ʼ\Èä@7Ѝ;tÃÓTÀuv u£”kô”¡;Á[/z€³ù{µï ß§»ª®óe¡¿˜£] µÛlxcòßÏ&ˆ±Ð³Y{B>ˆÆÌɤ*Ú$ÿ[ÕJ ¨2‹¦¿d#öC Æ£( ŒÙ‡)m}8u‰D_0µáηîd²ÚÚ¸ÂD0!( Cc?Û—©¦]ÃBâcZ懕*;ܺãÌ 4 _^ŽY2É·bÀÓÑk™¦î]àÿ9K¨ó[žƒ¸ƒêì|¿Û¹XuŸ!ß'P|ÿ…⃯AàdFÃ!”"C/ž‹¾Ý¢~=ÕZ^ áù¶d¥!’ïçft%TÌóУšT-dUubéèdÉå‰"M@z©G\Ž˜4ñc€IâÎÔ¦œº¡€$bÓþ±gÞb5»¯öÅÊL›¬îíyÖû–öï„Y0OÙËÌ(÷åù˜7ö(çÔÉ1¯rüŸVr¼½¡Q‚üÿ¹å£Œ"ØRòúvY=|C¿÷ÜË@õi²qoã_гöxÎòx¨!Fü&xÆÌ]/wäÛǹû¦>é6†¬eS“Ên[6üo‚¯m"UrTëàúÆÆMÊÝÞ¥¶,lË‘gNªße–•{î )øêq˜~x |‚„”¼4ª¼¨mÕ CK …¯ú§:ê´fmh “´—Sv›gÏd-Œàµ ß$k/eëÔ}õ¶ßÛI±ÊSÞˆî¦A€È¡ @»1°–»¥hö²¬GlùA»ÝvŸ¯.^|¥G‚û óÆýf> stream xÚ½XÝÛ6 ¿¿Âos€FµdùkÀºµ6tÚ¦OmQèåâÕ±SÜõþû‘"íĉsw†¡¸J¦(Ф~üPïÆ ¼ß¯~]\=&^&²XÅÞbíÉ ¡Ž½$D*o±ò>ùéìËâÏç¯utÀF‘H£Ä8Ó|]™Ö|Ýšær_|ȶÍû}s• ‘v¿¨g2ðoº­-Ûf´ýx|þZ…‡ê¦Þ\f" úq|ö¡mI,²Tõ¿(gsþ{ªëì²GûG‡ÍYÀ\ÆBe1‰Y¦iž‘ á>.P¶ÅÊ¿®~à$$Yb6uêÿ±¦Åvci1/w]K´¼!’)jkV÷D4DcaʯÖDh7†· ªÆ±Ÿ‰ªmÛÕ¥]±,¦æSÚ€y`À\J‘EÒë>(­]54m+¯- šŒ|»zFx97Ë„ŽãÞ3ƒ#ü  ³¤çÊù 0;ÕéPò?ü©Wã5ÐôýÉ…êTh•öÒJ{÷TüDüɇ®Qk‘†Ã5> •%B£&á-ÿ?PÅî2`¢_k»Ê—¦åû[wå²Í«ò‚³{s…¸àpHé Î\ðÑ©)$•dÀ™ztˆ›¯ìÕâêû•t‘C拃×Þr{õéKà­`ð°K½;Ǻõ4`?јû ïÃÕ»³ÉÊ¥×q¾’ˆµô¢¼óhæÔ£Ì,xIöüVÏÂÄ·ÃåPÍy“VFI$(r•T,â‰bA<„$Å^ÚfYç;Êd&?ÉÙZs]؉ ÆFP†Yo!Ìœ…n挦¤Ñ–3ø·y]•ˆ""b`W5ÍwUÓä×Å= êŠ6ŸIWØÉý,}]ÕÛ¼¼eÊ¥mÚúÞ¥ GYVekò9'Reרz¦Þt»]‘#ªCrTcºTæÿM_´”—4ºJ€²gƒ¢n]V% „ìÒ®,(ÅrqêÑIgdŸx‰è¹\X1eîéàÉPªI¬UciÊ'¢‡À>¥þ_à½~“ÂĆ{ûôÒÕÎjÿ™¢s0G¦ï]Õ:Ÿ9ñ,†»äml‘tå? -HèU ý¦êU´Í¸œ1ÒNc<- çáڮї‡nð)~Üåí&g^ªÞ0q×>DèÞ“ø^8uæJ\Ÿ…mir_u8Qˆ1]·dº¡¡Í]3³Cç…ÃF÷w„R¶¦ìLQG>ú E%øfœÜšÚZãÂ6­] ¡D>±UT;[³¶ÐxLá„t锼lm½ÆÐ@0±— ø®wó¦÷=ŽBÊÕÞ±àì1ê41Ï@¿ìß¹±6—5™éiÆÆÐÀh«¢ Uí¢ç¿Ððöã›7}?NQ¡ÈäXТ­êÊ^Ö ·Ü7(£ƒ¯«¶­¶|t[íFçŽÑë¬ë¢ÿª?g×9^Ú†ìkÚº6[¨%P ÅeÛ/¹˜+!åíÃð»¨aÿ=Yó—1d­ÄU …z±ÁF)ÄÔ¾½AJæ—EUÞ¸, óih²Ï”ða×6k×ÿ±XKRû F.´GJêQ6xý8&9`rÔ­,D"¹Þ¥ëºÚrÀå?\ €ñ‘«>+¹>9¼-6v¢qS±€g%{Í–·m€L„ž±ûøšOåFHT6¾5ÅWÌ@Oiîç™±Ô`•RE[õ®«š®¶}R:i°l,g/ƒÙw;g˜ÂƒAë±W)šŸ@vˆ'=L[Ç4D.îXÉ×Dl{y\PÄ™ÞYž:Ÿ]^ŠEÄî°)2Ril«›Ÿvr@D¥plûœ!Ò¡¸ÁlYmwuÞ¸z‚ ØãQƒw vR;>k_¤\DÜCš<ªÄa6jÁÊŸ›ÜnýÝÄ[W %‡N÷êµÈ̃¯v-Á༙È×JŠ8Þ±Û®i§žÎ¡ÐûC¯í:fþénv0·ÂtW²>®)„¾!!Vô×\F`]¨Ç.¥ýãŽÕõU5>b8ß_ÝØb}y†f/^J)¿0MK³S(þ EIhŠÚIg»$L(u† ÞßèÃ%Y”Zº‡‡›ÙéÓ'P‰‘2õà Ük’=‚¥Qm6UW¬Æ?Í }j3XÓL½³3&*÷Iék™HÓtôØÆÛ „N“q<-Î"ZíÏ9‡h-¢L":Œ‡h¬ˆ§‰/b˜ºe‡H$í¦š‡áÀšìYž[ e/óÑÓŽìÕ‘Hãx|‰„í¹N8Ý…A¼/Ý0Ÿ¬eI~{üгløùì./ è¼ñ¹„úÆ)ŠÄ{Û^jΑoÜœãš-oò’ùL¹"¶C|„³7”¥ÑØ^|§ä+[÷ñÝ•û£ºÊ·ψºoؾa¿9±é¶ô{}_Wýl{žíT*E_”sÅd£ûjqõ/ñJã endstream endobj 623 0 obj << /Type /ObjStm /N 100 /First 884 /Length 2161 /Filter /FlateDecode >> stream xÚÕZQo7~ׯ p/ÉC¹r8CF´Aî \ÀÉ¡½Kó ÛjlÔ‘ I¾¤ýõ÷ÍJ¶d'Úlà]$æŠ;K~ä|ü8Ãݬì‚Ëš¥ˆR\”„R]ªeq9*Êê$W—KpZ %¹aW¢£aX’#*y’ £%Â#M2Û3âÈÈE)¡—Rf\TGÕú¨ÁE²[h¦Iµj6%ë µ&¶?h¢Ú-v GNžV¸Õ„ DЄF³Áäá!{Jpß œ¤ls þ¨ÍžÀIŠ*\ Fq_0yZ’Nk±VR«›n…“JÄý)°àÓ¦®d8L1ë%cT¬ÆúŬA» •$¡[ð‹bŒV²Šˆ 1“äJ VøÈÖ nUðƒv•‚Mƒq;Ê„³¸šàN…3*£uŒ `±jVaŒ¡FØ‹­ÿ*Éj .l½Äêªj ¸Ð09:š4oþ¼š¹æù|¾XOš××'ëö÷?/æLš˳ÙòmÀ ïš4?5?¾¥öǤ9ž®Ý[Ëc(™Å·¼¡äø›sö9˜=wGG®yíš¿/Þ,\óÂ=¹š¾Ÿùžºï¿ŸàßpRò¶^o pô)hB >¶ j‹!VOACPÚÕ½Å@Ù×;0ÄÁ1pM¾˜ÔÜ`Ñkà ix %xÉ;>p© dêÀÀÃcõ¶Jo1¨€“±CCf{$“tC|…Êßbàêk‚ØÕ+6·[ ‚U»0ŒÀbŸ-¶¹Á!Xµ<.GvŠU;T²æÁ1¤RZ¡ÚBH‚U;D²Êð”ÁóP§Áª"Y\˜ˆÌòN+±R@ÍØ…"Ž€"Tx§–Hb@NêB‘†Gk;÷–i`°ó±A”rî$I–ÇFÞ…‚G@!ä܉&’#KéB‘G@‘äÜŒR»@È ½ïȰ" auI;õFzî¥t §Ž€‚Ä#sÞ¡ˆ°Ò)œuADÚÉw$HXéNA¾©„;ᤠ+]ÂI#È7©bsß±“ $¬ÅòM°Ë> …†•.ù¦”“r¸ðR††uI œeÓn¡"ñ¹3¡;Âù½²~Ž]óë¿ÿãÀª„ Aœ/êæ×——ïnl_.æë¶Ñ—ì\lóÔËv7—í¬;Ûþü(í4ѼZ.N_ÏÞ5¯^¼t͛٧µ{ww>^ã¤ù=Íæë•“lG–Ç6êÕâzy:[µ'dmÕϳ³‹é‹O®' ÚG;RòíöõjºDÀ™6æíL¯Ð¹ê$;ÔÛ”ˆï†ñL X""Éò!B Zfd'¦/{æø÷¹?™®fÏž­Ö‹«ßžüöt8¦$¥6C¾Áx²ƒÃ^x>N—ó‹ùûa!±0X¦·2|ìв¤³Õ ,¹ɘ¼ñõ×™|ß÷ÆùbLÃÛJÁ€Á‰ÿ+cˆj*=íLbOc²Ì#§CârGBîˆK´³–psüÉ2œÒhùLiT¨4™6 S6 íà~S–m¹¦ÚoÊ­½Æm™¶%©PvvhGúŠ iØ(Ã?‘.¿Óù™?¾¾ôÛ8œPåöÈD‘†±oèÓÏ!?>žÈ×lü –…@“·S}.:¬ õrz:k!LOÿĠØ*Ï[ ²£š ᫇'hz²X®ÂøR¿Á‘£Û~#bNG3ƒñØ53’÷RKûîAÚÄh;”v$Íó££¶‡æùéúb1o^7ÿ:þÉþ?9_¯¯VÏšfzößï–þ|zv9ûÓÏÿjVÉŸ¯?\þm•¾[]Ÿœ^NW+l6O‡š7Ãß†ÌÆ#m³üho)ÁûD<Ÿ®ä¶E…íí£W¶7žà(…øM˜bÀT¬[&Í–ËÅrÀ­s‘bmOÂìè>!ÏS;0D ‡á,/§ó÷·ÌÞñ|1¤­{—ÜðÜΓéB„Rôµêúêj Iøy# «Ã)ˆ§)ý ¶Lì+ÖÄ·aûeV­¾Ĩöbömo¶WΈ¢b?ÛˆàÐ^¯÷2¦²‰%ó€;ûö[uMŸmÕ•¸Ukr‹%H½êIÕŠÄ ;.a¹uìh/Öçí‚úL¹Í'5ö'ƾímÄŠ¸+cëeŒJ¤1ߣí¹÷žãq!Uâx ŸeƒöNÿ¯”ï;¾n†aß% H€ˆidûr„¤]3±¨ßbËVlåñk)Ît}zî§Ëó®h‡b¯TàÐU††RB¤¨ÔhM//gË–˜¿/§f÷ˆiyô%æÛ×ì%þ(ÆÙ"€ÜÏ8‹`”žÆXÊöåJ/cÆÊƒçûÛÛº"=[ŽP– —Ž`ÌvnÀ=SÀŽ]ú“¨·O…¶ œÿiŒŸiK Óû¼hÈ“%©`‘}ÅiÆðÚÂ6 I:Vï|öq¹->Ý_¸‘ú/Ü}Û¯í(_4;G¯<‚±-\›ýŒíP–~ÆÜ楟qJˆ•‡Ü`÷VD÷"ø«v)™ endstream endobj 741 0 obj << /Length 2708 /Filter /FlateDecode >> stream xÚ¥ÙŽÛÈñÝ_¡7K€Åm²É&ib  Y ˜d±X%µ,®)RËóó÷©«›ÇÐÞ™ #«¯êº«¨6Ÿ7jó·Wïî^ýð>N6y›ÈlîΛP©@Çf“$:ÚÜ6¿l‹îÓ©è‹O×¢û²ûïÝßx¯ÓÉšX™ 5ìH³sœòJÉ0×LæîÝä}”"’—üg—GÛ¢ìléd‹éqa¶Ù‡Y`2^û—Ý>JÔ dˆ¨$¨¿=CÍÀÀ±¨è†Û­zyœ A¶iñXÿ…§Gzzzi»ËÚ¯Eõ©/OU¢à?\^~Jyiî—ÂÊ{¢0 ’n™ ΞùÓe&[!ö°‹Ôv(«¿k×ÿó øø¦CfeѶ9ó³¿XÊ+A¡ðPÌG~ܲcQUÏà£Æ£³—ñ1 ŒÒné}Ù_˜‚‚UéoÒ2Ù2 LèÜW¹\QŸ×§‰*Á÷%_X–› ÊC O Óp°¢^MÝõípì­ÏÐ7×¢/‘9;“€Ô÷:TÛ»‹meMá€þÒZë„XŠžÛºèlÇà™îEÓꡨd¼µpN#ËH†ô¢{;c+!ë‡+Y"jð1Š’ù¤_ö‰R ƒ¶~ºtuäqøRáÆ©qKK¼²ÉI¹ˆ§‹Àb‘¥`Í,N@É…"ÂS^ûòó¥g°jšÊÁdÛwöX0‹y»V@wn×\åˆmð+þØMpÏêi¸i.Ú öz±’ª2ô,ôdáÔŸ ¬`Èî"Ü~HŒ€ú"½84£^{ÐÕeCM}ë4­:¿¤ìùÉê@7:ûÛ`ëžî¢æ·˜Ò6juN“Ä•×[;a #o¶…@36˜+Ò> bƒN' ²T?AÝ€H­ÐAŒg.)8 ^¿µ¶ë„.œyir‹*dƒ¤‰³K º”Í…‹nÃâØËV¬O°«íײmê+2І^k{`xü64¸=2ÒÝsÆÌ)Á°"ï"…¬–Ñ5Ñ|Ï/ÍáW{Ü…Û¾ãw i‘óÀ‘\­=Û¶¥Â[)£ *5£„B‚§ôÀöÌCÂ/ùµ¢H‚ÎɲðQÁ¼–AŒ`Yib¶?Â='¬½Þ*A o¢É´2„àI±p!Lhâ úòp¨ìÛ·U×OÝÈÂ{ÀšT{ÇsÏGx®â˱©†k-‡# "˜IFQX§A;Ïœ=p¸T6ƒXDSÛîÿWv£1¾¢°ŒB€¨c-[Š0£»ÙcICgП¡E*ö:ζï‘çlU‚ï(Ø7ÀLVyÜ c4¤ç /”™)µßÒìE„YÄ´ÅŽ†ã"9ïoÇà­O7š½$>e}_Ö-8¸žGi€ÃEõ³&ö†˜âþÌ;ÐV¯æ’ÏÏ¥þ]WåÜÑ>=dFy†^síß¾ÅÀù”˜i"’‹×úòxá ÕLFǯ é’H¦áöKIQ"•dž _çu<_¸’2WÞ<ãf .‰J_œ d~饚@÷%þj!ØL'åG¥¢#º4嬯Ý(”ÌFšöľQq Ž¸,hÚþ4ögÚ¡Á=ÖÆ½“ 7'GÇ´¹Øséˆj’×»œÎHU&0çÀ†=–MàsäÀ\º÷jVyЈõ!\AÈ9‹_Våj2I‘ÆQºý MRzˆœ$©\±“­*9,©'Óø ‡ ÙSÝ ÏH«±€kÏ€vúŽñD1©Æ´Þœ¨,“ü"Ô÷ÄTÛû§É) ´Šg}"i¹rˆFQ]hu-•”‹Ÿ\ÒX³f{­³íÏ»å¬Òùh^S78“Ò¡éAÌ([W"æ\`£on S8cÊ”_,=#‡Xq³á¿ÁöB<Žß_*bô&G Bà*[5 Ûá‰ñÃñ|O: ô"{8ïDø†WônÜb¨ÐšR9ÞjQѽêã¤ÂïÀɺ„Ý5¢¸n˜…Ÿcn nÅáa±B'üŒBNÍ)=Èùü©<Ñ*KU9äzØeq¹Îgϯ?XfZ:!È÷Ho;¬;¤ñ–¥¬|N¿7RYèü¥Ékf’ÑhåôUW…Š ýÜoyº(È'^ Å¬ñó€º9J–L}‘b_Ćš@…É\æ­½Yj&˜Äe¨Q† š{k‡º~6!!OjOk“xûφl•vr{Î6 >F/{³mŸÜiº%Ön¶½79cì³àg^]ð«k7/U¹—T÷O{Uå»S§„ÕžôÁè}¥óµZd. Ì;üŒA¹¥ÐÎ\&ñͶì *ÌÒ~—þd¦}8£|ã5úº4¼ÃÜÛ0ä\pîãž¶Í'HÎc5s(ó̤9®}j¬Rîõàè禑#|¥ØRèºç>G¦Çïe}¬†“]äyâ“´¢]ÿBûó!sƒÔüõ.I¶2³à‡Ð‚KO–p1+`ØÕÚ¿ÉÕ_j9iÆAqà¤ò‘ˆ*„v0%ÍeKÝt8«t$®êkåkWfÜ7¸Ô5àE÷LÁÞÌp,¢š?£±o1ã­f\Š®*Žìô ¹ZîoÀÈcÏs uyFÃàäŹLì++î>q8@ˆã6ÌKò|é/¼—¨Ä ù¾ÍÒ¼^þ½ïnt*gj U¿zÆhþ›g7úœµ¶>1fE¶þºb a …H²–èx·öxçDù|?S[û Ÿ¬7HÜó¯w¯þdi + endstream endobj 755 0 obj << /Length 1860 /Filter /FlateDecode >> stream xÚ•XYÛ6~ß_alTncF÷Q´m‘-Rô!- ER¤´L­ÕH¢#RvÜ_ß²$ËÎîÃ.©!9œó›¡ÝÅãÂ]ür÷ÓúîÕC,2’Å~¼X ÏuIÆ‹$vIø‹õvñÎñÜåßë__=„Ñ`gE$à£öPñaK%ýPSñwß¹æ;N.Z~HB7X¬ü‰šË{ßF§ïV‘ë:ë[®üÈuX³ ]çP¶¼©Y#5‘z”vWÞµm¿ú©ã¢kÍʆ•Í£aµô#ç€ÿhÕQɶ/5½4Üè~_•9ÝTŒ H‹•°ÀÊË„–÷gÞö©ƒ»ªÓ2Ždá'À°Â‰ç 5ô…ðöÁ™ïˆ節¦n˜sÞHZ6¬'Ë#mÕ~­R¹”¼ÖsÚ˜­’ïõ¶KãÀª2 Šx$‹"­ ôEY‰vt=å¥ÊIAbŽüVÖΧ¼bOñ6²ðR’%Ænk-Ì«?í"!ÌLDí©ò¡hÈ,ðIêû}àµK/u;£q9 Ç1t*Þ<²VÓvTh"m–^äœ4•èþ‚åÒ.nõBivoYÑ5¹ákY(‹Âw[QåZ ¹$$.Y®Â04± D£€Ú«Ï„½V‘Gü05¾ˆç|a¢QèqË$kkð]´*0ŽK`Ú~7N›a¬>!·.}áÇÀÀ³FfÍaÆ^B ¼â——Œ#—$=j°­>Èr{zïF.üy#§‘…$ö@+/Ûe·µú}˜õ“Ä0&=îT~Rýj¦¿Å°¡B¨lö²9žH•|Få,!QÎ!åP퉶‰Gâ w@iøoÙ¾e9¢•þ¦†Žñ…£‰Iœ«˜ôaþ¶bT0MïÄlîÅ!ñÎpް㓤\AcÈe#$£Û94qÇî³9¡¼>qg®˜œx> <Ïa´Ì…)8}ÃZQëE4ކ=nÒÉ…DTIhâ‘aˆ 1ÌF£ªÓÈÏ2Íùž LíÌwþ\¦X7ÔQ¹+›zÿ˜µ^.$va lí] •«9,îZZá€0Z«½!˜R½òFêïš~\Â5LhrË P¥ÉÍ)CEîëÏ™U¤« Ø0ßiâžÊ¦w¥%ò*©0,w-ïwS(èŒ*5Ëw´)`TàÆFºæ–ȶÊ~¶µ€ºø®ùÌ?ŸÑúZ~7qŽ¥È»’µ(:nTA´† •8Ÿæ&/º0IÏ.Dîô4'»ÜQ `›¡6ˆ)âBµ•g{t¨lnµ&9I/Í ÞÐ$¼ª8–ª£n&l Te€ú‘鹺.]+xÅM[2“ðÀC’P‰L¸ßB%ÈÑè\{¡^ÎA ‰³lˆ$Oâœ7è9ëÄD•†ˆgTT@·ÆÞØup2rBC—>"üã]{£NeØžÆÏmŸø~öEó¤Iò\ MB’ôÖ™mÓü¢,8êÕ^¦õ¾”˜kÒ.›6º´Š•mÚ 9a¯¯–ª²¾>¨~YE"~£uq¤zÀj®gÌläf4çÖT°ä s{æžM|›®/•PØÅws{tâ¶ïW†íÄqµÌi+¬‘§çGý<p¨˜„tRG^jž†WÏÁ‡c ¥ü‹wz’ÓÆšIÈ^GðºžìÁ ¼kÄØ” -ìMW}AÌéyÍ¢R¡Ç‚s½ç=Üoh{o”ÚÐÿ¦kõ=jya«ôº­¬D/à¦çìÑBðšYË ½=4ÞZ– CcH’OÎ!bY ÞšèÓ©a,_Ü9s¥z ôÑlÙ¿º«Ì–Òœ·L#Ö¬Wç´$ǬÃóS5vó½®B8=жTÍ«HÕ©Ñ…ø¶dŸåýãb>S·JÚV÷¡4ßSuÃËã[†Øv-ŠIvô¥Ty¡eO1.Jñ²§(Úcw(äå‘ëNÝÆ<ím˜UÕt®$‚¶X¯„5lïÁo>õm÷þßèÁ¿Á _Ì¿™o'U¯…ª r³pÜqzЊXãòâ"®Å k·±Ö/t\RðÑe¯ð#g¨Uå0r‡Å f 8S1¿î ñy ø´ðXdÞуˆy/a-ÌHà§Sù/ïÆY_àÿùÒÍ7:€×8Q¿Ü`«fÃæÃÀ¢{3~l¸ ºáœäý‰ièÄQric¤Á[ç|‰:ô'*jÓÚõj{…ïEk "é 4½2ý É÷5·¬õ/-ä´üh°®-€‹R»“ãŽY€9ÍGTnËâgGÔ‘Z¥l&u•,¡ò¬.´>›× ðײlÖ¾6ÿôïV`myÕmÙ¸^Mš‹srë_üFp ß>n™Ã‡†!ðæPšù©OÂÐC¨Ñlo£ñŠèCï_ œ>RÎÈuqZ‡¸Ñ|©ëÀt,­ár诙©å纋Ïc[ž[ä~w¯™mÈ_¯ïþ×4v endstream endobj 763 0 obj << /Length 1582 /Filter /FlateDecode >> stream xÚ¥Xë›Fÿî¿]"ÕVì Ë.¯Só!}¤j¥jë¨ÒèŠaí£‡,pÎý÷}0¾óµ:€e˜÷üfÆ®³s\ç§ÙwëÙëwÔwb^ଷv]Dhà„‹|â9ëÌù4OšV.¨;¿ÏyUîYÙ.>¯yýŽ„½/©‹Q[ù Æ‚dæjA¯ßyĉ€6 ‚vE""ˆW^(¾WŸ´U½Xù®;ÿv¥®%;€\+ó/×w‹¼‘W%ßw{<±çƒÆFþߊb •"Y‚W,Sä!x£´Ü$ »¾®“¦eKu’ªËé{ЋÁÙYaJãWF1ŽÓê£÷¬ÐÏóÅVþ7gL¤† Q¼’,Ó7ê²Ï³¬`ê¾ç^uðO×è»mÅÕMSW¼½V:{ŠAsÅ~¬„ô¹™ÀW$¨µÖ4óm©UÛæeR꡽Õü6UÛVû3š¦UÙ&y™—;õœ%mrmdõ5ìsi¨”_Ü£Ãv•\éóÍð|s5æ«ôê cÿÔV¥I©ó»:èÎ’– ƒ”4wZ¼öJÓÕuñ`͵N²e“gjƒû®jÒóe3é²£ô~- ߈WÂuJÈr¤Ãûü„3Ö·ysŒÛØfë¢6ʧa™a®­¸OŠ›6Ï„:Rœ<ÎK¨´DÓVÛW|è|Êîc•¶<Ù³I ¤é*YÝ®þìÕ sôS*t\Ž%¼9Úþ„Ë>T&GnMâØ$ØveÚæU9…‹nˆü8¼SëÎ ^€XþÅiÒªYmþaé²!òht¹Žÿ¼­®U*ªêÎdVWk”Ã1 Âp27j^ÕŒ¨Ú°4é6L6kî¾+Ú|U°{Vèny—¶NJÉx$‹–½\zv>…KNJúXCYŃQí)F¥7ʪ+£^×^TVæ³3ÕË„dŸ”è gaê%Ú>«`\‘vi)—µ¢5m¢ã(Šã§òÒv\$M|ªq?Y8Zq3·UWhoìXÉø±Q©Ø˜VÊM³k•IÎ*ðPø“1.DcH>äEa:EÓñ“¨ºQíh¡¼êv s;*†ÃmU°G²#)Sõñ µùµ4V–U¹²øÖƒ3Þœ©äg€Öç¥k—?’fGóɳqÙM³y™>R– ¸Æóg[ƸiäY€ŽÙе·£×¦Øž‹9JUƒ<êi3xz Í~\ϾÌ0(à:Øî„FˆBOI÷³OŸ]'ƒ— #"qä$éÞ¡ * ½pþ˜ýfwŠñU.3PT½e, (vÁˆ –™Á"ÓÛRh8øÜCq„MU~_1¾ á\øßóÕ"®"<âjW¤õç=îÓv{p Ésì–ö‘`bYó¢y: ?°&åym†/]Kt;×÷§¼3ë,p.¶;ߤ" !óf¦LÝÞ/°?‡Z­¸~'8æeZ,ð¼[¬ð<ËáNÌ´â¥ÏÕ…Ä£p°¸ ‹ëh@áG¸­X-e/¶ }ZÍø266 Ø$(ó/64öæ?oÕ¡³s©?V±U¤Æ(AÒrÃ!ç‰ÌóVr}]t"ñ™¬=qšVœ3X ÊLîâ¨NÒ»dÇáx­–ÂG c:|ð‡"‡ïsûûIÝ¡}õÝîF/8¶øŽá.íEP:Š‚éX÷óL4A&Öõ+Ú0b*ÃþwÆ}]š¡ŸÛmOʇïß÷r $Ž ¾å pð®“[Î£ŠžS*F_s` qdøVCžs0¡Jþ,Ò3As[áðÊDSyár ‰‚À:þ8Ë–—gVì£Ð·óÛ×íÃ¥©å° b‹jel+Â’Àd …ø¡;„š D,ÒSÔêMhZ<(šN¬êçŸ"‡ÃÔ?ܲÒNWG]<ŠâØzèëœôÚÍFŠ¥D÷3B½yS»š»Ä¹ e¦^I”¢¥(™(i ’3¼æZÕuÕ¨¯5ÆEHjÎVÊFB‰F&6ÀT‚Édï1–§E~'œÍ&<‚±}×Nœ¢®&¼2œ[¥fñç¤|‘“ªXL9);è‹ÿè=S endstream endobj 774 0 obj << /Length 1711 /Filter /FlateDecode >> stream xÚXKÛ6¾ûWé¡63âC¯ =$iZ´ ´Ù ‡$h‰ö +K.%ï®/ýírHY²egS,¼¤Ä!ù̓3› ~½¾™½ø…'AF²˜ÅÁÍ: aH¸ˆƒ$IÄYpSç”->ßüþâ $y¥°Ž•‘í—õ¾Î»²©ð,t[Àúñ`ÖÒO[²Ä¼ÄÉ?«N–U;š8X`¦Ò”Ä)ÎümÐȤ$MìF‹$„1æÊv±d,šË[U/D8¿/uSoUÝùÁbj£Œð˜û…vRùóí8#”e§ûÕM7±$ã$zÙ?>¼{7± ….‹¼Ðs\¯»UWð»û]Uæ²S>¯ÔºÑÊ÷ËzƒÝVyÅXµ€ÿ‹±?%<‰ CIECíÉbÉi8¿±X¢p®U·×5öïͲڻ!‹ZÀ­=x”ØåÚˆ¯•FàÕ¹^v¶¬§ÌSgñµ $Kû N`«,$NL¬ÆDd%ß•k‡4?䕺³#0'1 GEÕ÷ŸÂ(„BÆH”öî}X€A¥1V~iÖ :ï–…Úiåݘ`|BG€Ák¹õo»fÂ4TÄ$£lpp7êT)#‚÷-k·_%mÌÀn!a$4r€Ò!ÆVÌÁÃø"oê%ÆK ~8ÇQ[¶ªóæ>P;gyн°AìFÚÛf_Ø7ÇÊvV> V+m£÷¾4öšô4õNv éí£Üî*5‘&½Âb±è½€·®õÝb…áüM£t®°/±qž2Ý{•wÆ@¦^C©Û{^ZÃ…°AËpGÁ—nâ™K·].uëk``ršŒ¾>`[¨µÜW>”®Ý¨®uðnj»ëg=l1+LÂ. /V ,ðeÝ“Áú|°ÏðÈ õ€Üj’ýP¿Ëî{m§!£µcMÊväÈ…ÓÂHwùÞÉ­½?vw›áî“Êœ›üÙJ¶êÙêWäíIzvæ£ô‚n¶4ŒÃ\û4/=Q ³‰G4{{3ûgFaRО(žQˆ‚|;ûø9 „u ÏÒàÁŠnÇ;¦LVÁûÙŸÏ‘e#ãTèbA!!BFL²¯1 1ª‘”A‚§>_½i°z(í Gƒm¿–}²IÊäöªi÷zÁ“¹º¢;ÀãëtGÆO0.žOÄžµ¹.wg:úö´¤¼ïäê¤RN„©ØÐ Š“>Aa?™rB£D<Åï®Ôˆ Ats:-ëŽÑb’gÌœ8Ó4µZ¶pú |4ûÊ•µñË@Øo u%o`]1»Æ2¥Ý³ xÓ©ävUH¬0gÛöPwòÑqçöÌï䯗“ª¼35×›½ÖzEÈŽ.X¢}–4"iÿ?“b˜©ke$á=ü†L·&‚³@·­…œ¥Z|)õ‚¦óÍÞ1$š&&tã‰Þ$92~ðˆˆ˜aล|€@«ÖVÓ/<éër[v¥-ƦÀ+5[{JÀ’-QË\šÚ\ǨÉufþâF—höƒöhS¤’Ô°…f§´s ü‘4ЛÀwÿW~´rÎc/ã1J«Ô•5Ní›pÈ>GÊ?iÞKg5ŽÉÀ5«fßyEÎÍGÌÖw‚–~ßl•³¨„§k§òRV.Õ5u§÷Æñ`y¦u²åé™â—´ã>ñ–ë‰H2=~¼¿œ/"†¹ÛTâ‰KÈ1¼aþž@‘$éW6(ï&Öƒ )Ïúkc.ëïÍI:!“¹eqŸ„ÈaÍPÓW‰ˆ“Êäè*ñ¡…œótŠyíB1 ¯Çç}¹ÇÎOØÕª”¾D¤àâ™Ñ>\1‰ÚÕ.³×·ïy‘‚;ã¼Ò&À0‘]çáŒãùÂãµ£–ÄÃ[à«k”ÀÕ)Ò3'c Ú†p‘p®IxÌàCêrú™ "‚%']vãÛò¾õÑç¯Ee‹–pø¢3`œói` éw³—mWˆ' Æl€ŒGb®È†Lݼ#°h¶ÿEŒÄÕÛ°aÓI —ïa´7ðmÑçÂä*Ëâl*Òöök†-g°ZZ©£ÿÌËK™Mo¿Ãq/ÞÙ«µŸë §+D¦@R&ÆyÓÆâË ¥yH¢ã•šL}n:šSš-(p7©l 䣲mOˆ};™ÍRÈ{<ùú^}™ütÎçaŸ=ÉáIˆ{ƒBö¥GðÔ~û9ß/v›}n”K³Þÿ»Jæê¶©Š¾pÏ<ðñÿK¤:: endstream endobj 791 0 obj << /Length 1672 /Filter /FlateDecode >> stream xÚµXKÛ6¾ûW»©Y1Ô[ ŠÒ<Т@Ûds(6AKË´­T¯ŠÔîú’ßÞáKy7 ZøÀ!E¿yrÆØÙ9Øy½z~½zú*Nœi˜:×['ÀEqêd)FI:×çÆ%ìÏš¬ií}¸þùé«(›íq€²˜ÉA$¶¬°fïøNQVäŽfâˆÚU’ÖóÃ"t×T#£EU-ã”èI·U†ÑìÂ"DIR˜ Ñý&AEÓÏ£Ô½ÞWLq%uÝyaâÞéù¡Á;5–%\" Ü[/H\:ô—®éIÉ5Ÿ¶kÅ×CÓL pü¸0"@E’(Û±-yÕµp]”a÷=NpMšõ†0 µxWñ½¢Æ^Œ#æüÎ °«'UÛœD)ìxeóU¨7j²ºFSÝÐŒ5Q±F–*d{â…X‹2%Ø%j`=-+R«I §ÅàxÇè‚I„ωQx%œEÈ'$•"~n¡$Ca>Ї›8e\Q€ZGZµIŽÂ("F8.ÔÁ_”…=2·‡¶¼–¶ÊÝM§–ÛŽ+‚}ß \;(üPî ÂOùÜõFžlõ@Im_¾q¯@ ¸p7#U•Ãä.ßëi+rÐ_Õjî’Á rw76€Nc%µ ’ƒ´›Z†‚½åthÁ[^š¸Èsb?KQ‘ ¿KQÇŠmoOÎX&ÐG´ ^¶^ ®P ]+`j¼ÛWå^›H›jKù´´×ÎcÝ>\’EŸ 1Ø1Ÿ¢t)Œ3gáÑ«låCÕî>•Îu!RNŒDÊÁ¹ÖìË{Òô5e–FÎjÓXº7¤¯ Cy¦Ãfëù Æî÷¾!9É…ÇR«˜äøD ir.Ú…·âL€çŸCð¸S~Þ}É]~ ÆïôÕçîÚ‰3ñ¹«ö_#–Þ„çîÚ‹Cé•Ú»óR}Ÿ¥21R™˜¨T&é•ÑÔdOn©õuJ]’‘H]Ï,xùB’ÚžÂÚu¢9­¹¸ñbÛubúˆÄ¿ USñÊ€ßÚ éAݨCÅŒ6ˆQQݱq l 5ÕŸå[S1~N>{ç…Øzñð_{:Þ l¦„ ž… $—0˜òû_SüwÄ(>F¿yÅ-’zˆ… 2³2çÛ" ÃO8ߊcÚ@&ꄯCàã(Þ6AÕÕßںʷôû›¬°ís¹èVx¨ÊAP2 ìÐrrÿìqë/H( Ò/¶â“%ó r˜|ÏOC”¥‰³ÿ5ÞOÿÞ…ˆ5Ó> stream xÚXÛŽÛ6}߯ЇH@̈¢HIA m“"E‘ Éæ) Ú¦×jdi£Kv÷ï;Ã!eÉk;»…aˆwΞ¹qpÄÁŸ¿]^<{-² `…JTp¹ x3‘ª S1“" .×Áç§Ñ×Ë¿ž½Nåd¤ÈËóÖ±ct÷O­w^ÄnùƒµBævÊ"ɰ‘&¾©£…HÒðÊÔ¦ÕÕS¨¥",7Ôz× TX7õ“ˆçaOÕou%2¼Áš 7MKÍÝÐ*ÝlµZÖk*5nÑfù¯Yõ46xÉ8ôóÖFWe}å)û-•¾Ä2ÖT\éÊKéZº»Ý²6Ðô^pÎ ),¨]Îáþ>4½AAò$\5u×뺇U9,•ò4:C 'bzuújî;O}ï¡ë,–Éýÿˆ8 Ÿîý²EÏp5ìLÝwge8µ7§…nÏñ¢E‘~éeMᎢT¤vÂDÐË(KÃV×ÝÝIÓî4y.\¨oèKdù‰óã âÚ Ä/I"gKŸ2ŽÃ÷Cƒ¦£­t{ÎuÀ+Ï÷Aw[³>\û–â–‰\ÙzX,Úó«ÌšÍç``QL~^ÆŽô£ˆ… ó\?Àëÿ¹R,“âQyàìfr.’„3™fÓçwˆ¶‡ÚèåŠÀ¥îÿ/Po‡Ý’âÁtéÖ\Ã%x ´Ñ «íÿÛèD¥–ñqÿ§».ïÜ1mMéæöw×¼,sé~]/«ΤZߤ{Í6-ÉÌ…iATŸý’a¦DæaWî®+×Úíé•m3Tkäҵꎺ–~•9ÑrG´ÂÍ-ä™ö°°›’)u˜i>$è¦àŒE2 ºB¨ðok_Žõø‘Æ,-Ô<@ÔÃD;Áa&5¬A€8©IMH8® ïŽr—¶@¡vêO3-‹ñJÝN¯›Ny6nÇÜIúü ÖGŒòÛ¦UkÈ@I¾«e£n>dÏÉ-ÈúôˆÙ+˜—åg@?Ä:c"±nêÊQø£KÓ~ë&N†X<óTµc~éÜpx¼ü©¯÷¦Ý•uÙõåÊiåáxØ…H"(žÄŽýÃãeÕ5'‚ÆzÃPDmô­o¼£Îy†ÖR¯¾Íý¸¾ïÎgYKUòxB¢¤bj_ÝjôÝÃSÈ®ÐF=9 áH÷KdÝུԶâqãÛÍPQ™(‚%g²¹EÙÁévÏGnÇÀíâ~æƒcñ»il2ºÔXãþÿˆÙ“™~¯Tœªö¦w‚Íç:èúŽ èãS[¹ÜzüW#ïAb‰1AäˆæÖgr¶º4+—[±æï–vëíÊ«­“Þ]Q©â#ÕTæŸãΟ‹‡¼Ôyþ¼bŽæñêòâû·6ÆÇGˆD(°·Õîâó×8XC¬ÊD‘7và.HÁ¹e)šO|¼x’¡öãàÞ3•ò »Uy~î #½ðÒÒñ óê¶oñ§íeŒç;#Ý´Q iênn¿§•3–æÅcÔ¥çuäù†Cº ÷EòÓ­Ú’‚Ï1{~¼7;tb9K³1>u¢Ô_ìÛñJq"IJ!6Gx&ùö¢‹Ãïj«[ÀÙÀЖZ\N¶¤d¶„/àãætôºÃÑİæÇÉö¹zËŸ i­ÅfN½Y$m›¡^Ãö×ÓÓ¥òâÅž ó–é(]a\´ÁQß9Æ\ŸŽº¡w˜ƒÔetI̲8;Ÿ†~:útÀµŒËGEù,ÏÆ»öÖ`>SdþUGï4…&ü‚…„.œQ‹¦ÏþGƒ}—cÔE¯S9N*;AÚHd!¾ï9Ißß<ÇjZ}ÿR”QÖ ß²w9aRŒcdœå„€;jH`×ÿ3)p endstream endobj 824 0 obj << /Length 1513 /Filter /FlateDecode >> stream xÚWÛŽÛ6}÷WéC$`͈Ô=è˶M‚En6íC´MÛj%Ñ¥x÷ï;䲤µ7N±ð’âe83&ï€úbF‰&<© O# ùߨuƒc–a²ë@D[®ú}‡ €a‹ªÐÂ)µÜ'j©“ãýOl¬=¥‰KœiâŸÅGoM®é `CýyœÌÜ=»š[÷(…ʤZ¦”:µèþQ ó†Z[º?ƒÜkÃfKýÒºl/Í C=ú ö»&¤0‹c’æªøÓéÅõM‰ÎòÊŸû²gŠKVPÈù¡Gç½g Ì|àV 0f£g/|Üa3xúZdÙ¬«~ƒÕM¨] ;ÀŽšV•.`@¿¤ûŠãgŠ%–5‡í:NE¨ë‘²Á÷2 PÅF³*–O¨øæŒ#bÈ“ÑøIz…aé°e–Sm-ìLqõÍfšfÃ:`¯‘Cjé!¡.µ›ÉÙ‹þ\ªoq endstream endobj 841 0 obj << /Length 1247 /Filter /FlateDecode >> stream xÚ¥W_oã6 ϧ0n/P«¶üÿ°=t[{ÃPlØ]î©w88Žœxp¬T²“æeŸ}”)¹vꤽ "J&)ò'’¢\km¹Ö‡ÙÏ‹Ùõ[)I#Y‹Âò\—øAdÅ‘KBŸZ‹•õ`{Ñüëâ÷ë» púqHâ(=O&¿ÉF”õZ±Î\½h2Žrh¬Qô³ÌÖl$vn¼¾£þÐXPä¥$ð{[.[Á¾¸¡ût5wB×µY½Gâ'þø|ß=µ!(u¨ORÔì0ÔÀžv⌒<«*&¾Á²bTêŒÊS•4!Qâ7bî¹öºÝ²º‘¾ììÓ)ÎÃSŒ#’&ÔÍM=whèÚ|ù7ˤŽcÎëyàÚû¹ÚL4dîø`ÞmÙl˜@ެÖ;Á$–P"ùñÃÌzèx˜´˜”%¯G–in´áPp±m«Œœ81rØÑ^8^Dbš¢/ê ÞìøbÃÀŸ‚Tçd)x­pÇŲÆñ°)ó ’M/0v¨[“ÞV+Eûö²ç£!€YÕf [€aÙÖÕ9ZÉVHÏ&æ<¤¡yÜ.y%‡¶bu*À¤R›-6¥ÄÕÞ`mŽ»RqqÚY,è,¼ô¾v>ÃGãóH óÙ™²ñuxÁ™Ô$úýÖ“Ôñ«’ë;Or"ÒБív e5Yu€ Ðd*9Óí&è}YhÉü˜Wì•Ùì{Jd—¥&^¿P^‚&!Á¨†ÊÏ ¢ 7‰(ñ½ÔˆÔ\ßAÚ‚=¶%@ƒ³¬ƒ'2Ue^6øeÅŠîÛJ/¼ˆµX`Άxβw3m¡Då…à[\‡8ÆØq´…£ÂÇz¢OJ‡ø¨X8ˆÇ0Pþ#‚¥Ü\1†ë'Œ¦W ¸@`å*œÕ<êb\­óGQe õÉ%”¸*?7“Ÿ±]´uÞ`Á€Y&åܳ۹ãÙ[ ˜fj6YƒÔ3”Ýn‚!~Ú¸~º`j uú*²4yØ GW™ð­Žâ场v«Ëþ¶\o4YsM,5cYŸdNÑ6çÇúôfûÄ´ÜM%ù™´™ºCÎÜs&ƒ¤áAžË= ©ìÆæD¯.ÜY'û©à=GÂTžmg‚˜$‰!B·OÙvW1ùö†&…QÐûíëØÿ»‰º€]¯÷piKÝ£ôeQ/¨üíÄë#õºî­ú€Ž‡}V•+ˆ!s¸éÈ™ó®Ö*Zõ~нï˜~túJY¿ÏĨ“z×l ´¼vdC5c×l˜Ö¢$®†ª{yŸ’$ŽFVw÷‡f}®rj¡Ô`•ëš ãXa 3i÷þuÛþ)8Ÿ¶ç²Ì¨õº´Zþ?°=Óæy‹Ä¶•Ú~Ùîv•>ß²91¿ï-0 VÏÍë´G8*³.ƒ>ìvg·‹ÙãÌëÒËë4€ N¬|;{øêZ+ø[?M¬CǺµ(n1ô²®UYŸfMî…2®`px\ Äâ˯`ô¶ñè0×ɤ®€Ó¸1¨›ö”%°ýwøˆ¯­hâµå%0ººŽþÊd.Ê]sÚI¿ù„¦_¸ý˜Ð$28œ<äëí¾ «‰>¿Wl2‘åyD Irò.'¡²ft—üï'!M'àxzQÐÍGü/2P̧ endstream endobj 747 0 obj << /Type /ObjStm /N 100 /First 886 /Length 2183 /Filter /FlateDecode >> stream xÚ½ZKo9¾ëWØKr6ɪ"‹1@fï° œ,°»I²Ýq„‘%Ç’‚äßïW­Žã—ì¶ÝÉÁ&›ý5Y,Ö›*\p%ª‹•ÑVGT\¡èX1NÉå”Ð’+ÅžÙÕh­¸¸¢“]ŒUÐ).…I!LÅßpr1G¼bBGfv±,Ãø¼°¢ƒÏKÅäT]T|Z˜Še‹d—Ö+RÐ):)¢.Ű:àœ\JK`öÄ\LÏöUVðK¶l-•‚½eqImS+h.“’­1b$¢ƒ…K!G¡änÓ”‚u"8ƒ0¨ ¶‰±.‰Q ‰ÍŒ?êØU€É9O@,›¸€¯¶£¦’Œ(æS¶‘„Nµ€+ÙR©x_jpl)ÍŽS´NqL™&Œ ³+kBÇXY6üK€dã$Γ3&- lIê4à•sJ ´¢Ù¦©N’êDCpÂ8:0™ÁR)xÒŒFqŠ­‰’$tÔFÈIM8ˆZÐ1îE—C”‰FFs)¸™#ÎJÁŒÅ¤ŒÔ:‘ÄèlB§ÀåíÄ ;¤Š â„ÏMƒL$­‚6°RS6!Éèà•¨tÒb#ø<ã0•‚ª  Ø€8µ3U‰“NH´b„ìh_!uj“S› ÷Êö,WQ?Ñ)цëf†Øh738­*a²·7iÞ|=k]óçô¤4¿/ëv±^üu<˜4íj¹9?jWjtCÿjgÓß–_Ü[SY©âS±9£×ú~‚™Î1x#[øËÅb‰ßvÊ‘N¹»–bߦ¾¥¾å¾•¾Í}[úv;Ïûɯ¿^ÚA·Î¤y½9\wÏÿœ-þš4¿-ÏÛóŽÒð¾ùGóGóûÛØ=ØÞŽÖîmÊÁG³+1x[‚böü-)ú̸—noÏ5¯]ó÷囥k^¹g¾ý<ûƒÍܯgÇ_Ÿ;Ð29’}Às/8aŠÉ›@å’=gùÙä@Â}y3”)%/æÌì¡!?9E|ÄòBBg–°x‚ú „/–ÝÌ™­gŸÛwÃálq<[œ¬Fä²ù)ñ¡š³PoÚÍ5ï¤çpºj_¼0&½{öîùx´À8Cxò-\Š7óv-?ê¨2ä> ùkB7ùlž;ØÑñÏ>&ŽÐ 8U‘g¸Q‘7W%yŠ07¯ÜÛÒÅr®ùÏÿçjõÄ]$ãQÃb3Ÿ¿ß…!lÁ°.›7œm…XøD𞇿y…c¸Þ‡‡ì²DâÖ35ûðÌõÛµ0í“í옢ùó|yôºãár_í»æMûe}Ý“]÷Å"7|±Ðc|ñ¥ ?¢ËØ ®k熺y‹‡vpò ó®²u'›}tr-Obk¦lÍñ‰!Žô¡Mc†(єٓ·œ"f6o× (’ƒ:zö×I§¢íâóˆvf+à,2y –ƒd¯År-†¹#"8=[½šœ†Kãeì7C"„XM~f9 '„%y ÉÑü`‡[—]j€o—É-ªóX)|CAJz¢‚”-å–ÆŽóObIs…¡Kž=’=Ï0I¼Àe—€´síôÀŠ”þŽ2V/}«õùlq2r²Í©«Ìd¤ÿ J ÐR’Èéÿ§ÍrKϧ TtÌ<—°•¦}µ26Z+•r Ûc|nŽΓ"FH|γiKÒŸKK V~@8/fM9QÙ†óY|Œ»³úzzÍXYU¨±º‚½0V¹úx 8™QMÃÀRÄ›¶ sBb£4 LðøvK4œ`ñÁQÕSá‡Ç» ì65ÝÈì&ãI6Õ®h¶¶“ú–ûv{W ýƒöw v93f".Åg»¯JPÝh÷hƒ]û˜êÞkdçÓÃv¾Swo[>8¨æwe…Íq2Œ«y•„H]ìª&aÏû‹uj^îíu+4/»¤¢yÝüûàû{öq½>[½hš3ý£ÙÙ¼]uu¼Ïí9‚£åùIcFfõËt ¯p¸Y·þãútþ·ÓÙbv:ÿ²YÌ>mZkìƒéüùxÙòg±»Žâíj“,±ýšx×tO9L6²Ç­¨[5ß®aºë¢.³„Ü^ÇP¹Ÿ$ÊÃåÈe~‚Çè®EÉJÆÈQ ÌN2Áé]¾uÜl·wd é·[Îh\Ì·""ç§)Ã#Â0C¿Ãð®ZÒ@bn†?fjÓð´û ö{rlr+ÃÀ!·_ Û%BHÃýå4 ”¶e¸³Cg~ØdI‡òB‡ 3=1¿ØU>£Ø¬7ïÓ•ž˜WÛ:×ßk?®ãÞSDk?Œ(¾"à¢.Z%—Y½J¾¯¢Õ~9;oW«k5­‘Ì(‰ÛÊsbû Crë]æoÜ[ßdùCO„ w°¬ë"z¶ŒnŠ\'‘Åñ§•\bóWz¤Ðýü8þ·wúÛ»[Á¹ Ž¯Ã°’-$¾T^û?è]1Û endstream endobj 858 0 obj << /Length 1508 /Filter /FlateDecode >> stream xÚ¥]oÛ6ð=¿ÂÈ&c«ï¢(ÍvCë¬í0Ð6 •DO¤šúßï¨;Ê’ìté† æñxw¼ož¼ÅýÂ[üzñjuñì&Š9Ë“ Y¬v ßóX%‹4ñX‹ÕvñÉáê/¥Û²¹_þ¹zûì&LG ‘ç³4i=¥Ÿ’ äm2¢u‰Ø RƒC–ëvé{Î}W‹F« ÷|}v„cU €yq„‚¾Í¯«™&,Ï«æõÒ bÏ!£zX¶„;ÔkY±¥‚V·;Dò1ýnt!èPz½ <§ÓB®¥ÃVÔréÇÎWó#¶Ä[Z¹A–Iì0òíÄ_yÔkí† ruÿc™¯:qÖW3³ç>"Ã7oùF ²•ÛhëIêU¢¹×ÂþYü±rwM¹‘[²]ó{õ_”¼kªò‹I k"ü±lÑfߟ$Cè± m|×\‰çϹbÍÏ^ìÁ¿ÿ½É %½Ô àÍöéwû)K|ÿäî†×â)7§K‡Ì¼B/OäÇ,ËóA3[‹cÑ3‰qÆ<ÿÈÑiYs]nxU ¯ƒÈÑ-oÔN¶µ2ûÐéšÒ5rLeF,„Û\ßgy£ ièeR€RGu›!®Î蜆,I‡x\¾¸û%~“f//Ïi°,M,©–tÓÒw ºußʽÉUsÛÝêÆÍ}ÌâØÔe³*J…§%)ZÖ{ÙjÞhDËÑ—Ôa³•Ë vˆg-È ~°8š»wÚI(~È š†æ’}‚xJôÉ=ÏyOÅÕàz¢€Aœ€FâJæöݧÛK®lëØ":Y²†åŒ8Ñ@ð†&W6J ¾eSõ<03g‘­áÇô_a8â“{ ÎÞ£p»•D*5›QléˆÀÐ4zBTe"šÆÎá‘Ä#Ìæ¯÷•¸2-:7f`%˜Õ6sML$3%…1Aû¶ÒºXO‹›×ïÞÎz¤š¹Ëµ2Ÿà³…hð)á¸TÖp¿ï(Ô‘6§t_âzêãüXµp&I¬ÜlºV_q×LÜ,¶Hs´åô“9Ší‰³âc9ÒKÕ¯×^ßÞRâÍz=½£Ö=ï“~M!xRSˆr–ùCÿ˜GÀ‡.•Ç!Å ø~ >ôo€©‘”lïʨù`~øûÔ1^ 2S+ˆœF yJmÆ×|ˆ .¸&È:+/³ÓmdÕÕƒèZoÿäµ Ä–kšBv-°‘×åxh¡6P—÷%óZLæ—J*“r}‚†Ú§ÑÿHnr‚—¥áÖ¢)¸ÛȺ(hE· Üˆ\j-ú†K7ìp%7TsõÝ ›ëßoéÎ!ÿ|_Z ¨ˆñn”¢w˜,Œ XÆ„‡FþµleÓ° ‹ìcQV–»  9Šîí1Wà2»ß€Éñz“™½™[ÝzS¼ik{|®çsëìØã™onÎlžT1H5É>Fèãgô$¦¨×«!”!Ä^ãÚ ¬7#%ŒI/ÀÛà±ÅÀgžT¦e‹ }'{¹ûV(нÏHcu˜¥3?À¦ÙyhÀ€;ãØñ—B+»f û=½©¶ìäÑG|]üPÂ}¦FKóð‡†:óxÒçÓxàÇ,Îf#ùAª\WJ>ò}õ”!w6¤ƒÊOp£”Ái5ßÙ¯ jJ´+HXø|rÁiC£­l †·e?¿Qžž{Yà»2þ!o¦,ÈêÜF©é°ŒïÜCË÷å¿;©:H¯óþaxŽgþƒãÊ÷?m'Ÿ¸HL¢Áé>8êè§eßx¯½1D'ò‡9úçÁMGŠˆEYd ÊÚ´‚k°’µ…°¤ŸSIÃÇ3ÔƒõÛ J$|áâ ~Ñ}2À‰uy_D#¦5o§Lp‹a¹„ƒË1µ±É§1EíeóU´ZM´Æ& ‘LñNÍ8ƒž\63¨×¡{!w†,xÌê#ÑD,qœÔŽ]߬.þl — endstream endobj 870 0 obj << /Length 1141 /Filter /FlateDecode >> stream xÚ¥WÍs›8¿û¯ÐfŠ* $Áaí$Ù™Nfw6uNI§#cŦÅàÜ&ÿ}Ÿ°`'zX÷õ{_´Bý=û<Ÿ}¼ %Jp"˜@ó'D Áa$ó¡ù=x4ö¿Í¿|¼‰x3 ŽhrZž…ªtмlu°­ô2KU£kóÖŒ8]×óÙÿ3 $Aô †EXð¥›ÙÃ7‚–pùÁU£ß-ëE”b…@çèë쿽¼ñÙú¾/”`Q$‰Ä2Œßi'¸9e8‰içægUù¡ô´0N<#ÇR[ûw_à¤Ã"á×ø‡-Hb$!fp¶–]é:­²m“•ÅÀŸƒ_C cÐ –ùZׯÁ½^\Úçt­ÓŸ†ÞSYÙÿ”=V™Ï¸÷˧ÜÓ…ýË…˜>#Þ®±—Eþb©J7»ª° 5€‹1†c"ºHÏïî¯-×Àn`âBvL{ƒ ¬–º³ÚËÅ65öƒs›».~@½>õ̵å]+cªuèD‹8e!¢8á.ÂEi±NsU×–TMSeÎQÝ*£Ä»1‚ZÀC›‡gµÙæúƒ{ÇKÕ8ê©R—FY=àɳºqo¢ EÙ øœ÷î ìÂÖO™ÀàÍŽ:ÀïkµÒ“‰ò:q†U5Lœ¬þn´7Š 'Ï`/'`¢=þ²Ç?÷··pKÛè°$Ä  PM¹ÉÒ‹DüHËêL#Ër·ÈõEfdE£WººHF±ÛèêìpŒ„¤kU©´yËw¡‹´\fÅê\Sórí"¿ÌÔJý¾(^5Ôa±ºHÄâJø}ŽWbE~ª|è+À°hê“Ev¤¸¤ô<MƒV(L&ÖµÂÛ†çæ’ëT‹nNéºÑK<6Ð8iå8¦‘ëxïWý¼õzéÚ.VÍÚÒåÓ WÙ6k Õ‡Æ|†M¡U´OÓw›v¥ŸvEU­ªreRÞ°Ï`2Ù<“ÈÚÑo WºQYþº³BŠa…êwÏGÆø@zh“ Æq·Wô†±™Ý\9„ÑÝdEšï–àk=1a© ˜„¼‹K11^%Žä>p°ëÐØ¥ñHý&Ÿ®Š`£štu,‹ƒú1ؽ¼‚1æDsïXhn³Ÿ¦¸ºÙ?£j…:òîU±˃SPî‡QÓô1Ä8$R¸ß6TaÒ<ÚygEû¼Pµ£î&Â.¦$>èǯõÕFX&{œ>LÈÒwi4BÈ)Ž£¨{mY¶YVÛ}‚žXÎ s}c5ƒM ¶%·3ñÂ6‘ˆDdVÓY'ÄQ Ù~çL{ ¡ÃÖp,eîûpIÒÁ%’I¸„Äq"{põfñ1¼È0q /Ž“c¼»Æ1¼ãý'–Û¡Á S=¥‡`É£·whAÙp‡©„„¥jl5Cp¶eÖÖ=\A·ÇÓXQ^語lœ!ÐãáøU»æð)¯Ë#ísºªO}Àœú¤ë09"²Ä˜SÃÖì“߇ã>óþÀxÄ" endstream endobj 897 0 obj << /Length 1272 /Filter /FlateDecode >> stream xÚ¥W[oÛ6~÷¯²˜Y^D‰ ¶‡vK†Å€uÎSWx´M;dÉ“ä\þ}/’E[• AÀCû\?ž›q° pðÛäÃlòî.âAŠÒ˜ÆÁlŒ‹â ‰1⌳Uð%\”Ï×_gßݱ¤Ça‚z I5Ë;Í·³É$ÈA)eˆD,Xn'_¾â`_~ à«TO†uD” òà¯ÉŸ¾ãÓxNYßs‚Q‘ Á œxžwbmâÉP” ÒÆð¸§”ãPÚãQæ{eäÉSŽ8ᯠǸÍâÀ㘢$vnÿªêe•횬,<÷aø¡‹`JR%N¼POsˆüoÌ1ü“¡·K‹iwVëx£°Î¶Y.+{iJgþªMÐ’ŸOˆRÇ­¶…¬ÕÍÍï}ë=ÇOÝèà_\Sîk>sç®*µlœ‡Ò×”‡æqÌuñ¢O>Ur·ËН!+<Ùz)»ó¬vL•lTùƒ4°¨Q„˜`@”rîÜk,b¡\­Œ-Cîlš*sq(d÷J"¸~_Œ?ˆŠ¤å®(W:ôÇkÂCU[›à¸%t²ëÏWöÚ4䇮J’CœK†hܱ7ªnœõ§e‘ëÃP.þ…7³4$—Á’Љä˃Ë4ááSÖø:ŽÐ¥Y‹…°"Ï.Ðó+ )¬Ìg—fªŽÛv ¼g8]‚Çlº Ò̧ƒ°7§iƒƒ!¬¦)ºŸ·Ïr»ËU}ù| 0Žº¾hf}’vM·îŸ¦öìµ´\5ªj×í¯¶/ðùU¿½Ãò“òô¸¢Ò ÙÞ¤»*õÆt,G¡‘ätäø..ÂVÝÑÖc?{,³•q«r¿ÈÕx`]½rÓX¡>œò-ñ:EßøÑ3!ýRnw²RöÒ”ßwz>ž—¸.NÕùï2ïèLD÷µ²eÂq/«)”^[xÿt³çð} ÏÎ,ŽžBø!ÆSi¨–ÁîÛæ¹íÑm{öªF}¾”ûÛmÝôi·hO‰ë7ÁT蟅‘¤ÃÃ.¥š2 COºÞ/jÕ8.gßü¯ÓÀC¥·Béû> stream xÚµXYoÛF~ׯ`Œ>P€µÙƒ§‘HÚ$hˆã NPPÒJf!‘ IÕÑ¿ïÌ—"e¥@aÜ{çøæ›YQoíQïíäÕÝäù{)I#yw+QJDyqDI(¸w·ôî}N§_ïÞ=„•"åDÄœ£Ö,²Í†ã² 5‡¿¾›|›0hRÏ傈{‹íäþ+õ–0ù΃©4ñÕÒ­0Fâ@@{ã}š|lÏë•ð\t…g”DóbšÄc‚"ŽÊŒ“4aV‘_«©ˆ}™5r:ã!õ3ýÁcÔ)ƒjEiHþˆZÚöÑ€í£HRâü&ëE•ïš¼,%ŽÊ¸þK¼Ká¡·Ü—\‚ qä¯öÅB£z¨P­›Y%u£,lc¥¿Íƒh§Œú¥év²nj©à$^µölóöíÄ»WkêÃv^nò…#¿™+çËEcËh·Dïàvúݫ䮒µ,šžhÙž•Ó0ÔÊ+-ŒïòbíøÓãZwwe]çóÍA÷óæÁ¬®¦,ñ×û-Ü[ƒX¬bU¶q´nÇvv¨u¯•¢PõÅøfýcļqÄ ›qF7ýÂyØ·dH©ÿêð„'¢@݆ôSyƒÚ…B!FK £`ñ)ýÐ h=jm§º¡¿ªÊ­ž˜Ëv'*#—æÌß‹º‘ÙmÅþ¡ÜëkÙèÅÚ—ÐXºh÷DɰSõžŽ';qª-l쟙™[ã…¸Ö•Y£‡óúzÔ1§7ׄ3+gD"‘>é§牿û5Õ~aŒ #y£¿ }ã¾ì“e$JBK_ó¬–77(ãRøg=îsè"LI|äðëËo Ý9wf5¹ôÚ8 1?Þ:ã‚ûe¥“Œ«\9&trL÷üÞ±¤ŠR»]L{ÚªÍCŽ€à1SKu©0P„Ù]V× q3žpGÜ] ¶#¼äFnMH@¥AdSž ³Xö0ìÐÌØ¶¼9²“²€êÕr—U­€» ¤ˆQdÇTÐ%ŽORÚéærSbˆ?ÑÁ ®hË|…ó+à¼b!í¦æQÊbÈa #¿ßÑ×S9¥#áË s…uü9IÇ$ ÚWÅÙˆ‹ ÆiCîÍ(@ /þ±¯ëê“2(›od—Koô³ÜŒfÈT§þëã^Ó´(ë%cÒSÁÑxftpX¼p¹Ú/ÎfHy(²íI™âÿ¢e|y¢§Á2”)”q^owÍa4ÖÛ2BU8•N·Ëÿ`¢¾Ü²­¬w™écÍóø/\h€\_(å߇"^0ð6ˆ ûei@R@j‡™ÏLCÈEŠFÒpèL½)t`E¦nÎW@Yhé#mU&–‘ûlÜýÃåÆßÛÒ:¬*T‘û=o£ªåAmP[}åºôUp˹7ˆHÈÎgó¯øN¥„¥Ñeõ'ëàÖ´‚ká¨Ncºe¦æfC¦?Öë8…^×SgkZ\ªiÊüùtÆü 4d_:u eª 8^hÉIÀƒ/+Jˆâª/,ÚN’5 6(eVðZKDköŸ¬œ »`°Î™á)!´ªãþ~(”àI8 }‹Z$Æna 4 ƒ®+  W®€Ñ¼€×$C‚×9ÉA´U¿,ð …·ÔûÝ®¬áTO9×tÀ±¡Ê/­Ò Y!÷µ²K¡Ã{O‚Ñú³Ï1ᬵM{–NßûýÇàx$—pÇÌU€úÅÁ%M^7¦¢`æË­"ø²ߤfOGUÜun÷S¥xûtéˆt.ÄO}Â#x£¶V5)¨Ú˜¢åÿn´¯¯óŒ×fZ÷]ØÖyA×—¹B„$`ñˆ+®ÐšW}sŽ”{W¿«Oõ_I¸òÅLÜC¨ŒºüææÊ„´YÜÎ(±FæZ)º^ïÿ"2p³‘ðÃNÏðz˥σ„Ш…ÖCV?š|‰Ä™¿,{µYaˆI/ÒT£šŠT>)ôT½ÛäX9à «ÖÃøûõÊ8ÒL‹ž={†)Z"žÍ¸­;pÅíµ~©/éW)â[Zd[²¦ÅÞÓð¢ 'N±k«|n«ýëLûkÕéùP`…TôrΨÓðwá6Aå«§Ÿºmù›Ñ¢Õ/‹f–„`>îB1«Öµx-æ3Rm ¾»ýüÚ@2•;GGbûH[™-]Ü0jš€”ái_ŒQ:¸ðxx7þÍé'Úù þ_í'í endstream endobj 934 0 obj << /Length 1315 /Filter /FlateDecode >> stream xÚ­WmoÛ6þî_¡zf3K‘z °]—†K<ìCR²D9ZeÉ¥¤$Þ¯ß_dɵg‚˜'êx¼{xw|DµC“Ÿ–“·<߉I°ÀYæŽK)á^à„%>gÎ2sîfiR–B~ÕÜ£³Çù§å¯o?ðp°Ê£. #0©Ô™‹*j6Ý` »0Ê âœ^ò[‘‹ù‚ùt–îÒRŒÖì ÷tÁ„θ6ñK¥ È2©ÖZ¤„ªÝ­ýR? nh½Eõ{êSøw„ÆáûОæ.%6ßÔy»ÈÄVŠ4iE¦'“ÊRTÉÆÎ¶õ7\Ï'A̬mD™óÄ#Qï5AÀ0ˆ‰ë ¤=ž7‰,w(r83ן ÙuÕè—u®G‹ˆ¸£õŸ„ûIÈSÔí’µ˜j­zõ·H[c°0»Ö2R‹´ÒË벬çÌôôüƒ1~£ß·»­™¨ê¨*4 A¹$ö}N™´r*ðôÀ(ÌUÊ=xZíLÚÀ‰‰Y£ÅLžôQLhìZ0WI#®®Ð:À©ÔÐCíbÁ}6[ª¨¶®“R{´Ï–À ÎÏüÔ…ñ<ɲBÂ@MƒBZWy‡'g¢í“•ÞêVgëG$bñ±M‰æ 'oL6B¤ º îý…5]´úÍCQeM±~hõã“)Ê{J™µQ˜w…1µêÄuš«±kÌÂM-­$’ ‚Ì»r°Lb~Ô)°ÄYDxd2ûV˜%ïʦ~U4²ÏL‘ï.Ùïú9ÙlK@ñØVßn ±Àë·[hm}7_ø”ÎòJibØ#|(¯„=4­Ä~Ïí6«ºÔr-G¯0¸¾t($B|ÐW¦ùtlìG=¸6ßO®üÚÕ­@ËÃý?Œ¨»Ìƒ¤4 ŠêØ|:@Ú#^äÙbü¾ï³{%Y…÷ø¦Ûn±?ªÝ広΃½ ¡ŠÇ"ëÀóÝꢹ[MkJ¸Gÿ;zfv5šeß`]búÍ›7èN_¼ËiÀ•Î{)’Võ(|R»MRì¼6ó,tfI³»z!»ªÏG¹¹Ô‡µJþFªf¤6Ýì¶_ÖÓ|¿ÞlÛãçœHSpp…7B>Šì—ï¬Ã½ƒÏ÷ÌÉz;r³¿N®—“¯W]KnÏ´x (æNº™Ü}¢N/ÁÂãÈyRªǃ¾zäÒ¹üq²):7¦G๘º²Ætîñà’óF½Óe$Žú;ò£0}__LÈÔ:)ç<œžz¢6·€¶¯eà 9÷üY]!øg 3|*âQïmñ˜6âŸE“ÊbÛâ-z®—2.Wõ€eÞ3æL8wêŒÕíϹ¯PQˆpîí£7‘+ ,|ÙÚ%ÙÙ³¢hi§|<½yÛhñh?(©Ôð1ïh¯WWBëÀ$šeEÄ ¢1o@kŠ7ª»½°\Z {ÄŸ¤ìîbV“1 knÀFÏæ¹}¶p ^ð²µ+Žáuj±Âk¸x‘šNÚÙ²÷TÖÖQòù÷„€?`Ï—³‰Ó;ûÆC®Î\ž¼0kt0vÑà+ã, z'‘ÅÚ¾y¾zŽûlÈWuŽR‡4›þSè÷n³²D}©À˜K¼uÆ> stream xÚ½WÛnã6}÷W؇ÚÀš¡HJ”ŠîCÚ&E‹Eîº}Ù.RY¦²”è²Îþ}‡"%Q·D Š…aˆ¢g†s93<ÆVlaë—͇ÍÕ-å–|—¸Ö!²lŒe®Å]ŒJ¬ÃÉú´%d÷ùðÛÕ-s IÊä;Øid Mï‚bg{Û¸”â¬\Coß*î —›Jýæ)8?¤b¨¹ô¼º%Ôò@ÙeÏ`ˆ®l½Ù팷ïE¥Üv°!Lb¶Ûzý’˜cˆy¬(•­°A%Ô:P¨ÎÂ*É3õVÝ•Z¢ª‹Lë%Uk . ‘i‘}IŠ<;wAv’Ž@J\äC0‚ñÁô† Ï¢˜Øù¾ÑÇCÝH;÷Ã~èòߨÁðµÕnš”•ܸønàöœÔ*½úñÎÜ2e›C´cÄF>TÊ êp/Öd')Û,©g%µÖO"¬û2˜º3 ycVó¤^.÷"›Á‰ËaºÿYÀ m¢>©S[6ÒçlÉo.Yë'kÃ\U Ý Ê÷KíÙ4Äi~ ÒÎZEÔ¥0P=Mö^ê!:ê!Ht¡í^ÌPN3'x¹þ7ËþÀÒH‚91ê'ó˜Pÿ¯cò3cŒÚˆzä[b³ó<ˆƒD÷Ú±®Z”t¨KÎm…ØÍf¦U{ÏGò•`ÂxͼZU…ßóKßëÛ&HËü5Ã=3m]zÌæì Žúo0›Ž_ÕóƒŽ<×þçuaDÙÔ~Çmrfo„ØLÝææ°yÜØ ƒ-»»ùì!òáyóé3¶Nð#˜AÚñÒˆž-fÛˆ3 šÔú¸ùcñžnè`É àŒËl‹ùòé¨Ã„6°1™ã{v‹Ã›§ ¸†³ B¨ q ^ÅŽòm\Ëj”j+*vÌÙæg- mKÍϸ‡œû‚WÊáPŒúÈsuæeX$ zæ8Θ‡I~$ GûxÍX%Íƺç˜}IÔ"k²ôgÄb=ëZö°«bÃ%àeС:Ô ÞeÁYLÄÖh¹†àqüsޝpxLTÍpàbý”ýI™Ø£˜æ¹YÉæ4~x¬ó².´°¢‡ru)‚‡rbÍEî³ÆA¹þÚù¦T-^¢ku LûI-%÷ÓÞG3ØBkô>‰t”á×0}•c¿Bnm¸sd±ZbãmwõºŽ,KwI…u„øPÃõ:2¡¹ö."ÜŸXí!º`Ûs‘ÃŽ¹5 Gº0©f’Ëwyª QèôËÚ3®˜AxüÇêÙ÷”V¨¤+p:Î ‘zœO¬¿)ƒ,’ž%í)´áG!Z Ep•Á@n Ðl•Bÿ?’/I;õàƒ<«ˆ­vùaÚ¨0?±ÃLÉàÞZ@åˆvÀˆÚv<çmǼ®Ú~Lt†÷Pk1 t"¡Æéí]Ä×’*ÌŸ51Ž: Êî¢sZ® “A˜„Žà¼òÔAíõ™ÓÊ/NT¸3ÿfÝÿì endstream endobj 852 0 obj << /Type /ObjStm /N 100 /First 877 /Length 1813 /Filter /FlateDecode >> stream xÚíYKo7¾ëWð˜\(¾f8ò€Û-89´uríucT–I’ßoV²ë—"¦^Z@¹³£áGΛ+…\pRØa"‘œ—ÕÅŒ§R]{).¥âôÄꄪ˕1fGt*Ž9„LøIFNï9ºðgᄉdL²‹1 &“ ±‹)ÅOÄäb1±ŒW°O#Eðh ’2Jv)¬P&À#Õ(j”âR,F!LÄ(Œíä2’Z1©FÁ³í)Û±íTlo1!£@2£@2£@2Ùþ’Ùö'ÌÉÉ5ÙŽ!¹‚(^™0ÑèrÀD“ËØ&Ùå É„å‚CL´:( SI (&RG5ƒ…s‚–l‚ h€¼šŒ’L+F<‰F)˜à¼D :£FÈ ÉPàÌ" (­äÌ#…âJÁ&5FW81& p޳+Ú$ˆ€Œ¢x(Oq¦Ân0%W)°aF¹hÕDa=Í 00)ìŽ*ÌGñO²½iŽŽL’ðw†²A!ÇP&Œ‰Ä‘æêpFL*þ –b6 ep1ó4¦J<"£@©Q2¬¶ØR °aÇk–Èð¶÷ ÔëP¸@5ó$l¢š…(%W NF¡°Z¯ÔU F(˜à 8•Ô(ì*gííÆ¯Ý¡`ÕàÜø—_ƒCŸÍýªx¡›]L§GÏŸ›9OjcN%y‚© Ï ½xœo)Þ¢Ê æýùlåööÜxº,pªþoû¦wÉúê†anpü…Â%ôOk6È¿]Ìßu+wèÆo_ï»ñûîËÊ]-õþëç/&¿w£ñ+,ÛÍVK„^ðh|Ð-ç‹ãnÙG¢žôswr6y9ÿâm=˜ŒOôJô¢±Úd®*­Ù_ÌfsH<ìâA²°¸{ŽÛHzþÑøÝÅѪþélöÇhür¾8éýŠáãøÇñ›ñ«ÃØ?Æcl.–êͨà&ž-ÊåÀB4ÅïE¢ïÜø‡ùû¹ƒBžœÎüÑdÙ={6Yúå×ó£ùôÓOŸÚ± *QöãTNêºj5›œwÃBBZñ07VÏ–Jæ‡#ybÝŠX.¦=žëX̪‘ö®¬Zµ7j„G_äo¹Î{é@‰Ú˜YØGiäMÕKnœÍ€S#ä$¶¿´ÍioúéuÞî´dµ>Èik¸ã´,tZ^;©ë±ê´¤ðT1xË÷)2ŒÅFŠ>×¼ÕÏÖÖ8YÍÏÏŽ÷˜à Úy>¡Xˆ™=…¸-âN&ËOþó}ÄW)ÛÓÓìS·8[m’Ôt:ž Ž5:88HAWÑ>´'!ÐŽÃY®Ç«‹Å’ÒlZ¹=ø_çý+žgŒé˜­æ£ûºº˜Ê·…&f«øí6¤‰¹hñ­‡‘Q HŠß_z6…™!êPwšGüИ³ní^¦cØŒq3¦Í˜7c2&åhYÃbb ["ò™k“TtWºn-­TÑXºˆKÁJUòŠZjÜ$gËË*ð¤;½Xv¶º9!VØ}•ú-$Øt¢u?ŽºzGdB©:të­Õt-—xÐNøZ¥ÚÝá!E„U$ß’$’ݨ℠|­xÜnD'_g—:ƒ3 ˜K;Ô®]‘Û”í²ÕF»Z>o—QÛùLަÝçƒÐ†¤EІvèÇpn‰d+ éÙr•n¥3»ÒmMg7x¯g(¢ôÌ\ÑÇenc&¸i#s´T¡•9À ³ü»êUÍåNîÈéa¹ÃnÑûœ79#ÇAëÕÀ¾”ÑÛ¥|BëÑ3°"2ïˆ3¶ÔüôQnøbDó’Ì›9 c²Šd{j0î½kŸ.n]ó pBö!kƒÈnÏ"ËnD Séý̬sn÷ñë¼»nïe†™û$ÚÈÄ“´ñŒ}Àœ9yó¨6fÔ2Ô*91êwj<æ¨ñn¤ÙÊ „¤tµ:ÄÇ¥x'F­Q< F•5$û²¶eØúUú¡6†]Zý*0üˆ–†øÛ1!=^dÚ|{ØðëCÀùtÐ[ÕØ7hWA UO²ñí`®¾ˆÜ¾HU í‰Âw¦û˜ÑÀ¢¬ÔG`.l·0 Ù”ÒÆœQW¾Æü'-úã7 endstream endobj 968 0 obj << /Length 1207 /Filter /FlateDecode >> stream xÚ­WÛnã6}÷Wè‹ Ä IÝÛ‡m›-‚]´ñ¢ÙÀ eÚQW–¼¤gÿ¾Ã›,Ù’“Eàˆ¤†Ã3—3Caoëaï×ÉO‹Éõmz)J#y‹G0F~yq„QèSo±ö¦+Šå¦œ=.~¿¾õãŽx€ ŠХ娯D&ØjÙ¨#;·Âs«5³åæ…íö—½cÏë[ê{ lŽt‘T¦G˜³yˆñôýÜ<¿5UÍ¿àoÔ?veVW0!ê§ÅsJP Ê´’ŒÌ}³’¼®órkæÌ<ŽG^7¢”fR?q+&¶ÍŽ—µ]Ϫò™‹š¯­XÕSV°rÛ°-w0Fi˜ö`T«¿yV¿’PPæäñ‚ŸÊxŒ„>±r}u4j È¥r’ö˹…Ì­m›‚YE.kw³£\^²fSs ‰3™;(Î-‡J|µ£¼~4ZÖBì!V“ÁˆÆ½Ãÿzâååh1a×›²d;îÜcM†@TÂb­ØíëïfÈ Yä¼ ›ý¾È]N( ;Æ\ia~ü|w§l¾öÀRAíùASéf1ù6!° {¤%uRDƒÀËv“‡Gì­á%(F~šx-ºó |ÞýäQ*êÊlìT€Ä ýQß?«qoEiB\ ¹y©ÅŒ„S–AFÑO7M™ÕyUÚ™˜á´Ú™3ÍÊq«©0úVkëzÅË) RPFƒõ.3‘ï5º¡úuR,u½J ^…fûo›£A ¦A$ÍŠÊ3mm%vÀ·+# óöÜ%‡\Õ$%°²ï¹"ç3NŸ•+Uªßi¿u51)«,gµŠ깨JE 4›û8~RéyÈ%¿2Ryݦ$ð,ŒŒ9ôúmQU_g·Ç6{»ËâmWaÓÖ€ë‘m1½¶¡ÜF#”Ø”ú,mÉ|[»w¿ÍMGËv^>›ÁÇâÈÅ–]ut{硜à Ì%¼c8£N[;é«Ý´Š#àuüù™Y7»dèr¤—\öôHÙîbÃ,í‚íå™t¤|n‘ÌI„ÀGòç›Á/tj$ñiªÅhz€,´ïUËPK_0¦åÚ®¹Ík®—sKSõº'Òa¼Ö׫%·×œže „(ML‘[(… µ…Ì(ò bXª´©'ùÀ1$EäÔ«§¤r¤+«NÜöŽzŽrýP³Ì¡J½¾Ë7Žªß³‚ÿ§ü(™ uÙ1CŒ(ÂWæG`Ù1ÔKÏãz—Ïi”ƒ¢“æŒ5ß ž™º¦æ¬´Áuk7È¢ ø>ò éFá8¬… %®§Ó{ÎÍø0SUX{P/InsOMr×:à%žØznøç9Áh’"Bƒ~ÝUißXl ÂÇìÚ¸2°«ùÙªjjW\bepÙ§L*}Ý„ÑV«] YÔ¼7Ø9X©UÜÆ¬¼T‡ÿÏ/ {ƒSw}?QÓU;EWM\÷¿¿™´j?Rv ÚöK·Ít¯´ã»_ß;ðmг¡½·-Y[æŠä‚š»»¿ûÖrÒýˆ“&»Ômþ´“) µ{Â=ïcÀ²Ô endstream endobj 985 0 obj << /Length 1630 /Filter /FlateDecode >> stream xÚ½XmÔ6þ~¿": iOº˜8ïA-m‚(jËñ ò%ÞÝp›dqŽí¯ïŒÇÉŹp]J©NwvÆöx^ŸŸçlÏyzòÓÅÉý'Aâd,‹ýعX;ÜóXÆN{, |ç¢pÞ¬üðìÝÅóûOÂh²3ˆe!ðÑ{r±Û½¯š¢\pó‰g®x|qòñ„ÃÔsø w?e¾Ÿ8yuòæç°øÜ¥,u®õÖÊ 9gIÀ|ç¼:ùcä7µ ~0U{,¹“‡€O¤+ëv/óΔ²Ôç>ËR>(õÌœpýÈ[ •f±¨YœeŒsþ5š‘â'ÄIÈx‘,¿È6Wå¾+›ÚÒàFÛ‘©ãò”Å)¾Ø–-È$«u_çš |ūڷrÝn?öe~E´N¶]Yoˆ.ꂨ…¼<ó½U¿ÙŒk×[iXšžH•¨Ë}¿¤yÆ£Õç½’m r´3žhß–¡Š – ¶Ê"cgèˆ$]íd‡‡’Ì\¤|+µ¤0í¶¢£UA„‰ÂðUš£x,ˆv]vÛá°¤eUn¶æ:¡ÎxºÚô•¬;Ì ²h0'Þ,j:q)‰0Z/3k}]fhÇÖR.&åÈè_¥¨s‰7qoõ²Ñfƒ£˜žéÛq³?ô­¥mYíwæàµû½4ì…jz05Eü°ÔQg˜þùtžM~±$ †Œ¸­|ð ]¾eh·^äÁ/Ÿ%•ŠiÆâx FXb¼„ £Äõ^½óu+6r1ÖoǾvìO“åeŒ "ÏåÀ“ZrÀ÷Þàû;Eù‚If´fì.%1ÀŽ?˜èÑ4âŒË‹²ÝïÄa•!Œ§•ìzUë°6Hµhí,Ô·Yš>þ,0bÚãíCt•Q6{‡Ë_7 —B¡ÝÏÏÜÈóV§§4Þ{x&eê–Ýa©1¬6L}@Õèû–0ŽX¤wW¸»KÈotÀö@ @žåàfýU&ŒæÙSeB(ÆïS•ÂühÁ3€'BIš\c"5êJ MР«÷ÐÀ©°š¸m¿ßïJŒb$£% d|χBr…\ Ƕxk»ÒmVâX ªBA œµGaae·Ú ËcpÐ5,,Ü¿”€ü&,(¸¨”NÃ勉<ÂÕ÷@L’Óõ 7vAfä›…R pw¾T娶©šúPµ”ò?Òã%§WRîOpX—ªíƯ˜|H¥uJH²tõÄ+Ö-/_¿x±|BÖŸly°7PïáIÎ{rðqµïtdV脤$æÏÚF@ KE7ÿ"`FX;:l~mÎüª"´¾ ©Š£’Øããt®¨bê}Ú?0iu:á  {'†VÈ5¢ŽèwÝ9”ÝÚCÓíóhˆØ€™å–Œ¥éèK¸ á–ÅèAY0pü,¼¶qØRq¼z%»ÉÒ˜yÞ–ug²… ‹¼iÈÜf½\èßhI•eU¬Â`}(tSï°{‹³õrOt‚ ¿õ<_é×îÎó^) Ï·öÜ„[ÊY˜ÞJ¹E1ãñvªxKBBðÆ©%dj‰–¸ dB3K.×Ï2óÞÆÝ‹Â„ðDðÇ7›©¹ËFKÂl.ºøâT Ë+ŒèJ {“Ê5>8;™uEú>Ó×ÅðÚ)Ê\ ¯áëñ5,n¿–¶É0ô»©‡–Of/Lth¤ÓÛ½Å91ÒÍÃ?g½‹¯‚Èü7êU³îÜBB M$³‡€Ú‰¡„>yæÿ¿ï¤håì‘p&§Á7u°™Ïx4¦R%ê˜ÎâhÅ{x¼ü  endstream endobj 1001 0 obj << /Length 1096 /Filter /FlateDecode >> stream xÚµV[oÛ6~ϯP²‡Ù@Ä’Ô}Ø2 V¤{HÜî¡2F¦caºxºÔö~}/’E[²Ý¦CˆRÈÃïrÎ!±õbaë·‹_goî\ÏŠPäSßš-,‚1r\ß |Œ<‡Z³¹õq³4}ÊŠy²ØNÿš½}sç½%.&(!žœK=1åë`®ß›këÉ6 Ä7µäÃ4¢–6ÜXÙ‹ÐßÀb¢Ð Ô⛩M=<ù·)ª¦äê%Y(˜Ôé-ô(¢‘ÛÂD‚ÓÀåDA;+©T@flrm|”䨨—¼\'G:°Á< Éc þ>YhÈñ6N‡ùèàÆ))|íÝßúh{OfK> õ!éô¨j–ÏY9ø²ø žï·“Y9%áä¥Éx^kŵPs¾*yÌj>×éïÅB=Ë”å/jy†02ñÚaˆ-â§õ{(ébR 1)Â×d}9ŽÓâ t>†_2ÄÙ‡a—0ë)Ñt`Kƒ&ì Òi,ˆT3 »‚ø}È´v4C¡”ºU‹¢TgE[¥ì¹htúÔË6â%x3\@r:®YA·–­R^-@àBD°µm% ¡ :fS™Z?Ûê _sÁ5ã,Ï͵úGÎP™©á/ê1{x+iU m ê ô5íê¢rÌrõ䛤ª‘Ãòk© K!Býh0]Äë( »›ûÇÛ>šómŒ ÛAn¡ÁígÅgnrû^lþc«6çN ¸™ÏõÖ:_¿J]&&ŒNy¼CмJ“8©Õ[–TÕÛ?½V ª<6«Uº5„I!ëÔHtçA©*õºNꥪH÷ë'€‡¸.ñ¿»n·›â"7ìÚîåååP¹nt,r¡<» q,À¬Ì‚œ„T‡úüñþþþLK÷-0·7øiPG£W@Y“Ö t¶ACžµ“•Ì«6— FªÁ<”ªä«'yXIâÏ•TíJ³¹2] &צ¶{¥xÀ5ü¿•s( ƒñ¶Z·×#Í> stream xÚµVÛŽÛ6}÷WhÓXsER× }Ø´Ù"Å¢@§@‘ Z¦l¡’¨ˆr7î×wx“%[v“ …ap(rfΜé{[Ï÷~œ½ZÍîhì¥(Hä­rû>¢AäÅ‘BJ¼ÕÆ{?'ÑâÃê§»‡ 줱â4;zOÆÊò©fW[g¾up÷@¨—€N(% ‰VZ’X2ªß,–¡ïÏ{#d¬6+¥0R%6E~0òǽû–K3+ê¦d©Ü‚Ë%öQ¦Æpn¶|»ìÿðC¿b][|RÒšµ0`õŸR×!Ïjw~Û›é¸þ Ä©:%(‰ãQX¯,ì ÏÙ¾ì¬Ön÷¯;ÅsÑíŒÔí¸¤âRKu/±Ö ò¦CF\í kdÇäT‡Ü¯»ÒªUSë QK (­#Tv¬ÎìÎÃYR*ñ—CSc±ˆ+ J&í¶FÈBù7³µ%©å`¾¨·JçmúeÖ4ƒõ——òv–ùaÊTâÍÂwf°¬Ùß“õLÖƒšöŠc{?¿{|¼°TRBO@š2rê`”âä³ÏE¶Bòžx[¼1’¨ËÃIUåEë2à~ÌÉNT¢>TWò×—í$ñ°*ÄC+ã…ì¦ÿz†®œÐAFnnn;C629rôB“ñâ2®hímÏ^¯fg\øî›lˆCDâeÕìýßÛÀ" @4M¼g½µòŒQPKïíì—¾±žŽº“C¯trˆ% °¤1Â$½Þ¥ƒÑ€ Jì:ûëO]»ÀáœeP&$„Ú×™9ºjfº“’TA¹/²¦¼±ßs323èãy‘“ PJ¿„s‰E—X¿~`ÂøË¬- |ü‘„ñE˜èÃHpzdá¿fàöRù¤nÐø|'Ù–O‚=?νŸœ¤Ýò¨åPh9x¸Qžnû7 ÷P þÜÝh×_:lÝãÒe%Ž 2‰«Ìï™ÍÀšŸó;Jˆ]°O3év̦ó¹e<³€¦"O `ýo‹”@OÞó/ª+›š{ãP›D]kŽ~ ˆüRÁÝöj”cVxe%£IõZË !(À¡ÛTäW]ŽŸ¾@38Tb/ÑtmP„ÓtLÑc‘[³Ù!+ù×À7 æmÉ4Q”Î}D;A@˜ â÷ L)ôÕ?(é¡·P5É^ãY•3“Æá†7-ÏxÎ:}žá“~h0\ÙÝ8æåsš ¡Ÿ½’¯A à‰Üç^yÔço97NJ`2ÓP> stream xÚ¥WKoã6¾ûWh23$õÐCÚn[ ´ñö’ Z¦mz8”'=ô·wø’%Gvœ-‚„9C~óú†ÁÎÚÁÎçɯóÉå8 JB:ó•C0Fž:QˆQàQg¾tîÝ”åùcݰrÉÄ2«ùôaþÇåõô|LPáJFRd‚Í5 ödgFxF#¹¦U>½°b›óz xl¼¼¡žƒrè+ÐpIP£:ë§é,ÀŽlKýÑl¸ž¬Ú2m²ªÔ_%+캨 ={j«†/õ\š^_IPpñŒ`”qÏ)Rý;°R‘“UUÉaÁ Äþô“qý÷µ)Aɉ_A¿Þ²tWO™0†¥•yš8;¤£+?!ˆ‚sÓbrÿ€%lÂ%ÈKbg§D Ç'@:¾óܹ›üy”['½ô8 †>qüÈC0ÙQNìñ“  (‰‰eÇ;­5õ"WiÎh Â,æãf†yчÌTæ è·;Œ@ñÆô;¯S‘m1Ž1ðÝKÆ¥Ð!ˆ§Õç› bLiìê1ry]ó²ÉÀœW½ÁŸÚlJ÷Yþa9lêõ¦2бvìô¯Ïo"ACPëÇŽŸÒ ’~ë2ï ÷ôÇ CÏž™K=ê.¦»­Á£ËK!ž’À}Ùr‘€–åÚ0ÅŸY¹Ö2²J帡¬1‚šÊYH!"±Ù˜Ô騙F:hŽÒµA±g\û­fk~~W<£ÃŒ•î’k¦|yù¬'¿ìË™‹GXî—áIľ¾èZL v×­ôÚé~~âSÁŒB(«.~c¥®¡ÅHI©Y%@5u+Œp³ažíÛÖoN@@ÀgÉŒD(6/ýy6ö¹|ÐʦœúØ}ÎDUºDâÐÝm¸0ûP-jé;ÆTvVµf•—\-gúy#ÅTzöEö¯¹m_:r'+ul†¢4±0m@l¡žs½éƒ %p‚0¦~Êìëqx¨JÈ©woñI'”™©~döUÆÀGVŽEz¼Þ¼aHÝAÑý=M(TË„ ¯GÒ+[˜PDÿ‡Ìv1XL2ÐîMöCˆþ¨ˆ!:á6[ôékšÌ† ¾È8$±+r¦¦Q„/F¼ÿqÈn • ‡lÕ# þ¥=ô:7î$ù°Z_¶ä[xû2äð­^£ —ïó¡[Л^“ ˜’òL<ªÇtxÐtæ¾{ÇMKð"èá¾­ Ó~spu*£¦­|^s[¨:ŸÏn’Q„‚$îã¦çtF(ƒ} ®,U•Í`¶¨ÚÆr¥MúᚣÑÔ€ÌGѨï endstream endobj 1033 0 obj << /Length 1634 /Filter /FlateDecode >> stream xÚµXKÛ6¾ûW9É@Ìð!êQ ‡¤Ý Òm7½$A Ë´­B–\J޳ÿ¾3J–µÊf´‡µørÞ3—»€¿,^Ü.ž½TI±,–qp» çLEqÄœi%ƒÛMð.”éòÃíëg/#=¢T:e±Tp£)êÍǃiÛ|gxÁ=‹›ÛÅ? CˆËíR±4Iƒâ°x÷Ø|ÀV–gGz"!XáõUðçâ÷á¾éשbŒTœÅ‘³$M¼xyWì?‚WÂJWÊ É²Tô*ýg–B‡ûåJjæô)šzSveS»›fÕ‹3ÍRùMê‘'âOÄqÄ2‘’H?›¶°åq`?µÆÔ›i°ãBÐñÛ}Ù‚qÒW9¥àÓòª¢³ÍGcý¶mNd³©‘eÌ"õ¦êìZkÿžk‚N\É¢%‹T:Øç±(òcw²ÆË•×hñ;¿5˜Úíµå®1͆vÏû²2´c–R‡Ÿð'¯NyWÖ;tOR–Æ‚e:&Öe¼”H@¹¥HÃÝé`êŽ-WZˆðUG[¥'9µf{ªh¼m, Ú²C&Mí‰Î{c ïš ªñùh aîÂJùžsYÐ|¤!N»¥®MÏÌ+ýæ*rR nÜ+¥I©Y/%O»(ÿÔl½¡“§ºìhÔ™Í·Â¨‘ ‹REw¿½—Ô_úNƒd~Cb˜˜ÏG ‚j)Uåm‹€“éód0Í“Q@ÍËÑõÏÁŸÜû³}Pޯȉ¢MêÄU('1” Ù‡ò PCá£0EÓ6ôEâwœÆ;å\v“‚ÖÁД7݃3+ÈJ­C6íJ••—m%b&ÓÌÛÝÛ÷Ñ*=¦YûÜæEçŠL?aLCD7~Þl=ÙHÔ bº‚(öʳ’¡~gQ”†/îhmc¶è³üTuß<%*:‡T”z«¹Àwy8ÆYD–‡ò_ËL¢Ì÷TÏ糞)·}¶õ• ë´ji2Já™Bª(“ô–ÿíí›73ÅSBñqOÔtPqÎekæÓ7‰˜JÔunÜ|ÎÇÊ´OãnŒ£Á)ØAϤ±ê½ó e²²|ÝØOÀN.Áµu¹ý¨ Ȉî†ÃÝÇKqð%¤‡W%$÷å媒ôÜæ[·Ò€L¸ú‘‰R€L„z8=ŒM^œÊj3Õk—‘ûZïît|-ÚÉfÇÜúB9o 1-¢ÿÆÈL±˜«Ç˜‡ûÈÅdŽ8a2¤Ãº2í=£]l7ª7R··Æ/îLmlY´?\ ¬ f’ ›¸WzÌü^JýP¡NY§cð¼7ùÆØ±>_ªK+:{U⿙ݺÙÜ}3³ô;™m›¦»ÖmÊE rÉ„ªG«ˆ>î°gàªnßlh“`Y‚ŽòäÞ§HHF¥ekg:Ìæ‰ïc)4‹•îE¥åD^•2­‡v‰€ÎT^ìŠÈzgŒñpý7ôPèƒ1Ý’ ·Ž˜€ÇÊÔõVÒëÝÒ„‡qR"DŸÒ’ƒ~DÔ¸þc2ÍáØyÚQ—Çé¥Ë·Šp¼òg\øç6j=#Ë\s†N޹¸•rAÑÒB»oN®„)5H†ë9-±¬Ž°‡ƒ@€" Ü5•!ÐçŽæÖ/Ía]ÖÆ3)k‡D.,Z[•'m;KÐ Ö2›ÑÆã´Úºs7ûþn æƒh÷ÊOàØcË¿à÷^ç§®9Àã£@XC!nôo"Œ€;ú··€.®ø¶C`þúUa20C<¼õé=ll•“Ñ%]ë£Â_Ua}„=‘$LIymÖÂBÅJGƒíØ_8K» úá÷ ^-/%¾Ç_«i½*» ©-‰ÌkÓ‹‘‚ßA†M}9‰xˆIò>ã`Ë%£Ž. ã„;e ¦»”þý[GÛ`D*7Ưäd"´4¼«¯,T5øjK4!nøBÁQôÂ,×eUb&Ë$ö~ý} ‰já5áÚÝè`ßî`èƒoÅT^Ž–uÛåuahæÞ³ŽÚ'«£ôYz‰\íAÞd‰1/×bž3ùô…†›àÄÙÝAn”Õ#kÿê‡!YÐkËÍðt"™ðÑä«ÿä1ìtï!5ú‡Õ¿ÚâáÉ endstream endobj 1056 0 obj << /Length 1726 /Filter /FlateDecode >> stream xÚ­XÝ“›6÷_ÁÜž©‚{K§I¦}h§Íõ)Ét0Èg à\¯}wµ ‚/¾4ã#­¾öã§ß.Þ½xoV?Þ­^¼–‘—²4æ±w·ó `BÆžŠ îÝÞ;?¯‹¿ºò¾Îªõ‡»_^¼ÊY!ƒ©¶3SyŠSV=æÆÎܼá e´äÏ.»×“U—ž/^sáê …)‹Âð¬æAw¸Ýû   w†Õ.XêLÜë¬Ð­÷ÃzÏûb…³dÛ__pž¿kšþ‰#æ¾AsxÂRA;¼l×aàߟºî»'Ýóu·ÌcâÆOÅ,Mø¿—ë ?oê¢ì˦¦n³ý[ç=›m39uc÷Ù„1KˆvkŸq4œŒ›sY×é‚Ú}Cσî÷Mѱ%¦’tpÜøÛgt£nÛ²(ë{Z4Q\B3•pã<jÁáÓcEh¶ ¯Ó>¯þ9ê¶DS/M0õÓÛ¬‚Ù`¶PÜï÷ÃГ7PÜìè™Õ4 F5-‰,ì©S裮‹Ž&5õlÏ®Ïz=Ýð±9µöÀ½Î?¢ŸŒ¼mN}Yk¶ÞÄJù?×ÎC°7²ª÷û¬‡À¨ÈϳNÊyÂýr!€Tìo5 ú¶Ì?®ÃÈ´ý†Æ«ìß²²²{]ëÖèˆ=k$N²Fv4ðPöû…pòH1ÅOÅsN`)B nÁô8D—Ð1ûlÍÿ3ê<ذפO¾oÊÜ0@ P,ŠÓ©o¶ºÐ] ÀÙ¸íÓvG—»Gãh.„ ÎÌa^úIº/Á#m+0Æ›YM­I4N>@d&Öû•µúX•yÖ‡“=0Ò?õfãØ:qD…冾m*ê¼Ѭ9„ƒú¨XiY7þ2@!Ü9çúEœ‰@ èþ&Üë_É|¤¨Ýxh7ˆŽÈ`–J²ÖJËBg£¨…‰dLíe”# .0x=úÛ´µËŽž]|lŽj`/[²˜‡,£Åhí‚•š,Ö‘œè5ñu¶ýî‘:D¥É„>•Oœœi49ç ¸TMkr츇(.’…9´¦±‡}™ïíôaÚ¸; £¢«yªtúNy¯ * ^Ý­>­Bºp¬<ÜIi4?¬Þ}¼a'&ÒÄ{0Sž ‘B0ˆ•÷võûÅÂÈ”·S¼„‹eè‰X™Ê['ËK5YÊ¡¸‡¿¥Ä-OMOE,ža¨1hR{Œ›q É¡œøIwy[g]¨_ÔRÁH«ïö–)1LɵsŒ« 3Á¡|ò…ÍFSfžùévÊ¡`6À–±²–¼‡û6#SFŽVNÙ"fe•¬´!ÏØ/w$¦N˜Ì²z7®·‹wmsXª*xÌd:Þî{ðÍÁH–îL$‚9kûúөļùÿ² ª<«f3ZaI—Çœ%1ŸÞ%´pÌÈC)tÉg¶D€5⸬‘¿Ëݹa€09®ƒû~õ‰péT2’ôêÄÛ[çEík+ Ç¡8@ YœÌRøS°ÒrTkó¤ˆ((0àBÅ;t@àBät w:KÏþ¾y ƒ¯ƒN,è8Z.BGP1m­p #ÓóÝ ƒ–\?Jœ¿<83ÜX÷ýÜÀ˧âêJÜ ½¥ñ˜çR ŠÈ`!ƒÃDv p“.!ƒƒ— JÆÏ/Æ7æØ%ÀLœ:€‘R Å *ÓÑ¡K€Áq“îÓh°Á¾l$dÉDLçyHáãçš=Û6mT -Çß )]߯93J™RÑEœˆ˜E©š¾¯?…!1ÊðêÐžŽ½ívôtéEZz‘+ØpéEºXò2½ÁâHX^ÂK7"•.Á@ô-Á8z.Œ4CøP°åˆ¾Ybü„¢ÎIÉqUüfFÑ›ŠH˜‚ª&äð¥Q?QÊØèÔóX]¥Ðä}uønUh°éPï«ýå*k^N.~êJ e?u…ßëKê¼ ž}¼tš‡ÓnWeÛJ_üJEï¡   endstream endobj 963 0 obj << /Type /ObjStm /N 100 /First 924 /Length 1865 /Filter /FlateDecode >> stream xÚÍZKoG¾óWô1¹4»^ýŒy@» }Ø]ÅZ¢aeÒ )$Ù_¿_5ɬ’ÒÈm|°»føuwu½«GÍJH¡Y jZhxÊ)àQ[ êÏ%HòQƒŠ ´±†’€Ë-m“VR(MC–P+ µ*FýYðOû?Jä/ Dö79¥Š•œ0à08'¬Y)9Ìø® Q!Çس ‚µÚÀ&ߺfU8gf,\pj ,T&ŽgÉ` 'fM0ÅÇæ/8°©CDõ78 Þ`mÎ¥€†‹³aå–ê¯òÂ~×Ö×ÛÚÌìý° j°¤†õa– pP8"‰ŸX|uŽ`d&ØÀ|fø+Ø›Á !x³æ\H·B_B2¨.e¬cEf·™{° ¾2”%¦¤µ.Å­óurê|ãÐ9u¹(쇺\¿’ú Ã:l¾Íêž’ð_ÆŸ_‹{M8×Úß8I×–V˜VîûÂa` ¾\FÕ÷5 źDÜ‹¤É‹“é·á¢“Ây˜þãŸÿrmE,¨E÷µÅíÍÍëÉ—_Þ æl±ÈP0QÄ!†I-fDÀgËÅ&¼x¦gP‡â¬}Ú„cúö*ócoX`b»ÕÏ@äVösJȶƒÅ§?®–—/ç›p¦?~{¦¯æ¿mÂû¾úýý?Ì~žO¦ß€‡ùb³FHé»L¦çóõòvu9_÷(Ó_ý0¿ºž}½ü-\øæ°ªÈˆDU)Öö»ÍVXѶð¯‹%V¼èÐYò@èãŸ8è¸Éôåí›MþþzñïÉôëåêj¾ê;¥×Ó¿O¿›~sAýÁy»Ä¡ˆJ„Qså(ðl8gdŒÜcì«.Õ—aú·å«e€R>;»ˆ—³›þÜå3*R¢3Q4ºw²–¨‰ïe"žßÞÄÅìÝü.3n9¹üÏrZë† G<°²»Ø½•ÁC¢ÇöA`3Ž]ÏN=× +&H ÃÀ‰bAd®‘2 sIѲ̌ó;åÌúï]Ï>íÌ#øoµÿ…¤žæ¿eˬ×}¬i7Ònä1ýZL"y2âa‡ØÝP'ÁÌNúÔ›ÙzþÅïf›Ë_ºýôÙOŸççZr즇Ák§ «ò:ÁÝ¿ÉÃŽ¾ÞÌW³ÕÕõz>bðAx@rçf3Q ET`ÈI-"ËŸdêê÷E<¿š­‰WÐðxìp«‘=Ÿ·ÉË/6h…c*1U:ÉÏfïÇcÅ_,Ù‹…WFÕ–¡1Ôg¨&]8­)U‡Gæ»Ø?"³›4*½ñÁ¹Bä6 ›­m õa4£`n‘Ó@–‰ÛŽÕdOkBh«ÃÀè b F[’Çp§ÂüÙà#c>˜£ƒ ßÚc‚>–ÈŽú­ŽZ­U脽ÛÍ1÷ºÙcŒ‰ÿž ~P­A3½‰ê‡‚*‘Ž£3âZF[>º h³.¸Sä´ÐôVöiFÒ;pg«7àã÷”5fïòvÅ=C°ÿsqO”¢7ÞÎ ù- £JTz8•¼]˜.=ÆtéˆyA•ž­È©Ö¡h+Ȩm(:qôv~ZXŽVíÇÑŒj,å¡|Ãb;Ò²G{ÏÞØ>µÏrèÎLOvgj;wæ4¦;³J¬è½s«P”ÌÒ¯¼ ŠRø/ªé©¡ƒóÛ$©ˆØÙo:£ß’j‹ù±)‰ù~}üpJ:†ÖF¨jóó ¥DmÁ‚CÒÑqÈY•¢zÉy('„aãÓêÇ)ÉG•§;ªŒêŸT ¿G“dÈäÞ±ùwØ$\ô¤+ÌÞ,W›WǸ‚sTP©<:£¯E†¢½Ý?šXŽ¡ÍÐŽ^[+Ô-6ÝcÔ@° \JIžŠÂ¿d|è„$bõSËÌ–ÞôɯºËÌ9íµ=‘÷ľß¡:Ù¶Ÿe´'F½µÓR£ö¢9Õ?‘ ”´ Ùb­õtYo+åÛÅåæz¹½vWTþùŒ |©¡Ýþ ø©¨*¡5çèùË‹ ­Z>}Yw½x»\½ñ’NQr!©îùðOcŠªç!>v¥Ø|½†Á\‡íE#ÞP@$LÑP‰²ÖHvš¥_g«ı¢Ýs!~8€‹­`œ—ëÅÏ#  E ÷ Þ†˜à«"Û ^©yx^~¢dP d4{68cûö [Á¬7Ë÷ãJ…ÑDpF^Zô¿l`C÷gþG )f*÷xÒf¾ZݾQ2„>FüÏœX0ÕÉG4¤Mïùþ·¸êaÆwÛsó_â0L endstream endobj 1075 0 obj << /Length 1624 /Filter /FlateDecode >> stream xÚ¥X[oÛ6~÷¯²¨X^DJ¶‡vk† E·µöÐcÓ±YÊ(¹‰ÿýER·È‰²¡HEñòï\xŽppàà—ÅÛõâõ%‹ƒ¥‚Š`½ ƈE"ˆFœÑ`½ >/^}]ÿöú2â½™,¥ˆÅöiælËB™Y ìö†Eozèç‡46B»ê^¼¼=TQWƒåãçëKÊú8“ $)¢â¦ØŽOï« ”&Ôc}³ )ÇËMYl³:+ û³¼ù[mj;þ‚9®”Wþ¡$Ðfg;üøOÊé4fø#O¡¢JqË ™FÓg€Â1Â1<#Ä ³«œõÊ‚F‡ãn—Ë›\Í "$¥œØMÖ{U)»‰‹$­EœÈ½Ûª;­6²V[dbhá4²;Óêìò>Û©Íi3‚ôظˆŒ p5k_‡ð ¥ü)n‰Ä3‰œ7Œé¦("-Ý{éÔ»QÊy€V…<¨­ýQ—v‹á1"8ê™y⣈q?Gn¿¬“èØuòrç@䲸µCE„‡.¬0P@…D NÏÑ|9ÆÆ°ZPXµD Ýf¤ ‡ MÓV™žsˆ©ÕJŒ´^«Ôj%zZ¥V+7Ë’“.‹Ò ò²¸UÚʬšY+—'+U»åKpª­BÆÒ凲 ð Œ1Šb<›;iˆðÌG?öl˜yèÞü'Oîe•Ý2Ͻî³zï&ÛÐf |Á˜)ï?U-u=¶˜õÍYöúI+Yg†)Æ"sc¼Ÿ§ŒÔç)óª5;I‘ˆ!.úî{m•œ“¬×oCÌØÝ°v_‘¥5½ÉÊáÜÙßÎôFä:Ë?r%MÒ1òcõ‚T y!A¢p`èùŠDàÒi)ªZÉé„–P.7LhŸ”3ö›¼*Ï$µ9¦H†ùMÞ”ºžƒžE(‰=øWóYƒ+3¿î^êbÖaÅ é§²ù¾&ÓŽå]©³¬GF-PXµž rÛÀ0¿š¼a.FÛU­›ú¨•{ÿÑ­n㜂àÓKîvJ ‚;×71w½¹ÒÕ•Bň'#‡mT3Žd’ÆMžUûÌçýQaâÏšôQãH}ÿ|÷ w¹zº˜\¢ lIÁ;%Äs¿[µ—H3¨OwndbÛ<-ÿv ©@ÛÊM(Ü¿v“ËʰoÆ¿îÆ/[…M"Ç€QéEVì$s·ÿN—;º0Î Ô]¼²¿¥}8©[[ùguTÛï§N1wy3ç‡p°Áµ«å.§ëVdtñçTUÉ[§ÈÓzß9ëÂûÌŒ^N¶g·)¸‰¬x*³ú–”Ö¥n9rÖi„CœZfÕ\Ššå}‚œà¿ÐÓGt–ZŸ-Ij£ðÝzñÏ‚4ñLÚ~† ¨Übl‹Ï_q°…—°;Ô6IpßL=@æñ©'>-þ<4MÓ4Ìu€QÀ•,:ÛEƒ2Ñà]r}[> ª (+háë–o2?ºk§KRç'Wª*}È éè psÄ‚¿„ÛЉöaÞ¥‰ŸUeÖ]{ü3Õý¸u3ݘàËo¦˜rz ±¼> ê³õdWèŒëq‚0áý´ŸÇ·mZZÜ/*»}]ÚS›È1‚©ü´Ö{Y[iV[Iµ/¹CVÕå_¬tsI™Ê”‹åUÓSõ–ÙS¸Y®ëM¦7GÿFÚ –(ТQ ›—åݬÔÕÚì¼¾ñ<> ’ƒäã‹¿k3ålÔLs¡®wõiè®Þ¿ïãIôÿÿS€C÷0ÿCÀ¥q1¨ÇŽå éÊ—g‹¦(I’®(ëÇqß­mWi›ÎòÁx h|”ŸBt÷€ó3H ËÅ<~’ê§?;PÓX’Ac=›é¿ö n{mTæöÞgÄy#iÚ îÍ®"M¥/…Îb7eèåÛ½—Mõá0¤|P*váH0öB‚c”tý°VPkÕÄÖ JÉ®d\¼z7å7Ð un2»!R¥Ç_!`‘Bî"ÃÄàSdÕt±©&€@ˆuqȘ*ÛÚ»ÿ¼’ÐNFì¹½ÁR¼ûÈU¹käÝE–ú´a†c~7>sŸÙoSs‘˜¢„g A PÂÄN­wÇe¶ðpÞT~‚k÷_Ä?¤ endstream endobj 1099 0 obj << /Length 1551 /Filter /FlateDecode >> stream xÚ½XÛŽÛ6}÷W(èC- fDRÔ%hÒܼMÝE,¸m ‘%G¤³ë¿ïð&K¶6°i±ÀŠ¢†ä\Μ: ÖA¼ý¶œ={³ GyB’`¹ p!'AšDˆQ,Ëàã¼<4‹²U2ü¼|ÿì Mòq„QšÁfFb-2‹Üö › dNxAR=g—üædÎë½­ì0< Ãbœ¡$³k_¸5ð‡² ÓKìðÃÛYðqAX4¿mïCÌæ¢mï>~ 3g#gÙH[}I!©=íõ=ßîj!'=WœÐ ƒÍ’¸W<ÅcçѶŸ"Qøg|‹£;ÓîË¢ù/ ûœ”ÇÊ™“¯ä–¹{µÜ½—›½^ξΰñ `ŒâœÅvöñs”ðvD4Ï‚;#º bIc ã:øsöǃ†­ƒ ^IŒ–Lj¥ù9„NŠGÑÅåö`zuhø¶*Bª~í¤=,#ˆÂQWØcô¼ßŒÅ(Ž<_ YtÕNUmó€.7Â"kì €F½™¡‰¼™˜2/#â÷ÖíÊ>o¹vôÁ>x]·ÐwÒ¾Ú½¨öùýi‰V5GÄ'â'BØ÷²7CqÒ'ú}PÛÝñ®œ$„qìeyâl¾ÞoE£´ji<_uíVØ|µo ã\3¯ÚñìSxÍ¢ù–«bS5kûQmÄÖŠóºLÚ¹»ƒ+n¶uç Naó_˜Z8=œ1«mÇ·B‰N¢—Yó˜!’¦ðØË¶®E¡&¼E»G¹SoAüªFV¥‹uÉ·#©º}¡öOí„@k.(˜W©Íw¨ñ Ž@õYî(4ôôñÎ5<û·Ý§E(íϪ+©.9Žä(Ëz!=’iºHŠñC¤á“»KûX “/n®,+^ûÜx÷$wr*gF§ÅESö?!áÜç`Á›‰§ˆÒgù®® 1]…rü„H]Îl¥s ™ª=mG–6â‚Z­=ß@®MÑv':®ZçÙ'OžœfNJQ‚©KÄÚ@~ËöÍ×}«¦|FA.õb€ á\u{°Ï½´„r±xs¥#l.¶Íñ ±R‹ o\œŽ©í‰ýù¯gÜ£$'cò¡“\†”…Uuo\Ñn·ÜÙÎ;wTµnÚN”Ž8¶üK/^9”.+Ÿ-†EÍV;M®Î½;.•·­j„[3BëdŸÝ I©a¯õ¢t›—Óù,÷»]Û©1Ô¦(íÖžóå#êö;Pž’\—PØÒhPAô¼â_´'´­úU뾤qnXDûRO÷Jš 40Œ°·H¿x’±2•Û»'á0˜¡:¦ŠôGTyú¾pPή+$B$ЇìL.¡gk‰_ÕJ ^ö(¸øð#6>üÑ¥h½Yb2&‰\PgilàA Ì‹E Ôy·í¤ý¢óåòÂF´=Kë]o.5:Î4ï»=–º.mªbc©œBÛÖd°QµùEd½ïøm-ìWµáÍ5úÆ(béõÁŽQ–äG]Ïû[0†öíí7ÞÉá¶'»-hBQÆØ jé&ç…l~Öⲩð4¦äÉ<=òÓåÎ` bDzR@/}=òWžû‹ÒúÈÀ°™k''//P%  ÍÿÛËÉ)¤6µŠŠíNnDóíŠÛØ[¡N ™ÙÅ ›0†þ£ê¸ÑaxØ^’a*?ä²FEI~Ôe ŠQÚ¦‡Þ0g”™¬B<—v¨üš¶©~$ü7îh ëQ2oZ7µtlv†ÛÇH§Qº‘Ï£ù;¢;zSÝÞÛ+Ž›ÛKÓòé¯î^)€Sj5*Î_¼9 _o¥†í†ûÂ*÷>}'у@ Þù;î;K:Rˆk \ Ž™dwÕ•—daŒsd2-=ÝhdÅ9u†óÁ_’¯Åå?é<ˆž>§NÈîûIé'ûKÑKÍ=ÂŽASigló¯G€D{¥Ö/:Ðú)¡ÅÏG¿/¹ßoàþ]—Þ¼3[ÏäŸ@ÿÃøŽ endstream endobj 1127 0 obj << /Length 1984 /Filter /FlateDecode >> stream xÚ­X_Û6 ϧ0º‡9@£Éÿí{h·ë€¡+¶öŠ=tÃA—(9ï+•ÞŠ¡ß}¤H9v’»^‡á“DQEòGR–Á&ÁO³—³ï^&EP‰*óàrDRŠ$̓"—"Kâàr¼“xþçåÏß½L³gRÆ¢*#ØÇñè¶·j©‘q&yû‹ËÙ‡rÈ :ìg¢¬’`¹½ÿS+˜ü9€©ª îë6H£Hiý&x;ûmØï¸uâÇÉXüHŠ<‚B–¢*ŠûEƒËL®M.ó|µš/âL†×j9exÛÛy”…¸‰#¯í<ÍB³¥‘¶4´4¼QíªÑÖwVy•‹¢(¿Fd¨üŒ¡ò¼R&$÷º[Úz×צÜöpë©¶Ê`•"/'zúCf~Ù|âi)²Ò+©n{¸ù~×wóERä¡j©"ª»ý5ó8 ïpX„½aNT//!1áO”ݾûæ§YðÞñØFµbkÜžšÒñÁæó(4|΋’e¡˜/ò² /i¢¸WÆ<¬;Üí{ªï¸±L=צ1ת¡] Aúõ|z@ž  ¦ú°7½3¬óÕgÏŽL}¹£(e>À íéndUÛ­ÝÒñתÓ4á®Ñ B9ƒã0MÚºo5µ$x?îQ nëå &ÈåwÆ™º]6û•¦ E´ÁóÀ²*gÁÄ›_­ùCʸáqÝMÖmŒáv ù-ß©C: Ÿ61:T€™õâÈ&rz[§š«Aô+Ó^ Ž0 ˆS“ı.ìº-ÖÞWºWuÓú¯™øç#BiH8ªéТu3ö¶£¡Ýc%² Újpˆ£ðˆS^¹© Ÿâ~eˆasC{×=·|–Y÷Ú¡2·Æj"îàJ}½t É(šc»wš±!ÝYõc $ÎxDotÑ•n>1–$·v’ È£^Þ®Ôµ±ýXå÷™9« ÿkÙª“ì Â%"-b@R.¢Šßuj£ÏæÕÿœg!1€52)C!÷z³£Î÷Ô¼~÷êO]›¾Ç¨y4ëÊ=—uþß³NVNtõÜ¢o =¶}÷ ÎÖý%‹ʶ!Ðÿ~£ÛsÙ ñI¡úhÆC¨9»›sSLQ‡W»(* Îå…B¤Iz|<ƒK޽£›ñÁâHYÓP*#UTqɾðx¿kQ \p:qñÑô^'Ö—È>v®÷ýÞ5Æ¿!´tX5<,,ŸL¦>Gî/¬ËR1T}˜¡l×Ó`mÕ–éà,`¦µ5-º)>¡½f&·húâcË\~ïqjLãus,ÍVw~_ƌžƒ*Ƭ¬<*öÝjí‹%öB«wP:xM—šf¥ÝmÙ7©W·÷p(°‘C­àryQN/eØjíÔàh-µ;e!!ìei|‡tÜŸÌžHN‚3@W,²d”¢Q¤‡êc/¯ÏC=‰¹z¾äº’Š 4 ÇS•#hó,D‘¡øÝhôÒþOh’Ä"Î&EÕ[ŸžãÕÏU‘|Zb}]팟d2y´f)< ÌÞÀ8HJG“Ä” U «”9m¤é>¨Ü+4¼ôË¡·ªÝƒÕ>‘tоù¥TÖ%ÓM`†2erœ¾§… ¿·x¨@.Ù˜”RºÇ?(JØ,O `AÆD½¦uñòù«·N!ŽôÏ|Ih¿áÞôÔ±ûvx2À•"vfsQ!óa;üq»¾ÆuŒAØB¨` ~X× ¯ƒP¡ýVu÷l@´5V§Ò[ýaiý5„ønÇÖ}âç ¿K`^»¤?z˜\¾yw1|iákãA¨±bz}ÚépßÑ•xŸ“ï7ô¬ZŒ÷aE}>§½Ïgyq9ûGÉûç endstream endobj 1146 0 obj << /Length 2002 /Filter /FlateDecode >> stream xÚÛŽä´ò}¾"i‰¹_$8Ò ‚Ã!´‹VîÄÝm67œd‡þûSå*÷$éÌœ]4¹Ú.×ýæøÎÉñî¾y¼ûòû8q ¯HÃÔy<:ï{Qœ:Yê{I:•óÖ•í.öÝ»?úòû(›¡Ç~àe9Ð2xQ„(w>Sóx÷÷] ïÏ„ÃÐKB§lîÞþé;œýäÀI‘;O³qâhÆÀµóÛݯWrëÕFsáßKãÀÉüØ+²Ì ÿq!(œ-î„^‘V…oõ.Ê\)F¹Û‡‰ï ZZ¹ ÷‰~°9”Þʼn۵lGÃaSß´ˆ½´H?Ga£X”nx%Mñ&{å;9”Zõ£êÚ…‚ÏŠ.\äÎ>(¼œÍòx–ëxœÚ© ô³ÔÏêƒÞá­Þ¤óà-Ø:AäA(íÁ¿± œwa˜¬Œ¿pXîÅé5zÀQïüćÿ`#ÒÂÜ ²Ðâ’Œ pæè£(ÌÜò¬êŠvº#­ãYPNZ£› âJÂ8\h­äq€ß§šD[ѵQ|À“ײ $´‡šyµSsšî€   …¤ßƒ§‹$!ZÑÈŠ,Ûþ’åÈö;Zû®Ÿê«'Ô¸2÷žŒ·2/(âaïV>½›[3¼bû<óââÖöašü€…m ÚWc{dÓ×–ÇÍ.,oh·LrfùO²Ÿ1/ ¸0o­†‘­{ü\+¯ÒoŒùšqlÿw'¹™x·‰¸¬RËDä°÷<ÏZ.íÃ8lp4î{‹× Œä/vûÄ÷Ý­[/z·£ k_Ó‚&²ng‚D}eü÷~–³(YXim¡{^;M¦X¼j©×-J~Aî1,ã{¨Y µü¨_1*üy¹£OŽ }ÞºÕ"H•ˬzëþ37v¦ìŒ »)ÅëIBÅÛ'Qìþ±ƒNãva–¢%¼aêûúB›]+isj[K)6Ag0{Yª#£ Ú+§aìëIÉ)éqõ¸ bÈ+ý¤†kÀ²ež“gà”‡X×m ܨåÞkUcÏfݱæ;e!‡ÍÿwÍÛmÂ1z¿¸¼-×>µ¾EãñÁ¶åvžÒ£ù;=Úš eåe÷¯4 ƒÔóƒkeÃK…ñEí /ó¯CÄ 5Ä78‹ys%‚œG vŸ–Eës:|°"~%ô*I@Ùµ£P­Ô|`š&¬S«þž¤ døe£HL¥é é°ÔͦéZ¦30#Å LôÃÚë§©ªb±ˆz®ßCÙõèí4wF àX†3–ؼf2¦ÔÃùƒE>ÿôZÎ7MiêþÜt,ꚀZ´§ Êù@TÎbâ¼ —™ß;ßµé'p\Öb˜ÁÊĘYä*O^‰)Ê5¢UÏ}'¿* 9¾pµþHšžÍE‰û  UZ哜ûÜ‚˜bb¦Íq¸*äì;„úÎÌzR§šn¡ÑOÚXevõaK!®¶i‰ï_°ZÎËRy›s6?ŸѢÅrØ÷×Û?×àKಃñƒ™ÏÚj2rf±ñæ°úÏ>´»š‘pŒ×²”UgÓ©ÍgôFw_ˆá³¦¯>†e«Ž®²°ºÂ;ê je’?ˆx˜BhUq±èf(ÂciCj%1¶ŽŠ ÕÒÉhYŽªºÌØŽ[gÈŽèôFîhµß×u1smDVÕ50¢ïçÒ†™•¢i„6®‡Ÿ÷´k‡o„Íð€™`mÄÀ–ñ0”ñ0m?´Á @¤Ó­§¦å+Š˜!“ùÿ&å–ð«®#š¾–Ÿþ&K|/ôÃÙ“ e{j|ʃ,…Y”/d7êÍãÝÿ)R endstream endobj 1159 0 obj << /Length 1556 /Filter /FlateDecode >> stream xÚ¥XKÛ6¾ï¯0Ü•5£·¥¢=´@´šb㜒bKK´ÅF&]J²ëß¡HÊ¢V~ÄÁHÑÃyÏ7Ãu'›‰;yûðëòáÕ›`1IQûñd¹žx®‹‚0ž,bE?Yæ“ONÎþZþþêMõ(ƒtQ|ZÂf¡ëì%ძÙï¸wcn®Ìý…[sÏCi+›ëÃ=ߺVë‘7r:žù®6Jý´mÊšîJý%¤û¥ë+õ]sµbu}CgO˜úeèŽö𳹫£¾ZUtÃ(ÛhŽ9{1<Éc…e]¤¬«ŽÛ/,œ­ µûi®V.Ôº“b[™©‘™ŽÉLÃ6ÔòGÜæÝ¦1¿hëSe=,kZM9ë<™ nìlyN×Ç—‚V”åpª9óõ˜!œéçkµÖ¯ô‘øÎ Ì6æ—¥¾ØúhôÖë”%RõjWŸ,(<7ô”6ïèZËÎŽÙ #¯Ô\à!À«ì>û~4(~?è]IP',²‚–ù3a{™6Ò¹Zß¾ŒhB·ƒY~ì;”©Uù6ÿ6¤’!RƒªÆY:€bÎoµ¾¥o ’7,ÇL3.“û`8B µjXzûî©‚¹K:ƒ{#oahq–‘]­Eï,Œ\“”ó6I a|x¡+:a«ÑP°ï©qôÑÑü¥¬ø™`ŽÁÓÀÞ!œ‚ÁÏ®úFŸËŠ0DIÐyêñ$d†(Mú~–Åt“Ä%^`nŽg½·@±¿°Sÿõx X]Ìy+‘à‡ƒ(1ýë;@i×µ£=ÈÁµ,NùÕÂÈ¡£>A’<8T6"¹-°¾Ôæx˪¢£ì_5ãBÞ¤–:†‡N»Bà£H$ö,Ъþ¬ {r]Y§Ó5çSœÆß¯Æ~ 9‘]—RŒ ³RNiŒíÙÛˆ¾0ʪ¬oî‡f·+jߢ¬Ü4Œá-ɵC„ÁùÖµ\Ó×Àá9Ycè’?~ßV¸"}­ÈßïΛ½6T Ï0ðQ²°]öƒÛã’Ô:uÚBnªÉ çYö(%FÔ2¶]dÉ‚ÅÄÙö ‹{¼Ð2ïùA{ÅÊ–Ä2]MTbgJ’Ô°õêMäöë?Q˜ÆtþîzƉ’•²Á¹ëúȪÑQÝŸÖcZE òïf¥ð¥ÂkJuvc–9û ¸YÕ½¾éÔX ¾aâû(ô®Æ(ìõœÑH£0Lo6F ‰)¼ tö¾l¢mÆ™ü—S<}4Ðí²n—O‡µ<£ocühe–U˧¯ÏÒKwY9{Õ[§Æ4 ]Œ’4½9h×èªÊ`½Aw\=÷ªÚÆ9C³|ß5˜¹ó£ #ŒöÖªà¢Î9›µß‚h «Z´ãh_Ž,²øÈ…®Ù˜b/ô÷ž]çAØ îT”ð˜¸Ô°‡p:ró ¦¾w—a—||÷î.P±Rïë<Þõ|²ÝÕÇ3Î…w8Z@RZEm9Jª~‡͵« ‹œz¼"ã½ËT_×òÙÞsÁ†óÜrŒg8Í4·µ|R«+çмgFůH†£©•Œ³SfJE>iU±@Ña‘÷ P#Œ‘=#×¶å1õÂnG!Žs’_ôÁx ´‰eÆ¥OjùBÈn8ÜŸ ©±¡£ß•ty‘ÏÁÂ<)v¸.Fa¢¯ lSI5½¡¸Y}¨Är8ïO{vOï±ç×÷l`p/rÇ¿±òu‘pR±Ñ.¢Èíþ¡ñõ ÃTÊž0ýè2õÇ ±a *•2*óþT #0éÈó›ÑVÆá¦ùëÅ‹øõòá%~´ endstream endobj 1065 0 obj << /Type /ObjStm /N 100 /First 967 /Length 2279 /Filter /FlateDecode >> stream xÚÍZÛnä6}÷Wðqæ!YÅk`˜$˜$À.سÀnœA w+vcÚ’£–“ñßï)¶åŒ/í–3ònì.µŠäa±X§ŠlOYeÊyùL*[ùÌÊr„ð”X¾$¨â™EÑ ¬˜JS§8Ñ)ùß° øƒNP1É«UfQIþ•öèÍfé2â³èG æð‹n°¥Sü ÂDÀ‰&¢ÿˆNb ¢},$´H˜BFß)ËP 2ËP‰ É£ÁLÈô›¤HÒ¾³Vpå„I’—0KçJ‹¨ÈÇÒo1¾HYQ*o1å$cÀ@l‹…2Á0AÐe˜ˆ³´Í°‘çòÖÃZÑa ¼àdd²hšaEk$Ó±Æ*gd:„…‘Îñ­++b AÂD ±reU¬é˲ÀøÊ1ÙHR(-ЫÓ:çeªhéM2AòF$¼ô‚¢rÁ‰m2ZLÜZÍE1®˜Êå+aù”/–³pOYåø…%RÞƒXùb9KNùädÎx™siT0,˜"„Tô³ – F€+Ö·0RÀâˆDÄà4*°•ì …2ªWÁiëoe*„2 —þ0lN$cd·–uFE&鋸¥…bÀîð,¦2 !y­”ËWIÅ,³˜\ÌÅb0j2Œ•¶ÞBµh•Ä”’øŸÅÊ'*Vt"‹aËn°zފݽW)”9ú R2"á1a܃ÃÃê[u‚Õ÷ØÎGªú÷~‚ËhvØ‘µƒ·Wëõûƒ¯¾z\¾·ÕvN{qšv §áص½ÏZ\jš6'§3L÷"Úì4M‚uÑdïi¿íÚAªê-üÌ#T•foY¶Z°gàÛ*[îæ.ü¶ ú«~ì»Åq3¨Uýøí[U½k>êv¨w×— ^ÔgÍAõ †mÚa#Û¥@=¨ŽšMwÕ/šÍ6–•ïþÙ,Wõ×ÝGu"#úì1[8³:å÷¯îщL0lõß´m‡NOT Þ«ï!ŽB…|#D3 ¶÷0—nªã«Ó¡<ÿcÕ~8¨¾îúeÓdæ}õ}õCõ͉-2™Ì@)k­Ñá•mÐ%€‘Õ¦ÌàM±ý±ª¾ëÞu k÷êè×V/Úåk1è< "|»Ñg¸æÇt >ÆÂšþ)úèj­7«³¶^χJKÜó1é$\’¬–äa,¦pf‡a#¶¼°––á ›ƒ$èkcâNõi×3¢ðAGá•FJ4²ÆußÎè"ÆéˆìbDA.è€à¹Ūýµë/æÃ¶Ö8âðØèAî>k¬†óâ«çu»\7ýæSH%"§›Î'Ÿ*ïç“Ç´AÓZ2…iÚ>xí OÕ6AK"6M;»þE” 8ìT‹ ¿Ñ“A“÷: DMÓF¾Œ—vñÚ*»Kr/Êk9?䵟Åkïór­-U¥‘ÎÒHgi¤³<ÒY¶£0¶Ê#-f7 ~œÜg)j¤à>ÒÈ)`YRFá¾àìν|Ú}lfd?Fè ¤ë.Á[‘j0r7”d’ú?MÁ3BˆF‹Žœ!]Þ a½ÚÌÈ4Ì^o §¨=òwŽ@OÔQÚ‡°ÅoWõfõÛU7Ôꛓsޱ “¤!HKX§ {•5jáÿ9”N°‹œØå¸Cª†¸AEO¸«,Íh•’!¦¹¤Q˜OB1#-‹„ çeÅi, MFXvÌ;Q,£ Ï ÇIzá8$Ž.ø½pæ^ä Ñ—á° #©p ‡uqwr²¨×ëa°Mˆ^‘E n“‚1!‘%Fñ„‹lšº_l³¤¦ýýa†”Ó32¤O•÷gHiŒlšªmᦟ¯í£‡wO%B%ÂæTml3‰CÚÒT›8$ɘéTmãõä®ÅµÙ¾Œ6IŽŸ¦Â&“´œÏMÓ¶K÷÷:á@&ô ”ó½ÏÌåIJ$nbŸ­@fì(Ð(ð(¸9³<¶ ‡UX#„fCb2|ÆÝ¡yèëESbÑi½ø0Q˜HFbb‚åèÃévç8ýºnÏnáü ®k·ñ²ï»~F"AfœU¹£€"Û<Ç,¾þ$‘¬Ú³9Y…œg¢Ü—+ÔhÉ °(Qk¹=óaˆd9 þI9 "#À±ör a"xÞ=i—¦™mvg"8+ aYÄ/ÐÿÿÃ8,!!Žp8§r4²ÎxЇ("n}Ÿöå2íßQ¾¥}9Èü"Ú5‚\!MÔNFgŸ&j{籦j»ÚÏy¢6%_*¾‰Ú„¥$÷üó‹]Du‡Ïþ2k¹ðµœûlÖâ›ãx¹ªºFã‘ÇÜÈcnä1G³žMÀÓ3 q8#ƒ­ˆƒ&”~% ñîzy >XÖ›óRéÌXàH…z&År0ï2!,cmåÖ`7‡Ö›1ä­ú®½€Áw"z ‚QVÙON^yK¨;åN´^Š Dd"‰.7“*sªÞ–ª7 )«ãê_G?Èß«óa¸Ü|YUgˆ‚W§zÑ]T,Ϋ£ðú/C³NHœJ-ÌA 1XÂË=B~6vv¹îÒÃjyý{ÓoÝõgUݫźÙTØM»Ï~1*žë׳‘¿Ë%Y¶ˆßžäŠ=K8'”ØpÇ‹Ý\\×{)nÂ:{£ƒüî bC¼]h›Á±Ñ>¡a¼«K ÅòT/ºËæ—Ÿ_aý/¯†¦ÿe³X5í¢ùùõl†´a{ŽeåpB~ñ ×JruOF{Cû¶Í²ê"\Ô›XÑ=ãúùŽòŸ> stream xÚ¥YKsÛ8¾ûWÈÞ9HUB|ºvIm²US©ÙšŒsØšLy!²0¡H…{µ¿~»Ñ­µgË6°ßýuCö oñ÷«÷wWo?á"eiäG‹»í‚{A´ˆ#…Â_Üå‹ß–ª\Þòñ~£Ë|õûÝOo?ŠxôMàq'ÀÐ!¹ò¬ˆ·}±HàlàÙµH^û1~oùïíñ>Ûé"_­CÏ[þuMO³t¯Êǯ^èýüåÓ'xrd¬×Üci˜: ïw²Ác#fo,\¾)äáPoìÚYCvvA—;Uë–^~¤ÇÝç/Æ}ÎRžÄ¿Ð‘Ÿ«VÕî¤ýZU <‰<Èì›|°GA[]Wå^•m3#}[W{¢6²QÎüçL·ŠHËéIÅíܹºåÃÿtò9vó?ø9ŸÂîÍKܹöñÕ*nøXû2kuU¾^ò4¸—…CŠ÷ÂÑÁó²…Ï’8š¸ø=ij`ò~™Ï8sØoºÃ¡ª­F­ÎDå•K€­’mW«f6tÕæf³B7-JØLl¼ÙV•óA6ÝÙÈúRP§Ü­úrÂÂÊõõµÍnÐê˲ eóϪ³jÊÒMSÕ•ß»¾ªJ¹W.³µs?”•õŸÚêR›°‘JU˶ª ¤Bo<>šç‡¥þEG&ذ îÀí3LŠ/±X,ˆÃ©7e=uð¼yM ®¯{·. ï.…óy!¿¸”/ÕÓýЦÛÚhd5d¦ý «ÊVêRÕÏGÄ ï˜É›âÖAÖ°vû"·<§ø3°A¬Mo0þ¼„çŸô7uÞ(¯÷@ÓÖ]9Ö8°qU-¿¹Lu9 ¢2» yÙóƒVQ0k󌉮æå³5¿™¯ygòÕ‡»«ïWDy Þwú€‡ Ùþê·ß½E{  i²x2'÷pú{€•Q,~½ú¥oí§O3M@9Œ¦ 0) ø¸±8ô!q“ÄhLâɇ>KîJí=Ç®±lŽûMU4ô‚9ŠOò³]Ô%=¥}ÚáE׫ \ÚÌ{Ö"‰à¼ÆÆjÍÌP"„µÐæ×ßT“ÕúàZÌ™óNf*HË5OXÛ|¸Û),[?ôûNÕЫ+P?Kt«.ìy·žðOØj-xŒœi{ú1Ô غ ­r’Ðîêª{ØõÐ7h 3îõc clfTä1 ÂA¥•u «`-"ÁÂñj3´ÀUméœmdSNÄãÊ¡ytnÀž|©V<\þû-µA_±9j 3¨7ÍË1œœ¨úLø}‹ÐV¤úÞiÔªb  ×)=a´ÙÉV㸃*JÚFT£cci VÓL²æPDAâ\’x…ð–Vàq6Kçñ¡îv¨7î÷#ykvU‡£!Ò€e+ è-3¹€Âì¯øÒ ÞË?*¶ŽÓ]ÓÜ(+o³òa£µ,Ü÷„³G¦‘Çj-KWÚ™«é¢'HÙvÑ[Š<rP™þêy~FÚjO)Ð×Û‚C£©È¸½‡|õý™ËË~ð”¼&]KÝqçR0%à4ר»ÔøÂЍŸR)±Ï9û)àiO;툯 ›ªÃA’èÔ–…¼İÇΔ+ÃÌ4[CuQô:Ÿ$i:.!Tq®„pJˆâ,YÔ G~>‹ÎZx ƒºšfNø··jê¡«õðF)‹E:1yÈ™u ¼$ÌœÿÓYs/¡ôÕGA'Šx2“>< žOp¸†NqÎ^LÔ2pŠŒ©›X)¨ã€*¸Žºž˜M-(Ïÿ•¹µöSnÁ åh+¡ÏŒµm8¤ñ4Èt£×e Ç=˜Sžìaˆ{g"óžì|IÊp?`¡#Sàî»’:u"®Y'â‹ëTf7ëŒïÍgô0ß”Ä:7fê½å¥­áÚvPF,m&ô¤©” üÀ6ÿ$ÜXñdùÐÙß$ü$±¨Óÿ~{¡·Â•‹ÝþÞYó¢BŒ¡ÄúüÀË!Ê?âÅ ê@˜ùäHV@Øw…´h˜Õ•ÌÉ->@fCÙ$oh°¼L=Â4"Á éÔgµWû ï¾ðíïx¸(( ±7 w& ©ŠÎzÞ(SÑá\oñ¤0º¢¥M7cÌ„ÉÞ(;±´;Kèý>È~–7ÓÓœÂ>í+!‡l¯ooóêR“™Ÿô]y¯Ú]•7'cR?2ð#QävÚñ8´¼(HmË‹ÿŸ–WÈÿ/(ÇLp1ÓðÝžmx>ãÄ( ;ŒÐ+/íà?÷{u×þx×®óX %\>™I`æ—ñåŸh4IÊDM[M® yTù»O&܃xñd4Á ðÁ4å쎟ÁºY²{™<àOŽ9½™ßr^í¦çaŒSàóæ%6ˆqoù1£´ò-žÕÿVJJź h6\›Ü'ôC!5i>ìQŒAñ(=Œ¯Ñbs |ð2;Ф1~‹¸4ÎD£¤ŠbápŸÜGiÑâ+wøÊÏ5.#Z@úkx7È ç†»¼@ai؈B—8Åâ¤Ùý£ÌLäSºxº¾€tbï²é¹ü7T ·ÒeVÕ`árŒùæôâšZ~Éœ=fÛƒ´”*lµöÓþfßsœW{ÍÿÔCì`Ÿgr­ß8‹…Áú‡è®qçf””.ͼa¨L½±xnG 3„æŸ@çpêžî®þ xãÛ endstream endobj 1189 0 obj << /Length 1597 /Filter /FlateDecode >> stream xÚ¥XëoÛ6ÿž¿ÂM¿Ø@Äêý(º-ЊmhÓ Å:d´D;ÜdI%¥¤î_¿;>dI–3gC‹<Þƒw÷»#w±]¸‹·¯®/ž½ ’EF²Ø×›…çº$ãE»$ üÅu±ø}Ä«?®|ö&ŒœA7ö@âaÕ*t—w7k^È}á` ˆ9VÎñ$jé’nÙHìÔ÷Ù?î7]8^JâÔîBïà³¹&W+'rÝ%!(%ŽÌóÆ7%ý¶?³#vGËXÑÓïô'§eÉ’Q-Y™¡yËïØéÝMƒ…îù1 {/ÅÊs—ÛnǪV>®‡Ã„ƧI¢ ‰I–ú6µ/«•ãG®M1u…  #ƒŽQáxIƒÌ˜%ä|«/ +ü‘t!PBß¿½€åb_ÑÏGú€üýÊ RoùݱBëõ_,‡h© F^Çy/!~4ÀòEƒÌ ÷f$õB+€LÌÐ —låE˯`Ròº’3Æ ²Ü8œÚêñwÂ`’Äˬ”1V 6'p=’†˜cdQ¤y6]hÃ=¨ìp=ôIš¦G»9õÄ~ÒÐ @ ĀΒ=¹‰uÀvšô^}£ÍÐâ)œ@ã²Ä µµöO°]±¿Ã¦iè ¯¶òa¨úQJR?ÓX m…Ø‚?°×·h5 §u¢‰÷·L˜õ¶gœ`E3ò²Ô£uÏæ£[ðCËŽ¶l£±š(”ûݺ."*˜mE#XÔ"g™ë6Y¨kvÐq~]e>šoÎÓÃcÜet@ ¼jºVu5ÎUEB’,¶±´ jj†~4(TyÏÛ[c§5X§RÖ97¡:î\š¸« þÙu}ËÄM›kJš³«ž¦%_—ûU-gãæ¹I|o¸¼0Þ³ÍF5 Çð¯r¥$›z 5õ–®|w€ø ª`8ëÅ$ÛѪå¹áÇê’L­¥ÀZ¥£‚ªiè ¸~)' ‰²lÐIάå0íÓ^Ô¹:Û(nÁ4U?ö0UŽítp{H£1¤ùfU¬Ðáu-¤~_ûš\o4•Vz~ŒXlD]t93"lƒÑ¹SËÜÈRU ¨Œ ½ÖÇÝ«®ôö–¶³É\mþ` h#ºñįE!¯æŠÆ‡‚ qlE> Ü^€VŤp4§•¥L!æ.åÙ}„´;àLDü4Õ­ÔœúïøßèÃã!³® T®¼%èrjözapr¡HiÌÜQ@ü ÇOCÅÎû)@':?£@÷/ÿËÁð ¢ z´*Úê«¿GUÄP‚6 p”0¡œæ€#mוTÓj1Xóz,iN^É–ÑÂpnΰΥ^”õ¦uæj¶`p€çæ¬Ið ¿¡î80%U½ †ð´".^“RG.5•W--µØ–ULðœc-પjXsÚé ©I]m:©{5z;ꔲ3硟ØëØý´ò°¡ts®ÈÛº³P©jÄʽ)tuQiÜ 5¡µGûìÉ*"D¤Ü›kƒ YÌ@÷Ô.h5ÒÐûš?‚¯¿Ò]S2yþ‹1]pé¶XL‹æ¦÷T?ÂŽ*SQ1Gø¥úÄVÐÝΧ\Sîé^0ÝŠ`½­”‡8½3Õ†c<ðkoi6.d mF]iT"w°õÀ#ÁáÎýgßl!„¨gxáÌèP£³U½Ÿß˜}ðVÆË¢ÐƒÃ)«Âe–<”@'„‚… ±ÅÉsÝ­àxÑ8ÃDñá Û¼™7u=zŠ_®©¸¾¾‡*‘Ù>Êî^: öÏBñ>¸Ù[jÉÆ>i6*Àªæ‚Xö1·‡óÜêõY·^½|Ò-d>íÖ'¨ñqÒð…tÇæò¶6nË®iÊ}^x:ì–W¬œáelðØ;å`+Ô‹$GÿW9öõcõ¥«[æÈ¦ä9•l¥ÿ€Ã’Ëv\¬°‡Ù2TôQ^kn”*å$þ\¶.¯&è»:XBž‰G~¦ à“'Op_ÿ¬µºy³ñõõÅ?ÄŽ û endstream endobj 1199 0 obj << /Length 993 /Filter /FlateDecode >> stream xÚ­WKoÛ0 ¾÷W8Y-иò#‰Ó­‡X‡í2`Èe[‡LväD¨#e²ÝÎ-öß'YXŽ“¬]m‘É)8 8Ž®§Gç7áЙ¸“‘?r¦©ãàáÈ€; |g:w¾Ÿ r‚“ûYŒÉüôÇôÓùM0nØ„ÀsÇß°VÆBå(ç7~àD\w ÝAByà…½4ys:pò±OœËçŠæj¥ÌQZfò½ ò™,!Y ùN‹%bò‘{Ì(Y!Rä"ÅÀîd8‘ÎVÕŒëHåwct †€ÿ¼..®s:ÒüLÚ¥Ts)}¾Ðßµ‹´<6Jê{îÄ‹, ®¶N,J†ll4 ù:É’e8/”˜¦òIà Íåë=ÌJÔ å6 b+‘-´Òó€Ê;¶–ýç×ëõ„Sõ•XÛà‚±%‹,Y²Û¯´Tþ ‘/<…cI~•´P@BÃ0ÎÔ"C)b “…]¥›W«˜ª‚Qf‹ŠÚª#Tà ¤Ìþ¢r;ŠÅìZõcøØ&úf“ ÍÜë«o‡˜Ëýhià»Ñxle1]êfÌ,ÆÙ„,´–JV‰!3(s®ÍYÌ›9ÇqV]t•Ü8j´qwÂ-w³X¯ò,­žðîBF„ðÂ1”Tçj°  /0ÙÖÓ‚š™q¥–Êõ:«6dä;íæWgAb˜Ü]<·gùNM$:RÖÖ³ >Vf¦*šçxA”{ô{ͱÈ1Õ \·ë¼‰èEãÚİÉAt•UÝ'] zÜñùÍ4ïÝzAHꢿU$¨¡ëË?[Øð¥{R´©/?p–éøÔW w°àèìä¸Îdw®KEJ²J¿%èLÓ'ÎѯÒ0¬žmˆËU1*Œ4gLÔ醡5/l»)¬ÙÛ F·.·ÙP×låvpš…¬kø<éõ„ã=;Yi×ãqdDUaŽRXfE Ü­v0QQa3[–Iɘ¨ãîöoÌW®Üè >[ˆ¾?< Va†`ëLÌh¢Y`Ñ’yƒJ{¢ÑÝ€‹3 29Ñr±lågÂúúÓ’´QÎqZsùéäØÃ’¶ŽØNîPÕÿ_­a.©Ê=œé­)oûC<Ýnªñ¦Ê×(Ái¥«Ó¼!›á²ã¼yÀÅR^ó‡ qu÷Cß“@ßóJëvºad\ᨾkoïŠÑ¡­B­ «4ð'ž‚¨…ŽöÒuD˜J^šB‚Qÿ5FÂþbª×ïrS‚™ Ñ{áýÌ좛~4³1çÿ:YÎe­K¿èm‘ГõN?ßOþ{9À® endstream endobj 1205 0 obj << /Length 1009 /Filter /FlateDecode >> stream xÚVMsÛ6½ëWPJÒŒ $H‘™öà¶q§¹uª2IF¥)Ðb‡~ÈV:íoï‚ REÉv€ÀîÃîâí.¨uoQë×ÉO«Éõ­»´BúŽo­‹QJ\î[KŸÏu¬ÕÆú¡úë[ǵÐó¹Ò³]Ήã–í,ª?nó…íQ:ÿÁÆq–¤b/²™‚›Qz! «ó/Ô£QY 5å+­µËëRÌ`‘©¯Q¶ÕÙKáŸnw-ä~}—ÊÍ:‹¾6,hlíÎ~Äa:ECνm4ôžÃHÈÜ{ƒúŸò'q$õ¤Q¥‰â*Ýë¹²(•÷%þ=¦Õgµ(¬ìUöܽA„ãÞŒÁŠ'×Ýé8$µ\›'¢X\¥m,ª­8h•B/‰}”ÕàÇæÝØÙ‰4/º=¢5WÿnTû7§cG•’œý†rÛ¨‹‘m£,›/Ìårvîz ™;ô OÆ®¢nº õ—8u¼¥#«ÊÃî.Ï ^%²d§ÉCöò ­ÖYø'  Ç ÜV¢?á_‚0ÎHM¾lF¹qzHß}±:,§0ŽO‚0|½±-'ñ7/p,DU¨:£©j³%”?¨I'©|´g,ÑGv[®À¹ë;H uëP.°`¡¼ºå«>ƒÆÙó¿FÊÍM–µ‰z_ÊAÞB=-ÛUºGåz> stream xÚÕWKoã6¾ûW{’5—OI<ôE“‹¢@·=¤‹@±[]‹r%yÿ¾C‘’EGqì¢{(rÍçÌ7ß|3!hº½_ÎÞ݉V1‹Ñò QB01Jb‚%gh™£ûH›¹ Ñç‡\ïÚÍüãòûžŒ Bq’ÂÝn®ì–ño\/gÏ( ¢‡ë™Ä”S´*g÷ Êañ‚%•¢/ÝÖ — ã-º›ý2Üwüí|`|ì%8%$ÅŒÊÞ‡‘ýÃað> N2¬RÚ{òc·Á$‰ª'÷ÍŒûzHŠz.dT™R›Ö-¬æTF›¬0Ý;“ÎÇ*ÆìºÀùÎIO*ŽÌIÜܬêbו Ü<¸ĦhAS'Ê_nмà,zÚ›Uw üâQ­Û}müR»Ñn`ö壮ݎ˜`qø#ºý¢µqÌ BŸÄ¼ C&èE̤ê÷d&?✄?œ¢zú᯷3tߦË]ûmÒ¶ ¸÷­ÝG…Ym÷ù®"(p% D±’ä¬'<¡+&^qöˆaž/8!ºÅ“‘(÷lcÛž¿ “17_„ŠrÙïé¢ ×eÛ¦r£¶ló܆ï.«}Ì^22Ë\~‰ IUІ‘gé&WÕÞÚâ R¸’ù0ø„Ο‘î㌇×(ö6³ea©Æó˜ºÓ¿5ÙZOæÈóœ !ð9“ÉŠõ~XÎyÿªžS­÷.KNÙñêûG‚Ä"‰3¬ÅÕ±x9À'S¢;ýû\1 Ó^_".iøvaZm%r ì“2:+XwZ»ÃW–È—¿íR Î7ºW5+éƒE]mæ8ÚMœÐ•gµ¨˜%BÏ‚—ìc Ù*éåÕªãAfm›$æXB9P¹þš•»­nÎgq 7Æb(€Ämj>Œ\éÝ›P[•T§vŸÖý™7õ63ë7ã£Ó•|ÕL¾oÀÔJ&¯u{Ap«Û°ôWª¼Ú¼ì=g8¥ì¿é8˜~nðš¦Fc"7|PŠ’¿]>mële‹§q‡É*;÷TWe¸z¡§c» ä1’^XT%I¢÷ßÜS¹~²:›í·-Ôw<*Z÷x^io¬©¼…Ûªúä ãfºje®ºøjĦL…Õè¸ñÁS\aA“‘7å‡mÑœ‚:a˜15 µe\ ® cnú%‡ø$=Ç+(r”R“•:wCkÜ´" É¿¢ê hc%Ñî³Ê¶[]Åé­[0¥@È}¸í//îÁ7W?Ý]5q¬ŽbË4ÿ΂ÿ]«ðÒ{ Å‚J,_Yº¸t¬*›óŸÿ(Ø„ÿy=&‡Ö{2³R(·"lÊ)™`XÈ¡s-÷gÿ£¸­êºO¦¦­á×i—iB0ƒbá|öbà pÚîÁ‘Z¹‰Ïs&]ÃT›UÖø¨º_ôx™*ÀËKAUOék*°H.Á­˜ú'ê,ì2•>…)S hLû4:Ó?6Ú¢ãqò 8‰ï xBÜö-£Wþ©dhðd6B­ÿÖ9B endstream endobj 1229 0 obj << /Length 1240 /Filter /FlateDecode >> stream xÚíWßoÛ6~÷_!´/`³$Eý* šl‚[ CWdŠEÛÚdÉ•d»ùïwÔ‘²$Ëi‚}Ú)òx¼ûx÷݉Z+‹Z?N~˜OÞ\»‘Èç¾5_ZŒRâ ß |J<—[óÄú` ê|œÿüæZxI7ˆˆˆèiddîjïï×q¥„'T_úýΩ™96ãZÄÿ;·ãl'{G;*z&†ÖŒáâáËÜ™qÚÅÃ?rQã<]êQK‡yöç´ª+âÌ\FíÛz-ËCZÉ) Ôë²p¸g*ü޵RY–EéxžM‚¾3Ê’ÀÕ¦\}Ž7ÛLV£nœºÅ]+e¾hÝ Á-umãRæ`¾G©ýÝ ÇÅ:Í’{™ïÿ¢ýåîæfŠëË¢Àɯ`áÈ0e\6c”D^d^jÿ„V¼Vë}ˆË¾^XèéåŒD`x£÷5ÊÌ×i…3…éAÏžjD¬¥*pZ[Ž‹-ø-ð°ˆU/׬qo+˪Èã,s˜ýˆ™«íœ‘ç¡ÕʽCZ¯[ 9ºÇ]¼#Çê >…ÁõIµdTIesíº×Iý²ëË›÷W#¹  ŒÔTëSôÄ™PIç@ O=ŒÚæ:ô`B¯jlp¦®ë …4p¸z -,uæ(¼¼ç£Þ\êÍZ_…ŒYézBCH¼à%8{œqnÒçÅ”#0ù‚^ “Âb¼Ñ¡>áP‘{ÝÎ]¯äó[g¥IÛœ\ÒÎ2YšæD¿US§7Õu¡‰ŠNÊ=Ùµ]–*V»Áÿ+üö¾]¬ò°}¤Ë!%bè†Þ…3­ú†ÍE€Ä nÅK브µÔ\{$½]äuœæMÉÃîXsqo ¥ËÁ^‡;Ôrc)7…ÒŽW¼Ü»g<ÏÃ?ZêëX‘Å¿8[ûæ¦ùÀÓÀŒ> stream xÚÕXÏoÛ6¾û¯ |²€‰%)’’r:¬Pì²Ö=¥E¡Ø´%Ä’7X4vƒ,9E1á8¦‘scêÂpbO3œ&Ô9ók­Ú d‚¸8MÀŪ®JUuý†½µ_ìúí²_eUÝÁæÙ ~6–x#$S†E„L$"éI¨1D‚[—T»iŠcWÔÕ$§€L’KRX¦q|6"êšÊb’jåÃõÇÏï<¨p*P±óÜ“`qÂÕwÏ1æ1syæ³… ÇN$«6ªíêÆb@$îÊʺÚÛüvÖßcÖ@ÎZlRÉq¥(ŒÀuØ2—|n³½òÆøy̧6»˜ËçàýBõOA(‚¯ÔkW25émP²Ú?hôµ/šöºI³2š&FB Ñ|[ÍJ ‡?žÝ0QÚ+BUÈçù»Tµ¯Çõ»k\¹>æÅ&÷A(’˜%—±,öù”ðùBçqŒùS!FgbD…UVª+hð÷ìNzêã¶ó¼xÞYž`"øa5N#pê_²šÖ§£ÚÙÁ [þ‡â^׎êWª~²?Ôwgöó,`ð1 bt¶°ˆ¬&V6”:)Ž^&idðÐhÀ—K ¦‚QáýÀf„»–©o&‘bfH‰B béøý cb*wk˜fÙ;º´ES7—ÇaZçðkRÓgªòØ=Õgv¯Q'^Qw—µê¬6½é^ͽ¦õó ×i²¶{A¶®fŠZ•5@BVU—ëüþÃø8¹êæx¿·žùŸÙ“DŒÐåhäÑ ãZ€ÁìA×”$†ýIÔ–Úž™S!% v™kë\ùªDà$Lt 7ï:(ND:<ó]×wº>:0ަ\›þüj.0ù+’8‰ÓQ?c®Ó¡•®ÿïE«û‡êÙöQFÄŽyOý¢Ë?ÃNP³GnúÑÄA Q5ª J_] Ä5‹Mðöö Ey¬›®uB}BçŠBKÝpu*laør¦–qºÒ¯¶N?LýqæZ”Ø$Õì›Ì™™Œ'ôÀ;ƒHaÇîéXl²Ãá©_.íÑäÌer9âæ´Óv I|Ž–ê)Š–KX ùƒˆiQ‹VùÈ¢­{ËMë7à _å—è,Ȥf#Â,³M§c¤? ›§‘O1åÑuïN†B±•Õ«q.˜…!=)UY7Æh•m·j­„νáo¨J[üTÖ΃ e ]>›rôvgvÜiGw€ |I¿üC[x;˜»ði2gN©'«#±ÿq[?ú?Àß–" endstream endobj 1256 0 obj << /Length 1791 /Filter /FlateDecode >> stream xÚ­XÛŽÛ6}߯Ò‡Èh¬ˆu+ÒÛ6Ûn 4ë´IÐ2m«+“®$¯ã¿ï ‡”%¯lƒ"Øð¢!9—3‡C‡ÞÊ ½_®~œ]½¼‰3¯Š4J½ÙÒcaÄ<õ²4 ’8òf ïϣɇÙo/ox2ŒÓ,D¤šðÐø¨ÄF¶(}Ú3à€t°lj×M£ çhõëOb³­O^j_ÞD±—Ãâ”soʲ Í9íõÍdš„¡§7’zR=TV©º–fÖâÁ~k·²¬–UI#£üw¨4eaP$…3L{&áªÖsQ„)Áÿ/­R­[ñ¬©…Z=;]± [†6\+­½k/²ÐŠ"“„CD ÄÎEæ9IŒ|Æž÷Ý©S(†¦;ßÙ¯¢±k1—u-öûÚn-«ÆX2eq„,{Â$‹F¶vïJQ»‘ÝÆnÏ;ð‰þ6ú]¿z=»úçŠÁ²Ðc=ÔS–,ɼrsõîCè-à#ìÄEîíèÆãŒGÕÞÝÕ¡iò <=È'Ð/åÌKCD|lÕižðQ"²((ræ‚ô;Å$JÀ‰jAµÛÌe3acšÐKjÛÃf®k;9×;·=N;Pk“"ÇŸ€uÙMI^!XòÜDô’ž¡—$ƒ°°Ùÿ³l˦Úv¡ù|ÂöÀ„Ï!áO¼é¢Mx±Z\“¥Î—ìv÷ĬðõüoYÈã¨>N/½¡: ?öÎÒÎO§ze`;âÃEjQâd„=LÐ åZ4¢ì ¤föaÂtÓÍ$Iü’…åþu]ÓW§kD¹iR/âi1÷—$ÉÐZ¹xac>‰»µEA·Ö­´ÀéDÓUjE£}Õ­-`¨Yè.8g8Ü<Ì–¬¥ZuëÏD$‚(ÍE„ô‘#| =¯Ôl­ã«%âl‡Nä‰Í¶·­Xɧ_,OÑˑ»càîsÖäN•Åíž6N×&“W;¢÷ÏéûE=Oïß¡ã³h¥¿¶¯O™€Xà¬w nVŽœû礈|Qïä…Ä=ÿHÑk:z€zP? ¼ËS CðY§òG´y–{.¥íÛ¯0c6ÉÀåZU¥¨ëÃ$M|Lµ8í÷„AL(væz2e>q2 ;MíQ-4’ ±kC×(Ò5}»{[©R:ÛyCM¥À[H*·‡Mzøb%:ÙögNû{t@V@b¸•.ºð/Ƚfå¹î›G`Œ³€Ç=ÁUPô|Úâ•Ü>dƒ‹èÌƸ[¾4 àÄ?œù‹ª-wf/š6!å.¤XÅ™ÙÞí°„àÔ´;kP]SD=’D¥€^ã0óÕè¤ý€$­Ug«ƃ„cU¸ywɲ3¤Z@Q£M¼a²Ô”[D¹ÞF¢›0_Sw™¯›{Z`i·]ÀA7åþ­¢ï¦|¤.ز©”®õÊá.ÂgZïÔh [mèÓj é“8‡ò)D)Ù-+?ìã!ô(Æ/ÇjÌ…Óô õYæQá„L í~¦3<!c0áÀRç$:ò8Úâ`¸Öœhzn[“;°ZÏ1ëþŸ‹À'WáÚJU Xœ#™( ²¬3ÍkUjãÚ¯`ÈuP;Îm™g…¿rKSÒmlFUÛî̽ýýцÒ½£©ØšÎnJB 8…cëœmÄÐ(øP•V—= ˜…gIê ^lrZÅ&;Þ6¢Þ‹C{ðdH‹þA‚ejZZÃŽ]uÌHœ‹z·`r¤…»tkDG½ß@‘TËî9–R- ´â@¶WôH0ãR(¥í.ín»Õ˜7%nG—‘ç” ²Äº#µ*ð¦#7èÄú*޲ã]×Ҙ ¹ÝʦVb_L0œ2!™ë»ŸnoêÏÀºÞïדÄ?PŸ0Ô²«luCi·lBƒZë{rª{d y.®¯Þ~Ë¢˜ÿ€·NšùÒ¼˜ÍEc¸j–ÔÂé XèÖƒq³SŠˆ!&¡p#rE2I¹‰ˆhIà 5 -[õ|enG½÷qðvv3Íi­[w œ“ƒD<5F÷%¯°¥Ä‚×̦Ov³P[pw½CØlAú3ÇUp‡âsÈé22©µ–—ù[Q©g‹ç<ˆŽØÒk&’ãóac¯L.sôñ…' š³î3,1xh䣒‹žQ €NÇ®C}ö몴/‚ÊPïÃ0RòÒÓÂùû”jã'†9uwPJé…Ýt«+ós‡ [#T “¶h›‹òÞ~ÑÔ#ƒ§”ÛÿËONñ±ä6?e¼šö¿ÔxÓè{jØ û›Éh6úÒG§ïGÊÁký_e« endstream endobj 1168 0 obj << /Type /ObjStm /N 100 /First 972 /Length 1731 /Filter /FlateDecode >> stream xÚÍYIo[7¾ûWðØ\(r.A ÜhÀÉ¡­ãƒb¿$FÉì é¯ï7”x‘bÚ’Ú^¤Ñ{‡³ÏŠ1E\Œ‰œ$ûfW£}‹‹œA(> ƒÈê¨6hu¢dO‚ÓZŒˆ.«A®Ô²+‚F§ >±4Î`Dl¼¤l¼íƒ©1cPøØ˜a©$[PðVK£ð,“b‡HIeÁB°·bÛ:Pc+9"2~•Aå†IL‚ ¥8™\$4~”2ö€r¤ :ƒ¿£”¼Í±=—‚åf™jÀ¤jÀq •A™i Ì9@Pxv"0â¦v0…­ˆ XÛZr,¦(Åè8QÁ^Éq6£lÄ%cà‹¶GxYª=‚r\…lìZ‹Ù2I`èJ@™uˆ¢“hÖ@™u(;±õxÄ R[ N¸i¬°¶ɉ„h[`©H[Qj&“¤¶*I²ð½dm„¥Ùä´GEÌ$ ÅüLP*·ص–€`a ÔtM ²­€œ gÄ!q[‹g\?ØJÉd’ê4AYµG¥Y;jAò« ¥÷Üè?ÿBÏ?‹x…ó&g?ì<~üctJäsêñ5ô²V­>„k¼w§“S÷è‘íZàÀcmÙ. ˆéŶx;g¸k¡ k/~˜Ùá û~£³éáËáÔí»Ñ‹ç»nôjørê¾mõêëÉ€ãwÃÎè¶&§s+6m›ÑÞ0ŸžÍ‡ù¢µg¿GÇã§Ó/nßvÔªž/}©Øo<àc\àŸL&S0Ý_ÔJ«ÕÊs"^tAp#®IؘìŒ^ž½9m¿;ž|Ø=ÎŽ†Y“#Œ~ý:z¶ÛýJ#D=¡.R&Þ(ƒÁ×ZQªÈ£÷¤Yú¥ý<}5uðÔO{o'þÍx><|8žÏßM^ÿôúÁ³åf$ÊÑ«I$ ‰PŽkñÁJ°&¢Þ"ѧñ‡áÉáéñçáéñäèxòn³ÂqˆÞReÇGEýLŽMXñq¥hã¹ß;ûèßžM Ùt²9qP á-dºf/(n ï!à\„XLt‹­Ž†ã¯ÃÑ“-8ÑÂ)[}„=ÝÀ'B©ƒ9å•‚ _NfóËb´Â€Úû­0Ôº(P™½ Oݬ"—ÁU‚·þ² 4ºª/h½[A#**ÿŠêwµà].…« Ö sè’"yïRXêÍRXòÚ¥°Èy½+zA¤>RµŽmÎ6ÖyÂ(’"ùB«SùèëÄïçïý$Ý`a‘âs±Ab¡EsF b†Mˆ„’ÒJyþŸlPˆŠÖŒxdo›õ޲ßhYWe˜|¾‘³¥Ü!gËFeè¤è"hÕàsíå­¾à^4N>S'˜Ñ~“þߦ›º$¥ëÝRšÂ"¥/ v†Ä:î¾:SÐ:Û!kMíÔ×WÀß›Qð!¥­ 9a\€ÐèˆR©½hœ½tóŽ6ä…|÷Dø÷E¹!‘î!—Ú[£EÜTkv$µ gÁàPÓ“M`ùا“Ó¯m\½VÕ×bTóLB˜ê“/Ô®†<¾Kk±þœº þÖZH=ó6À)ÛqŠzÑÈVŽ`MªT{Ѽݯô¡ÓFì6ŸpðQR'šái»%Ú Ú|“{Ã'Híµ ÙÍC·+c…Mb\³‘m¼fÑÍNn7aëv5ºÃpw|ëp·*j–ÔN´FÌT’·‚–„üαÍ5{;¿t¢Å®ºzµ¤”ñÝ+7A˘ã–Í+{ïX•x3V¹®Ý_9Ÿ÷W.çŦ›:¹A;Ab„±K_A§KíB¿¹seg›ãÙáû‹N»Á£¤ QTûGã\ ì¢ð6&‹[ªãO'ÓÙé|ó#À·«Æ’|lÇxûƒ$Ae ±ZÔK¸CIº þÞç %)nP6ÒÒÞ½deî•[“¹U:Ñ’ËŠ®¶4Ìx½Z z7…^4Åâ«h':¢½äë·lÿ}7Ö›ÿØÓºN7û€ÂvV."f+Ø8«³V‚¿VßDŸçæ—“Ù0Ÿ_»ænžÒ;\ã^ß>5,C'„ kÚ Z û¢½’(Æë ½Z*$Ñ¥cê24ƒç¥ôÿPãL endstream endobj 1273 0 obj << /Length 1561 /Filter /FlateDecode >> stream xÚ­É®Û6ðî¯ÐC% f¸S*ÐCŠ,h´hãô’"Ó¶PYv%¹¯ùûíò‹‘Ãáì‹q°pðjõÓfõô%A‚Ie°Ùcĸ ”ÄH0l¶ÁûP—ÇáߟÎi¥Ë&ú¸yýô%Sƒ[¤b iÑ93(+ìy±Yýµ"â€ôô)GŒ‰ ;®ÞÄÁ_p”ÄÁƒE=œQÎ.‚·«ß:zÓÕ AÙP‚‘ä$PXEÕ 1 » ò«ÑUŠ’˜´¢¼ÒM´¦‡p3b*4·í·WI^E\„§òµ¥»(­L" ÚÒZ©˜\0”ñÖ4ÏuUù¹ÉOåH¬é:1#̾&1RÔSú@©˜hf¤ÔqÙ™¸Wæ,0ü“¯Ť»RéæR•5¨‹°9hx‹X¸Ó©Ó§Û<íå±CË7 Ï –ìpò£—¥E¡·~È›ÃuÁ"¢½X:ƒÿè–%9 €´{è ÞK¸¯Òr;óÊ«k $«”±ô:½éuãžM†FÆ4äÁß8P ö6oÒ¼xÄâFs¬Å¯uZe g }T§ËþÐ~h8½xГ:Wàrˆ2éágžÐ!­=ÿð‡â Ú-øûL*½Gèã¹ùò ¤ t-`DJ—Ü£ÁšI†œ,æDšjßiÒ)Ÿÿ§€«‹8…bªfÇpìÕ@‘׃ ´ì áÿø£,Ìˬ¸lór?!`õæÁqÄ¢hÍcny=}+÷*óŽ}<=Úˆ¿½Ôæ½›- þFêÈкŞ<ÜÔ¹*rÌ(J±¤c3½ÕÚñæ"€Zg6ßÚ—w'UDq¤pÒ¥žò «¼IËL/ÕNЈêQoŠåt ü-rƒ„IŸ8¿„k'Èö”]ŒS#òŒëÏš(åŒG%”W¯žwuº×–ž+îMb_ÈRI1)}-°Í|f±i»FëwPŽÐH+?¼¸¦ %„Ì“×Í´‹Ô¸ïs_œ>§Åf lç¥.FØ¿¼{ófÆÏb8ÿŸ RÃØz±7œºgUDàþ¥o]¾Ýpyœ2e¸sÓgå¤j3Ç#‰píIŒJWyû››6pËËñ³®|Üîܺץ®¬Ïû8hNþÀ¯—óÌù °fº?¦ð¼b2 ÓÆ¶UO9ÍZ7'`n-ë¹Þs¦—ÂVÓ Nš–ºs•Å—<È÷Õa~ö ŸB ž·h°i²½Y8°ð`ùøÒî¹Åpz¶¥Ä|e§r›û E¼>y:zuºÓj6î.Þä;ïCÙ—¬ø&#új4ë>`Œ¥ýŒÙÄT‘8ïG¶±÷'dù‡H’‚ß5ñÂ+ýaò£%þYëÒA[}®t–6vÂïÜïWEêÊ! ¡GØv¶ÇºŠ SÅ(»?åÀÜš€³ :ÎŽ?/gï€õØïZîĈ#Œné8_ü“!»Ô·O 1“¼sð_êi}çÚ_ûûœl:7@[P öëCßlØŸ^Ú£I€ÿЕ_ JI–òÀõfÛ¶÷ L`sÈÞ¯Õ„;×MÜÀÛÐíÆœÅsß¼Î×L­/6«×T¯ endstream endobj 1291 0 obj << /Length 1454 /Filter /FlateDecode >> stream xÚµWÝoÛ6÷_!`/6P±)ê#ØR¬6ä¡k]ì!-Y¦mn2åêÃ^þûÝ‘”,ÉŠ“a‚@$}w¼Ïß=gëxÎ/³wËÙÛ;9 IB:Ëã{aAèD¡G8£Îrí<̃`ñuùÛÛ»€÷(Yȉ—Ä GÓµ¼ùñ±Q+©ÖH?óì-oï(sb` dtYiN—F(Íðÿ°p¹çÍß=™ïZlÒ&¯ß˜PÇÇCZ Uñ¸ÿ¾9/EÝ”ª2›z'ÌÂPvœ²,Ô¾;(6gjPt}$<¨‘5eOÆ1Í›´–…2ûM™î1ë_­¸,Ís±6ëÔòÕÅÁÍÅQäf‹ªw:nób•æW4З ¥oFÖmŠõIâÇc–;Y âj6íá¾hUÝ¥jm3à´êÒ·'Yï¤=O­C•apÚˆ¨Öa þJ„Á‚±k…Êò¢j:¿]ËÁÕCsLVŠõ•ÛÑo•T™•#G™Lå‹Û'ó#1 sÜàêÝÎÊkqߨ!y%ê6ð­õÚ¼L§7}ïZæÉ»ä¸$„9Ïä–£ÆÙ6{¿œ}›ù ÆsüºxĈ'N¶Ÿ=|õœ5ü7ˆsÒ¤{'ð} Ö¹óiö{‡Tã¯ÆG¯>‚¾aà;œss¿W¥„@ a/ «OIû-^~(,š‹º~r «K9¤´2_‹¦²\|nSðyƒFBNÿÁøÃ àç` _­äÏ¢ÊJyÐ)Ö7ílâ°y¦û COSöh6±ºq|F £¸”Ï‹ ÇJùèÁˆ°ÇðGb§Ü:íò£&ÂKòt%ò1·ñêÚ¨¡KGëcëªc#C>LÌÂu]«?v$–#Ù]ìZèÀCƒE/è_d-|°]6F;ÿe§A<¼9vdh•Ù!|â·n¾P±Öšƒ¥,Ì—zCyX‡€º41wù|þdtëÁ…Ž;b7nª&Ë`›[¢¦Â&¦‹A‰±‹µ…ryž–77õÓA·¬¼Ý( ݘaüº\¼?ç¶wNIÜmE‹æópÿÕUj3d€U.ó r$„Å9>WéVL‚Ô%h ½­xæ¦ ÙnùSo)§&Ÿ±Š(VëgÅÞ–hþ¶Á «®êù²~£63¨ƒAÛâ¹U“%YO=:/Jók±úSdu‹ ©]e©e^ÙbÎ #Å$WÖ-:¤ê œ¬ž®¤ûÈb¤ë“Ûó¼ÑµýgL³Îtò|ä`"bÿï„@YB|ž“jòetmDø(ö&ÍQLÕÌÆÌûÿ08P É.ü.ƒƒŸ@;g¯^,Aã­+`Rƒ¤õ•4¢Øvá(dÝra0üýêŒ#¶ðü²=>Žuy6û윂.Køü^è›èuðf!íß´K«+FSË8æúõ€&Ë­‚‡ÔÐñyÔŠ^iºz‡S˜¾(öƒQ:ŸŒÛÆÞïç4µ€4žÁ‡Œ·4PþZ<ÿtOƒ' :–ŸD=qC¡Ý RAw–õÄ- ý×’]J‚j¤A'iùñóû 10‚~_Ži>e MËè]`/=©©B”êr¦a`E¦Zõa<ö‰ïÚÇÎEôr#³¯,µ¯ìªõzŸíîöþÓû‹"h¿2ÿjöœu endstream endobj 1304 0 obj << /Length 1373 /Filter /FlateDecode >> stream xÚ­XmoÛ6þî_¡d&+‰¢^ŠíC·%ÆbÀRwÅÐ-Ó‘V™rE:NÿýŽ"©JŠìÅC |ùÜsÇãÝÑsïί‹Ÿ–‹71qr”'Qâ,7Nlj“&"8r–kç½Ë¼ˆ¸ê­ïV´eÞÇåï/np:Ø!J3@ívÄD-YF¬Mk}³ØR5§·¼j½0pï÷[ƥힶ/n"<¤¬€”B«Ùò‡©ð!Ñ4AyY¢¯¸çG$€M^¸UÛpEMF}ᇠ²Xñ­8CªZ”´¥…d­>x!qY!3..iÅ+~¯Ç²dºÃé– Ým6“o«Š¯a‡ù,ݶlÛ(t-â íˆ&\ñ’µ•|¾†ïJ”Ú1‹ºi>éÞÆê8¦[ñ‰6;p6.gH ã…#ÏÊcMG(µ:.yyž»g³^5Q£÷¦To^Z*ßí “fõ“?²]’¢4O¬ Œ#N¤(Ʊ]s¨dið¥1¢)**ÙzVo=¹mÖÕ‡ ˆì"k¹]M vÕÏuEµª¿x qg-#‹]?Òí®f§¯áÈ2LbkÀ0Gij¬5•ÔóI¸?øºLÞu.ü! ¨®„TÝšI¸ j6¼Ò+3Š ˆº('yoà;å@j3ô­…Ôprqq¡;ŠÉ)¨’ŠÓH3t¢å6ð|§W)¨=·¼ºÅݼºƒêÞªõû—ÇÈ|E8‹Ï7Ó)éô®sSÕ³‘ ü¨›åíÛkg¿Ì*ktkï¶±Y¯çT14¨8°ºžµÜÓº[QVõú$(Íÿxûúµ¡ºiš‘—ôò„%O`j¡ÇPW§PÇÇl .ãòê´¹Ÿwæÿpq½\|^„€8a_à4G øD±]¼ÿ8kø¢Î3çÐ-Ý:q9=ÆÐ¯7‹?†‹®æ'pP ‰C'!J"›ÅµÆ ÖÄ£XFîCL¯aϧ‰£6µ{Qà>îZ§.¢jø8dÒi àÅÄ5±ö¸AâÂe~ŽA:ÅG±·S+3{a¢h«T<çÂï“ õFÒUÍf²Q0Îá½Eû°ô49HNiŸÄ+•‘’Ü¥ªÉ }«ðY êצ*TE­×éAkL ]u;7{^ ‚?”9í½c»·O‹º8B¨&+*ØË—Jƒ!ùc9œ@úIû4Œ<'‰»ôR8ã¢äUAkUžLq³Û‘º¹+¼Ð­TÔÃCKw~wåÀ[rDÀ¬>œ[NŒywªÚÁ8viÛìùZ÷»BFu~ÖÍÐSƒ¤/ n7wSu§wŒ2 ´$IäþíÁmr›½wÏ8k;m»áºáß{aæJ=äŒYšj‰»s~Æ!Ê2Ü—5Ïñ£ …Q¿£âB2jdO<ác‚Q–Gc“þ‡¢heÄ»¿ueTžº[Ú]ð!ûíÞÎ*OžÿxV·v³«}ó ;P¹ùü—õYïùþ¹6ûj²)ÿPVEyšçÄÆ*¢YC¡ð/ ob endstream endobj 1315 0 obj << /Length 2221 /Filter /FlateDecode >> stream xÚXK“㸠¾Ï¯pukWµ5z?¦’Ãne&•g½µ‡lj¢¶é63²ä©v;©ü÷P/ÓžÞ=t ¢H>|í/žþâoï~ؼ{ÿ)Ê…W¤aºØìï{Qœ.²Ô÷’(\lv‹.ãtõ¯Í?ÞŠ“ÑÌ(‹¼$È@™#Va²|Áeõå©l.yçóF°K:Z»¶‹×a†ƒ¤â¯B—²R“…#3óÅ:ȽU<ëIlËN :WUÇ…çÇý±^ø8¿ø‰­˜“¤^$vŶ¥¼{SW+±û¶< ;FO}àmYU| ]n¿Ò‚óA€Jå0uú‰—ÖAàÖhòk£ÐK“èÊÚ0Ë–ú¼ üeƒ/9Ù©á%ÉBUbÛÔ;šÞìéy>Èí>J«Ê.'·«Ð_®Uw:URðZQ¯bù"Û¦>ŠZÓ\»˜]„CvÞO¸!ã'çeÞjæÑòç,|ÅËKÓ‘`v¾  àäb$ËW©´¬Ÿi„75çÆáJÝ8"&…å©õæS©Ä‡ß@ Ð÷{¸hŒ.m{–}Üë‰Gl@øì¡—Áôð%˜§Nø4¾âÄ‚ÇÎR&_Ó¥¢ó‚dâäè«`iüšùòGÔµV¢VRKÊuð UÐÕ[-›º7ĸ,Ø -¶zØâOO ›Ó±Qˆ€Ä'HÁSS>£H'+"pÅÏ«Ü_òJ–Ùì1 u%ÚDã#VÀ×v ʲH+€„úÁëML½ ŒÉÄ#…— ð@§V«˜ƒã ¬éÉ í/Ë­îÊŠä>ñýk€á É eö/:µ Bn­y„Ú–zØrß´\Fià¥Åï"±ØËŠžö>LHx±ŽýÈó£Ç æë_Â0™±üĈ܋ÓÜjl…îÚúŽqäÅCZ`pMIF %é<¶H%øŽO‹âäŠ]­×‡RÓ÷£|>°øÄÊŸ¤º¶•VíNˆÓtʘkgr’&@§dºâÕ÷¡.ID\,M¹a¹¤GÕ ˜P"ç ì³•8ÚÕgYïxͱ«´„ñÑqòÄô á€ömÈn–±ÂË¢â­JÕEyè£{V^>€œKl6"?]>‹Z´ àB¯†ûQ ¤ô³¾ØÁ˜¬ÕIl‰üñ}(OŽ*€dq<Ëa0÷õõõ~jI|⨠vr  ¸ÓÃmÓ¶Tƒ¡õ®Z,¾~À4bñSÉ£¬Ê–^ 51ÏCƒŸíVv®¾œÓ=ÉVSrÓÐ2.‰ÈEidȧÂa¢H”$/ ¶µ‘d+-ˆ¶é6Sí¾Uùß‹sfTš`ÌúMO‡sc¶¼ëh+À7A¾|LzbM¸Ò¢ð$÷§R)s,˶éêí†nKÛoHÓ‘—†°'ÞFÆ…qc¼P$@Í~$O$+¹ãQsrxj;mÜœÐwFPj~gIÏ Cû’.•ÝÕ¸$ÉO÷wè,~ÛaL{a2t½p‡øêØîvyÜÏrö)±0êI¢¯Ú¥úÞt¸‘Í/ªC€ìØÏf¡Q½âVo?´Ž6ÚØKþ^2q7 ñôüÚj51 ~LõßWªqÞ[}øï{ù¢ÅW?_Ñy›GÁÕrw÷ÖU¢7¡öÞh„é"€Ò®Ô|Þc©¸.-îíÕµ|:¼@5­vºËlOnávùµ„6U¨™_ìÁ9èƒ[Wn’œtý ÐwÀÝ Ÿ›ö«"ñ?Þ!PªäWA’ã:FãO5t‚¡|á5È¥ø¤‹qÏ,¾!αI&{­mÖÃæ½5ö¼K«DµÿàÒ69x]aß4hîc¯‘éý/ôx€e8ÍBu3Í7u€!@vr¿moéü(#b¢#—õxx4þw}Çc[»Ú¶»(SO6qèðKÓâEðZLgóÔlà¨\o¥ˆ˜Ð(àõuÃÖ½MTÏŒuTÏPÄÃKOðÙûêf‘e²%ñGè3 ñ¬¿ä|×3â0%öâ¡}áºfX¸s>Ö4ºÔõÄr£ÐlìQöMU5gsU ê*^Í·ˆÞ—ä¶¶mxÈpÇÏAá<Ÿ¦ÿyMÏôÃñ ~…ìyÖð’iŽÜ[ä2ó¶X £¼æ¡æÔ³­ä”,æ€~»îvb~x;Xï!Œ†q þö·RWª9x{ëóËܪ‹W¸ÔR?cÈJ›rÆå©”ÕÀ˜˫烬Ä›Ï?}¬ýŸYèÎÜÄ]¯4ßáþ~¾;;No@ÁÑ\Ïî6ìµ³pí<üLòÍ]w·1ô€™›¿_Oææ<öú³Ðލ[jµy8zÛ A@»J;©q_O‰Ñ¦ Â×°Ó¾~åU,\ÑO¯ #±ûp›ôy„—Ùf.ƤŸ›¯l¡v¿ŒJÜÀ3+®®öùqóî7¡´aÆ endstream endobj 1328 0 obj << /Length 1870 /Filter /FlateDecode >> stream xÚXÛnÜF }߯ЇÊ@v2W]‚ö!E“¢EÐ6ƒ>$E kg½jÖÒv¤µký÷’Ñ,iåØ.D³s!9ä!Ç<ºŒxôÃê»óÕó×ÚD9Ë™DçÛHpΔN¢4áÌ(o¢±=“&¾ÆÿŠý§®ÚÜžýqþÓó×*Ô\°4©þ„NqËŠ=Ï_Ke°7Ѹw­2…›×2Åótä_<»×‚³Üä4yUm6{{¶6œÇ߬é»=ÖeW5õGn¸½D[ ZüÇKAUéTÒÆÚÃèÄ3Ú^³u÷ÉÖ׸ˆr¼,²^²E?1(ô¿HÛCˆíß7û×±é,Ê<ˆšm]qeOpÏÐݹˆ£Ä%Z+ËEJ“_‘€ß«n7uˆz$AÅM¸·MCßKÛÑ Û…ÀcËÎn¯úºrM}–½X2„lpû¢¾|ñb¬TL`f˜ß¥EGakø(µf„yÛ¯iÇ$X5Ó™ê7´$¬n榔EF7ƒc.`Žöž!»Ö:gJ˜%ë&G¼]«Wç«¿VðH éiTβDDåÕêÃ<ÚÀ"x€©<‹nüÖ«H HHÈ÷Ñ»ÕÛ!ç_Ï`ñˆW¢EdÀŸ©ÉFaÔçþ(±u:9)Yž‰Þ[¯à̱èÀ1Òð¸¨é lÂcŒm•ƶm!Mhž‡#ˆóöÖû³À1mâ¦nŽáT{<×}ÁUÄÕ®*êŽ&šm@ÿX¹Ë¨þöÃüúf&7½äÓ žÀUŽ”yÖçœ×hÑu§Ï?Àˆò£q‘ ñaóžäüé3ÁãÆ}fpñ¹ŒßTŸqbÉ"çP^†¤ƒŸa^«D±Ì`>˜$x+žÆEYÚC×â,>¶ÖÑô¦èа¡ _w&²øòˆüu&ãßwÖYX_@˜j¦xþH„ ²J›Ûêê°¿%¥+êvÛ¸«Âû‘Þá뚀¯¦[ŸiTûlmÊ$d>yÄ¡¢G…zÎR5h†OµÆ» àú2X]“ÕÁS“°2 ØeêîÉ"ðŸ¿Wl›ýžrÉË÷S¶èŽÎ¶/&h#¡tvk©Y’ÿ(¥™1Õ’›¢¾|½õ,lÛ©XoªÌÍÝ2D ’ ä˜ÆÂ »³‡Õ ¤üc ­Ü†&×Ã~_`f–AÉÛ…ð”Ð=r9 ‘ÓÀÀ^ c~D-X-ö•Ý@‹"…Ž›‹?¡iÃ%ä 3 hr þò¸êk¸>˜ò×ççŠ=2‘ç§â¶¥Õ]6_£7ÂIðIi7¶.-íhp6¸™*€aßI®•HãŠYd™”ß­z¨‘9C¸{rÉÐ ê$ EIþŸàùÕù½<ÈŒ‹÷ 4Ìóï;Œd|¯Hn£{URz3äk_õûŒ…~óAùØw,±7Óz`9vÒÔwÔaסwH(–UÝvÅÞç’3…ÛÀãã:ƒwÊÉÚ5Ígd}¿u Ÿt 2É‘™$’³[¨W>>qYÚ}̤Øãî!Ðc"žô$†‚¬eeÐ¥ú.3CópÚ–ë§Ò ö«ùÃ32}V­U’Åç;ÛZ¢È&¦¡™¸ôîe*â½íüHÆ·Í‘¦.,M ÜW%<\).šcG‹7ØÐ,%ãœKßßÂ\_?l^ô ÝÎïÎ5.@©¶3 »¥Ò |Ó.BÝÔkÂ[µ]¢á#l¡DCñòוּ‚„ÕáYø¾-.íb<ÿž„Æ´Iž´£+e޾¥ÏÏïß¼y6<'K©Ö-½êç¦ f„¶ï¥C§¸h¿hÎCfà ç íô9y6ÝËám4®ž4׸ñ«(ð·¿YzL»fËNÿî2²6(<6úty$P¬>ª§%!©=÷´›{¤¸ZÃÔ††{àHúѯSÑ+;ømŒ/ y¿ÜwÖÕÐ7‘E¸ºÜÄÄAx1×ê/Ì•Ðew½Æ§õ€³txj˜*è̇.£qW /es×ÄÔö扊5<´FÍg&“ø—Ðͬ5”Àª^"Êîý!žÔLÈ'§m >¸ªqUwK¿&M µQ‰VL_SÝ®iCä.ƒL“»Ûbí|­G6+ÈÔwÖÎ:äÖ–Ý;=ñšž?p„>†"öåTÒ°$Ëgsö¸T9'Dj¡N?~ñfW•;RNË“œ^ª§F1Á‡æ¢'›¹Ç`(ÍÄcXæ|Ù¿WXôâÂAUÙÿáü1Ï•œæÍvFRáÙraËâØŽnâä–~M+¬WA Uºz±UmÙ"-¿:_ý°fÄ endstream endobj 1337 0 obj << /Length 1685 /Filter /FlateDecode >> stream xÚ¥XYÛ6~ϯp6µ5CQ§ƒ¶A‚f{ HÒt‹<$Á‚kSk5²äèX¯Qô¿w†r%YÞEÅcf8Ç7ŸÌ'W>ùùÉëó'ÏÏüx²`‹HD“ótâqÎü šÄg¡/&ç«É§i̾œÿöü,;;ý8d^ä½GÍD8½Æ?2¿h²Õ<ᤴD³s{x.bœ4"~’œÍEȧYÍŠ«žˆŽ¨žÁ áLDQWˆ/"'^âi¥RUÕf¡)Ís]¢¹;³aYæí¦ eEÏ˿ղ©Íެ¨³•2ž~Ç!|&Ba=±B ô®ž¡°É‹c»i-g‚ƒ¿¼<§um«¬¬²fo”•¸b–m‰¦+õ™sQ¨•5mĬ¹"ˆÅdîyl†§âzÄ8/fqäŒûÌCŽ.‰¢áL›µ2ßÚ²n+zQÅ,€kdUYlTÑœÂìBL³Ô¬Êí6Ï–ò2kCÍæÇ§¿¦N •’մ߬˜PŒ9:ö˜Ç}k浬Ž]%²{F=ãAnÇÁ}ñ,»I+²‘üaÂ1æv߇—0é»ý¨­Þg«n«l§¦†Ðâz, Ý­ÔͶ¿zà9ÚÒA¡P:‡2ý<¾'*c&šœ‚E\×’tÙ‚xqú^÷üjDÁâÖ–yÈùôû¹yž4kL6–…zy‚¢A\/T:z§p†¥•Ü`s'ôó¨Ô§OÞÑt³–MGÅ©ûXøßªí亩 \¾$…f:¼Q’^ÊôPŠðò!3d—²V/^`á9;}ù…C|lç>ܪM‘Š`¬—8g1 *ZÎ6Û\™É.Ïj%ôÕ0ô¦ÕcÜÄ‹‹¸S؃…#&† ã‰ËÓv=Z±/Ûïf`cHž}E§)³¨9¦ à@YQ¢@¿Ô½¸LèoÀ!U×`¾-ìÓ”B¯w=cÖ–rÛ€º•ÙØk濵²ÎÀ–F§€Y%;ñŠI8Í3«Éœ¨Ô²Ü@Å­Œ°Ä\6´£‰ca;zDâ &ŽÍ\:„55h)Ä.Ës3²”ïi¶©Fú™d÷üüÖl µ\µÅ®Úi| ïEbÑ!­0§½h þ±dRa}›á‡Ã2Lx®‚@ÒÅ•j.¨•:_û>‰ãÞí·A©jcDQ’ÅW­¬dѨÁUŽ Ãdæ™§u•:@è~™Ñ× øRXìƒ àðáý+LoÙdWëÆ /éÅeeÞ [áÐ~‡Ö‘„3œ1%%4ÈÊb©t¥ùV7¢Yž›.*sa½#ôÆYÐ]±¬¾ZÈ3ø˜Ø[04¼–Å}x/TÝØ‚¶n{£†Íþ½¶_¤w0µ›p³›þqÇÎnŽq&MÓ{g†Yxx4ºíøã'‹ë»uRC –zê#c‹ÏÌÑDãö¡žž_Qa‡Jæªi7îbÎ$ÿLf9ñz‡;š§æI„Þ&9“áÑF=}JáX×Å;¹ÌïYj¿zöË\¦â-· ƒª\ÚÞÈPˆq‚‹àH~y%)¡Ìñ˜·àºÉàs@¿ÌäègÇ&Ñ}¬>(½¤KhPàJA5.%8›áO|ú>Wƒ‚‹KhûMÕ.›¾etG}\sH!…4£Ç¡¶_„·¸[¨Ý ½@y‚í€Åîô(G €ôs˜ê÷OE±}•×åhhY?þ£…¿¨ÕØà²Ÿ-“OZUjÉŒCÂZ}A˜—k̿ꃢ۩¨#<ä•f^öšßÉ ³Ñk½9òœá= endstream endobj 1346 0 obj << /Length 1241 /Filter /FlateDecode >> stream xÚ½XmoÛ6þî_¡¦)1«W[ ¶í ºk=ìCWt²DÇD$R¥8Á°ÿ¾£HÊ¢,)YôCb‚:ïž{îE²­k˶~š½[ÍÞ\ú¡há.¬ÕÆrlyþÂZ.lx®µJ­Ï'øÔ NîÅ?œœ~YýòæÒ[vÎø¶ƒ–!(l„ýHˆÌluÈ.:²s%Š„™ cúÔ¾ë ÈQžjÅóѳ]„û‚]e ¶wL1N\Tj-Ò¸R«<æ7mäoy]ç˜VçC1ÙÔˆd„W-rë{…ëo?~¼ZuÀ1Ÿ¯®~}»º:šòX;{¶·ûÉœñ\.—V?Såzš’ H=Éé­Š×EÁJ솕-Cx É1HÕdÖ×C 75MĽâ"ñôlŸeû{ÿnŠä]šJáFS¦°õŸøòChÍnûgˆ­_BÙ‡ßß¿WÚRŒY`ê¸ý¬C 'Òq S>á„Ñ4{˜Œ:¡¼Š³ŒkÐTÉ%£¬¦m•‹u¦eÛÉeÍq©Ÿ³!§”!kÜÆ=# ÑŠÖ¬VËÝ—¸U$©C¨ªÉü!_³ìÞõPCb}ü,À¦w‡'’ëTÌ>8M+ÃÙFÃDèµl‘ÝíRТlÇÓ=ò/)b42ùa+ ,RMÓ›ÔÒ¬´€†Ÿpme…ua¸­ °j¤ŠA ­Égá / û™Ž2tÐ .KÝRu@kÚô£\Ãe5Fr½Ús nɰS‡S²˜&˜+ñKRòj‚sò:¼"vQà¶©ÇeF°®£@>ÚkåªÖ™@%%ŽaP@frMØÀë5ÇU5ý Dnè~ãàïÚ Høz¨Îƒ^ôd£Ž‡TtÆ ZjVà2®tÉõह´.IUéö»ÆI %G1ÑÏa&íá~hqÝ7ð(eX†2•Gc7õ’Õ×ÛÝ <­¸Y5Ú§xµXŒ.Húî.P4àø /5ºM©‡š®J‘ÛÇó»¼<¦bôaSødä5ŠC_‹è+ã RàŒÐ^NÆt’ nw[ÍV«)×Aƒ¶·Îp~fRΌȡeð'u)¢«ÛpÓË{¡¾sP€:=Y´êj#-5D²ÐTo›p½N¶$K_·šÇ-jýP¦Ðloé¢Fûˆ¤–é`K¦jsŠ¡»ãþû“8†(¢…ç<½T>'‡  •kŽã";ì5¼ý eMÏǦØýTüê‡W §îèñâ…çNç®xúò±··Ç46)¹W oï­R1°16*¡ š6ãnÇ;= Í.V³Û™…m9íw'pÑÒó­$Ÿ}þb[)<£aP­]#š[¾oø¾8³>Í~}‘o>>@`:Àõ…—y~çÅò^~tè|ð—Æ!EaK™ ¯Åì‹|?úÝdÂ-Ür¢ÿãÖ¿ÿpw endstream endobj 1357 0 obj << /Length 1698 /Filter /FlateDecode >> stream xÚ­XKÛ6¾ï¯Ðn±Û˜õVض›"=h✒`¡µ([…^¥Ýõ¥¿½3|H¢-»NQ°(Šœ÷|œ¡mm-ÛúíêçõÕ«·nhÅ$œÀZgµmâz6ñ]ÇZ§Ö§…o/¿¬õÖó'+]’€@G¬aKê/ž›–ß'}WßWIÉpÓ•­XŸ`²{¥·¯œ'%‘_ß´yÓåuelž1„¬HÉÝë]Η+Ç·Y_mñ¶©+Þµý¦S_“*•¶tüÅ#þ%EŸtLWÛ’¢£®–ú;®Á<"á >É*¹ÆÐ#±ç k–+—Ú‹w¤ºK¿îi Óµ|iÚ¼LÚ½|é9㯠K€Â±MßÃq]_’þì8¾¹îÓÊ·íÅz Ê®+}p”ÈÇh%|{Ê»úÜ.i´Øö%«Ðd8Å»ºe©ç¸!°5•"ç}¶};Ïä¸Û±9&iÍxõÉ«=¼ošºí”ìð#‘Õ¢ rø^h"vî!¤ò .´"âèzJb_ ­ATÓ(U6ÿÐù†)sïÔ@JŽ£:Sž75Ç)i]__“_hA|r©#ÌÀR™Ã´ËÍÐÕvÇq^á9J/ì>Æú_!ÿqô:.Œ£H‡f™4H-6Æ„±=„ú«3Î:àâgØV$MSì§\N¥5ˆùTï›Èt ¸åÈE¬ýÈ“-›EŽc$9HfIØ3Û ¤Õ/—„=bÕ£ý(èNÖÞôVî”ÈÈe"ím‹y¯£íœÔç¥UØsÊœažv´9oÍ0{© ‹>â2æLh8Í«-9àjȸRl§ÉF¼\Ð7g1aŠÓœÿI x{œÈè8ƒâ6 ¸K¿ ÆÏ©íÀø¡©7†ÌÅŠßUKÏ^<æm]¡øˆ“T‚.<Ÿvùf'‡]-Ÿ‡§˜úºS O@Á€:ê€dryÐŃZVÖ\±‚C'ëÕW€óìˆ]Ò;²‹0†ÃÍ4à½rm‡Ð80ñ[FÔA4Hm†åppò1hð/foÍÿá’Õ7§tÏ–Lë Ôœ•ù;¹ä—ºl’–)kùLk"Ïg|É;ù”é"üS«)¬rˤËqñ^­®Š¼bš}Ó2ÎA nlJWš­u±ñQfq:.dNågÓìÔž[tœ(ÑI “+r?(jʈÏÎÜ¢ïåÃù·ÃP¸,&•Ñ6î˜q¡f5FIΕ2žo+mOmï-«X+ÀßÀW]·7ƒo´?àŠÌÄ&žó9-”LI…t ÏuppÆI,‘ñ¹¯û‘‡ÒxN„n—tzaÓõ-ã!ƒû_Ï ”™¾OsÞÈÑßjã¾8‹E©ó3SÏ4éÌÄ.»MÒ{)4,òîPãŠid1­’¦®º¶V–¨õô ¦vÙ$3^Žtòûö©¨þmÐIB/†“l\âp\¨Å¡p²ï•|Ÿøž3ëí¡¹4Dj9+²£Ð)-ûÚç}6-,©¶FTìIÅQ5V§ãNv*Ò4-á:ôµ^y•³Ù Fß%½ÀýF –á6‘Û%þ__O£I×Ë“)UJËán}õõŠŠâ·uH@=kS^}úb[)|æÄ#ëI,--ª‹ÐCçÖ‡«?Oïâ Ä, A…Àf±O‚xèÎ]mxFµÂÅË9Þ·K7\ íg¢ú¶± ,ؤPšÑS]*|6^µ¢êŒÑíëÈÅLO›F.ñâø[L(o‹‚™Û" ýØÿx‰ãB¾çcwŒSN XžaË”ôE''PIµ‘§úJj.&'–…O€®´¬£o.pB|€}‰5ZÕ•íµ¨HÈïO-T¬U> stream xÚ½ZKs7¾óWà_@t7—ËUy”“­Ú­JÉ>ì®âmWdR‘(¯•_¿_ƒ…2Ii(s°Ø3l~|ø4qqŠ.&ûTWÙ>ñ ‚FGÿ8³“`B*.Fû*U§ÕçರÓ\Iq‚ÑÕPÅ쪪iàOd&x B“0I5 ¨Øˆb‹(t«Ì– ‹-€w’l„mR6+S³Ù&È6|QÙ¦*Ùqh#JqÌ`.9µÙ±e– ] ø;«K5xyõ!¡únÇ 2ºƒÉ§?_.Þ¿î–îÔMþá•›¾é¾,Ýݺon.:|1ûµ›L¿‡ Ý|ye`c˜x2™žtW‹ëË÷]{G«wÿêÎ>ξ[|q§¶¼Või%’/õ-Ö›]b+ýÛ9¾Ï˜ôtœfVΕW[øÊž6d2}}ýnÙžÿùqþûdúÝâò¬»l«†·ÓŸ¦ÿ˜~JíÁ }-¢„|Àº‰Ô'$¢ÂåÀà”W¨}Û|üÚM\¼Y8Ä蛓sß}ºXÞø“ësßÍ??3¯b p×  P³úŒr®zÆ¢%ùÄu·9óÏ͘ùìS7ž5¬Áb¨ ŸÀ2(… 8AîêCƬÛвh—Õµ¶¤ÎY< oK ¬+÷%9z@àQ´¼[Ë‘´á3¼Kñ:wTõÇÐ0m†ß+ñPm…·Ô6mªÙ3ë.€ºIëhu“Ö`èt=“*mbR©cHÓ ŠŠöBê…Ü eL”"…lS½1g+Pˆ¯Ó£¨p>{× )jXÅv–ådéX=ÇÇ­Y¼ÿ}*â©–ÝÇ Ê¡+Ëg75AqšXW~¼&¶ikÒ¡sG´A’Õ…?9[¸lf §ƒ³…W6¶[«[{Az!ö‚Ž™ZÌ ·~²ÏdKðÑø®T¯©>p<A}p ÑgUÒëK0Ή.ý{fW-ÓÏfËY>Í®Fd¾oØõˆ€l¶›.KÝÁkÝ$s~Õù“³ÙÕoþ¬ûp}ÕÁ"Vtš+ƒ* ’¼ßMÆ›ƒÆ¼CÕ±Kpth 8%ìÚ7±ÏÜè7X+ØòÊ(A?×.Ê1jÞýïa«XqÞ5וÿºvðÑ1”í8ØzE±U›³1÷¡s3!ñ9xé°ë"t‚+yœEgé¡Xz(–8*£h€´@8ö ~)Þðtiwÿq½h9z×Å~¹¸³§¦vNáš«S3É®õ3üU(¡QhMÖ ‡‹Á~Ÿ `–<„?,%-i’^W~œmÓÖ€g+ÉÞ¦Í$¾&¨m­g“6=¹cÚ,Æ÷*FY™zoÓQ÷ˆUÔ}bµM›”}EÝ }X‹3öOG8 7ã¢ú¤¸¬ƒ¤ö Vk/ôTV{üÔ?uTü´›ÙŒs>UðݽdF[-a77;»™÷Ü »Ÿ™%pÃhÿ‘ü£Ø3˜µèßnNDrVx<¥èCµ¬ ªö‹±úv_hŸÏ..ÎoƤŠvØ/åðFv,ÖF§vÑCô÷»nÐö?IÈ+23š´ŸßÙGÍ»{j´Çøù¯TŸ@>ú³MPt±ÔG϶ž|mMÃ(Ýç`Ó½¶mÚÉà/Öù7T[á‡H4P›A¥Ðý¥ýšµ endstream endobj 1373 0 obj << /Length 1478 /Filter /FlateDecode >> stream xÚ­XYÛ6~÷¯PJuíC‚&ŠdÑ6ú×¢×B$ËѱÇK~{g8¤Vò‘¬‹Åb—×p8óÍÌGj¹wåqïÙ«åìù›HzËâ0ö–k/àœ‰(ö’˜3)Bo™{}=¤»k¾ÛN7»ùçåŸÏ߈d´-âKRÐiäe€"3nOÙx$»°Â‹0Á9Úò¡UWz²ëTûüM(ƃ¢ eqjM3Û/ªïê/[UéO\r3õl¾œû7EÞm¨û5Þ¾µ‹»Æøw° JŒCpü", :ë[_ï…3?<ɩڇ½c&CIª_6ó€ûW}¥·]ûCXÇ~0ÆKb–¥¡ ÜËù"”Ü/‹¶£^½¦Öe€nÛ¢Þ¶lOåÄ„…Õ¹$Ë"‹Áñ`C~×pÖJu:gó…(Þ©Û¢ê+²Æb;6#pŽYtŒ‹øÿ´‹g±(ö×ývÕ24ê6ª³=õ©[*+0…çXËiq3÷¯QF7ÝZ8µUEMÛ WÖ˜å¦h]¢ˤͦ‘u ÷«ÞDzÎ:)»~`®µvÇ…ãÌÿÄyØ8= ²5µÙêt唿“„B²8hbȉ=Èd&Ôôhè´2ê±f #1uwlÎù™Š5üƒjúÆåäëåìÛ,€MÜ Ž•QFGÞªš}ü̽!tLd©wcD+/¿ð{¥÷~ö÷I0D>%‚€Ö'V880ÐÁˆÄG.FÉd/–ÎÇ¿šy$ýz A¾õ[ð®ÓÖádŒêjCZV¦ØR«¨Y©]×7s‘ø:w”rL33G©v©@°T¤ç e™¬S¥ Eä º]5Å®sÇÒë$ø{ôúï¦(†,óUYb:O¡(iÞÕ^KC„¥(›a¢+ò;ê ªþ¨²WT¯(ºn€Ûpúá­›¯$°¯ë¦¢Á}D`à6’%v¯§ª†,=ÂÛºS—å~Xê5WžëþsP8B01¤œŒÊÝÕv º0bOÜ&”~v„"2Å Òu|žâ8eA’¹=•Úö ÀTDÞ¤-ò¯ˆ" “‰ ®bêbÚÚU˜Þ»ìh‘8—U£‰| ³Tf{äS6Z™ŠÌE gGm´¹1 6¡R—ðd:ÿ*Flþ³Hˆv™çSÑÔ[J>œ4µ íͦXm¨k93·»Š^C…¡À¥S?¥ió”2ö_ÝÑz®Gß`¦äú²CÔÒÐ=gâl‰$,arUš× BÉbM‹êZÜÚ(¢p2­Ê{ V=±Â1³›¡|­À؃’æ¦hõÑzË"Šé8±_ߪjWêöáe—‚Â8r;ܶ—÷Sª«—ÈoØ¡»Ô”vF̆òøª©7¾µÌÄp…â9GÞ_¡/h8@“Nî=|úaûä þµÊ~¡&Dõîwø„xƒtâÁ1ö7 …µ»Ò !7NÖîkµ& •î9¢Ð±ç–.Í7éF[¿îê~âR61g£®­eu¹ì2Ø4÷F»o²AY«âjc»ðTïT±CŒwÊ鳇;ùÅ1¡5 ýº öûƒÀ?¦hñõOt1dƽ—õ¶¼ÛC¿î‡ÿL sa¼§áÁ–ÆBv<#Zz”ž@Ê%Üê?É"e5kÕ8“ÝÔ®†^–Vƒ ”r…/†Åš^ GJàé^‘á‘gÅíûÉÀÙ;ôÑ{À-ð¡ñ7(â endstream endobj 1383 0 obj << /Length 1308 /Filter /FlateDecode >> stream xÚ•WKoã6¾ûW(é¡63Ôƒzí!Ew‹-¶‡Åºèa»h‰Š‰ê‘ÚØ(úß;|H–9È ><3œù†óq„G;¿­~Ù­nßû‘“ $ôBg—;.ÆÈB' 1"¾çì2çËšx›¯»ßoßd$é‡ Š0£EØÆ%ëcÓ>tÏ %¾ÂöÛ÷žïÄ JoëW)nÐö›-Áx}_ÕòÀZ³hº¶©3‹¼¶»LÁ+ÉÚæoL0ü\óf”µ]k™º Òš fH‹Zt-3äAa;>×jýwÉÄ·¸«,_çu=ø±z·[=­T©`Ç8ƒa;i¹úò;ü ÆŸÄγ-ÀuQ¨*œÏ«OGÌGMLPz#b—B¨Nx÷ÄÄ.1N0á4×CI<önCȺk!—QEdF¶ñ°"°­™úŠª}U™ZÎ çÖ!ð€Ô|ÿ{ 0.pp$(¾Ñ^ÿÊDÚòF×Î8Ö~tà’nÝE‰ÅæSÇ„’VµÒ3Ùù •ãá>ÇHÉŽr U­2yH„ |  x!1Å©&ý#0à{Pµ™)Ã`-À¡Â*ÙÂêF-’õó§³_òǃ4Ó½-»Bò­¢´ŽyȘYGSÑ’½9nÉÜ#„…$”=!–è;àʽö9&æ)Ò7Ä(åÆ]k:R[êL|¸áúƒ4òϘ²ýG˜å²bÿ*7jâTîë Ð*3‘Ò‚¶f.O  §$XïÕMí¤Q¥…¨­^š²FZ# Zt!ï*´p^@¯@¶À!*¶°Õ¡S¯Ëg–zØ«xÊŠ“™Ôˆ~õÌ„[)@LÐGÖ{;©„mŒõÑpPLìÅþS‰/ÖÀ|œSȬB¦Á«Õ„ø} ~wáB- .”‘ZÜô¯v¦r­¦?›!ÄíúÉ“??Tù(@T c0î[u½úWù5P.áŸ]Ÿ‘èäDÐåÄ^ î«ËiïS#[pa ö’[kxBG¯7{ó×&€û¤!V«¶D;GS»3ÐÆwya3óf7þ G^v¥½ü]¹gíÔ!›é1H@ÙÒT.@¿Æ9ÿÈs[Cé)-–KaÞÖÏ®>4‹¦ý¡fI[½ïÙúôû÷×O£Eo© QO÷,¥¶²=­Q&}hݲ®Êt ª––þì /™Ê‡ºrñîSW?,p“§zöÆ¿m< –ÓJöáT™eö€ ê„Ù3›h¤Íäò…NT_ ËÄ4¯ÃwGZ6oç¥óW…NNɉ&­òÎ~ uôÊgAߘ[NÉy+lŸÒFªïÓNËóWÄ+MºèöiÙÉá½»Ð.¾¥³žÒìÔ¶»ÜŽj‘»Ó‹~| ÔgÝEˆ +«Ò:3ß"/½ÛÿÖÚÜ endstream endobj 1394 0 obj << /Length 1544 /Filter /FlateDecode >> stream xÚ¥XmoÛ6þî_¡¶_d¬VER¯Á6 ÛšbC0¬]ú©-ZZ¦m­²èPR`Øß‘GÊ’âº)Šá‘:Þñ>w$z/ô^Î~¹ž=»Œb/ò„&ÞõÚ#a°(ñÒ$ bF½ë•÷Ösû·{õa¯Êº¿¿þãÙ%K³¢i&zÌ´Ê,´Nž]Ræe ›DZwÁ2¦•4Õó­m½âKQ½ ãð1GXT/C‡h[`gAI“ ÕŸÌqúòhPäõ mI4M)k÷E n:Ù «u(Û-Ƈƒµ‘4íùøuÆëwJ yœŸ À¸Ò­Ž`Åæp\âØ,G½bjï*W²Þ| ‹BVß7ÇÃ×µ–R7ÿš)t<ŒVJG–í z\ŒÆâ„¥ÿ\”Nköâzv3#`.ôHÏÑ8ƒ0¦^±›½}z+ø–gÞÁ¨î¼ˆ1#råý={ÕsrÚšD€m$,(‰ˆ§YÀX<@¦O‚ãt4•yF‹þ2ú k–b+æ4Ô 5g©t&Ê$ K¾%J L¹ŸÖ1KF\Øo¢)T¹oû)(SD4å³ É¦Xè u;5) q¤iâx Ñ3êïåœÆþA(”¦þò®Ï³ÁT+ÎÝTãm%ö\5⌿ü±|â¯lÐAŸf>¯Z¡jÞ–zŸum¨`¢ µÖRáèkì»"Ø'”þfêŵ0±!µIFƒ ªÆö'-‡ÊÝ^Im =ïDÝ6ÈŠÁ¨Â‘v+PXòÆJ¯±qKc?mžGX}Aò íF¿£4+½59ú»¡%ÑÕ@vªl ˜¢ü™§6ž_›9ZÊAÓ©^³·§¿ñ¢jUêò£»­´íV” EQÏ£Ðÿ\*YëÀƒù‚‘Èålµ’»~" ›J.yuÒ„­FQ’a6¥Ž<ˆÔ ;µT;^UwØ;lËÊhEǰÌ·„دdŽã©c«zÚOY£Ù®.o:«€(£¬) ür%rH["Ê–Weòa+ì(¬4f‰c×|áŸæÊK­Óc‹…)J¾N çþAÁ!bYWe­ÃcqæËå?¢hû/ØòzÓU\ag©xkiØå„%þ¥f¶TnRÓòº¢,KLjâpkòl#¬¦CÑâ¼ uÇøÈõ—X°îêÂÔ7(‰_ | iüE° NÔ”¡©¥}Ý~éÿä‚MO¨IÊ û’ÞˆQ2~M)‚öHèT%"¥{)¾l. ¬ùÖé {ªäê) Ô ìêç£yGh±¦ R(#XVb­=ò®jïW•fR{ ¹rô’vD Þº±-·6Ž[uqV’EA–ÇšEòÔ•’BùïÏP¬ØÚÄp¤ß-ËM'»fÊsÊbˆ8²LH }Èü=2zú¡\µÖíRvõŠ«;ìJØ"1Ð?Ö)¨æýÁ:A‚Òî¿išñqy˜N(¤ã·¥`']Öp84–Ê£SAáªM"€\²Ìbñ¦áqòÀÿž ÀíSw³6iñ'löB|ú€h˜Ë½Ñx|ï"Ëà"{ú¬ÿÓSDt C0ž+›+ú9P΃q;¹޶2Mà>HÝV>·ˆEÔÊÊ] ‡—ŒqÖ¨ƒûO«AtÖÑù=½¶¸kCå<著Cµ_ãPë¾Ù½YÙÏ G5 :ƒ@æÄ‡Xàˆâîœ}åi¬U9²ž“¿˜D“Sólõ÷Ï“9BঔeZ¼¸å»}%š‡§Éà©™‘3ØèY¦Kn›n¿—ªíß­w( û°•õ¢¹Û-¥¹?OŸq¼:ð;;èà?ñ {r|ôêê~íamÞ˜ú°†ƒú⋯Á>Íû¼¢;yûË:öæêê+Ï×_eÝ*ÞX´ôih%‰íVܧþ1»cw@YµFœ±ãö€Øû—ðàüÿ†Y繇J:BåÚ»ãn Þõ­±­ÏóÆÍ¼÷»@Ùœ¡ÍMÇ›RGÁõê/N¦¼\ÿ¹ »“ endstream endobj 1406 0 obj << /Length 1140 /Filter /FlateDecode >> stream xÚVÛnÛ8}÷W¨è‹ Ô )Šº݇.¶)²( t×}j‹€¶iG¨,º¤×ÝŸßáM–l%Í.І#z8œ Ï™ÁÑ6ÂÑ»Éï‹ÉÕ Í¢iœF‹MD0F4I£,ňÑ8Z¬£ÏS–̾.þ¼ºIXO“f9hä`Çêl껥\â{óW71r8‘&æÄœZ£y43cÆ?öên¯Êºù‚6_fÝHi–/Ì_rMa!ýÿæ¸cNc”g™³ôr6gO?¶R·Jh÷µQrç¤æ^8a[É%¯œ,ê‡RÉz'êÆmp嵬Kbí>j©v¼ªŽ×á^‚QÁб¾·òÀÀ×gž ý÷’«Ç⎠*Hþ¬¸+¹‰VŸ…»’•lU©CÄ|µ’j]Ö[Ÿ<9ÅË.³¥zìH¹qòQ¶N¸çá^ŲvrYë²,Ö&Òaª}¨6–;H;ðzÞ ñÿ&¿³ùX~Šï÷BýúZW/¨_gò•S\òŸcE|ܧޕáÀäíbò}BàŽH‡SFS”­v“Ï_q´†Á4¢E¬ê.JAYBA®¢¿';tž¯– °=2Ó„DŒägOá<p‰Q‘“À ï@+fx*•[uØØ´õª)MõÍWgv!¦j¡TgœšdC‚|:JÀEÇSn:Õån_ ·å«îW²­×Þ#ø‡òHm£ þué.&Ý5K®Åõõ¹g½ .²eY΢ٜb2½m¼'ÕŒàéÁüáGï½M«jíbànï ¡É?N3¦ð¢…Ö®¾F ¢±?6÷JÎb6=h È&T#8æBQxm|>QÊ<#î…ß´LN-aìÛÆ‹Ú­ÜùHÚ•Mi®y0¾ø§G=5U%¸ve$4Ž ³SBŸ.²oD^9¤çÒ*H±.Ó>½?bŒ€³ dnDÎãEˆ0ÔŸ ÒþCSf@ ƒŒšbåtµCoU.g1ž¶Ð¯Üf[Wå7Skq‚åë9ò^öÑ47P  "¡•Ò|+F1ô\Le˜ÚøÞð›o¦?¨»MJ1 m ¤MFLX¥u?ðªOÆäí¼Q&ÛÖu´§bû%O<À,ÊŒCÅß ùÑœ¸õ´YúòURºBí}åüZzBµ01‚IšíäÖ¨â;¿oÚ²Yké-ëv¿¯J±F—c\/EÞWH¼2_±.ŸÏ ðƒ°à=²Ã•6‰Áf .ënU„%Éi•‘è‰âFj' JóbøÞþà†¡õóßõiâµoZNLóÒyËpß—}~4ºÔY¶aJ­–ŠÜQ1sôgaù6:¬< „76¼h-ûTwnã X£·Ü+Ì­·]LZ†yRÉCÈûëë‘Ún\ #$ï†wCÿaÈ AŽf¤QÞÏÎe×;«R7}†¹(6Ì)ÿXjeä endstream endobj 1417 0 obj << /Length 1239 /Filter /FlateDecode >> stream xÚµW[oÛ6~÷¯ú$1KR¤({éÖ´@Q Xæbi(mkÕ%“äÄý÷=¼É–¢8 ¶!HD’‡ßùÎ…'8Ø8ø¸øu½xûñ@"Ó8Xo‚1ŠXˆ#Ñ`×ᦾQõ’áð~ùmýéí‡Hœœ`˜ ‘€:³•s½eÝ—ëÅ? C£nJ§AV-®¿á ‡µO¬È$x0;«€ÐÉ"—ÁŸ‹?uÓ¯ÁO£Sü£˜‘@àÅ8:Á?f‹Ñ1ŠdB¼Wªß·õrE9û²ƒ¬lº}»ŒD莓¢]26u¥êÞ.4ûMíg³¯³¾hj`–‘XÄ0{ %Æô(žq]ÌâpÒXò^uY[Ü ×Oœ8“$ÁŠ‚ç1·Ç36k{Y|´×ÚÚYi®¾bLk·Ç²ƒ.kîÌPX:@äyp¿bŽ;¥,øAIÐn?¼ú8õ-¥aÁ¼“À¥Zü’‰kG&Q†$þÞ–«Ëð¯ª-’tŒÏβ´,í¨p€Õ’rHø“–û´Wù…¾cÒÏ \$¹cî Î@¨d­‚¤ZuôH‘½Ö7mZ);|59$J‰¤·3ëýM×§Ù÷—pÄ%">åÈ¢èwioGE½Sma|lÚ¦ò;àlˆ ãH1„óp½& cD $ 3V¥ß—²Jß‘°ÐÒŸ@fÝþ­²ÞI}´åvZÔv…‚# ˜L`Ø­i.%V9ïÒÖŵ^^RìœT”émétöÝ›5¹¿eIxxÐT¶‡¨0&â±mE¿+¦ÅÇrUõ4™W:#‚]£áK—nÕl ?Néq`LRÚC›ÚÇ…†K#pÉtËÁÆÇ8üee¿÷³ê%ˆßµÚÛ½­ç?…˜y8–°Ã¹1$!õ1ün†â§î[¹£+"P;3_u_mRûáôÁ˜>§Ŧi_’Yœ§,¿W=Äg÷Dq†×›I >íoakÞDÂç Ž6Âä± „êo4¡0À1åM=s¹ùº‚$º‚(Wá¤e׸Qí¾]WlOTªß5¹ÃíövÊ,2SúaîýæªS„¥.ƒcWPÏ8ó|;—‡´º+U÷òN@Y̼çˆÏÉáé'e¶+ÊÜ{óÍmÚ©7§¹ M‘är {tT—&>Vêãpˆ#ýýËçÏôºN£È‰^M[ZÆEÆiµ²cÉ~‰;Þ@Hµ7ÿΰIa):êŸ9ú샂á1må(ô8ÿowKqŒˆ8VëM5©çÛÛËCßê÷*Í\JM[ëKµ-D¶«­^ÙÉêÜ‘€ì?éd ˆÄü¥ìsÅN³t®Ú $ÈL¹“ÖüD†5´g¹•”E×Û‘én¥©åUZÚÀ'I<Ÿh®þ ‚fÇhÀÝè ÎAþ©‰g!ºÈ‚ìÆÐôšíTeŒ•ãÞäY°@L,“)ÖîGu*ELF3‡pL™ ôÞN˜Ú©§$Žb;@WÞ6egiÛI#/œ.ÕÝ©¬€¾î‡•ï;µÙ—®¨C09iÒ‡÷º[IÛ¼¨·CRy±¢¢>Ó×öÕ‡púvŸõÆ-@ãì4Ú\ CJýd–ël endstream endobj 1438 0 obj << /Length 1216 /Filter /FlateDecode >> stream xÚ­WÝoÛ6÷_¡x/2P1"õ]l)– +Š[‡!- Ʀb!úð(¹‰ÿûy”,ºŠ— CðH÷ý;û΃ã;¿Í>,g—7Aâd$‹Yì,s‡ú> ÂØIbŸDs–çÎâÅ·åÇË›0q,#aÆ@ŽæÉYñn%¤läê~Á|w_–¢kÕÍ™oÞƒÇ⑯—á±D¢¤Û–?ëÚKëå Æº§ŽGS’eF£z•WeûÕü¼^x‘ï»¿à²æ š\åµúÿTý«AªÇ’Qj‰XÕ¼ÿM-§=Tÿƒ” yôõŸ=\¿ór/^iƙۧARn…ø„àk-íJ.¨ï>ì+QŸ„÷­ñ9Íq"&1ÉÒ!»®‹|7ß×ë®hj²ðÐá÷‹ײi•nb‡û½Y‹×n+P/ê#T‚[ cŽkÝÉí~·+ ±!'ªZvyFWƄŠj<¸óu~ ¹OF#UK¥1ª‘‡:’Ã9FÍöu‘$ ‡ê¬MdÇ(*è9ÈTèY’8ÍLüCäüUt¼(§#ÚMìˆßÖešÐXµ‚”ZíS½/†Ù Z þ{ÎSáVÅ2LÜ­(wB¶¸é¶²é [^㪻’OE·Ej'‹ªè Åþ}A#×Èës¯Å—Šºíßà·&ÇUŠn/k•YSö%ħCD>ß~ú4a’Egƒúa³‹ò‹0)|U¶Í E $u¤Ú"ùç¿•¨ª“—V^ v”–ƽê¼Þæ×<“4®¯ÖÔÛ–S2FhÌìD½~æÕ®íë±,ãpp€Rfdý„Mòú¹“|Ýá&—Meø^Jè†Çnþ¾oÃÔ'YtlxVÇí3JÈ-@ ïp½·NÙ±i`Œök§_HH,{NéøBÅU‡Qda ¼= Õ5æz#Ÿ¸Üà"†˜0i¼òŠ2ÀŸsh©‡¹±ðââbZ“R³ý†Ê„Ô2á¯fßûÝø—«À£-¯a–@·bPZµ–BtaË¢íÔ·+;Z¾1惮·†&}Z¯µ+ó¦é9¿çrþºg×ËÙß3ªë‘´b¬«ÙÝ7ßÙÀGC‚,už4kå„”¨(È(/³?^¬%=VÚÚÄ!uX‘¨¯O{dœC«7R9@Ä IäjØúÆS皀'a4@)øµåzˆÑ`Ôžq ŒQôã78gêxb¦¦Ð¤Â,îQ´]Ëb§ê²?¶âëg@³BÕ/'ÐÅ·§)מÁRåY6@SÇ_<Ç.ÇjIµ>!q‹Ð¸î³Wý^ˆúnÒßmKaèNâè´Ré(WQíºÃo¨¤öŒš°BjG¨¬ÙÂ~¶ )ónßᙞ áH‹T¦«¹ÑÝeÏ+JS¬foΈ²Ì…O\ üÀÛVT÷¥Øô[ó·ªaŒ…Óq’ê™…¹±õÆ :#óšãèZÈÑì÷ÞJ÷ü8óühKLùÊXd3Ý!„m6Â6ù”À°’õ 1/æSIP £ :ĪBí81£Pܰ¨ÑXSó¢Î›¹™µÕ}S’Éj€âüÂo®© endstream endobj 1448 0 obj << /Length 1416 /Filter /FlateDecode >> stream xÚµW[oÛ6~÷¯ò$K‘º{é°µÀÞ¶¹{i‹€–iK›,y¤”¤ÿ~çð"[Ž’&X‡ Ež¿óš‡€V?mVoß'iP’2cY°Ù1¥„'Yg”¤œ›]ð)ÜߪZ¯¿l~}ûžç I^€&#•æ(²¢N·ƒˆç “Ëñ¤þÌX:>E)¥á/­<ÊnÐ눥4ìÄQî¬aÆ/ ç9¡¥·{óp³à[œ“„§^F(i5n׌†cÛÊ›•ûf¨íLØAù›JõZߨýõ¸í[2÷9*’²4ˆâŒ”?ÚÇΆcÔÉYœ¯qïæ‡ÇœÀ=F,&YjÝØÔ hOhÊuœ†'©4)Z»Út{%ô ÆjѼYs'¶B£}œöŽi8¬ã°–vÞ줰»C-;Ó Zv•Ô^»³­T¯ìô(µ/ ¼Í­Ôƒ‰B1)SçÿßëÒtõœ¥¡®{妢۹µæxj%YG)OÃ÷ª?ÚåÁ޳SßtîP¿·ã]#×0ܯ³4|K yi÷Œ'fv¶ÅW§¯wÚ”Ä ½wÒØ«£L”YÐ~ã,iѤ‚ÂNÿ°º¶ÏAfsPu»Ûm¿ûú™¦þ㬮ŸrB3÷£êÞ¤)s¡g7;º+ÁiÕw»fè;“ ¸í$íp£ýn=ÌUÚpó30lP=ˆ¦kºÃL§†…VZÌZg—^µbÔx¥³ æ˜ÌäØÎÌݳ"MiÚ5[î=ÃýÁŸ=á$NªÇz¸[ѺéüÞ!ŽuoAbUõÞ‹A*Á`?…x–&ÜP²Ñ¢‡µÞ¡uWîF5޵[8ÈN*¬PÃö¢pÚh=Ê7Žê¦r”U1¶Ž(¶N…O§¶ñô!ôËÁÇx Ü?q&‚¯–b'Õ‹àW’<ŸðG#g’ŠY ,U¢Ì­äGä„ÅÆq=^yÝ’¸ÜÚ"¼5)»ÝÚûF·¼ß×ÎàñK?Þ)¬ùÃhYù9–ýHÊÒ*zx.KyFÊ‚ù,½CÀä¡o 0­j¡D8ÃÏÌa¥ `Û¢;Ÿ¨ …Íšæ\Ð Í“%Œ$4÷N<,4Ïœ|ê¯`ü±ÀuœN×Ý|K‡mpàÔÏgJÙƒ lgy€e%aI= w@<¾Þµ_@\­ð 8Bô@ƒMౕB$¯Ö5«ŽIÏINëäÏRWª9™N·Tߨ‹§‘ð*äéûV°ÎIæ®&ª9ÔðÞ0 ÁN²F\@&RH§ÔîoÛ§Í/0ÛÊý#«0ÍM/Z0Ï€\“òl^vwÿ%jÙ­ ÝJõm*@£P¿ùUãÄú6àÀaïZ×?öcWámi_GjjkغÇ]f¿PR˜ò) ÅROò‰Ôÿvï‡Ù»Õ!y±3Ä9'ižþ?q‡­`ï[öeÆI_ Ø^aÞê?Fv¼í(Ï´O)½–x•VËó®:ç”>ÙéŠïÜéöîAòÊŽwÁjós3c‘;8ûi5Åø2kß9î÷æìì٥䩕<ÿÐZ'üÆ3Ž\bóÏuÉÂGÎ|&,Î?Y—鲑ñ—ÛY> stream xÚÝXKo7¾ëWðØ\¸œ_ ¸-ГC['ÅÞ<Wj-¹Hþ}¿¡lCŽVÍ*–Š¢[ÜÝœ×7Ã!)“ Ž$©Ód¿ÑUÂoŒø—íÇ6NЏX$µêb¬6ˆ.…†O.Eš½¨mNvYÅÅåÒ°Õ1l ®“*¸°£ XTñDbè9dÿ0X â#gSµØ2Ì6jšá«6í 5™i&7ƒT<ÆØf@r¬6£B½Lm„wEuOÕ°R£ã`êÂpMÝšSÓ2e³ 1“)\+Fð!iŽ…Ú xPÌ… '±æ<Áˆ§`ÞÄ„¬í#–ËÀlà"¦~ÀºÅÌ×X•`ÆaÝšM—Àíc”’áÔA(C%'M' ø*Il$N´Æ•‹ðª"€ˆjFŒñª ¾MàxÔð˜ŸÙgØL&Ûd…ë!ÏTgÁÈ© YèjŒ,B‡ïdßlFÔ„‰Â ž0JM@vªÔŒ’ À£Æ`ÀD¼2Gæfµ¡ºÆˆ¿ í# nÕ’Zà°(Fż¤ì"s{Çs6˜¥©+'iDTšÑ¦k3VƘÌKÆÏÆmÅêÑÂd„•ì#ôJÁ¸µ1Ê Ð.ÉM¢F LHlÔÐ(5jD|•`ò!0I³0"¤… d–`T02¾+R/EáÉÑѤ{æNamB&Ÿ¸î—_C"/Ú¨ê 7»º¸x=yôèŸÑ”“‡¾#Á){F6ÜAÏgKwtäºc ¬hӎͧt½Æ1ܪH±ÕƒQÎZ=˜×àÛë9°ùZ.ïž_ÎÏ^ôKwêºçÏŽ]÷²ÿ´t·r_~þ£Ç‡é»~Ò=…ýl¹°Ú"6Òô‹ùÕåY¿XÕ›öîçþüÃôÉü“;5ñ±Foe¥(ùR_CÞô‹¿2bÒ=žÍæXôtU M­/¤7À¤{qõfÙžú0û8éžÌ/ÏûË&#¼î~è~ìžžR{0µÎ`Š“Gò ^[²·º Â{‰@=n}áºïç/çùîäíÌÿy5`ŽYòø6Lµ¶(å,^QQ6cº¾‰iVõ)2rô–)ãÐQÅ´Ö䩌Õ…Åc[‰F}òvš‹ú㶬¸›ë)²=+ö‘e Ê·%ºÊ.„+CaŽÕs8šÉGÕà‰|–:}ÎÓ`Z ¡Eا8vmŽ \ëªV´óîE{T¾ÃâoæjÕM®V¾wÑ®´×¢]ƒÏ0[‹øŠNˆ¹xÛݵ"œ¶–íÙ¢÷'çÓÅ{Þ¿½Zô5¼Ê)µ¾¥¦9%òaбøÒX´"]3D㥣­Vvj$š#ùšëîUùߣ½†´A{kçïI{;iì‘ölTD?‰fÔÛéL[i1'±.[iÿfºè>|3?ÿüê»W¾$½ŒF“þø–j’|ês÷€¶”®CÕ{ö­ÐH0NŽ^y,˜ª2viF+g'íûUú½³œò&Ë)îÄrå–¯öºvÄ] H÷É{Qöv¸ÅÍWm=¡`“馺•öýì¯u®ß3÷"Úm4¹ <ô8·z;<&®¾4 +q¶ü´ô'W~±œž}Ü£>èSÈï¡z»K0Ï.+8øx«:ÓÙ»@i‡@§ÑŒö-S=:»Ár1ˆN8D\Ñ1o÷f#Ñ.c5QÁ®Wx$ZpžÏ4VÆþË££³Š/ƒ5ô?ŽFU ¦{v{/¹R6K®¤{—\¹)¹"{m¬QÕÄ.þªÏè](«·‹hÍm/rÓ‹‹V䦗ïû«qTq*ÄáÿFFºÚíNê´Álú{¿Ø¨{’w¨{ëà¯ÞØ ¢ꇎ]: l®#ÁŠî}¸Ž ¢5y»‡Æù‹Ôë—çŸûÝbîá¾æzå»9«{ÈY½ÉÙx€œMØAv¾Víò­py{’ÌÎ[jر`)+ˆªÐÆnÁt‚^Z·¨>è×µyßO!a#Su—LÕ¡ÜckÛt$:–`¾‹¶_®AÛ=t$ú¿£µÚ%ü8°„2”‘hF³)kKÿ Él´ endstream endobj 1467 0 obj << /Length 820 /Filter /FlateDecode >> stream xÚ­V[o›0~ϯ°º—  Çl@Ú:­é6u“ÖfÚC[­$‰K ¤¥š¶ß>ƒ Ä\*M‘rl8÷ós@`8½Ÿ&Sjºœp0 FR‹›#È(³%¸3Ǹ}žL-Öᤎ9jj–àgá˜Ë¢b!e@hçS ™Ä®žIѳҋבŸk‚»èdJ(p„0·jw`bq¥¬q#»ÏoC “!4Æ’¼–„h7*øpeT(61‚.s‡•”Ç2žœždU) Òå'º" ÅiªŸ·÷KMñónÅ~ò8Üèl6zaÁnqÀ r‡‚E<º¾E`)^ •ºxªYc`a m‹Šs®Fßv–®›¨^l"naÀ¸ wþ!i E–†QL ëàz3ƒ±ñ&K “04¾üx%i ifñ&òä%LŠTžÔƒ¼ÈÂd¥$2I#oîG{RÂ,èp÷%)‘}ÆúŒA‰-#ùàç‹,\aš 6C¿W+ð‹+Ū‘6¡AØø±úó"?)ÚLHmâ­@s¼<ï—„1­&³~¹ÎêjTxiq²ÃfCâ´¢^²<Þ(æÐ±mÍj]ƒcÌr çíjj¨ªžC9¹ô)Dî¨-²GÄ–Jþ÷Ü[ùÇÏ ÝeÚ”•od=…Ëâ^ßIÂÑ…z—Da"f_÷å§$к—Šîmu'^ì׺·XÚyФ®eéÇ{¡ŸfFãÕ&Ù?†„^î«”ÍE×’¦R§Z`OP³b*I ˆ1å³ÌéÑæ~–èþº Ýáà{ õ¤*Ã˽PÕ;Ú/^Æ›XšL6ñÜÏt‡ªc3©Ô^ͼE1ˆf×’~u+ú_wªDå[S[0ž¶Kçúm1¼›¾ö,³¼Á®öJÚø*ú ×\yؤ…¿l:N‚c2e¨š+¾>h»8îî$‹½©xz®·~ú&Pî]Õ{¥q0óåÁOéÒ_g§oâÄ»ÁÔJæ'L]¤Õ«Õ‹Ééç¹X}Ë4мu~¬é M«Û¯š»Ê­Kô?«”®Eü…>¨ÌM¿«·[3¾¡bÿþÿ‰I endstream endobj 1484 0 obj << /Length 1733 /Filter /FlateDecode >> stream xÚ­XYÛ6~ß_! •˜I}H ‚"mE,´m«+K®(eãß%[²¼GZ^£ÎýÑž³q<çíÕËÕÕó7~à$, Eè¬Ö÷<&ýЉBR8«ÜùìnT{­ª…ï¹ß_Wïž¿‘ÑÉ'¾ÇY?C$HråY ¯WWÿ\q˜z?2‹„ïd»«Ï_='‡Ãw%±sgHwŽÏ©/a^:¯~øMG£§p…>w"O° iðmt5Ð<}'Xó^·ª],Eà¹uC£î7Ú­¢‰5IÑ,üÀ­«ªúOÖ4¦•]ßü­²ÖŸµG˜À˧ØÃè-ÃÏ…½#Òâ•ÒYSìÛ¢®Fºm0r%¥àÌóbú|µU”•±ç®»*C6—ÜÍ ½OÛlK‡EÕª¦JËò@뻢ÝÝNµÛ:×–ÚrÄìÙbés‰»®L-YZåôñºIwJ³Å2ò¸ûëšN3£rÔ4X‚Y’  ÛöRC7¥aWh]T»×,xìn:t“›'ñlðdïEܬ×4TY×4éZˆÒþKË.5†ý€îL$_¼ÀÓJYÃÃ?;ÍÆé§¼†®”ºAYû½½ÖmšÝ"#øã“ð¹.HX ßöÔÎRBlù"°– é¸@K¾Û¨¶k*•ƒ‰CaM Û‡º£ Úš2~tÏ$†KzY6·N/9­1“AÔÓ[7{Ì'æfƒ -H7ÍZ{ÝÔŽä˜9íV}TõÌsú©)¸²2d4ç®B²ŒºØíMLü·®ãÛvÛÓmU¹?ý¤X(î`#«sE³»­ªì¬)ZK€ý*Õœ¦.!cf"}rivgÖð§5a‰ -%¡uü'nÔl%8¯ ãª:© 'N‡<xž›«uÚ•--~¡á·OïßÑjÉΉ‰žcR©;SªO™˜œoN£ìŒeo˜o×ûúV]ïSLÕYÎ'Az¯­^@ÁðlÁÐ÷Úì[7žQvD•Чlv¼¨&Í…\Ì&F—–¨Mö¼Þ–¼2}MDø%jN®">Ϥ**³T«™ÁE„Š„µÁ´ßDLxM^+M<«ÚJ¾kÒ=m¥VÜ™]–Ò“X¹f®ÞŒäPw0gî ãðhPÙôÉ9N»ªžõ mfuWæ4½é‚î÷¶ ¦ògcL š¦GXEhÔÖâG{Ú}Ÿ1ÿ5Æ,¼±J6j_¦Ù¬k½˜…œ?èZ_§5¶@ L1ɼWªM‹Rÿbùs[”sw1ˆ®£Ó²‚cdRíÇš&\À°«óâ‹ç Ó`Õ{Ìšƒ%ªì65ÎLPãd›.BiE;ºÈí R Åà"`£5$€Z˜zËÝ}  æMz_½WMÚš¤ƒ>™mÓjÓ/,ÈõçbDº7éÞ8;Þ3Ô[m ˪oT–vº§Ÿt0Ú-îAKÎgs#èÖÔéM9nf Šh÷Rú¦ ¬ ¬»H|aýáKñ¸A ùùýp·Ý¦ö‚H°•×ÕÏ,[ZÖh†» !L ‘mà>€ÆMÐÀ1ùiVñ5 -ýif@Àº©w¶¦Ð°¨íýQ@à}±¶E*;d¥z ½BIrOÆQÖ}"˜8ÂtÜO~Ÿ‡±ôÅdhÞ‹'ŤîÀ`ºǦL¾á^]Ì/ ˜(vC³ßé' ‚E9@ziL­rÉ#pˆlÅ8>Ž…¼m û\¡’3zůšQ‡³Œ™Æc˜qÉõPVjß_BÖ2Ö îk‰ä¦ÅCÒ´*ḸÅìV´q|âÊ´L9zâvQé𭛿–lMã ”^ú´ÞàwšNÁÝK“b½‚'fâ@iâ@ŸÀÚÆnõq á­j‹ô/c¢±Pß¼XðôÎà,KŠÕ±è¹euµ†e]ÑYÿ”4g'ÐþO¾ˆü¹-80„Ò4S.ôöP**Sg(åÒ§ø@+(b`‘òЃpQK€ÓIb£íþà®ÙÚ$a>­O•ýôE©ë Õé1y5ÿtõõL¹¹”X!àS_NÀác3šÅÑPâP®þQ¹ægá'6mŸ~izôBü! ¾§è^º1É£ÿÁ ú‰2‡ËRßEÔUw&wêæ¶ß·¸ƒ"‘ãÐëë®QšÍÒëÕÕ¿¨s]ª endstream endobj 1498 0 obj << /Length 1380 /Filter /FlateDecode >> stream xÚµX]oÛ6}÷¯Ò‡9@ÌúV0`ÀФØt[ã>µE¦H”­U&]J²——ýö]ФL)²“¬‚@yI^žsî%¯±³r°ónöórvyãEN‚’Ð e጑ç‡Nbx®³ÌOóŸYþzyã–¥”`æélÖi}ÏÒ •–3¬ç‡ÉCkÈÂŒY¸‘lT#¯ÿN7ÛŠÖƒ‘Çž—7®çÄ08ô;wcgA„#OÍõæ|`<¿f»Rp¶¡¬Q ¼PϬâu+¨ú(Z–5%gõ•\¦_Œ’ QSLYý¸ZƆ¢ZÏ ÎϦ†¯hsOÙNZ¬³×F.@nÛîþ&†^~k;/kݪ{ .6m•N{k-÷¸d/xÄ éœSÆöÏEq<ü]ð]™kÜRõÈi‘¶•¸Ôhei­­šµ~áÑL›åœÖL‰)À6I„Ü1ý LTûÈ{µééZ–WÆ+í=pº-\LPäûC$ôÆni3áŽë"Ÿ„ÏyãMT&hÚŒ¼iÝ¥U íù€Å+íZˆ’‘솪–:Åꄌ–ñ‚Wß—l¥>«’éŽ=o+ãGZVš:½¤hµÏ4K[Cã± ÔSòzcXfßêË(V  ÐÛ£^¾Ì'5€nüZ­ÓÝXÑÙ:e™iäŠI{(&dA3.4|ÜpñHÉçÕ íò„ûh`ú‹‰C“4І Ö´h«ÞÛî¹}.ž÷k3ü‘·“dúèy2{,MÊÝ‹²‘ºTâwcúÞäÖûܬ]Ì2ºmzE÷TµÉAÛ¶™Äs°5ZÙc©àaM™¥•4²™¸À%‡?m9¥õaªÃ1’¥}ìõ¤åCÊ`ÜH†” Ž3szŒ¡cù ‰$Ñ©tBrö_8SépèšCÙ¬ÝÛTâàŽxç:_Âý!òFAVCb³uYåã³8‘ÎŽ‘<>ä-r¦Ïû÷oo/lýœ Êå:m¦6ÎøÞä–z*QáIdàüó9¼%³xîk'æèÞŒ‰¡^SpâÁRIøÂÐ`V4Œàyõø¬ÌìXù/‘%ou“Û¸øª£MŸuŸ iQÀeEGÃm9Gk”ÑýÓCèd|év \»c¯h‡ñÝI”«’¥ÕPE“9ŽÃ q:¤z‘bKŸiú9¿‹ÉÉY&ø»+ûSu’JA›VôimDÇ3©%/f1æj¸¾ÅèÅ©³/Æ(L^ž«Ê¸:Né ëº\I‡›?#:㑘¼U3KúX–@‡šø¥Ú€Y1ãúá!¼dWªÚ*¾’Qm»s7˜C-@U_Ón²£d9X5¼Ð! kŽ…v)G©V«»ƒ"­ÊÚôô"PR‚?;bå˜×ïždwÿ$°®÷€Š È1)ú>н4©^ˆ¥ ^Ôf endstream endobj 1505 0 obj << /Length 1238 /Filter /FlateDecode >> stream xÚÍWßoÛ6~÷_!ôIb†¿$K}24: Ö8{i‹‚‘i›«,y"Ý$ÿýŽ")[²â&ë?ˆ2ïŽwßÝ}<áháè—ÉÏ‹Éå O¢å)M£Å*"#ÆÓhžb”0-–ÑÇXUÙ(£¿ˆjJ’øiúyñëå ›éqLÐ<£­BJ¬Èûc@6=’yáÛÿœÊkÙÓzîyyCÙ±ÇÖF$÷†6B©ÄV~ ~¼˜ÎŒcÿN¼ã=g¬>Ã(Ç^ÿª™¯÷[Y}Ö¡ï8ò8Äà¯yŠòŒ¼®¦3šàx)Œp«U»eݸ§¨jip/6 ¥ß¿ÿKfpVϱ™?lFæS⎴^îàu)-‡Ã-ºº…´ýËÔîYldñu åœ;Ž‘~'På8Æo†ØÞU'hSãq3&ˆ¿«Vþ½,± 5åvgžÜR›FUk\H=Ta‘$ý~5Ò„"ž° ¢ªÝÞC¸VSšÄßl7I=bœ§çó xsõÛíõˆyèv 1Ö{ç ±,°„#‚Ó~þœæÙË“_¹e½V…𘺰 *·ö CùzT»â.eµ6›.G§@„!Âxˆ1TíIÏI+Ö ìúQlw¥Ô/g• ,¦<ÄIrˆ39eÕ(í‰åÍíNJê7]ÀÖŒ€P'z[Sˆ¦Ó\Kxéô&׋Éßê8" s–¢,çQ±|üŒ£%l ô,zhE·'À¥ÜÖXÝNþx6¾–êûЂŸ)'`âÌN©þi@¼WPÚyFB^ÞÕ]U=Zr]çŒj›ò$®·^ÜW„4ýZ)J¡µÔ?Á[†b¯Á¦Å W8ÁƒúéÀKºhÔΨºúÿ÷Zƒ‰¤ßŸ(MÎ1s†xšèá½-—£ «GÌ ¥¤#f°³,KõÕ^[¡‡á‡²¨YGaùáälš#zh¬{¡åÛ·Á…ã㟠7c(™ô§ǖݬ3Ω,ÞÖ–Rí?ÒRÂã®T…ò2â¾îÄ—¿—aí|Sõ¾q{ èÁöÜÓ)âö#Ð]¾+·ûÒ(hqe]Í h0žÇïW#t’Q„yÇÙ^ad–·'\]ÁMUiwŒ–în,ç1 º Ò‹ˆjé-åÙEh+Pv;«ÆöB«eܳ”B4Tżu]ÉbÝ^ŒD›PH{m}QDiQ#;©Æ˜™Ùë/ r‹wc7PKN;!Ô«'›R†X“뙲<“E/è©ÛaRÎbnW-mÁ³£-Xòdß\žZÙvx°Â«`FºE((¯>ØÕSïwÐíTbõ›% tIÀÀÅEâÅFi—wçp/ëÊì^ïÁ§Á•zA¹ÕƒåñÔŸËL·½ ·²NTÅ šMuDÄÃÔ¹,ü‰««òl5¦Àvl:’cŸ:·’nѺꖇÄÿÑwv¡–ЦvVÌ)¼¿÷VTt½©Sìý¦md¤)bG!Ë6œÖ—öÄv^ÉèÈDÖk’“/¦tŽ8ÌÏ?þÉDÆ™!|6õ¼¶“ e('d¼õÎ+=“õQ¥ÿåÚÈXó²æB¯þ4suüÚÇb#Q˜ð…øÜ>ÚÏá ƒÖ?ƒÔï endstream endobj 1524 0 obj << /Length 1835 /Filter /FlateDecode >> stream xÚ¥X[o£F~÷¯@îC)Ì2 °jUmÛd•UT©»^õa»ŠÛ´\oâþúž3l0¾$U1÷9×ï|cÏY8žó~ôótôæÖœ„$œqg:w¨ç?àNÄ=ú̙Μ/ή¾N?¼¹ ½•~’ȧpŽZ“ˇ,- \8òÌñp6ßÛáÚ-.‹pPo¼yNWëBÈÎÎcß7·ÌwbØÌ%mì¸4&¡곪ǿ®ÜÐó&?¸ú+›z“5›Züé…^‘Ë¿ðO¯õ|V¤RêæfWŒçU56KÆi½×þwŒÛñ¡\FI‚(¾ÓëþÈ›¥n5K¡i¹Õ­oi§e£;UYlmKÈ´ÚH³n•6Ùò­½’z$ cør)꼑xÊ6¸î©ÒÓ`H‰žxî¸Kmsh“vTYB\b‹¸/yQ¼RòaC\tÜ%V˜ZÝ«z&jÓœŸW×XÆL>‰¢xû‰QJ+1JÄ푪6}Ì™K‘ý-­SÓ¦çÞ½@þ&²¦ªM'­Í‚|&Ê&Ø8­‹½ø¥æÿ‡ÏøÑÍtôÏaÏsh —!e„‘“­F_¾zÎ &Aâ'±ó¤–®œ€R>´ çÓè÷£§0Pn“AP'H'ñ)¼ :XB%q‹Ðw`~z’à ÝNõOúé¸vAÌO’—h§+ ¨,A8ôµL¿ ™ÕùºÉ«rÿûÕ ñ>¼§zût™£RA4™oÊL=>i„l¤næs]»:ÌæY¯èÜ‘úmmÓ—¤FFø#±S/Ûüø~ä|Q×ø¶“+×÷’VX¾wžê®Ó¦uéªDÏË…ž\×b¹Ñ£’Ê/œ¨´R¨ÅXB¼¤ÕëöÝý§›Ý úú¼]5l °oW”éJ È¿‹®´œ œãúQBü0·²„¦L—ÃZ™B``ÊÍz]äbf¢µ4 16pukV ßee‚Û§Ù Í–u]­EÝäB#F‡£°P â2`ž‰ÒÏ2]ˆËùÉñx5I‹€ólFwŸ€üöùþÞÎ3Ÿúú JC·ÞÕWÔ›,6+€ÞÓœëŒ.Ï}ª×ñ&äiÝù®å½å¡`Q6ÖÞ½{îï ©îðaEÎCÕ3¿¨ˆæ”3ýMõ'[¦Š'ÔºÛ©'Ü÷vÑ%‘Žp_%N<-sÅ1¹.º¥Œ·­%>ÝÕ\¥¿–œráUiÐ-~Â+ËT|> stream xÚµWmoÓ0þÞ_$:©õì¼§ X÷ „ÜÔmƒò¶ØÙV~=vlwIÚõe+š*ßâóù¹Çwg4f4>vNFã3Û1¸¦kŒ¦‚X¶kx.Že£‰qÝ‹èo’älqôkôéøÌòjú6DÀó¹±Jѵ„J*ó\×­é”òÀôÄ7¹ä’£éÀÞû˜fÕ#ÿ¾Qˆ¥ø]Ø6­:nnùÀõßç¡4ÊÒŸÐü‡6bL¾Âuz“<&ôHͱãsc®½ãq0öMˆãXà¸)3F„0Í21Œq! éŸØ[˜Hùòâhà@Øû‘•Rq*…3FŠt`Îå'6'Z)Ž¥t15‰'“ˆq>°šÁŬLHÊèPo‹ Ð}iªËgºu*KÁS,ñO‡±ÔÒØÆïç5,¦e2&…”³i‹µ6½5pb«áó©¤*†ÜšE³nÑ2ïy >Nrœ).c¦V¥8!4Ç!™<ÄÕÄ(Ö¡LÏ—éM‰ãh‘ÉZBR™¨Rùõ urcLÉpG”iVWhXVeR»,Vw÷Î-,ªQ%Ñœ„ÑT‘q7'<8ŠG“γ2ž¤²P:°VLŽÖCºP¾’ªaÛ·´“öÆd=í㪠_€«É©rŠ–y/¢t¦u4¨££æ¶ñüU1©\ŠX6)Ïñ­r·|? Ð’E1Ý¥ÌìaSë*Þ–@“§$å„çYÄ/–ßôpއB]yßoã>(ëv¢ 3ÚÝ¡Ÿ«øÈRÒ,¾<å]muÌõu¥ÙP›î"¡µËëIÇ;Wëv1zRdü‡M$ßÕNýz6î³íúr{ Í«+Æmóh^ õæíÚ<ä[²¬ˆ¨>Y]›ÓIÕ»EU ¬#EábÙJ¬ˆkþù7ºæ©¨%ßß½ióúYöä(hš—–‡5ùåRzר­s:êÜtPõlGËÖ´ðË“Îõ/hLø$ǬÀ7î*ÕİolqÆÆeçÛ£ïîªiöÜ;×FüºµA`¹«ýKíÍn{…&ü//ès*»’lü‡Çž”EŒ‰QÝ B”©TÕøåêââí÷¡ <ÞCíá~åf£]ÑÆç¨–å¡aå≿¶kiµnºeò‚ý\>BNo“ÛÛ:«+Šgd÷¶jc'`‰È¼_éïôÈÏàeAÓÀ endstream endobj 1543 0 obj << /Length 1383 /Filter /FlateDecode >> stream xÚÍVYoÛ8~÷¯ÐÛJ@ÌŠ—Ž}Yt±é( ¬×yj‹BQ˜X [rE¹Iþ}g8¤-9Ž7Z`aÀCŽæâÌ|C¦Ñ]”F¿Ï~]Î^½‘yT²2Y´¼xš2©²(ÏR¦¥ˆ–7Ñû8SÉÇå_¯Þ(=’”:g™ÎÀŽ“iì'“p?l{cmÓµ¨2K½#ð’tçAy.rd’‰×}ÂÓøn·1í`'êÇôÕ!ÇAÑœ°ådèáØ÷ø„yÆÊB„°»ëM=$s¡Óxè<5v Oƒ.•ÓĘ¥"õˇj³]›óÑN¢Æ03µ¯Ül‡Ç©Nß]½} ”£]Ð󔕺|*·nì€e¿E>Ø:³ËåìóŒƒjñ}d\²¼PQ½™½ÿ˜F7ð¬3YѽÝDŠs–+ ëuôÏìïgÏî:mZ4ˆ1S<ÒeÆrqµýÒô]‹=pTE5éS. <”ñOK¥—³j‰š6Qi V¥c²üËógÖ…bZðo93¡(;"­%+ÒœbüÍØºo¶Ã16^ØÔ›ëª7ã…Êûfâ8giY†ü`Kûݯ̰2=éL¤©¨¬rl3ì*œ*Î/4ùåÛ^ÇÓ{CôÆ …ÖïZ¹@ÜêCØ´»ÍµéqN%b;ô¨‹Smšs&EÊŠoÌÿìÓ _Ò’3¡UÀ9.s(%LQäÔ èB‡,7P7ÇDQÀ6 áq>x†l(âæÐñ¥uêÕÜ´ôÝÍdô¦Œ^Qþó‚8åŒ7b»]_›IMG3Žn%„‡awX3V4-‘¿s³’.ø±"ê\<¹&Š‚¥{ºÜ51ßs¯]²<×Sºbp•ë^[—¾yО˜€^Fäîž<¾©·À=n ñ|&außW[Kˣ뙘.M@½‰ƒÏv™A;îš"Ûþ”ð"övÖx™Ín/Ò’¹ teï=,ˆÐe|æE«~À#|’ÿ§oðówÍYùÕüð¤®Â{ð+…ÆUD endstream endobj 1461 0 obj << /Type /ObjStm /N 100 /First 964 /Length 1743 /Filter /FlateDecode >> stream xÚµYKo7¾ëWð˜\(r|F€<à¶@ Img›q¥T’ƒäß÷ÊräHªWñêàdvõ‘óq8/r£¤à‚‹"ɉâÿ”\T2•l;¡âTÙiŽö¢¸“ Õ%ƒ…â2þ¢äà²ÊBt%Ø´™\Ãfv¥Ú¼Y\åVW‹Ø4ÐØÐ…]ŒjRÂÜÞåëÑølR,6=ÆçÔf«.Ö¦»Q#\¢£X3‹#6] .Ę"è UC)¤lK.É‘’­ ë%MJq”¢i-’ÚˆŠIr°rã‰%Q®F±˜½Ä8A5Ui#Ôq€UÔlV+¤GXfpX!°xÏ ëâU„TÛH¼Û âXS“Èq‚jUüXl]L*mhv\ma kpÍjª“` Ó ¥lRt±0"¼ŠXWÅH![–Â8BÚð¶çµáÅ ‹iˆ ©4 øUØ4$µEk,ŽaΡµ4­¦¢bÛZ6”`ŒÈbR‚d›F5·Œ²ÍfþƶՊ%)'ÓoP m‚¤Æ˜É¬ÑFÀ.©˜›â¯p€‰‹¹Š2´V2­ ­5›V8qˆ 8Cjs°9vh"$µX\¢Ü†ÂÛWú%¸¤jª-Ì«UÄ¥Ìf0lZÊmKà÷©PX¦b®¦]µÙF «¶§ä`®¦ð(øWEÄàUÄ–èfXÔùÛ†à)SÛ0ÈTêèäd4~îÎáüÂÿøó/DTðl‘§ÉÃÁ¦W——oF7ðélºt''n|*¶i5êôšWmgÃú$^=Øt5óŸÏÎ_vKwæÆ¿??uãWÝ—¥»Qõêë§?LÞw£ñ3¨í¦Ë……wc:¿è³«ùy·X¥öî·îÝÅäéì‹;3õZÕr@‘èK}}“9&žê ÿd:aÒ³UÎ2Z-g™ð†_^½]¶ç_/¦Gã§³ù»nÞ”…7ãŸÇ¿ŒŸÅö`üα²˜ÙÃ5{3ûôuòö²PJun•+¥ÅMEe# ¾–²ß>WsÛ÷Fª›~ŽOŒÙ£ ˆ½5²±†* V¢ûsæ¿W³Æä}wF¢o­ï5%Jغ(½I-ŽAŠ þ‚ ±&ÅY½u·wp:Џ¢êÒ7 |'Z[}™=†i™´ðen|SæL|tÊ–Dè8èÄÞzÙ~hMðMékQXRûÎà þï &K#8õCGÍýø=›Ý[ep£Zþp¬e» Ötï2XuÈ‚FQfNT2cœ›=N›ˆ¾àqòÜßWN?·hû0YlE[ÍD[͇4•»Ð„DQ’‘SÑ!Û­kC•Ýò3;ªâg×¼7ýÌ®†ô3!QæK@cËľؕ…_÷'õ·“E÷èÑÅôC7¿X.^?xýð{o³‹’ÞÞv |§·íD'”'áØM8„Ô­à#õEùKO´pö¡ÊQÐlgR¢ã  ÚÔׂ„ ÆÒ—wLh)è G¯ÃÔ4mŸŸ¬É¿o@ÇëC’ÝÔ­ ƒ†8áHmw”}¬ÖôGäÎl·‡>ÞßüO./iÀ#_™vbÂިϚq&"¯œö÷_ÿDŸ¹Þ”U1[ ¡¹«¬nÙ¢ù.оÞßâv¡–²Ç@ Ôò~O´–úÒfez±ÊŽÓá‘.R~8ö™·cŸã½cŸ½¹>UçíŽ9Vñv‘žÉNñ®K»‘ì‹‹ÙtËÏ™ðóMðÝ~¾  £$î‰&œ?îãÎèXÐI鋔dž,[ƒ7¥²Ãåþ~ÌëÒ%Ö®€Ò•Q²8zûÈ—PÁ`(kZKÜ­÷i2_t7N=`õPt1Ñ>ªOYìÓ™öá’’×\þ÷²OhÉ!¡%…–ì ­‚¯7ë«».ã@kNľL4éîÛ•ÝèXÛ7™~hÄ¡·Ï¬ýÐ\ÔW¦ã íø8hœòÆ"ÿ-¦„“ endstream endobj 1565 0 obj << /Length 1921 /Filter /FlateDecode >> stream xÚ•XYoã6~ϯ0¶/2kERgЗ´Ý´(‚b‘xжh™‰Õ•%¯(åø÷áŠd+^A@rDçøæ ƒÙÃ,˜ývöóòìãUÍ2?‹y<[ÞÏXø"ŒgIø‘à³åzö·Wè;5g‘÷¼k”ÖE]Íÿ]þññJ$ƒƒaÀü$®æDá–³ÀÞ{ãÁޅݼà ÒèÈe3g÷ÐmUÕêÑéýñãC‘Ký$&>Ïû7¥Lb?K¹“ò²š/xxõê?•·4ok;*ÝúVÏ‘ìYhX,xì'‘½óWÕÊ¢œ–ú¸´`Zý²]Õe‘ÿDü³ ãÆ±Ÿ½Øj»¦Ò´oÄœg~ÂܶåÍ—O¼8ƒiæ6Ý× èDI¡i!«5Nb/—¥£¡xd(Kx*Ú ÍÚ—š†E©Ï²þªRV|P2‰ÌO£^p4‚œ³È»µ¶¡{ÜõÀ`¶,„2°&(EtT6j¾`™íJ™«5­V/4¶U44}œsгììþu×ÕÍ~rße x7Ò0ïºhU#Ñ ¸­¿ ¸Ò$¯·»R!€i]ßÓ¨{- •´°<—Z/F©`BF’Û`åz²À(KrL!ýÙ­Vå#Þ¢4Ñœ¶8ŸÒöЗ(Yì<À¶jeÞù]If9‚_Æ8œí\ aèI «¬‹\¶Š–íFb,†Ñ ³€û"߃:nJÇP7Ø›t·Òª¥9ú ï,{e ­/`’7 D]¹€, ÄØmˆ6θwƒƒðž6ª"ÂN6šìä–RjKŸÐxZ)›AàÏOg &šÞæ¸1€Dm•CÖêNA†ºá­4AžHâa¼]«n»R>‡<Ý"L4Iˆà:tD&|÷&þóËõõ”ûa ȱ›|âwYÖÎ6“Ñf!{?8J+kèTø‹Æ†ø Ñ?ˆ—ÛmQ¦Ö«zíB ¨\ÌÐxy»œ'¡ç÷qˆh­Z5bS„ÌâA„Üœ'Š"¶Ö-‘T…bÑB«J+ÐGÄâIVlZ`,àqäC¼¡ÁÕ%üînfû«,,\†a Ñ~Os“ƧsYM¥šjÁ’æk"ma$mqßv×¢°,öÝ!¤¢¢©+L}àÞˆ1ï ÕÁˆ£ãº•Uv˜¨Y:0qèøÖ±æ²sŽè|«,BûÀÂaVÁ˪º¥‰¤Áš} ˜ÇФG›°Ðùj©Æ®°Ø:ý;å]kL¥ j}¾‡8èºÒv&£L$XÆ¢í‘xzÔGÜçYo+‰A_=žó ƒ‘± üi¤ð¢¯nO·ŒƒE¶õÖeSƒÐy[7T·É†AèÇбŒÂè3î”ESÚô1·1‹“R×v†ó¾¦˜ÁØƾ j_Edí#¤›Ûc­+·ãë1xKG¬H‚¢›T§H]ËVÒ ²b—/¦‚ªÕ4ÄŸ¥ìÕô&OS'}¤hB¯š†áiM_Ös¿º¼¾¬…‰6®…zwΦI½¿æ ºðº£¯¹± ½NO6xðXàÙ ¬ß9vßée_[pÓn3ì¹Ìûš¤‚—æ•µÍt­ßköH‰$5-Æ}Œ%™u2m# ørÎ Ð`a܉ž£M–iæÝwUŽÝ‘%¼NR÷:±w-_±;:ÝAy±7ÔD4¹ˆÎÚÞ~ßÔ["ÞL(‡…Ÿ9ää\vÚ.4HlÚ›@Š0uÑÌlÂÜlË4Õ<ö‡êºíiEr4r’Ä{1H0—Töü ž:Ýc Ê{Méƒá+‚llALºi”ðS+¿ùÌœ*Làýòë Qƒþ )l>¹8³š“D@C‚’ašOZƒI„võþ=9ùŠz¾çÄ^â._ŸÔo-ìÑQIy*H fЂ£©M0ZU`vƒ^  ; mTCÄ'|(Ë{¦²ÄM‘ohÚ{ìÈ|ìÀþ†d@iØhºheÙÚæ´ÁŸ\ãZ=VS.§Ë‡5Ж™¼¬uçÚ4Óõl|èÿÒ0¾‹ ˆÕ-ŽS<$>ﳄøé7€ìÚ§Íêî~{Ú…aè§‚¿ö¼¿$pE2IÆ?%Ü*kžK¬ˆÓ?ƒœ"öÁÏ 5' žø‚‹q¡x’ ÌúWÛ¤nqd¸ŒTûô,ñ}|üÇÑÏ&)0ŒÃ^Ÿô±½Ä7m&àõ§}ÛØ÷Š”€2{£ì~;¶uòu;>?¤°ÄŠÃßçùtqøQqð]t¸ÍÈZÄ[2ÐúGÞa qd«ƒÓx“à~šX›ü@÷]Ú^ç¯ü5LmƉÉ-f2|³!Á¾ÙpŠÙÄœ¢°h5J]ŒMG2˜w)±hF,4ðŽ4ôÑ4´ïÇz-x/¨P¶·\úÖ™Úx¦¿¿ýÛj †ï«ýû­ù>ËFËUi=ôúêÆÕF>î»p×`“ÏáÓVªw)>P( P¦m¼†ÊÉ… {_×Î÷0mˆû¢¿É‚]ïŸgד‡Ó‰Ãè ýãÎiÉÔŸ–gÿóB endstream endobj 1578 0 obj << /Length 1541 /Filter /FlateDecode >> stream xÚ¥XmoÛ6þî_!´_l fER¯Å†¡C›®C0lKŠa节–˜˜«L¹zIë/ýí;’GE²•4]$qǃð/3£±ÓÈŒˆ˜dãÓmIYJX:‡vŠ‹²TÖ Nù­èfÎÎ8‰(06e-ñ]wÝ)+§ÀÎ!¡ÜÅ –Õ¦Þaxê—ÓÆ¯ÝYµÒQ  žQr1É3!,æpŽHÓÍèI¼®iœ“˜å¶Ñå0±XÎ7­i^s¡ú]¡ûÙ—Ê¢Þûæó£[~{sîûsµmO>MÚ‡4¥w†Æ÷rQ6Eçy³¢áÒ5íö^”îB'ÅÖˆyd $Éà»çú´²™fbWtr:ŽŽ,@Y` aZø<\8Œ§ËM]WÒ4_ó t© áFóüi+¡A5îÁΣ†€9¬í|°¥VwÖÚ$M§SÖæ3®Yˆ¾´FØÛP››ß 4å·±(ŒB7fŒ‘íD>.Óƒð`Ò¨ Zá•’ DÄþ—€å1_š:`Á¡yF’4™‚cïùådÌÇ ¶7GCln”¡i’ŸœMf“®ÿݱ´K endstream endobj 1590 0 obj << /Length 1376 /Filter /FlateDecode >> stream xÚWÝoÛ6÷_!´s€˜ÖõUlº5é6 –ºØCWdŒLÛ\eQ•ä8ÞCÿöÝñ(Erä$„§ãïŽ÷Å;ÚuÖŽë¼ü°˜Ì/yè¤,üÈY¬ÏuYÀ#'Ž\¾³X:¦ª¾^튬Qº8û¸øe~Ä=îz,N@ŸÁF1B&®=°Q;³à™#D.îĶÌe=<µÎ/ýÀI@8âÆ^ÐåÅ,J8éº;›…®;ývFëRÕ%Q_h[<4Í<—¥azï ®¶»\üå†îüóZ˜ï±}ñÜ>ð´¾!Î(ŒÇpŸw—•ÆÅ{D÷¨äóûÖ¿¤ü¦IT³ Q»BÞŠ|'¹$†U^Û U­D%ï1íîM·=”’·²sàe{ºÞ­7--6am‰…n/ËqÄ|/lKìB ê€3ž-Àz¥Š¬”ýXUzKÔ kæ‹WƺYâ²(M†6®†en¤É¹ñ3³z"?é=D©¢ƒÞ‘‰‚ˆº”™ZFây £Î῟ŠHéòöP‘±ô1-†jjudi!Ûb€ QVr©2ÑÕ˜¦ {!äù£•PÉfWY—/_ÿú¦Nw-Ÿ(ÔWƒŒ$§3rnCK1ôw´,®Þ_|EnÑ.ÇÏÓ:¹XL>O[­¡íéH˜›‹0@ãÊ»"Æ'Õª1Îôò\3ûÌvŒ,ôŸÛ¹þ¾Æ8>{¨ŸLQ¯\ŽçÚŠ×ᬿã°espûlܵOª§¿‡çâßÃýT¨^WXXëÝJéñwÐ㡺;~|õ+¦hšøíuþ½wMëM[²†;šä”%ëßÈF¨¼þ·ïG[ŸplìÛšŒ{·ø{˜â <&̇*suNß…ØbË5ò«‡)îRU£,Vè¸Ê È½¤‹xÿx¿kãˆÛ«f£ìÑ… ËØ…ã¸;½U•.¬ÂÀõ¦Xµ”ô±iš²~5ŸË‚íÕ'(Á4Y1GÎÜãÅ2½-wà •^Wb»Uź}ܱ³8u.Ô\iÝ%‹ÙÀºˆ¬ëì÷ÌmÆÕÄ(à]— ®ªiÍDžcN#œ³BèRn0S=°Õ':1ê^ðÏNrHd8Kp»0ûûgD“vvúÐ\mÖÃã3p4þ B) «j+ß¾iñ³}¤ªsÙè}hAd¸YŠŠÂ$d§=@Õc¾ìámŠñSÝ®Ÿ^ˆeRØæŒŒûÀפ˜"‰)à VFm¡÷r€7Þ[YQ–=‚0:CÆÂ‡€ºÙ§1oÚJ§,qªµÓ’WûVÊxÔõ¢¬¹k®rTÔ=—Nô0eqÜý°Ï¯ ŠM"LuYêšj—›Þ†Ì‘Á‹Û½Vƒ(;!‘\jBæv£™¬kQ©ü@;qæ»=mAÛ`p“†5ýšÅ)óÁ‡a5Õ(Y[£8¤Û\ôF¾ÎmÍ|.Žf¹‰%mÈð:ûÕ„3 endstream endobj 1607 0 obj << /Length 2341 /Filter /FlateDecode >> stream xÚ¥Ymsܸ þž_±“~ˆvjëôF-•o¹LÒK'½Ë¸ît:¾LÊ•¸^5ZiO/Þ¸¿¾êÍÊz3MA€²·º_y«¿¼øùöÅOïÃÍ*q“8ˆW·»•ïynÅ«Mì¹" V·ÙêΉåúóí_z‰gÇnâ ÇðäÍ—]W¦m^•ÈüÂã-fò¯ÃHše×Áiñ§:?äm¾„ó°ö…£××A9V`C]Uóø¡"*tô×üîyAšë²¥év¯J¢Ò¢jºZóú]U3Ãií{NEZ«¶p×סð÷yÝ´W8#AŽFei«~÷S·­æ`Ó¼ÖÅ#žÎ{íûn"›yüØÙánªi©WT¨òéºÐÃq šJ«LƒA’8×iUf¨HE ÃA§p¶¼9PwûHíiŸ§{"G:Ct⨚FgvpíKç¾;€î åܲašv|¼˜Ž·Õ©êàYEÚ{ÕÎɬ¢¶¬Z$|§Ô¨ˆ]cˆ]WDë*ÕYWk+‡Ú±Ê4rPmºÏË{’ù»'¼L«‚ç”·{–X59ú*–®ˆÌ_7 ô„SªƒÑ΋¦f‚‹ýÌX·¹*ˆ×ª`椣ÛÔðáþ¢MäüVjâ:Ö |8µ‹àVýG§ËTÓ6æˆ0AÆ¢9ê”÷_3®óH3y¹t{ùI{ͨ¡qrd°nDO܆rn!€ZKõî„=®}6ƒ[Ì‚S<…׌­¹f$öjxC4'&üx®'›_ÑñT™1rÀ+W5‘7ˆ#A8‘™Hvƒ~€—p¢ë'±…­SŽ®„À¶«KºÉVQäz~büú‰i"5Ü@Ê w$ dì t…hJGQ÷¸y0l!áÈ‹ŽJcãX8ˆ‘÷ܺÆn\¡!tmü ºÂ §–kÕWô1ƒmÁ§€¡Bý74€¦ÈÇ+n¨#-=óâcüQE§Z^ ªx^ÝëÚøt¶zÇ´‰i${çÚ%T½$"Þ.!U«±sk½ÄxŒFí<é|ÍËŒ(ŒFœ]Œ$˜§H¢¿Y`~É!û’¦ ìÃð u[]ò²*ªûÞˆþ£¶`Q¤;…‚¼RÓâœ7¬õN׵Ζ"ß^À¥5Ô¾ÜbÈuyÑæåKwÁ“!§Çq<ÊØ|ÌýÅ\À8|žÔ뇽ƒs¬Îäû±+¹(¼èñŒø‚Rôšm)IÒ¹«Ž{àt¯Ó¯DžöÚ88‚ü<Ø€BNµ7Âëã†zs7mhxÈÙ;,tŒ—C;„ŠÛß—p7~H*ükícÙ‡Ùxy€ઈ‚´Pu%9tÉ3€ÈòîÔ* [Ýž´æÎÒÑP¬qj r”X*ÞmŒf’÷‚Ò¢¤7Zk!wùד+Û}Sß7ïʇ…\ïÄò\05,L„ÁWW%ß(¾ +j«m«ŒÃÇTÿÅò)*Ä\}ÄÔ0¯™{V(›=ƒ¨T'Iª 5 "ú‡Ã W:ðž’ή®DÝ,ý(³N_Xè¡„ÇCxy¯Ö¢¾¼¢áœë ‹j!sÓ“ìiRêHÚ¨šyE/«³95”•½D˜¥ –2лæ½x¹ÿ ézáà+Ÿl™s‰ ÇP„Ë`\H †äòÿ«çG® û˵ˆÜMõK 'ÃÄw¡¾ºQÓ¯à<LjÝ0ðéᄅÃÓèØ}¿×š ,Ž(〼ˈdý ™çôKÝ‘gb×À&½ aóàëÞÊX9éß;å¾@ûóžXê{ÍcsÛKCùׯ´XÙ}÷4 ~Gá'¼QÄH(ùe_±ÿ»¯˜ŽÈdÿ&¸»[’Ôs"údÓ[]Hb¬¹<§y/ãïÝÏyiû­ýblb3 þÞÝùŸ?Ÿ¹‘Òš§•UË–Íð­ùÊ1¦—wÆþ¦ÊÇ™×.:ß¼¶Ý£0“ôâY?>þühÍ»ˆsëÜÆ÷(Å/v½?/ˆ˜0üˆçª‹ØûKuÂ(¼ZÊä’ºîoÄF¤þ†Õ~ß@p¤È¿2Ï]Õ•#-«Ï oÓmp®nXt54,ËŸ¿uûIŽîÁjáÿຉ6þbn~wûâ†ç¨a endstream endobj 1617 0 obj << /Length 1335 /Filter /FlateDecode >> stream xÚµWm¯Ó6þÞ_ñ)•¨ñKâ$HÓÄ6˜@WHƒ²/À&7q›è¦I§”ûïwìã´Io.° t¥ëãØ>/Ïy- v ~_ü²^U}‰Ô¾jª½ªqcªBã}½]ò8Üê¼7d¹Š„ _n¯8=^®å]8˜È=Uµç¹ÑÖV°o e±·¥nU1øic½yìqÓ´žP}¯À΂øX£»²ÐðrÃ#ûÎXÉs˜ÞÇx¦W#ôéáv ûžu.{Ýô拺|Ey•“°H$ärc=w£öžj·×ébý2‹c9^hG‚ÿ\ÚXªú×=òê¼y÷|¦8qN"&«íUb^BǦ­¹ÊæÇÈp*Ê †/žÝ¼›¸´õ·Z×*3K"Be4Åâùgµ?ÔÚ|{h¥À¸ ФM:ZŽ}U›GCx¹ ¡!Ù×w»CÝöñùÁ|õ',û¡EÜ ŠF#E{½Ó]eÊÿ_Õ?A­i»Áõ½^FCqïl}XÕÕ­Û}¡r ÉIæ»Tn!(‰hö*·66ºTÉNU®zmpïJ9’§RÛµ¾ñÇmc‹rço+\šã~ƒEøÉv´;Ø÷-2ØxK¸²»ÂÊ7ç,TyÞvEÕìð¾†W½—ØÚ>pjæjxßÖºSM‚cƒ%¸Øx=•U^â‰ÍhûÙ6d»ßZTÞã®Ð5*¸„ÎÜÛ¦ ¼"öÔÕKüŠßm‡þm“À6¦,òmÑñ=6¹sJó_]G±„*ÔáÿBõjÎ8Õ¨úÎTæ1F¤Ñúªf•º> µè1(à¤A· òÍý‚ á•°sùÞ(£Ÿ>­ ñ)d‘;'øÑÎ ù<‡í4Ä¡^MA‰Nô´¸ç pÄ©—úvâB̸Riƒ™“TJ $‘ ?Ï#ÍÎ\qõñ:ðÓÍHFÙXàCÁ‰§E{Ü€1O'`L–!8‰H}iýÀy<½ô~S:LL,¹¤ªA3$ñÀ4hnq„®äêhü]Ĩ¢¥åU&&a©¼pLª‹À¾SÖZ¼ß7ÁgÕce-8ý\Ì¢ÞìËvß(˜EÒÐuTFGJZ¡`¢íî÷{u‡ÄÆ_¹ÄÖsøÆFÚø…éqÈcÃÔ6â’·ºË«³TD`êï8‰“³›|ïwlw|)‰d:MÎû@2œõ%ue¶mSß!eއCÛõx:1\A½™#NMÏC ÿK0 Ë›5tÄä|ŠŸ3xûDB ‡s7(¯ÄÙ;pޱ 7þõþ˜——¤’{ üÌYŽöpÎÌ5è;.½ßÖ®ÏP/m6¸ü„Ëëw77þ` ¿7Ày×§ã)~–f—ŒÕé.Ää  |@ÌW¸Ýà f“%–õî endstream endobj 1634 0 obj << /Length 1740 /Filter /FlateDecode >> stream xÚ­XYoã6~ϯУ Ä\ñÒ±@Q¤hRl‘nÑÄ‹}Ø-ŠMÛjdÉ•äÿ¾3J¶Ù±Æ(’ÃápŽo† ¼…x¿]ü2¹øp##/aI(Bo2÷x0©B/ ¦¥ð&3¿'¿¸Qz‡R꘩PK“Õ?²¢1U:m²‘ÐþÓˆkß຋Àí[…; Æ-‡±ˆpø\U#ø‹ÍÊMÝ[¾ß~¸rWòØó˜E"!F/û{ï3 Y‹Vö?þ1Óf4:ð›’Úãú¦nÌŒí1ëí§Ÿß• t*9÷ïMÓdÅ;,’Õ4Œ^m]®À¤Aé̋˴DK)ÝIòåööБ–h œ,OŒ!ÜÆ C€“õ.48’1ò ‚‰ ékpšnê6—îãyYææM<Ø~a̬>ÆU:튪nƒ µo?¦K3}Däq±¾U‰¢p! ؤ»7ŽùU^—  ~,ö*ìÒçÝ»ÀHúþþ£ ¬²é÷@ðÏ…m1¡“VÿsÒG‚Ø5ËZscÿ¹gì ‘„Žý²¿ÄÏjK©û’öcßÉâØ¾®Ý0ÊÖÑVnpVnÈB‰O’Ä>¦Týv·æv÷¬½5'žwÐ ¨«]\¿¤«unŽ'ŠDÆÀ rN«÷ˆERö2ˆ˜ÕK<n[ÅÃú1@Ôä - Î"¾ Àe©ù‰q üã'¯˜Ü}¹îüèzrñï·NÉ»œ¯bÎbðÂéêâÛß7ƒI`Ëd{Ï–tå)°W¤Osïþ⯃ª¶…EßËA¸Pq>‹ÚÞ Oû‰IõÀŽ Àê?¹0¿£¦Ú…óòÀúZ…®D\óןY Æñ9G¦š)¨™”p4§ÿ_M=­²u“•Å sîƒùÜf„Fní 0"Æ;ý`ä~ü¸£ÛSP0.TúXšSL«p¨âëo°NøvèT™fSõP:OXÈ»\þ:”jÀG£._¢Añ$¤üÀíÏ7ÅÔjÝöÀ3j"¨NóW—{À ”Ô}4:˜CؾKÌ7W·÷ƒBFàBQ_HëšMç¯uë¬.O¥ÍÔ}«rfl6üOŽ>ųÍSõe1åy[0V3S}ìjpe6`Fë_ß…Ð}²o°&°LÈd¼µ`ž‹ýÀ}›‘ø¶¬ZäåC å£PÊ/mLàƒØÿ4§ÁÚàI•¤¼ ©‡¨Î‡$âB1¾­T9‹`Rw%RY 1 èâw é?ˆŽ‡F"ÎŽŒ±Hãh›]Ïk#4€5\êTÓÕÄ4‘­Vf–¥ zq¨}§Ð ¹Ìþ¤kG»tÞ\Úi(¬æ›Ü±*hnSXÅ]áÖSÓ Má8TR»J‹ Ü^½@R'œ³ihç,CwBë©s“ÂZ³w¤Õã¬Dâg7Tnšõ¦©ÙžSãÕ1î_oùô×mÙøpÆj¤ÿ²­ÝÎ÷Íf–¹(+ÊÆ<”åãeUÛ» ³ʼ'ûº*p š ݸd­½|Κå‰~‚^¢õ;WD¦œóršæ§r‡X•ÝJ ÅÝŠ»‹^Te4Â"øPmM]dpao]q r°aÔ/ß¾Ôéœ^»½M—ò½€C„ÛI¨剂j§C8qÚ¼JWýIà›ê‡)žÚl6d`ó²®çámwlt´òýßÞIHŒ“ß®ÈöYB@Fê}\V<|—““`9ܹ£h“m6DÏtW¾*›µ`Ó96m{—Ü¢+½¼ Ȥ°êVgÃ|”°(à[1½ÛÈ~ݸ±Nx²ìÃŠà ¢ÒhV•ú Ò{ N¦ÔÝÖÎ0¶-ž°÷¼Ìàþh3ôfƾÑX-r÷܃ êi¹vûkÙΑY­Ë*­^{¹!tv·XRÛÌ¥¥q[ÉÝjøØ‘FŠ6-"&K½%r\¨C—PKL8&éíñÍ*š-«l‘Ó`bûØtþ“ÆóÁãœÍ=ˆ`¶èд}±0”)I¤´i_=²öM°ŸQ³æÕ¤Ù>`xn’@…ÛÅSóGË6+pú+š˜" endstream endobj 1647 0 obj << /Length 1228 /Filter /FlateDecode >> stream xÚµWÛnã6}÷WÛˆ¹¤î ZY4)ºXh×Û—íb¡H´ÍV–‘Nœ~}‡7Y7ÇÙ}08¢†3sæÌ eìm<ìý<{·š½½ #"û±·Z{c„±—ÄEï­ ï󜋯U¶cÅâËêýÛ» é臘 $cZ1!Je†­ùÛÕìaF@Ä9Yö”ÆÄËw³Ï_°WÀË÷¼¢©÷¤Uw^HÀh€\zg¿µö†«ßºáŒâx ŽQGãðÛ³€;éôM‰ò‹X,ýÏëû¿X.¬mü¨L‹iˆ¢8þ`@Oä?Ž à'&ò†ï%¯«†–~RoI(Â>éãÿG~d‚ÆÈG ú|Ëò¿U(Ëm&Íž0E˜´é:N˜L@j¶™5§±b&eÃï>ž$W‹e@È<«ŠŽ_s¤®˜‘ê5(a ïØØZc÷v\^mì‰Æ¬l·—Ï*HÈ Nui, Å&>•š ” H[Ü¿ÞL „² ‚È©€»±U’‰ïTÞ¼™°¢%§¡(BvR”F‰SN ž«ŠÈšg.¶/pK}„ƒdÄmºƒ”Ufmë= à¾3ËÉݵb!ìœæv5,«#¹°®9V*N¨j£Uö%Ï3É »¯œN%‘¤!ôU§.™nŽ—z#FÓSâmÆñã‚DsHYÝp᜛½FX ¾ªÛq$DÒ1{±GCŠRÒö¨×ËSäG¾·ô®Öü$² ›œ¯#þ8Æ£ ·å|]žÓí%ÿØAÝä¢ÐpBsê¦Y<ßv¬’âEXÆâqpô§ž¶-yS¯YÛ• 9I\ÊD/ø?J§<°ÿkŽÃý‚c¶í·¡Ùù ý/ƒ„ è4tŠç"Ïʬ1ò¾a…îCažõ8WBÃä¡©¦¢‚ý6äÕïŸn'\ûj?¹4f m»»ùðqÒ‚“Aõo6¤Á·Ì‡e†È“Á4³_£Ù¬(ÁdÅjff)ë d°ž¶:Â)鮳cîDxµ?Lä°“nÙn_2ñúÙ‚±8lk¾| ÷»Å2‚›ùÆ,E&3#­Hžî„òÙ<è«B YÉ‹+«Qñ‡ƒÕ6׆À-è¸ v2ÏÑ/Z3 ïŒ*=ßãP…”¤=Àïr²E—«‹U Y)j‡üÑBì^ZZ¹.»J\OºÖä÷K«}Ï«Nl óçÒ?˜E°‡¯%«”^ÕÔO}\î÷ÚŒ¨ .äcµíñg°7vOH^–Ú¯/ñ;tØÕë±;T |”&q/²;ÕCJ0ß‚Z4ó܆)]è‚í²Jò|~É7[é*¸àë5|T¦×†ÑY§g§«~Û¶¿Îœš|¦€ÎGzýZªJ.¤söÚÝ/z÷©å¬®v;Íqóu›H—2îrx¡©m(æ/ü0*{òÖÔK(äÜÚBßf |f2›ªG;$µÓÊÅÁÛ6ªLÈdúŽý¾Lê4ˆa¯ŽÕ>¾ÐBÓßKÕy{¢ZßJhÿÉœë'^Úh4°á?ê¿¡,ô endstream endobj 1658 0 obj << /Length 745 /Filter /FlateDecode >> stream xÚÕVmoÓ0þž_amX%âù5N&‚!Є„è> ¥©·òR·Ýþ=Ží¬I—uŸ|±ïÎÏÝ=wWwÞë©wxBˆ`L/FR È)Ó98?dr1ýpxÂxO“ …ÚÑÉš¯ÍM1«òVÕCî‚ÃBA¨mÖÚø”cäÑ:r¦å*γùÄç¼ðí:_.šÖ•vãc#Yå2.dóq䬴ˆÏÉÅÐxoïѦ|ËôãqgJ0ŒphM÷í¡²uÒZ¢ÖÚî.d}YÕEc¿b»\åÕ,έœ¤2ùnÅušåÒŠi¼’ÆÝÐ[—VhÒjm¥›j9Ï~çRÖÎ¥J°¨«Y.‹õјy?˜^FÆTPGtMªÄÕ=Ñ­³Ü%e]Õ.'r%ËîT¥VZÉDUuÓ…+ÇŠª´Tä¨G+BÄAÇÄgVc@<YH;µA8(™á‡ É'$„££ùŽ•ª³ÙRÉ£S•K¥dÝt©òÞN½Ö&àÛVãACDARxçÌõ¡ö i‚µQ-à փÏÞ§ÛöÚ^M?ëÀ{ý¬± ® :¨|³ˆ¹Õ®l0 0Qˆ»¼½×å \' ´k5û¦«äöì²qk>u]™®eVO?¨ÊB–êÕŽDP}µ`¿’;À‚‘Ƈ¨kß7²Iêl¡2KŸ;yÛ‚¡f‚H;þÓÀ{AoõÛ[(‚z¨šKΚøJŽ¢»‹vXâ-´ýê¶$¼îè÷€ãz‚õÜZ¶€›@p½Å©AnE )E:JdTUn•‚÷³…2M…ÿݶ¡f²àÝOÜczf„2Ö׎~ ~ûH>I?! BÁ“öÃî þ!ßí­†ìÏ7³ÜJ/Ý»~vzúß7Â=÷úΗ¤A¸ùÛùû )Ú—nª¹ýÚ®« ææmvû—½ùçàš×ÚJ²Ï '§Õ2Ÿ[¹ˆU’ÂÑëŽø RE–O endstream endobj 1556 0 obj << /Type /ObjStm /N 100 /First 975 /Length 1770 /Filter /FlateDecode >> stream xÚÕY]oZ9}çWø±}ñµ=ã±]E•ú¡ìVÚ•ª´»›öR¡¨©²ÿ~ÏÈ’É%¹ì‡ÔÒárlÏÇñøÖÇHÆÙü+ŒÂߘ ý3~Éj#^±âLŠÕð&—¨F0Þ‘¢“øD=XÉøàu Žub)ÆS#áƒb]«± ú #¸è³°W Ó'|袾„ Ã$ER/°3Áy%›Õ?XÞï”S°¢Î‘ VIj± uDX¹Ž(&P]5ãYÄ‚9ƒHÄ& ¦K œr„¾1E®t Ȭ,Àç¢ÄG(¬„_BÉ:-æ&Gu|êt—±dC>¨›J%•ž1vî0‚¨n#X©‹ó†„H­`(aw°ÈPõ‰86ì¤Z¼¢VÅÒƒaýÕ‹aÂ’°0"†hª!êfA°8¸’ÕÐHŠÇÙëH<çŒ\€…T)N#„¥¹D‡ÁR' r&:êI¹@ø<Õ Á‚• \]dX©’Ž4ctŸ‘ƒr"g"bß«é5–EwÅâtÂÄ%ê$„‰K©“d¿ œ¡«’¦0éÖ‰ª‘ùØHÆ ` ^Ê)"ê<£ê ”‡pÂð¡Ä¤+ÀO¢[HN ¢0VH5ˆ¨I•&’P²KX %Wš¨1É•fd#…uÕˆh”Ê“£I®òD&¯t< Xšr(©D¤«jER޽££^óÖœ¢œªúÄ4¿ýþ*ÓYÒâ.Þ22¹?÷^¾¬èãédnŽŽLs Ç1Ø×aǬ!“åa¬¼ø¢‘ÆÖ–°W,`˜¯y?›> çæÔ4ïß›æãðznn–úøç÷!~èöš7Xv8™_jýGßkN†—Ó«Ù`x¹Ð„úì×áÙ¨ÿzzmNuEDØnfosùŒõú3Lü‚j¯y5™L1ééB¿”VÕ¯¥Q–†¸•áWÆÂ]w¨ÖÙz͇«/óúý—Ñä[¯y= g•ûÜüܼkÞœúúE÷0Àî‘MV©f‚гˆ)’‹-h÷ªºüƒi~š~œ„ìÙÉùÄ~ïÏ.‡öäjl‡×ßgÏÕ¥Ýð‘b5W±_KØ3TÆ20¦`ƒìæó¥¿¢3ùÑ Ô”VZsWã~wIN¨ø5Zña$}*µäs6<MFóÑt²‘ì)í‘ìëà›+šbrtŒ–¡/-ÑT,§ØMØ¥vaíÐI™¹-Ÿqr¥² ³«k¹U®Áâ6k0ç½jPœÛ¨Á,]–ú^›½×K™Õ[Ÿ/Ùj?OÍ@Ú™éƒùõ¼æúå¼?ø¶‘æ¹ì‘æëà‡5}:º`ËÖty:šE¬¤ôÿCÇ·ã_qm]‚‹ ÚÒí£E×ÐÝ¡Øë%ª¤înâÒF©êõøÉ¥º¼mè5}i„•A+ƒ;-çE{&µ·÷7ý.š¨ê{ZÅE×Úa›Ãò2ál‘€ÃÂëRíù¡&Ú¾Cdf“þ¸Û6šœÔ6:²X´†".ÁàRˆþÃ}4´„üˆà”~DIo¨…dÅûdìûÙè½Åa‡w/ø!»|Ã%zdKiÁe¦»ú¯¯ªZëÿ-ðßê…ù‰Gú-YGë„ߢþÉ:¡/Ûº|Ñàq7Ã…>dª]5¹b“Ïú ÒæôPí¡‡a¿_‡³»ÅWƒå÷‰¬ßÙ½=-Ê…Ýí1·Ä–h ­¾•k‰Fé$nË›!×™BK4h+ÅàU ZïrO4KÒ­ï%‹óû· mê…xS(> stream xÚÅUMs›0½ó+t+¬è Ntjwšé¥ 9¥™ÁrBƒq ¸qþ}$0’:Ótz°%ÁÛ§Ý·t‹úä|ˆœ“…ðQˆCÉ$ŠVˆ‚¹HI‚}ÎP´DWnZ~¯Š­ö®£³“W=¸ «¸œâ5Ä!–}9? [‚螘1ã(Y;W×-áå‚Wa€è ¤‚Ã>CÎ׎ïpm¼ªž÷”`)(R„aNý‘÷)D­v ‡mãø\z3æwsóC'•Ù§KWigæXmÌ{‚¸—skP˜uáQê»§_.æï›k'•!Á{MÄ\NäKú44þÔeR¤UºÉQï£$‘hÆ(¦Ü ÝéR›@VÛ<©i¬ 7Oqi÷çï<ßwí!ÞV›u ú˜cƒ,¿> stream xÚµWK›H¾ûW 91ÒÐé7ÍaÙìÌj£\6q”Ã$ܶQ0Lg4ÿ~«` 'ÑF#O7Ð]]¯¾ªÆÁ.ÀÁß«?׫w,”H*ƒõ6 #ÆeKŒ£Áz܇1¿þ´~ý⎋ÁJ–p$brìš"oZj–­°~»^}]˜â€œäRŠ•Ùauÿ øø:€O‰ žìÒCÀ A1g0/‚w«{yÓÑ*OÙPy‚‘ä$ˆ±@ ¯XÚ´º®«z¤X3²›½HgÍØäl ÅD·(ý\ÕíG,0üˆ÷ÐP&‹“ÝbÐàš‹Ðk1ë™0”`ù3¾q”3”À8fîð¿t“Õùc›WåÈ ÓqF„<«E'é#¥bâÇ‘‡âò„‰Þõc/‘ɘw[jÝë²¹ŽhBÂv¯ÝÄr3H˜bøZW×T„O¥ûô”·{¯ü!Ô» ›¾ýNQÂ$"„œåYŸp¤ânºŽ8cáºÓS××$ô ’0÷f<ÖyÙêÍ@K;KÝð9;DæÄ ¢Œ!)ŒÇ J„tg´ušñ‡yéÆ&?<ùGŒ©• o¶U}@#µƒÈ…"")E~5zöô ÑS}F8‹©3†Íœš[÷ÔVnt!öïœç¨õBg©ÙÙVµóuVŸÐ@{4P!\ $¢Ó`"^[{uƒ…Súž‹·Ç¢˜¸v’hƒ9Ó€äÓã}“îôbŠñ¼dóŒ/¥ìÀ±Kš'®Sù{‰—Ç1–œ«Ëœûª* µÎ뛪mÆIÝ`¤.X Æ"þ(”S…*~ŒB/ÅÓ8ÃD !t&•E”°Q*q ”¯ÇܰÜ7ó/-tÙº÷Mß×'oL†%yùH#Êúõžš¸£&¶Úò«·ÙäÆúÔ䇼Ð)ä±nnÌ# 3=¯+¡.žÝÆ,…/›fîíºÍs™òÌ%*1ä“Lµ ‘œ¥`¡âðÃ>/ôŒGÀ©ñÈ!t̘B´§¿}Zo¢¬Úƒ0n™ª±S6°|¦CÀÅI¢Ñø¡‹Ã¹¸Ã©XãnÎKÝY…+qPX(£BÜëÖ¹‡º1¸´;Ú}ÚºOÕÖ¬ÞÂG_^P¯‘O@´.³²ªl몘åºßÇs3y1a¹‘íw#Ž«$l¿éöÍCù® ôá±< ŒÃ?ÜqWÀžy‘—»«÷öª¬JÝ?r¯ŒVó¢ºþ6'üîå›w·ó»öÕ¡*ŸÍŒ2_´~ìÏÞæuÓöO†êû[Ëö:ûò6 ÿ½Z Cú}|.ÿ%t98Ü@FÍ…~r1ø´¥V+–WÚ%†9Uõ§ZÄÚŽÂ"wP9fêp×.…Çå%­õj2ËOÔ4æž…^*òê°1Øö{ üS›&ÇõQft¢ÜÜ#ÐLÓ¡ŸÀr%dø*-ÝÇÏ~=€ÜO¶3$F)Ü\hú)IæJ\‰NUkŽ¡Æð¾cvù5#¦”Z’1äˆÆã¼·):'ŽÛ«Ô©O7øgÎX ÷Å_²Õb£*m¡3pÜ{tùÕ¢ë Ï®­±ÑëºÎ­'‹\X¥¸€4"%â`mD€5ãxžž.ƒ-2ý˜ ÈQ&\¢ÁèEÚ’ã¿ìýÄ#ÐLÓI¦Úe¦(™”2¿£¬ü+ï $,æƒDeŒpÒ£hýöýíL|€[*‡ñésP:a½‰¶L1Ë vÒ]C˜â?{½„ŽXÑþZ{ÈŒËÝCZï~ä’)dIßúµIçø޹@”öGÏôÓ¼Pp èÕ2ºØc7zkx==­ÕÏZ–§Þq>v]w vt)‡ç§½îø¸búBvlt „n01W^ õÿˆp˜ endstream endobj 1700 0 obj << /Length 1748 /Filter /FlateDecode >> stream xÚ½XKoã6¾ï¯p¼‡Ú@Ì%©wÐ=ll‹¢h6mQt‹,#Ó¶[rõˆýïáCmÚN/{"E‘Ãy|óÍHt´ÑÑ·o¾¹{óîc2’Å<Ý-FŒR„ñ(‰)‰>º›þœ¬‹¦åÓ¿î¾÷1H›CÊH’‚$µ+‰pËjdÛñÝG ÎÌ‚4ÀC3žàš>JVÕ¦*_6#áà¶$&YÊímßUSMvÓY&“¶2c-E«§¢ž²t²ì6²l½´+Ú•Ù·’zÒˆ™•0#ÓYLÙäξËŔщèÖíµ6ß1…‡á,²¥ÜŽ=nâIÓÞM× ;a“m-Y?MY4‘ÊlôH@ F3ÆHEz;¨Ú€:Ù_I ðX';ŒJN£É¢2゙™wb½nôt —¡Ö¸¯(õÚ¼R )Š.}¹Í"’îñt÷󯷾̆„×›MÊÓ(^ •‰”2z¥0:ÍåÌ/È ƒ”—9øy"ãJVÑ!ÕeQ.õ‚¥Æ¦SæÁ\yF1RøÁy,Ó¸¯aÉg1E}j¼÷˜›’˜öŠ…‘ Ù8yÑO)ÊÖ½@›¯ŒbÆj’8Ž]«]™·E…pŸmE k!æ!EÊä(DsðE-¶z—ÎT˜ «yïjÜTAµ€¤Õó A´× yRD_4z·,›®¶Û4:u„¨Ë<ƒµI eþ3¦GÑãµx˜Y¨+8X úmб]wòDÍtüÎÿ2€šqÕ}1–e=Ë«²…>£_‹Ív-¯QÞÆ ‰qØ™‚‘™–õò“ÒɶÀEt°™s²Þ”¯zc÷;B¨=ÿ6ZVŽíÔs¡‡=êð©U¤¨fâQ6ÎÎ'QâamŽ—Ýæ çÕÂl¬ ‰Þ˜‡Mücl‚S².r½1;Tá(¦_ü£Ä I‰+éË•¡:´¡‹]÷r÷hˆQO¢ÐSGÙÞ+ÆÇpæÚ8Á.Ù³ýù™GëO(e`F*7c0Ô†C²ÄA†jÓp²…‰ß¼X,¤*ÓúYw|ÖAG.šÃ°ùQ­Êßøôk%HJ‚ŸO`´/1WWW, axVˆö´ú Á³Ñ©ÒcƒÔ$÷öYxFЇg}>†zÃ’ aD{ÔäÙ,„GñL~0ÑØIäp P=våß]Õ*v曂ßW¤_ºíÕø‚âWWöØÍ{=²¡ÆÐ9¦IìhüSiÜ uÑY¥·ºSêIŪ«âÐÑcÏDiWÕ–Fª; …¼g‘hbwq€P/ÛB¬mB@Å=rWOOä³²˜‘ ‹.Qkð¿©U<¢Fº§¡¹Âo@!ÔùÂ{è,¯ZØåif‹V ¾Žd½”z–×<˜þ£êŒYؼ¯ñSHyK”eÕÚÈ5½®ÝC‡xÈ?¾ÃðÕü‚ðÅÊw\"˜ýâ й\íY¯ˆmh¡%æ±7´6‹Ö²ózXriDàûïÕ&.JŸŒ!?~þê’Í ñ—qt¯©9(v.‹¾×YßòYh]ïâp[WOÅü £AÊÑds"›ýã]]•Ë«±ÉeœšŽ\˺tÝ9ÀqXy{D]G|äkèB¾€g<ŒUü*SÏXí-=Ͻ[MŽ|c£ˆD!÷ÛTy? E(×¶ÚŸ‹ñqœËêÀða½t;¶ÛͶ}ñr{[Ë¥í§-šŸ8}0Çærã¼xmëÔ^›g¬ršÒ Û{óUU5Ò-ÏæwY•' )ʦ•ŸPèßà•½?2êý iµ¥Ëêq?PÁD ÿQ\h™¬l^U»×?»NXçö,MÛ37|(Wµ-Ø2æçÂq›r‰™/eÑWÃ¥E)áçk…sŸAÒA6nkQ¬Åãï7ìíÝ›ÿ†ûáh endstream endobj 1706 0 obj << /Length 1633 /Filter /FlateDecode >> stream xÚÍXKÛ6¾ûWéÅbFõ ÚCŠ&E{éËAI°ÕÊ´MÄ–JÚQô¿w†Cêá•÷ @N‰äp8óÍ7#ùÞÖó½Ÿg?®f/ÞˆÄËX±·ÚxÜ÷™c/‰}‰À[­½÷ó$^|\ýúâM VŠH0? AY³¯Š|u­Êµ*·5®Ÿùö”oᥰ1qãRˆÈì\ j³ûU݈~ä?_,#ߟƒÈQ hXœe<¥ußÑôj'IÀ}$ݪfGÒQËZ깦Gy86's½m²ljzTv”Ÿ[u“ïa‚ž›ê¥;›û,‹²ÞF4ñ ênyÚðMš+–&ÉÈÜWãs{S×íq¯Š¼q¶–ùAÖÎV{ÅOòhíº¶×XËMÞFhVNk [¿Žßöíõè­˜|Ú·‘ã;!ßùmmío V?‘?€A²fáó7­%da*ܶ«Uy:ÔSª³Ù}ªPJÜkçey$©*÷§Þr#l”v0«6Ý\-)Ë,e±àã8¬«¦¾rˆùßcaÇÞKÃÕÏŒùÏH©ßôÙ¥÷y= ±oéjhäco¦så0™—–ÊM¥y£nì„ÔºÒ“·nô ïû-]Þûl’â‘FF›µæuáÜpmo_TåFm[íèÈ%Çm®íÊÛ,Ý-ïfbKø£“úû儎Q®^JæØ-€ª³ïÈÜ$c ãP£FÁs~,€l'|8]õÕL£ÌoË¢QU‰ŽcŒõ¾¹f\¤Š,>]åP!¶å(Z«?ß¾†iâè¤ÜùüáBèê„«få hP¦ìäæ,»ÉžÝî[.þÊáCç…¬Ù”éNÆjª]k¡×c09°É/Xû”=?¿®Ú¦³Qig@¾|ÀgÿŒò®s ÿ:Î^¯fŸgˆNßã]§) R¯8ÌÞô½5ÌÁILd©wkV¼s–„Ú½÷×쮯9M7HtS`or£A xì”ÂQ3Æ–¥]:­Y€ÍL¥<‚*¦°Ld->ïr5¯Ò»N¿y¢…#æ;ŽÃ¡?¿/‡Ô;ƒ‚‹YÆx=ÅEÔXÆ¥H £ˆnô“¬ ­Ž˜_#?œgMªà ÀU×&Ç ˆîöœýŽ”…°t²UíÑÍèœ4`a¹mq½s{"æºq$áÐß0¥ÊŽ·.»£°ïhdy3qh°¸;»Ý©bgպìÐbȱ¤ “ÝÆ6 E©I–åÒ1cÌbà%D+s1Ð l±Œ3AݵHÒÁ­ðÉt¤(`݈ImFÊY‘$óJ«­*ó=MÜ,뾕V »…„¢ÕÚðîÞhhé=Þ¾Òöì²ã€ñ¹¾V ÄÄ&BUZô+‹÷SÕ’Pe¡6§©¨ § ¢BçOÄ%cišÃIó¶’.É¿†ÙVÕQ².Áü0cA–¡ÀDÄ¿¿øõðø&í¨Û%1.ðÁQOøB¤,êèèYOù³4C[KžE]z,øüDoœ‰ª˜ëÌàZ°„Ï'ó¿¿î–]¿ eÓê²~N€!gq|ø13L£`1"bÚŒ„iÒÓøÔcî& ±;•Ój ǽÕOuU»S«¶\Oø HæûüÉT•d,é·1»bHÀËÐOÀK-ìÞÖùVÞ˼ðhH¤§ß»f"¤¹aDö|ø0š'꺂mS×€ˆ_€CÌ:Í—-¸|¹Ïðž½ÒH·îSþþŠuŸ¿À¶³l?‡t–vŸÆ¿›j¯°‹Þ rÑþ)@1(a„Ë0JÈñ‹ç°_%©n©}0=v‰ødêIé‘:»Tò²QE=êb‡llìˆè/Imù¹­ÐÏ¥½ñˆ]}|œ—^w6TÔžpì9ÿ?î\*•qÔÕ­8<·æ›]ÞÐ4~„èƒ*ME43V…©´£<˜ ;z=Ñûž['âðŽJ,ÏÜ¡ 9óxjH _+jôiº:¸-’ú²B©nòâ$“ñ°#€ê@g ¨/«íÖ[mÕÈ@ûUú(b}jà\½z"^0»¾àûÐÿŸ—LK䔸®É°åf“Ì­õf]j endstream endobj 1714 0 obj << /Length 1536 /Filter /FlateDecode >> stream xÚ¥XKÛ6¾ûWéEj†oIh{HÛ¤@/AÐm{È©ls×BdÉ¥ä}üû’EYöÚÛƒ¡5$‡óøæ£qtáè·ÙÏ7³·¸ˆ2”I*£›»ˆ`Œ—Q"1ŒF7ëès\Ö«¼üZïÚ¢®šù—›ßß~`É`Ç%)¬hµ“Ḭ̃ßtå@wá•41cnÊ_óŒÆy¹WÁÌà ” M„É$E2·,ªuQÝ7·X`ø‘ +S†RÌ;+µj÷N³à„ÆíF9áaN…5Ä~ q}çÆërí„n÷VTsŽã‡¢)–åónÏ‘­ " ë6},ÚÍ%¦&)J);i*LˆŒgÈx‚ L§Ø[?_PñÇ1Ž$éVVO;=±=$¯„¼FÅ„BzHˆ¢Dœjß?åÛ]©šÉ N5…%@PýZwu=_ŒãîùFÞØ“cÐÄpèÌi.s=Ò„‘^“‚{Hâ4¿sx°¯‘’î¤ÿôþ:(pÄÓ>ƪã5Cœgç vy,ÊÒYºTîÙªí®Ö¹.Êg7 •Iµvo›¢ôšêI­ö-dÏ„Ôg/†?< Ô%þ™U èa*Â8åö.oZeðÚ÷þÀ¹6ïßúÿä×ûMWãXŸ^ÒæÜû›Ù¿3“Ü8"=’‰$C"cÑj;ûüGkøë"–¥Ñ£UÝFPéÞseôÇìÓÉœµpÖ7X'9‰„¤H&É ¸$=êŒP”¥}5þ²É!°¢ìê÷¾¬—yéky°Úô1FpõŠcÚãeÝ/FêªæWÕ¬ta·?[Ø# aqõ-¥bäÀ—)â²o"Ï!e‚ÒDt³Vƃ»Iz—Á‹„\ÓnÔB½Ö{ÛCÙïèÍhîM›¯¾9ñNç[唌Ëg?]Ý™Påû² –ñj¯µªZ‡ÒÞ¾¦ëÊä0AFÇ;3M˜sícß¨Ö Kkˆ‘ÚÚ?7ªÐ>+L[2°o™÷Ǫzm'øsÑ7D#Z¸,ˆ@³WÄÌ"À!#Hfü(d$“‡™{$ƒ¨TnH͉ˆ¶TÓØÈ™±¢é¾ :?ä­Zƒ)ЊÃ5­ÍаD[kƒ°n+Uùx9ã‚xõ.o¡/é+|¹Û7ù’"JûÖ“¯×>þµOÞ»C ±/;¥·yy =GŠøÈ~Àµ,ùɰSê›?ÀûeŠhÖwƼZOq(hHTL¬{Ö1 Ñ%uA‚zÂ{Áɇ²d™ñ-bøx±U2„<ð/ó¡í4ê— Ç„I³.´Zçúz´¹d™·­ÒAyðß‹¦ä^ d׆ÜëÏ&¿W—¯ØôÀ¿!ßi‘GAÇÝR鯪zèB1ìÜÐD22 Èn]„Žf‘é*˜RN‹‹4bgäPà豓ßiù÷û-”MóB3<çd0n|E rW+èØ:µž* Tž^Ý1%0öBÉIÄÈ•P$3”°¾â ¶‹¼;'±ƒYt)’1è¡·€Ž•¡³ö½²þè^‚ú‚ š¾í4¾“žöJv%„ØeÙ¾Üjwý¡¬ÎW}1?; økÝô±;Ùä]ƒÎÁ©ñ‚½ ì«ðâôqˆ–‚Aþ®ªëÊ䯴´ž¹{t´ÄŽö€àµÚ8ÑGÌR¬´C3qUïT¸dÿ­»Ý<÷Œ~È…\l¯æñߎ¶`îQ³ž¶€èAÒD¢»³ÕC[G @p O @²Ê­m  Õº¸/*K²ám˜Qçã=Æ¥»N]–wÕiJѽ1£ñ­ Ôëõ޶÷ëM¯®J¨Îòq2ûÞÕ ëd²}eÜ™`‘•]öPø÷Dˆ¦g2A˜“«2E8¡/r’ؽ!™H}™°ÄqyÆä €<ÊÈ‘Y†RÁ®f\gG-™Í-Aÿ‚„•Ú]kÂûFpùDnLQŸ] —¯rÒ¯‘Œ\Kö|ŠK…¦ÇÚ{ º'ܾÿ¯ÛhU endstream endobj 1729 0 obj << /Length 1179 /Filter /FlateDecode >> stream xÚ­VÍŽÛ6¾û)÷b+FEJZ´‡´M‚½4qOI° mZV#KªHíÚ(úîФVòj]']0Égæ›^æ޻٫٫·$öR”²y«‡ƒ‘ˆy1 %¡·Úzq²ü¼úõÕÛˆnFPˆÈéîr)ó2»ãÍ'‹L3Ì«t°§ïXý0ÖD#à·|'–~HƒÅæ´)ÄHÀ@Ðlâù8E„¥FÄj/¤•±kËÊ«Rš#o,],1]kÑäQ*^ cÙŸ–&ˆb+÷Í‘êBÈILO1†ÄK@‹zŒ "11²¾[ú4T¥!é-/·fÓÕäâÞ‘Í’Õšf_ÕÚ¤[ Tù8@)µëVîïÌwù) ÁádO†ó³à¾áI~!¾XÍ>ïùçCŽ£Ç#C~Úó2³Õ^ Z¢8ÔUÛ¼8M"ÈÕUȃ³»ŒôìKFö­œMrSÕÂFêÌá¥2‡\šµ•b×ÚHi£rkAŸŠ“æïì­ïýñm²ƒÖQÿîXuVÅcö¢Úðâ*÷ýÏøŠÿ™6¦‡=üš¼T ê¢m\1hi}Ý´M)GeSòƒ V‘Kuû–Ë €®d±é9ßæY®d/aöf5ûk†APàá¾½F$Dqšz›ÃìãçÀÛÂGÐ…HšxÝÕƒaŒâˆÀ¾ð>Ì~¶ßt=ZΠ-ba@ ÏÛóykŽF‡(M°kêïD)Ý1¹²ý³jÌ U¿-,›Åªp wIâEÖê.{Á A$Ä_ã3²ØÄÈ"1*µ™ó³›&7…ð¢“d/ŠÚìÚGk»Æ7å=  EŽ<ÖtÓ(k n½úÞ:yý§Ø(4îa‚`þêò 15(?…!=‹æ(±äé€Î†Ezæ£0êy2ˆ½¼èÞÈ3Ä~LQ¬Ç ’Å/Ê݇º×U¾•†Ä,ƒÇ«“ÝÙ ëü¬×)·,Ö̹9‰¦<£t1ùð%i7{»Ç¯Hž‰ë¾-5¹Øº‘O@-ž*ùã“kÏdÕÑŽ_ð®ñìàñ3¡y„_þ¯+W~—¼ðœõVÐñbë`0tC—û¯Ëa¥ºÕk¾&‘a»×Nt©\}«~TãÎW£^9#Ø•tú…f{Òî µ«WjžÒCnÌiP1²—ÛoÜ¿B£¯œwŠiìxÐdˆáéò/N9í— endstream endobj 1740 0 obj << /Length 1941 /Filter /FlateDecode >> stream xÚ½XY9~Ÿ_ĉ4iú>Fð²vA$iÄ:‰ÓñÒG¶Ý=3ù÷[v•ûJ'3,Ò¾ÄÕ¶SÇç¯Ê‡=Kgöì÷«ßVW/ßùÁ,±’Ð g«Ý̱mËóÃYÚV๳Õvv;Ï…”¢H¿³jáÄótñmõáå;/êýÍ·+ŠA§ž%jÊ•MV`nØ›»¤ÉK7R}ø—ÏõžW‹¥Øó{v”(Õ%¶Ú,»#uï9 ä~(çìyÚ伨æÇíÈuϱ¥[±qæ«ë£\¯÷—ØòÃ6Ø5“üææŸ¦¬ùW;°ùÃâx t:ˆ%‘å,¤DÈQhV”…ذŒ0Q±±ã–MÅYMóÙDbƒˆî)×óMm bƒÐíÀ m„|rþ*hü™X=×ò¢ÄL† 2¾¥¸D½/›úœ¿¡|Zˆã°|ÛŠý袂5½”Z±ãŒƒr§ J} ƒR=mPz¸À–ç‡úˆ"˜•Mů!BÛ› ‹[ ©©ƒaÒU5…ÆC}kþ(Á ~C¢¡«KDZ’ @‡/’cœ±Èf,€ ÞU,™¨‰”åîÉÉÙ³6™¨# •adx…‚¾…à$Ÿr*Ы–,j¹Þ3šUW"My5šË«ª¬P;œÈŠ-é)²cÚ‘ÅÚxXqÙdd²$=|áó;õò†Õ]z­lZ¥c•Ç|]f@/NæŸTÞGQë\¢Eè:Tå¶Ù謂Þû=/°ŸaÇ®)6µ(©SqûG¾pÒ¦ cÐÑ! ½#¤aØ0G{¹ÚƒSýPˆp9g…ÒïG}Šú æP<8è/Íp&~(¶pdâ ?ÐèweóáöÖùö õjÙmSé…¼uìÄ  ÒÛ&8Z=ðjQèµÏ$Û©ÄóìdþÑø8Ý ™9åX`¹¾?rlºî ìƒme SÕ c+Hü!t´L•^WVŒ³­cš}º™ R±—æz‰zÕñR‡Ø3W-|{®*‘ÑÎúsYj"dzÐ!5:ä‰OùíI©¹ òmjÞ|Íë{ÎI½amk¥*›tOÊ‹S#×S´;–Í‹…H…Qc[ ù%LÌÈT s'ès?0©Ùª¨á9Hv=bÚ5ß°Fc=ï¤é¢±eº >0ç¥5Íjà b!Ñg‚²úAå 4`…RH 9EÒ8°<7îÈ÷b»-!ðÕÚd Üawhs2gÇ5ïk~8£:v-×k7PÂÌGØýùÚUS7sØn6!°å5¯rQÐ?1)¼}`*¡äE" V7…¡ß^·"`¥Öó…Dߺ”Ð2W}ÀªkÕW#¨hG3Ge‰²(T  ~lº+‰úÂ> stream xÚVmâ6þίˆèJ6¶óŠªJ[õöÔêtRuôÓv…LðBzNLãpÀ¿ïø-›°foÛ/xfì™gž™qì‚(ø8ùe5¹{ YP„EŠÓ`õ ( IœY… ÁÁj<Îòhþ´úýî!Nš$G!‰28Gë4´f+½IdO¿{À$ÈÁ •Á‚¤D[,p¦N1v?ÌIÍx%;#m“Fj„ýÔµÕnÇZ³¡YYÛ ûiÃJz”Ìläq#Y×UÍÎì+{5Ëó±)»J4ÊSðr¢°HŠ‘/%å|éûŸ?>¢§'ß?• ›#çEId”@BN£°@ùèŠßw•sû"ŽFh\±0¶µEY29ŽH^êàVmO-fuµÛ[±MG«Æi°7Bgõ¡³wÓvw¬YcÏ›¿YÙýh6=Ö5½lغ®¤¸Uð*l/t¯4ÏC„n@é7ze˜;áê÷m ó,…ÿYtìÈ ¤h¹¼ŠÑ‚Ò¸DDûUºÃ´¸T5[»o'BÑö ¬œmŠÎ‡(–¡ùòàê Û;²‰¤dÜP_p.N}aðª_n»pGîØ·oÅÉS~K/Åv |I†×À)‡à­ô{¬oTÔ8u§}Å™«øµ7]§Šó—tÙpd*ð›m—~J®ÿ_0cÃq“«É?&Q€ú¾g(Ì Êzòø[øN I‘'­Z1•˜€Ìƒ/“?úv{½êæxÐÜÁ·4FAœÄa–¾Ñ·ãÑH@8,räýG¬ÄId,(žÍJÍò  NÞ2Æa’þ—Í J=ƒ*ïÒÌRïW&˶:¸þþ ’8º@y˜%È|éè†33ÝFsP%2 #”½•®,‚sµw0fÔTR2ås¼R?ôbÿoYwl»¡jÉfåž¶´ì;ÍQ23hÅÑ Ú+‰ó›ãÄþÓµÓÞIÔ®¦›3MOÑΉÎ{:Ç‘=Ãݯƒñ¤y˜ªÃîÁbáô•"±ÐÆòF]sìt"’&z¬á4·HIjÀAX8#³ª3ŸzXÔ†še€ƒÞkBÁjçN‹¡w£ 0.BœôïéÔ’ˆÓp¾Zw(—ÂH²ƒ6MÛm%™õίÙ8¾«ø„Ç‘&à £ôwŒB::*Ó*pY˜£÷§¤;æeõõz]õWœ7?šÁ××+“ÁÕ÷­âµyÈ7]¸uµ9ç|ÕfF d)tìP¹·ä…I⇪ˆµÝÐßOÕ33öå¥ä~ÐÞ Ò£¡»ÐÂHÜ»[ÙF(u?ñú™FÚ`èç‡3Uƒ]¾?«/¯iípÇ×sÝ–ä÷^ öma诇<ýêÞ&%mí,U…¨ß#}mô8ôkF]ïžöÙòÓÂĺµVV®¢%±OÊRm§tj·Ÿï­0ÝLß°.¿FпàIì endstream endobj 1667 0 obj << /Type /ObjStm /N 100 /First 960 /Length 1475 /Filter /FlateDecode >> stream xÚÕXËn[7Ýë+¸L6çAò€Û-8Y´u²pb55šJ…íÉß÷ •º²}жÔÇÂÖ\êpæp^œ+*…B T -þ)¡qàR‰ù³ªìBÌÕ…ذZr ¾×RPM¡P Yó rK€q(âZMBéZ°ÑºËÁº+¡®µX¨¥ƒkhø¦eç`-PJ ÅÀ¤¾¿¤æ ¾%u `ÖÎMÍ×$PVü+ìRû™ú·9PsrÔÕ™˜à†)æµ |Ç9» ¬I"—L5¨aqA)«À.¤n£øz§Ö 1[ÁüX¸ë®”NÈ]J$ÔuwÌpãì´4ëk`Þ}Ô*$Ä k9žCÁ.A`fX² â'ª@‰GФîÃ?Q?6ääz‰ yø-)¤æzAG ap®RÉ| ¦jA ¤A'$ØjYkдÖV!um࣮ ä”Ü;uJîcì`÷ޱ@2ßÁTØMàè*¥›N©ï€æ,]*Hׂœs%59;hҚݘÀDmž%Í‚6uvÀ·æ¶¹™‘0HµoÐÉÓÒ$Cò¼4ämæ 6HÅ=&-d1ß¡„T77«Ð KЗ;cXÌ…< }Î{Q–üŒÈß\áÞ‚ÃæF¾!'HÅ£‹#¥§Lzœp¦Bžu–=S=Á GÎÊloo6QŒ†2>óúÙ‹%ŠvEEB/?~øðföøñWÐTb‚™1´(E$ëÀÈÚØÊ(–Íd MÕb«W˜ì¯–çao/Ì÷ÑñTÛzÛ¾‡y¾~ð EÖ<³¾À,x'\? iáõ(Ÿ¿8]½{¹8‡aþâù~˜¿Z|:v_}þc/ŽÞ/fógà°XžŸy·ó†|0›,ÎVOß-ÎÖ=®¯ý°8>9zºúKn9zÙT¸·¶7°wt %ÞP¸ã7Ýaéow´Ö½a&7äÇ&ø/ß¡†£Wê.ÐhñQ&c>‰.ýòD§Š¼ÎƒèÌ`‚î2†VÓ˜sDã¼wöš1}-ƆV½©f.•É¥ºT3[/“Z¯—I-w*“ù“år¥‡ëÉÁiõÁa-`nø²r!ä.\aØ•Ìæ/?¾=ïÏߟ,›ÍŸ®N§Gz3ÿvþÝüÙ!õ§þ‡t°äÝ?=ðÈ©†«¶(ú`ìIwôË0ÿfõj¨¿,ãÑÛÕéùC÷ßVX¨•žAšJ$Ü™$&TÉ"%¾‘Æñçe<8>:û5Ã…ÛãC°‹ËXšFŸ8I2œv9âüÇÙˆÁ.úUÔæE%Šê1j„ì_àã~@9úOŸÔbC#á¨ùf>¿Ÿœ,ßǃâÑéûMB½þ«Ýâ’¨6Õö%R­;A££µ<Š6\ÜѹJäQÕ.cÛ:slj»AkŠÃÞÆì¹Ê šÉ–ó=«m_–ÒõK¢Õ{ÏR­Ý¢L6ÁÉÉ5Êä3…ÆÛn`ºç ¼áÏK#ìÝ[®9×ßïé\¡vî%ðEšÃ¹ZwöÛˆ¦Â6®9* ‚¹a^N£ª™9J’ÿò{Œ‘^Oâ{§É-Òc|qé(fö©~<‰F·Ã\Tѳ²5Ù ¼©þÑ݈G=¨©a²ªƒh. 3ó(ÊŸw裗ZçP ݹj¸]¯¶û¾Öøïe[|ea¶¨`%”¢ú”žÒ‚`i7ŽŸoÎ}B_?xýðêê¿ðW÷&øëÕ=….­Ä"£ºÓuku'h¿Zt²J¶€®`’e͹DOý14Ü[zû‹èæ’ÚFéõ¹Ï€½M™–kwÜbî»þzvN¡KÖ(m­ˆ›ÿP8†î/ÖW3hk½ðî›hj÷œÞ¦­èT1û öÔOfÛ@3B!£hô׈þ;ˆæ&Ñt­xç+Iñ'ÿ¸Y„ endstream endobj 1763 0 obj << /Length 1105 /Filter /FlateDecode >> stream xÚÍWYÛ6~÷¯Ð[$ bHñµ@¶mR4´ëä% Ù¦m²ä舳ÿ>ÃCZI«uí ŠÅBÃcî™ohìí<ìý±øu¹xñŠq/A‰ˆ„·ÜzcD™ðb§‘·ÜxüB÷OŸ·euhó4ø´|ýâl KiîK¢¯,°Óòr¹ø² @b<(ˆ ñևŇOØÛÀákŽéÌÕƒÇeèÜ»[üÕË›~zA0Œx1NPLyçÅȃž"x#”HÒùò[ÐØWi£‚0âØOíg(hÖ?‘Ä@qÆ`yœ cðCZ‹~WõºÊŽMV#?ü¥†H/$ ÙùsΗ‰þP3C¢0±Ìïêt§f•>6bœ±ƒT|ÄçûúyrŒýª§TñÕ¿ØÏ:ÍsU}†mÍÿDÿ_`ómìïÚƒ*šú¬íçm¶Fêx‘“<P?QW?·–G›ïØ‹ô YV.MyÈÖ–þî«ugœûh¢idaèT…„¡8aV¡ÜåÖV©*ª³ª,tœÐ\\f• bû>H"?Í[õ…x;.>Õ?à9º «wÊÕðm^—Odþôª×‘_R—_Ú²n+ÕUÙ4–çŒzù-=sU_Þ!d Ö[ƒ%l¶EÀªÆØ¤WÄõH¿¹öHÿžÌJzûîÍ›³üóxF%A,?¯©`ˆÐëG8÷cx=”4ï àKþÀ¦Gèe€=­Â»&]åjfÊêÄrDElï-÷Y Þ1á¯Ë¢nªvݘ57Nö›ÛvÑGÀ¬v™>²XSX¦¬qÒš}eºË>ËB#çMR,ý<«{Tn.ÀWÙá«Æ5û«rsß Ø(w¯ØØ­cZÁÕ¾R T*ï ëßQègN$!ÓfÕ®›DÚ™ÿëPÒf^7‹°õÚXÒ¥(3ŠÙɪÁîÖ~7j« NÛÜŒ²Ž‚Qá¿-MÓÁi³O+.sîËÖ'#§˜3WNR$ýMY<Ó—ÝrŸQ7,õN2´±ˆ¯K‘R­ø™ÞÎsËW(ã;PMiùÚZ¹½#ê£Zg©c˜`ÐC%b ’ï¢ÞE4zj¤ Æí$w¬H7õÿÜšÐÍ É8B6²ú]a=ã×=ŒŠ{uh‡/v†Dú‡@ÜY¤¾«úG(CR$Žœ{ÆD WJ÷Žq~ ¹¦´)”Bž»V#¬„{NØ“J+UC™eÅÎî˜tëk£ôVVÔÙÆíºcÞÒ=/qZèúûî’†`}ë”A…ÍðÊÍ¡CizJ¿µÒ:ÓüšÞ©BUiŸ¬SÖì¯KMBú:[¥µº¹égú£õã&$ðÛD&ñ8ÞW½—&8˜u`4ŸÂ·½ D6GÎç:nrܵæ‚îˇFY›µ3J æŽÂ3IÄ៌¼¾\`¶‡ endstream endobj 1781 0 obj << /Length 1369 /Filter /FlateDecode >> stream xÚµX[OãF~ϯ°Ô‡• ž‹Çöª} [XµBÕn 껢N< n;k;þ}ÏÜqBZ!˜ññ̹_>ã{KÏ÷>Œ~žŽÎ.ièÅ(æ„{Ó…‡}Qƽû( Ä›¦ÞíIDÆ_¦¿]² s’ Å1>êL!Æ$8y¼ûº)ëM%jycä9 „w®NìÝ %Qs¸Ø&«uÞ»¹o=»$Ô‹à2gJíÈ›àE˜k^‹ñ$ðý“'z]lŠy“•Åg?ðákj.šFTJðœ`ÅA¬ï/Ýû…x¼ëòøýæêêT¿{!i†›d¯D pÍRQ4Ù<Éåù…a°ìž&Å8Ô§¿Óï?&u­w‰Q;«½++½®“¬êPñE²©¹Y-7+m5¥^ç•Há0·V©ozÌš{+·Òj¤ Ó{±“­w31/W ¶ïÛ›ýãI‘îŽî×ÁÔc›ŠE²É õ!É7†¾°žj§Á»!1ý€KïÊu«/ÿ¤¬’©ŸÛC)ÐglCG^Í]¥Läx禺`¿S#„£ØVë_ú½SC ±ˆÚb»V¹ì[Q=f#‘CìÔÎÊ8eRêÎæÑûrñ:4“£âWû1ÐËæéÍ!k]óv1Ë]¬ÖÍÓÁú-WYÓ÷ßóPáˆBcÄG‡ÞæúžÈCEqüRäC{ -E] ±!ˆá6?¾I)cg’çå£Î `äCŒ†ÚÃ~×Í6Í€2q„8=ÞCN²íq‹ÅÁÑ"ÝdÒs¨­8xu¾›¬{úæìtŽ<ý%ñ?h2º˜Ž¾Žd¨|·h…E!"4öæ«ÑíßKá%è ^Œ¼Gutå1 ]„ÉæÞõèÓ^`¡ Ä©‰ÀrΰÇxŒBÂwØu˜ƒ§0AqÔ¦ÖûjLÃÝI ¦®\ôð–;9¼åªy«Ãõ»ƒ$ü»5äãŠXhEõ¼ÊÖ à/6Jü«6£®OÕœ•†Ô+¨Y½½¦zçªÇÉíº*Ç88ydd(0“ïËÔ<ȹm §#Œs„y[[·úˆ£OˆXØN'‰)†¸ (lÛÔÜ-e×8àFƒ.7¥œ(tôÕƒ‚ ZehQ gÅR“²bÌŽHbRe ô¢wŽO¥ë ¿@S@W¤¾æŸ Üs·;ÕËš"2¾-‹&ÉŠº›EB…YÍ!ÂÞïô«ánC™äc ðOþIž MÌS̲®³™ÕDÃÄN’?ÈH‹y#±X7ÕM³VÉÒTà5;ÅœpM°ÌN×CÝ"<¿À hã×$ÿH Tà(QÊQj} ¥PÚêÖÇTÔœ¤©!„ÚO+ÆÏ˜•Öí=µ,n€- G–~vd­!i$†ÚÎÅ.Ç€ [Ι¼Åà1‘ŠtÈ¿Œ¢¸Õ:©ñ+¡/¶úC™ÛN?(òª¥g·|è7U@>˜ ÈëŠÛ×l8A> stream xÚ¥XÝoÛ6Ï_!´/2P«¤¾µu²®-V´–¤èC[t”DÛZeÉÕGÜì¯ß’EGi ~Љ<Þñ¾~w2³Ö³^ýzuöô¥X‰“„nh]­,Θãù¡…Ì <׺ʭv%n`ï?ï¥øÒÈÕâÓÕë§/½hrÌg܉b©øcYΘÖòâêìë’Yü ÀõùV¶=ûð‰Y9l¾¶`+‰­½bÝZ>¡¾ti]žý5Ê;~*+\ojgNès+b‘ãñ`°Â°`<ˆŒ³®“Ä|°åy³ð"[ŠN.–nÀlADí¯$=«L*á³6‡Iàp>Äfe›ÎD( Çè’¿É6kŠ]WÔ•aÚÁD#Z<¶–<=œŽŸ/–žïj›<ß³´GÙ¢6Š––½¶;™¢¤µ Z«ÓdÖÑÒ~SdZÞ‚DÎlÙjAšcW·m‘–Z|WÓ*±Ê­ŠÙ« ¼¢2ô‚Ñ`蜗:Üû¢ÛÔ=*Œ˜½kT _/x1êŠjMëëE`‹&kq;«Ëä¡Õ~½¢g·Z)tËØ׋™Ðü¢lk¢RIϾ•¹–Q“މ™°š‹Nè³éx]QÍY4øXåß`¾ÌY‡ë¯žÓ­Àg·ÑIL’žÐK[l‹R4š¥¦çûE —_ÞŠ]K+EEÏ×bá2РťÊ:g¼lè0¦/û§RgŸÎ&& ¾ŠF‘ÕU[äßœ0å¨}'†âÕ…¨ë0C#7“g†\Ç üáD±"-h6º¡;¨Xárª/!²L¶*J¸ÞÐê 2¡V°GîDF-`# -¢ÖÆ$mŸ(_,y9,LÌøµhtꉽjê-R1Ƚm|è˜xÛýÀ®ëŽNVu>g¼—8,1øÇÅÒçP>úT¬Nµ$@ù×t%—7KØ+Ö \N,Ä@‰V-½8„´Ìi¹¨²²Ï%±ª¬ÂÕuY§ äæ9~ÂMÈjáCêM]m!OÁw1#¡H¤¢•DñA±A±Ï[Ú-k<ªW(¯ Ò‚ …æh qTÒ`ÎÇñáåqÙë×}Q–DUµ¾_ª·&P1S›8d—õBß¾Ú(ÕalÏ®QJ€š«æYižfÑí¨ þá+dÁm‚xMeVo¥ÖÐW£™ã-ô1Ó1x‡^b…Xw¸Myc˜’iGè¢à€°dè„ܸ*¼R`(: !SgÃ:UR©Ô˜ÅŽÔèÕY7ù¸Mø4ªç·êŽ  »õjH%›vSì~ R2æ?‚>=Vß04(áÏ–_ä ‘ËŸµYʤÛÉ™ b¢AŒ£+ÃOPF`éÓÖûÊoÈï8b}‡P{F¨ÑO>»ó`¬ã¦î÷bå©JIàœFÒ‹¥)ìV<»Rd 6a9½™qãQ"ýñîÍ›97 ”öÒvJžIÏúȘ[‰²øWêVUè¬j³ÌûRæfS.ø¦’6ë;éhÍÓQ z­R áDL»ïZ]âwΛ‡©Ê:¦ªÉ¼ù‘ Òl Ø/Šü‰è½¹*F#çêêóשÉöËó7—/@ Ÿ3ï¥ ôô´×`†¬û­*æïzXæ mÄ5 aŽv‡¸yü8?±‚1 Þ˜Â|LÄ ¤  1Ï~Û·í¤šW1’¨CÆrû£ë†DчT-Íõ|5Gâ¤å,ç C÷+œši~u²©pVcX]Tð¾ªõ»ü¸Ôž1æ¥DäN×,jwp¦;8Óé9sìQ°C3©œ)c{ð55h>¹ŠAœêkð¼©{} ¾P®ôh˜ÇgßʹK+¸taÂÐŒ†Ñi`"(tRÍ¡ý¯¸êñäØœ“ÚU_é/ Â1Ñ™¸ÕôzK¬ºÓF´3«$`ø‡£ÓŸl‘n6€œlÏ%|i”÷Âq*ÌÚSSêbZ10 ü2S‰OWBÕ¥ÔBÏñ»jªàçÄV³¶òâ^à*Ú)0¸y—3‚ĉ¢Ifë jý©÷ í3 æI]Àn8‰­ðdè8Š ¥ YnèlÃtñï î›QzñMlw¥lOoš1HDBAh†OjhÏ–ô”ÕõôæˆÊ.à×ÿ{<&®ç ý?ƒ´ U?R¬ÀWÄ%yDy¸’h™Ú:¸ün‹Ê]qª «e¨Y(põÑp0„û·ŒŠ £^IÝãUÉ!¡O5èî¦Ôª!Úà›³}ÆXøð®º"%Þmšž{¼™¶UÞsKš\ õ\÷êÿ„ï£xdT©°i"@Òûn2dßßc:°øŽU1'Ã`˜“€ÔXiQáwÅ!TÌtçm}ã¤Ê§*7 ÿSQ1Ȳ¾?÷#æx¡kú÷ñ a¡ õÑ©®î†PãÿCÆñiÐ!‹®¥3Ôf{È¿™íuv\NÎìÿ·dòWïÐ'¬ endstream endobj 1808 0 obj << /Length 1757 /Filter /FlateDecode >> stream xÚ­X[oÛ6~÷¯P³s€˜•H]í¡ÃšC1`IŠ=´E@[Œ-X–\‰¶—¿sxHY²å4» HHž õß[z¾÷ëäç‡ÉÛ[‘xËb{O^àûL„±—Ä>‹÷rïÓ4 ¯¿<üöö6Œzœ"ÎX ÐcxªVÍrõ´kòN|káí-^ BqˆB3FjÆÔD²ß]Ï"ߟ¾£á äšfzRªÊnzE3IÃZ=Ûu•Ód/Ëb4X©‘¦‹ºÒ²¨ZZåR[Mr^ï4MõÊ|œ~ø,‹²ÁÁ$Û¶'þqF£ªöŸýȇß`Œ{?ä.‹V#{pCknGqIþ0”¯ÔáQ¼PÍÚŠïûâ<`Y’x‘«J Y"÷¤á³Ì%¬ôú’ñsið©ü¹õd€äŸ+UYNŠÖy}SïU~stÇyX8g¨­*¬÷dYì­À\-$†#±m´º(K§M.Vr^ªQ¿6ü®ý%,–‹—ÜüJ¤^tÿ%ž¡¸þ·(æµ²2U­À´ÖÍÀUåðZÿ_xÄåï?|ø€÷ULÞ?L¾NÐä{AWþ"?d~–y‹ÍäÓßËaŒ1‘¥ÞÁ°n¼0Xbê_éÝOþè*Þéhj,Á^…#Çaà…iÂü$ùFý å9à,KWt!üé êšûÓ¿¶ÍµH¦ªm‹ŠÝÅÏ “¥p‚ð™Ô2â‘–†!K’Ô¬]4ÅVƒýÁ÷¸Ñƒ8ž)Ký˜î5æ õ™AGBÇ€“í¦ª ‘M XEµÄU:­·ª‘ºnZÒ0À;‹Y–%3àôƒðÄœŒC_²ÌØXÎ KâÎ ªúº«_Ò˜2~ì“Û<A"HjúM•Níü¸•=ÃP?ÑxGl‹:7].I(:0û‘O–mm0Žáƒ á‚³(²ÝªªÑÆ´p[Ô¡& ½‹5øDVF>Ïg!xßòA†q?£†Ìm9By])šÖè\¶–rg Ï6Rà‡¥^³ôÜôî׳‚˜ËxÚ?ê» —?ÃÃÆ,ĉw_i2f"éœÞîæÐCôîuf£ 2£Ã<Ç3aK·ÁŸ†§]µ —#r²¹Òér·Á(1®ä©`Q ]I§”¦Þs?%HSSÚ«P&B£ô®1Vh™VÔÅ›¢eY¬¯,$fUXɪn6²,Ÿiu@ŽzWæ¤jŽEg§‡dËÚ0Ž“;’Pÿ‰T¢Ü'`͘Û03‰ßûÐ…,U9]Ó¸‘º²“î‹j˜« +“'W,û§h‰(ËzWsP·mŠJ[¶'ì‰8YÔ›íÎ$ÇÐv{lX¿DW¿ŒþЂ‰&8i±‘˜!83TùÜZ&»Ÿ»šžòŽó°*+š.꘶µIËÐ!ujÚàX!6«ôµU”3žd/WÑ™H2&¢dèæoVSìX½Lœc&Á-nìÔ¡0ãÕ‡ƒN7álœNŸë]C³®pâbˆÿÍX«à> ¸xu¯H ùf£G‰ÕÊÐv[ÎÂÖq(qÂÒô¤P ê EôóIÚ€1ÓØoL.ØX·aÓé^YV¹‚…2ÕÙeÓÑìiælj—jŽ[¯ ˔å¸pVÇó“Ä6_DM·»f[·–l:&{× ŽöWà"î"•Ö§å ÷Lo…ÓËðTæÆbhø’œmd»K…¡Ÿ@ö™DGNY´S< Ž7ƒá9ƒq»¢mòð=Kz4Œã`-iI/\$<5rc…ÚšF½’š6!¼­>i-šB«‘x†ÆÅ"Þ%ÉÜ{Åp?ò»J¯m­dÞo$I}–dQôpäïÇõ•$޹ob]dãBk‚ƒÇá9Ʊ ŒaïØ €h0"6/\@˜+"€ ˆáœˆ%¸¤!:¦=&ùö¤U0ð Ðm<àžvÇ3aCnn Œ¦–V*ÝÇBg®TåÚÙgßç•ʇIÂ{ï þTœ^=1œSnïž°=šÀ`röïhÀ»'†8(éÚ>ÒM ií#iò EÔq3ãžo4—Äê<ÔG ¾<‘ûÿ«h—/vÞ'W†]×¼ޝâ|ó†êÝj á ³ñÙ ÍðQÃኙÚ÷èÇV.ÕèûçtÿDÃí»÷ïÇ™‹%\Õ£Úlõó@Æ<ÿ¯t#‹ ¿²ïñ« ^Ýn™WôXS½«ÌeÿÏÓt?Ü}|?Š5<}ÿY“_¹ endstream endobj 1826 0 obj << /Length 937 /Filter /FlateDecode >> stream xÚåWKoÛ8¾çW9É@Äð!RÔa)PXì©uÑC»X›±…ʤWíæßïP¤lI–ó6—-D"9Î|ß|GÛG®Þ­®n—)r” *¢ÕCD0F,Q&0âŒF«Mô56µN6ú¡­õâÏÕï·K– v¤˜ L‚»ÎTrgr…÷Kʶ “Ì'4ss~Ë7̉ÛÊPNˆŸ×Fÿs¨jXÆÝ²sâ„”sîMB7ýÖѼQ{½Y$ãø7ÿXÞýñéý¼q±5¶Ò÷zhG{Öîìë¦REY˜íõŸ½6Öèã@•åµË`Þukþjm£ï]<õÈ÷êãçI8"ìÙÙ½5ûz&”ZŽ'?UÝG¥ tUÙꉰÖ;½þq¯êR?G©Û’ÌÀ}ÆTOTý¸wñ©j{™L°ùu¸äoÏ¥x.!ESÞE¶ƒÍlƒÅÿ™ësPÅ3y[@Ä/WüÿÑE­L Ûq­I ™z³»jAp¼m÷Ú4õ¨¯MŸ“>çü N†9Mú⨇få’ö=ôR¡ÇzAx ;5¤g z²± ÷Y‚@_q(œ)E ·ôw[ºwWÚ ¹CÍøUe€‘´HR’Å«ök㨃×öp( WÈnÔ,HlÃëN5ç.ç¨þY”¥‡å»öϵ:4mÕ9…QaêF«0°½©½“òøo÷O•­jôæx¦G‘¾Ï¥ƒÁV¾ÊÆÅ!=Ù ¾rU9úÀJ‘dGû›¸yñ´Ó^òGQ ß|Á\™Í|Œ¹> stream xÚµYYsÜÆ~ׯX3/Ø2w„9¸¢‡D¶ì¤\IUDW*e¥pK"ÚÖ8Hí¿O÷ô`ph–¢Y•bvÐèééãëƒñên¯~|õç›W¯ßÉd•±Ì³ºÙ¯x3©Ì*11ÓR¬nv«_£Ô¬ÿ}ó××PJ“1®$ð±4U[lvžo ¤}»†çëwBN>ÞHÍíבà&ñ`å]U7ÅÇâxêÎ36 )òT Gÿó¾èî‹f½QRD]MObEkâg—y³æit׋ªkÙz“j½Í+zyëèëjXìéâ3Ùˆ,…?ýªkòòPVwWD;Te,å^G×n *ñ¼*8:ÄGŸ4}ŠÏFrÅD²ÚpÎ2­¿üp²S,‹ÍÀÔ uý%tYž¾èž`_ j<€Ö¥”˜‡‡¼íp57½+[÷´–ÛY¹w›3¢Á¤FÂÿ­î¬ã­6™` Ïœ ÔÝç]ðr,VêYÔ‚eÜ“æ§Ó¡,P·k }Oò…“Ñ«SÞ¶öN°.«, Axm3ÆR€‰³Q`T³H¢ªî¦Çó¨ÊÃQƒ$Ò’¥rî#C$HG‡@:&{ᢦÀÂå}^íBŽÇcÃbÁ½/¹M毗ÚšØzUÚsݦ»}?Ø9(Ì#@𘩘ÃõSœûê·|ã#²l_€)2V¤Øܸ)ò޶¾{C[yPIÆ™6>¼Þ„âez(_%<ú¥:”ŸÖ`…"ÀRNý5–|êÖÕùø;¬òS½:z‘TBVÁ§³ ,—[ewïè¬2`Ñ‚+Ð ´obÝ o!‰¡òþÐ…Ü](É÷–¸úT§ç öF‚rOMÑÍÚ눜óŸd<^Ä$ˆÚbšô‹„%‰Þ!4K!' >ÕîÒU¦GJÐc(ª™ýíj_6mº&ø¥‹¿ 4A¢0YD]œhŸp¶?ıh0Xêí¶oš¢Úíµs²”3•.trALãO¿ÂìR‚IgB¦3Ñà‰ JQ¸šÉµY:ê 0 bp¢´¢iêæ‚Òõ…<}Z'$ø,«}Ýó®D·'·q^#ÀØ ŸkÈžçP³rðYV»r›wÎ1~ «À¯E<œbwv=`3~½a¹}A oï‹í§!µ¿‚…¡`‡§e…Kík÷î÷ROKKŸn®¬hoWÛÒ2EÖ¡ qÍÒÑŸnþñˡȆ€M<ÒZM#û|*Œ¶ÂÐNédÚ> g,– íŠ-èq"–—QtDMEh –•}¶½½žqÉ žùîÁú®¡ oÚùkW˜/oŒÉ[§Oå•”™ØØrÌP:?9Ó¯c‘Û"nr8íöÞ æn Å‹¬8»õ¾¯¶]‰I²X­ëÀæ*FÈ*ôhºhòQQ¤ÂU-¼ª‘¨tŒn›|kk XÛæTƒà ú²%ê¢jûf #ï$ Å iöúŸ1<Ên¨ÔÌ42ÊÇ`y§.nÖ‰ŠÎ§¡Úî‚Â̶M.ÆŠÏ'šÈSWm°™º>@SAå+ uË2:òÜmrff]5"ã[@‡z&Í&¹LAÁðD±"48•£ý‡XÇüZ\KXðP:’L>@«˜æ6Nªú–<£Fz šÂ&^룉p…,rç{¸Fcà‰â-¡8LäÄKíçµ£¬§¾+&”"‚ÆÑ(”Å@©ÌæÎô€ù¡/®Iú¶Ç8±¾5ø=ˆ·èCc›35âjCv›Áìï2õûóñ¶[jp\=-\äÓÆ†–"öìç ‚p©Ÿ6/x®öÀ¿Û˜àJ.¤šÚ•'cßc¢úö¿ : ÷ ¶…{»O¦Z" ÍS]V}éªJؼ=OKhØh­ÆÈ²iƤsÃXÛªC+œŠºØŒR²¦ÅŸR„pS"×,gÑÝ¡¾Í´ €¿eSWG¨#¢Ç‚Þn×Ðê©m•ñ°ŠØ,>Ý6e~{(XïH]ó>Щ˖s?ÝÖ‡þX ÕÆìÕ.ïÜjÀî<þÑñt°­IâÅg)!ƒ@žÎÚ»­9h½îŽîü-¶î˜!$g•’3ëä–îzèøì[ 3uXÄöÛÞœàÈ :R\€pÞ3|÷¼AÄ_’(¤i¿ãè­S®sz ×ŵ{Üñ À¨+p`+¦Žg0œüù è?{ÏšÑ}]¸Ìg!&¡ PZ– ƒë Ft`PCÆ¿z}²øòÖº–È{NjÕ²_P`Áã_”¥l´ãÿO?’Ã9±ëetzº&Y«œ5GZ¾¡V¸¨Ä þ;¯"ÆßN¯8¡àŠ>áFdãC #1|M¨xv$5múð„½±øQ¾ªj\ñc+¶däð9âÍ` ‹ý#àíƒ•Ž´¿oê#í!¤<+žâ` ýÉp!”è¤éË®AUÐõZ/K‚å+>¯ÀBW!J8 |Åуâ®> GRµ×Ó ¿l#c]šº®)„Cö(ÝúÙÕÈq"ñWÝ.T7#ÀOkæïÃPë›ØØ7±aëÎç§é¼:¾›‹Ê¾³.ë‘¶4X”ëå4£<úd9d1€åDêâC$.²hsXD0NÅÕLIÚðÄç¬30L¢ 3Ú£ŽmÄÃQvà@<€*ž½(2šP[BØ#Rú? nŒ(ƒ»{§DR:´cÁ‹ãHËfñO?3qs\¢Œmá<Ôgç0eÝ»×ma½oñTþló©d€·‰ùÔ07ƒÍ/íˆóÌÞÎÐwôëö²iŠƒo/Ï¡@15öV¡@ žÐÐj†ÊYÜî{¾õ©hrh] »¼é†éG ÆÕ‹Ñ•‹ sÉ{ )ÑÒ7Ãðfî‘‚éqPñDÃÂñ?#+‡Y<4ŽòÄ?Þ°×¹ýÖ×OqK˜gÇÎálWRÚrTG§CßäÚö%°›ü c§Ô4wAï"ðáÍb¼GݨÂ)è¢eAÔüáæÕÿø ã endstream endobj 1844 0 obj << /Length 1576 /Filter /FlateDecode >> stream xÚµX[oÛ6~ϯp›‡Ê@Íê.¹ØË.íÐa{éòÖ-Ó1YôHÊ©1ì¿ïP<”)Ev’ C˜’ŽÎå;ßùH;œÝÎÂÙÏW?Ü\½yŸf³%Yæq>»ÙÌ¢0$IšÏŠ<$YÏnÖ³OA£ØbÍ6­bó?n~yó>)¼7Ò0"E î:Ó²0&W!Ûܳ] ñ".Ì=ûÊOçõ|ga@å< ƒÛvÇ­ðVƒÏþl…jáy05ˆâEó3‹ PT’¼´q>lÀMQGÑÚoÔžUÚ\”Þ2{W2ÝÊÆ®ó8 hÝ2e¯ÅÆ'~˜b„©C€}ÛËÏaÂ4W“hÅÒÖ‘÷’î÷$¨D£)oxs‹‘±–Q}œ4'Y™#8ù©ÅHcóA?çi¸!¹©9Ђ֍al´ç†j ¼HW¢Õö™Å#gÖP ûp/ÔQÑÔpÙšj†¶Îí°²ƒ×•›ü ¡ðΊUÔˆ‚Ís«ÄŽa )vèÝ~¬ùÆ$°a“ ;€­ï¾6ÚŒª¬ZyzaÓ6•…ôYf¤,qÆgìô®•ø#åL…°Ë?_Í>y‚ÂZ‚¶¬Þ£'±çVáu@ˆZ¹¥ý¼7äò¯¸Þú²Å™ íÂhTœ“´À~»=•\9ˆóu8œ”¾3˜DäÝWÁÏqœ ÎÂ0¸éÀΡGFŽ-ßáÊ0ˆj!'dj¹$qú ÙKËÈse½+¾ã5•öJ=ß±QìtIÊtéͺf~ð³p€Vî-3yiüêTéÉÁ¡_yÒ_==:$E¾è䉨žÖµ0³q¯á-Ø‚0T¦CcÞæ£)_ .)Ió|$Úºc±A½ Òí¹î–Åáô“aäE îK;ˆIþš™`u+im×6_É©•žÜeLÂeäóL]"ZA Ÿg™Ï³ìÙ<ËҤ߮k®ô¿àÙ­8L`ÇNŸ‰—¯Ï oF³‹3çŠ0{òYâOµ+¥¹nŸ6+ä]äÇÒ™À9©LÒ¡~¾ûFwûúÌùð¡XB¾%x„n¸óbJ™Z_×ó®eëît{º{¤†Ï*º×fOéŸÛ‘Qö†={™Uw 5 Õî÷õñm¿›…0£Ë¡¦ªãn%jÙ”U—„b BýÚù­¶nÙ½¯|1HATël.UÚü·Z¥]ÁiAzes¶^žJú›}«Ñ×w ûé6“•·X!ä”Ô_CÓÕbˆ“‰ý¥«bèÓ+í¡Ë ¼=?¼N„úû\Ÿ°( Nµ¸ÔÓ±-f¶ÍWÀ¯*NÅ£}…þŸm+<uŽ¾Æ®ÒõšÀTwM=îñIµeÕ]§AÝ}Ñ;ÄÕ¸¤kÇ 6¦B{_ïèÄ×k{µ¥jHDƒ:þ‰Õ×îËœY7Π“#å>J¬GèTz4ÀÉÊú‹ÜëÏâÑ©„15^"7^ž z}Ý ‚çBÑ〶ø(C´'¥oíú·Vi_¹ƒ­p3®%ôU=à“)àkpt,‹b@¢ïëºg“Âþ›cXÏ"×NåÈsè­¨âÆ”ž¨eêÒ|³;.Wø»cô‚˜W}¶Mw,´¦4vp_»È >ó†Î`âæ40çÓA ^5xRVïû„UQ%N¿Ù>Gã6]0ñbê… ©ê°·Õ …vã®F23ÞlFªpœ2Žq±Ï5¿ë{…1€Í¡tµ³ÀáïÑ·ùZ+²TœÔõ õ};ŸÁ¹f^œ Ô¨ §ƒyÊ¡Þsøúøú›/oôN™O_tíîö;LÏî+ù ]ü%F¹]PoG2ï׉áŒ9±gMÿKÉ$¤êp<ð´\3óó˜zpfuŸïn®þÖh¥ endstream endobj 1853 0 obj << /Length 1496 /Filter /FlateDecode >> stream xÚµXm5þž_±×ª"²Ý÷T@ô(Úñ¡­gãÜö­¶7i„øïŒ×/»ÞÛäZ ¾œg<óÌÌ3ãÉyέã9?,¾Û,ž^‡©“»y$Îfïøžç†Q⤉çÆaàlvΛe–­Þm~zzÅ#É0Ü$ @O/S3¼Þ7´ÀBtá)O¯ƒÐÉàN‰;ë0NúKë ŠäÕ÷]#.Á…u໹ŸÉã[Ìoð‡–¾õbD`ñµ˜ï¹yœÄêÃŒÔXÙãÕ:ö¼åË®aÅL~*P-7[,W|@e‡8ÞÉGÂï†/n8Ù„aã«9(–ÔÃ`6wø$wwè ð;µ©I¡v-mZLùI .w§¦›¸Ñ"ÆŒšJîmºZù³§Meá¶ñMÍñ¥73‡Â¯a_ŽôÊ]Wœ4µ­CŸöñ¨4$.b0J‰qR–vn”íÚÜ'TnJnI´x} ´©+\óÙ\U]ÉI[žzŠÝlO7¾'/>[ßí)*ð÷ú«ÓYпc—–Ù&‰íV€…V̘ — áìãœlÔ¸–¼ _䟲\Pl"«ÉÔlÿÄŸ’®©Ë“FO˜Æ9dƒ0;z³°Ë¦…¢­kìó`iŽrSb.»Qì:K$ÚV¦›ÑgRÂê=‘e‘`3~ËEñ‚hàñ4QC8D¤ÑÀ R—¤†î"ÜXG‘›A«´!ƒ‚øó‹×ƒ©Q9)j[ݨtü qÞË>gÜù2º·ƒ0Å{L™]ÃrŸ¼û¤Ü¼zñz6ùŠŸWWy?i´0¼]ÏÙ?g”Ú\š)oa5ß~!—ðá¹çs‹¨r³Ÿ¸¬¢®¯éߤæÓLMÙtÊ}²7 ^HÇ´ú1oX‹¶%¶íkKt"õíØ;—+©eô[Í·©“ìLÚ§<þø¶}Þsõ¹ç³"™È&‘/›æ/ø®¿¦º‰™–{TW`š:¼{Z78 tû¤‘`ñ|³x¿ðAÜs|3u…Qî¦ÐµŠjñæçìàKÐè†yæ{Ñʉ|ßM£ö¥ózñÒLZÓµí@Õh´\Iä;aÀ_Û"k(ô7Ï|Ý<¯W¾CÞVaºCJ›²[AB±Š‡D¬xxKQë ®˜q>çF€í gØdf† 28Gô÷˜”´\›ŸÆk:gGè>¾/¯ÿ´¼¤/»ÀK—¬©€)þ’TX@+ßw¥”MS¬2²ý£žtB/âO_}©‘>p°ŠXŽORJ¡dåÇËQ‰³-+ÊáRXÌ‚®”f“©Y¼s a¡îc§¾ºDÚiMÍEy²§¨êO@`Â_Š´d‡˜º §˜šÛ•¾5õljD¼¡Ì|'7;èŠp"~äDXn Ä0s­4:~èoÖ‚?~(]y±-ôfh Aê/·¨¾]‹?âãE~yuµZ‡i sÈäR¿ƒ,¦ÄÀÇ<7“xVb)g1*HÜ(7ŠlX®4ñk­MUõy{Ô»›ê˜Œ §§¬¬ÛÂdÀ;®. Z¾ž~’»Y««Š‡©+ò–f®\ËÄR"_^Ѫäd´“òwØ=[Ë)Á>E*eˆ£3êHÍ€÷¤GlzÝ3•iµ1¯/Ì ×³$ÙRDûöºƒ÷ÞžyC(àù}4Y˃ƒÆ¬gËQ†C˜óD§î3\"Ѹ?‚ª9- E—”ˆ]¨.Î`2Ò#Ä"ב€kåúñ Ëʃ¾À;}{ÇgÔ@­,»¤g€GíEÄÆÔØ©¹{$ =ºœ>ýËʼXPq¥ÿ”¨ßÀÇ;R¨ 娇$>ú¿r7JÓ‡,ÿEN‘e6MGôˆ4Ûž|ó¤Ï€$Š-ØU°ŽáþwÏAM—_«‘£ZNöW•¹´²¤6¯~{.’l¡i¹Ã\ð/{êÒ endstream endobj 1756 0 obj << /Type /ObjStm /N 100 /First 973 /Length 1776 /Filter /FlateDecode >> stream xÚíYKo7¾ëWð˜\(r|A€<¶@ Nm”dÓq¥T&ý÷ý†–bÙ²âu¼*´{´;ä|Î|œáƬꂋY²“„ÿ‰\T† Ùq°'ZœH1¡:-Ùt‚Ë]"u%µAâjŒÐÇÍ#€5áhA2ß–ÈN”°†ˆ¦6þ`Kñ6a_Šb’Ú€É"«D„š-€i&`¶T3˜“Ê6[¯Al p½böŒ2™œ¨bQ°Åk“’ÅDZMjÏSÚ¢º0Þ–†…1siX8@ª6„] ÑlÀå)ÚÀHLmÜ&g³`µš?áè”ÅfA,§Ò ‹É¡yÙ”CÃgD¾Ù(ÔÖ+ð>[‡šÔ⳺,ØU‹€,˜¡9E!is F##mZ…š ‚)ëèþýÑø‰;F2äô‘ÿü˯–‡žÅbŸ¼…ôtuzújôàAÓ~:›.Ýýûnü“ Ò´ { ãŠý:ûA¶ÓaóÑÍ8JÖ¦0ßøÙ|öæy·tÇnüìÉS7~Ñ}ZºÏ¦^üý¡Ã‹ÉoÝhüf»éraÉË6~4>ê³ÕüM·8Kèöì§îíÉäÑì“;6óZÕ[:ÂÛ¾ÔW°7™cã®t¦ÿp:aÒã3ö2X½ÖB] él-—€µ±£ñóÕëeûýãÉôýhüh6ÛÍ›ùðjüýø‡ñããØ~â7XkŒÙ#œDÕ7J*â£Å¾š ô°y÷¹7{1sØ;Gï¦~Ú}ôG«Sÿçj¶XÍ»»æ¾AЈÀ¼6îD>6¿­õ`æ½€>LNæ§'‹% …£øb´Ø£2ÞØ;‹!îEÒ}ú0_ ‰Ac¤Ï Y-ÑW$X”ìI÷Ãx=Yt÷îa–ÝË;/ïnj*øœaµ¶ÃÙäçÃ…ÛQÞ¤c¦äð¡ ù6ï©Í;"=µµ²ÇÖöÕföÕO'€Ü[±n”ÕOÛ6>aã¢ÍÙ Ž„~Ú”qÒwn¢àóe$ç´}©/pøai»Ä]ÚÎõÖ´7´Ë$M|;3ÒÈ 7ŽÀ‚#Ø6.Õý,0Y†¦«Õ Hj'}M>Y}k!Mºiˆ&«å¬ ÓÉÝ9•prÚVþL7À¡¤=µ1¯G¥xm)>¦tmF"ÆØS¥ûrºJ»U[—IµOµµ•œ—rBªy7¡¿:‡«ìæp¥[çpÙZ5l„x€Š‹C+(ph nçX°›²7wNÎ2çc7y?ïÞ —Ëè:|´Æk‡,§Ñ]‡ç#P4D‡CƒšÆ“1Ü G¶J´?š¿&§«]F©|FÙV>/`À(¢2j9J=µÑR"cOmÑâSïU2òý|Omt}¾d=ÐÑ~0¾–#J(;aú-9®'5ØíÄZÐA|2(±¸Šo×#ˆ§Ld×VÖ}é|]yÌáèg‚CÁ®®ƒ±X½^,O–«!±Äš}ÌÎ*¡Ê`©d%«£Ø-ÞßN?z;YüîßͰý—‰Á®SzÃåít¤«jç´­ לþ×þïi+ }æžÚÄ(!”¿±«±Bi—{InĽÖ{_æ^¢5åZ–äØ.‰#z-Šv%Žs6»ˆV}‰s¯ìdnI½VâðÛ ‘à™>`z4Xv3ÝŸõ¶•·#Nr¹åÑ?D1퇯 ²íEs¼‡¶•ÏoŽªW5gWjÙ%cºe﫞i·Šì¶[vqÛtæ´NgΡl„u'f_*Ö°Ú킺&¡H®í›yk¥T})ù‹Y6ð} yÎâR´ëF\R=ÙgœV÷Õ­ÞC„øaC¢Âüõ0^ŒÃ>FðŒ’r-ŒóZïm÷nµìºA ‹cNÞòIkB5Zöß¿Ù7‰÷GQô¢£Ñ¼}u•ˆCy¦%¢…§ÖãŒäñåk¯Ú®ÔN’=¶µ§¶"/íëèO™}—P_Í}ºû•¯h¼õ)£7ø sAù¼a¯¾¢ :ˆ6H)ð7©ýŠ—ò endstream endobj 1868 0 obj << /Length 2142 /Filter /FlateDecode >> stream xÚ•XëoãÆÿ~…ÎE 9í‘Ë·Ñ+qÛ Ÿî|Š\q]I+iŠ”ù°Oü¿gfg–"iÚ‰aXÜÇp^;óÛú‹ýÂ_üãÍßoß¼¿‰âE.òD&‹ÛÝ"ð}FÉ"M|‡rq»]üâ•^íªz£—ÿ½ýéýM˜^ˆü@¤p³”YŽ$o|æïž‹U˜ßp±’)¾IÄ_¤ŒGä‹_V±ï{·½\É0÷ÖfxûÕZ•{Z¨NºVmUã,óÞ¾}»\…~êYÝšUs*ÌFÓž"U£¡ªA*Eš¦N×Â4íŒAA$ÒÈÑT;bW­ÿ¯7m#H+˜yºÐG]¶ kÇÄ­ÓßJ uj^Á&PsKsS¢ ‹UæÂr"c’~*ÔF¿ÂØ÷ŽZ•Æú&íAµn¤—Aìi¦Õæ@£µÞTGMãªäA «zdÞ¾CýÅ졽¿‘áÀ/>è–‰$ I·{UƒÙx\]ѳ9›/~ìoðçê ÍþÐ^½£½«£jš+Øðßš üd(ò€Øý…ènð$é ­±¸fX޾ë̽*@_š·ËíN§âÜ“[ï[úþp,•>)ˆ]œô¡§›VÕ½Eßýí;÷RÇŽö@¬¡ÅCí_õ>¹ƒ½Îpœî…á*Q’}þb„‘ïmºº8¯ì/.—„±q>:Ïôsé"ý·ß(.grBÆ"óûÄÙa¢¸]WnZS•$kQ ~*¢X›–æÍIoŒ*xUoT×°Ž‚RšðD)Id&ò0»þ¢„ Ó‘¼Rn)Íñ¨·†BÀîlõä641­MîÄ%·ÛÞÒÄfÙ·S­›¦—ebÜtë¦5m×:bÜ¿3ñRkµåœÅ0¦Œå^ÊØ»ÇUtŠx²å‰y[Vàš&›ªlI³–a¢é¨æ‚v°U­¢Ñ®VG-z½"déõ/”%Þ©VàT˜¶kk“ͰžÙu­=4¿v®:Z:¨¥ôÁŠ ò4­(¢@%Vd]mÔºà]à TIs`Apÿ„2ñ0™ØHäÊê(šö±0tyB¦ #“ïU 'gPŠâƒVTQÐàv¹îÓ I1v hˆg¨L9%,Ž|Æ^`Vë3ƒÜq G5¿#L{ f6>)³§2ð^ùê¸9(wV ³Qú;'” ŒÅ/âoÙ¢ÏÂ1k 8ˆS">–}]u'PE9M:)ŽÅx»ã<Óh|_ݳ>°—Á¶!_PÛ1fCJ%êãèÛŸÝS«´†h‰}|þ »íïŸò~pjTc[y.Ùƒêÿf :y8‚õyއuè ,ìÈ >åÁöýY=Љ3L€&ŠþH“^U[ÙHÃTÚò±wœŒ¼Â•F”¤éljôΞËH†ó8Ç8)ÝÝ÷;Œº-T'ìòpTX Çúñ™¿µb.fMm¦…g!«Sƒãñ^•ºy7‰`· UM!~6ÛöàvZGH@!!}‘¥ªŸ=WÒõ'tw÷µ9T¨Ñ3œ#(åÓ>,ð á&â‹R׆®`\#,·+œ¸â¤sÊĉðãתãÈû«å˜Ö ÊS‡epÃUP`ô4à6Ú$4*‰œ Y¯¶Ìjãå˜G\`ÀÆ©6Ô À˜n]@ÅÐ-­èÖ?‘-j¼thøñÉݤ©ˆü>y5T_­ˆ¡ž+)’ )CÅž–_ÖjmhbÊ”zë&[.EЊùÂÇàA2H1eÔ¨¹øÛ’Éñ‡É0lmȦ"„äU{={eÿÁnÕËE ó'‘„.DÓ¼|Îô |ðûêö%=ž‘^Žñ¥ƒK“!ØþPº¢pR~ÎŽwjÌ]WµŒœS‹r‚ñ‘U7•­Œ.SBuØÉ…ßW[3¥;8^¦®¿ • # l"¸d¿ÆÀJ¿5é%€à‡Z)Kf{9^)´÷Um£¶-*Ò -­ Û&RB]bãÈàžåã\`5œ¢â¤ýë³ÝSrRKØ Á¶‚ñöaôyÈì§²À~ApÀŽ>޽Kµ’ˆÈÖçvÛ®ìçÄûˆîÄï“úL«M[›MK;j]u--óG±ÄûÕPCÎ'Æpc¦˜Z —ZêØ£žÛ,ØÌ`.O3# !/ÅÉ\f ö`-vÇ\鉽í¿®ÙØ #iK’q'_Ð×É4€È€j̰ •¬+ öTQwvCv¯?ÐSñk6ñY·4k£ôsçÙ«lLCï?Ëã #U6Nšme­-k_Ñ“1ÎŽmð!P¦©÷ q$䓸‹ƒµ調 5L2‘…“«î»Î R‚€n¿§Â¡êÉÒp"ûѶõ‰‡×0ÛühY‹æ Ä·qÒ«šÉàr)ˆÍÚ}_¥O!øF¹/7ES]^?Ig—é½Pñë?ó‘b•I‘æX¯D"‹¹^"ð6õW?©R_Í4®ø™ZÒGÎË[×Üapûý==äs@±¬i^Éã‰]?Þ¾ù2yT~ endstream endobj 1877 0 obj << /Length 2084 /Filter /FlateDecode >> stream xÚ­]ܶñý~Å®‹ ÚÆbH}Ëhúà vb j_Š8Hy+î­`}lEÉwÆÁÿ=CÎP+íéö|FvEg†Ãù&ùêzÅW¯/^^^|÷*LW9Ë“ Y]îV‚sFÉ*M8‹Ã`uY¬~ór¾ùýòÍw¯¢x‚¦K²øXœF+×v[eP/8mpÂÝãÄùAj€Húsùa#¸§p“ œœ%qèöø1f,#–gÂ!<ßøA̽~¯pðâ{ü¶Õɾíp¦6"önjÛkè¾+›kš8,ý©¾j+lð[:’Ÿ|ÇŒ4p’˜%a´òEÌÒ¶d»”ñlÜúFY3ˆÜÓí®÷§iËm±ƒ/¥+3ä,`|¾Úv…U0 ­Ÿ@/XK*zÝ»MÜÕPíð{ìKÐý®óßOZkª(†ºk%Ž"ˆFCy‡0]·]®À!LÝ"…Kˆ0”޶ieoP?1Ÿu{9‹òÜ)è¿KµjúðýÎ}&vô‹ጵôr÷l?—7aY=AÜ%yàDÑÿ[`íÖŹÍn«->椱5÷Ììí1tßÎß“(Z$Š]³%€$ǬGóí‹ÂiE>¿z8îÂ|ŒÑRŸò‰ËR jîo›AN8 &ó[ü\-†A<‘S¸´. ò®+TÁ6?M\êM©2 ‰”é1°` MK4’V:UMRis²z¥vÏ»‚̃,ØkD–Žj1öŽl¨+¯÷Är¼6,Ô“ÕT¡š­}‹ávÂ$8®Ëž–µqjÖÔ3‰7ÄÓtÅÐ:uú ‡Ž2ÃE:å!Xœ'ÎwïyuD°ÂÞO=JX’„ý~ÐÑrGç°¯P©¡W+‰Î5·ÂE–Ž!õœšÐ”CÉÉæ<Ùü9 ù$¹Ì}q½^òÆ(¶Ž¤h훚p†€Ùap8{”GÞO ÂdQ”ÔïL©²ÓöD0ÆLÌ3íöhÂ>yÛ E€­92‚ô´W®,ˆÅ\e†¦ªkÓW™1]eivÿ¥(†²x¹/‰Ò>>ÉEïÊãb–UÖëgæúLÎ{ ɤ Z1w’êm ®±Ã–ð‘ö9¿E˜³,S¿)ÝÏ­¾Â.4Y>WØú®ñB<é Îg@wŽ÷ŸÝP±ÅëÌ?//þÉ)uÞ endstream endobj 1883 0 obj << /Length 1562 /Filter /FlateDecode >> stream xÚÍXIoÛF¾ûWÈî¡TkM¸/B{)·)ŠIES¤#r,MÌEá’…Àÿ½oV.¦5—ö`s†3oÿÞBÙ³ÍÌžýxõÃêêÅÌ”„n8[ÝÏÛFž΢ÐFçÎVÙìO«ddq_Õ)™ÿµúùÅõ|ÛAQ ÜÄÍÄáW®lŶðBÅ¡;[¸'‘·îh‰óü8ëv¾pýÐj¶„/|«ÄÉø2°îÛ2mhWåhP0©ëõUö}úžVáíëwv`ß3¡­ë"ÐH_Åe6Å/D±ëvì~;Ç/oÑR+3 Êr‚3Zn¤-k’â–©Cn¬XGyÄÚ͆°†UÀOŽƒœ0™-à™dÜlq·cÏ””5’5¼y(«¹X‡œd"_áuÕŠû®q"“'T=ñn—Ó¯sEÑTòù±ÅŒ~l«s"4_øvl­¶šì0wl «MMh)P!5·•Ê¡Ty æyq #ëÅ¡µ§Œ yümFÞÙ¶[R¥UÝË{@ÀÔ­žò|+mßU5w–¸«…Ô9æîàKÓÁ™R4;Ê#¶çÿ8¶øÙ׌Ô;”ëiÙzWáðç`ñûPBåò,ƒ9A 7Í‹¬ëkðuÙÖ«R¾¨ Îis”›¶ä!ç[:w,•~Ÿ³ãÚ£X—U3!À톑/j?Ë] ¹ ié±E%Q©)î‡;– ŠTA0ñã¡ßª©5ˆ<@ÍJdx`«ƒª–;žÔrUàŽ.Âä–‹æÏò¨&ê¶ÊXõ\"n+*¶#)Å9R–‡=ˬXT¢ØSZ¾|ÄÅ.'lPµN=Eèc`ú•Üb¦§ÿDÐæ䀩r,=Ê_h³•«OŸæ (±¶õô$_pÅùS ”/$ ”Eˆê¸’Op××]ÂÙàðd ×›¶ eÆ„üBÀžƒ^0Ó鵜âGïå-eÊÞãB¾%ßÞìpú€7d™íòc}Ã.À.MÔÌ\Gø»¯ÜR_jšç“*Ór_å{Z¾Ípƒ•¾54¹L«¼-JE™Þ×(’váÐÁ×Eª‚TÁëz,²Àìd#5Ñ÷ÿ$Z€àMÆ ¨öØ=%1 =S?þ6¦»á#?6t˜`âxÈ÷“sLøÊd½¶O°‚é;áÅú°¶(pM¼K(‘^WñNigdòò³Ô½ÐF‘3ôsq|ß•+nÅw‹!š¹&<€·&jclJg ¸ìèSïf¾Wx Xày¬¸ËÅÓ“¢(1ª‹ÍêÍÛ—&E„] —‰”u[”¬®p÷ ׇV+•2l :mS°¦ùÐ6ƒ‹av}Mx½?2>¶&3Ôs}¶†uãÿ°žÅJÀ‹¯>ÙÓ¸¼ £>#·üT7»G˜¬ëÎrú ŽÖ˜‘åRÜí‡}Œusa[Þ¸<ò5u6ðȈˆ‹½˜&6‚.!™pÉ+]n³LÌ»·¦ ©ŽÌÚjåÆ 6Hî!ÍTÅ1r_Ãùëx7”{¤¯ò/;ë*g0Nâ¢(Š';šèÿˆ(uªõ’6Šaöu[ÙÎù—ÅôXÑluåÐyšˆ¡‚“vs*hrö›"¬j˜ºG”qøÝLaÒÇ=„«V¡—ÚøhF³YZA/7sJuoŽ™~fBÎ4##ÎÆÙ8)–—‚÷úúsð=E…› üÇ3÷àœUÏ“e{"ìÓòù…žoåÃÕêœIø/æã¹(Ž¢i¿šZÔáë°%c\HÄðo†Ç~B˜ÑUÏÛÚQ]0oÏ`Âà€W=¹z#»ZÌzUcM-wM•æÝÏÈ Ü&L .ÓžðUu‰FUÛìt3Ä?/E‘ƒ¢ÏO°¦i œèãnˆâ$¹xX4¿àŒÆ ”xÞÅÃÀùÉâóñ@#Îé°¥©.5Œ°A¬R˜—ªbÜ®q;a'?d:Tê/‹(»ÂÕÌ YÕÿ6!—r(ü²,œ ~ö!ýruõ¶'g© endstream endobj 1889 0 obj << /Length 1294 /Filter /FlateDecode >> stream xÚ½Ûrã4ô=_á,³C;³Q-ùžag€a Ëì 4}`J§(¶’|«d· _dIv”*I—exH|,ûÕuÖŽëü8ù~1¹ºö"'IˆBg±r ëÏ(tAà!g‘9w º¼_ü|uí{˜^˜€0œNS7³5ig¸m©@ž¸ŠÅÕ5òœ˜ß }qkæ°¿6óø!‚òòW—³Àu/›œIH?Ÿ7;uÐJwXAä |-1 v>ðc_#(šõª%•;FV]!á¶Î$ðøøÀ6õóïnàò4±È—y¥0Û ¼Yg]‰¡%¬+Z-bU=vu‹Û¼VòÔ ¡¸­)òýc;ÈÄFV=Àp© †æUK¨|Á¬—ĵÊÀ¹±ŽjRËNQÏj}TÕ­–¶í¨ W»v“Wë¹òž‘øã¡äÈžNÅ?œÃÞtú§ xÄQdˆvˈÅÁ(‰öÞGÜëi„étj!=àû'‰(ÒÚ¿8Ë$Pr¯åM¡léº+IÕ23°|¬º*μÇÌ[2HDIbu7eW(Æä n‰•S‘3KÊñO$åcú(–Ä9{%È7³ñºt÷NyZJð½JÆ_o?ì;ÍðzW‹ë%Á•ôöTð8t3‚ ±¡àou'«èJëri$’žkß'LMEDþ!Âv÷÷1aɶ¥øá¸Zš›šó»ÿUq9n§Q˜W$ÅB›£):Š íhÊxŒ)e6øI„®ijª¢b¥ÃB•¦Ã¤Hˆ¢è\j •sþÞB¤‡Î%V8öYÚ€L^&L<3P•ÚŸò¿lB{xc¶Ÿ-6‘ „³ÞQ:z5…o·GJ /º>ó¢ŸT¢ùñÖ#ê}‘5o ªÍU / ­0ÍTdöȈôeŽ«ŸÉçÅæHÙŽ“äÿŒ.=/”8¯ŠÝ‰æÞw\2ZSwÚÛª°GŒc€ÿ‹Ãν.ªO  ìB&;³1K€ÇáµÆ·6ÍÏLíJÏhÊ Ÿ~ºÑQ)'´ÓEüá•’Lß©®ì ¬~A,[ªíwE1ÔL=®xòn\: ²Z+âF ªô\*K}¹ƒ‡–& ˆµ"ÿ@XJó¦ß÷ÕÕ5÷ø˜;-¡ ?¹Y ô&ßÈ% .ÄHš¶ú;4e먳•F£=…uW`uP/ÿ$±Án7¾| £“";¤¢?«Ë@vÃ(3¡·n¤Ü~ËðšX-ñÒ2f™–ÙÊ\xûíÛq(RËã©uÍÈ4±®Ùâ‘òÛê^1 endstream endobj 1899 0 obj << /Length 1121 /Filter /FlateDecode >> stream xÚÅWÛnã6}÷W*Ø@Å")YF ¬ÛnŠn¶Ý8OÛJË´£F–\Qv ¿¼ ’"g“¢@Ÿ8"çr8Cž¡ ·õ ÷óè‡åèòŠP/IFÞrã!&‘GPz˵÷i\k¾™ 8f‡¼ž|^þzy…ã–!ÄSéU[$X©Œ #u£–n`•ƒ0VsÆd^)ïÛÃŽµèX÷ÇË«·!+GÀhjú¡Û0ã$ÓÐÁü°ú›§uO¿ã<°Š1FÛñׇ˜×u•­&!j> B ‡œ ‘ñsdùá a¯ù$¤ãð¨dm¯?7eeÖÁ¦kÚ’@bâ\:ؽ¸HŠR²JÀjtÊÂ`µ!,±õ~b»}Î_.u'CSé1"®ä2.Œmr¾™Âñm‘g÷#…-}¢uâ0þÕlµ¥È;…wC.Ú ç<4¹úÖªï2a¤rÏ+V«Ä«/~ª+–ÖvÍ”A–À~oœ+pŸkëg£B{Å N™št²PêC-fZvU62jYý )D3,dL.Þ]ÁÏù‘ç²ÝÕ)«DÏ Í™N;D AÓ¯jkñ»ÀŒ×·‹E'Z×~À³Ýæ/µMR.J#=”Õ½KwaÆòõœ€ßy%œƒ%xý£«RåßU䥫Ü÷v[JK_ö¬ŸÞ1Ue^5–{žf\œÓRõÐ5*\¦ ÓÅh¿Ò/FÞ•Áý×Dl ØP×ûå蟒6ÐCMÓ '^º}ú ½µ\”nN¦ÞƒVÝyIæ'ê"åÞÍè³^w¦.ÍKpA!1À´ß™\Wj1é° %="w??ò}ÎRˇ»Lˆ¬ØZ®T<)^Ø#¦Qü–=ê½t±q&GÛ½üÄEZeû:“gqˆû¼ëÚ^lÌ—škpDÆ™<0<©:ÞŠT»4KÂÌŠl—å¬2“u9Àýce mÂ.žž.È?Ä€Ò†üm+é†:NsE;™àk³ÆŠµYÜW¥Z>fknÁ3³Ð~lèùVÓÛ*-xW<ÍŠˆF ‚X ’/(5¨xÎõ›HdxCZáÓÝPÇòšïúŽF:8Ç#UW¦^µõœøñù;$”˜6=bşͲ¤S®®¨»ggûw°éQ:C ĺähQZ䲕Èíï,Üǽ=Æ©,26ß•5ÃÝX>+P¿ß ¶å¯oÅçáÉ2Æ“eŒÇ!ʨýÿxû-ïlÞäÁÜfË{o%“¼7¼ ÿEìÊðÚ÷óðú¸þvviåðn̘ób[ß¹­¸3lu…î }m&.|Å’‹¨ƒxzã·÷0x¶°r";@§º7Üb˜«V=\Ýáûõ"á)î?äyÿ¿äìOGÿÐý—Pýð™k·þÊI×s7•ú­÷–»¾m]ƒ.í-úžð³™ëù€ke-f.ž1eƒûòb_Ô endstream endobj 1915 0 obj << /Length 1142 /Filter /FlateDecode >> stream xÚ½WmoÛ6þî_A`(f1KФ^öt[Z¤( ´s>¥Å¦Êt"D–URŠc ?~ÇÉ’£:ùÀ“|<Þ=÷ð9… KDЛÉ‹ÉË×,B N D‹¢„`ÆC…  Å]L>û¼xûò5=O%˜Ä!ı>Uš«"×u`\'Äpº˜|P0 ¢ûØÃT([O.>´„ß"ø)‰ÑÖº®§Gœ] ¿'ºx‡«- `ý(Á!§("G±ËmSÍ˦(æK¹J›¢dU ê§NbÚVõ—ß1™Þ¤E#¹Ú(Éàìˆà(áíÞ÷çïÞÙ£FA†ô?@pÝ GºB·b¶9ëLåUoÊA¥ûЇÑœ&P°»W¹†9™æå'B‚[÷°jÊÌF´OëôzFÉT¶žµ[eªwΪ7nU²*ÒLŽ`E#†9£‡`&f Z'Ü6¯¯œ•ºújÒñ‚7³@LM·ðlÎH4=«œ 1í ÓU®äÒ=}iS¾’>¼Õ½M-_ F 3Àx]I„p}l¾ìºÐÀ  …[+©R<~"‚Œ`sˆÔApw7€±Xëa¨ hsܨkýž>+æ–Ä”£yãV»ù\§—r”÷ 2ìÔ @AÈôÅÝÝ gíFSˆ‡§¿R&ãËf-ËZÍâÓO»ƒK<- á-jg«èL÷¼º>‚#»¹o¯a©O`›…³”¬U>ØÞÝÈ!¼¯5¿xêÕ6ײ]©MB«a~”)A R̘rz›®«BêÇ“%†ˆ!ïÚv>=d‹°s:ˆ¤wûÇǵ“3è\Åg < À~lºŸª‹@kßÉ6†n dU ,]y–——þ©©ªªTO"Eþ4“ƒEO77£]î)Û”ºVMVidŒLÝ1 þpŒÔ%jÍo&èÂn[îÊtg.Ærs –Îs!P5é|rž™> stream xÚµXYã6 ~ϯ0úäU–ïöi{¢EÑcšöe·(<Ž’pìT²wvþ}I‘Nâc2݇b€‘LQ”x|$é<é}¿új»úü»(ör‘'*ñ¶{/R„Q⥉q¨¼íÎ{çŸ cõßzÄþdzYÿµýñóïÂôfW$‘f Ò±ç1²¬$òívõÏ*€©ô‚«|‰ ˽ò´z÷—ôv°ø£Kyæ=9Ö“ 4 a^{¿¯~»È›ŽN Þ*H‘D—ÊT(Œ”`.»Aÿt´U‰< U~]gÒ/Ì:¾Õ능ÿ@CÙî´´¨^’Ç"L“OQÏ©& ¾H’X(àt7úFÛÒTç®j›‘W}Fž 2od" bÚ¾=jT$ •¿ï›ÅXü È>´R4;¢u¦hì¾5'¢w-VM×ýC€hkQ¬Xoâ8†+KlŸÔùœ÷R*cYœíô™a±p€6 ŽZç8Pr–ËcVH¯UìÀEÝ;© á\é’)í~î>7{2U×é†>ŸÇûM{0Åé¤Í4ù·>Ú U"ò€ýó‡-zÑ3sOƒvâ©k¼¾—±üÿ‚AÂyS.û:Û?}ë˜Þ€g¤ôuóaÆ>å·/lxÍ ofýI7½kŽ—Ì‘ ´Ž¢;…35€u»N¥ Ñ G/7]Q5Us ïI„à ÇI–s´}ËénrG)dçŽ=uc¡Û«&H’|Ø‚[›•æs±öžÜH¤q:ìq!êmB¥Dšgc¤|]¸ (¶Å™ò5Sú~ O0[£]nxC4ƒ›T튦äm‹)èá\k€}dþ{Zs`ÇUÛŸÏu¥wD¾Á‚íÜ ]¹i;FïYÓ]¤_1驪kíú¾kOEW•E]3ŽËºµt¤¤¬†“¶i1>ŸõNLâkä Ø<#3Æ àbÒå:™Ã®u$ý•iĉÂË­RJ B®‡ø+FYÙß¹øÅU´Ö•&½å}ea5(Tz)‡¶ÝÓNïQÙ¢¯»¥ zªG´i˜%aDù¤"ü‰Ì3o˜>|¿òÞ9¦CÝ>è‚0iwkf\+é÷|ÐsÛÓäæpK˜=¹ë6LwQ†gÌ3=_ÕMhêòTË -Í)Ô¡¨W¶­AÈŽ¨˜(.™ ˆ¸³6Çâl‰¿`ÆcUóWQ`…n„‹A29w·Ûaæ;Á³KظorT X,XyD!}›­¿Ñ&kûBCq7?ÿ·ä§D˜]’TôÞ`öU‰‚Ö4çfÌ"QBY$²HÞ´ Hæü΢N­Ñ»sóË≆7¶4à@4.ƒòG·úT•mí ‡ 9wÂØ¸È|¢ºj4æëÓ•âxº6fà¯ì0Úuà÷˜ƒ§Êÿ…YIY<f¼ç¸\1T”‰$>±d`†ºx£nˆGÔ|ò rEu®5—“ IšM¯Y·—äþ®YK¢ˆaò³ëû’«ßñ£ ¾º¢þ/q Ì'5Q›²=~š^FÎÔHàÌèZ®P_|áLuk¤—òy’‰@^ŠòÓ±*3u@_¶T/©Æ–¢g•èÒ  ¶†àê÷Û¡®Ý4è®~qÙ–®”¶¦›4´CAµâ’.nªÖö¨oÏ4ö*Øö{ `,ßÝân¨°Ý‘fØ NЍkiJ†x%“Å×Ú6«(£àXå€^GÅû<ÑÇ,àœþ\ç Ë…þ?S[®âYj ƒ¡×&È3‰ŠI³ùÉP}"âS‘Ëdù’40Æáìfß2ón;Mëà%ÞÁM2XÚÎ( ÇÑÏå˜uo\y„9•qSø:p” [­›ƒ‹;˜»B™ÊëbÛwg×CÀüT<Óä‘FC"7ƒ<D÷%_¡h@0"0 ùÉŠË.µ}½[j) 98ÇŠ±@õææ½Ù ¸ƒžú8{A+.^áÎÆá²¨£ˆ®`õ%£²°K!N]b_¶oÛ/¹M.ÌgK¿Ý¤ž ÿ‹m>)ráõSµgíÊç²Ö¯¼óFdžˆâ1ÞÞ+ßëÆ3®løœRî„~šŠ8Š^yw¥B‹‚ï*S"¾"ÿI»æ#ƒ‡N»ï6; ®+¹¯È"j?aÑÔ6óH’B ITʪ@3º)Nš¢mÀÝñ=8†S»¤ÈÊ禹syˆ’0R¯>Gó0œÛåžØ\¤i|}Bؤœâ„Qcø[H8Ô}¨4C;,¦w½H<$¤†°R±eayV½,[/Š@Ålú ØUååW¢ 6¹‚ñù> stream xÚ•WmoÛ6þî_!d(&1£ê-[lX[l(4s1m(2mk‘%U¤’øßïNGÉ¢b»Š”Ôñx¼{îî!íX˱ÞÍ~[ήÞú‘•°$ôBk¹¶\Ça>­(tXà{Öre}¶“pþuùçÕ[Œ4ýØažã‚Nç[[ɶ¨8s´y°Žv,ú- /B!m|ó”îêBHcç©ñê­ç[1lyçml-\´å’­æ‹Àqì:m¤¸OuóÅ øsIž¥åH¦i¹§É ¸KH™Wå5z§.\‡%AB'˜¦/v*í|õË+š¬êbß\_ïZ•*jÙ¾¸­›|§|­½Ù4¹¢A®´.:ŒçÚ Ïe „;óW½O5y¹™D˜U¥Jsý!ŃhÒb ìW!(ðtEŸwŸh¨¿¸>/Ï#";Hþúøþ½Þ[äRõ ýx]U(½K›ãQFF”Ÿªv[ZÈêYeÕ6™ž¯s¬'#š:…{”R#ãU)2€0¼Šê=pFµæÅ!K<Þ×û¤b”#g<º‚†ˆ—q'61Ó¡eÜ ŸÐu#ƒƒÓƒ·+q¢2Õ–T~^ШĮF{T©ûÎÙ÷Ø@–vɺpuö<=R_\N|Ý#«¶ß)ÔÄ$ƒeõø,¹23&Ûúhš³C²®_PŒ}ô½½Ÿ³7ËÙ·r—c¹çr^he»Ù篎µ‚E8€ùIl=vª;‹».‹¸óÂú{öá$OuÄ µ1"Vp3䮸>㑎4¹AȮǒx ÙÝŽ¹Ù›8öfîBO+%œÈK’ʃ„i¹¢‰rX9$Ñ‹øÿA‚®’ðÈU€5ÒMý»Y“טÀ£„?½Ž°q Á½(Ïý·î#—8r¬üTûZ/Tk}üc±Õl¬~zónf}î-u̇ÄÜ ì ÷´¶Ú¦JZfE»’¾R2ЈµhD™éóU¥Ç­`KÓ!Š6Í¡il¤,\2¥œe!]Í[ÝPµÚÕU j-¤€¼ÿ˜dÙ쎃–*½!pá1WÛk³6\èèˆÊÜÑÄ÷Åó‚I}+ GÄŒ‡qßé¡Ì'Ìäe5n“ÀcnØoÄ`N×ý”–Bù¾qfùð’#9g1$JoÄšt{¹H瞢)àDÓôbdõªQ$® } Éïór%i mK«Tý¾l«miɺjví‚.YRyYZEJeuHÔ‚6ŠìY¦ÎåªìöX^&ØD  "Ì|L˜›øÏ ›àO솜EÀ„ÌùóØa»vU{w”R5÷ú+ÇwÎtÏh}ê«mS!1<ÒgZjŒxÞ$ŒEÓà±o šõiÅþ2ÖÕ¥[¬¬[ÅôãˆÞ Ô:ú _Αi$–í|Mc×ü¼/ ½&õ  ½Î›#¨ûz8IC˜Ë[½ë êA¢(4*=±ÿXÓ9ûŽžàôûrmp7¹œp/lÙ­ÔŽ#£«–ÚÍ(—#žÂ½à³¸»3G9ª1:Ç{BÞšç@¶ÊáÁ×'§ãidέÈî'TØÝZÀ¥—Çü ýñ£ýLwy÷Ø>×!€éá·ã1Ë|üêÑvå~wWçÌBƒx«Ää*cZÕü1Ê]æÃŒúžæí2݈—ÿ=ýP1+ëÉx dî)¼@r^÷€ô›¼L'?-ñ7Ø33¦¸_b¥_;¹ ¿ðÿóìEÁ–íàä¹pÆ”|ÞæˆcGŠÏ’ âÿ sf endstream endobj 1863 0 obj << /Type /ObjStm /N 100 /First 969 /Length 1893 /Filter /FlateDecode >> stream xÚÝYÛn7}÷Wð1y(—·áp#@.H[  'Ú:yPì£V^¹ºÉß÷ %9V,%+Kn‹>Øš¥Î’Ãá™å½'ãŒ/TLÊú)F>3cQÁã_R!˜+Ô›ÀŠÍl¢T!ŠŠËd2Ó1%è;S²bØñ:3#Tgưs:µÎæC•¢ñ:@Âcª*1À¹NÏø"sÆüŠp¨Ó¤¬ó•ÕcQ}E!¥ .Ô1híXg)Å/Þdì&„º“71à»X+RŒú%6žT‰"Ñ u,Aʪga²×ïr¬VÕCÊ&:Ÿê¡1ôrËx,!NÌQÇ‚‰Ñ þ©@¤CÑĤ)±JIê ˜—¢¨„C Rß(&.ì$ˬKx¼Ë¢ïz,&QÀ)$ǪXB‡$œbŒÙ¤ˆ' ©DY%6)¹ú&H’RQI I ¯RÒã€é•¬jƒKu)P e5à¬ë ì—X#xLÅ×%0¦óªa’Rß%C>]"ƒ^Nq˜™ 6D¥JÅëAIC•-‚“Ízìã”1ž(™°u˜UTRè&¢BIuŠjå„D69¥ªSTׂÅ3EÝÈ’I)&€äªvX,×3Ö5Ø×7€ã±Ü&WRÎ’¯³Ã^é.I GP#cvNjO¡ '[ «E…³Qä¬DT6pÎrt||Ô<7§ðÎ>1Í/¿þ¦îe#|(ú`,ÛÍG£7GÿOÑÎ[ kèãnfŽMó"*eñÚ‹Tɵ|PFâð2f hSßÀ è&o~šŒÏ^¶3sjšŸž¿0Í«öÃÌ\¯ûêãU‹/íQó :´Ýlª1¯¾Ôœ´Óñ|rÖNq°ŽýØžOÇÌ©êBBVÃlIØ•¼Ázƒ &>Èÿ¤ëƘôt€U­€UøLŠ˜¾·çí»ù´½©Q¥SæOtÒ½‚MÌsóîÝ_s“ÍÔز =Ñ¡8ËøÜÂë5*¯“ü&{·“ü¼f¾Ík¦½yr`ÁkN_àõ&â €M$'«iX‰»ÈGl RÒŸ¥Þ\s±R±yr|\WhžœÍ†ã®yÙü|ò½þ=x?›]M5ÍùøljŸ†ƒÑ »°ãÉEÓvÍ_¾¹tóÁ¨¹lgƒ«Éøb2¸¼vÍÃ-.ðuÕƒ‡½À••ê!Á'Q”í§údpöG;ûæZùIû®Å1œµÍŸóÁtøç|\MÚét8î_À{‡ê±þúfñ_›Bw§«a4îpµ°þ”mAëYktFfq™þ h?¥·Þ^,ù¾s“C;@¹':¢Oì{¢C –¥ïÜÒSß]ú„`îéNéÎùuñ Ðz~]¬¶W~M«$šVIt¹ŸCåNä$µ—^ƒ¦¬€³ú»nB¤Žü/@Å"èéOÂvùc¬u„Éû…ë‚‹vv]±^/·—ÊÔ†D“gOeÖsge4ùßMðWï*6¢‰œåxOh¯MI¼+úo®úJ endstream endobj 1978 0 obj << /Length 1742 /Filter /FlateDecode >> stream xÚ­XmoÛ6þž_aäË fù"‘Òö)šbCÑak†}h‡@‘™X«-¹’ÜÔÿ~w|Ñ›eÇEïŽÏ=¼;ŠÎžftöæâ绋W·a4KH"¹œÝ=Î¥D„r¦$%‘à³»ÅìCðy[ÖÛJ_ýs÷Û«[¡zâ!eDÅ ËÈ% E.¨Óþê–‹žì\Ä…ç\áX«ú¾Öͽþº©>ÒˆÂûõÕ<¢4p# U‚º9$al´ªø2Zd˜óTö­3´,I¢¤ÕqS]13Ò"Œ žõ&ÍÜ+ºÏÆÏ»`J&ÙHD/“ÁOÞ ]lŒ|X”º.~@ø;°I«&ÏòMÚ8‰¼è4`ö™³PHŠsÆH¹°‚x£«bnÐÌ‹'¤¤P¸ 9 ÒÂ>õzÓììϺ©@nj“¡"q—F//§¶ÈI†^$-Sz Ry™¯Z‰d$ËppÕ>Z˜öCs=a%Æ$wJîQÓp/óªá¡Øx2„¯ÒͶ²”é ·Á¼½yûþõÔù…CNÛ½ø¡0‚§@ðYìì` a¬ì¸ÀÔ¦F¨ŠNßT˜1/Ÿ-uö©¶æÌ1Ü7Q"v,6 ”õcƒÚLP®X`ãbÈÈ#E¢ùœ7ÀÁ ³Xk£–6ï‘ÝDŠHcCÀ2¦ø„ ;ó‹a´¤Áƒ¶ÏÔ>²eZ¥Yc¼~A䡸•îÝ$,I;vÕ×8 Ì!Éçež-ª´vºm“mƒ_Ë´vs¥}šƒç\i|—Ðe¥ÓÚeIJد7ëk7„üxÎk=u¢€(LÎà…"‚·'ìÉ)ðGDr9ˆÍáÒ“`ƒ$‡µ›¨³ûÀŠGÁ³}ÑOТ뺭À¾0·…ƵçhØþ§ÅU¬Ë«²ÀZxŠƒãÎ0 ­_ýîð#EB»ª™•Eݤ‡zÅq¶õˆÆsÙï¼T°­·À¥Á¢d¹~Cõ«jgEG›t’¸Kë ü‘xV¡+öçŸo.f¬ç¶]bÏጠ Vù'lˆµ´™Ò²hJ׈ÔäˆÕ1Í¥¶ÝjÿìBoî— Ž³«y§Ž…a›Õtq¢e!ûDY˜ðPŒÅ¦±£Ê–vܧL¾Xi›Üº@â¼[Dm¶[¸a7í¹Œ×«˜:wŒ0ÝTåöiyzzÆ{²ñäÅO ±R{Šm¶;´WExØ:“ú/½ÍîE3‘„«Q þ^»…7«º<ÐSÎþ(ž˜kxLTÒÞ<Ì…B@%Ê*66‰&´_Þáía׎6)fþŸÎÈPaB$ë‚1É©C¾JA¤d£@žŠŽÞÐÏgÙ‰ '0¾­ÚfûÚÙÐLb¹×„ùÜf>Jö:$£ÑE×?_ß]üìß= endstream endobj 1992 0 obj << /Length 1527 /Filter /FlateDecode >> stream xÚWÍŽÛ6¾û)ôb1CQ¢d¥½´h6H’¸‡" ²Lïª+SŽ(uã}÷ÎC­¤ÈÛÝÂ’£™áð›_óà&àÁ›ÅOÛÅË«( 2–%" ¶‡ äœEq¤ g2Áv|\f›Õçí//¯b9àŒRÁb‚Ë󥫯«|§*d]pº´'™µZ‹‰Nôõ×üxª”I^Z_^‰(Ø€p[{7Á:„cÔ[±ZKΗ?¬Ý „O\òãùv¦kœB¼”­CÎ2™=H9l“¦ŽüSócQ(cÜ>×{·1ªu›öV¹MQOµVº%Öú@"½1h« ÷_ߨöZ}=5h±3|lêfªÿœá!ËÂÍe8®Íø–ý—Áá»ü/T÷Nó*{kH£:žÚ³'ÿ—Êã ú­2ó½ ïBx÷‡*è{ižŒviñð‚dÄ[rdùèUôðsÝQ8x+;£&‘bNª(óª4Š‚©=ŸèÓ©Qû²È[—Sç“A-y¡¸UÅÁs›O¬+µ)÷Ê[~1ì s>îêêRÜy‹¼z"§îf9gð%ciL©o|À žH/:ÔÍx‚ÑîJŸ™>ïÆ~éÁ‡³ÚCÛãXÔºÍĉ8YI†47Ý2þºý[.Ã4xõ@àb=οC§‹¶¬5Ê1¸)MÚ~æÁ>‚ve›àÞ²ƒ8 YG°¯‚‹w ¾íQPó= lLâ0ˆbh"ñxÿ‰GÝ- Ñ÷¬«UÈå²nŽèp!}¼¬¢t Ég)6àpsjJÝZ¯ãÉSí’/CI–n¢ç@áÚr2Ó–#2¤ õ?+S4å }?Û9]o^à]¥¸É\ëí” hÇöó¯Ð^¹F? D¸Œ !'Þ‡*‹“ç8SFŒg}˜5ªí„4™Ñ®»]£Ð/–Ðô÷ŽØ¿*·Nµ4ìj¸ÚFd 4üX-¨5²ïÅ#ìŠØ >ÑΣ°–qº|K’¥›3Ödª é 6]Ùæ»JMŠá^0ò®"´3Awí°r&þ'¼­úÚ>/Œê¡ü^Z `9‚%!ÀÅqaý—¶”ãÌä\ʉíªç*܎Ñ´W%å÷ ÙñÔ7™¿=võ÷n·Ë Åæ$än_–Eù,3–$áØ9}Œ(J…šÒ2¦æ¯¦,@qê»QåÅ-¥‡ÿ¦©e 7E×øÞ5yáµúû€¯$•®Àèè9Wlü3J8_rRQuÊ£Ôž†öñ–^k{9ìá'÷à,•So¶j†Á œŽÓIˆa7Ç ºöÔ³€Ó½0šºR2Q*Ñܾp\±S·ùJpHáºÃ+b7ƒâzv”(•Tøà{'îuݺ ` 4-¼ G¸xªMzƒöðÔþ1AûŸ?;Ô`SÕõ{aì]»rì÷¡soéÌ“ ®krG«ÄæŽ JüòPB' ãçµý0Æá$ô`§ìI?ei–}Ó…Ñ¢ù. !…ÏíÂñ  ÇÐ4Ó}Þ[œgÀdû|iƒ†ú/gÜ¿9D©¦ÛtRí½Rz˜…f’…„0µ7Zu­×UmÌyÂ|㨯џ8ZíÙìt³ê¿‚L³ endstream endobj 2004 0 obj << /Length 1323 /Filter /FlateDecode >> stream xÚ•WÛŽÛ6}߯pЇÊÀЦîVÐ>l‹l‘b‹¶©‹‹¼Ø€xvÝ`þØrVáÒL?œ¸jÉü°¯BÓ¶K—K. ðû“åš„o¸Ó‰w£Á¥]–~éN?b~äuõN5ù8 +‘fl´¤¬Ôµ´€i£a ƒC­{†åbP+F÷Çléô÷³3:Cƽkl^%â¶ÔUm–@”º1sp³ã°8:¦Û転¥õÁ *ùG¦µ™·©£0ƒ®+a0Oæ.·’ëÙÃóeÞ*Œ °C<ô¥•µé^Ë –JÑä¤écsÛ‹}ë -Ï´À73MBªîŠõÈ.88ÖAæ9Î8hæÜ-~P{Y‘6\bÀµb¥¢ ­›bèìC´ ÷ ±¦™Háu‰{­³~è¸Ö¯å䣂Yu÷ÜŸ‰7`Ë(¾äÓØZ²Àï“ÂxÄ‹<뀫ê_MË ë2ÎP×^AKH:QjëöØq-ýZ$*×Ð=}îýÂ)¤×ð³!ïøÝd6ÔtŸùudüZÖ²*²2ƒR–Ruîü4©X¶©4£–pR²fŸÚžþq¾ÄZn»q`­UùíÜ8Äet£ÿa€0¶J­ÍF%÷¹H%öo³)u.ýCHV¨àüô1r9[£ ?ð*¡ÇؾZHê,j«?šž?/d~Ÿñ»ºÞ뷋żÚ$,UÅ¢²ñ]Ý YÞ]?dQìñÔqª\”ÛE1/õ"ôÂkUsé2'îÛj×*7*ÏÕÜ ÀÚõ:ÓiÓ>0ºÖeR¤R–Cy¹•î»×ÃoïÏv\Ç…Û긞€|™C¹V^X·´‘É«SÂé+úWÌ¢¨wæýíÝ ŸNwnsýÂK ŸhLÅ»Qìs©ou/ñÙáwö; ŸÌÿƼ‡7E€É)´ 3Qe-2ZÀ»©ÆüÆ9 ý¶/n@iŸ°­Ôwv/¶nT;¼y3ÚMD…$tÿ—v/ug0aˆsPn„Þõ„¶ûMy¨ÄžLX¨†Èi»$ƒ*Y7UÙíÒž8˜‰ìŸÑ—ì˜þr9¼ÚetQ7𯉳äõhÔ¨°ŒáŽ~+á÷‹À?•N`càGUìÛ—'.jraÛÊŽlî;œ_ ¤ÍªkWŸºpÔéFììd¾ß4ä¿ÃNR<¾ª¦ LÙ{üL B+¯j3m™º«“Ÿ{Úß‚qz¢‹èÉÉ“T|·ºû{†ÿv endstream endobj 2017 0 obj << /Length 1700 /Filter /FlateDecode >> stream xÚµXYsÛ6~÷¯`¦/ÔL…ààÙiÜÖn“ÉC“8Ó‡\SÄ EÊeÅýõ]`²l«m:K‹=¾=H¬üvöóÕÙóK‘9ÉžWË€QJD”iBI,xpµÞ‡09ûxõòùe¶Š”‘œ `d7µjûYVM½2[Ϩ»áâêìæŒI60ç á9 ŠÍÙû4XÀâË–ò,ØÛ­› bŒ¤‘a^oÏ^÷üG«c %IÄ‚”æD¤1 w³k>ë›Ôë‰t ÑDyÆIž1¯Ñ[<0ç1 %ÀGïÚ™HCeU/ÉSÂàæ :"9âˆ$ÉI–e(ѯJm¹íʦžè1è35EÌYF’ìÐhLáÇЫ$ŒÀ•Þ(²ëT­gs–ƒª ‰ZéN-F£(·e_vë²vÛݨf,¿naÑ Ø&/ÍdÓŽwÈͶR8Qv8v­¬õ²i7Žý§eÓñ?]ËÖ«ñ½[º–y­‚¹Sd–ÎãÕétc·VHGMEDÃLŒ™å$Ê#o'ÅXˆÑí‡6ÍI*2” |,Î ‡‚DIŠkWëô, ›­j¥u4<&¡ŸÖr©ÜÌg¬.vɺÖ8Å,;§àžNÂÆåäo‘¨äµªªÂÖîðÓÛ¶¬»~Ö訕r˜ƒ?’í*ðä›{È"#yÔ«lg/o„Ú‰µæþ0ºÎE0vòíp.ËòñåµÜ¨SîŽ Ø˜Ð3+d“ð÷fÆãp¯Ìÿ[e •PtCœ`b䆄ŽÜ`öjÜë¸À?Yí$ÄXdF—Ù8£ÆÉf‰£»‰ Á —yȧ”Oí6'Oà> ÷$l­›jÆŒ.Qh„5«&lí.4ø¿RH«zÑð¶l›z£ê¬"âÄÁÕÕÈ×mvmᎹÍx=ã4Ü­ÜFݸƒÝ˜A®šf;¶­,ºÒséÜ~­º#ÁI§q¾—m}$9'K¼wã}FPGUB“§‹Ù¾ èÓk-4²IõNÒ®Ž|‡¥ôuoóTHWh]ÚÇ/­¡½´?ô†¡`˜|(’v×ó~·×¾•[°!Ÿ=›Ì™¦˜ùßC,Ý4°l"ý‘ìnç—•i4OÖ솰 e¬…[¯r­êvm ]â;¡¡U¶‡ÔŸö/}·ô5Ç ‰yôÿ~…à"' ÍûDòøGˆ_ðk¤„ë­*ºÆ6U.§odW˜H\Û*4í)U½êÜ Û…2Vå­ª'¶OIDóoó9ƒÃÈ8;õsÆãUAùRèË‚3I7´ cs” %{cœþ2És"²¾;Ñê}xÊëdœžÅþh_–!ò|]÷ÚW`€øºw¥I| =qáGŽoÿ2ÐcÕèi ÷6ðuœ*¸€œ00¯Ù¦Ã¤†Ð‡îIpû[ù9þ endstream endobj 2034 0 obj << /Length 1534 /Filter /FlateDecode >> stream xڵɎ£Fôî¯@ÎK¡¦ +9Lf‰’C¶iåÒ3j•qÙ&Áàîåïój£v{ÜE–L-¯Þ¾â`ààÇÙW³7cd(Kh\m‚1bq¤ FœÑàj\‡M)«íÍJæwÌÕM]ݨ¦©›Å—«Ÿß|déà=Ë”f`7/ &h†A€NБhªí£·Í‚àp{Ü«ªkGϧß7)2/‚ˆd(åÜ"’e]m§ô‡Ü¦ ÊõÌþ¹ „„*ï@²ˆrÞíêVÙe©ªm·³ëµêT³/*wµ«”‡wv³—Õ‚ððÁîºb¯Z«¥1£YŒHO÷þ„S§=@ÑZt:(Ù©5šÈ4 ªˆ§1¨"E8%/Qƒ,Ê‘íê!ùóĪíJ:-\FÿÑŒ…c‰,»² PºS6\ßjU[{q¢EÇ$¼² ìÑdð¬Þœ²B"æÌÓíÙœp®)ñP½ñ‹Ö2ëk¦Ÿ³>áHdÉ9óGŒ”jw&(óî|Ò ¦že @3”0÷ð“r®ú¶lë“5!ßRìTcµ ~‚´~eÈ&öÕ‡{¹?”ê|I²$î9ÀAê•qŒÃï"ûÅK®±Âˈ`ÐPæ•:ܘ ÿŒ9¾ÿÖÂ’%…-¹~MAÿÀ‹þÆÞ¿k´öízÓ¨vg—·F/­Ý¬ìךª€,d¶û¢mûÍ­ ±åÅ|Uò¦¨º‰Oò]óyôKíûkýÒÀXwòÈËîÄäÖᥟ‘.žá³§–ë¿ù¦®çŽáùJ6s̓ۗE«%Æ¥ê ìZ}㥙}¸šý3Óq‰Ò×­˜a”à$È÷³ë/8XÃ%°€X&‚;ºbZ±û2ø4ûýY4Åq¸€<&€!7_-ŽïŽGñE(D)ÍÀ—»4ù¾h¥t•ð-(§9ÀkëÊ~Â"æ¡£rRLDRöM‰G1Ý#ã1Hìüæ½jó¦8tpóŠdòAk…dPZvÍŸ•Ýß±-Nø!4ÛÀ/ÿxRm nPH.ÊUÝt½Ÿ)7 zޤ/7òØÕ{ˆÑ\–åƒå¢•Z÷6ÙÙi?½•=÷²³«\:VÚZ»ãW–Eß“\ "9Ê2î™-eÛY÷ºDPZOû:cÊEÅ:­f鸴üj¬i4ð‚%,|¨°ˆt,ÖMÔs´öΪ7¦:ëû~ô¹Ém±V0æ RF+·`õ`ïÛÀt6mê½{îß;ÝDMx,Î VB)Âqßø^§öÝt¶ Ú¹ƒM]–Ög úèVo³yoù Ëä]Šˆpµì3¥ü\%PœÏмQÐm¬U3?Á|œ!AzÞ—ÀÀydà¸ÉÔoT'<ûÿóg˜+2ÑÏÆPËåËÜZœ$æ#·¨\'çŒðq ú2•¯Yå»ùÉñ N g·´Ÿ¶€Ö§øŒ1Õ*sÝjø Ã1’ý~spIyhÕE.òÇÉ”]çþzÂ8ˆš"öjÆ7Dz<Å4t‘BˆsL?†# 8Ïñ´MM9t£Võ7(³"¬÷u§<2?ùéR«ïšé4¤]÷ È+êá;ˆ¡“3"‚gN6ñéþ»ä©é~?àd¹„iYKï£gJ•SD1å¹4ÕqÝ5fÒ¶{'w*l’ní©)Ëf奆åÚÃ#ô¿0w±ŒÂÜeæx¹“Udk I Œ¢tœœ×¥rü¯ë~ļÓ#ím )ešJ!ª!æÏçÑàÚ4?uvþ–q7­õs¤“޼>áP:(üôÞ Gõê/HýˆYxH_ Zû”LC¨¶¹3î…Ù1e¯«ô EéÈ´@úÐƪNlcÃ,eƒLÇ{—KùnÓ9K­e'§‰Àõù<0° ™e®ÕkáÊ;Û87Ó¿>w"ÌMc\UŸú.Îež×ÍÚö ¾~Dü4°t Jc2*A—õ  "°ÑH}66ÑÉЇÎü_ðöäi endstream endobj 2046 0 obj << /Length 1116 /Filter /FlateDecode >> stream xÚ•VKoÛH ¾ûWîE¢É<ô ÐCI]v㜺…1–Ƕ¶²ÆÕÈóï—ó*9JâœHIœò#)ìm<ìý9ùc>¹¼c‰—¡,¦±7_{cÄÂØKbŒ"F½ùÊûæLgßç]Þ…QÏ”ÑL#•ó’×3Šý yÞ‹`_‹U‘óF(}v‚Kð÷@‚% ‰~i±n|·/ON¾&/ï(óR8‡æ©Åih±>Í‚cÿ¦Pû’?Ûn…*ÀK±.ÄÊ>/yþ£©y.죬¬u-k«®[e)›m{H9{^9œºäÕFÇñ£,ʱ@uÕZP‚2ˆºo!÷M!+õ/Žð+8¤s´èÂ^ÈjÑ ö³ÓeÍ«|;½x éå1ƒ}u%*›‘þÙa¬$y㲪‘{}éZÊik;¹O~N4w°G:ÒÅ„"–/ßM¾}ÇÞ >*bYê=Ó‚’^z“¿_%…a6ð¢Çlˆ-‰e2TùMÚwbÌ Æ@ËÈñõÁr? ö5–ÕöõŒ%þtôÚQ½FØG®m7iÜ(¤(Œ]…n„ÊëÂpi´•N›_·NŠÚÓó­PÝUºk˜ç|+òV5-¡nŦ˜ÑÈÿ5#‘/ªÓ”˜ÑÊÓV4[Ѧlë>ÛSyÓBÎÝÔÖ (ììyÓ¸Wrme)ªîL­ÔÑJN]­¾è ñùjU˜Ä˜§F:iB¥ÝÜöÂŽÀ!§h„Xµ#°P ÕÔEµÑ|o©~’ã(A8ëNè|ŒÀÆPƒ¤‡º”²|3La¬µ¯Es¨«XƒkÚšÝ]ß?ÜŽ€Á¦ø·óu——¢¶jQíS••»B)¸¶Íw@³ Eqi‡ÁÙqd2Æiâ·ò ÄúPj=v$‚—¦M¾Ͼ‚Æ"©¿9ì`™rg±¦Oe¿>˃;º>T¹+( M¥ãÈäÜq+tœ¥pº)–Õmñ‰ÙË$â“kýó8šDhB·Iì‘"c”dï#Dîp³,Ð$F0“ ë1¢nª=*¾çïÎW€æ³i¼EY¨FðØö”ÁÞ:µäÜùy¶¿L«Û¾0.ªFlD}òJ–¥8Ï6ßrØpƒ¾p+ºÊåÊ£·¿>Þß¿h)70*Ëóœ×üé=Ãn¢´±µ´ýpdËgàï¸kGͱ7k|ÓÑ\cnÍ_C{â¶=ß$ÝÛd;žþ&öûHž¥Ýè’Ëÿ€9nH+—n…À ±B'`ÇCÓka×3]ÁÏŽâF˜‰ã›î!û hTŒB„?«òÙá\Ï–¦9´®s£e.w{^‹îåËa“nÇvŒùëéQÐÐÿ²¶Ü¹iÉ>ö–yˆ}ànH™[Njl2‚°›u¯ VÖ›šE뿱²\9UVÂ-£(®ÆÃ©-J¡é:üÉ?¼ìHõ2À$Aa’~ Gc½?€ÿûçj– endstream endobj 1963 0 obj << /Type /ObjStm /N 100 /First 970 /Length 2010 /Filter /FlateDecode >> stream xÚíZMo#ǽóWôq÷žîªê¯…``íÅ&ÀÐn€$ò(y,¡È5I%»ÿÞ¯z8ú°Hs$ …rY3S=õºªºúUSž…3¾1õ;˜Bú Î*$㳨 1T¥ˆ¡Tu‹aRåè GUŽÞˆ— 9#xìKJ&$¢˜ìô= ïp…U‚ ¢ú|pª÷0(x5“`4‘𑲾?©YªØKõ)p‘Ó±)ª$•Š!©ÊÎP`½—=¤¬z™ Åj—“ÂË:;rj#ê<AÁˆÕM9v¾ŽM†}¨R†ê<2"âLä`¸3ûÜ™€ÛXMp ÃÕ‚úŒ·0 {ÅY`!‡:^-p9LJœ×9–窗tÞ/ňÀ£Ðƒ™T‚ÿáî $„¤À‚ `!E<«ãÂãÕIÎeˆà8ç$8Ôd`ÄO RÔ7ã2HÐ{€¢s°‡„$ú>/&äàh¢Ã¼³WAbŒ‰Þ«y|D«z1‘œš'x‚š'ÑN§ƒÙE„ˆ!UWBM¸H¹€¹ÀŠ—`"¤Š ÷")^L3&ª#`6kÈ.“óê K>z˜`oë0äHÒÜÅ­`R¨ÀlRjBŸÄo2) B‰ÄN±ºë%%®ú04ã²!eŠj€ %5/x¯ffÄ€ì4á„ð“ôì‘¿šé¬ÏTŠ:S{u °d:,Œ,Ž'''“æ9ÃÒóXЧ¦ùÇ?ÿ…õå,‹F›lF”×óù§É7ßü_ûÈÚŽl@À‡ic[,â{Êï—‹991Í{dœ ðuÔ{¤ŽÅîY)HŽîKDÝ„ˆR±“°*º1xyóÃjyñ¡Ý˜3Óüðî½i>¶_6æÆîǯŸ[<˜^¶“æ;`h›µÖÑjfÒœ¶ëåõꢭ÷bwïoíO³é·Ë/æL͇¬nY¼ÍåìMWx‰VÇÐé¿],–xéY·)(¬º)l…Ø ©r/”­\/ø^ ^à^èßœº7ÿn‚äùp}¾©×-þ=i¾]®~jWuîSó—æûæ»3_/tæ𙆠õ®Vœ–êl=f+1ZöP{[ƒöÁ4^~\ÄüÕéÏ ;[ÛÓë¹]]l¦›ÙE½šÏ6íj:­Qœäh=v¨j¼uðúp¿^/ÇÀmÅ&l¸"lE7íälTrÄr½ ÚŨ0¨«›@[ª-LaÜêê|9Ÿ]Œéê±·‚Ýž¼· H–KÙï—«Ï›¯S»øÏxp¸x[PU@‰¬×pQFyÃÎź_*L:{˜[ æóAÀ°ÑÁÙr@¨X¤Õ–3ÊÀÉþus5[¯g‹ËœéêrÄ\ñ I 2[,U®mBÍ!qº¼_:U¶h tŸõÜåC÷XÏ>ôd¢Sè!Ñ)îÙD'÷´&÷´&÷´&—1 J§6³ûú×`3k«åž­“ùô¼‘ g¶Ú½lÁ0Gm€†YL¯Æ\±œm(z„ámBcÈÜÄ€°EЇAûåóªE¹_.FtOLH ¹-j:-rÊÚz³Âîó „ÿˆRvt# µ,P¨Í•üî(ÚÞêè8ÚàÆäã˜M×óû,rN~_~êÙËsËOé«Né«Né&WÏŒ¶‚ë?fAò ƒNÀ8õ|Í[‡œ¨³é‚ä²Mk‡…°é„áXþ°í²í ÖòmÒb•i ˜ömoÆX^’ílêdš·''Õ@óíârÑ|hþ~ú½þ½úe³ù¼~Ó4—³Í/×çöbyÕ¬þ4Ÿ7«ùtqÙ€“^·ë&r|ýd¨7!Ó3POUm©ÐÑÛ…ü‚XŸJV9ëõ,9áÛÔbcÎû©3Êû1Îg´.Ýà!´YÚ†Âóón0ï4….ð÷•øÝÚd(2P;l¯e 2] ƒµÑþ$WÏ÷Uì'iŸižY¤ëyzW€=÷‚ŒY‰%DKØ"–³þJЗ Jø»í£¬ mo¹˜ˆ¢“þÊ„­AÄD_lÈþ œqù! šlý} Mw6ì‹U-’/´ͺýµ;˜/±úcÉðµzWùf­‚ÔH9†r„»³ð@íÔ)…¡ÚZæÊPmaÖ3¹ÚÅÆ8T›ó‰Ž¤ Þî‡:°—ºj{m ÊØé>B:FsLŽw°S¦g>ÊÛzG=åž‹ò¸\TOGPTYa±¸‰ý±Ma)ìg€çËÕfÄSÏ„N%ù½)8×AóézÓu£«Õr5"žà›†r€yða-…z]°_Ð~’RIÜ›7÷QýøêÇ×#"súk‚þ'€³úo‚þ1(¯‹ð\æ'xª.9~ …âGQ(ÞI¡Šu;åvk Š;Ëø.mA gŽ¢ÍØ sâ¡Úé’‡jSÝåe<67Nÿ-ña…yR…»ë H¸»Ê‡n—vÄfò1”CÔ ÿµJåÁÓ endstream endobj 2065 0 obj << /Length 1446 /Filter /FlateDecode >> stream xÚíWKÛ6¾ûWè(1ÇDIzآ٢A/Iô ­Ìµ„È”CɻٟáKyã4-ÐCaÒˆÃ!ç›ofHm#ý¾øu½x~¤Q Ny´¾‹ƈ%<Ê8F)£Ñz½ûªÛ‹ÍM#¡Êjh–4ï—$ÅòãúÕók–M,°‚£¬(À¾™K0ÓJ ì–m>Ñ^yõÍôG;é­ËMq|Õö]0ýø„Ê#¥EûúÆŸn…äÑŠˆrnÍ{±Ú+±iªr}`†Ÿ¹s–£÷f?·¥«§Ì¼\/>/ˆ™IF0y¾åQµ[¼ÿˆ£ Œ½» >=Í]”‚²„Á{½]¼žqw0ʦ>ŒxB"ËR>°{qƒ$€‰PØñ{}ýÐt²‘[Þ`½” Rd^×-dõ£,Ch§vw•6i±šÇ(ÉQšf?’#`ÓhŒpÅ‘é7ÑWªÙëõg©t¤Iz€€T”9lÕA½®E¯ÉÊØÄK#Öå’bŸ'ð…Æ·BH;¦„,wbc…¡³ÏCïô†ÚY¬`ˉ·!µí²‰ °6¥íª²½™KMŠ(Õ€Á0¦_ÐrÅp¢ÑË<Ú•š¶µo·n/ªrIâ6Æ!ey0'A…¤‘6u­ð"Ý/ƒ•vì”}µn©^Æ|èîìSµ¥Ü"ç@P-t¨hŽ()ìbïúr+Έðyš6'¥áÛŒù€S|_¶ð"Å8þÅ>ÖoÞ½|f_ï„0Ø[¡n„¼×“áOôß`¬¡ $X­3¤ìµ2BÈ™E?o÷¶‘ ï©a˜˜µ+ýeÏ…ÅeÜ•Zo;àlÿdtÎEÅe¢Åÿ¤}Lq¨\Ô3úÊÒ§ß[1“',EE–xmÊ™$¡%d¬\ÀÕoí@ÉÍÆw}õçÛY; *ðhÙ­­ë¦w\×äw šèO²F‰á ¤Oh¸–Š.Mfö”`„ñè\ÓŸry»Áe˜·‚,½Ϙ+€™«í†7Çhm$ Ô3SÚÕIÍý‘Ù ƒ¥ÕAš*l¾ùòj¥‡ºRTÕVÚ˜R& Š ZÁ€IûÍšf~ ”Änß©R=úD2UÌ1Ï¥¦«Õ¶p_šÉt7P±m´úgZJJΊàèà•{18sÝh¶Qv´SͶÑuÞ Œ¡ïŸ9hMú—ÇåZSqží)℆ÍeR¹ÎñJw`æg•r3g™#6Roèë ìBËÉXî'iÀqKÝ–L?%E2ÁLËÌ“ÃIËÐ@áÁ Ýx0ð²1ÌB&L#°bP×Î#•¢|ôy/ħK*¦é6(]À]¾»~YÕ¥Îg´ÏjèT¶Oç’m¾œß¡ €xž„YþOëÿlZë>~yOtD8‰ :§yŽàXô¯ÞVhFàÄê‚Ò‹Ïôî'ÈJ-Y‹²·$Òù">„¬D˜ºj¯·ú8"Ì¡¤÷#öYÊ£¦º·‡ë3¨¤p.aüŸ¹ŸP¸ì2záýä;—Zwa8kÑî…®ZÊOÆm'=h¡ÓB\Øì»FŸÍ̘.ÎæÅŸ9Ì„ÚÍ> stream xÚ­WKoã6¾ûWèVXqI‘ÔãÐCŠnŠöТݴ@±]¬DÛêÊ’CQ›äßw(’Š%ËI,r°È 9¯o¾â`àà§Õ7«÷×4 r”'qÜl‚1¢, Ò#Nãঠ>…³õç›_Þ_3~$JÓ šÃEƒP'õ­\>”‘^a§4$GÇ".ŠS³iO_©5Áá¶ßËFw“ãóß÷×1=68 "’¡,%ö¢j÷sõǦ ʳØ}³“ë(æ8ì´Pºj¶vuh«FÛÏvcõ()ïzÙÍ´L¬Šœšˆ$ˆ0ç£nß`˜lÊ#›.WúðzWVÑW“DYèVÙõý®íœ1µl¶zg¿«n˜Kç©Ï™52ÓÜjýkÇ¡¨{¹˜õ9ܬîV「´Á /Ҡد>}ÆA ÿ„ûͳà~ÝŒ”2 ßuðqõûÙ Ü4-up'a$`9„*9bSÆaÐ`G<Ì?JWÚÂvk¸çi×ÁyãËhÊ®«Úæ¼Û,ã(IÈ%n[êM¨—qŽ(våû£ì U´Wa}˜Ú¥Œ†;Y v!”Ûí;¹ékóÍ ? {{ñeˆ]=¶½²_›¾)C†Õ½‘iÕ»ÚÊFB)‰ÚÔ’¹ì¾Òkîìâ®o»^I¯ÜÄÝ|(aªôÞ.|ï]4ÂPÉ}I€âs^WªÓö”Ñh«s•$C”ß:<{üÎÇ)Š)ó|$¬MZ‰B[GD37ÖØåÌú ¨ÂŠA̾[†|”˶q_Õ桘!æ;¹ì~D &yÆO£õgg=§9Â<4å<OÀd7NÇêi ®¶U#j»ÝþûŸ4±DZ+ÑJ¡åìØI€h–‡¯‰ÁLoe át)©{ÕØsî³ÙõµÓ=øÔÑ('(i|^ö—å(#c¦M0tŠ +ûmZdfÓª}_ »7´—ó;uÏÊ”ò-Ð6i¨õþ_5‡^»½Çƒ41ÁYøk«ÝÿõNè?chš„$dÔà å>2Ž(ËVº†Ý´ŽéŠh¶®yWºó=¬|ç7 tEí»Î €Ž‡Ú†¤¯j“vb+_ß#ÏSÛq \újæˆI_ƒ@Sðò¥Üˆefñ½ýy8Šê³ž|³‘õ’Í€*Ïfø{g ”‡E=°¬Y ÔlEz¢®*ei—Ö€>Æiø³»O”e¥‡›H3x \H)iæåEQȃ¶œCÍR˜3&5»Qb/»Ë'Û¯'CãË¡¬Zº*}“ŸÒÔ¥6x]6cg期ٰ†¬#úæÈ+<·< "#MÂ÷ýN6 ©"Œ£ô)ô ¹I‡À;;Ãgžr7üd§üft*q€ bÍyh¸‹rNF/ÜEö‰3îJ錪—cé* $Yo–ILjqö ã{k£æç©Ñ~B-…?†^š]P(C/¢þ²…ëžaãptŠÓçl€ ãyrÁä3·a!Ü””áÙ»í£t»ª»ö ýÁʵ üç/’!ŒŠ·KVŸ-/ŠÒd4ߌ–VøUªgD£·»TïˆU“‹ˆaæÞj˜VíŽ^^gQÂfô¹ä3*,{âè·‡¡{³Îa|±7ðøžrLO ÿéá0”˜C³" E(Á«ë"¡u endstream endobj 2097 0 obj << /Length 1312 /Filter /FlateDecode >> stream xÚ­WYoã6~÷¯ÒˆQuíÃÝ,¶hã-Pdƒ€‘)[¨‡¢»ûÛ;¼IQœ¤- ˜#jf8Ç73”ç¬Ïù4ûy9;»‰“¢4ò#g™;ØóPFNyˆ¾³\9×ó–‰ÛšV¬]Ü,=»âž@F(NSP§X±G$ÓÌ3'wÔãv-»ëÇrS }ÜÓj[jõäKëÙ…8 G¡28q\£8Hµ®|áÏ›ÿèêõ{Þ4ß<âÝQ –'€{(%F‚ %îw`Rd(ù’tÎ!0C ÅŠÕ¢)ݧ3±·Š_>Y¥}Å>F)8¤¯!èl¿åÊ”—Nï3±gLSšÌñ“G¶}ÆÓQ8îèßÇâЗe¯ÈÎ>.g÷3 *<w# A‘¬š]ßxÎ ^Â)(HçQ±VNˆ1ŠÃèÒ¹šýö"F®&=\ƒ­Qˆ%(Š£ \÷ÆI¥ ¶¿bbáúÄ›kAE6¹^©^X&~ÄQ¡lx‡£Ê¡A%uÊüE„hã~amÆ‹­(šz²–tµ$P-FàJл’M”µÌ.Aij±ÜÆW»²û]±ðÉüAþÑP®÷EcN†J¾v,ùû§qR’yqb#Û *ÚósHÊZ[#ãvÒ·2 Q”øVÁ©¶à±MU gšÊ;nóEë•&ZÁ‹L0n¶ù'óõ®êœÉ6,û«¨×ÈDhÐÊ0à²èÊ$&ž_[ºfooc½tŽÓAS†aoê©®ôú“^ì6BÈê¹Cû>€‹žqñx»}žý±´ÄTL—–?ã¹® ‘®‚ÐHÏàP×(@±®LžÁíÿ`„­Yd£Ql \ZÕÓ%À^[8Q3ÿ† ‰”^/.#K¾!ÊféÌW Ôö£?ÁH°lgÀGkcÍ–eE~xÖvŠzdvÞ”e#ëñ0kŠAæ›ÚóA¨ { ÙÀšþÍ÷‡³Û¹Vðúl"u°†­lþ±ƒN'¢’@Ïô’cA‰¡vAy,ÊRë¼cOn®Æõ\ˆ–•ù0뎛B#L†<âÊDciGm%8² ´äŒ®T6Âù†ª\Œˆ ± ç[Þ,0ôJ¸ è ªò]©f­654a·áÕ®¤zS ¬œÖ­|cð£‹Ú…9‘Úîßá€ÉÃöE+:(óРŸ;ØPÛæh˦²ˆ} Ãnô™‚ÂBW0"²úcî²È­ÖCVNä÷ àÞxí{Bbä'Ñú­¾S oº$· ÖEÛ½·;Î_v/&êí]øÿ. ÜÄ硹Rdòñ„ž˜Ç“»ŽÊ:juòÚ÷À„â’ Èf{ ;7ï}“9SŸ5?,º9&WU¤’hYÖÈüHšr{ïS_p­^›ª*„ʘâÑ‹¹Þ͸’¤Wê¥W¯zøróŠ J଩(XyÐ[jب”Éa£ÜÚm·ö­1¹›3_‡£hcÏôû0a-»¿¥eS¯%›ºo¾-–r­DF¹ÜÁF¿hÀNÆŸ]ñí ŸNÿ‘Ò endstream endobj 2108 0 obj << /Length 1154 /Filter /FlateDecode >> stream xÚµWY#5~ϯh »R‚6Ûí¾ ì‚7Dàeg58‰3iH´9þ=å«ÓÎt2Ãjy‰ÝvU¹Ž¯Žàè.ÂÑO““Ëë8‹ T¤4›ˆ`Œb–FYŠQÓh±Ž>N NgŸ¿\^³d@ ¥2Dª\?‰M¦÷ú‡ïæk®¸f›`÷Úå5£øS¦ùç1£FÀ<†CJ¬˜¯fóãéÏ»ª­°›²n÷ÊnïÅJ5;–vÝ×5¯Äú;Uáí¦ì¤;2dvË7Jx1JŠÝFk šÎ FERú,ŦéÄ‘N›}½ReS‡ñ¶Ý•bý͘4)Ô­Ö@ÞàÓY5û¶\ÏI *Hîõ0HðÀƒz×ûÿOK¸˜!–Çž!4"ƒÄ¢zF†ÙyocË¥ônTÍ ·XÌãå á´¶‚¯õZ©ïô y׿¢v·›¦¹ðî™|XLþ™Ð G¤Gm H"Ѫš|ü„£5\Q\äу!¬"FʘvÉ.úmòkÍãÕ$¸a ~ÊH”BP8ÕšñT!œÉD(*râ÷c7‹³©à üDŠ]@ȲÙÙ½†µ^w¥Æ«9Ù ©äÛ1D*gÿÅz›þéHú'YòÌAォ®l Ò‡Ö¬KH±ÎQê¸[!ÁÒ~*þ÷Œà©»”ª+ë;wÅÝê²ÞÕkǶïj·ÛŠÊÓiüä 7ךѱ8±ªý.ù5鹉!œ‰YÑã@ø1HÞ’—ô÷2 8©³ WöÌݾµ’g5<¡™sþã<ƒ@e)†zt^ Ãð"m°F½\0#6°çYA¡'ìÅgèêyš@-î+Õ/Id§·ÇÅdàñá43™áh{lñ—ÒïÌóEð¡ûŸzò+ïßõ#š"c¡#?<òªÝ ùzÔJ½ök~eAk[øº-ªV=Ù­GÞwBgœ<*òU)eOÂ; Õ°çåA ..N·6§‡ï.Ü«1ˆ¡}¨ö½[ÞZî»~\¸‡Öê>7L¾Úº°£íÐ`gä-Øçßt4«êkØÏ÷0š1“ôÿíb4ÉÌm÷ãóÚ¹nö^“›th»K¦MÝìëA‚Ø ÂíNÌŒ†PxßGÆÍg ¢˜|™6FIŠpÁ¾d˰··5Ó“î®ÑïƒþdÓ§foÏMC‚u鸌a4\ééÔp.ÓÜ€ëà(B¾Œ©)K°o–ÁÌëÚºWä®ãUe ¶Sª­½òÁ40…\K\Ë«¸´Mw}Ô’Ñ Ÿð±ma7þT6™¾Û•àÑÍTg)Þ~ÿÖU½‚1H'ź”­=ûÎ.H«þæpüµ;õý›ªOSA3Ó¬®.)qJÞPš<ÿr`ÉK…Øûm¬]ôµ*bWºÿ:TáP¯yçößOWòåΟoº¦ê–©¿„18t¾™Á’  ôø ;À[cfPÄHú‚€.²^i‰£.!'t‡dú¿²“Ü endstream endobj 2121 0 obj << /Length 1876 /Filter /FlateDecode >> stream xÚ½XmoÜ6 þ~¿ÂVÌz®ß_†m@›.†¶ÀÒôS[:[wçm]e¹YöëGŠ’c_œd†¡@Eó(Ê$>¢ã;;Çw~[½ºZ½¸ˆ§ðŠ4L«­ø¾Å©“¥¾—D¡sU9]%Yɯ7¬<œ}¾úýÅE”MvDEêeEþ´màgh´òÍÎ:Êrm°3ÜDf¯xɆžŸ­ÃÄwÕÞ‡áHrÝÓÊÏ‚ÄýëØÔe­žö’Ï­:A+k7õn¨Õ-=n¸ºá¼3BíI:Ô]e6Š-­_ÏÂÄe²f›†÷ÞÙ: |÷\´G&ù³€ìúâ"Œ&ið!¾Øó“‚â«êâH|ßýiMkࣴ ¯H²kUÉdOÏ~yFB;(¦ø'?ñïÜüL‹W1ž»Sÿ`Ô¼ûªµ°)ø/ιwÂÔù NB¿‚jj£Y~‚Üó3 Å‚'@HœÇÖJlþä¥ÂòB*^¡&w·R´ô›lX·#‘໬éidÛ¡!Y úµnÑ‘ÙÑÑz+IÒpÎvœL;Öò4|ê¡pÙY¨!ø©+ïuœxIϳÎ[—´œ¿}MB¹çÐJ·Ê ùfoq*ù–KYSL¾9Ó7é0°µÑOšGçTK-ëÞˆ‚Ôóƒ˜Þç>-‚Tª=S UŠ¡ëóðÉ2A-ãÀZaÎÑ¥èš[”b G):1tдQ¸µ"-™Ç9)Œµä¬¡_(Ôm%¤ßCÆ+{PËYgœè0´êGBɺïÏ‚ÜUÆ‚Îd:ò§«•æ^ ‘SµR D×2èç®´¶ìH£e;t¥ªEg¬”_ñ?nì© ”¢S¼SÖÝv©#€Ã,y2Ù±WL:©û¾në†IHxš¸Ï— ™zI8’2ÒÃ’k¾È§uÄ—Õ…Ñ1›0Y©¬ Ê—´Tch€*ÜB˜6 øÀËübÞ˜O¤ë®W¬+¹!òZè ÞUCÅÞ4¦Ö;-ÈÇ1b]uÒý°é¹Rcëˆ#—L ÙÛÛà¾ßªÞ"óCÇ_ʧgR•NRµrˆnºÐ°Ü‡9bébxâ¢@G@†YœÔ]óhäÁ½š=ú"øúB¶ÔÏ §ÏJ~zúËnJ.ó+±lXß/`+‹½ Û_³ïõ–ø5Frmº~nAy~:n´Ç4¼ÛÙ‹Y§~õëÕêË í|''’8àIœ²]}üì;ü)ó"ð6mp—ÅÈó~õǃÑcϼ(ï¥@i1ôMKcÏ$£ñ<ªÐ+ò1ªsvTp“DÙ pÁ Bï $‚/”‡#aø-‘êˆf8ùp5úÍûRÖGM`ß‚ P?Ã@:3ø˜Ýb¼È›ø£îDzþeà]iž°ÔdÜ4£¥fnÎ*£d6z)I펖{ñ> ·-WuK'“k^ݽÅ „&HŸðv ‚*ãb2‰ô¢È¯ ûû–4Û‹†Ãf`öü‘êÁºMÉ-)õXë%ý¢¹‰J›[Ò2R*ɹqz³¯Ë½Ñ.ŽQQœCŒh뇶eòG¸†³µÝ1»ê u{QÍÛ]íí0=%ƒ›ZG§ÇJr'kþ'’<íDŒT‰ù¬úîÛ7ÏI„_á`tòët*Ö;ëp" íŸ'‰|4¸—‹ÝÐê{þ± Ÿ™óˬ€Y ô2ŽdWuyî~òýPöŠôœDâÉÍLJ=Bº1FuW6C¥'éÜ`5·ˆF3ÛâØ"¡½ÈA)hH2öÓ6Kïâ99ÐR‡ÖîOnrÉÀ%fpšnMÅ{IÓpzœxè„»ñÊÇ6yz„ÌBs¿9×iкŽV1T]0^Ñ3 æhM3&¨ô,MtT5²µš£öþ„[-IÇA ¾Kk ½§'i8HH:Yû4cÅ‘Áå0K9 .øÊ0Cíô4šÆ4„ê'ýåœîV˜ŸHÍÚcÃi¯N%¬ ÒÜ“hmah«+cÆŒÙå[&•@F¸éȬå` 7ú}…uà û»‘o°›˜ÞŽ‚.1¨5ˆ`¥ƒpèj%Éè>7“IËË=ëê¾íÍ^A+;93{ëîÄï:õîÚ´ãì³Ê°Î·5qÜ–"Ét0Š÷;¸(ÌÕèëÆõ®ƒé‰VeÏ:¾W òµÓÁÖ~¡D²ÞíU+t¿Eú‚Þ’$ÌJI‹fÀÖSGƒD ¬£§[ÝŽÛ3LOG†NÏX/½æB£›_Þsí6²wHæó$ ªqbh*zljû¥¨w"f¢ØÎ7¤d´Ì¢?5\¦Ãx¢ÑÎ6N:qñ…Ï™a2û‡ ª4q£å:ò@Ý­IÝ»£í¦#Lî¼ÿ~@È„^îÈcÅËûWS–yq1UUò¾D¦ öÈ`¿,½ûR}¬àÓÜ “yQJÿu½\¼TJÉ™²¡onXºÀ8ý&’~,2»Â(ÿÔ| endstream endobj 2130 0 obj << /Length 1143 /Filter /FlateDecode >> stream xÚÝWKë4Þϯ¨†3Ò47I›4á±æ"] w1ôŠ ÁMœÆÇ.ŽÝˆÿŽ?§i§V,ª8îñy|ç;ç8ád= 'ßß|³¼y÷~¶˜äAžÆédYM¢0 fót²Hà ™Å“e9ùù. ³û_—Þ½Ÿ'=ÑYšIžHEg €/+P¼*ٛИúÓÞ¡©=5jSŸýr€pë<*ˆg}³É4ʃ0Jûf1$k^ÿ&¡üEÚY/®EH5ÆU¹`¤½ŸÆIxÇk¨D4+ÈôšVúY1Ð@#ˆˆ~ýP‘vÆcÎ 3•=ä<7ž>îA³Áp<ÊѨ3©/»¨³ 4x}v?MÂðnÉP£WΙV¿Ái8*ƽ¥Àá52¨Ù0ºµâj±†2Àa©œ”ŽL£0ȓ̳ZÒB4p©ž½UQ6PÄ0 k½ÜÁU‹¸Ù¤H¶a³Å$O·,€Ñ¼‚ž'¹ç‰ha%°±‚dpæÐ+AœùζŠ_Œé¢‡ú?ìœ~ÑŒâtóÉVkùÚx%“ºÔ¾¥š¥›ÒGA¬*}â«©HB™q Õh÷ ;ôk}†ú’†ú Dzªê‡cÿ©†bBõƒ? ¿à`Ñã„cÙR¼…ô;ÆúÒØ…œ+/Q ‹Î…ì`)ƒ j`”QbÉO‰±SÔ—'€Ù¤]ÁÓù€ g´Ç´Chc{µœçL²’•’cˆºH{ëªÏ¹s9ïàìúsFö*{‰±aDÖúõ@Å ¢ü]À–p ZÙ0ª–$–Gð¬ä1§mMwˆâ˜V" c¯UƉ%­ŽÔqQ AéLw> û9_qÙ‘ò›ñšö<˜g³ÓñèO)Oi2 yvI§=IÌc?ä½_éÿ$™}þïÇàìªNïÆreZãíŠRÔ·oñDvi¯:0âÛÚ„ ;5N‰pK]ß7%7 Q6]U9\ ‡cVÅhs:C€mSÖÖÇý>:¦|ˆŸžžÆÄ”!ià ÀZƒëŸö°kØ6g_ê÷(üë\ùºÌÍâ [¤^¤Ï²Ú¨¥„ØÁ¶1­Ì:7È Ü!¨¯-ÿrt*$®î!-cîa!¸"ˆèšÆÝq l‘I\KsuÎFòK.ãùÀ^Kº#þ%¢×ÓFB¡«ÝÏßêvXqHJŸÄkÈý¡ÜoWkQ™•íUÇ© ×H‘ nEi¤³ÑÄÀ!jm;Ep7Ûd:£D0z‰*(!ƒ$ ô­Ü…îÎqÛŠ¦#3éö«u•¨ÒoЇEM=j-Ÿ?=>X¨d+?ùóœúÓÖiƒœKzöb-‡9Ú ­*Û.7°pÝrW£¢¶mÇ]|å$¸½ðfã3ÍU®åÄé½ÊÄÒ¹´C–s#Ap÷)A+o*ž/9ܵŸ§gÝ(Uœë–)#·êÿè6+MKëÿ‡°'ŸŽË›¿£00 endstream endobj 2139 0 obj << /Length 1356 /Filter /FlateDecode >> stream xÚ¥XÝoÛ6÷_¡G˜RE)À²%-V–8ØCR´LÛÚdÊ“ä&ùïwül)Š“¸( RæÝñ>w öVö>O~›MÎ>EÌKQ‡±7[zcD£Øã1FŒ†ÞláÝûÍóVÛJ.òL4²ž~›}9ûDùMcÄÓ„‚SM4Áîž«Ùä¿ -öÈþŠ£0¥^¶™ÜÃÞ¿xp”&Þ£!Ýx!ˆGö…w;ù«“7\!=´ƒ`GÄã°R¿jG'üÀ{ü!JÒ4›òÈîi2ìo«)å~Ǫ…qš ÂùG,4–Ðx$"1!Î’KYgU¾mòRõ¬Ø[Ó I¼€$(Nœ5kYƒ)4dÆ%vwàó-òÞD~SÚ6âß)Áþ Fàhrµ²¹²ëåÝ”•£ÊJUçu#Uƒ¦£L+1%̶„¢¥{¬Äv+«V‰ªÜ©…3þ¡Ä«V^»½ù< ;; J³†ÎE-Ïϵªåò3 ÿÉ ê=?Å)â´Ëâ_l´ëÒ®%¨î±¢q«] 9mhƒdašK%E³¶·ôì6²[ÙdÈUÐa˜ƒ„›»%ÜéW‹• ðË€÷Ó¿ð¼þ^€óµ žÀ*†±¯ìò«]®ï¾~m£R”’ŽW4å&ÏNåþ!³¦¬>ȽgÏU#W²:õöE¹›ò8·;Xæ*×ñ}·ìl-*‘5o)ç¤ÊÊ…)”÷_”+¨ÉâTã+ñx*ëüêúä ©]a•ni†Ù®Ôdzdy.*-«Ý¢>šñÇ3ýéXyó0=lËûÏù?™¶(›²-Z÷ ˜&h ¬wqà¤$BQêÌPï¿þêi ×ËE jÕ‚E¹ìa‹E]CSÆüëäÒúÝŠý½–ÍZVÀ”ú¢(ô&-4;Óà@+©RûÚ–Ó :P<`j 4îÇØà¾!P¥ Ú³ñ;´“;=#Ä"ƺÖ|}12èÝãøK!z¤³øµ‘>L£è˜€MÈû='—‚ÔI¶© s™£(éh®Åõ›ZO)!þ­l\ &!D$¯íϦsÃZ—iGPºðjеPcŠ0ŠxÈ:M Ø_3)n‰2¡¬L]CúÓÞ!É¡ïï›cKàØQˆSçÁ¸•´«Û:\»Íãº,ä‹z0ßJÊEýJWb¶UÝ›ö¾Ùdk™Ù¡æ„ZïðüÝ•u)—;ÕBލûÕ^BHo1ŠÒÈêq—²yQŸ0þ^n¶Pc‹óDëý»¥aÒ¬Ï{wx„"x;hO­Ä‡0d}¢{Ó.fëntÞO™FvÅ}TÝI®²b·8ȃ‘4 ´KS5’£PQ¼ó¿€&“¸&3¸~+èã*؈&³•bb£i8Ì= ÛýÜÄ b˜÷Óå5×Ü©"wƒõK )G)ï!¯Ñ~;謇³bìjE‡›Þt÷šHx§%ÈEÙÆN•΋•lvÕŽÄPݬCˆÙÍÝÕŒ„("‘ŽÈH¤#D0l÷x4 JÈ©yiÙ °Ÿ Ê‚!(û ÷g‚ÂD~[$…u™­ç•ˆû¹Æ“(ö5ëï²sôYÝ?³¡·û^j]¹™B`Ñï‡)ñÑXpŒØ>‚CF´†G bJû-ÓÀðšȨkå`8jš*Ÿktßu`¢Ýåš›• \ý*±ÑO2Š©öÃqôVºë. xþ£ãÏÑcx;° Žýb\(ä¤y‡ÂC ,~CF½šMþz×gŒ endstream endobj 2062 0 obj << /Type /ObjStm /N 100 /First 963 /Length 1567 /Filter /FlateDecode >> stream xÚíYMo›7 ¾ûWèØ^d‘õúl¶¡H{Ø–öà¦nW,³;Ûº߇r’:µÓȉ ô°Cbú}‘(’¢dÊ.8*.&ûŒ®²}ª#)&$G%šKƒâqnØê„ œ‚“dàD.Rpˆê œ¢Ó„‘!²ËÁÀQ\Ñ$ÕQ Óœ`”AÊŽ :É A›‚©ªIÀ‘ =HÅ´fM“0B²)Éâ(²)ÞEGJmæ¥ÉxØÛk HjL ¤œš ˜­]Ó™ÌD¦&A©ÀE)âQ¬æŒŠÍXÁWmìì_jì ì$hÓ‘YTDnì ,2%oKcWñ¢6v¶µ±«â$sJaHm½`[HÍDX ˜H !‘ &Q ¤Ü^´’ÙJ±(LÁ-T“0 ÍŸ°@’ÍØÊfFäX)²“u°ª1` œ—€b!@ªÌXRÙü@„1’0R°JzbŽ ø;FsÖRâÀpTø!« $ˆ-#iFÓ’¤=3’İUÈ$“ º §æ2¼d§ÄF‰ñŒ² ÖMÙ<O*'#ĈY!#~*ÚðxƒMÃ5Æ6… ©¶’E7 9ÍÁFlõlåj~ãâ´D›xiU³!ѥдŠ-¢H’…á^*HÄHJæGL<áž`fȨÁáá`øÌ ±™|솿ýþò)xg4‰OpØäüììõàÑ£ÿÑ[£5zo'Aè+b¹ME}E(]CM' wxè†G‚ðÆÛ6ì㤗_1–‹/ ‡¹„e ˜öú†ÏgÓÓã…;qÃçÏŽÜðåøÓÂ]™zùßÇ1^ŒÞç0;ž,æVìÕÁðx<ŸžÏNÇóelÏ~¿ý0z2ýäNÌ"BØÛ^P"ùR_ÃÞh%V5óÿx2™BéÉr0Zm0á+ 9¾8³hßþ0ùk0|2½Ïš±ðzøãð§áÓj_Œß)f†*à‘9™‚G‡Oƒ‡ —™tÊÅ£°î,Õ穳4¯µ×#ªìSèÕ5{lÐh.Å­ûAk𱛈þ£M)ûRè¦Ju½8­–­ýVª×+Uá{Wª\.*U®B —í¡vŠ‚¢‰£R½Y@Ì7‰ΧþøüÌ¿/ÚçøÓÇÙîJ=¾b…ÞÔ³±ëd5ß +‰Å ú§KVh„¼uV·±Ú"¯ùËÊÅÌ-ÝmdnrMË»"[TòUðí•|:aGbìPh¶OêD+©9ï³ÕÛ^0êk¯jÙÊÝÐGrêDs èîu7©zþÞ:Ú×ëmÕ{×ÛwYT>ÄùÇÀâs²³uövžHª”åæä\Œóƒä诣¿ÇóW^=\ËÑš¶ÈÑUðí9º ­8 lŒ™ûƒ¥àÔ ¶”£Ú«: ¡5“N4—äcíu#œìçûêC(”µ¼°+‰»äÅŠ욥;Ú®¿tɵ²î‚ÆLh­˜¯H/:&Ÿ©—‰…gB éDcÖÒ ÔŽ˜R'š3’›ö„0‘¼4ŽGá.÷× Bªy=«®%ßSŒi=ŨÞwë±KÂn=’a’#ÚBEuµNÁ¹Ón¦“-õ[Ïéèìl<[¶†“¿ÞuìN³¿¬‚¿dŸx»0ìDsDIîEÇ$pwÜÚü˜k/}dÝ´•lDã§ü^4[×IwØx®¥Èµ]h„õ¬àrï‡ë6W·hs6¢SEý!Ùe·»RŒîîܺî\É[9—4®•Yv»í¾ÿBH{¸T°Ý¼˜/.R´ þÆÍã||p`¦¦ï¾î}wsËAÅSû 0ød¿ô1ˆ…´“«ÐûžÈSZaX—íçÆo3œ£nfÛ\×Úï>ý™µ ¾Ê,ÆÎ¾©ß:Uö+Åö3¨í endstream endobj 2161 0 obj << /Length 1270 /Filter /FlateDecode >> stream xÚ¥WKoÛ8¾ûW(Ø‹ ¬Y’zç–î&Å9l[÷”ö m ‘%G¢’úßwHeIuâ.A">†Ãù¾y1ÔÙ:Ôù°x¿^¼»ó"'!IÈCg½q¥ÄóC' ) <î¬ çÁeŒ.¿¯?¾»óƒ‘¨çù$ä(ÒBÏK¸"—M»äÔ]åMÝɶÏeÙÔêð‚â·ëÅÓ‚Á:ìt÷‰GC'ß/¾S§€Íl%±ó¢E÷ŽÏ‰|u]å|Y|ôÍ¿˜5ÂÄ( }æD4"^£¹ÚÔ×Ͱ^'IÌ,ؿڥ¹"•b¹âEmKFÝNk9 2L"BÃè¿€4 Ï8( #Â9‚ù[ty[~a¿‹‹Aµ‘ÿÔ‹N —õÖ8vdCB©g„×;™Êf_æøäm=xlÚ¥[<&žúrÉ8ÒJÔÒ¬Ëm…;íÖ±ÃÏ~qaâŸ&–þü (ü²™Ë¦¡ß ì‘LEe/¯''hƒ|gÅ)¡ýÆy0{X”j"õÌg ©…èEM}÷Øôf`éo&ÌÆ¾ÑDÀŠ>ýãP•y)QGÖôÒˆÉJÁÊaX<a¹ÿìO} [´98°3g‚lµhìnÚfoÖËZêK·¢U€œ˜ø¡ŠF’ 4`µ¹àªÙ–yZiRõ¦Tî²aÐö•@:î2Q˜iY¿áQ q8¦L 3¾]2ó“µ|—¿á&¸¯ïÄe£Šc¡]4²;kÎ,W#PW<$a‚‰øµK·âl οóÇõ£¨Ú*WPBˆ s•–Ü# 3àÚ×P¢È.¨È—ví…;²£ÝLfN“‚6æèF×Ém¿‡JнÉÕŽàηò? ¡bó¡b7ûCSë+Aä6õ 1¬a¡6Øau¥AÞ_Asrß›’²UÙÉ%sQUZf0Nðêh4uj*ŠÓ¹Î¬ºPàl„AÕS&ôÝ—LÄü˜WâF0`Gൺ©*Sv =0H³¬Õ =—Ðõ SifUĺ>ßáÎ šº0âðfŠ2Fù(rÆæòˆÄÐ.Qö¥´6Ú&K3M0Ìt[öbß8®@㛈ç\Cc÷昫ª pB¹•Û@Š}ªköHø¡¬SÁÀT•)±ÚïËn9T9©AC+Ü§í£ ~[0S<útêÇÿ£ðÝôРS©ê˜Ç™ ,ÕáaƵ•zµÙÈU!­ÈÕ¦Ž`µkHV#Ù–[Õ6Ì>î*ÛÓ¶>)­ÍîozÙ+¨jË8¢í0pßý·©)Æ“>„l›4ÀÃ<»¥Ü™ÑÕÕÕùr ãy­¹ý‘BßÝï—ä†þPn"ýÓºþXÚö(ôpþjE{Z ªòG©ù¨V^˜á³¡ÅLTÒºl"\Û: ¯Ö$HFžõ篷é»›û/·ã¢<ƬzKœ3ÍÕ ×ÑŒtç™XßB|¶e.-„NÈ™ù¶qõD8 ÛÖÜ6szÁÈ{S@õ)^–!ÑXHÏ^‹½Q¼bÈú©Ó1kÁ½²'ÊʱA'q¾Âš `5†×„è&f%V”›h¡UxNî,!È L¥ÄÜ Z‘Ú̇GéÑ:ú]g­(ëZå²–­Ñ‡ðдkÚÞë³IÿÉü|A‰O endstream endobj 2184 0 obj << /Length 1622 /Filter /FlateDecode >> stream xÚÅXÛŽÛ6}÷W(›‡Ê@¬ˆ¢$JAû°¹lÚ"@/Ù>¥A@Û´-T–\’^¯ÑŸï𺒬x½-ŠbáEÉ3g†3ÅÁ:ˆƒ÷“×·“—7i”Q™'yp» PG8Í’ÇQ†“àv| •Ü|¡ó–ËéçÛ_Þ`Ò™Ë<"e ëiY„šÄv‹—7  ÎS%=äÐⳄ¨%̤ÅïqÓé,‹ãð;óÐ]×½.Cza^æ§Ò¯{]Il%ßôº±^DýL€8KPT¢Âyn„~jÌSn˜i´Ð⦹¡ÍÒ®ÌkÚ¬ %YÜQ¡<Êrì(ùƈôxH£´ðÂ*![n›{Áª¦qºeV°Øa!öV’jÅfôŠÁ’3GeVöô;PÞTÝlѺV-ß¶ ÜuQ9de/Ç0qyÝ´œ-_9¢»@–óúÿ´ùePܾÉ.sí-bžì~Áv²j»F%¡¬\]·¶ì›`ÇÛ»jÉú+ X¶Ü°ŽŽhõüÄmî˜r° »È¾QK[4bAkj©l·Õ¢oÂâ oÑôqWW ·Q] iÌÙ†Þ }^<¨KçÜèÙ³g+~Ô#æd‰1×t«>¢òü(™PÓµœau¡œC8I¶f¼÷¾ÛÃØT¿zeÎÅY¡øÞ;p|¿Z½è(CØÅYçˆ9í‘;IþHáøCWÙÉ»ÛÉŸ»Çòi#Ci”%e°ØN>}Žƒ% À—EpÐ¢Û E("©Š}uðqò‹OçÎM3;¹ ÔÌS¤%‰2”å¦NÚIIoj•r÷g>M³°Ý¶ü+Éôi4 ÆÍŸ¢XÅeÕ§N§zšp?&öU>Ò"‹0"OáCë󑜜f)(‘Þ2±à•Ž0=Å{y·³F^RDEž ióžyšÚs <G'E‚I.ÚfYÉjŠÂ¶±]Ô>UçÊ4ÕQFYx4o¦R&ôóvšdᡱ#ǪQðuàš¿ž(“Ä@Dî­y¢F‡„þU%üM%šÎò‚„·&,*°ªÎÀ ÛÎ!LéLŠc ü wf ¤gàŸf¸ÈÃ9]ü!9]°&³3A¥ÚÙ‘8tÚTÓv”Ëj±‡\Û!±¯$×v\¹£^žÙQ&MƆ=ÏOpÈ+ ‹O1 Ycçœ:ò€³ŒD$öT+–cþBÓq°2*Š¢³Úb䶈#‚½€AE¸Þo=žvu¹ÌpšFH_qº†yŠ7Žb(²x»go–%JJÝVcq~tÍFÏÜ¥g0;ƒì~Ç]Œ®©î:e³Í•vΫÎIíÁTkw0^k{bÅY¬Ä …ê‰$‡”8¯•_ÃL&„ŠO&zîm£²OjH¤‘—¦®6œù0«¤w6-Ïg˜–!¾,îÜÔ¶öp´_¬î› …ã­ogjß;¥…½d©wðe§¡ •Žo] _ߪUKlÚ}m•šÿU‡Q¦FÃŽW¼e’Vµø/ó.3ÇNÕ yUÅÓ?/ó4„k'dŽZ&ê]UZ5ãƒè©W[)ŽUÇl×ÅêäÌç»{Ó63KÛpÖSO©.Å¿N=&±”(J²¤¿¾7À™úo< "tBhHJbC³(=¼Y¶MÎÞ~p†ñA\i\5#1\…Ú„H}¡(*…ÃÖØö›¢‘·‡ÆU\VV¶».M_©‘]õmÄÃÊ‘yùaPº»§² Ýiå kzþã ù¶ÁîX}DoÇ[Wû+äðÛŠôõ¿`k•å]M=gòÀØðûÕÅ0ü¥MµÞt§;¨\}/M®°22ßÎ,%ûf¡’^߸ësöX_²‚3êÕ‡¾N,^äĆ'ÐéKGúüFú:”yI’ endstream endobj 2205 0 obj << /Length 1927 /Filter /FlateDecode >> stream xÚXÝoÛ6÷_!ôIbV¤¾‡m@ץ݆aÀ:o/mÈíh±%W”šøaûÛwÇ#eIq{~yŸ¿;Ês6Žç¼Ÿý°œ½~çÇNÊÒHDÎrípÏc~9qä±Ðβp>ºœ‹ùçå/¯ßá`«†L¤!¤7Ý—ííÍmV[Ù(Ü>óÌ-¯ß ßI€. ná‹„ÁÏYˆ;AþÉ =<‚¨œ÷X¦ƒÙªnZܵÆðãø»Ò4Þx¿lšº™/BÏs¿£æ_jú3^ýTnnin+¿Ê-u5Ý«+ì³FVíè†7ê '¸/ÆãÅ´z®—³/3ìzïõ‹ÂÀÉw³Ÿ=§€EˆùiâÜë­;'àœÅý­óÇì÷^ÍÓV4?0.0Ü!Kyð²Ý‚‘kpÁÒ„[{_«6[mKš¡çšæÜsÍÔµí­¤äsá¹wψÏCPSx‰øäÃÑ ñ8!v”*oÊ}[[C!ÂŽãÝÓc"0Zz[WE©‰¾»½¾`”¸à4½îª7™yiU$ Z'ò„T‚r.B÷+þ˶]v<UuG{ÑC•”†iøc‰ÓlÛýð~je‘Æ,à‘µSÞ>´7ú<*#äSÇ=­Þ­jo³ö(¬vl?ŒO¸6×6£Û²í¥Aì®Ô~À&rïoeE5ùQ§8,µªÜTý)Ñåòó$`‰H{ù«â†Žç:«q·…§¥%€ÿ§±¬¯ÕVÍíšÀÖ9”[þÌŸM;õÍ—Ñi§èüÔ!ãû}j [ߠ󜕇±%ÖÆ ÝŸ×Ä3jˆ09ÌK£q¨Pè[ô= 5òf¦fÊÌ$­ š+[C•Ê"6xJÓí[5©®4¶’‡ÃhßÔ9Xõ¦Þcâ9‰§³pÂuY2Ä¢‡¢¸÷væQ¨™JZ:zeIå §q8¾9/Í)Wú{Ìœ–9(ùÓ° vŒ}Öhu\žª7廓æ= ê EkÕ±CÅŽVecNØ 2§gƈpwnvµõ°ž0Ñ Å ÿº¸ÄLj,òÓHŽþöo4±2ù»£ÓtÛÖøG§.)Ÿ%é±@"½œÖ*}ž²rçÌZ9VÏP×Ö©l¢˜”ë[R&’>g^èÓá"b¬ÔWî“òo\¹?ʦL>ìó®cìøŒó´QRþH+†x…Gìã…CÎßèGЦÛA)£ž•àÎ5£Ï™˘DXs¼Ñ‰ÞfÈ= §2ÕHdòù£ìI‹¥!ÌhÛö@ŽóTén¥,÷´q~Hݘã¯L¯I¤«Ï)§«  Î1o’£P 5ªÇÆ6»C]J5r®/]ÝZ’GÂbûÄv(¯wÝ6c¿O jÔJå‹ Qp”ó-ñí³‰Ï-U¶+óI^s¿á¥õ[¶ÓÜBYb jiˆjT’VÔmÝm "X™¹Áã§u§ßœf=¿LŒ_"lðÈ”O§h¤Ç ¤çÅ) ¢.á¤È\>‘ ]^0K‡°qà4‘0NÓàtXæ+ÀxŒ}‘ 샅 öA6ºûD ì‹ÿƒ} K:.ÿ ª½ÌËõá|<ÏûƉî,€Š,¤sXшôºw 2fÔ ’±žµ«'Òn‰oËÒ,ÚV¿E sz}qðƒMt|—©Ëóy2䣪m¾>è ž¬ÆIË€ƒÍ±ø½hÕÛÏLo³Ýª°û s'“Zuf0ß8-×¶*8ä[ùÄw¨gs‚ìk•§^…£SÑ;š?¨zÝ. @™g }Sub««|h›m¦Kpèz,`uW@rY}' ãÅçì“®³ÄëC´ªMÊA^Z,5 ׃op$‹ù$9ÜŸ<ÓΩ¤ØIs\/gÿZßé` endstream endobj 2215 0 obj << /Length 1052 /Filter /FlateDecode >> stream xÚµWKÛ6¾ûW¨ÊÅÖ2©§U$úØMš[»î) \idkW–\JZÛ(òßKФ^– {="åræ›of4H[kHû4ùu5YÜÙŽæ¾kºÚ*Ò0B†e»šç"ñLmj_§{ ÑÃó £)̰3=ξ¯¾,î,¯¥gù®áù>;µÒÀØâB$/bÒnKz®Äç¦Ç_ ¥ÛÙîÈ;šcÏÅiiK¦ìÚ•ÝKmŽ—†'z7›;MïãuJ±&âdiq–Ší>.6b•W²ßƒØÿÌ`Í12|ǧFRéý\<£2 øQJI¼ý·Rå¦y]õu-7pv@ þ·$ðã7lÙ©>&¬G½;)%•Ö½¤½R›XñcèÀõë[ íÍë»ØÂÍ› o‚«ÿ"ȲGB9‘AI)„úØëLVÿÜ3±áãe‡°·fG*£±!i˜ÍÅî©ÜîĪÈî>(¡.eÔšŸ8`º¼”„†Ø®6ÓV‰eœ7öA(1{ÚÍÅ aßxô‚Æj½#<Âéž' 4©qSGZ,>t`mt ¿±xŽD‚(dEÌ%(ÒÒÆf¦#_]‚èx|uY,UxþªN¨-{*óB¬¶@Ò¼¾ðØ35„€¹S«) äYù²!t-×YtÆvx/k¤eŸ³=0ÜômˆtxG³° @•ÛæEÒê¼ d’“sp„q¾Kȱv…(÷óœ¬a°nçÙ®!¢Jj®ØaÀOçërƼ¦¯º©Ò¼æªëyFs©6 —it<ã*'éãu¢ôGÔíºÙÔ”µ¼KJÅ 4‰¡©Ñ ii\4ü=G–«GÜË×TÚq±Yƒ¢,©oI¯™g¸ êk¤ù¦ðÖ “¥qP‹’cÏÊ2=JkD984KºåùñxÆûI5 ªHå¡Ê¬{€V»‘ÿõÚM ü[’fŒ» ,(·¤‰ëZ2ëö¥þ*6q>˜Ý zæUiGóâCPåßœkñQj¾éãã¸u/S¥Ü¾C—Ç´»âõßRµÃ¼¼xôð~cý˜Ü®&ÿL03i¸?L×7¶´`;ùúi!û“yaXþRÛW¢[ÍÆØðl‹­í~òçè PÍ8lVhÍ8 ׯšé`ÃÁ¸=ãÀ±7¶Ø^GÑ4ü%VCÎ'`q04•£‘…¦Ç…ìêüuDg¶3ͶbGÄcäY¬èÌò¦Àò¸zV„¿ÎŸXO<å6¯¦‚ 3€Õ‡!ÇpÕ—Ïï4ÞUÙ84‚õF¾jäò »ÃpðIqñ23i’q88C0ôgG~¯éŽéˆ{ÿæ}ÿò™qÜEÎ×C§¿Y¬¿µdªw¤N®b¡ûÆA. endstream endobj 2226 0 obj << /Length 942 /Filter /FlateDecode >> stream xÚÅVKoÛ8¾ûWéE*†¤DJÚ[vÛ,P ´qOmaÐíh+Q©('i}‡=œÚY·—…!“Î{¾!‰ƒ]€ƒ¿.—×I¨à”Ëm@0FIʃŒcÄ,ËàcHH}^¾¹¼NÙŒ5)2TŠ,Ówqg˜ØëÅ|Æì1Í Ñ ]uÁánßHÕëñ§ãå5Mæ~æALrÄs§çñ©éyLGEN?¯¢˜2>HñÅÍ:¹•Té–íú_¹é‘ ø0„"µŠbÊ3$£îFz¹«Z·'"€ʃÎ,ÝôýÅSé•q\û„†< §ˆòlP¨Ò3Ÿc—£<E•|ø%»)ÊØ(lS¶x½\|]k‘ŒhâIŽX‘›fññ3JØ|%EIÛ®m¿/U”âð¾êZeÎd_Çnâ²¹'y†'>ù|òÞžàRL*RG_Ý X”÷e ^ì<©ÝºÑ6œ% þ™EåG‡,7“&®onµ8¬«Ý¾ÝëÚ“tµS¢ž˜ÕÛXæÇ7e#lšJkˆb%ºÝY°ÉM§Û¢ógÞ˜J·\ËØk¿7¥Ý]˜wÔ°tE­«Ò-ßœœGïQ’¥('Ä_¤>·´AÅsO€ß:ùL i/2Þ¬žãqv8º—zöÿyòúQ4wµÔç'6…<ÝÏÀýÄézÅ c¸,ÝEiæ­òÛÀ–b=þcì ÝSœ® 4ÉOªn¨+Ý{íÛÑœ>j°il 3ÎLšï¥“Næ.<‘^Ù+ÆmÌßŶm/¼ØÅZt35'ŒüÔÈ|Lɾ endstream endobj 2353 0 obj << /Length 1941 /Filter /FlateDecode >> stream xÚå\[oÛ6~ϯpßR`fÅ›(ØC ¬E †{hC–iWˆ-¹’œ4ÿ~”%9–D‘º1È0ô!A ‘ß¹‡<ª³Ø-œÅç§ñóãÝÍ»OØ] ˜Çàân»€Ž0q.£À%òO›Å×Û/ÑFü|ûÏÝï—7ß}BxÁw‘›¿å,–Ô°|üÍ›üÙwŸ»zbàP(Ÿ[*ßàdˆ#b-&×CuàK”‰$ò÷y`u„Ãí£lÒ˜—,åêå€1·îOiÒ0 „]ñâ8t¨'º³íé t„,ÜaSÕŵxžWá-<µe˜{C¨"AîȘ)‰¶“H]dîI/lX@D* ÐR_§ÀxNCâ÷¿ª*¤”—’ÿV…l„AéÖP—«úë8É&…W¹7ÑGR±\MËç­5)KMpÚ€…;Ÿ›ÓP]é¹5rµ »ÅŽÖYY“s-#º=οMÝ:P·”2Õ‚¦‚û„=DZ‡„•ýC-·ûA^ßÊÆÀ¹]‡Ñ&Œv*ÊRø‰ºÓW&Ë­Ó þf³ZûÁ}–øÊ”‚eµ¢¥D”öOËÉÞvÏ+¯âh%’$NT9J’]k‰æIÑPo+וÍIƒøû0µž=<=×¼ÖøW²[ü,ø®¢Ýµ¤ß‡ëj·/—«oŸ®ÖñOUB/¸Ì\{רQmïU¸UÕ;I®%!-Iæ¦ zi=IˆÛ’6ØÇé)QÅ"E;d ¸ÛSäm’j½Z2WÜ™R$Lö~M©sö&]<½ŸÔ&T”ep»r@ÿ®|ó© cSÅS· ×ãÀu;ŒpLâ(>©ü…1€ BVÛ†%݆‹¯êý`à"Ô(ÑéJ¶#¡­l2ò¨¡_¦(×ëB ‹Ò¢ãŸª j=JM|²Ã{-öªH)˜Ã àáL¤Ü^£~"_ƒÓº}õsoDÀ¹9²Û&ò¢ƒOºƒòо#.×Sí®3XNù&·¬ g)…ž2ë=« Oâ2øI;ÿý8]ÑÃvÜá!ÎDõ@±^³R–LǺtªN=dßlÌÜ/Ã. ¤*B#’Gç‰Gí‚V’¢#I‘x› §YF»Iù£r<×܂ŽýM—Ó “Ǩ1±™Ë•’ÓãúAlãdÇFÖ70ÝZA*éFÅy˜?Ñ¡tÐ0œÞÖ~"–ÙÓQ,‰Ø„Ÿ ÕY—ªFCR8¨>4ÏÇ䯈>bkÇ£Wg°õÚÔüÙÐe~’¼…Hf+^©2-=õ­Õ<Ý §f"]6}ϱ‘Š÷ïû\¢–oÛ½D­Â· ÑOAàïuó³cÈ'ß98½«a  aÎÐÜ Ù¹b7'ké }:¬cû~ô‘A Б‚ToM5¤á.2 Íß›·‡% Wá[Ç›'ëÌ•’ÞÃ$ut†0Ÿ!Ì»ÑmÄÞ›&Wî1µ|Sƒr@=¥‘óqëjä¶î€ŸÏpé«8&®j’w­âmœü}j=å»tdMúb:‡yozY‡nÅ>Ös$Ç#sd}I˜¥¦#èÉ-Ì9[q¯®Yë‰ ™>]–­€ d rœ;‘è(AaS£„d-ÿ^|8ëñc1™ K벋¥[.ÝÉ´‰l|~²³N±ØH¦^ 4TñyLŽìâ 6¶Dšú;SC0ÙLÄþï}Z¯‡P²$m8Í¢æ,G?Ñ— ÞÔºòë»’:¼§8³σ#á¥Y|´5Öüz¼ûjä¼)~r 2ýÀ¤DŒzr¬ZüÕ!žŽÇDf¡?ŠL¤ã2Åøš{&´YÖŠâ©ú·ŸDùlà+†šŸŒÆ[[ÌõÙ/á ™Žõ¬ÇÂLÿ¯Úv¥|HÅtù?™$Ú¾ò¢§^wCýBÿá-{…½‡'/JSNNö?§¯®¸a®é¼^sg±±ö•‹A׳œ@¦º>‘<6ÜHO™òþõü2rù ‚,N–AeR=zYïMgúnBÇÙ=à2v¾"”}V±n «7³ÌÚcøƒTN﹘Êäy›¦’¹vÛ6º#G½¿\¹ÆƒæøhÆpÀÛ¹·aîÝ~Á„Fܬ#lBÑá_Û f ×KFŽÛç‹–¶³¬üDùËàœ«/û[ÿ½É[àÎCwé,SÔ …ÛÿêWG4‚[o ¶éˆ‘çO²ÈU¹¨üow7ÿlÊ endstream endobj 2155 0 obj << /Type /ObjStm /N 100 /First 967 /Length 2218 /Filter /FlateDecode >> stream xÚíYA[7¾Ï¯Ðq{‘%R¢$ (ЦH»@ “v;ÈÁñ¼$F&öÂãi’¿es2“±3/;¹ôdú=¾OE~¤$Š)¸à(¦èRÒ_rµê/»È¤Br±ˆ ÙuUü“®[‡®\ç®Ü79¡˜àôInÄûÌúUf—«âpqB\éceqµ•‹‹!•ª‹ú\0|ä€- SÐG-*¬M¬ú0 æ°Jx›©©$J ¸Bý àŠô/&õ‹ å†!Jt±ý¢`°šõ‹‚1jë6á‹–ô (dŒÂw àîŸåÜTªº¬¿…A¥¨‹Ô-*rð#\'ð,c4' U´àPê.ÁcfR/Uh±(lŤ¨CÁÅp‰N¶â‹²@Ôt ɱªáYmŠ×èݤ–\ê3‰ NåØß ÖOú³â’ôIÀ¨Tz´¦‹ZN€Ü\ºv‚Ë}î"V:ögXó„µDJXŒÏ‚¹&x< Œ‘³Ë%u;ñ²`RðAeÖ*$õEŒÐ¨G!¾m:Dœ“ï BPú$° +ªº€RÑÙÁFìâAµRŸ¥H!êçˆ3Hì$ÃL" #ûX—RÒÔ;xèJ}‹)jF' ÔæJjýeq%3ÖZÍ)ëÑàÍ"ø—BJ úEK¡¡0ÞÖîBø¶Ônc€¶1.AÒ¨Ó¤C˜–“GN&¿¸3L "›OÝä?ÿýK3Èw‹ùæWÏO~üñÝïª[“ˆÜ‘ÚT|ÝÓFŠûŠ„§M9û § ÷õ“I>Y.ÖîÑ#7y2ÎHŒþÕÐpBlþ +RÛ?`É×jÊ0›‘€7ùsµœ=ÖîÌMþü剛<Þ¯ÝõPÏ>üoÀ‹é«ádòËõ¥RwÔïO&§Ãåòj5.7äÜŸý1œÏ§?/ß»3>·ì•GkÒy<ÇxÓ@T?môZ,–=Û”!5«—¡­°1ô{ú''“§W/ÖýÿïóÅ›“ÉÏËÕù°ê£†ç“ß&ÿž<>‹ý:Ã9F:ƒåmœ†¯^šRGð(Ðû©ûõ©›üº|¶tX–¾\øÙꪃ˜@­zð XÔ3ièÜ‹B…{ øß.Wþô|zùÚÏ–Ãj6_.g ¦¯½=ˆ° ¤Êì¦Êúdº×¬ó‹­MçX›öôx–ð1ž[ëá B÷©î þ›Êü…’GI=жÔê+ÿ£}K»4¯µ|œ6ºÊ;R=×&fœ6gÄK'„¨j =,y‹oQæqY²¦»,‰^ä¡,‰ŽwCŽÅè²]–jBÛ 5˜ʤELÛ)F F甈¼ N¥Ä¾î'Œé‹åj}@Þ¢ìE×¢h±õðF/í[Ì{ÍX¯¦³ÁŸ^]øÓÙ›ÚÁêº?j^·q9y×§Øà£oåtË^7Aè2t{HTŽÈ&2í/qÓ‹‹ùâÕáìHÈÉ‚ÖÙ É1x„ù½†:DPÊ¢n<ĺ9I¾a@‰`}&D><ž®g¯¸0@i-Ñ_Äê}† ïçëO¦ó hz|q½©|Mß„Lí(Ú ‹Üx¬6£Š!ÕFGŒã8eª­/ÿHmd*Uy`·u»ZŽTT(ä;EE÷Á-*¶u¢± É«7ÍêM³zÓ¬Þ´m½Ñs‰­Lˆ&Ð!+PÒ€DåÉÁƒ ¥"^Ϲ26cR÷sÿlý~Ý©ÿr}Pîg¤·ÖßœÒZ;{ô$züþ+û;ûÙâ|cÍüÕbzq@sÐÊSþhNŠ›}Çç­90ùrÀš`‘`!{XûK„AÒšÐCr·ïæë×Ý+««´º½µxh؈—P®MJ¨Œíæ}&­†õÕjÑz¹Z¾=`Y,”ßVÚÐv‚¡$¢îÁ¾]½F {-Ï$Û*%}ÎùŠ-àשÁŽ~ü¶±'Gö¡æ{í™^nÖèj1[vÜ’gÖ£Üt}ŒÓô=(}{´Ä’|´çÚAŸ·ç}^ò©m+=¹Ï)ö†eû½úíÃØ‚$1Ê>ÈG7ÁÇõVŧ\î'×ÓÅùŰºsž¡§ù£[®[Ê×ûk%ãÌÇÑׯ]-×Nm=ÙAk> stream xÚ½[M«%·Ý¿_¡e²ÑS}IU0œ’@V±wCN2c˜1f²È¿Ï)Ýî~³™îYè6˜yº_ÒéÒÑ©S’Ì,ZZa+$’^¸÷lŒ"ÙðbÂÙˆÒ»¢¡­ŒÙ ’?W.Ôz~I¥EAKÑ%gŠÎõñi/d1û…Ï–r³lE¡ðÜÐ)Qaôø-t ž/ @c:èš¿ÍƘßCAó{x„¦ùTæEhÌïEiÙsoETòŠØÈçH-‘v)âb,Ñç/¬h›1A„”gPðJÏž»ÕðlEÑ>?E§:z"TÔç“.Ö8ûRŒzÃC‹qÌïY1åŒÁèÅÌr´1Šõ˜ýa.|F jaÙ‹·Ò›ç¸NgÎ'w.]28ìRºz·+¦²?·ÒG†“ìî>¿7Êh3âèjÐŒ¸GÙs`Æ•ò)ƒÊ°ù)î‰À‡SŽ¡‰%¬x›³½8ÓüÞ(.s¶&ב£!œÞ ±—ÖŠœ-iTÜñøhq‰Ö"[R‚±ÂŒ–È ¢e%ÿ ÕKË9µÑ1hy GWhE‰ÑY0µ–“)`5n92%{%é/ÀIM;æ]ümˆq¾ 7„"›`póœ ͈Àa"ž=€Ä4I(ŒÑHrj³Bdœ£1F£>Ù̹X†çh˜T¬š?ÃhÜtþ £1ùüF›PÑÄhX^ù@X_lÆ ‘@¸ü™`4Ìw" Ïïâ /ïÞ½¼þø¿_?”×ï?~üôùåõ‡ÿþóó|ý·Ÿ?þòòú‡O¿ýûÃoýãõ/¯}ýã{š/^^ÿþá_ŸË{ê^,Ýꉱ:f¢‹T<+¾÷}y÷®¼þP^ÿüéÇOåõOåw¿þôŸÕý÷å»ï^ðßCªãQAŸ Ö¥ŠL0 â&µ*æ½:fŽ›UpÆbT°òë —OѹNék­TÈ!æë(ÆX9¹6£J™‚*Ö@a:ÆÉlÈB x`Œ)à'DŸ0@… XUÄ¿¢¯¤DWL/4›A d ½fr„@UÑ~Ž:S7YÅjÅÊï•¡ÆV‘¾"Öaà–ô£LwDª}C‚Jt¾kq„ƒE•i™[[Ò’îÁL£ÄDÒLÁdpž *Ý¥U'Ôzí™Z6NhQéd>t!de¤/,†ô…5™šB>¿ŽÀ"€<ÙŽò„Ì{‰€Ÿ ;„M ® H[¯Ö;„M¬¯ Œ•T©\¹A`¤ñë(P£…) >¯ˆ¼1®1ÐJ 0MŽÊhÇ`°3þ q ~„!+2P’sn Ýì÷¤‹Ñ°›WÉ2ÐÓC¥fÒMŒØ 5_Eµ‡zú;¯ "y&Ôc½D‰+²Œ?›fA®µÇÉl¬Ä Šä€jyÀâgQ£ˆC$&¼nã ŽÔ2QzCÀÊ€™KQ£Ãdë-P~Aœ­`UTåYbbe1‡Å>[ž¼>_v–È»­…›„džpr¥@hM FÚ›>XgÆZd}™³ƒØËœKº’:À=¬b€@­™ÎÈ ö:s÷O˜ <ÿè_L],‹•Y‹ M-÷L°Fé*×fä^Gä›±Õ{ 5\…‘©£ݵ:AK܉¬¹H¹;3Piœy{±'LÇb_— ÖÚXÊCƒm8Òç¶„Ÿ¤ ZJ @ÈMFmÕrÅ MS¯yÁž@ˆÂNˆ+áO Äb_Ÿ— b½™b†…Ë­ÓÍL1ÞoíD$H×»)¦^-·F·ŠùJ$d} ?@l5ß5]ïò[Õw b¬/ûvÛŽé%†•‹ƒQbDžýìußãtæDÎ6B˜[U’›â™·†YA/¯A, „dÐó˜3kïÇÅ¥š÷BòJ€žmS­Ü”ùÄÅfÍéy¡¬J÷y%@ljÇ5}ˆ¬9…Þ@ ­ÙÙ©çÒõ‰\™÷à, p#Ïz7LíæÉÈ#‡ xoÞ°1n9â9X¹a8Xy…A×'î—Æô:¯HÈ›\“Ô~‡¾’ö-ÛPâ‡M¬óbD×3™z! è·„È{ƒNd*d½•Q8{Ô‡•Ñ1êh'2ÕieÖ€BÌc_«y#UÓñçew§gGòm} W•G¶®&uŒ3b®t–ÆH…@^ãÃßÜ£à<§êÍïËM#’ Òßp¸Ò-çŽÇT$9CÞ¦ïû8ñ¶¬ëÓÖb¦­kOPJ ¸'þB!rÛð솥.gÃaË—8ž‡³7‡/¹*'"5|¥\Š=0p&4€ÀK§ƒï©ù ÿ–WT6 Õp;‘(§õ^ õ]5{óRy+ žD¯O;†}a\bXÊÊme¼S #ï%´Ó»•+!àùÉ£Ã;±Ì{SÓÏHîmë-w  ïdý ’:]~¶õ|`Ô7ÝãÔêÙ•|¦åt8 l9ë Â⩇Pæ€Á|Ä!/&ðÙ™ãú„q@ØÖÅ%„•KSà^ç•i)ÒQ5U¼ÃXÞUdÀRkž:wHüø|ÍÿÉg "ÝïÙ;åjy+$%eæÐjÛ½X¬›*ËÓ-çñ¤y§-/jÄ<‡T}K$þæC£þ endstream endobj 2492 0 obj << /Length 2030 /Filter /FlateDecode >> stream xÚå\[oÛ6~ϯðc ̪x'_‡µÅlCtƒ![J¬U‘=IÉâýúQ7Ç’(Ò”ÄlEP ‰ç;÷ ê¯îWþêóÍ÷·7>!¶ž ®nïVÀ÷=„éŠQß#®nÃÕ—wÐ÷Üþôá&"î{ŒyPõпüðñ·ò±¿9ýÃ'ˆ.ž_·/¬!+Y¿¶ ’ds—Öçw  ìqÖžþ]s²üãñUV¨üõóÍêËÿDzêÕqkñå_ À€åKR W€Âé¼è ~~R-2,<p]@‹Óüí ."<ƨp°BsÞÂÃ!ŒïN*Øc‚,ˆ >o FGT¾)5:MG }=>*%„„Â~Òà!še9­| FRŸ7”OI_#ëõ¤“ŽÁ·FÍ'Í›ÀÑql桳í–Ðëg:G"³N{rÆãrBy[Nœ{ªbI^idaœ«L‚I)ùV&Á´0šó†R¿€¡± .N—ÈßeM:’<ÁìIg¹©ÏRF/ì?H_0R.õ9à5S¡cFÄ&^<É–é­w‡4/²Ç]RŹMa²lÝ€¾ò@F @z–ŸòÇ,r¼Eðn5‘†Î}ùöΘ†›í!<©|zC_({ˆò<¸WuÝ®i©®‚R ’T?6<ëböÕ 662ûö<-CS‘;¥™9µ Ocg•Ž@ÅÒ!JïBºªeØù<€®3ޏ€ww8‘*Žé!>¶êºÍ²tÖ0y‚ðÐCöQ¾®YŸkç-±èXÙˆgŽù¤Ø”Ç÷i,Ò3 ûzö À}Ïì»ï™ U„²Û(NÇÈyê2hGi‡4ŒËÊðçÚJ]Éàu­GUŒÒž•õku7yØþ)ËÚ|ÖTQ'C¡wr.r4a]`Ga±l/U›—ç(z6jê"<&o«£hù.ž‹r¼ûê>9籇ç$(ûÏ#(ð…Gú÷KY&ëÍ‘þß¾Àî’ñ £¥K0¡´yáÚy•M„}•ÝÀ3Í‚™òÁë†|°ÄGêWÂmò&Ç(at§ñ L…¥Ö…†Dõ˜G¡«áÖÃðªŠr „6†Ns^t‘o’8/æL3ÏZ'Uó)ºp cúkNÆ=NûÙrëüvëÛùð”®K€³î`[KöFxJƒ‡xçÊ- ±#B‹ß{/Ob0Cw@‚:'AÜ낹ׅpO¢_!öÿíùUr0_QP¦6Ñu«ªqï*ÙE¹û™ƒY«³Iü u¿o®û¹èÖpÑñ8ÕZ”UpœÒYr޵Öð[4½‹2CÑ(Ý_S¨=¶YSÞÇ.˜›ó:yðLßT#àùÑŹ02î­€^3¥ÑóQ5¸GÐCŒÛ”ƒi­ëj{NskÓ¦plÞ¤*~ç,E²eùåËñ+ÇýÞêZ”þõxPÕè’[Á–e¿²z%»ýÍÆŠ]+wï1ºªÞVàÊ߀›Í.?=¼%³“ìþŸÔËV/ëó{±(0ÑÁ®[hÎëQWU Ý-ªùRÍy=³~2íåÌ¿L¤ÎKbä~ ‘ûk b»¥+Õ·ÙÆÊ]Â:f[±O5qÓmìüJß}§Œ_£Çæ Ñýn‚]?©(c6á¸k2xÔd–Z‰Ò›€È£bk®“àÕj•öEÝ€«Mý—=,î~C˜·•Ž>ú_ûØàÞÓç+Ø=œ0Éiyvžêˆo?gè…Ž™.¦¹DÀ¹K¶§;“ KñÑsñÖìµäÙ½½ríäÇÛ›ªt.Ò endstream endobj 2357 0 obj << /Type /ObjStm /N 100 /First 1019 /Length 2821 /Filter /FlateDecode >> stream xÚ½[M«¹Ý¿_¡e²ÑUIUª˜™1N ˜/’/Ï# üÀäßç”nW?fᾆè5¬ûºïÑéRU锺nmSIµ5IÔšzª]| © ó%iÕ#õy‰KÒ¡> 4êðAMT:ù¨%¢Qï0b@Vö¿œ¥û¨'sTÖDZç7,‘ɼo$ÖSP"²ÄÓQw^‚[kÁ\<üK¤˜·µ^ü›b©©So2R³îœzI\Š1¦æÌ{æõjKÌ׫œX®W%qïþ`½'¶R0>ò˜ßa‡2ŸBÃgÓâ¶ño(%áî¦ÔšD†³Ò–D뼓˜ø¼*IÆp<ŃRí˜C5õ*ÅRo6¥ú}VÜì>¯Qê:­g5õ1­g-i™Ö3NJæ(&IÍûzR¸ bó>Kªä¬0‘û}ÃWÔÖ5"¿$­²Û~´dN#N&äO9$YçùžLµaø„2ï³4Jóç# ‚!*Ö"æW¹Àmدú é0jiàA|Äi`:Iø£à7… &áÇ)õzžS|]0„ë)ŽzðEø5†„¡úŠ2¹‡Žâ`ä.ZÜÛJDÝIœ”ê˜÷b6â†ågÂl$}Þ‹Ù¨y/f#sÏçZÜßÝõëApQ,ÕêŽÁ³M·Ä³]ý×kïÑÄPŽÀøU³y/fkÅ€15r')_dn˜­9 1[ñ{ñT‹Ì{=þÌÝ€gt!F ÇwÏžÝ]^ý÷×ûtùöýû‡Ow—?ÿëÓüüןßÿçîòÝÇŸî?¼.HåÍåÏ—¿\¾MóÃÝå‡ûwŸÒkÄFfwǪÙàiðÙÌÓa,ãîû6={–.?¦ËŸ^=¤Ëóô‡_ßþû>›þ1}óÍþýÿ$W2Œƒ4!yÀuX[®3YôÌ_¦XÇé/ ¢‡FËŠåmÂYÜC çªôe’Íân$”3#ßÝ$±Ø`pAtdÏàpü,9£æV¤×•¦Àzøö£%Ã5á3#‘•ŒmíËêJCtpð\%c_êŽ#+í PÄÂÎÁ žJoqh 9øÂ#'¤÷ìéèY˜"Šf/;¹b'»Éaešª5WìÚ;‡†¨„²ºÅae†à¦p¯þÈG&»í’KCS+Â`¸Ì»TKžû"Ò84ÀIqätÝ4[ØW!k² $biýË$¤¯ß¸¨RHŒUðý¿Mc¨¢ìv ’ Ô œRAîª_k‡çé5Nòéò÷ü¢-»Ò‡(„>Ðôþó/¿¼ùâÍTʼ»7A–n¿¿ûÅÃûO“ è†T_{MÅR¶¨$:Š‹ëìºpëíÔ±Âó//?<¼ûñÏ./Ÿ¿H—W÷¿}Jo~oÊ—x¾»Ë÷˜÷þý§^nL®n±Ÿ?¼»Ÿ+׿ýíþ§Ÿß~÷ð[šF–!0Ô0S6_Á—o?Ä9Èõþ¹N1ÿ¬]œÖ,]¶ÁØ=.uŠAA‹Ç@bÐc 1äÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈ#G @<yòäÈ#džìÉ6 Ô´p $=‹A S S S S S S S S S S ×@®\¹r äÈ5k ×@®Ü¹r äÈ-[ ·@nܹ2222222222r‘‹œmÈÈÈÈÈȃ1ȃ1ȃ1ȃ1ȃ1ȃ1ȃ1ȃ1ȃ1ȃ1ȃ1ȃ1ȃ1ȃ1È[ ¾Y³£ Ì„Œ¦¤ ÒÛ+P!Hp?…@–ïçHNr]ƒURrƒZ¤ƒ"H«ÝÐ ·wBÑAHZ t\ÿjÏ>¤äBçȼª/BðwÔ„®HJ¹À;"œmœD¢L:R‡ê*~"c°RSGe í°0åõNÑÕå†îNÑQJ㓜"ÖC,lQ±ÚOô¤ŠÌ¯sH$x(a[‚ˆ‚Ô?Éý~×Qyn#H§aΉs?$¡k á¡Ù½6Û á¡Àµ'Øk° .fDÍσKV¶sÎ*"Wɰìçé»[Ëv/W®…€ö~Arè3|¤ôEWÚÉÀ3Kϵ±¿,˜Œj…õIÛøVó` ‡Î…[3HIÒ³6/TpÇfÔαy5È^'9ÄÎ’ÒÅUp€=úÑ óR§Ü„¿‹Äxv ‹ÔYÎqË(ýüiõ÷‚›Æö×¶ÝìÜðlM²¿*žÑÙX²iìñK½£Žú¸­e="±2S†žÚIlzê&‰µb&Ö‚ŸÛ¾•²Q?i5¶¸ú 5À.­‘µÊÈv¤óeýI@5¤gï Ù£Í£ìcepB7[¤oÄÚ Q¡«ì"ëõTí-_›Ü®zªBì Ó³Õ¡BJ¼!o‹ÐŠZ°ÔqŽ)"BwÉÒ[Çn’xŠèØHlÇC79t]+ê†wÊ”[¦_aˆ¥©*6q÷HÑ}¯¨Ì‹Ö³Ng®ŠÊ›Í¼¹/•7›ÉI.~ MÙaˆÝ/Q™Ó°s,yb6zMIµå oô:,y–æ‰mûòF¯"qàm^HšÁÑ××~³Í«<žÍ>¯z°¶Ò%¼gB¼Ï ~8[ž¯g³©æ¨æYªh ð½!Ù»jLmn¢$×Óäv¤hô ^6Í®šöørcvÕIšFëÏÓ¯]5¶Ÿ§Ï¶š#IÓžàè2újvǼÕWSŸ"@ƒÄ5@oRx‚7;…-gß$±ò˜*æNb˜·I¬LUû¸o‰ŠÿýW·;­ÊÚÃlÿÑÀNb7I¬ÌµZ6/ƒ—l_aˆ±’·lþãàÐýeÛWô½-UUÍ+jI+ª-NÍ‹°n×N‰J縗šv¯#ÖÛVz„Ì5oÙ8øajtŒqXéŒí¡Â‚ÃÖ{“ÃRIµucBÓe3Ù»1•üçrN¶äê‡÷üH·2ï¹Ib¡¦òstT>$|+› =7H¬<ˆNåîûEµ½SY‹7ðØI?êØ:•;ÞнQ¹ã–C¿\ÙÁøô«]9p.losà•né]SpËM9†ÿ0Ð2Óµ§è°{ÇV& hJoKìØ. b£eïõ–"9z7¿”ª½Î6ßL3ªAGï-EÆ9$âÇ-Åñão¼¥¨×zN€î>Q=;ŒGŸhŒº˜O^än/ûö娛¤~ ‰ÿR…K» endstream endobj 2598 0 obj << /Length 2000 /Filter /FlateDecode >> stream xÚí\Koã6¾ï¯ðq¨¹")¾€žŠîí¡‡"‡ÛÂm%*K†$§ñ¿/eɶ(Q”hQ»I³‚<œÇ7ÎŒí-Þâ—w?ݽûøÙ' Etqw¿€ž°OŒz€`´¸Û.¾¼ÿõ÷Ÿ?ýùáï»ß>~Ƭñ00!$©Óc²ò¡w^Mýãg„O/Ï/+ÿY½)|ÞgažGi¢9À€CÿLÿ‡šºü|‘•‡T/ÿ(Ïò•7Áá…/ÚbK9£|…§!ÈüGp£r¹(Ç‹%DÀóD[·yÄ“¿P£c"côFîÐù}Ô7rG}À¯¹ãWîòŠ!…®DüL¸ä¼zH¡ˆ†ìüL’‡ËmxÈC ¹†pƒœN %9>F‹/KD¼÷Ü,.Ç€K'ê#7Øû€³© ÁóãC£èDZZ¥WÁ¡HWI° 5Â3ù.d¡ÿ ½LTä–NaEô~&ONÐv¿Êµ¸•jòØ 1AÍ!•p °Pv’ôÇ¥†C,e¥#Då£D¥Ž}j@T*Eõ ¬ûU¬ÃبEø\èd•ñƒs×f5s&ãG;˜×²"ˆ/#FS#¹FÖê”Ü6ÃcþF|KJúV|ë«UIÀL¸ó-æZV>^Vѱî‡Ýt=×ôºg¿H]q€ûcìt×ôT=ÉæøaI<ïý:J¶Qò ³8•Õ0Sk$ßSž(ªIVët{œRžUc>»"§j¦:[‹A_ba«Þ”Äï•ÄU (Ä9àˆuT})'¢Ø£0é­Î|W}d©êž¢vlÍâPZ&UMIGÕ÷»8wjrªË³g¯—ºrM>‚’¹Ž¸D,:PʰèA­qÝ…+Tæd|ØPñtªŠtlRÏ­ÒµQd*¾®ÌÐ〤µq%´Á•FßßMìx’ƒ:£h‘ȤY |µH„PZ½Ôùq§E"ˆ²×+²‡cí`“fY²ÍÕ7ãCkÀIz5G§Š2݇YP¤™.ÕÕÙ©:Pêwt¶ ¾BÈJÇ@4X+Va–¥Ùj}ˆã°Ð©NH©´¨‘•š^GK‡8˜ Y”Þ‚¬G'dÝ’M¥É|È‚‚V³›ú=E´ua'Fv\9{vXw.qî »Žðî ;A­“êIÁÏûÌÉ%ï'Vcßmržýð,° RN&‘bþIäüuƒC5xœ®ƒ¸Š7Ò³¢,Mva¢kÔÔ±Àõ´´¥eXó‰pƒ¼ov¤ÂhD¨7>$óóñOa_?Ôþ®U²l§ø„ÍÍ™Gvî UßÑnŸf2'·11-K{fp *”¨ðZ#ä()så”õ…í`-å2y°1È€‹b P+&W’šÆÇ£½ÀxSÒ8i°ÙŸêlÜ2Üc˜EE¾ âØÉ æJ0ѵÕ%GV¤ˆEPÆÛv¼ n°¦›64£ÛТO7SQMO4‰Nú,®°Ábc@‰h+_€ >&6ò>…y]n䥡ȧۃ†neW_гhg\,^È‹àa_8I®ß0·ÿ¶Ø„2ú>\PX“¢%¼iE«Ú©qÛ ¾xåí)ýçÒã¨/¤Y˜A6_q8t=W‡'>ᥠ Štmœ ¨8îÃå> ·Ñ&(´½^¥ÝéJУÓÉÅ@g¹gäÖàÉWë û Ãd’GV{%½å°uNõ¨»d/ƒµÔ|ÙÀ‚@2J;D[ëcÑ;?ÀV%«:œöp}1$?d­ø›Ç 62æõ_~*EÓW ˆÒmáS #šVÛô°ŽÃïžqÖG§õ òÎDÌòšm&©VÙŽw³àm ^–@Ú€`/ø· ÒÍ¥x¨ºn÷„Z#Qþ¨ã]>Oˆ%ŒOÛù®Kc:PÎPé>ÓŠGyá¤+ð’å€ ®—?}¼Æÿ‡¸!5@U%Éa'Ñ»yÓ*ÑjÄPù»2oìà¹Íaü«k·H{qòò‹›‘^ÜÅò"»l,¼Íò®åÃU_ê{½[ê#M|j%—i"ÈFhz.œ[ͽH¤{ðntHŸÌlôt  _¾ï: 4ϰD7™÷\õOSthcgw-)æ´%%3šè´}6—¡î_jSA¢ÁÕ*:¡fcž¬LÚ ½¹š•'ÜÑ‹¡õa_Û¾PH\ŠUô8Í™®×A¤/x¾íݶ^ŠÒÑSÚ®î2l`ªÃ0'-S2dGýµ‹—O£¯½8ÀÜ-T-éNõ³M“°'ÆÛ%1]—/‘k3 ²ŸênœÞ6Þ·œ<0ç“‡Ž™Ãݾ8:ÙÇÁ7TPæ=¥ñóó3£·¦š<˜¾»Bmª8`¡¢×ËÂÜÛù>š}wmÊäïš ‚Xÿ½ÖE–$Vd‡pÊç1¬¶²ð-Ѧ]YmëNoÙê‹5õÞ8i—V_%¡aÀ´=3ÚõŒ#O4:%”ä…,@Ï)zâöŒ¸aèÚßM·/µ^è$\™%ÀÞ÷Äp,nǧmYãGOa_V² Þ ŒƒÝz¸Ù¥qSj[#hô§Ôš2ë'cû)/𭩦нc‚×êéí¿ŸîÞý±¢ endstream endobj 2494 0 obj << /Type /ObjStm /N 100 /First 1020 /Length 2736 /Filter /FlateDecode >> stream xÚ½[M‹É½Ï¯È£}ÉΈÈÈ »+dl»:Ø:ÈÚÁ,^4‹4‚õ¿÷{ÕÝøàj« –UÎLõËW‘ññ"3[«õT’VIL9˜I›cPK²98ä&hj­r`©ÏÎAMÓøñêIJ3ŽZ™í£NÈൽÎ$> ï%I_þê’d4NàšdNÎà€åŽÕ'Gø˜M¢xKêê˜Ã;Ù.(ø_Ÿ žJ”†W(|¤Þd4Ì”( k hÅK™¢àÍ­+QZK6Ü0Gë4DãïFª"Ës3Uu>×K‚ñ8[—„wál]09[·TûXž«©NYžó䥥·ä2sôN/ÉiDŒfrïD%yr”JÎC“ÏN”a©‰p@£a9òԬě—‰9¦qùˆ2 FLÚ™~ìCäÕ]ìƒÂç*–l¨Ëli˜/(= N„ÑHXÀÁ9ð‰Î7÷RÒ ‰‘¤YÄ8ÒpñŠ¥©dK¤YÉÞ‹§éuùDK³ÁLõ4A£‘à°^¾V`O,œ¨h᛼¨˜-C¸QáÂ`hôËÂÉa])Ý8»Ð[G#M¡»–ÂY±t"bœk,¢ oäxi‘Šw€Ça6q#\D¤µÅ1›ôI05ú>ÃÈᢅGÅPJ®˜MÍ0̶x#†˜ KvÅlº„…#®D—¸`ô‰.á["ƒD_¯i˜Íl’øãÎ`6[¢Ã±Ø<¾DúT}xñâáôæß¿>¦Ó·?>=?œ~üòçåç?ÿüñ_§ïž>ýôøémA~(ïN<ýéôý[Y~x8ýðøá9½­Ò2ƒ§•’Zuä ƒ5)¹O<ömzñ"~L§?<½yJ§—éw¿¾ÿçcõ÷é›oðßÿÏÁšfº â778ŽõšiVŸì“0Ý‘D Æfo™o^3mî£eDË Û‘„ƒ2²·š™¹ ÿ2 }lh{.GÏÌ }fÖ‹Û$æŽ$†æŠH¹˜øyì&‰ºçrÌž™‚ƒD-33ôo’p¿ÃrÀ7:²Äe95Sec9ö$ÑAÅÒkɬV6@¡ê^òluƒÄžyb*–Á/$jÁ²ømuGµÀ% °.´fí_AhG.`@¶fÙ„ÊŠRï6s)ퟀªDtÀ'PBœ¥Ã >¡=—:rLä Ȉ£PÆjG9ÛÚó.¡ÈªW—0‡ô¶ƒ¦¢#GóoBMÇ)hpQ˽ûQ±±ºeš\ÝR$Ç"VÂ6·~UUŠ2ÚVξƒ¾TZDíJUm–-—èû7ÃÚ<Ÿw5ÏËÆ#Ϻ‘´çþÍWpX›¯›êž;ÈÞ–-²<Š. Š}PuyŽ­ºqy©ÈšÎY+¨¢?/¦[àžZ¢ éâž§Â:SF^¶ÒÑ—¢Õ‚|:½~ù*Þ<þöœÞý·=^ƒãÃé{Ìôøñù3Ï$?Ï×þüôåÓ‡Çåwíü»¿<þôóûïž~K‹¥-Ÿö–ªéRÁ_¿ÿ¤æ~~~1ögÌ¿p’Ör¾¹æ:˜ƒƒxxÆÃs}˜›ë@b 1°Ôx Z z F YYYYYYYYYYYYYYYYYYYYÙÙÙÙÙÙÙÙÙÙ¹r äÈ5k ×@®\¹r ddddddddddäÈ-[ ·@nܹr äÈ-{ ÷@îܹräÈ={ ÷@<yòäÈ#G GXy„•GXù äÈ3g Ï3ò»}r¤xÍ(W©CØbRiPq©CÕÚÖY—ìØeP5X @ÉxéMsǶSÐfD_p@–œ¼Ôq“ÃØÓX äºu?x¡·\ ê’nc÷¸îiˆÁÓ‹Ô¡î—[$ý òS‡º·jÇô9b2^Rƒ¼¼„â’!¡@ ò~ú1']çȸEaìØæZÝ‚ŒÛJ¦ð¸” îG;FÓ Ï:©Q¸‰§„~@•kÚÚ¶(ô=í ˆÎ†þwòòÐð G'Êí~‰‘~Ь"EÀ‘»@ê×­c•=»=áŽ1Ê"šp˜ðIoñx¥Óì…?OvÚÕ!xâ³ÙgÝÁ!xciPЇC”É]ÃIðÆ´AðÉþ«ä(X %o‰Êƒ ’rvž[¢iíŸÎ£žyT|".yßÒY,HÉBxS1b[›•».G‡ŽàÅTøeã]ô¼@ƒ†ñ ]ü¨hEòàVÄZ;Ñ7dë[=ïž$P3Z½W¼š 5!Âû3Î]€ƒH„CðVˆŽ«C¼Òë1·Éd`r¤ÉŠj1ä¬,…»Špá «OðVˆÈÕ'ÐÎg³~‰µvA5,Ê2jWípL݈OÕý5ö…αo’h¾¿¬»XeÝmcÿ­¹WÒ×­g±Ç¸„"Ëà­%ÍWï•÷æù@\"qY +0„]Wƒ§ô[g {ú¥*,Áû22rç·1 –`IJ¼oµ».GAïW ¥„`9JæwA*Òív㹊{µ‘« 7.7ŠèØSK 1á¸.g\ì‚'/* h´tM?¦u8f½äKC3¨í˜$¡(I‚¿2*¾ô>†îO}+@Û<¢v,ÊÕ# ÝŸnmI´vXó¬h¦óÛPP¾¾u­w°¯…øu_ÄÐÚÖ…¶=/í„[.×Bø%¶ðKá^Y;Hå®uüBb­ã7Iìj‰µr\H¬•ã&‰Ùö¯ã¼ 3ø%=žuñÞÈä®á†¶“R÷ß,ãõ þófŠJè<Èë6ò…ÂÚ|Ý$±¯!°s¹¶Ã]ÃyBÑÚA[ÙKÁoB¿¨Ûrö,ç/ùåjók.!ÿP'7û endstream endobj 2707 0 obj << /Length 2008 /Filter /FlateDecode >> stream xÚí\KoÛ6¿çSøØ3+¾Dò:¬-¶Ã0 9 胶Gˆl9’Ü4ýô£lÙÖƒ¢H‹n3$è¡A¡üõû¿Ÿj0YM‚ɧ›_noÞÄl"€Q8¹½›À ˜„€b4¹]N>¿ƒÿôïíïï?Z{ó0*¡ýC¿ýñ뇿ËÇn‚ŠúûמŸaŠXù‡_‹óÙ:Îóx³ª^QGCÀ9¾áŸ€‡‡t1ÀŸ©hÍd¦¥GuzððPC z?W©?€O²’±Ã}º™|ž"¼cÜÈ5„0LÊ€ üÄõF®£¥îõp ]ÞÍR?ÐÓ½>ßÊE¤@`,t€Œ*zì a—$%apè¢óâyM·Y´Œ²ˆr I¦ôŽ,ÔÎx†Ð; ÒŽà·Y¼Ž‹øK¤Á"€BfÁûéEðn·Yqºé³wê™ñ™ùF„¢«íß³H®¢LƒV )ýŸsO1 œôk}–ÈoϰœȰ‹Ù[0ï;Ô 1O8Üaþq—æ»,òàûiax(<«[„FŽ<à[¯@–üôà°±-. ü” ]¨l@¡êQ‡.PR§.úØDOF‚ >=)…£‹"P&Ÿtf£L —¨ã/ßp¯ùF_gä ™Èl&‹t/tü×ëj/…Ýé°0p…wq  AÀhŸ8æÏz°¯B¬-ŽÌä¢Ðfå†DÂ×"‘eº›'Ñ›»Tâˆ7E´6×&8¿×"V…lÀk9#É*“{L£D¼  S¥lŸ$q^¼‹£0Ò•œ¼yG%}¡ªÚ’8yŤ`窓Q%$j)nH*=“–J(_¢E‘fo%G^dúaa#ìRˆ¿t „*€’nÿ•?¯çi¢@T‹‘¿¹[EOÿ~m3àÞÿ)zÑW%ü<×Ï!¬3—Ó‚ 4€„¬Û–çÏ›B•¹ñB¥/Uìj#öeÉÛœ’7±NÞgÍÙN7ïmNNlì›á^[ü½ÐÝó_h Þ°»³ØŸ"ùEw:W±b’¯èõ¸ú<Š·Ñ5ÞQþ„G¼ Ùð™b$€Ûû&·^f?z:PA$¾‡­CœR¼×ñ)NCx ›Èy¤Ë,H ØXÙ3 ¤Œ·¬?‘ëùRNïÒl½K¤Y¨ô…ÅXdÈ옇`а‰Dn·É³Á#ì÷p&`‹rÊЉ̋Y”eÇP92`û€ÁÚ®0¨)^”O¢Ññ"€Ö¦QW@‘v£#7m}’~}zšè\•7ª i3½ÒVC ì´’;$ùé"ݨB×·„„z˜ÃFöhìq^̼Ši#Cûz‰Ÿq¡Q‘ÜÎ*z™ Sh´®5BA¶BÑtÓÚ{ˆ¡N›ÓšlI¿l¿3•ÅE«RORÕØÎæñf©:å|TÒ<‚Xè5`¢œJ–«ý½ÂEKk3É=îûD§Ú·—©ŠIËØ,êÒH·e<Ój¤ÑãÙ@bv«[x6‹íÉŸ 5P݃ Qe#kù< ÷[Ö#?æp¿åû¢cè~kßÔµTqdyJƒàº[G›Bƒ¥êFFjF˜m…«dÊQõÈ÷Ëq¼Œ*z} ©ÄÞoLêÄØïßw•°wÊJö7vh”Ã/»Î«&ÿò0cž~q`wR‹žÌuš^s#G9ûDUóÅŠQƒ‘ÙÏUà »Fª¥‚¥,äl-ó/áQæF‚Ö×6N¶gƒjTrÂiPLcHwqÞjFG;¦·›"µ´m¾ÄYº9GûæÌQéºTCŠÜÇrÉrØ<8ª5â¢ËpÿàÆ9‡phŸCjvÔ¼qw§<áx§Ü‚á~Ñy_"MçW™@jq7†»‚>bô“¼;JñŸ¼/( ºw#M]dzý«wÿÃùßðîÀ XUcØ”PºŒf‹¥iNi?05Í*Bê.»<š.£»]ùãrâ^}(*|k¿ððSÁë¯{:yú²W¥ÈmfÁõ>ÝNWQ1•E‘ùðAœû(…`#KK’»¤ð1yØ~òPðK /•œÀ>•-6Â4µ½•‹¹Šm}­ÖÓe¡~…c £z•š‚VÔÛÊ8ë;Ÿ Hé´ Bu)Uï7­‡¬=é4Nš[™åÑþÃGØÔ>ìò6€«oÏZ7 –·3ÔÙýÏ,ùùf¤­£ë×ÀÂ¥np­j@/+~xæyÏ êŒ·¬{Ǭ>˜&ßYѧÕg]ÑQôPö½˜·fWpå{°á}‚vŠ]c<ïû5ü!œsœ7TG•?¬ÊYÎÕg†:—íªš#Ýi—L~NRsÏø»ü~ÈPœ>[~цRßp=>ÎòûôÉǽՑ~kó5¸5w;œŽZáq'óX…ÿBöDC¦T„Ó¢>ØfþØ>Zs:}–w¿~i7ý×Ïòƒ†縭äÔtñâåT°óe²ÿÑýásC]ÿ¡„;[EÅL?Úw/&<|ïÎ=~ï®Ê'ÑËðµf„§A…ÝKÓØðôE¨{êzY iVñ¬Ë³I'^No=MèÌ7œv£œ¶Þã|¦ÊŒäõø¡ñ?SrOÝ?–çößnoþn< endstream endobj 2600 0 obj << /Type /ObjStm /N 100 /First 1020 /Length 2832 /Filter /FlateDecode >> stream xÚ½[[‹¹~Ÿ_¡ÇäEGU%©$0 »kœ0k?$1~p¼CX²x_`óïó}êSg’€Û´|ÑÌéó©ºîI›ÍT’¶Z’˜r!I{åB“ÍÎ…¥¦“‹šz_Ï´ä³qÑÓTç“”¾€F™z‡Õ$$k¯XM’´1¸Ò$®üF³$ÿ`U“̱¾DÖsøš¶õ6²±žãÒ±G›¤–?rsÂþ™ÂW±V*éë–LQðnfB”Þ’ÕÊÝzOÖ|=çÉ\Ös#Ù¨†=ú#œÔ{IU Yá’ªV>皪9¹â–j+Äóšj7Rå-Uß>í©ÎíSO­wó‘šxÁ>S©øˆÇù)^¦qK¬4aA¼>þeÔÔfç`X—Â7=uµ…â©[_(#õ:'öâ[2ž%uï|£)©I”©É‹eZrY*0krÝ>ÉëöÝŽyå+2¿kitiwÚAÆpr¼ƒÜ1Èñ^,ÍBŽw¼ ³>mT (³ŠråiRµ°iv_ÏÍ49Ž7LsVèUèP)HÇ÷¤(åձȓK¨Ä>¸lÔË/K¯ëkÔÖ±¶ªkÙ€¾Š¬ —": ™®ØM*Õ©+v*8–ØM:Õ­+v“±=Шûë»iYïÕíìñaQ¢‘†Ýø.Ø ݈·AÂ"Ò°›án®˜¬×„À¾|-±›Õ²¾†ÝŒV­Ô@ðÝŒ¶8ÖËÒ§»'Oî./ÿùË}º|ûîÝÃǻˋOû¸~þãOïþqwùîáý÷ï_ø‡òúòûË.ß¿’õÃÝå‡û·Ó+kæ{éÈ“J)%ú›¹šà±oÓ“'éò"]~÷ðò!]ž¦ßüòæï÷Ùå·é›oîðçÿ§A‹åI‡PzºiyRÛ¤çæŸ§¡H4!+Ú¬¹À®Ä[Vh€–ša;DHC­Yà(ð7È\øAe˜šaÒŸ§AçD´™…ªD¸ä+ù"VÔ³\à3àYsARpfŸÁÿgİÏÑT ‡*8ƒ].f2z.tДfýó4È‘ÒèP Q±9#´ãÿ¾©FS?‡jž'½ø¯©uæ Hum2O¢A¡•j)›ƒšƒNj¹cžˆ Jc¤Ûn žø–Ì@¤ÐÊ¢§øƒY2Š#¨gäweȼ–l*縈*k¤ž‘Uè²:„Pb{¢Ði€ôÀKËÌ«ü7iBìØqÈýŽFŸØ|å˜Wi  yÛ!bHC‡ÀCt¸JG5x­ Ñ}"pDD+ѧ¡Lä`M`¬Ìi»#H×sh 8b²®ìLßGËФÎK8'KBÝ¥!ŒªõTi χvŽGi ½š¶<ôSµ |NG©ç€|;ìIö±ã%z?^¨'ar“*1ä2ã$½œK½Š(Š*…#¤#A^QËýH— ]øêf0 %ðÕ¨‹Pþg•q®qP!™[ßÄ¡+Õ<—ˆ:&¬âFCÎ^Bu¨Jˆ"ZÃ&Pc´Î6œEÛ<–íÐàåxµ¬Þ†yUK*Tõda }aÃè& ¤˜u¯êú*D Ü¬(:nDèÏI*1à/aµ€вѼÒw÷=Š™ÏHf'È×"pÒ¥–’‡ŸTðÔ&ÙÌ 0ÚȲatŒÜG;+­»*„uä˜ÿ¦†â«Î*ú‘²pä–Ì)›å²ÓHá(@r̽¼®·#s*heU2›kuP* ¦)Òù³äQ±»9Â7jžª ,1ÆÖ€}~|Áa(zÔ5S>»Ó(«"¹¢è…üW[¤¢(f†ºöÛ"Göf‚:56o™!€X;­ôbiÁ)Ä(ð ôÐj ÑÙKrí@"4Øêb$µðÚeÂy §yúI™¶A¶F9 ‚íéšÎÊöµŒÃv0Qz èƒŽ¬9ÊUoK܈€»Ð5²úGªD˜¨šä‰ü2LT«R?wüÄ‘zé0˜¤jÉe…O¦Sà„¡*mg_׿ˆÏÃú­9‚r)ãµÃ8´  z38Ðá{½ªC³*vA8!…*42^¢Ðd0B;©¼Öãì¨O&˜pQÊ¡R¾Úô,¯âht˜7qH‡¥v=‡á´ÙR£Ýœ¶4߯B­¾ Îzl=u(ëÈví©OÕs³‚4 öÔÙÖf)¨‹(ÇÏÒ‰›f^›ê7ÍüRWý¿¨xš^!Uu`ÿ.þË_ͬöäÈO*üλO?ÿü:~öðîãB}¦7éÛ·žKÑyýA×a€ëÕÙÝ\?âòüýÃÛ÷ >]ž?}–./ïý˜^ÿ'CžƒÈ»Ë÷ØéþÝÇœ¶/âøÞ>½{¿~×¶ßýéþÇŸÞ|÷ðkZ¬B†ä²§Ìw°uùüÍ{€À·ëó‹Û°ÿÝ“¬5¹¿.4‹‹ÛÃ=‹‹y]H‰E K K K K K K K K k k k k k k k k k k [ [ [ [ [ [ [ [ [ [ ×@®\¹r äÈ5k ×@®Ü¹r äÈ-[ ·@nܹräÈ={ ÷@îܹräÈÈÈÈÈÈÈÈÈÈÈ#G @<yòäÈ#G Ï@ž<yò ä›YÍ@ž<y^‘½”XH,6ä×?WÒÔ¶±d3»/ý|<ÁA‹0€^'pîg{ ËñqÎý&dq_Í»½:\Fsî7aª1Œv¤3ˆä'NžÙ)p€°°âq$ÞyRã¤üZ‡mM×8drÃy" Á{/™:–å`  Y§­*2;•¹ËIý¡ëA*ø{ähz;HÅ‘(áçi˜ýxã@€ƒ…Λq ,åÝ&rÿ Z‰¤¥ß£Vr,»—Î# ôê.×–燬!·„Z"§ôzVß™Ô*»Û@ž CQ–[ݳÃô¤¦þŠ®«|£Â•Ãú³©°‘Au2ë?› aKh°ÞBO¨ü²û\ƒQ¸sŠñ+\¶<²¢ö–MΖ’ªÉ3ÚAç»ÇޤBà(µpˆ¨Ås¿×ôŠmͺ?ûú ¼°gßx±f~žÏ‚n:§ó°:6õà€²ï(:T"ðMÂk<Ë„·oÔ’œ¾w0ùÐ\ózÖªC=êí(¬!óBýqN?|…!Ž*¶_}…Õ†xªçbȾÙè‘q°Ÿ íN:Žl­ßÄ!²z®‡aQ…Cý¤ÌBà.…w&4‘'Æ;|E²ZÊ<‡‘k*»ÛlŸ^sMåAš½¹ãH"|®Ã+7"&ªBN¿D„È‘Š‰ºƒ}Sõ–kw¨ÙˆJÇ]ëÆ’e^D/™¼³ƒ"u/·©õð3óʾ%/]Ï̳B+{'b½ÁpíS(²ù‰-jEIæ;ἕ¯`¡ˆÞ“Ýìe¡,ŽdoÄP¿‚–¶ùˆëEÞª‘½aK;^‚„)«ÅÿE¤yu`­kÞæ¼ˆÆdŸ·«JE> stream xÚå[IoÛF¾ûWè˜ÃY9ãcÛ$hÒº@´(ж…Ф¡œ¨¿¾ÃU"9œ!Å¡Ñ9Ę7ï{ûfwõ°rWïo¾¿»yó“w8…tuw¿®ë LWu‚àên·úôê§?¾ýýõŸw?¿y‡¼‹§ŽÇ¹$U|Ï?ºq+êoÞAtñõºþ| ½üËÿôå˜löb£¨|_¾@<2Z?ð‡KÜò£aä àÕßHz☆ Z;Œò Z@IÒbõ7ßUp䇭ÒUùã/ïoVŸÖ¸¯8ÕBæL"^­p8-Àâô´MT©„ŒÙÈìŸ ¸3AÐû@Áª'a`OÓÞÔžEÔ@¢¤B}aÛ‘¿ #ÅûXò(ýkLË@E¯'õâý\œr XZ(ÃGGȸx§v}×ÕrG¸ãy´Ï]ì?©ˆ¡ Bp¢1\Š‹Ú–èÕÁ‘Ã\®¬Ñæx®6HW­7òŸÐÜ'Yü “M1ìP¦ˆ3"Ì6aüüÿÉ&`YQéä„Í6+}z§ÒÇÑ{ß©*×ARï…sͨï"×À0fNJqÍv¬åГšWdñåè‹ÇY¨’ÉK+‚=²ð[ößüçB@(؃ÐÁ€N1ÿX„ë]xʬ™‹YFË öŤ×õÕ+4†%›Ì»ÒðerOßk”Ñ Çׯ?fƒe‡'ÃäSŒ/÷qÍÂíê„è]ä†uà5êñd\rÁìú¾| ÒñCîä?ö„Ðd4œ=®ŽÆËWE̳òĸüVÔ ^[†K å<Àa³[ ì™û Tëb,qÈ[QéêÒ -n8œ˜«7Ö“kægû$V%ÏA¾|îòì宲zëCÖEG;q¢ÇØ Ä‰NCž·ýX}÷zM\·Hl¡î[ ×l›7Ä&ã7E½:*ÛNj麆fLÖ²lC-ÿG6~”(yš<â1ÖÒŠOÎ@žÑwV|´çºbÚ³9oyïBÎŽi¼¹O“'SÏëÍÎèN›iäKn´õƒÏYꪒ£U^ËÒ³Ws}öno#_È5M]“Ê¥§c ÓA0¹T+¸Ü4òÛ$qɬ‚I¸C˜ÛQS–Ö•5«v3IH‡Å„µã•üÈO×Ùé®e„ßí?SNÀ•Beó+bfr[‚Óƒ’3—ž’ÄÇÜg‰ 9„»ÍvïdC{Œ)!·"¹³Pz¶V•GE2ÄÖbï äPR#¤–“þòè1†™¥fd. °’“ä׫b¨¹ŸÒÛÛUÌèþs#~@™C@gÆ$B? óA°X<+"09)Šð T…ù#$m£"Ø{{°¬!2:ºx’a4Pð0K£\ÕüMòW¢5­ýðÜ”yÍÚox=ƒd¹:i;ó0Lj‰íŒaÿ¡V…i53¾I˜±š©ºë>kÍZ溡Ic¤xrâ0/HÚ#¥$ªF8g.ï©„¦ŽLnêÄþ!öU ”—r“ŽCüm’ª-E1dûHB/jŠd€ì$­¨nÞ2c~×h Mo«ËYÝUÛg àé,e~&no¥q~ÈmS#´Yó™‹àN¦WaÇ­ÈöÙQ;C«²Â¿~†¦j®ÅéIUåH²xZlX<—»Oë¶n-¿V"´Ýuÿî° 8r° E䡜7l^Ü€Ù÷,8ÞÙëÆ§a©3úTÅÿjV±ìöR&-‡ºLÅ¥Xnyµ¼C::Ú žµ:?WíµgâaÏ´V´ëqb™y>H–8%ƒÙl¿;•ö·K2±X¡ÝÑ…b­œ³õ™©™æÝ)"V¸?°\’ZÕâZ£ãh9àðÙÖ;?ógõÐ#íárÍÚ0QL=óùç¬Ò¸áÀ¯÷‹çrr¥x¢0~ȇË&]Ötå½üeI'­“â3îÓ~<.ß709V›§ÊVv–fÊú®Q»¿¢ž3 ›«i{+%ãmòM•ûdÐå“®&ÕtFç¾I±Î0‰`¯'BµÙã 9œümÚ¶æsh¬màK\ÇvÍoUZ‘• AS+î“4_jiËØØ>ÿŒôWTÏÁˆL)â¬@e¡Jsva嶬¤úY’®ƒ$Lõý„(ÜÑÝi­††µXdé1ÈÔì_úÖ>o`¥"Ø’ÒW?­Ôõ³\ÌÚ€‹HÃ'ÏqšŽag_æC>e-ZWÆîè ÚÌ>{Ü\|fQj(1TE陃ŋRºÔ={¼q¾Ý¯Se_³}ý˃cDIàGZ’­ßS°”A<Óx 9…êýx…©°Ò–™n{}G‹ ݵ•ãžåË$ƒ:t÷d`X‹CðIÛö½0\ÆM—ôÌ!TøÎ`zëYº †b˰-e2ÏÐ|ªD¾¦áýæsxÝ‚IÎ7âØt¢_õþRÍoc° ™{_¢Í³C+7mQ/?&3©ãò³yùe©/ Ì¿üƒ•MŒaSw¹‰©#Ÿ^|—ŸÖ#ª]ö¼½»ù*ý› endstream endobj 2709 0 obj << /Type /ObjStm /N 100 /First 1020 /Length 2758 /Filter /FlateDecode >> stream xÚ½[M·½ï¯à1¹pXÅ* l J$€`éDÐA‘c×V€óïóŠÓ5Ôã·aU;Ûóø†õMÖpJ%qNT« þ£¹ ©Žî‚&­äBK­± –lˆ = VF¢¢þ´–D4Ê$$ûó pQÕšHû|N;¬j¢®Sj‰FŸï°ÄDŽì ,ó#qíþ\c%ÁÎtx³î¥á r”†PÄQš¦Jæ(ølµÒD±Tåüמªžÿ:RµùW+©vñ5Œ°æk'!ò5¬&á¹U&Iªùf˜&Ñ2ŸkIšÌç,‰Ù|®'Å÷ÀFÒR}5ÐU2ÂøX ªþ' K5©š£tIüuè¢WçÜ[Ò1Õ-µ2†K=5žªê#µÚo”í4¬1ÈÕçÏ Nàèx£&<;Ÿ“„%|Ý¡ÉÈ·¸–Œ‡³и°¯“0𯒿 l¥$댽²B° WžÓí‹Cê©3W—6›;ÕÔëTY©iˆkÚðñ‡º¦ [<|KØU1:‰KœÆÃx/•rþ3Œ¨°ëÚA¥ºJ@¢@  bs•uˆv~À­µÏØÍµ”á"ì•HVKĦX Äñ¢«Õ«‘º^ FOäV«Q/ÌÜöëÃj\Ì™aˉ¹øG¬Xkõg¡&biþlÅjÜ c5¸ ÍŸøÕ¸·)b5c"`µŠ×]4÷/÷ƒ5Á{‡¯†Õ©ª;¥)Õé@&î‹6Õ1=}@[/^ÜÞþ÷—ûtúöááñéîôæË¿žæïýéá?w§ï?ýxÿé]A|(ïO>ýåôý;š¿Ü~¸ÿø”Þ'3TçÎnE¤”ÉX[†Oà¹oÓ‹éô&þôøö1^¦?üòáß÷¹ÒÓ7ßÜáßÒsu%Ôš‡ë°•ÌÝ#Žd!û: “…$L2l„˜ò€So¹¸T΢c‡C[Ç‘%w„Øs.ÓGîÓ JÖÂ;$Ê:°¬\=‚ðȈ R$ÃzaŠ{³CÁRPËîðø 'MµŒ°—̵ԯs…ö îI«ö ­g@˜fÛÙ†¾B±Œ˜€øÎÀEö!8+œ1?#ÄX© ,.ÕÓMŽ‘Gaž¯:edðc6"L‘0 Í&‘ë3bñ1ñᢌàÀƒø${Ö{J„§žÂ.3í˜e_ ©…Jöä3{yÙªd;;1’0˜%ro#ʰJJAaИ3õ«\é 0¼†ÙëÏ-B TÉÔä ~ZM»e/‹…ਥ!Ù1Y ¡•éJyƒµý+w‚[쾚憌)©Â qØ* ¯:¦®•Ú¼ŽÑK¬T”´+;­$a(š¼ñ@!S<`\ažÚàUŽ!!B(½#YQç‹ÖYá©¢°±ŠŽt}ÖPFÌô~Î Ó({ÝÒØ²Æ…ÖÂo’X›Â7“ wºšœ¦ÈNYÙùœ£TÔ´ýêˆYe7^Öõ&!ƒF« v;‚â;aG%qƒ>^¬¥h\kGöB¹/øô£hú $ÐsX×+ ƒeÒžQÈú,.ªh¤ºŸ× Œ HiF·¼£ºÞ=.$6÷¸IBž!•‰Hå7Iô¾ÞGe6½×b_„ó¨;î1ø|t6½—°-µä±SMŒú Ê(=‹÷À¡ ô£c/`.%±ÕU[]u›ÄÊ®y‹ý¶+¢ƒ”‚!d …åíù­ÕêÙ,·(Q;RI³cv"|£¢ì¯Nfó ”9yo#–Öv[Ì®‚XÍ|‰ÙUç9ÑÎFèúpY«—6z —U vg'š¬÷Ð z›„®¯r++<•/U.eÛk„WªC*Á°ýT3#£ †: ïÎãÐà ð‰‚–¸y¾@÷%~aƒæ¼d—q`ÇÝãd´ã ë4ÑcÎ-ãH€á§ì](û½\ƸtxºEKFåÀõ,±핸 9 ¨¿$„Gø…ZœÏ0:ã6êA¡ ¸)õ«2Ð7kY5(»ï'ÙÍO ‘Ì‘?ÿ·½±²¬CÊ@Äî—–IÜ5ƒ9ÜoaUå¨@)e~ + q=ñ[X­Gã´ÁW[Ïs“y»dÎÅO#Â.Ñ+d—Q\Æ]p—7ï‚Kâezdž·—ôC:ýýÿL^­KKæ½þáËÏ?¿‡_=>ÞÏ×øüÚßîüéÃw¿¦¹SЦ“a¡[3ÃÃ럒¸ªžŸŸ›ýëÏ©§5‡RΕ(!¦ËÃB ÁBè!ŒMà@æ@æ@æ@æ@æ@æ@æ@æ@æ@®\¹r äÈ5k ×@®\YYYYYYYYYYYYYYYYYYYY¹r äÈ-[ ·@nܹr d d d d d d d d d d äÈ={ ÷@îܹräÈ=G @<yòäÈ#G ¹—…À!Ô$ ¡…`!ô9|°o>ø~ÑàL©>2gVºON‘æíøÔJÝ›ZY±%m*)Pµ¢æg€¿Í±•zPÚ`´ýÅã{Ѩ⎄NŒ-Ík«½ë¿±°”  ÄXŸT>Ph(®/Ú,øvk‰…Ã4oÁ甈÷y2÷AT¸²wLµv#d¶}M-ßmhÁèÞ}°®Ü|üâ­A:)"·Iô…DÔQT"k .~£0n“Xjªšhžs¶[¨B•Qãä ¡Ÿ¸Dú¸èÃ'.éz¸À5Xš\úh,*Û‚i~û4 ÚÛØ§Oíø< šÕvó*›ê7ÂAçÄŒ9H \hØ Ý;6|ŽHå3E¯¡JzP9*fw8‡ÏTM­À.Qñ“úl‘ìK¬<%òæÓï¸æÄ ªïÊ 5ŸÚ¿½«ž•g#ìA MˆOÌP™#ÿ¹ûDM+؉£Âö1}Z…|êê(DUzn\q»ô/o 7Ìáƒ$7I¬ÌÛœ¼Ìø÷3bN^kËmï2vå@Ó%N‰™ÈoRè¶>q\(l‰ã&‰µå%öÁ‡ûHæM‡“Z]e?K¦cn.$ gž$6‹ λ³ÙÏ`Aál7h}sa·6A×—2 \´^ÊEygµ•3ÎñÁ§§Ø¿Ö³Yƒôžmï+,ýêˆ ‰i·)¬ôŠƒ àB»éøVc š/Û;À]BzÑ¿(£I6ÝIà\Ö÷À~¶ßG8§ORU÷>u:þÏ5|–ªŽÃ Ë-Hø,ìðo¿m_­òA&ÑÝ¡ËKñ?àÈ9ÿ endstream endobj 2816 0 obj << /Type /ObjStm /N 100 /First 990 /Length 2010 /Filter /FlateDecode >> stream xÚíZM«¹Ý¿_¡e²Qëê~è ÌÀ$ÆI ‹aìEãE2y„!ƒß`<üûœ£×ÝžY¸: ¹!ðs©Jjéè~ž«ª>LK+}˜QeÃKÁF“Q\;Y"œYÆL4¼•¹º\Š´Õ罈Ìù€–rÊÕ‹É-‚-/âkV"c­è£H>÷bÎÖÇ1äOදÞÒmõ&$¬a|Æÿæ³s üLìHe_d(‚YÔ8é­¨¯Þ!EÇê½hFÃC)bVL:^¬ûúEÓ\¿ż¯ù²Xø7‹Õ›­ØìÄ’R¼­ÞìÅ%k¤Rƫ׊Ûs¯÷¤*2ŠÎãÖÓ‰“úLî7g ®1[‰îD0¥„æI/á2°¶õ­^+Á%ÑòSüYt£Ùše”!¹Æe*k4n°ˆžP46Ù’y)[½w< ¥´ŒÆgVRž{½d§Ye‹’:Ö,£¤·5K– ëlÍ’lOi%çê)³­^€œ2kH/$Í‚-cKhˆ4šÉ¬-ç2$èmêà3`™ õfgÙ[hÉ,2±ÁijhaœŸžÃ€“Ænع¤ñÙä3¨{rh¡×aB‹˜®“æ™Æ4'Ók„3é ha!Ç}pZ˜?è-ìC–8cðÙà/r=Ã/ 8´`ŽspP7ZØÇ‹§7ÿþñ±œ¾~ÿþéãÃéõOû¸îÿøýû>œ~óôáïÞ6D€öîôûÓN¿}+ëæáôíãwË[³6ØŒN¯“Î;¥6¨ÑZTÓÀ¸¯Ë‹åôºœ~÷ô橜^–_ýø×¸¨ã&ˆöôqqÑÇms£ê¬[0ËGÄ?U\CŽPèÎH«@NCÒªÌïø•E»AñwÑG‡“"P4©ŒÌ=g%PéÌè^¢Dnf:®®‰ …È|¢­Õ~$ Ýè¥ Kµ;)̨ ›ˆ€¤ k×q/Q o©!=#H1aš‹\Ü „Ï*ˆk%¬¾¸i@Dã0‰µ/ (‚ôœ¸ 9¡÷ÚçQÛ+©„̽ϚPâCEÍ@vëÓ{`Hèd‡+‘\A ¦«,Ûi@Anܘ¾`pRRo‰ª~/ gu€õB"¸B6rÕ8ŒV¾3Z! °tD”J0ýÚ0f¯¨®>Âö[#çäÚç&Ùªµƒ`¥í €ð¬így”²~¬vJ9£±Ÿ™,¬ÙÿÂbæw3 Hu¢€óNšå9`RB(È>"wJâ\ÿ\AœëŸÛ ÆF2™"ŠôŽÅ!p*Ö¾HbÕRô;s9PH€S5Ìs.—Þª·þy±‘ëj l9Ë`ê™z Tk0sôƒ Ý7º¨â"k—Ì‘(ÎÔ™c0sÄ{̱SReÐ5Y”Ò;0ÁEå>QBAê ¾q€ ap›b'©äý,A³ò”¬ûÖÁÀVpC¬¸¶u €Õ»•@AìG$w¯QJå]°ê“0,C=Þ™ý>t_™­y¤ˆŠTŒ§D“\ª’Yôq7}<Ûe Lü“ÇD ‘„E…ŽŽPìtÐ Ñ,4>¡P«ˆw9.‚A€FÂ=Pyò ÝBkçq1É8.ÊÇÐGcþ™$H²QÙh›Ö`›ÎãsDiø‡r¨Ï¬érŸó"CÆP8åƒÚʨ·1ì,DMÇ¢Ö¬@Àþÿ s§MÀÁ0=xŽœ×Èíx>õˆÒÌý†éÍqÍ`æ9Çщí™ƺËocØY +X­; ѱ:1huÄ.wå>ÐFæNQùÚÄkt€@Å3ù6 <³å}@\£Ÿð #õ&\åˆPÈÖ\Žp澟W‚ ¾û¿ E)Η¢jÉw–EJE52îR’C0H`©ò` E&9Èä}î§wW gzwÄÎcK¨Â2Ò5…ZJŽq§z¡4ØÒò …A+r:v’;ø„>¿s_.ó&†oÀ eGw˜DG¶ ,žàUÈfL­vt¢> stream xÚœvP˶&N ®aãîîN ¸»³‘àîîî  ¸»»»»w× ³sÏ»'9wæ½™š¢jó«—~½Vw“Ê)Ò YŬ­hé¸V†ÖVöÖúúnf,´ @G };h‘ž”TÉÌÁøßiÁ“ªíìͬ­¸þÖ¶ê;€$"ú 31;3€ÐÀÈ `àäbfába010²ý[ÑÚŽ mfhª´(šêÛÙáI…­m\íÌLL¸( )A† l´ k&€‚¾)@ èd´ú‡…±™½ƒ•¾%ÎBÿ¯K}3 :CkKJšÿÍ!#ã_ÿÕ”šHã_ÿé¬íLþO–Ì´¿LÙþþ?<üU €ÂÒþ_ކöFt@#GJº¨I™­ìFG+# @QB ` Ú€Å_r2à#Ð h¢Ò`à øµib t€¿â³2°2±(Ll¸èéÙÿZ¢³7¦³:ÐS‚(µ2¶¶´Z9ØÃ32ŒÌ @3+xú_®”\A92Œ€Æai};3€&#€á×ßß_Ú *Œ¬­,\«Ë€ÈÐËŠK|””¤þoºèoe!!k€;€–‘ÀÊÀ à`fxþÓ©œ¾Ù%ÅðÛPÂÊØðïämþ]€Ó_ øWãQþéJÆÚÄ!€â÷®i1°2‚~ÿ›6ú—ÂÿÔ=¿lÿlƒ?þ»þÝ:ÿZû»{þGËÿh£·Î/ÿìž_&tZ 8ÿ·¾ù¥óŒþ?ÍÒÿ÷üüÿÍÌÿ8'ÿ÷é s´°øWRüÑ~PÿÙþ«ÿ³/Äô-Í,\ÿ7ÉjªÿJü¿s¤øg£J8胲´2±ø[df/fæ4’3s04ë[Øÿ’+ÿ*ÆÂÌ (gmoöë +ì)™šš[ííÿµ´2úDAÙ™Y™˜XÙúvvú®ð  afbe¸3Ì@ž\@Plz:+k ÀÆÑÁÄ ü¯)bcÐ þý…ØôB¿;€^ø7âЋüFœzÑ¿;€^ì7bÐü˜ôâ¿3€^â7bÐú@Ñ¥~#Ptéß]æ7E—ýq€¢ËýF èò¿(ºÂoŠ®ø¢+ýF &”#PtÕßOýoÄ Š§ñ4õ#O}{C33C3;CG˿匠3ú¯3 #àßr¦_b ™½ùor9qøíT»Áo²0Ð74· ¦éþY~‰íþ€j5°Ó7Zþ³þ—ø¯üÛ+ã_bs Ã?ô9™ÿ–ÿ‡ˆÿ+(ECk Pÿ]Ë/‰¥åoj@¼ý ™A„Y[Xü™3è’¡ÿÍ ¨¡éÿÊökÝÖtÀü픨½-ôÿ šÄño/ c3§?ÜþZ¶vü3,HÅäwкɯG ðOP9¿Ùf‘hêjc ´úC$3û‚’ÿüu‰ùÄ×ï"Ø@ÄXüšòßë vÿ¨tïÑÿÅ òe:~“ måhiðë*4ù#%F]Ö¿“ù´þÊ‘T¨ÍïeP }; Õ?öôNûKúÏÝg¥`´À¨²ýKffý{Y@ÄÚX8þQ#Hbû»ð_Èhÿ¯óïoß,¿„Ö ·ŽÅ† éûÁ*ù·[VPiö@K³¶ ë/ Ó›Ä rbzÚü¨Œÿ˜#ЭDÿ»&ÐÝLï`jü£{@498[ÿaòáø{,@1ÿuOÙZÛýÉ5hÃþ€ „ÿJS—? (ªë´On¿syrÚý•Á?îCG;ÐF9üë…º(þÍ@·è4„_œ³6äø\Ðr_!ˆëL»3Æh,’nV -4œ¬ìƒ}úuüà!ø¡SRy_¯Ö˜‹W!bÚEvÐÈ®žæ¢\†ñË'{;šºŒ\v„ÞÅÑvdƒ!ýÎêö|`´í¡*0sRaivc;y̦ƒ7¢æÎ±¶Òã@•_NlM¤cé9Têeà Êïm›Ft²Š:sGÓ»ÞIŒ~+F-¥=²Õò&A þ¥XtÓäÃ<œßõHl»ã¾Ô›¢ Ë""¾%“mšQ\å~p0PP¤YÐÿ2ýÍ.‚p¡Q]¦9éU=Êg8°;eí%4Ó@V½Í Øõ`þÄxÞzî=&ù˽;Ãÿv&(Òèt×”‚§.6©³y }W£W ™ÙV䓚³SN¸×ñК¿þ, ÛªõÌkoBnó-`dEÅ{R’îÏOµêfZ÷rM0¯g¦yˆÅëØÒglõ}CÖëÛŒ"#8ƒ+ ²; “‹]„ŠåëÛ.?ÒîÑ&Q¥ácÒµãpœt}E³ýÛ´PVߤŸ !©H{šüf›7Š{itÃÜîÄr#UØØ:%ƒcU%}ºZÞ63ñ×fÖYe׉!ŒßÒyn˜n•ð´­X‘Λñ'n¦úí­õÅØ~-¬jü_‰"¬o‚L[•á0Vò0=ÖGÙË ;î¾Ï:upò/kŽB(ÑšL]äŸûNFË’u;‚A¤À8~gÕ°–?ÎóÎÑÏzbS#ŒŽ‡ã`BUôáO\¶bk»që‰"œe`A½—ù)y6.¬‚JùpŠ.AðZz„çǺZµÐùór¬T–4ê‚ouDâ3…üõ“ªÐ÷#«æ ´N³×‡ oó™¦÷K­±5ùð«|”°è1uS©-3>ªtØ­ö‘yU.=B K&l´ã}~{1gk­^µ+ÁÝÛ®õæ^†e+Vèo”ænó“øH´)+ƒ>|̙Ç¿—{;Æä§ü“Ûõݘ ÝXÎf¦ÌÀþ³ì³ÛD¸?Cq!«©♫‚Ïð›ŠÐ$ŸsÉòuJOé\¾À&Vú®ð Ëw²ÇÍnºýw Ó¹Ûð_'ÎUL•Û›j²#lšz ˯݆EÐ"Ù “©í ÛŒyß÷LüÐS·VœØGBj¹ætì|ªJ2 v_3„wÿ~Òþ-,u÷Vð¼8X‡ja,ÑO\qŠÞFeNÈÙ’ü8:p^ÆYëL¡µßz‰‘¸29“òtÀ¹ŠÝ ÿ]åËél¶ÙæTÚìÖš¶4‰rŠZ(LÕ{À ^_òQCOZ[8WÅm¿vüY)koÊ,ø·ß0%Œó–ì½(”Oã’-4{›?÷ä1³ ^3Z©ÉHÄŽÈîÀyv(nÊ-|—}?b¡üÈ3[žkÿ¶CüÊïmÛ$wŸh1év¨9miC™û=#FFš¶æâYK;ŽF]Ôb§€$bøI凅š"&ÿ‘žŠÊf¼•ê×EjšUÿn- ;ÒÜâgeò=?¯’¾ŒÕ¥BéÕÌ-K·â×WçH:J@3® f¥_õÓºú@óSFߪÿ&Í—þXê¶R[L„oãÌ»«Ùt¾/‘<GMY‹^LäçÓ£HgG.¤‡¼r •ï庨±uÅÐ8B ªRNçÁ¶úаnwÛÙnZ½‰QäÚ$¿c“ð Ñ)Ã+ˆå—µ¯Â»Ã5¬SôMP¢Â¿ÂzýùiGÛqAµ±‡ eø:4‡ô ײ<x¹xJ”•´!Å.ï}Kš·éêη8z^ùM.+Ì25 0ôøÙ§¨H$Ê¢OòN©äœ-+Tà=‰u¨àh X Ð9ÆÆ$º†q»Ö9{]öéB¸›0?½ wM¹%ý«+´¹­}=ÂêÕOyº5LŸ‚¡€2û.ŽÄò»íÆ%Ÿa–ü‚:ñLY#¡æ;~åË©²]"`w¯aƒf¤Ú.$ùùuÄߌZÍ0–kÍÏ‘ºié³¾ùƒŒ+,ÙBþ¨ÒåÙXtþh !S†Õ¤y¾(G>LJŒðKiÁß‘¡Mœ„y#KuîOUxæ•YåÙ&¢à Y0 î‰`Å 'AŸŠËè“ì»ÝÅIû«Î$mSr†É­DyŒq>;‡X]ð,„ksºë¤ô½Bùæ…LåË Ÿ4Xç·=иMfOS¼˜}ߣy.¹3öb„¬°T(@‰]w0™<”F>N#¤-2¤r9ø–¢Âu¡Oÿk™WDe*jÀiE-;½9ðÀ\½Š#ul †Á–w\)Ni c@hƒv£ ¶_¼úÒu¾æ‘eFONÕd¸ øŠ³]ž¹mñÖCë–œÇ ¢öÜjÅTùlFNýzO.r­—í¾SîBñ{¬ˆŒH°ÕÖë.£®2¥]¡¦3¾•òŠiŽ\¹Äñƒd¢H?¦Mœ÷ý‘ÿ;IK†à·˜¤e%6á%¦|g˜ 0ííKªÛž»M{PŠùq"6:ƒ¤™õj{Z°}Í#3ãæìD€XáÒ =p½~reA-þ ßž‰(Bò”WŒìÀ½þOªwŽñ–ß#xÒW?^åŠèO!ÿÈÒ2éÍò¶<¿ ,æ$N3]~\nÆ9šYg«¶˜ý9ü. ¬©ÓID*UÓ™CQ­'«p'[º oÎärCEÃX<ŽwäÞ<ú¾Jë¼òŠÐ rÙO\bša¹àЦÞ×¶èÖ*ëånFºŽx ‘àŸ3h=,Á(ô#Þ0K·×³çq~Ù«"º4EìøÉÁÊ=ùih)Nª—ýgB¼——ƒYH²°MêlGö¬ûÑø&8ÏãBt2g’J¢Õ]âš§òço¡£;i™_*9>­Ý’ ÕØ² 1 gá‹ð$nFgƒ©Í7|Hñ±ÁT¡1ek5mCIýî1>!#„ÃïwûÑéšuèD¥®Ðš ,,LÄù,e0lÂy›u<×ÿöfºù[\˜ Lï2P'žÅÆ»sÓiøF˜'Ä“ßÕDsÒ•mTÜ—o[M?°ªÉ5º ©TiŠhŸ/…yÄ©#–8Š%í@Èäò,hjÐûX(Km}ßÛSÝ9˜öM|£×ØdLr摦U0=‚ò‚:•ãûþ+†àóF~_á„ÅíR¶ã¶ZßÑÞÇ·qmV£¸Ñ‰œ±‹?Š4Ïû­z» ÉÂé­Ñ¿¢Ö)±ûr«ÿ4zž½Ý”³DˆÉ™~ÏÏÀ/¾æíÛM‰~·¼ðj±2zCg.ÌžtZôžƒ7+ççwÆ» ,þlJáæòÉ,´^™®ÅÝË9UÜs*±7¾ß.Ð¹Ž„!Ué0R|Ìßhd®¾JÏÔã.]ÁtwŒå£˜¥ŸœqùH“‰):!aÈ(·,÷öz—Ü$)ûÕœ5écjú„¾”6 Ó•£5âÇñ¶^!M”­$ o‘HÂâŨ‡`õÛ&½XàÔYXÑÀŽÏQS9ãÙ¦õK|_Y•ÿç(dߪõsRÊš ¬ Ö¤ç#ä|š*“ÃFÆ"Ù,ó0ô÷ö«iÔY'=¦BSÔg?{²Q(m ÑWñ„™r£Iœ3iÞëxFu¿Z TÆ\’‘xœeÀ`(¬ÓÊ߀5ç!Š ÊcÇGcš÷Üj9`m/—÷P™iÛƒiÂ^¯òfˆ¬yÄßç@Q×ÂUà»(èí´Swâ”>×°Áôµ L ^›ñ ^˜,lw¥tˆ^ò4…•p «HfO§óòëÕœøú:h¨3{ÌG¹ÈÓ:Û­”^¬Yüp§´ŽÚð%EE xNmü€€ë×°Àç%òˆEÒOâÚT qqþ°Å¯­`‹>+CèóÄ,eÅ qaßI§ÈõCŠŠ¹«A`xYÅòvró%÷´¦úÇfƒöÊV©³ª =¦Ä(¾â›h¥Ù×¹!EZ&îÛ/h.Ãï­x4Š?•{“\Ó¯'ݽÜÎÞõ©´Û÷ª®zgÙ/uÚþ˜€3ßÏÆ© 7y ”T’aiÔ+øpµ·OºIj{pJDFÎî‰ônvØ Ɖžö¥’HQ°‹ì8n6­#¯Ò< Je>«ƒìÏÚ$qåŠvà&Øîë7±®¨Tõ;âò7ß>K`/®y+wåÄÙeÜãJ¥uoŒ vј.Ë~Æ© s¬<„)7·C]î52‚á6úäÙ¯]µaQ‘å–¥Þ褖ËÕ‚ï'Ü»ÔÂ`ÙôšÎ½{‚Ò_ZL.Æ­,!‘¬6×á)?_Þ Èè7‚K¬öVeUG~\óLÏo|z Û×ÏÝÑ#j=ä㎅w H¸Ê4ÅÝ÷EÀ ‰”Ñ ô5Ö8®±ZœŠMYšæ²Ââ V £Fb,†„ÀCö\ûâZ(¹®ß’Q(0㪊2ê<)ñ¾Õ€ìªÉü¨Tú⸾êõ#k÷çÎÊM¡v¬¬ÙMÃ(þåù·gA±P>^ ?VÜsÊ™Ú1Tü±Ô]‡FXÖÈÜ–B¢“–ï‹ìjáeÔ‘ÁF/ / íËä`®à^ï(lãŠY MÆ:$K)>Išq4ñm–Ô‡:!gp€X6f~C€ãN…¹QÀé6·H‡F'*Wó6 ?^Õ?öF3NnZžC~i½ßPùʨeÓ R R=¡ïò×TêäsCêÊ¡ õ)ÉËÛÄ |ùMM¢“†Dpߨ*5åHå• ïrÖ-„œŽàX5ÒžvüŒ­Â9mœÎKY¡Õ õÈK(¿ƒÆ¯3K´o8Æ®`RõгcÃLŽÕË;¾Cqœc‰}l?Šömút²ä6Ì;‰Ã ‡XTI—a¿©ÌÉûîkq•ª"8bÞL·`Äð¯³[ ÖÕL¡Í‹gÞú‚›§"£+ì÷¤PH®ŸNCz±ShÙ/õ/[bç— ÂÀCQ¿JN"l¾)xy{ï—Æ0ås#M'—šŸ¾h°D3Ùt ¦»u.jÖ£&ö0ÇHxÒ0­\S¤Ò˜Faÿo¾ˆŸ°Ø%NX†i½Rÿêû…ˆ»Å|H(cw1¨)¯oÌŠ`Ì´‚ŸNÃ\³î\é.AÑSûA?´NÖ}oVÓÄ>•Üv¤xÉózb¼¶€Ý­ø ]OƒˆFÀ¹'pùR`\xpö:¼S;}¾o³`Œbö‘¦O"BŸØÒ¡½åËTÔ¹=þ2ã{ ±}yE‹Õaø`ËŒ¢Ùi’yCJ²ðvvpqUœeûdXW‹‚ëu'ŠOøœôÆlÎÆ1 ÌûžÀGÜj÷5ù™Cwð¡ðçH¦´0;ð¬ªdÃç >Ä×±œæˆ„k.¿—&ï90wô]Ǭ0'8)Ç B’Œ vX¦Ñ¶th53ôž}{+q‰½âD˜ºª¦‚†Å4þGtÃÓŸ³³4A“¤yç,¬*1Ç:&_õ9Ltš Mý–¢«Â¼ÿ‹M±±¥tcM múÀiUc3¦¸¥Ü+Q@êÑ!œ‹&_|`¡5D²gÝeÑù9ç¦: ûüÓ©+ M˜5ø÷…'×ÐÓâ¾s2M;Òîm%jîëòµ6ÝñѺ²ä ä{ùæO(V¶›7aÃÌ4‘Þ%¯Øùˆ/¦Ëzek9ºZ-ÙYœ·ocÈëÐ=Ýõ0a}ßÊ1kDŒ—.HåN-ÆÂJšÛ•“%•¢³Î—µYºíúØ‹&Gí®çÂXÈš~ªªÂÆÃHʾáQ`ä0¡˜5VëË L²LŸt$‹V)̲HÏ¡c,Ÿ‰ñïùèâV•nZañd’2°RÕUœÒw3žwÅ,Z-ÏpÛíeÚÒ¢´†ž;ÊY2”e x|y3Ç8ʼn®Y^-¨?9±-,®d·nÇJ¸C_×h¾e%4‹DÎí€&çØÍH­wHßAÀì½F˜3y0ÕzãÄ™ÐT–­1ÂêÝýÍþðÇv§‘.í™%ÿÃÑU È…®ñwï}OYÔJÿ‰ãu(ÄCù¸;]ú`4áU…]-‡Ü~d()Éó½d‘—²·Å (Ÿ<¯-ù´UP5F9²‡:Ñ‹åeÛPë¼éïiëUß“vPÈr puÉ¢a,ež,sx5òvCñjêÇž™'7¾„—VÄä/aëЛ/ð$8³žÌ¿WFÈËò}ã@^€–âr_šnWlÁ{üœÅ}؃ݞÁÌ5£.qœÑç^|ÛxP¯õ ¼ˆ÷®~WX-ÀÏdQœxÙ9 mC§vAµñÝÎð1¾­rÂé†Wuäó7]”KÙXŽ„k9¡B«Öš}¾‘òy6,#¼»EkC"ûÝ–+ݵºî@Ÿ~ëpÄ“ ‚ä;`dT'€&^È;—äþy¡óM>~o)ÓÛ>V§Ù¨ð²Ã»¢I2žtõ3<ž"ö…Zgÿó{íæHŠy+ &ôÆáâùѶ™ÂKç謭+"µ\ú•X/V80l7úÃßql]å$’°œ¥1‡òGâôûÒK‹âMñÐl»ãDë­g¿«|ÚÎf?vÙdzõ~Ä}Ž÷9´òš{Ä_Mð¥²þòqڈ咉/­+î.6Sñký(öé»óT鑆Â87L³’é§¡R‹?b瘵šÒÀKƒã÷Ë#Ñõœ ¥†L"½el’_+’w…VµÒ$¬¤ØˆwüÙÐdâèÄ$4¾{Rox3펲²¾Ë¢Bc\v›wèpñ~…lA%š¼ì ÞÙ½±¥Ü9èøÈš5ó|GÒKëø8¤!27BQÏ(ÝM!÷®Î8‹jºŒ5wýÐHlß¿Q7¤®ˆn“Ïå}(}Ã_ÆÔñ ô$—H5xc'Õo—R_1_ÞV#5ü·ËM·îù*Î <ùA—~ëÃFˆÁÞt÷ƒ¢}oý’DòiUèqT&ŠªÄlÙðÃ!üÓ-‰¯üW¯TôÂX¦Á”30/r¸QŠ\i_Zn_Eø†Î„kžü«tlþ·ìõœL1ß¾™a|}ûÊ'wÞN:ÆÆð¦œ,Ð|•‡ºJùV¢Í&„4\þ¢PîƒðjBÍÅÏ8½î‚µHÞ¶G>ú |šbÉÙ9×§r3eŸèÐH0¦²k)òºã¿.&.·¾)À˜”béu/òúÁæ.qâépŒöq—¥<{JðÅ5$ê=ÅR1ë>uÁí¡_ndü|ă:Ÿ^訟”üé 3ëÕGÔŽãZ"àºwQ F¬áa-—ðǪŒ7âçAlfÖ½WX=86o,p ÝD7„_ÿñù©?Bwj ¾J&à.Û©"è¡'Õ›HÛ—u†¤qðŒC¥î¤_ƒ£í^ÿµ7ׯ[24 XðåK‰6'IÈöšaŸŸ` “³ “ÆüÐÁÞ0±­$9ÑxNfCÇ€»ÕTCƒ φƒ¿L¬¦Õ(¨_ ¬²w¦×$Âÿc}«›KáÞ|Ôü›\dmÆ IÂìTcç‰/=ÏØ1n‡ë>û¢^dŰš§U—Tî|]ZEU“þ§žÀ¶Êk°WÉj N‰Èï~RÐ Ž ~å;‡E¹€’­Ï×ݪ®X<€“Œµj"ä$ß»Ü=ö¥Œ§µêËအ`¦ Rß,ÄÖN6%ðM”,ÌÛƒ)2¬—´°¯\²ÖÓLÅIÅogΖÎâ¨p˜ñ¶l“a­»Ç{.cDC?³€æIôs›!inÆžn«?¼±â(5ë_N¶r~ú?°,ÄøÆ·ßu^®Œa‡Ê×D4œ>‹ïAß¿KéWÖ¿?üÒ/Ëwç° ’ÀÓA_D û¼r„Q-ócÇ a¢¦6„ìµÃ:ÈÃ7qüU[÷¹×o0Û š#œ0ƒy3«ÓÛ<ô¡cbÁ/5Y8¨ÜÑŹÎÃØŠT‚£ý³ˆÍç'¼Ž8Üüó'.·!ê.›ím¨ûÌp«ïçç•ó ,—q àÖëDšËë5E yË9cä‘’Vµ÷QP–Ooµªr eV"ÜÈ·USuH+)?aÊP‰&çŠ^ÔŽä‘"õ‚¥Çè®æ~<—EP7O†µ°à#øÖÁi¦™pûök|8JdÅKNùhY{´w&…i"I¿’Äé¨é‡7ǽRÏ‚¡âŠÇK†61·ZÎÑ“î¹dz¦š6sô8N²¤¨Ý¡{¡³‡9\÷ž/Ý”",ŒéSi™OѤö”.rotHÝGæ‰ÈÕÕL¯ ÄFEÊÚ#±0¦—lƒNæ’üÊ2Nq’>j½[w0L¹ËgxÙcÑw¹EEŽ#vòÖ!ؤ¶ù‘"†‰ã†®Fj¤ xá^¸hà%ëœïŒ=7Á.)U\<ß$3°õ?j°º3Ó€»%¼o“þ± OR±QÿNz5$â¤/™sÉ­ÙÏ­HÕE¼wI2Ýå]u¶¤&ld›“]º™ðS^AÒ¾°†óµöªõª|Ÿ‹è“v~Ådÿ±.’ÀÝÁA$)Ñx…{´´+HÎ¥\Ùè,ˆÄ]„£æù Û†9x õe£‹?^$¢Š\ºùPð gŠý¼ô­ìU•=ˆ[ÞCx³AÝdÈè–¥O„…Ww§SP{Ñ –] zÙŒ–M50KÍíÒþœ¿8ÌEIÌe°¤kåʃðúùý,Lø´DOº´2z¥~,^ˆÊhm?Ì´"ÝóG“qøFîÔË(ÛT’Ÿúµ&U’ýþj¹ºŠú•?'áæñC\ÿkÖØ,%mͪÉH2kÞöt]ޯݼøÎ=’Ú›S0k§U„¥µ'¥ç—B‘ÏKÃÈeøÈó‘gdx<¢åÚ°§O%ó¦­…R¸_Rt¬â)“½vïFÎ}Åm©Êqù{í¢QÎiNÖ-ömöŸc µ¾u¶­}K†¹Íûî)Œ«®Æ(Å5‰÷¼t‹<â3 ùáK8Ö)\9ÜDsïÉâäO$äY™võü-ÞL¼xx »Ã÷‡ä4Záþ¯Ñ'.z›e]`\ê}ÚZºö7)›Ôý…k ó3Î- ãìx8°…*¾¹IÄÔ²˜ƒo âB Ôåo®õ4Œ©ö?$@5¥î3‘ÉLÂÁóÆ£6·ÈëŸÂ)Ïñ«)ËŽ'Ú`¿³òÊ<ÃíÍm¾ñó*Pf¾â饦‘¶ó‰yŽÛŒPÞ¡lµ‰yÞHëä¬q³fò3´Ü„þI‹!]rmñm†ŸÕÈã€D¿úÀëñ§•/#BŠ^钉у=¨;Ïw[—­´LÉ+¯xÝÎý³J1±B—Rõ»¬Ôàß§ŸrÔÝæÍ?{Žßëuø6.f‚ž]€ðæ¶è–ïüzô¨U×hððž?ü<0bã•?ã_Õºaù]ÁžŸÂ¥œûÓK¾Ó:é‚͸»Ý:FtV?ú®xòØ®‰îÿNM<¥*B:3mŸ2æ¬e­öÕ®Ö9f±ùv÷|wþF£2Æ) ­L¾:ÊÅf˾z&ëú0Ç^äŒÐH¯Ñvõ;/ »3çÓ OгÞqÔÞA€³5ZÕ‰TÁs¦–& B–'ÞÒºç“j÷°ÒéáÊ1õÏðÒpŒ†;ŒÕ³Häk÷>òXADLÚÏhXbÖdM.b  苌)ênØ2áì!o¡#·®‚ﺡ¹Cô ɾiR¸/ˆ-§—%LþBxRø¼áÃ6®+ñ"Ì<ô¦•ó¾¨úQq¨e½ÉWGënõ¶®îÿ4-ÚfMŸ *±Ê‘õ‘·°‚¹O d¸a«ÊضƒÈÀvÞs¦ÝÙ+›ø`E6+ãÎñ»}Sfdk\;y-8$=3£âYxVûÖ%†á9íšl'&µ§Qì”ÞÇ’L›û]_iL©|q™'êÛ‰ô*ä™OÔPéypn\gÚz }c!ÃÞÞ«íãLZé+~©x¨Û€^˜-"¨ãV¿À9?#ÓУ$'ØÏàù§XÀÏ%¼ö ò³ŸèsÕ V=ÊÏ"Å£›o¾.Kl]“!Ï~é\Ä Ž:à v÷M`Ù{=_E„‚@ó,ÿ,Ü4Jƒn¼±öâ§Ý…ùŽ>³€°›ÓFEƒ7#öj5ÌDl¦no%ÕïÂ8É&éÖM°‚vÓÃíâ¼ÐÊa:T¿$çËè~âÝÀ¤ïu/=ÏæàOÁ.²òÅ àÚaÜã™'væË2/H×k,˜úîY (¤*Ÿ¥êÜÞæ«®\ÖØíø t£æ?këµK]“aU*¾œÍQ‘Üåÿ ÃÚë&ë¤~»B#°¯M/êx‹™øi•ûç……¦ˆc_ÂÅFþ¿!Rp¯…Ôí£×}Dª¹w¾:Öë”Iƒc pšüS »¶¸óœbîf®Òµ¼!v!wDãεGL,X‡Ê5_>Çž»‡©%UWmÓ©6c¦Õe(Ha ]È-3Òñ.ù“z›èuæ•ö-9òÝê"~lG—ŒkL9p%_¶C¼å›pë¼Oíjèæ Í+mhWâ‘7]3žIÊÐMC;4§Ì'Ânü3‹ÓcHøìyL¸'(6X½©0ˆ(…þƒi¢à¢¥§P¡}¬DÝϰ6§s̼ÙöTK¤i <•£>[Û ð™ŽÍÒ1§tË¥mWs°hQ9ÂC_ŒáJX,vŽ>ç{%VÀ7ð®ÃdÙ’³P£W#¦’´ëÕ´­‹ë úDÖ4¬Ô{Á oz;.:*·üßT݈'þð[Û¼‘ä´þ`BÉ”?"ÅÁ3F¥*9PѬÖ߉ÎSVß*>~O‹Æ¾'eä¸HãúèxÇl‡7ð{ðÈ(bä,8Z&„uÍÚ:™I/ì¶LÆBO9D‡»Ž ©…Ø“¢üL]óò« AžÂ¡ç$Ç+׊Jû`¾¾<É™n`d%Ǧñ= kë ûTjÁ;9œ·A€¥‡iä¹çN/Û|x¾X´ŒN·xOwZÈûìÍð¥„xÂ+üyòMíŠgypæÏÒ4x½¸Øý‘°«OûFöŒpÚJ̽v••63ïǵ<Ÿ¶r#Ú'ÔÆd–ÙsæCsŸ‚M.]5ÐædEßëQï8ýð/Ã,ç̧ûzéà×Zœ©"]vÇa¬ƒîˈYáÉ {bIý¸uÛƒÍeãÿì¦LŒ¬VS­í³L%£0Øt_yÖVÃg÷ù¼[^>£ 5ë£Î’êbBx1ö¼‘K_.™Ð3Ù]Dt'Ì,ßÞ}@R’;<÷ÈcšëIoìB e¾iÆÓ«T«»ì&ß6É™ì·Õ¾ æXÑÙÄ Úô*aŠA.=1í©# \oó`4™PLž¸É¤ROòDÅv—½S¹³SBѵè(lÔx>ˆ;öêb>±L¯wЭ€¸ÛÙWtKµ' ,SòôO³o\[1ìû‚°Ú¬+bÞ­Záb™Nã"ZZŠkÜÙÜ;™—ãTãm™Ï˜w0 Äy¾„¿B¤æxq‡´è:oqÙm·Fï:>ä½<Á0¶êNÄÒ;ït¡Î#WlÝ´Ú„‚Wá Š‰šTÌÆ xï‡e'‚ݧ«yœL¨ÞZ4+¾ZšŠT%Ûîör+´}2­×¥å[X»:EÓ/±§ ûð[P×»p3wJm¸7{‘l•ZgB²Y6Ç›‰}oÙÏùˆzF"¹Læv“zvÀ·©¿ÂUðIÿë—¨m& %Õ«Ò*îZÃóF¹þÁkS ‰).AK`<µBx,ªÏéNÜöZÆ*îB¯4jv¬Ä¸ä®ü<±Aß«ÍÀÔÒWç;ô¾ùùgXŒ'Ò âÁ‡#¶ÚR¤¬Z­ƒ3HC±÷Ae‡-A¯ Þ¯nŠµÎ±VÌz.z£®1P`R:éCʾ{¶“&ñ9 ¡J BžŸì!âË7ÌöBà$)àCÅœN÷ "Tõå. · =Ë<ÖoF¹×‘=„ŠÆws? \GðÑlEMÂQ–—lµ­PÁ# X(å`njš=d °C ¨$ÙxX}¸šÍqDÉöç>|=’Sä‰`€§k®pµfS54Ëò ,vš“,Ðü0„h½)|Œ§æñŽ£üVŽŠ3`®q%½:m=XD!$áç«_~%.Q6·'ÚA>_ÝVn­(Åf²1ÃuˆÜ6øÜy'À­¹½M°Vz.ã62WòDuÊõí«<_`~³žY…Báw”9Àºˆ‰òG|0 Õq:ïAŠm¼ª(’¬›˜£©iàě݌ñM/ÕToœ=W"@C›Uª¹å¾©UÛè4÷B"‚(Õ4¤<Ñò¨—?Ž`ÖÉ`‡GÖS‚AÉc“ÉVݵy-±µË60=PòŠÉ°È;ëÆñà7±rè'X¢þó ,ÞèšÙ;€1O'8—[é´‘€†ü•7tŽSÍ/(úÁöÜÖž%¿Ë>'`øÛÚ[*Q-ñ"¿h±òݽã:¾Ã}1? ׳òÛvýq…DJÅÀBLÜ„²å--¤Ëý>áë16B$è¨Uºò°×¯‰E6ÕtXàEؽuùégÁUf¬<-6—„“•Œõé­ú„NEÔxu(Ÿ0éÛÇ ”X»–$-îøÑ«X¡ÝT>è ”™à–„JaLwgoÈ^Ti’‹}K DU¹l®ŸI/î%qàWïäwR&Æ·ÌàÌ `-Ó˜ÝEr…ù*m3Ù0£Sf.Ьh{«Lp|¤2—°Ôu©6Vä˜ÿ®ÙÍ|KZ{Ð^RÖÝS~XƒÁcn^±-u‘HþN¯öpÄ¥ÎÕå ro{$‚X½/ÐÃÑ6QI<Ü~‹4±êç†ÊòU«îVVÚ‹´?e¾—~rÖ{8¼ðoˆëxÃ<Ón¥à†Þ~/ºY5.ÓUEbËFãx0?\ŠGdŠêiFüª~â §RÌYN)0ý¼$¹¶ÎŠº}ïhìÖ5çç}æÓѦ£mä·gkÌð],¾†Ù“áhP)'î<×&B@µ™„€6ï+ÛØÔF§Â–ŹÀ÷€Ò`ðµ°Çêû™Òfî6´ªˆ£‹½y³:æp+OL¿¦FÁ8º*<ïpSÆ–´ìÓ)RsÅ_Ïh °¶³i<‡©N³Yk[·ÒJMëÐt çÎÔIVªm‰ÂqDXÚáÐ>–6Bz_ï ê$’ï‰% ±D›¹Ù¨UžÑ³³æ øÎÉ ñ*_û;–×ei(`»=Ñݲ斦u1@q¼vB691ËÙ¨…ôë_Q?«‚Ï^îѼJ¯“9âÔ iwÓ¼ÌhF¡œ»£r¢€HÌêÙF\pŠQQ-©ñ™ BÕva9á_h$IC 2­>XíáQq› †÷ ~ÇZV»´LºüÆQ5ÜkIwàå“^H¹ºÃC"A¬ÎžqJfózýȶ²ÑÌë)VnÄÅî6hi u^DwúÛum öÄü>º{k‚Üé7ýÇ`ï¬Ì³­‹Ò1gN§©¢Çàš4Kº\Æ!i9ûísX2´¼ó‹½,¾ºÀ—[÷Ü–k²2É|¾8ªÃøçÑs!«>P-µ/Ê›uOaÐs'\9Hå$m‡ι՟²aŠ´Sýsƒ`1_ô/»á´\è]«¿|§¤­e“ªá×%J-¼Ÿ.QçåzÒPü¡-ÈÚÿF "àmà³*ô¹&×äy¡<[ìÍûÅš8‡ûtæ~„9%íÆ‚ Òæš/,—¾65«±Ãf!¤ã(ªð§ °fx»Ë!œŽÖ»z[x¼ë‹Á’¢Î=FW B0o2-ƒ¿ÂL¾²ÜzÍßqâú„ÉϲMÜ]¸Î¬¯[&ÿæEºÂzkðÓ¤WñZÇW¥Ø#ê ø„0¸uŒIí·xÍýp>¨®uv2´ÚbW´Þ9RžEøÜ¡¹·4j–\ÊÉrÕ£ÚB 4EAæ½”&íÕÛ¥áf£ôw̶q¥J6‹udC˃ƒ$Ðæ ª-¡dT Yèt)äúcÏÍZT²wÉVÙ¯ùæòÓ =îVC#òF5õÓö T ,m~6W`@ºu²8´MócÌ'Å'ž^CI[¦"L³f©¢øUêJýC´¨Äb?VjÓéWì&ñÝ—úº¦ž‘ï@v¼“kWÞ§Í Äï F‰mu º œU†'L/ã]–-ö,áÚpùŒkägp±FÌ”&ÌÝ<ú~/˶;ÔÇ ¿ÇÛ¿Áÿþ1yÒÊ» ¼]\ôåO>NE îºP6Vnª·”4M¥„éªö–tÈó#¦f½Ó_­SAeZ¡DYî­v`®¥íØ5}"ûê—iÿDX܄ӖXíguØ6·< ‹UÇäÈ ½ÎL¢Š£÷™ú+M‡!T=Šzîl±r{K°BMüÂD'/>ìÔ¢¢Ô“â¦cë–çããÎ2îSo©$ݲˆLE¤ÍÎÀÚ9,7¥“ÿ=Ì÷ïwÁÆ/‡/Œù„]3Ÿ3Mq ¿¾ƒ»L¬kì9”O5é÷½mä´ý²Ñe8Œ¶,NznÁÉ~—½€¡³.å0\g@Á÷}З¦1ÜÓ×þ}»qé£MrÅ!k°£yÇÝW3»þm4Ñ’¤|kz¦}®Mãl=ÍeËó£ÄV–tÑŸàIzZ¾dùX_ ܉Û& {¶k}¾îbÇ£—WÛ‰/Ar?YÄH|zä^cº@¶Ÿp»R£Ö‡H˨EØ‘|üFæ5f[£¸djÉZ›ÔR­ÃܹçJÏïÇç$ o,cÇèØ Öcp» ?‘£cʱ %zX%èüŒ~Ÿ'í4ã™Sçt*´p šÕª&¨‰Tù5o7ý- ~¢¦§Õ–åXâ}ßþ«cŒN$UH釜àýOš½|Nñ¦Tý.S;.6ê2}ýK$ýÊãF-ò§i{3ÍÒÂk5/½º £ Á¯¤Hñn¡áÑË©²;G©ÒX‡ª  ææ%wÉí]º·âtlìÓ`‘`´åqÇ/ b˜i¶I-ÓjUúo³at#‰gê>ç)ºúÜd‹ö™’}iCŽ9ð ¥åb¤¥q%à/è<<Õ+?{ûó3輫ÿ`Ö S8üâùÁ«é­Ñ 2"sÏ £ÇCN¯ÂÓBç"RRÊÇ›«ñƒ<>†Ó+8ÖÄËrS„ïzÖÙDön}ŒUs`Jfªóû;¥cÙ'Ÿ'òÕ…êÉ•i.î)¸-(pÓ«½3XkÑi¼DJÄ29-Hx÷¨Žás‡ÁòÞD̃+/4/¡[Bv‰ùô&HÑ7u9eÅÃã3ît#¹ôœ›ù¬GLëQö!Z¿7TÝŸ‰¾=ÓÝl¶_õÍN°\„™ Ä5¢…xUÕ¾GaüYRNPQÔ«9zšË2“ÍqêR“æÒ5±:á»Á‡Æ@È>Û—žžÓhÌͺ!ªV:¥\/5m”ñ‡2ßFV呪Wg$$ lr@#’Y‚Ò5†*O?n[|t¸†µ8`ÿ)[=Œ–Ué÷å1òQ{áE†e)ŸÂ´ÜõjœŽÒ½¦éÁ.>Ñ~E–a‹aÐЃ U>3Ïé°>UC–©M$nã™ êP‡ƒYÇêŸëÄQˆ ©í0™oL‚¥‘8îæ³“æ’;ZæïV?´‡ýh–UšQ—ïs“Þ-×êÂæÈYGwº:šºh•VÚyÌÒÞÎ5µÖæ“n’‰{‚rQ:UªÔ8ÆL|èÀŽ»xƒÑåÙmyò%–ø¦S-Úî7-œ@vrðÌÑUŠ 0{ÄÞž ˆ]FnfÈêÈ¢§ªœ3ü@g†x© “2#M„owäü—R']‡â¡Ø‘Z4ÏÿH±]VÑ¿eäýÆÖXð@Áãä;dÓ·†ÏN}M›ª†’vè)fO{B¥N÷=ðü£œFVšH|;‡B®ØóS›ߥ«Oüý“ñ Õ.éœã#0ùÔE!{s>æx–¬'“n~Ì8Œ£÷´¢© ºŸÊ^Î$]Ý-“21ÿRPûÃ/ˆ¤/|–™î÷×RÚxL‘t²`­†»Š’×éd®=‰ŒF(‚[a–=º<ãyöpíw˜„Já`s@ÿµœ­Q ñm–ÍJ ìlÀ1‹ Ž9´ekÖ ñ¤Úµw5,‰ïT柲waØŠ„ŠÓïvB¢›ü ïñ›ä0Z‚ÊEDàÔ8?b\ê§=u „?~Ú£2›ÊUf '’—Í‹òy†~lžë96(-ÞØ³“i›g^œ !6ï&æç˜Y;%Øø¤®¸÷åÞË9/2 :ëS~›{^`ëW"P{ØZt†y‘<´Môs~k_Ù8€¸È‹N¿±<;ˆXjwl'7ÃWG6Í«©s(ŸBÑNªuF¾ôq‚ìÌј¦Ìäñ‹ìJt@d:H§"`I0ïp®Ø+ã"»À®”`¾ÒñYÄëÞ}qÏ”ÉÚxRŸ•v¨ò¼,–O,u –TtOãŪ¥¥?Ï)þ¯D 6ºÞ%±žþøÊrâE#0:àj8ØHwˆ‰ÆÚ|) ù¾™ëü`°nâ‹ìáUVÊ¥+#²ShžLË/Kcá@Ô"ãu-C©€;»$9"1 é¾Ñ/Ãíe°ªä®±Ø¢SÉ0¥dÅ62ÛFƒ2ÃbÔó,‰ÃÑŠrøMÞÔèÞü„WÉ–¶@Â"mR7£§4B-@pl—h›ÞÙ»zX"sJ tœ.DÿYb!† ó/“pÁ¨*’õ´L–¥)ä…öŪ±x‘¦é¬#Içæªª3éi†÷昖vI¯þ°öU¸}‘é›`­K[ˆUS Lñ¡Ê±ƒàߨ:ùjxçWÆI#¹5ºœw NêÓ%m/’*æ–°:¨IŸúÜרˆKå°ú0™–q’ò{N!¬WÂÀ% <~1†.îåR¨W€C=`tôá4õa(IS?‡Ó ÿD[î+ŽÏ!k§$·‡oh¦N<Ûkž³ö‘­ZQ^í ¼Kž)SÅ0›H ÿ}þÕA³yåà°SþMù9#¿ŽárIê<«ý1(Í>Òc åphëBªýЊ|©Áƒ½P©Ì´þ·¾jüyibšõ¦}éýHé»ÉDÐÉmWù‡64÷©%ÁtÀŽá4`Å8º}òW¿:§w&\<é9û¬g‡]G5,‘†jzù‹9…»ô6oE¢Ë_Î$*¹ìºA®1©rÃûö'á«+‰Fû ³}Õ àùx^°ß[$¢…¤ ¸[×"ÈmÍÀÊkVóýÒóÃi½’¸eÞ(iŠ¿HÅx7ýµ‡=¿§è0»Ú-2…$ì!¢¸êHoºÕ~¼7¾¢vBvýôÔ†>û|̹¡ +s´‡Ü+z÷pÀmÏW"HLcK‘+îW)ÍOèÀ¶…±•óð@ÄÚ…á g^ÕæamgTDØ¥Aõ%x"RÙ!Z¢aN¥Í½Õ¸ÂÇJ±KîÖLõ):úJLJæ‘X$š~aõÈÙËi¹iÚåÏ]·«ul¸ó:îfQ.)/"“_ôyPQüCYôc#Q$ê+1V&À&{ß¿5êõ*Ž•¯ÙÐ$iìô*­÷Ÿ<ú¡œ iÔ•§¦ß²ãYë,Â:zØEËñ®&.îÌ›dáoI€Ây{Ä¥bOég@rAÁކ:š´m ªX3!ö¹yúO4q4,5W:®Ôts€üü§m õ®AçÂôÚ ü5œ\£ìØëA‘ShîÊk,ÿ’’Œkš;ãË«U‹6£„5ß±*_­ ÔlÉi'°<¾¶1h-<~c‡P÷ È#é4FsÚýŸ>…÷T™eœF¼Ú1¬íYIJMDqhŜт¬ãˆ€p2Œ²š¤!nŠÂoåõÝ1­ùø÷#3cOEôjm@wù¢ [§ @Á‰90å”>M~J§ã|&MæHC6—NåM—8(d6BÓ/>IÜÏ¥<Óèðø“›‚3Õ1–ô Aìo=aD™ÿ%¾­.¥®÷b°<)ò‚•Q¿¿K ¾ºˆ¹ùѯˆ¿â9ûCÁvÄuýP©J·%ÿ¿ ¬¨ý—&’ñº²'¹:”Å©mü3bC±9Ë RŸøzs“ŒídbWü¥ß”Ҹξ0©G! Ò)Æü-Ûž¾uf2]Gàõ¾ŒÓÒ—¥(]¯”½jFðzφLÅ¥N3í%=±¡ì-©Ç¥ª„“gøæÞSƒÉ4’Ÿ@Í›HS¿Žø ”fLïÍf ‹×6½åoCI´×ð µ{wçœ]Нp'Œ„-\/ m èù¥oËSÚCÓœv\é²"ÍJó‹’ ïŸØþ¦Zâ5Ñý;\&©§%—`椬”K}¯®ç¨Šèx°ex3—¬Ø ÉúJëÍÁµï%ÕÑc ~Y]w=Cí¥îPäÇMo݆‡¨Öæ)çI9½4 ‡äè+鋟[3gÍ5t~úÇ£üÇÇËo˜à €¬wAùâáÝ»úšo´ž3µ™põã-æsO¨q—C£¹ßE5u‚"W?'[P»h‹‰®v Óê|!ß9äµ špHÀLÿ˰vžñ§Å¢›ÄPo}ŽßÊÛDÉ®ìäƒAÍM÷"ýØ`¹ÆU’]“t¨–‚€LM#a {¢7öìúÖ3‰¦ KÖ·|ù>‰æƒ%äBµP”(­°™¶T8”^h^(azþöLƒ6ìÉc“–úå‘2ÿ„UˆÞâ”À~H¾iîMF52™hŒ5šÅ'¶Dà2ÃÈè:v?zõ’vÐé²²bõAò )nÛЛ׊BoƸæêÎŽYÐJA.†‹𻦮½‡Ö¨ø8Ý%±MÕ,}UÂø‡/¸«Ö‰Ê4–÷žMz‚ázNh_Ý÷ê¨W[\¢¬Ôì£n„n÷§øÓý0Øå_W4ϲ¹=ªch~ª-êF€/Z‘[÷ p‚û/ ´ô¨Ë¬½þ¯*SAŒ}tù}Ҝת'7¨ëŸ÷$؃/çûCâ oÍ7kv#noÉIàÂ' ËkÏ;ŸÅÊ|E$^ýŠ6t`+«=û¬FJŠ çÁ{–‰­Ãy‰zCV'XÏäü´x"¯ ?Ut%K°_ ’F0èpí«Ùõ„òÝ׬Ñrf@@ªÉsÛÈW Ÿ+%Á[+ñ¸ê™Òï\Úu)é-L+@àíDe ·pââ‡Â×¼IóvJ¾†Iy=z©6 ;x^ÓØ"bi³æž#‘ÉÚÖöeI¶dG^¶hmPçn5 ¿{ê:Ç3>q7”ŸÙ†3ÂD«óu㕤|ëy•ö #©ËhžegUо¼"|ʓǔ‰JáOøº äü§•——çý‹ç}ÐÙGI³£uo‡ú\°öFƒFÅKå§K 8ÒʆX?ªu+&PМ÷™i‹ˆ ë·Ä=ì ÛÓá‘‚œcž7k©ûNú×UºéÄxq–oý»Ú˯ÿ/Ýñ¥À«•¿þ)É–0±Ü1ŽðÏ*ìJÞ]L¥å+Q•ZÔ®¯Xù7(žÅMtüáz U_w8)Mvôâ8ˆàìöåYRœÞ ðUQyžÆHz´'­ÇÔ`¥ðÁÑ W/ÓfIÖïq׬ڥP¸Ã{e!Ý^À¨ªX'XP“uÊ»$ôúéíWHàça÷î— ‰ÓŠ f‘ó‘‚*ŒÚ¸¤â¹Ài~¥AÀ‘ý(–ÙJÏNš#—Zݲa`åÒŒN•óÎu1UKì:Z\0GïÆ·AµG"@EeF?|éfÖœ_á‘Ü‚4oJôiQ£”©÷½ôãСk£Þ ˆRvÉ;E´Û"ša§hÖüqÆ.9 \›ßùðR§‡ ÐXps"Ê]³áøf&×Äaþg¹‡à ÿë[-f‡,MQWÊþÞ}ˆèÁñ)£ª³÷–Féº |WJTÄ7[gôå)0Y\ýTçÉã‚@[ÌSé+~Ù艌ú!`œ5à nÔ’éuq1µýؼ°Ïzq¹ºÖ¿í‘›½TÖ²àxo¼»ÛÃ'Lú;*Fúpûœ&^ǹ CVÒRõ÷1áñhøPœÚ›(üDÙ p9E»éVì¢ê5>SU²,QA3#¼QÊ®+¼„Ÿ¨Ð¨õf ù˜`„ñMêïZ¼Ïòh]±< Ò£Ê÷™žÿX’…Q”d­ßzHzåÍ„9証û; ¶Mdè>\SÌ}:(ΰzÚP8õ /ROܨ‘¸?êSTÏÀDNŒ¼ôiq³Qc¢cE$᥄ŠLN§Td»H=k^õ°Bݤ×Õ¸BVS•ß]8¯{ÓýOkg%§¯~˜â/º®ÉåË<:¶ý¢á­‡”=8$›˜’_«˜Æsö…ÚÁØÏg"¡’ˆw0ž-C‚ÝlT¹Œøôšw=³¶‚lSfë¶±YZ­XdðU&¤âŸ«mÖ1ó]³?l飶@9‘‡Êfç+…/8åÎm¨£d6ç!ÿÑ5@0é,é¨A/FIÎ_©©Bþj{iYá†Í V4ƒ>mCîEÐ¥–µy9$%+˵ Cm!ð9†I™p“¤›ô ¶bQµANÖ% „¿ä§Ãæ¬üúÙs_UÇ$cÒëÔrG· ,£zöZí® }Ã:ÑÒB–|ÀÕä4Æ-U™rXã2p“—Ad˜lD£¾ ™à@ƒûÐ+òãV'·`Ä&J¸dûENñÌâ'¹?±›U)4»vý4ŸÈµ7=JÃ`Ó<ðm×µhúñÂ2?½‚“~Þ//”“KJ´û1>;¡É°~O(c¦^”Ðñ;pd©íö+/¾ùx×-@"I|_4bYwþröB> PÛ™cè‘…P1RÂBì^ºòÉ0KayåµCæâOf*ÂfîÐû®u½'#0xNRS³Ý3Ö(I¿÷s¡ZC6[ •Ê)3ã±ý­W"‚ g xߌœAƒQzZmÐ9]ï/ÏŠ?ˆ£ž°o€uEn³fS¾J¢\MJÊøåÛÝN(°mûŸ2q™úUеɔAuµØûÛ¼ª.,/žÈ,;”â Þ^Òvµú·¾áâpè*®/ê'-ÿ#Õ·i9ðZ²pˆØ¤¼ H;]¸ÃŠŸ#¸Á5™SŒ+jGÙñ#JUÖós߽撼~RvxNÄ‘¸¦,™2‚yÙ*Œ9žYä@aÑÀá¾@¥‡îe£zÍG¦€Jc`# º”ã]ÿ„D#ª(({ øí©#ýîYᕎžQ§*²„ûk­ªð •!í¦Ëµ©™â/.|úÖ6ÅƒÅæËFyOc%þ@ÝÓvzP—ÕŸ3¸‘wÑE]ªïz0JÄ?KìÔptt]Bÿw¿Š1´«8ú¯ZV¶:öÚÐÞöm£4uÔAáû¢I?ÍÅTô»8´@y2P›0m*¬ÂFAØ–ýÝ¢x¢)‘^œ|ÀDÀ`Ñ\½ ïÿlÍU´ÎïsýÖÄÖLæÔ¢é³h Òøs‡(å*.ßK>¥)èR>§éÏ? U)Ͻ4+G79 ‹Í–…ëàY.ÀZ·Æ VçˆlœËàBƒô*â…Ž±ÌŒÒÜ~°ˆ¾…Aпíh´Šo–T ú\1 :ŸÇ}s9ÿ“‚ÔBm˜-Ô8ÐKc€’,/çÆïé;»²nQƒ:ê«^ÿ†9òá õ¹Êl³¥në;K¶V¦Ÿ¥r^Uÿ·ÒïÚËàÞfÏÑþrÊFSζa±!7ßÓ/~§š#Z¬Ëú c(5†5yü¼€=Ýñ2‰X½”ó%haKbÀ‚„™°ÆÛä) âF¨qã[Ãÿ¦…)¡Õ³úCä8ÈíI…ñ3hJ NÄ[óè_¬’ªÐ~'P5´Ü¼~/—dG8ñ«|K ðD8ÌŸþ±4ëï $Rï~×»¬6ò¿mškîÐÈx ªýþØ)‚§Òªztâ,avÜÎõ›ä_ã˜Zó ·Y cæ'°†žrº&¾*Øúv´!WÝ0jI&‡Ýʃ‹%âh„áÑÁTÔ–ž$ ËËÚwÔјTm6)®pÕ£aYy ¿ 9ÎÉ“tê‡xˆs~«/+¶Ç“…¥“›â2×Á|70ÍßÄ Äjν‚÷"IaBöO¡ SÉç§1Í\ñ…™Õ›RØ#ýÛÞ­ }ÝDBþ0šÿ¡Ùã°xݪNpä€;{x•Õdq EWwaçÒÓ­Ûh÷ö6Ýlz#`MDu[œ€ÏÈçAØ’ÉDs¥†ÒÆüOù–\”ìÿ¤ÒûŠÞ0%=ónàlÑLö )&<–"F-Ø#þ«r`NŠûš¥`@†h‡mšè¬_€Ú"…÷eÝDs³C^ÜV‹S-˜0Ó¦õÖ—}S ¬ ‘yÏ}ewùVî…'uPî/†[¶}/ ;pÅÌûÑy§;X­}g‚–7iŽ­ç2Œ˜@Ô|BÞ©º}.ž¥,¢±ÄL÷pü£R] ý”»ó÷âr½rÆ;þ¾EðloKZZ@ù ÀòSе‘ÒzÈš @Hã5ÆQˆž×-¦¦M0¦;ýãõM•Ù:¤ªöZ ¢‘¾bYöXž·Œ€EëíÎf€½W>hÏ‹£½h’I„¥Û¡©¿/= v5èQŸ+½ïʯ•ÊÖDþ°K!¬ÀÏâÌi{õRš$'F¥4º¢Ô—ñ–žî±Ž5 [Qñð#£8 L¹Þ (Ù6xº÷EüÒ’yu6gñxj˜ÈTª/9>˜CœÕÞÚu_’&<òªmø9E š` D{ß{×RmTè„ü,v–T•…žN Y‹2·ZV¹&G$uÞŸbiþ²t±¶èµi”›²½&eûë×·Ëš˜‹Ël<;ÖÑíK?¼j¯ ¦’,±¶&ßBÁX:ý.| ¸JyÒÞòný›tñZ*m:-fÃâ9Jú®@l×7 wj.®»’¬·S@Aµûˆ~ýhó¤h©Šìi˜!;<Ö]ØÇóE–ÓXâmDI˜49ØàÖÅÍ{@»·ÄwͼPx$­všN*Ia¢s}öà9.M/ôÇ€³N¶xv¸·_ ÁKü`DN[}ÛʕPÂ"OÏD¾ HÕ×H°IXÉZ"Oͼ:ä°mÕ+£õæT÷òE²MÜâ=(2˜G$ tO—ü‘лë̳ÀvÎÉÓ³Ê/‰9¯¦%‘Ëw•[ÁóIšu:jtQÎjR0-2Ó`¾ž¡pAÞiÛPóRF@äðŒúv4Pʯ 튱qã&]˜J‘ÂgE錙¸)G-ÞÄ ïQÛlåqHY^œ ‘ý'ãz3A[-uz³Ïâm{°–ü-@ø‹¼ë/¿ÚÕaÆt æ…Á —ç"‘‡²]-ÕØá™' ·B\?‚ô]ÈçàÛžð¹Ÿru~x›ncs©"\jø²ØU &¤R°Ÿh°Rz€T¼=íàÝa:bऀ”k÷:׉Ãgùb›äÈÙšÎ;–¾‘'ñ;.4ü*´ë†£rÜ»§2Eá÷£Î}”ô-pîCˆjt—Eu‹|žÁ‡¦%°òuS²tñBϭˤδ¥ˆ ‚öÚJòôbîÍÔ8ÐËÅíÀÚps†nC鎚Gˆ˜Ï=ã_ÖA½îSœ0YÛ ]íLÓôQœ®íçjRgúÇTž u»n¡·sdÒ§·ÙŽ‹?õúõ*d·™#ã˜O±a–ÿÇó‹aд…ß58#úŠºo[LXr˜À):%e^ÀÔ1=½MÚ1maЮ%F'ã).zr˜ýÔÿ-ÄÌW¥LMH©^ÕrÖ†S±‘C‰’˜¿¡…’¥ð‡Z{ùÖ&K šº6òõžïð”ÿ Lb"i[Ÿ}yíúÞ?ðjzÁ¦G¸¨ %¡­<ïeH`ÞbbKˆ#¦÷Xÿ7Ø«CÎ÷Û ©€XÙÒÉèc×G%0œD¨#ä£Ò™$œ éÏ`Ó´ßÝqNwÉR]0²'ÕðƒBÑ˧‹mšë|iºŸÁ“fFÏåÛÊHGå*O@ð M¨XXv‡?ÿ¶AötQÍ•Kv¦Hõˆ®>çÛÀ…X1C3‹(RÓ±–+÷‚õ­z!<#Ý‚Pf:¦SCZ2Ër ;•™<â4„µ=YSJN5“… BjG8CX–Àyú„mÈ?:¹AR”ó\î$Ãkkß¼N•â)…;\ñÚòlõÀúüI~^9K¤SŸÓ!FÔ †Ë´Áï jx“†"¢Â’HWÅ-dœaÓ á3SkìA>bÙÐj@=‡ÿc]“>›·Û:f#ˆ_Ù'ÆÁ´/á ÚüIMOmÔGu ;v¿µ8BÅOÍ9—tûѿڭ:É.Xáó%ŸXp8Y¤Áõ%ß’™yI—GW3aë½ Hç`¡ÁŬgÇìGàÝ-¾|å5ÆLzÉÖ$‰†V&£ÆÖÐÃ4t:×ÖŒõ¼½n»ÊÄœu»:êdB•/æRälD£ï±‹OLà}JÔWó4ïÀÇ<ߨ)Ø E2iÒËÎ"[ÙÅ •Hä 3py$qVߢMVe–Îf’—Þ.vÍy4©Ëׯ1ú ?.nk?ãû¦•áËÈ׿.išxx jâ‰ù½bèPKXBƒ [CJynÛ•DoI¯÷=0ªEõÖt Dº\xÚø–DñɆ .FN:îQ”_UÔÀIë—µ¨‰Y=Gøêëæ:‹ ËæMëÍyÔÇÓéâ>÷cvÚ`uóÓ ç†.7ýgq–e„нm¹‰¼èW.?Ø.o.Ó'È#£ÆÝ˜¶ï³¸ØwËL?9r¹^.«­^l…k ™,¼ÌHÌŸ­9uÄ÷X‚&r?g¯²ÜŸÎF9è™T èj1³Yg;Ezù šw[öûw4Ó˜rƒºÑàL)æã¼ñÝa>pû|ø~'p…•ZHªð‘GÿÐÍ*‚Eõ=‚N†¨t½ëé·øÓŒTXøž#1!ýq(>/Gk¡óST•“ùûUãíR‹qÿ¬Âº˜²¤þ¢ÙÁä-Û]ªnƒ…#7*ú‰”4ö„gÑß÷8|ƒ ?Ží¢Â÷÷ÕýʦzÁ<Úçóh8yqíI?,¦Àv”­P·lz¨P©UÇ6­q™pÀ—Á¯0Úéîºô¦Ó¥Bá`61,§¡'ªËÉZ½¿«T{£”yS†ý”ù×YQÆ´¯³'$)†,–˜ˆ—-,‡è›Ý"ÁDJ­YÖ,#œDÑM¦*Ëê ˆæ(³Ï2ÛÏLSJ`šK­Hpu£!”ˆ±ñY(:Ÿ@󇌬¢àæ-Q¯Ê]´$bc© {u0¥7{kæã.RÌ“­bŽÜZŤNÃö›LAÏŠ =4ãÇ­pèµ£ó^z>žÑ+¬D·=…Ï–ý³sƒBó;µ·¹¯ãù0Û³ aÞ-©koóúHÌŠ'áýª¹k©O( Rϼkä^Á/šÀóÔ®æ|Q€A"wØÕoþ¤²>!bOÈ Ü7Žf©´ž-g33Öhyw¿ƒGETìÇ Æw9‘¾d)ê²y6±?f¡Õж©Å•xü<û–(Ÿ6Ið÷*FQë‰+Æ¢bÍVq®õëGHhédðx1Ê]zßn1À­QÏ•âå=šenžŽ²–͵é+GVêH sOn-ÏSH)«qþD¼Neo³=â—Å V›ß´t#æ1&ÔFÀ`ð&â_)-®\2ëYÉpž|˜Ëµå˜äHEwlØ¢Âyæƒv™\X«ïzÍâøý¢øW°;:æ2A ð93ˆíó̘éM« l¾ An A"2îN)©ð¯Òu”¿T½—ëVe÷\ÉÊì]ø>wºöFð1”ºŽžÜ¨ú:¢Ð–­Za”òóÝ2PسU½UTîU®ê¢óˆí¥}ßEHF%¼¾¹y1ˆE”ï&›i¥.}KRg¡~«¿:jœÏEK6儱ˆâìirvGø’Ú-HWuÈHs>"J®\Ö¶„’¬æZÐRÀZïòÁÆÿ®˜ EÍi[pgBÔiaÓÜ;ûáVð “tž‰Ë3<óÅqŒÄÅa'¯EÒ¾µ’ÝBB~uºdÅÍL4F‡Á9(QҬؓ!ùÙÞeÃtñ’Ÿ–Ù°ëõqË"uÑIáxáu°-U¬²C8»üˆ›êÊ”]áK@aNÚ¶mêé¶ ±áý6ÙkÜóôŽÎ¼'ý×Ë’U{N'Ÿ ¼¶ö¨žf+Y…³X…cÛaîÿ5$J„[q²;!~ÊEk_V9uÁ|˜[M’Là2$mÁ t_§ºXÛ¿éThÛm¼?¨¼ø™$“£µœÑ>jë@Žtdö±n<:úJá™2ò58«iÒ½/AG0ÆåÞ:þ¨°~pØ>ª\¶æÄ¦ƒü­”‘¾ISÚ‹€øÏ}ðn*#{(BßFLXå«kô@†úè¼MèÀUŒ³P !´C'–ö¢Fyxp-”«SöØÇø;åËn@¼wrÞÖèyµ —_¿œ®ü{³–ÿêbi* ­wÉ`D0óÕØJNU¹Eh™º·±C ۙ¹–6}î­³I0ß®Ï[«”Ú Ò:Âá±™†Ø)oÁßÏWàªÓ˜#næ"¾ÑÐûEªBò†ÊbíýÅâÜD Vº÷Û¿SÜr¬Éð‚‰ü[øƒ10ä ×~ÌOCú Z·)(?뤳GCæ–åhÊoÑcåÆˆŒÇæ2Z«!˜swðñR\úŸµ6 GuzD¡ÁúÞc:uå5·°F5ÔƒŸîƒSN³&švÝÕ—ž)_Ú*,°(Ïäikf@‚­Ë6¿Ý w 6Qu€äë–ŽmâÃTNO&1ð.2lÞåÚDÆ?¸Ši3ÙƒûÜÃîDÍÅÍ¡~½ØÂ€›ÑV¤ zYS=õþFyÀB=ìøÍk¡ôF‘ѧT×ÜXÂ/cø>¬´/ͲY¦ÝCÄÂV4¼—(6Ï!>–b„d»C>3íyh¯ƒP+dl©®t³Áš-DZ5(GeÒR^ü¾¿ÆÀ1uÚö˜]Èp$BlÌOšOÚ:îÖ BSP¬0œjÈÅwÀ9ý@€¦2ž647úzû "{6'*5'kÛ%³qH ®òž†í L%£°™ÐHYDØ endstream endobj 2831 0 obj << /Length1 1386 /Length2 6039 /Length3 0 /Length 6990 /Filter /FlateDecode >> stream xÚxTSÛº5Ò¤#H7 ½& ½wÞAjHB‚$t^¥7éJé]©Ò¤(]zQA^ôxî½çþÿìõ}ókk͹÷ád30T‚¢`ê($F$”¨è[‚€ PT!áä4c°¿í$œf04…”þ„Š ŒÁÚTÁ,P…ÜóD@¢¸4HBˆRQÒU° ÐÜC!ahN”»¯ÜɃ­ó÷%€ IIIü(¹Á<à0  Æ8Ãܰ!`ÀÃ0¾ÿHÁ#ëŒÁ¸K {{{ ÝÐB('y^€7ã 0‚¡a^0(à×È=°ìÏhB$œg8ú/‡1Êã ö€°C¢±!žH(Ì€­0ÖÒè»Ãuþþl$úWº?Ñ¿Á‘¿ƒÁÊÍŒô…#Žp  ¯®#„ñÁÀHè/ FaãÁ^`8ì€ün PW2€±þ™ ñ€»cÐBh8â׌¿Ò`·Y UA¹¹Á4ɯþTá0vß}…ÿ®+åôÿ{åGBõt6EÂx´Tÿ`°&’Ûœ`€PJ\\ €=À| ο ˜øºÃ~;›±3ú»£ÜŽØ1`pGö‡Ä ö‚0ž°@ÿÿtüsE pàs‚#Iþk†9þµÆž¿Ü`ÄÒþúüëÊË0( ‰ðý7ü÷ ›ªiÝ·4çÿ3ò¿œÊÊ(€¿ ˆ@PJ@â 1@à?ó€áúøX-¤# õW»Ø}ú»e¯?àù#^À?sé¡°Ì…xþMtk ‚ýýŸéþ;äÿÇò_YþW¢ÿwGêžÄo?Ï_€ÿÇvƒ#|ÿ °ÌõÄ`U ‹ÂjùßPsØ_ÒÕ…AážnÿíÕ€±jPB:a-º+¼û—ŽV‡ûÀ p Äù/Öüe7ý¥7 3@¡á¿î0Ø( ð¿|X‘A\±w4–š¿]0¬†þYW AA‰MDLöðû’`Ï»øƒ°ª„Â|~“ ,„Da°!ìŒG”ɯƒƒÑØ™áhWì98ÿr’ü£ÄÓë¶ßLÀVÿ{ý[Ú0˜ B2?‹‚È„»¼ï8¯UbòüæPæ¬âœgîÕˆ" zñéXõ]ï¯t§Q¥eg–:¸ Mq„ÃDm¿LПÛÇg'ƒDlÒå’ƒŸž*‹ XÝGÍ.dÓ4Œœ4Zxzl.Ëž#w„NžöÃ+-n§"7Z^w ÷Dí£8¾²ÐN…$Ytfo÷m%7k‰¾¥2ãSÇÔi¿CuÛñ&æ'Näã´wiÈÜW”š›`O4¥(4¡zg¢³Ž“©Gl)¡ð†ô {x1¢²)Q¬MåãmŒ©ÕX§ã¸…È£çcÓñ7RÕ™ÌݵwÛF½=÷”UÔÜsR¢«ÕºÁ\Rþø¤ÑfAªd'’Ôdà‰ÆP‘Y¤޳cÉBA{®hÛŠãQK,Uýw ÷ýÓ^æ4muÌÂ÷ý gxÅ¡ê’?¼ D?|¶Ðí«„ê®ûúp{ÝÆü“j¨n+A´åݥңȪ"ËÄ™7Ejû:—"«v"­7ª[ËQšéþ$ [>S 7‡¶¸»;<ÚQdç§ßÍõn³e«¥–ìfµ&NãÿàJ[ÍDÜV¿¢³Ò¡Â5r=gUÏw8(©äB©œÛJŠß÷ð…3{9Î ÂøÇésu·woמ!˜!|‹Ñì_«mƒŒª¾ØT¸E®Q¾…—†kWèM%°i݈{1ýâÇ:ý‰ÕO;Ì´¹LV÷›ƒÌAOEž;¾7¥4Ó7LŸäú¬žœ‚E?«—!ðÒ»Ž$}𫘟MaR4Í•ÊzªWdêÙÌ'~’©´ ß 3CÕ?~ïÕ–¿“¢ÐSŸv[&-·Nn䃼@øÀjie—5{å·¦ôì[“F»×½ŒTÒçŠñs UIȧíòéFr):]©éâëJZ綸õYÞóÙ4%P­!M?WÈ™h˜Ï$ÖØ¡ãaS­zGí±òQ4cé×QËšŽÂ]á¯W‰ãV…­?æX[t8õ ·³4Ã"S©e ¸î=yä•<#0ÀÑÀîlZª«p\¿­°œêÎ7.áEþî–Ü{:pUƒ"Uñ™^Š˜í¾hzŒÉçzIǶH£¯aITX«>oxYPbúË'yq¸é³ï)F~OiŽŽ7ý£&l©T?Ë®ùge­(§lÍ~90ŸqäV9ò]\©µ|>ý\ÑÂ*™Z‡d”xÀÆðåšvôÅ]W}¹[»?+gM)e Pjo}qÅ}›ÅG.AôÏj`çì{óØÜÆ´5ª=ÔöG3WÜç£C*IDzâZ3º•+<ü•pÒÊŠ-o6›Éç¾`0ÙîrÕ×ù‰úeºNcöB™Äô O[ã%±Ã,qe9ª÷E^È÷Y&«DÕY‰uãì“gå46£‚AþÑ“CŠÓü˜³áä×.Ë!à1wäÐûÕ†éO3þdzå¡8{Μèo›ûùœÖwËzÏèB×>W™-¬ †uƒË³mŽ7fHqw0…ˆÔLgJñä+ýh¯»R£Í7õRIÆ[<ƒ]6C÷3âWILg­âg¯dŠëïglt¬yͱJ¹’úR%Ð5j¦øºË0ª½[¤º0ì‚r'¤÷Âmª>æ8øi¨(°s†À>{³mÔeŒŠÇlp|in•¾ê|Ë;Ô™ vgn£Ê]Õû¹›I°µ‰ôµŽ0S?€ó !0j¾›)nîÃ-R·‘ˆšûŒ}E:ä’ã/çã!#G㨛ó¸U±9:šÅoÛ´?5åófž>Èç÷bé›Þ?Ú^\s„ÆN÷MÜ¥½ b=!ÚŒà’‰û8w¼nâ´c\6ôŒªð±Î‚Ÿ†'Ì2,¢ïÌUϼÑòå®úœì†r`}Ʀkýû^Â%£]ž…™q[‘9NJ ®ÒÅåŽ[x;NÜÅ&"À- 5ýz§ü.ƒáç6ÚêðBß<š€ÔįÛÔ{ü“ž°ö¥©5BÞ¾˜ÇKÑØ~'\}ÊB·™‹À»Ð„eGΨ4lzé}]g×$-Ù!ûJXoÓ*Tº•ô2.?`½–g­Õlæ`)V£¬ !ªíÈd~ÓoÑ£ÀnW?wÅÝ‘H ]@ O7}oz]䃟ð‡ú¦y¿)Þûá­1ª×Xî R|[ªíº7Å2Þ7þÞr¤4¸UE]ÿz™a®Ei-­õU'ÑU7¦yYh…câƒÓ-b‰0ˆákxƒ•'–8–táx».Dѳžk‚x%ˆÊáìñ½{¡@–¹Ÿ! •½f ðnjê¿£uÉþ€îbyè•‹¯Iv|Ho£™Ûà—ÇË Jß8© 3$%ïͽl˾&åw½ý³I´Êbpæa[rfäõR ßîc©¸ñ­G…(—Ó]íS—Â6!b‚Ñs~Píì‹Ò^­„ªÎžá}<ѳ&A$ê¸ã°“[v²s‰&¸>'+‰ãS»óuð •áo£R!ÏñOØÏ‰m"šï)ª gúºKì[A½!»£Å£Õ¨CÉÄ~moC§ñî¹| [òP¡ÙØè¼±ží:R³˜‡Ç¯¯.ÎÝÈn"Àcd6œ7w„ØKì“ÚËíž6Ùƒ×Ü_žö'°¢SpÅ|…,Âñ˜§FŸó|a.2)ÜÅ)9…‚´ Š\++ßĺ| ª,"bBýnUhMïEëœÅ3Æ¢QŒ–/°¯ë©þô˜~«Ô;ÏXÂT悔 Mqw¯Qç«,;©[ÌôÚóП†Ž!%7žQMá9J…ñÕ0íXHŸt­ËvdKó.ê°8âŽÆÓöJ¥pS\døYüiÛQļ J)N½µÚ|[!Ú=¸ïÍš¸ýæï½QbYà%F~=¿Q?cÒ‘FÕ›•ô^gl‰üÞöÞ᦭*¼ìÒªd_-›÷¡E¤‡íàæ¢iÔ÷€œŒ;ßÄÌ·'Mc·„ž]LÈ]ÅecßgzÄô z 6ÐÙR¥¬ kŸSùHXøÜ•‚j^ɸTŠˆQ© …JäœÌ¦ìeÔ4>žc¦ ÚV/cbje`Œr—Ûbq…Ø™½a¤ÎŒ ÝäÁO`k³nî‡_ïE¡këV2B®ìö·”¦‚DKW i7»•YÍŽrìK©µÑ%¹È‘<²QTnäù{_¯±£=+Vÿê4Ý]7O9kc-gG©¬’z¹óÁ‹ñýŠÛK/'ï6ƲF=Kšø znàHÿ–¸êH`Ö¸¿@üxµã:óg¥VÉ_yÙ"íh¬ûë¸;ÈçLƒãª€)¼xk\(°°uìÆ›´æ²[Æ»ÔG³Ò µuÙÉ¡rôÕ¯Ùn]»Í7ÒY!D ¼îMÐc$ÙÆ£8?ÿ(Û Òҩثǥåö8ÿãSy ¶×né°ƒaÅ1¹ùû”™ŠæÆyžä[×[3É×e}Ïsõ<ÉÀi„[ÅeýB%{¸½†â¾h„È ÊW%-›(Þ[ºçAMÆE_®,3摌¡ñY‰3\e|¶ ,ƒÉÜEŠú ®æ¡Ù¥±þgϺX'wk©¯¶æ+øÓ äÕÁM²…}¹ÝvвY¦›!Rîlv]¸¥† 'kÜ%z9 {Ë×3åÉqûËF_ºØ4P#D-äïú)Ì«îËéG\ët@’±Äû?¸å`É#Ï>/É·ñ¨khÔµÌWôµ{Žó|£¹ÚC–¨ê½Òznó,˜´“)‰vúÄ_-…v¸¸÷‘wÈ<Ãr•­Ùòº3#&÷ÔÏ•ÃÕ•Ãæîv -þ>ı¥ð{ e» ¾y†âáÈÑѼÓÇî·†5OR ¿dÅà;,—Ñ »]kAˆÛáª\âÍ8]ÃvîÓn>ºËÁ&ׇY¦™8×Ca"…r7Þü‘qÇãÖšÝôå•¢sß;<«5öœ þL”¥l†¬¹Â@.ô’Oë±ãºr%Ռǣ=µ¥=+Ìä‚“¾6s¼áSŽï/än2~ }—«°U…ðRÚˆV0foÍ0Ïàpòéj2÷2fmç˨@Ÿ.g^òpïd¨Ýt¹,P§b¤ìކD Y0é»Üg+*Ömî¼øÕ¼§?síngSñÖÍð´~Ï)n¼¡«ÛFÒXNö`À‹«©føLe鳨N“Î}t½·‰§2º£m¼öÜ ÿ¿`^uy¡é£Çuê'¦çìíÚc‘‘ü•S–]0 `%Oú)ÊÄ”­Ó ãäJ(õŠšÇRK0)aÿü䫌ý íú¥ "Mé†çO–-5Y@©+횃þ-ÞaƒF¶–“Ù ä$O8ÔËÞfhªÎš1*¸úN>n½i°È©.×Ú38 Ep:Z¨¡=gà\ÿP¯Áª_kØn+:X…hß„ÎoqÊ‘xXv:#-î"äšý]ìSY 4{»ãrù#‡} 1E(áBuY0ÕŠžˆ«cøåyOB4/ˆr«áÐky«û8Hû½¹®îô¢¨Â»ÄørÝC›oÒæ 27©¼n'EPf^·X‘¹®|;…8¦Ô‚&QÈ`YKF¡€ÍäY4@èF3šnïÔÔfíyXŠÜ¤EìÏ—)b /cƒ=‚u1ò¾r5‘|«!*x]mÉ:1ýLJu…î¦óþ’ô‹£kÖÇgsCÌ:!¸Ûa…©\ î©§†ŸŒ¶ÓÝ…£ÉxV™fO^öÍz™ïŒÓ3z¼:Gö/NTÖ+tß kNQg7ªʯàóÐ6œ2°OWNÊm‡ 7wÃ|P÷l–ßU°½ñ¾×ÿ(ø(?³=$Fµ_d¶2R^Ï_EUÜ\Uýò‚E"¶Þšý|¶|Àwýóp_*¡IAœŠØ…†‡ÓŠ)A¥ØŽÄ¨Çq\µ‰Ý±DÓ?jT¬ÍIæ?Þ"+¬!Ðõú¼Äãr S¶º ;/BìæØŒÙôâ¾1§ÐŸKfŒv#Š{šP½OldÕuk"¥'ërç ÑOîÐõ¾P5ÍùK™ÀÛûÖºAyYé9XbÂiDä*Íý¬»¬ÚÑNQøåýÏzÊ×)hãrMªÒ3ÜàSvÎí{CíÀOE¯W=U#sScȸ‚/û$¥„.gKÛ×½”!üAjÝü ¤Cb%Ñ\©c‹Vù ¤Ó1±–úº´B&m.‰ÀØT 2@î"¢âfUü©R_B>ÄÕü»kqQy'îˆE wØ‹¯,%t¹´=²¦¥/Þé½—ÔAA]ޣߑ‹RFÉ“fÝab<ȘÄp[¤Ci¥øÕ$êöõÖˆ² q’þý6‡qn­yÂQ 7(óÛß%ÐC½YâFXfœþ¼ír§9ÞÌbËRë3È“PW@Ñ÷¹PH­V³ç¼rJUŽÍ‹ëŸ7øšp,£lk˜¨_ž*ú­›Où†h}˜'²£yIk€|ëªÀNŸöÓþ-ÉíLŽ—Kö¡‚R´†Â}ÅŸuëaÁù s¯‡¶¦j¯±Rî8¯áÙÄ–8ìw_n¶oUÚm‰ÈNžf ðãSî`˜{*j­Æsë¢îþ,×W|Æ©›¬º¸I†)iœó"‹œ±flvXì=Ô5S§Š]ñ»j}1—’wÌ,oPNœ÷5‹b¢š*¯Ú ]*"KzØK¾Mš%)²¢Ö‰u.ÀM°¤¦­çC‰I¸Ò.ýL½ÃD¨™b#På3pŒ®AûìkæËªkS­®EÍ]Ýu.½Ñz_|‚>ÇM`qÒÙXÐü>u"9ÞØ=zîæÚ³a¹²µÞzŸóêÁˆ éŽs}±%ƒµpï^»‰5`,›ö¢hÌÄ»íçÉoN~JëÕxdÜÙå~;BÞ å¸j wgTF¶CVc‰õ¿lÛS•º§dú·,•i‰ßRÉоTÁö®Ís»IXùaØø-Çsì“*:ÇEGÉ-t>™ÞÄŸºJX"Ô[s®s‘=d_SK• h’±Ç§è'õúÁy~{¡ÆÄj2K`³ Ãe×xlÊè¿TIî»ñò™‘ö„&ÓyÞ÷µ»ùÂÊžZñÔý•~¤Í¢Æç·¸÷᪸ŠÊnUmV}B†WQŽ9MÏDôÇ`ŒÏ¾ôq²„ìòn» ž/ο¬`§iô$ÉTƒ¥ˆó÷Í×¢Kïr3ݬk-=Éü´îmø‚ñx¿ÖA]àÒ Hb`ô#ôbÀ¡\ ^yÈ)D£íg­w³06|ýbõŒNm‹P`f&2E%§{ EÃ{S0ädÐìÓ3é)FÓy‘Éù!Pô»×©ì݆æmOÂô/O&“ïòéûýh‚´¹@Ò*-¹.–>ÌÍÓ$îlÉmKP§YÒg5œž¿ÞßPCk-©Ç¦ ç*\¼‰ÍZ&³£…ôøÖ_˜´Õ&¥’®F›äLX§?±o¸-X«œ®=ñ¨8ô‚~ÔóÁô­ñ8 ¨.æåÜì±+ëÙð"õ=`¦Yδçßœ7W@áCe‚+Ÿ37qåã¼®TÊÓêµw¥ª;?Fúzûä0| ëïëî‹/™|;‰ Á«õÍû™ùôܘú:Ãýo›) ƒDsþ =ìK-õaÞé´¨\ÅgWñ„Eá <ÕËÝÑo4Ž'ÑAuë@ ŸÌUw[¢¥Ž%R±Ó*ã·:Æñf a¦‡£€ܱ@4ÊùH«Ö¥öUöµ¨#–O³›Ùv5*©¥Î“?$ÎhÖt½*ú¢²üc‰¢¡¼Ò¦ø ˆÖ[îO[ñ“íMã¯;/:׈/ŽØŠ ýË+a´ê“F•ÑÊüm8’ë¼5w8àðdS¿iMfTöí]!×I¯çX6›œêÆJèÂÓx#ü»DúÊWGœjoL6Sssf#S"˜¸ ©Ž‘ R{:D¢qYõdü•_¢ÓÒ(Ûü0WëTìÔ6„åTÖv™A©¸êØa¸ì#I5ÖDöÐ1H¼¤_mÊŽ—AŒÆ‡à°Ÿkßwé„XÁDÃg]ô?ÇK‹ endstream endobj 2833 0 obj << /Length1 1144 /Length2 1528 /Length3 0 /Length 2250 /Filter /FlateDecode >> stream xÚuSy‚QÊaˆ"AXHñx\dúƒDÄg€"ÀB+û1+à„ðÄ|ˆÍ&üW­Y³ö‚#]ü…œAĆ#t rÞt&T„A>Z4s:–¢­gBÂévŽPÈ#š™ñX4ÅL,Sš­B ]3ÈiâôÌœ!>È@››Í[ŒÄÀq?À,fδÄñÌ6ÀP”twþ'…¿alPà±æXÖ£p+ƒc62@ÌgHÜ4Lƒ™Ûãx`Ѹp;ÄÑŸbœ€ B¾Ü÷¿Ä÷;E`B !@Ùè5|SGa5»÷¦ ùÐV kŠÅâìô÷u‚^(¹âoá>´H0óÚèîáî²fnï_£Tƒ³¶0æ6xÔ)¨"o1W‘Bƒþ©ûí°;ÌBÂláèľ ò¨ “î¾WòA„L¾™d3Eýþp?5ÏwüO-47‡‹ˆËéßd¶qí\xÓ½siüÂi‘Wü“sÁYŸÿw! 1È0›ûuLÀÚ 2)Á™5Æ,¾fμ8‚ é7 `pxÜ.€1"`P @Ý7C0sNÊõ0aB0  QÿÑøÌ¯À4Íñùèxf.=ûeÏ‚ÐAp+ÈP¼/A¶Iág“ê'ϵc0ÏnY´Xm˜ø,Zn©¸—+ûÄt^³fD©¶åñ·6‡r)mûÊ`9o9ÙäLíõ{­c"Ž ¦ jê»Ôæ¹¥i½0=gçCT~µÐ¤ó5¶EkÿÍìcÏÄWÜFW”OÚ;ÝT£&#ñº“›¤ƒQ¾òÚzå‹|%«¿¾ß1âëÆýÍ(ßu½Ñ¾#%[ÉãÒ…ÛSÆ›”.¼x§^Ñ ¶¥[ÒꨂïJvUž}E×*µ&6Þ¼dþžÓàéÐ(Û´ödz¾±t̬]éӣ뫻”å5ì×íS^¬©Ù‘ˆ÷Š´½ÏX¨}¤ûDkÃm“ëÊ6÷0dxË0ýtŒ~zli^¾¦ÈKÁõÑÀƒÉšv󶞆{kŒ²'éêÒúšÖ©#%‘Ëúî„´ýíÔÜèùøI»LÕf=?xäôÑ$äÂÐ6wjØå‚ÃV®u–ár¡Ýhõu(¾±237káò¡<]iu4ôM¨Ñ‚µ”ò‰Ö¸­'ÿ©°" ^…õý&Ç?»¹öøÀ’êS^PZo“#f¹÷n=q-—Þž'ÂI©S£ 6Ɖg'v5+ÂÁ:+E-%F#/7óË삯Où—$1×èwßÔé_èHÒû\Ýå¿äWÏ8™¶·PîA¾›ëóîݓҨý©ç㊻ûØ@BþžT9åÆ>2…§hZJ?UÚ7Ç[qËf¤¶*íLÐ&½\¶û꺪#žo£ÕÎXlñ-¡ÿAòi÷‘Ûh\•õñ¯Fѹw‘ö)¼µ}Ê­ÔDØ¡x5{báÙË ºœ2+î:£ M¯¶°ê%wäû:~ßuxéþÚe[ؤÅé=Ãj×Ì*/Þ§ Þš¨z:…¬žŸV]Òùq[ÓeÅ"Y)¹saÚ@šý¸Ôü&YÔäDtd[Ÿ–ø«¯­Ó~³L²wñp[Í:e…MY1¦ušX|®Æ¹Úª~9qluL,a$+Üo”[{‘$Ýmš—r>[š4øÉçá|½x~âÝp7>QåiíŠÏ¾\ÃîÈXZñ¨T< 0å‹\ž8Øeë@<2}ll¢DùöÓU§Þ­®\™Qý=ðD-£)p#1Íve©9Èk|UßÞ\Ü´3)¨J)´º}©AؾގÄWÜ÷uˆÐ‰<ôÚ¯4kç©l×i3[µ}!òFW½¿7ýå=ÇÛ81ì&A¦ò¯[¹%îúEµ Rˆ9e§tIÐÙçŠ“Šš%?Hdö)‰¯g×ÖÒ{}:Æô†dr—±Þˆ‚ëæó>~¼s¢Ø@ÒžhReQ?©ÿäÝü âý– {Á¥Ìóú#¿†‡èn»q69WæxKëïKÔ‡‘¶ná7ûr§ê²œÊp=í*VømI.xžÕu$ #c|¥œ?µ­M>¯óÕ™e–†:éËïÈÿY©`Ž{Yt2öéCƒ eºÍº÷iÛÔ{6iÁ8UÒææž5 ØKßËÕÖ­^ô]ð᪉Û%´«+Í Ú©#‰õVEó–\î~Eù¥"P•½kù®ì£ÏÎ~%²lž÷¸LÍs+Ä™yŽÕoj† UVÉHFŽª`åØiÝéͶûÈó8Q¿ïŠO ³½6ÿ²ªk“êƒÕK½Z$ÖM‡îžŒ áßôàsS—ƒC]·‘Õó ÷×Ä…h„vöú~¸Bù1‰Jìa:™¬Àœ¼í`:Øö>°LcœKRÍa¿ºƒ-â–†4&¤w(Ù[ðˆnRç·×Ë(U¿ã’KÚÓ}ã5*ñòa㧬æ§'RÊ4¥ï¯>o R:`¬4¤VàñÌ·÷÷(Ö2ë語rn­çÇêx¨‰êåj¦Ï×o \sš¿ÌÍ“òôTÖÒ…Š Ø§P²´ÓPËÛhy£Ø`#qRãÈvEjÆÁA fRð[SiN¿óëuC%þeͳNyÕÕ©ÈsîáGƒ©ÝÅ9ÞÄÞ·h{ÜÏܶc¸dE>!¥Gm,)hiþ|êß-MŸèî7ÂQ21dÕˆáœÝÀ²Ç±êh½ÞEÍm ì©’ÿ\hŽ endstream endobj 2835 0 obj << /Length1 1626 /Length2 14558 /Length3 0 /Length 15393 /Filter /FlateDecode >> stream xÚ­¶ct¦]³.wбýĶŽm[OlultlÛîØIǶmÛÖé÷ûöZkuöù³ÏúqqÏâUuÕ¬1Ɉ”é~˜ØÅìlé˜è¹r6F.NJv6rv\2t²@ À_9,™°#ÐÐÙÂÎVÄÐÈ PšD€Æff,@ØÎÞÝÑÂÌÜ@©ª¤NECCû_’LFîÿ¡ùëédaf ÿûã ´¶³·Ú:ÿ ñí¨ œÍS k @X^ASRN@).§ Ú ­ .FÖÆ c ­ `jç°þ÷`lgkbñOiNôcýpœìÆÝ€nÆ@ûT´{ £…“Ó߀…ÀÌÑÐÖùoœí¶ÆÖ.&ÿø+7µû {G»¿6uƒ)Ø99;;ZØ;þfUû7NgsCçr;YüUìLÿZšØ»üSÒ¿tÃüÕ:ZØ:œnÎÿä2L,œì­ ÝÿæþÌÞÑâ_0\œ,lÍþ -Àhfèhb trúæoìºó_uþ·ê íí­Ýÿåm÷/«ÿÄ`áì´6¥‡ebþ›ÓØùon3 [X†fEÒÖÔÀÄøo¹‰‹ýè\Žÿjå?3Cõ„¡‰­µ;Àh Ë gçü7%€òÿŽeúÿ9’ÿ(þ!ø„ÞÿäþwŽþ·Küÿ÷>ÿ÷Ðb.ÖÖr†6àß;ðwÉÚþî€ àŸEãbóÿr1´±°vÿÿrúïÖêÀ£²³6ùï:Igÿ-ùakö—FzÆ -œÄ,Ü€& ÎÆæSCë¿ýú—\ÕÖèhma üËë¿Z  cbdüo:s c+Û`û· hkòßáÿ¥ê_à”UdEÅ”iþËõ_† ‡ÀYÅÝþ/¶ÿUЬÉþ #$dçð¤cbçб°2ý½{q±3zÿRþ+Óe -ÜÚëfdúWõÿëû¯“î #jklgòÏØ(;Úšü´ÿü£6vqtüKð¿.ÿߪÿãü¯™݀ư+‹vÆÂNs0²1Ô@J±TÖ´P†™u£†€ÐB”J»±ÆŽxð1³%Mú×ù°É½ó¥D;ï{N@¹…B¸. 4Ó=–¯ý‡ V‹4Êy¡o£DÚ—\°&(|CS³¹er¹V=(¯7‡†RÁsQ ïyââ©F4¢«¶¸1‡‹‰ Þ7s¸é~O¯Z¸ÃbNZ¬.¢¥l&kÜ›UÒm|ñá~-bÓ½€âÍÍÈÐ\~Š! +˜ôßDùðËíàíǨ¹ÌÖØÚœÐ( zÒÍPÓ\=˜}Ù ;äC)©¹)©'óô=èâuÔÎo²¬ò‹(I¹Gk*îþ.|xòáθ%Ó³› òŽÐø™áç‡Vô<‚-^쾂d÷ •æ~.¨þÐ]™a*ôx3“¢q4‚³J‚ž,z0z±©ÖÓ_3ºîÍý5<±–sb&"8Ë#ˆ2´ß6L ¨íFf€¦Dy°6ˇökøbÂÇ×^/V—ÆV¡‰wÁÝ$¯®Z #øWй³ÔdÉ\÷·e¿k7È?'(¡¥F+x ûµíÕnâ“ ­‘²Ü$ffM4è´=æõ­± G€K„l'¿]æÞ ^Yyû ã1zc¬¿™ëð/,_d+'i¥úgÍø}d—Ïå%vâðwøÌˆ2!“¶ÚÈÙQèv…~hí¼´+ШìU ôÇ1÷]>mwË4V®¬L]rE‡\>ª4¿9 ‹›îGܼ„›|]Õ•½xßæ-ÃØŽ"50+ýBO¢è÷›ê« tdË›¢§cßé­ÎuübüK\~1±`Çg)kooõ&šZä(±Øüp|ïÖq]̱ëdh®¼ÉùNê¯dI4=¬­ÈKélÍIR€"ëËþÒ1h¥'šh¶oäJÏŠa):â„^:²vÌÒ·“^væZÏØÛT;O`‹Üº9ûBó›­g³=Ñè™ØË]h®(ýG¥‚ôÇE<Ëz/ÞÅMyÕè¡Ê¢6ìV7*¿?ú×G\EâöÊ4åOŠ0/æŸÏ!/¬!@ЖӢ|6÷3_Ÿ¡|H‹tÚ›]NO—æ©«2vS%•ÉwjÌ3òC8ÈZȳ3g×e¦ÙnN.6¨‡~Zlñ_³°Cáz×Sõ2ÕIdIìþ‚"÷¿½Ë;„ó?*™¶Ò›q™Q4(ñËW‰ñdÁÛò†S #7QI![ngyáh²áßsB ×ÛÇF·gz=•…iÌa½ˆ;ƒø#“‰ˆÌªviÔ)^j¡ÃV|+i ôØžA98C¾2>"¹]Ô™¬?Ÿäaœ¼ $/$™‘î^6Z‡»†-)ÚQ¾2¸²j«¥ËŠìUÁôd¦œï,µO lK[éµî*<)#ÿé+ˆl ½™ËB6ƒ+Í ŠÚGˆ›û½¡úV¼¹VYr­j¢;Þ—/Ò7;Q˜¡‘úËÓLAó»ö̇ŠràÿÊ&×)2 GîgÅû°…Å™á‹Q!¨Ù@÷}?ŽhÆqÖ–ni| ÎÝìIJ?`tû¢V››Ûz«0uKœc–B4ñ*Åã—XÓPJ¦úmêâ0à:h–““÷óZéØq)YÄDÅÏDÆŒ4™H¡øЊc«ÂyÛ‰ný s§*Ùè<É53ºq‹¤“‰\€íd8¥N`¨nõˈ}â'KȞѹoÏSf®¥Î…òö™Pw¬X )UWûÝR^€º«\ªÉ‘Ø=‹ëóC"Ïß«›ü`‹?A1‹9/œŒÁuú”ÇS†~Úµ!È#´V +óøkÌzŒñ £P*1òİúƒc_£‚&c¶#jp|—ú—ßꯤu%«…]9OÚtsú)¤­CÃ$¾J¹îþŽ*üÃGü³BÙü}ñÍVÁx/P m69º`ÆM.´MÀu§§tª–Á"z³çŠžìÊAŠÞw6^ö]ãçAž”Û[üLäÄ¢¿f™<ÕÎ~a_ßusBÑvëQ¥ÂŸq¥%¢ág¸äbX4Ý pÏ웥^ˆÌ|ëp·'ØþÀ*©šÎý1ðjs…Ùb[Uëá IÆ}täl•’ÕœIâ¯6b–uUN^0x~ÒXñÂU[ÃC â!$®îÆ,$߯*¸ÿœšzø”¸‰ŒŠÖëånXØ<"V—D³91¥ÐɺÕXy(Fƒ^”ý3µ±±Ë¤ñ»ø0Eq.%¥ÞGP…Oc2MzzÑ–K?>Uíj µMP1šCâv³ÓLÊŶ6Á 'ø£\ªG÷oæêÞõïþ·³õ°m6ROnoÜ3\#N5•ev3k¼ú9,úñ~p“-lNëöO7ê1}õTª¦{ÊQ·I›Eb‘å½ÍÑZØ ·M ¿Õì Êüæ z÷óÿdˆ-© ³‘2*­S¶›'¹k1쯳lM6Põúnf–*Æd u4Ô«ð9ŠãVçÞÜJ8¸´mÃcšc~‘ê•’?¸b¥g;Æ[¶FÒ‘iã ?à“þÆû†ú5ñ7û,å€.ðâ£o/Z"*¤é0X×2wÕ#òâ×D¶L|¦ÚïVÐ ÚèTétàÎHø1äÈç½S…Á›ja»ÃvÒêÅía$x“¨O4”Çò Tr_Û!³dÛtU Ûf·BÔ&Ürž·Ø¬2¤ðc`© §3¯ý.¶9ãdƒŠ¢þUnïÔôþ‡ÔÂîupÕ'÷6Y® ¼¯9îLCØè¨²¿Óɺ.Øzr³ไdªaC9¾ìÛ¡!EY1Ö¯ÝËó†Á¶âM—SçÓì•”ÃPÍ+r7Ä,³N"YiU]õ^÷`Žó ýif{™ní<;T_?”W@n¹WZr’ùît)Ä>N| Z‰+2 Ƽ.º??X41÷±±€™¼*@dŽ%qCKðXĺ¯‡Þ½¤¶Fx;1Ü•ð>e3É·ºDS;™&Ìwç·\eóù`áEõ†?¡æ ëߦÙuɃ3¡ˆÙœ²pë¹L5 ‚cƒ¯SôpH+&SÆô»¶Næ‘>¥Ô‚¿þ6Iã’Û]cܼË" +b~ˆhJê½.å“7·ù¨$£Êž§ç¤Ý “ L& õU‡ülŽ%ëQ‰‹ÜÀ´At¢¿;"±Xm¥ëŽÛ«õHp–'Ùjh¨¥²NS›Š€¨29ö]ýŠøÐÔÒ@ˆÄ?QuŠUUnå.ó°mz]¢wµ&üªÌqÕÖ5T^Œ+Ï'³´°…0â@¡œ¹“+ˆ"Ó9^|!ÏñvJ³¶Mp0#ë¡Wf#-jVbH0àP?/žFG–߬ÇLx¢d+®æy%² ¨ms!—ôͳL-ö»i'‘¯lÆ,ôâêbê×uÏõè-…f“;°}2¬q) ÖÅž>?­ZTó‹b¹µ £Ïi ë®fŽÀ¢OбÔuî†xT î°©<]ŽøD¬\ŠpC§o™¦ËYÚÙ¡4÷â§IÙ¼;æ0-[UA´ýDÃ[·|Ð$2Ôr/¾‚mNh ÃpIÚVQÆN:QE=I’%:$j ^fwZG¿ @Ú-¤:¨ƒT"½Ç1+²¯|&"™å6aMk¡ey¬Èôy Þv`ÒŽâ #›’T}ÙNG¿Küªèqö‹YðFU·Y ¬‡[Ðò¬[30xl 6ûå õ pº¹*(®ãøæ ë˜–û}Pß®hsÓ˜äÁøC!¹Lã”~ï¢6¿ë2¡ùãޅDZåª%wá"S^m5©e CòáØèÛÊÔø£†oÜîwp쉯Ҽ»'{yUÅ ?z"s«°K¯EaÑÁ8ó†ÄT—TñBsÃQ<ˆÑaëœNÂ3—ññòt²íçd|Öt Y³Rá6¨ßî¼M‹Mp—Å„í€mt~xèë¥OK®ù A„øýàÆì CnÒ žæ´a.˜®&ø1±6;Ù.±öî+4Ñùä”uA+ûLÊ,õ‰kA§•üà†’sŲNB.pyÛØQ‚fÕÉVï"2STñ[þ수O£ìfoØùÓŽ«œazºOìq ©>÷û‡&uM.+Æô–*ž«[PK§=F‹@_š÷gžf!üe#…@‹º–7öÎÃ#%G›äAL4Ü“–f'Fþ‡·Äý§CqH¦Ðû½P ý3ÖÑŽÆÅꯟÄlKþ¼Ì©YÝ6ç<èPßUÙØ«ó*T¿ >‘¢Â5ȉ¿ò˜ž£èo2ØP!TÃŒÏÊÚcÅ­Ï¢Œ¼õƒµÎ[‘ƒt>¼Kî)ƒ >³z7Q¸t”¹O¾ $¹6b iÔ•%•E:-’ú9ÔS¥È‘núOX!>bZ£n+Ksèlòo8ÈöUâû³¤ ´þJÉIåjÂVì“¶@¢Lv߸ÿuü=*_³AAèͶ;7íPœsq´¾cÑâ§=ëv‡,z™è¶øÁ<Õ rñ±W¼òÂFirºì“ž{ÂÉBaF6%ŽE„ë¡ÆwP’Vl7ÎQˆˆVÄÚ‚*/¢7c¬ëã9ºt„f¢í-ÔLÚ&Q4BÛ•ØZúfÐòO¨±áSÙ6Ñ׉¼lÄSž8ÃÔ×è.Ƚuâí â'ÛÐÜ$=øèx$©Þ-ú ]eæ^SO&Ãhå7¬úWÓ=п/ínßíâLä™$2)™ Ïý—òâÌ\ð&i)pÚâK£ii¨&Ošæ±?‡ “mlç(¢5xº‰9È?@ÌkÍ»ô¨ûÐU¦g1èX™ž‰*tšmWõš_nV+XL²Ý 42zЍ¨<ÀÓ×(³â¶ǘ'ÔçP=EBŠN!QÌ™„4Å^õUDìI3DÕ’lüð•äÁ〾Œ:³å™Ò¹[F¯˜_c÷¾ÌzeÞ3Ï”‘tI»Ä§v¢Zo½inðmyYÀ¿Ïìd…Ž}Õõ®ê6ÂFíú¤+äƒñ¡¸+ùÌMµùÆÕ"Ýi²š4kðœq-»û%õE÷F —Ôì]…¼LÓøëœ]¹Mø£À©øfãÇË­uƬr@iíçZ‚„o+1ÄHvo«Tè$ ÕOñÍØ{þ-È…S~¢UÂXçÎ?"« °æKÓ"9Ngñuòç¦k!Á\ ´ñ~|ÁYχ-¦ež<63ΜçLÓTUؼԗ3c:¶ç˜¸.T{‡,°­æñ¯ùæ"èGùëÛsi/ßvd‡¬ÌŽü@ùÜXÔ€@šuÐê½k.l,Ž0§YTD‘*À»nk²\Ù) íHts >1®Ø [qL/\ÃHMG£Ö(±>;÷ùÑq&¸yKÁvzˆp íšs¯Vp… ÖWí”–¸‡U9}]ÐORºœbçêá»!±Öi˜\\Ò©<‰D²ejño{5ø #ÅÄdš´§ÚªUiJ×O­6†4EbŸXwŒ?ºW1CBAL ðvHlÒ«ç5UC˜u±Ïgïü÷E<§dd„"8ʉ£wÕ‹×2©á ÎÞ8 üHÙ˜…TÑ%Í*2÷ªfR÷8ou“ˆ©-]É(ˆ3•¸¿Éí3>Ã! Yr÷'Åýo^(k¿³Ê‰!ni þ!jW¸Ó¶Üê˜3ï6 ·wÿÒŠú#N¢•ùÃà—½J¿þôÉøWPó1ÃZVdí¼ö£¡þjcÓ¯µjˆc)bOÛíýž¾çØâb;ãã’Z+ îøj¤óërÛ6VºÜ¡ôÒ¶|‰ ¨àÃ×EžJqšSô;Sž~PŽNì–ç)å»)à¬+ã'áAþƒ)“¦ÿZ¶&7fpëð@÷ØÑ`ÛÉÜÁ  ›¯Àxs«Â”–,ð¶ÉP¦!LÖ6#¹|¬jÎøf)ò¶nÿÍ…m2¯Éô}ŒJqÂÒ©±«ðƒµËlhµÆÃ:w;š)¹µÐ€ÊÿíãðܳXÄTí¶¬S§z(X«\`t 2EÁê_®’Å ùkoåúÀ‚޾“ËrÔÅoѳyÐöΧѼªŸ¬ª¼¶ žÀŸ—¼cµï˜%p|^L?1{s.aåØY²Y‡3ÌÒ?Ù@ÍwÖÌo>]Ò®­&‹Ô£óïy­UÅ;‡FL…Ì•!!»’iÕ1<6>×vÒ}e ߯AÞcsíúhâ%àËò¾ óì?†'xl¾Ó<ÜÙžðGš¡xøî&4§j¨ËÒ[` ªDBgºb•göhU¥à¸Ô2P6r 5Šè±¥û♇+̨¯€>Tâ{`‹£ÅÓŽô1Öèê`ˆI½ý‹S9ð¡ñ²' ´ÛêÜØ|ëè÷ý†æ×C¡J»‘Ø8{Ž׿Âu%ÃéåSkÆA÷™a$ Žh:ښЇ…æ^2Xl,úä¤èéŽø¦‚ØSaÑæˆôÀ17JÓzÚ¯áM+QEíHweXWâ¬ßƒ#;u›¸^ÒHÑõÍ? ÷í%ÿ9½Ñiºw«'”šûÛ†€ÂE‰j ˆ»„ÚšûÌBÀ>“[%¹®ÿˆâÉ ÒŸé}´R–²ü&‡/}¨Á„:Å+ ¥Jaˆ&1ÁÅr\ ÍŠ¸½"êfùúýClÔ®Á?&aÙµ[ùyÒS…yãb j#~tÇ/¿4È 3,ë¬e¾„ÂÇ%8ñ5©&'?û€4®³º[oˆ$=Ýc€Äv°wBÚ;Ì)#¡Ñ¨`‡_ìÐ5! 4߹Яß¶]Pžõ<Û{ FY0£½C˜p#í>÷*›èÑûÖú1X(ô‚¡c…jþ@–y»öºôÝÞ|·s†*ÜOº;€÷Žy±>.~1W^¼pØ@þuª"…„—LUË…}f­Æ· §UV9ý©Å ¿"2G:L·É­Š†í*iÂ)ãÕ‡âD 1eaÐJ L¥aCsëöéÔ8:Rið¥õ³âÉV€Eþ¸$¬ÜU‘.±êaR:uM<zÄо!ñÏ«ØÈ–MÉ«ú]©µ9^9äP~~;dGY-\·0{¦td,<®šÆðÖ¤&ôä´p·Z—­ÁME„õµ/}j£}¦ÕF ]òÞljÿþØãR*¦C¶Ãgë…à1•j××`O5–hNžiüä/‰máŸDƒ[U?^1jñE½O7_k2Š‚4¼Ä3ŸòèÄLˆ\’LFa³ëŽß¥Ô¦¸€{Þ›†¸£ÝáÍÀ}hº‘×fÑbED¯Ûǯ†VoûA=ÚµùkîÛ˜ªÄ’A T§ÿ¾ìðú³ˆéªT÷ìHK7DßWfbº«(º¥üBço£À€U—»1´:· |7µÛ3ÍÖ7¤ÚÜ/ËÁ ê%ÆÛ/r±“îs+Zysñ«ñ<¤Ñ­D6ˆb¤pà {è1Ç=·Õ(e›8ÒѲœ¥|­xˆxG¤Ú#„Ñ \¦ Ž+IÑ‘À­£0Sè'‚žñas·YIW”¹€ëÛŸ¢Ý¯$ñØ-Oë^‚Ö5U¼¿=Z,½ší@æâš~¬éß  ìd©vÊ)ŠO<¬ú•Õ=÷ʽ½5y›x¾‹ÿ$ ú¬Äóüƒt0ò±f¦–é»Ke0bàÐ+RïH¬Úî1 |@¸è…tÆÐ˜øVïB=lø²Îy´ºäz•µ@¸_.²³²ò0ªaZo-wªœf,¦ÜwGf³¡Ó1U´Ò¾½Á©Ì²,Uñ±†~ZÍ×I4öMÂ"Lœ’Øn„ÖÙŒ,ì¨$¸ZaŸ>ßqWEémØ®ý#n<ÓÔÜn´)üÚÓÓÜÿòùT41?P¨SXmhÞ\.߇¨?uno´òð§ô¤×+ä w×Ù2ø6›‚ŒÜÈB¡¨¹¼…P‘ºá¹8gÛÄ!`%é&ÝsåÔ»2šMï4ÓuQ½…+Oª{iÙä}·SÒe„@7°(äYè-—ð‹‰W ·…h@Ý×ãOÒª芸‡w¥_µW€Hœw1Ûå+(¢‰Õµ¿ËšÝTb®ÛÀùEU‘ýÂèwø[9jVòÓ GBµéwNUÿ;viî¯0e>zàЄªÑÝÇÑZeÚ:j›uÞ†~¬Y›ðb0ÎüÏ×ozâñž`I Î-¦4ÐI'(3NnOƒdŒÂ e²ŸŸòØ)$LâRÁS“ÎS©&•\F|$¤>§uÎÍïhµÖ83?ßFKUS6÷ÑjÓ·OþWž™|¹È¸Gœ`(ؼØWãt>þô؇ µÌw† ž ,Á_Lˆ"0;Ê âåzSúŽÈçJOÇìÐÞÑc-°õàw6&ßñÏýÙ)§íçé:›©/U¤ ÔÏɰ÷ðìúèÉtÞþtð‘›U|.D'?Ðsƒ*OCk¬ Þλ¨[ê\3Q¶¥HÅ/ybÒYä¶R'{â(¸ÑŒö!× Ñ¾,{û'†y¥˜Þ Ou›Ï(ž:b´B?ÛGsâî˜Ø“oš ÜJž™*V?Ævq(c¶© „rznz÷²[{¯¼úŠe8‚\âóªh©e’šàî—ë«§sÁê‹÷_‘0ý€WôŠu?9•?”+õ]<”n3£å·$o¸­H¹gÝS’{¢“ÑÛÞbò‹C5lh:áÃì¥xp¦ëý{èKKëåú®/&•Î*µ¯–jþtNÒM™OýôN@ƒÁq ›•k1º÷'VüQ¸žRi#Ù¬6´¥•v”@Ó\è¦Ýá7mäc,;Á”_É-O¹ Ž3/_ƒ1^´ÄÎ Èqß,ÌbV¨*jü=¿àB¬;Ww‹ˆ¶Ë˜Á½´¢"Ü0¾ ¦+8M ²8Å…¾S³´ ýhŒ¿'c•–:dëZM¥ *]n³t¦°ãš߀Z¹BVÌ`óÃ0¼uiò9D6ýÀ}î`öI\¼³š×ÛôÉžcê—;™ÉçÙèvÙËà §Å3ž•ìàžaAJKÔ X驹”Ù¿ùxÆ„Â|YN6€³D‘|€…:¶™‹%P똑¹OÅêGgä Éj Èû\£‘?G3}ÝT–ìH<îlF%€]Ôy^zïãGg /³(ç^K—@àé½ÎJ4Jl¥&m‰W®™{Ì$4‡ä¿‡4G.ÒÀ`Ÿªî¨‰ÛÓÆ\Ek–®¦n$WU{A[QTúç©)%ºa¦ñbò¹rfalñ$eìaK¥Õ\=2K^ÉmLŠ®o^ညräUYü¿UäS/¦1óýÕbl%à'¼÷¡æ 5·4F#F$ßFTô_êíàiÀC³Î$TïûÂÙ­ô¿ÙvÀhû/ÿ ‘š) è:ñýŒSbˆûíu]R÷ˆ‰£&ñ©ròÎh•%Ož×~âÃÜÉ—Pͨ¦fYÌs›¬= O¯4j¦5Ù¡¬‹(Oíl¯ìÆ”léñî/ö¥„3ª·0“ª È)åUA²¦öI³mÀù@›ŸÁ-=·&%̇„GÅ@[™øF]1êNÛè>20hÇR³m¢9I¤¤e?kòP±ÓLxW‡0.5È1y¨ÜàÅ:]Ì—ÛŠÛ]Gûã³Ï&y²n‰éõM÷t™mÌ蹿õ‘€t"aÁ+I%ñRV.s9âèR}élœÏ8‚«køfqŸàÙ ãÁ$;ß•n“,>ϧö¤+$MÌ¥®Ìo-IûöÀ™ËWtÏ¿ØñÐÒ¢áÂñ1¹!Tv/qOqÞò)y»G† ˜¥¶?*@¾Ù*íã–GA6#f½}kRÊYê½Óœ Ä‹»ÌçÅÐÔ»’üÕÏ!š­‡u<‰(ë—[Ú Ëhì¢CX¼kë“ÝVF4%à¾eNŸhn÷ö•I ðîO û1jœWíï£Ñ$w eæH'ÃLÜ@Ñ[¶÷|«(Ø_Ûq:„dÔ$sà7¤âÚ²þ8­bêÔˆª~¦Ržr7¿ºÎ9áM+sü½±ÿ?ö3™‚l£þA'}s­˜Cþ]ßäO+=¤XgÔ5aj'SœvÎÀù…õ™?ø¾V‚öåƒ]¥%‡b±P(»>\ù¥àVªY{f‰ˆòAæó£ þ´G¯jÝgMù5ŸñnPær’ 0ÚÁ6ÖA+¯÷ºúÆ!àU'L csÄëoéµlÅ`yÐq0X0¢H{Ò hI¢˜Øõ½$•îP¬n│æùö„@_¨>·ÞuìzŸFKÊTö°Ç+?u74¼×#KhLt+D¸™hY;ªõ€A{¸M"ñ¤L ì°œô·8QnE"ÔÒñ}ã/—ß`U.PLÛfÃäßêqÁ¯j¬ ¹dÁÞs;:³»ÖAZåb?«· ¿ õV˜ò-ï&ZüäönHðVÔUÞ³J=¡_1q:wÖ,ø–J VÐsÈP7B!ALh¾x!Iû›}• …ºs5Uz a϶ϩ¹pómE ŸˆJ'Ñ€pvÈø8ø¥©¶Áš[dð¨ÅõTRd#ûÌ|ð§ÉšÔYýú3€âöÍ#ÔkUUµ˜‘D¾mo!ýœO½¶+S­¦59¥=ôõ‡§­Ë†…b4êÀ™[¤J¿Ÿ¯Ï¸Û¨t¢ ônCO¾…‡Óº9žr±k*~1›N2àB o© aER ©D¥¯•dtԹ鋻íž:ÌN³…oG#ê€ kwñ¨§¾·4 ×äqö¹#‰9ÑpÏpS‚¶îÂ_£‰à¨ý­ò݉tŒ$—°Jíh I—QËdWÛé'[¥M’u‘l‹z}ŸÑ¸G¦2¾•©ðËUœ”å^¹6¾?î’£­F$€z˜þ<`Z)Wh ¥Œa£Ä®IxÅ&–ßx#§óCÜÈÞFبñ¾à¡Á©„!¸›_Š+ékPdižP?f–ê¦ ¬&‡ÂGë˜ÈL£ˆp;Hz‰b$i;M² ôu¢¡rd2äeu w(¦Pæ^“jy6eïþmCy+=)ym&¥³¥îN^÷SŠp ™ýüª[íåO  SsöDþóXðîU0‚Ã.ZJ³ Q>¶›2άÍXU-²Ð÷žôgg]$2MZ&«+µï¾GÈ¢WþôcôSP-Nclp¦p¸ÄäÔê¬Ôg¢Vb\оBl1yg0[¼£?:xØ6ÄÔB´Žýl' xTOC\ꋹ7z ÔòPøA7Ò2`ïP´d°õ5gø—^mùñæ»Çu*ÄûDÆNX“ŽíKÒ!l\pè;¯ë£K€#ÞAúÅ«y\þ>CC¡‰Ã÷Eé4‡¡û×ç¸ÉØÉýÔb DÄäíWõ¶íœ÷ÎÐ|.Ö¦•9\òwí[AþXºÃ‹Þ´GÁLS%S˪†)«8ØùoÿÄZ2yð>ö‹à÷ÏN·ˆËÌX‡EÔùáʼÁLÑ-2ßæz¨=<™{œè—¯{n¦@ʤɑ4¦‹újöšWÃã~å|=š×-:¾M Ý ç³n€ˆóŸå<»øÐ¥ºþVIÌVû+™`p ·ß*LyèŠ)Gžtv3v¯Ñ’YÁô†ðC¥/Ò{HíJ Lç IsÇ®‘PWT|3´#á”zݯ_ÅÛc_¢n!P[y^.4ÏK­*ôC‚ —ŽÍõf?tùÊ4=F–-_ÛE6ÆûœŸnE`ÀpC ‘µ³<óìK¹›# ÀoL©›ÝI@$«ÎÍ„Us"/oì­ØkóQíp’mGÙˆŽt«àXÉÀŠ¿gвäÿYU6b`sC+tDçòÖUXªÌ–¶!¸‹Aªœã }â5wëàÄoûµ¿©¥ׇ6HFÕbÛ™è` ™S0Áôñt2N¤Xï€(þ 9Xër¨y®¦6ó9dä¼³ ‰DB–ÇSG-Dñçi²(eØÞ}dQ°«¯1_½(Øj×:€þ»>þ ôÜþEí†Ò.Úë>Ëû©rë‘ F3±Ò­Z¨fH 0l1R¤EO¨1 œ1sŸüCròR 0Ÿ‘_Ž Çàù®DÖ펕?7’8 ¥x]ÒvÜ?ðG¼o¨jºÑŠù…îõÆ%A ô[ËEùåcvêì£O-Ø*P.ÈQãÌ5žceý"¨ˆÝŠ2éʈì1ë·q”ê"›€‹lµšõi·=ÎÿC/L7¦ j†Zõ:*}ó³™ÁýT{g<ìäjÕ~؉HpíR1;‹ä žŽy’;¥#ÊÝè}e\š0—˜0`´ÛÚ3ýÂñî>‘+â¡§ø¯Ò„ß\ñ¬‹úǾ8—V⟚H¼~É{\è®Ç{nV­ûÅö&tŠâ#`+ï]d°AW²baȘ E3‰€ÔtbI„Ql¡m >Dááp óŽYæ·¦:¹‡l÷}E‡ˆúâÞ›ÔŸ„¦tÃäÃ3¬GŸ5ëTÖ?i˜J s¦sùU£³Ô$ƒÚ ‚m#J𬅗7F¹ˆV¤Ár¼}f&hY[Ol²#ÀrgJI¼ªSê3ÍÕvÞÉ˶ ïÅyç»+<³h½z™ÒÉ1ì2¢1%ª¡uæ¥oÄ]î(ÀÛÃúr)úg‹³3P°*/Õ¿X4Ú%ˆÿÞ®àU&>àd¹·ÒæŒÆçOoÙ¸»¦ŽÉÓÔ)»Æ÷çµ±_q˜9­Œ"[Ø2wòS[Åkèt|8ï¦IØ$˜u®FDÇwoøK:ªÚ~€ÃYˆág„²ð¨XÓíHv$®þ8 \lúÍöBÔz¾ÖÑmM%{ˆùf”`Ï"þáë$¼Á³AüˆŠÙ©œb¾¥ñôÉd뙿BÄëúìèœÙ—`ª”¨OßåÛ.>IÛ7"=Ù˜õAÖ`µÒ4Ú‹{æ.Â…Î3˜çÞ$ ]ÐYNôm‰Ÿß B&‡ž/¼ŒøØ92%dLò¹Êï.P…*y·Ê~ò©·ââ Q'!0¸Z#c+ ãìÇá¾QÎö Ľû)kiDÌ÷Þ½°<{—E¡AƘ²z'µ1c>žJ‡CˆÍc×!4 :G•âœR»w$_Ô!,žËNƒ£8V ¿ŒÁ 1Û‹cW¨Ç©Bb‡ý!—_Gml®n%Ïê=xåy•›0Øš•¸Ô§‰ùÕH5+H-5h¢XF®oÇÿ¸’dúÛÄ­ÙBÛM{ÀßÀZ ”¦h³ñ¹Š–¦‚ðæLËHöWNi‚5‰Ò‚G¦ðâ§ßY¡3c¹NµÔ0ðOmòŒfú‘fÁö¢ô±ˆ¦+ZŒ~ú-\1q:÷¨ 棋€†}vÀ*[O÷9¸4ŠNLEèWsÅ6²ÃN'EZ@¶ÀªäƒìÊ î¨làÃôÒ[=ÂAÁ‡·~öÔ1Xñ[éV¬#UϸÎ7AÔ-ˆ-ZT^ܰ|ÞòHE•¼îz%!Ghýi{•àc4ú&¸Ÿ¹ü%(_Eùì0Óï ³ÏbãåÌTòx†û¼2yyÜø÷±ÒRúãV£†ôBmlStù¸381[¹åa»&ÁˆŸw¾Œí/T…r—HLžÍ%ßß E²e„Lu`(QN©6€š—ëµòcßùùwS1Ö‘) PßG5êñBq˜iа¸ ÎÚI+Ή‰áVÙórOI±)r'°F0iêCáû‘P‰BĶ'z¼ÂÇÖh9{© #b‘{¿ôÅ|fóç³ïÍuîÏb}{˜;©Úv5—Mùá¾a‚%+­Öé²w™ªY™Q£÷8F»ïí i\ <0òC>Ý<ÇL*AÊ's³ æÖ$¦Öªñ„@ˆ)gÁä†N8¯ÀsÈ#Þs¶­o¾hP_ÚÂZyòÛz”\³fŽ÷O ƒ"s,Ù'Ú yh‡ØæÃð Þ¬þgtïÜÈ@[wD¦ çÏu­Îw·pöE£~£(™ä¥¨6.ªOŽ[Â1šKü^FÍ€æ:A¿þ%° 6aÞ/úœ® ³U"ëE¯–pIx±±ƒÊ@ñ|S¸ØX2¿W‘O¬R£¦/U ryµ‚º=“9’¢ ×dÞDW}Š!í_·kÒ9b¿û¦*ÚD~¥ lô¬•Âݸ1¥ÆhlGbñú‡¹/8<}uÄEyºîa•Ä»1o`‘µ³0Ù%£äËÙõwIFqÕòü$ÛGw€Y°?8ê<ÁÌ‘9°Žç´ëb鬺¬âö(nlp gØ‘DÅðûègË„·ò&„A—aô ˜Ä]Ì/™`9“åJrV#šgÒ•e<ù“çÖHhÒ¦^÷mÖ™O1<[E®3þÒZž°âã³r)™Z«¶ÛfZFõi3c)5&ßÝÔíu™!ˆ‹ë0üŠê'‰IxÉ´Ró¨rªášÀ1•'i#WlMD9{äïK¦^{±_ #$äMh‹Ïò]õÕ Ò‡CÙMD _‘C÷1 -½•KÐ6œÁVó˜Ð÷Éø;ש, endstream endobj 2837 0 obj << /Length1 1630 /Length2 18662 /Length3 0 /Length 19507 /Filter /FlateDecode >> stream xÚ¬¶c”e]³%œ¶U™•:ig¥mÛ¶mÛ¶ÍJÛ¶mWÚ¶ýÕó¾}ûö¸_÷Ÿîû㌱WD¬3bÆŽ}Häiøl ŒElmœhèié82æÖÎŽ ¶Ö2¶ìR4 Ʀ΀¿vfAc}'s[!}'c€ª±@ÈØÀÀ ggg‡!ÚÚ¹;˜›š9È•T)¨¨¨ÿÓòOÀÀý?<o:š›ÚHÿ>¸[ÙÚYÛ8ý…ø¿¾¨hl p23˜˜[eåÔÅeDä¢2ÊQcc}+€œ³•¹!@ÊÜÐØÆÑ˜`bë°ú÷`hkcdþOiŽ´±øúG;cCó¿×ŒÝ íþqQ쌬Íÿ>̦ú6N{àd 0·1´r6ú‡À_»‰í¿Ù9Øþ°þëû &gëèähè`nçø›UNHäß<ÌôþÉíhþ× °5ùidkèüOIÿòý…ùëuÒ7·q8»9ý“ËÀ`dîhg¥ïþ7÷_0;óÑpv4·1ýOÔcS}#+cGÇ¿0±ÿéÎÖ ø_ª×·³³rÿ×mÛEýOæNŽÆV&´0ô s:ýÍmjnóëŸY·1±ÐÓýÛnäl÷>c‡5ˆüŸ™¡øKBßÈÖÆÊ`dlóKÆÖéoJùÿÊ´ÿ}"ÿ7Hüß"ð‹¼ÿoâþWþ——øÿõ}þ¯Ð"ÎVV2úÖàß;ðwÉèÛþî€àŸEc¥ïðÿ»£omnåþºõ_£UÿM÷ÿ&î¤ÿ·-ü6¦¥¡£¥û·ÑÜQÄÜÍØHÎÜÉÐ `¢oõ·gÿ²+Û;X™ÛÿÕö_mÐÐÓÑýŸ’™¹¡¥Í?"0ÿÛelcô_+ø+׿øÿ’V‘“—¦úß,ØÊý'%w»¿ÜþG5Ò¶FÿóðŒ€€­À“†ž… @ÃÀFÿ÷ýûKˆÉû“ò_@ôÿy–Öwr0whþ­›Žþ_Õÿßž´ÿ Œ°¡­Ñ?££è¤ocôwÚþ§á·¡³ƒÃ_‘ÿµþVýçͽ±±›±!ÌÚ²­!gEZfºSíÜáI!Íþ^zÐá`»’¥Âß~Õ¶=¾ia;ìz5Á´Ó_mîKgvŸ”‡£½Vd=)ÆWù8ÞD}¿‘7I;X©~é”À§Ÿ«Fy^/Jmƒi°Ð©îNÊ+è@àNw0:@]?Sø¹üöC#~²Cð1L­EïDjB©-8;'M´—‹KæR\^n:Ñ~ÞÒgso“g2ðõ¹"-»†t»ˆ¬õ”8³BËQÃj\Õ0`T¥)ž.ù& ì2·\7%Ë­'©,ù [c)Õ(NI/ªž*Q#¢ µ!_±ú"©l¡*fk$kÿRÝ`·:G¤'·@;4úÇßrŒü@r€fö5$!Ä{þËBÕ—*BTðFs`#LÝ œ=y>£<™?>`­5—O ²4yU¯BWL6ŒŽº6næL»Qüîw±ë¦<}TÐ<ò…úHtß»‹}ùÂ6Žl´jÕ@‚E[%¢ÅTq;¤ˆåeJµñ”˜Ó•Û…YÞ¶ÌS‰U Êô¬,œ¿o6Ú?ùÞbß\EÏ3›p§€)°{Ñé×7μë¥2@AÆÂ-p¨g±~®F2ÎÖ2S1[%¦ù¬é³f¨ö댆 X`pr‘÷HjíϤ—)üHÁ?¹{1‰ôK­`taì¥AX‰(6GËÜèÒ¥éÏ<_ຬÝöÀMߥª?×{l¸’9 õçÈÝW"†Û¸0}OÙÅðøæô¢çð²k,_ât‘ëóå'Ä)ÉÓq¥+~Ù÷q©õ"ò¤å¸Ž%Ü¥¡Óè [ùÃÓ,'w j@Bí´Ê‰ï:RŸ¾ó­RjÙ?äìµWõÄZ޾™_†y€&ZüY˜“¾ËÌÂcÒ=ˆÝ;à*›¢Ú¯?iw‚]˜ù©³‹]Iºó’ÿ)ê™ã¦õ¸§ü6ÀG%ÄÀX&:áé‹Âu˜x^ÍÕGÒ!x§+>æ$¸¶Ö¸¯=JAëßyolô#b“³1pæIÆE§1ÙÛ ãÈÉWW6Ú˜~öKVñ» Yëù#Øn6ߤlL¹¸+Íf’‹J%tÌEp7!Lîßî26r§qþî5q Σ—¶Çª¸ÚM3ÿc>÷¦ ¥°°B²~z`u87|MÆÜ×}yTwMG<¶ðAw"m&4Ÿƒ#Õ\¼(Òm|6qº}÷vˆœjœ^79¿”@xÅéjŸ=·ž)–I§È:—øU´íRÜtñ¼zž¹‘µeI¿îZMÛ>î®_6#ƒUŠÉ" ä\þŠÕÖS)ýWög|ZºÉøœ.ÿs9Ìezj1\,S)°{†GŸ§Í/a(j®ÕV°ÙˆeêÃGì ý× 9ô—LT¨ l`9„X ÿýšÂ½—»öõ ñÂE%Á—%]‘L)ÊXÔDNÐt~tAÁ¾ëVz [gGD9ϼr÷Ýí^ô”‘{Ýü¸Þèk"ó¼k.÷GBVÊ—<•m¼:ζIwx ¤ÀK¼“>òœ‹8{ÚœŒœ®14btÐÕ wâ>âRvÍ êoê¡Ó…«fZò×#™k õ”w‰- £·®rÖ¾‹ÖÕѯklÖ‚MÊi¹’챫žý_‘röh5î ›(ºE^>ƒ£Ö¶ žeØ•y3goÕVìŸPìÇcw÷ ¥D‘| „Y˜ßú÷\ SÒài”Çn´=óAá:ɰ Ç©° ËÌ7YˆÞzR­"?êVŠ_‚‘¹æ÷Úº×ÏyÞǯÛ+²þP?&r|‚|*“ð¬VŠ ^w¡,é›À3à¸7Òd{?¾²å“û{€cǸ´Æ¨†aÒÛÛ Û˜îä@ª„þ´mÚ;›\×Ñ›Ä;ƒw±ˆ¥>réªD;E—œÒàÉÊ…¸Oñ&²¦!êÔ;—úçöŠT-µýï"üêK/ùƒD¸!—tþvsNúÏ—CŒÊÛ¼¤øá>\`œwG¯uÄ•¨q>«ðH¸¬–+Ëßú÷55é†VåI â]Æ$ÀJ“.¦‚V'Pºœ«õ¥\EÄõr€¤@`?㨓ì’Õ€  PjPË–Ý[Bÿ'š°JD¨ò¥·y£”]¥‰lJÀuýd©_ŸÇh‚¦¯)e" )sÌ¥ÞŠ)•̕ʳî‚6z>›Gfnð ,2;»k*3^,­Àâ,s$lu¼&GlÏH‘­ÉÌd ®z;{cTéöV:àUг0¹9/¬mU>rbÇÔ8kï£ðôšÏAQ£‘¼bJ›Oñ‘ª÷/ «@¬EíÓUîZ#ÇÚMöìÀôh˜€z=åCk‰Ø† ¦Ã )àĺ2ágÄ¥*¼åò& ÇÈÐô›eç` Pº-¾ù€ iKiÒ%–þ¢ŸóhŸ…âm˜ŠïÞP§­Ó³Ê É„N-gÍÞ—šcàé}Š0¼ÄŒš«y˜õÝÙqL:ISUŒ{}î¹|ö¿ßëÁ†—2µ–ýrS Ӻ…¦ ´°r;MÔšuê"»×0†¿ÖKà”MYbã™|¨Ž,ÕõŠ’{„.(k¥‚ù#ßô¥>9Ýõ$Þ˜y‰*yªŠBp;ª‘¤Ð|M%Ë]nÖ’}} k ±A‹½½¡¸O½\úŒÑ¾¤ºKP}ž `õhvHs&³¸:݈}{°ÿãûÆÆ.½ô‡Ñ; ò©yùbßçÚuy(åú¥ð•ÿK_©ø¹&âl± 4ÕÍ5ïÙõuþ)9Z!)P‘#üKJ"ëRGÐÀ0-P¼cöÑ”gÆÔ:3Z*9QÃŽö$ úôLgõy©&JêgC"H­Ð®žlÊÕJ† ¼Îž—ŒUºÎNéÅùf]ÜßsX»dí·ž°¿O13¸×€zì$YÕf¡3™ cSŠ”#o»ÄÓ¦­Në˜) ¦•¸¹|‘õ>þQòð$çzi”~¨¡”ô°O%5™aXáƒ}uÈÄ›ÆÃÛø¼q|q?¡ÐÉ­ŒêhkFyÞg-þóõ½ÏSWUú´èäe*Zª‹$Ùƒ³æHJ,,äÂÐ<É˧ʨYÂaT›S­d[ݾŒ5sH„˜r·»l#¬×­£­uwì%7lìâŠi„møŽëá^"ë2(‰Â¬^:×ç˜Âù¾Þæ³ 8;„@Â÷ÕG×3 c|²¡ð¤–Á ÂÉÃ×Ô󓤌ŸÇ… ¶^Ö[×Ï»§¹Hؼ(Û0V8m-¬f‚,¶—݇Ķþoâ5 ¢¢µ¢×ìØ…™<ü.`±ž”Út ]çij²<S³j†»E‘‚”ºneݹ¡×9·¯©±k)½VLÚe[䦋C]â)Rœ¸ª؉˜‹’Їe`)ôÚ c»¨JÙÕF9þ*W–oiì(f aŠÓç¯5Óͳà¨ä¤¿¯eaa+›¤tGÒû‹® ¯çˆº_íé•ä½uI=yMÆ5}´—ûï…²rú xÛú`\Î/r”u™zçÕ¹X£"•–§õ n„ugµa6Ú'©;…õ…’XG'†MoÀim‹îO·3¨øL9Žþ ïØÏA‘7h’Ó¼[ŒN­PÓZ…K"¢cêîГ´h–Øšþr"̪·Šùãsý¹±¹¿ÛãÏUPÙÆÁõHø†AU+Œr—JœöU'ÛníHS’1ô,µí5¹•‚p2 ©ðLúÚ–]AŸmÔ¢Óó8•Úœ_Ûç¬×PØS²MûËÂ,Ão¦û˜+Æ'·0×$>»þ‚ ,$ùÉ€1#Òpm¤VMñåæõ+ëȸBTI…ýh–lä~fp ø’µÖ–Hs§œbÏ5“”<œ.Ýv&umV‡h¹íMþ›šr=Ùá à)Æ ƒÐˆ÷bº±äÁ˜Eþ¸'°3¼ÇÝ~A`¡ù¼qÄX&¯ \ð‡È>`Ú³ZS}ç>UA) µR¹s®.vƒJg½|4s[z"¸_Ÿe[‰Q+©š®ßÐ Õ¥+ ?s-nEt¾ªâq<¯3Ž7}exËÚ(-ï•…’,dô:Š&¨$u¿˜»j =~¢Ö’< œ-TëqÏ1U§>ynÂ?b¦µ: ætð¸±'„h”‡ÿ1¶kÀ ̘~¨{˜ÍÝÐëÕŸô•çÊ— ­x¿³ËA’; ÃŠÂ‡Ø!аÚËg€™TÑ0D0“Ó —QØD5çŠÚþ@ˆ¦AÉðå¾L˜ƒKÂK9Tç´ojŠIŽüæroÿ“4 YWn ÒÐz‡ˆåÑ?¼CèóºŒÎr‡Tú¡­«áΟïqÎýŸ „šÚ %–Ò˜$Ù†4X§ª­Å~¹Öu Np5d%L$™‰¹0§´RRûLGC$èJ3ØKáfJîîëæ¿üÒä‹g/x_/¾|ªÑéç1Ö†<=#Ò7,´ã8­µœiL‹uÅ’J"G6ÙMåÄø7Ù´…!Ü ¡‰¦ôðRŽ ×±Ò<ô?À¸êoL”T×ΘeU\'þ!$‹zHÚ]ßg¢åa¡?ËG,^Ù7ôÒkcm¢¡ÏBkÆâuêI~ŸäÞ­+[Üþ¶çX:ºõ˜“mhB™Bï ÃGܪjÓL¾z @Áõ ~·? ‹M2‰Ñ®Á„[NZýIu‘&@NzT.ôÒõ72 Ý¸úƒÈ å‘xHïð|xõ¤QŸSê°®”žÜ}òC:%™jÇÛYØœäJšâи)ŽåË¡ÁäœQ§z­kæõf@²™wu3³2ø íJpB Ú¥äÀO¢|hŸ-øùò=³šúýýmw?¼rEŒ}O|Þ“|mîq'õ§¶2Èìýüönéwåí̶¤ l«>í¶„šô{~Ònœø„X¿¤«/áä¥6íô:‹öJ^UCôËØU¶n¼» lŠ„£#Q¨‚zwEÝÌãDû0 .é©T “2Fù9ÛŸÇYŽnJ*Y2]U#Iú ´À˜­hú6©¶“˜Ý›í¥¼¨.¾a T­utKQ†×$ËÃ]kFÃæÉå-š i¶Tù€ôÁUêT¼ÆØD©¬=_:ÇÅCКbdÒ¨ 'H·ƒÂçƒ'­F/Ö&) æ¤2¶›‹Ûªö£™ÞáuíÖ’‡Ñ;1X]ÅÙ%*¸ÄB>1¸;tÁCfÍ9©Ï½œ³+K¢œHâ•ÅÃS ž…k"Ä{÷yŸò:¥Y V%$AKKT<©o¶æ”SŒ£pÅGÔ[ª…jÚý"ÞÇ?^?åûÈX–­!”8'1˜$WbÉž¯„ &:·úÁþ„Úè•Ç {µ ¸2 –Ǥd“.UäuðÅW–Z7…ì.ÑT@A=Z¼Ùl™ó훼³+*ðÒXòÉPHIoЉÑiÁžº,¦¢%ûÂt‘_÷í+ݾ¼§ÅMt‰•! 랺É&\'a)ÅŠLì®Ô8(Eât’)‹´un¢:o)/6тެWÀ. ÔÜy¯t6±M¹8Èé€âŠ´’Éo¸ÓùăUÈ!Á7/ Žtpÿ¥kŽšAè—”“;¨»“„ÖYµï"ð†M¡÷[-ç‘ç»R<÷;wÝT°¦L>åÍ>Ÿ5‹t¿ós,׺]Q7õ÷†ëÌ8o¾¤ÊùÃà)NæšõRæ!rIça!JsâÌ19*'Ë#jIбÕÞ{­ÓÈRã.½&´Ni2½_¦_d[3eC9ô7-»)x ç!Ñ ƒ»—3!—¶Ô€‚ªÞÐŽ¾@F§_ŸCgiL°¬ÔB¦Ó ~#ÙÁ•…Ðò˜—ª¯uЗØ-Í`+c,Å=du×âŠÑM{ Ì%Ã!˜d=ð-œÏõ„Ù›­ŽÝl„D½mv‡`¤§Œä¸è#PZ03€‡ùN –Ëö8aI|?¹3]Å5HüF;gfÒÿ”cEe^9$PZË…ž³Q”_x†'(½=G÷X˜^~ø vC®òe˜…ž¯WÚ»E×XÝBl¿" #xZ…ê–Oû³hû5]* åËbM ٱ©è—åk|HÂù@=>bÓåÁ¤™ u°S¿Ž{7»LyÝ'qû±› Ñò‹gÚ† y¿‘wÍÀÔÓ» ‚x»cž#G~€D©“äuuM ÷r¡ØÄŽŽÿiØ¡Ú-ûÊ*1„ ÔÇÓ'v_êÖåïÕ”PZŠÿr*)ú~̨M žR)_kÞ¨ÂRưÉ.ºñ’þwÁ—³P/Ï~onTar¹W”öL„¡]ÕOg>ŽªúÉ‹|ŸÇç£Rz¶³ºÙóŒœËKû59ó+“Ø[|Ya”ÓCdY3³Ýfré±Ðyl:lÎ[ŠñÙC:cÌ^HÛ÷µµÖX¿ý,‡_QŒú§Íܯ'g Öý9=ñåu Þœ¿*©ÑÚ ÎÐFÇ(e:}l¡ö¸ö6‘Ҝկç6>-ë™Bæbì㑬´Ñ;rJÕ¥¤´ ƒc +YO|ÎòP|aÊ äïÀ ÚÆÎ ‰Ã¶*ÃmĚƂô‰S’ ékþ@º„Î4|#®ºÞn£…ú$&k QœTʆ«Oí'Ð3‡9”çTŒþâú!´ÖÉhÕ6-AcœåÆŸ¹Þ’PÞÒ¸ÜÄ^”9¢ÏZ܆Ñ”O_Ì‚ ¾ŠÖÏnÑl&ÇágnŸÔM§g| ¥ªÙM‰ß؆»´Ý¹Êð「€é_ŸÖÇšCþôr|U2É«¨ŠÜæI nÿ=“¾}m ñó:Íh"q½3”ó,_ô]žÐC£¶Gqç$„w¾8 “ ðaø Eül$¸U!bG"'èϽrg4;Eü ôgn½DIìRŒK~É¥÷+}-le«Ç»/¢#Ы;<Œ!Ž‹ Äaýv{“/ßMÑE„/¾Á'¼ij̪Az¥«Þmw0ç!«9»»k‘Õ–zÔmÑ"6ê•©qjô* N¬„"˜lÇ~ŒaîÇ÷ nÇ‹'tdšOßwu;]Æ2uië(fÝŒydÔ¢·6>ì] Ûǃç½lÃ5_ñ‚îÜå¨Èó5ô£™%…zj ï\ô36HówÔ‰y¸ú×È÷ÄÁ þêòˆ.žÚhW\ÙaÏ ØòØ^ÁŠuð1ÉC?-ÑŽÂD±íÔÁü5œ¬5À¢3`÷ܯ¸¦B„Ï…z(„¨Ïmp¬öFvœ$ÇxzÓ’‚Oö3ÓTeÚ‚ ¥.æd^Ìɬhy’»ÊŒ½)•ÍÆ¹˜)²úó4©!Î×90Pƒs™?°Æ›ÇˆÀRÞ$ýuÁÚóëT¶k )¤bHnrع·¿ð<å]ik]uíéò•©« a ¨¥ùsæá(îl.*­2ñæò%Æ8#(|›¾ÂÑRÃH2¾·Ì<†[ð/ÖcÞ]"»Jc¯¹èŸÔ!RÖ<Þ×>o  õ¼û9T»JâmÈ•[Õ£ ¦»ÖEÏ™ˆTôƳ…ÆÆh±¼£ñõèÐPT%Ɉ•¯Ðâ,9QÎíù} ·ö PcƒðmK%r1Y·!ë’ tºË»åC@©RÕS·d_Ë]óc*E[@œ Åa0^Ãoí6¸á¸DZ8 £Oá¨í€ Ù-+Y±±ë‚îex‘†ÖîE„_tŒ(ü׿ˆö|ÃŽ–ü„„Ä×] .s3mþ.N¶žWOáP´›¯Ê¼¬µûN™¦Ewû‹C™D“3ŽÐ¨Miö øÓòŒÏ6E~iXôHªUÁ0Ô`EÐP}ÜÏú•ßeTÛ´ÊÎ0ËÕ¡’¤ÙâÔb Ë'ðª ñÉ[€iÑa.Å{ˆï’ý‚n’]*be<_Ð¥,ËÚÖ'ˆrA ]Š(JôèH©Û°ÝS‡ÏÇÕAzóÓá¨%ÿ%Í.­Íá²Ô“sÐ¥TñŸæ¢’P¼`ç&{GdàÌj >-Þà*;«‘£‡vÓ«§ÎÉÅ|}œ¤×©73ªWŒ'o¢âU¢”N÷’ð-C~Œq½­Ìê=÷±üž«ï GT~gca =wÉîGÂ'.‡à“bá<;ºŸzBx¿ëZÅL¸zyŠú>h”B@½ˆájiIËXÚ/QØ$;û?Z$J5¶­â¡‡EwC@ 'W«°ª5¯Ø³Û]-å¸1QA¤{¸Þ}:LäLXÍOª Ɉ@šQPG`Ó£Gq{Í=¦Ã;ˆÅ_7{”-ndRq@²üùoßôö°ŒdY‚þ2ëÄ¡jíÖú•ÁÃß¾…Tt§;j¬ÒCiŠ—wº1Î÷ù_£~PïòiBꙑ‰y†"Ëiê7ô±†r™†|ó§BVóÕ4³èŽ~宿«¢§ÿús¥±Xž«s» ¦·¥=ËËØé=ëÃ=¤¼mÉE.†¦µ.§(Ò6íß`ÖZ{æê ›:^XÅáÖu1óÈ$h¬­€¼.@§p7gk·„kBé¥eÔ*RÇ¥Ç"ATB¥e wdóÕÔqþźQºE0†ÅÚnßø'gØ`÷õ®ø]®Ðy^µ²íR%šã%7v ”1ç…m?Õ’ƒã2Ì"¡7nB»æÂ;ºH½‘@ÐWËëm½ÆkÌìZ!)blP®²#:H¿=‡x˜«'l‘ù,‹©0‹¯&¬!p]Ü/"Vw*®ñcîk^'¶³%k”Ò8:å%FÔõ¹-«pÖeKV´Ö3Nsz˜!tBõ•íªŽw”ä‘êzŸ¡ßËöWmR½Î­èÃ…ÊâDëÁI™åÇ‘Iœî…Õôøú„ kW#›oÞ¥àœ«Ïo]ëè#*Q,coˆÜ}›dö[zœ8 X¤°MÁ¨kSÊÑAk²½Ôî §g5äW8i$öÙ¹üýtóWrZ\¦ML—QšnN¬E”1l£j‚¶ èn pžzUÁ"×sü±³ïl )0¬\Q1’ß`H½®ªŽ×I§?Qß±=‘}Ü­âÅKÑTYf›Šë{¹is@ZFžû:A¯ó•Åýv9Y¿¸ïëyGz. öàsf€°gWžYxÁh™aA­.&~ ·ÚP³µö8žhç§“}ºƒ}àx(9ˆœ;’9Løi”7ÞÞÁØÀœ–ÐÃuÊ'N›zf‚Dz:Ø÷Žç^&¯°˜ã5£6ænô蘡e®ÐT» VyyÆ<ÏNm’ëg\&Ànrhø‘"MÝnÜ¿ EÉ“ÒýVLÅa ï©ê´±?ÂK•«±Ô*îRFÊ03r1PõÌØc AÓ /ë(pšë`=î.ÝÊDI˜sNø6f‡ÿ ß¼²«õ?SõÄÏ>êUÜJKr‹Çx uRðÑ7^~\;ÇCȘÊõ_ þ´€Ñ wÛh`Ôô׆yÈMÿƒ?¿fzžékÉ–³Gƒò6EþÝ£hö}Lè°GŸÆÕtê²¾NƒZòQ¸-¹ä(hàºDæÁÐ)Ï;°5Ý+ÊÆ,09JØ]õ;Ï'ÂûÓ;V}êOMìoüñ—žœÕû)¸œl€ýÈù±P‘¶±wÛR4m³šãÇ*ŠM@+_¥ì‰í Ö`h¬ÊzÚÌrÞŽ£+ÆM)2¸è§«¢œÀúŲ\ˆ(rÍíWJÇ|•D§„Žmó>¨Šù ¹ †×8‚86㇠ßML>ÅÌ…rÏ XÔ­à7'¥€—޳5‰_7¥øÅ‘­?o"Ÿ¾ç@ïû5‡Wê²*Ú;¢Skéâþí†Ö¦V‰]A¶ƒJðા²FK’q`úÏtè¡ãK³àKQj ¢CTÄ2W#ÐóC¥Žh9#´ÀbSˆÁZIB ZKˆ†ný—@AÔC㦦i[ô‚M1­V/Òœm^?ÜoyM&‹nTð§uûªožóg³gâΘà)¿BB¼±Zo”ÔI?=É=ðm=¨óšWV¼ŠÁêÁÌ®NŸfØ™ôü‘ˆï«RCrlg@Σèˆi$wü[Ðô¬Ež<ЯuÄzŽ*¨:øîå•á?÷e/0¯¯c(z§GŽnnÕøGõÎÕÛÆÇ¹ZD.þ#2ë0߀Ÿ.@Utý´LæÅt¸SO{õ‚IoZ.“ðÊ!}?X9E«µAó¬ì'ð1ºoõ›üΕS)ÚßåpÕBÕ X3L…·Q‚«,d_Æhë¡»ÎË~ñHÚsaæ„Ü`AÜæÂfsQ·‡-º‹#ˆj6‹¦7Îa!ÃOíÒç=}5ûý@=Á PäÚÝX¤W¾r*mËhE‡" ÒJL× ô­{üž©ô³J€+5àS®s¦Lk̤$÷Ád:ËÕ³ŸðE~7ç|oÉŒä‰o’E~œ©Ê–Ÿñ>Ãö°§âôäiyÖIåûÖø¥¶!ÙCh‘mºÖãÕòÜ”•ú"‘­¹M¯&‰þ Óú±š'.Ícb4Š´gÅàôn$ Ê.Å»1òÞ¶’!ZꯦÌLH<­¾” V¸;ºÍâ:ëäG+;b ++Î$ú# Ç:×€6¸³âo0ÃAñð*É™ï‰U.{*+3-ŒÎxw¤eêOÔØõ­)HÓG¢æ€ÅáJ;SFµO¬—:yèÁûÇ=—ï‘_ÿ–t>‹VA7K†I&n½¦Ï9 ‹=”%R†Ýœ€bïö¤y^X ’ —‰Q Ò˜hÁû «OáEÙa¢kj'b¥I ëTg:{£/€åƒ¸½Kû‰kTzÞ Fdß©ôC¨ÂÈoŸÝvµ tg-¸€ßP/÷ËÏ[ê¶Úê¨>Ñå±ÉwL´:À×·Ÿ(óùoLj ûí'ü4¥Hr¬­Ää æŸ¼ê?·oØ™Ë7%´vhÏMÊ9` „bØ"ž4•H°¹ :1gô‡{’Ë"º kÍíÑ¡å}4 +§”ô12Ì0ÚÖS'‘VÈ x¼ƒu´T´ª®v¿úEz„_Ô:º+?[Ë}Œ¬“®”Y?‰¥ÌJñƒPƒ†”üžvlŒ¢ìe£ œ&UïÍŒÆsE½.$·›KÚ<¦ ëmÈjOW×&{Á§ÙºðK˜Ï(Ÿ4@B%Y*yNNIÚ›™Š›¢u*L¤óë®CYoV;°ANèŒÆáj9Fåük`ì»p¼EÉæT‹æåZÂhkÁI´ú°#á“ÃRDl-b'xm†Å‹7Gò¥MÆæ¿ãüh®%ˆ¾‰ú«ìñ^ßž8ŸÐÆk4û)¡XîXÂW†Eñ¶h‰0‹Ëã_´MßÏý*fŸº_ƒî´¾4ï(yÒ.fø˜p5ÝÙë_G6ÝbÚD÷óÇY‡ž¥Ï.¦½øò‹³ì¢Â­Hs1–{ƒ||–>il’ñµÐ<ñîcºÅÅŸÜ­+º!&‘ç€2ıAKìw$J¸{Ë_…&)ŽSSk1öº»}¯Z$âKÐÝ®ZlòWVí×Q âxä2Ñ€s&¸%ƒ7øH ã|®²=‡É4RHÛa·œŸ¤Æ^CÕmj»&³*oC¾æ¥°wí­÷¦Öñ+Ù>RV¯ýZÙI*Å”æ0%×ôʼn5=ÁÑu]þ6E=£ ícŸ)†ÉRÀ>z²Ì#¿ ¿ëŠ ¸Žn|óú¶ l²™V˜ô~°Ñ),Ý]Znš9½öçâ‡jì§é‘²¥ã©ºu¯~œ†Xu~uÆ–™wBÛ>QR |—†ÝÉ!ºã4awCþ•› µ†\”üª-qñÂ[lV™ìS†W€îl ÀN~y,¯ßœIl­)¢ˆ“wÚ8Nm†cµ’êŸJxŽìÚÄ„çÐtS.eÊáBÈ€1>ð~1ŸÏÐŽ£R7é„sœÊqdG¨–§&}‹Â Êøô®y/…ܾނ8 5¥=I²åæ³å‘§Eû·®­;h·•L̈Ê[¢à«p:²íZŸÔø±îL­«°®îšüŽ #^}‰Tüƒ¾%Ú…­WôÔñ(`]ëyÇ7t /Òô¶©f˼+(°R÷À$Û1‡s¬bI³–Áx(ãÙ”ò±Þ ¢´Ô®¢+¶º¾œÌŸ«±@þæñ"!%¬ú˜Ü-T°ú^J²²ß³—l?•ÄR†¬AëîÄ š×"ß;‡ðÑsÏæ†3L_ÁfÏôúònë$cÒ¢2û7h=uÚ2lðQƒkîïbP*€‚‰¢ßÜiCØÂÜ—Oí )HZŠXÂR¸D¹—hM†.] Øa"Ç“˜ÅTPHWå·ý?tÀŠ·Zs’Ë„*{j O·ÿV/]΀'K%ºa£&7ÌÙ0BáÌí·ˆçœÍŸLÌŽ'n‰Àœ¢¸NÉê*ØØFг·ýCj¬_>½ƒ_rE«'¹lñ(»të;…ênÙ›6°£>›B¡ð, ™æò=²ÿ¥qhà}FWÀW´Þ>g3 ,úk!À<3ü© :ŠèÜ›QQûϱj¯®‡_©ç¬Pw£àï’ÅÕ<Ö?âJ±Âyr“W€ãâ`…Ù!æX0 •w¿dÚ–D&PHf´Î¤-$ñ\íÉ. 9·ï4°IŒï¢T¹T¨Ô´Åvm^Øÿ¡bï}**5üT¡|ɱ¡§ÿ$91ðC~Ìã6ü½­'ô`·cå¢ý´±ÊøRþŠkp_ÙK®»ñâÊ Ž8• ²–*½)ß“PDËÂTN£öV×y:«Ð"­(Ñ8Ä–°Z›Ø¢•œO¨«âQ½ÄRÚ?À96ÔIsËÛ¸‰õOWènûgtÌhL¤+®k‘¶¯KYöJLĘCÀIgô·RÆÐØ•…Ý µÄm‹+¼Ë`zÆ•víy]g!©*Hœó,Áj8ímIT¥E´b­ð¢¡ãˆžàæûÇ ‚>¾ÈŠÏüÏK6í‹Fc‘¨kÇ~-¬WžKŬ·‚õЏ†1ŒßbZèÑpÁvÓÚч¢e$3«<ö×Ü )˜‰÷.N.ɯ58+‡ï­‘œºð\P`€M¿Æëº–9’44Öõ¦=+ŸÐ…Ö>ÿT¨´šLEciu^0uÓ‡ßþ.4¨¢½ ôõï,MdÖY€ëðïäO†fŠýÈÂy1ÞÐôïÓy{›r7Z(‰ýÄ "gŠmzÞ}.Sãvãh¬ ÝKæùÇ’&äïêK{YÁ¯g¹Ûz0ÌÖO·Y…F-ðuÇû/GEôA(Ö~ôõä÷¡qÞQ*É»k¹†Û®})/Å›i$Om\¸Ÿ².Ã~ɪ˜ÒäÃ9Mr¬žxúáÀ)Z!Eø6L¿ É+-„¢×t=Z(6¸é Z*èÀ’—瀖èy7&7ÑvbQU†|ï † k5 l¬Œ9‘‹”Wè –é¦7¾iëû‡•”ŒE0É[v´Â¦³Ém$"ßâ+sõ\pQAe¨ð- ×AL' Ä 5[ÙÏø'm±FI§ÔU áꣻü¶?9Éc•2÷@Š…sQœÑ2CY醪 ÊŽàªY¨È€hååðÊé¤á o-œ°¸£ò>+8Êìõ°(à-âôë­I¯"2ÞJ£ÿTö ç)Ʋ²@Ü…6šŒÃZ²×ék[VBÖQ£„†`÷=8ÍëVo†Ciý9 ëçkyÊ܈È{EQŒF—˜+³;ºº¼ÿ—$Ä4 Zd\ñ8Î!Cã¯Îøb8ÿ“¯ÿ§ƒ@’>Oݵ<$þ÷vjåZßóúS©ÐØhúܹõ ¦¦Ý¯Óª<4‚`ãà®1µÒÇ/Ažûkè@|³¹=N¨6œÓôæQB\irÄö¡7†k/ 'ÄËO´kheßXp+,` fÖUJÏbÛ¼C1²ù³&fØ|Z6õÔâ†H9Gó>Gh@>ã!6 GHÃ××B$9ä¬IÎlë1Öö#¶§Ù˸€£M×D½Ï‡ó7“öpÆ HÍQxú01s®&™`ÞÂV•*S'¡rõ :fȇk<@ÍÓ'£«‘sŠ“ºàhHòKÅ®79<§îÇÇê›ßbðð'ËZ%(1&!j†š«–w¶ê§m>³rW#âk]ýÌÊá!rYÙA½£ßj §»Å=‰š˜Õé”='–Wï}~&úÊ?†ðz¢¦ž;êÚ.Jߦ¼Ðˆ°—äèk‹­)j^bµ‹ríæänª‰ez£Íe}:P¯VŒ8â-`x½zG$&VTO°Ù‚ã&â@ñß ò77y™&‚‘½PâÛ„÷™Ïh=;+ùÌ~'!Qø<ïzLÁ×.jL©|ý—Ÿ7B’³éXYlô.ëuX3„Èà2jXÌjty@ÑÕÀÛëo»?»í÷Ò’3IOø±Ùb$WQf„Z¨gš%ÔÏÀ¸%UeÑ\úóÔ˜>9IÅ*6bž)ä¹:!_3;Éj¶eå#Npü]?)²í}ÑÑÃ+@凭„¾„±½ÏSSÐKÐôƤ|ÝlQ Ô:œŽðÆ x7ÙG$>ðžƒjAt0¿2îî/ÝN6†Ö.B¢ûX»q—¹œÏ}Urlj™x;GÄwQjv0#¥=«^à…[z8þPo—ŽîîЛ…Ä?à_z”¼{Xé[‘„%¹ë®LC‡ç”g@#õeÉ%£‘ž4|üóx— Ð5E—FdȨ¹Æ2F¡Pª•¬vþA€ÎÝh «Õ»R¦;¿ró˜` !V=ÁÌ{)È(’ÝÜßW ÛD¡½B5šÿSXþ=Ö¡Ù k0xJ»¦È&‡gÖ‚Ùþ¤$M {ÒlÝU'2;„óQ±X_OFàĪ`±î¡ kiÇ$K¿5"­ÅèÑIÀ4žžîÄU¨i‘hç¾{âÜq˜¾4d}à}åÆAy—J‹õB$`þ¼PHáÐ.!-0¡"ë{YµúKîgè»s3ß«„Éw‰Ûm™E±\®É ?)Kœ\=á݆8D]ì>”&öͯCk¶ ÏOO•;ÔNsÑÎ.žkxì‹VŒ³ Hĵ*ˆê8ªµ zAé£RÓ?âzp(a_V HrÑ÷ç+0­cØЋ/Åì×à{gŸ ´[FRøÏÈw¤ÐÀQ´«D¤s.衺G†“'rÚY õXûMíøZß•éÅ0!T#ÙÎiÎéåˆÍ_Áù'qi—®ódRâŸÄ,ØãBEÍ©qÜQ~R€Ò ¾ø^rº!FÂË`qýß~ˆ‹ô%þ}×1`‘&…Á¼­ÀÐØyÆ2x©U 2¿yyçYÚW[^=ØÆÅOõÏžHÐú–0×èèµ$z£ïùh` kÖ­ËSW˜ÙôÈtÇm—>4u‡÷Ð1·M­,0 °à[|¯fΙ±ž%;’‚xµI¦2xdV4tšs´ìüì ¬úý0w¬J\eFÇæ @Ñh@ô99¤L:-v4zÕQÇŒöÔGt=ÑÇØ¼çNØeÁÅE9ñà¬tÊÅΘ µPjG‡/s„NŽëU›Ÿ‹e†ÝÚ)÷*BšHýeš™9æ‡Maº><¹ÁB G7ËýÊɈråCy0ì_sƒU“m¾ F:­‡¯I§gJ*BXƒ >Ù•A#­º©œûðR:zôŸö%¶¨6'eÅíë…ä% ìW‚&·2þ7Xv”wÇO=sM8noj2OýØ2ìT‘ñP ŠnCm–%{˜H£+ ©óúÙMûú*×2p˜HJÍâL>;6Rú¥fº‚Œ`S›¸¶-'Dµé:¬”<Æaú±#-"?qé*' æÞ^®«JÎñr¯Q6B§&{f¦ ïŸ[„ÊÆZ+Ø\ìk–îMÿm²Õ<à ‘YÌ”²ªiΨ™–¿X­ ¥&Œ{0%vÐ;ógÊ÷û8 m†!vD'&d!– U?4†Ë·ö‰½C*?Fòµ¨ ¨k09H5Qû\À±'iºV]›.,š" nÛ,+JÙA¨Ø# ™F~$•XèŠÕwÀàêYŽD/¸Âý>¯$Ê¥eÁÛh)ž³Iû hq½‡zfk®w¢ã¤Bo´±ž«Ãå›oèdxÆgŒmóä6f#J4eš£ [÷;+¼üÿ / Ðôã!­}û0^½Ð®¨®|ðIÐr=¯3…“ÀÛv]HÄ÷OU¨6¡;‰–0o‡ˆšî¶éyx»lªÖ‚GÞnØÙ2I+$·ƒ>’u1Å+ãî0Å}ÊyøSùlY ß™*’ü/>oˆÒ…¹ož—HEÊQ÷uôî…£ÅU– ßàðf8-ˆø0ð?_ðpËzWÄ­ovu²ü¬Úh3—‡©‹ãªÁY·:Æ) ­á-DÒ¸nxÆè•Ì’ÝÐÇ} &Äé6äjžcºë:ᴪǚ€ 0˜¨1dNO2™]Ǥ¡t()ÖS$ò(¶r”Õg6–g%–§Ø§Õ9ïh<±©ÙòÂÄËñ†ŒE·öæŽwNà ó\ÄÝê®Cqš}öS1’ \Ol©MÂ²É Ö»ùßâw^ÉKº’®IÀZ1€jéQýIG?ñ»h|B=I|°ª¡„Â…EöâáBdF˜®Oô¯{b¨ù}5¡ÉŠ®ÞúŸÌïÒÜ€{j¢ª+iÝRÎŽ?Ö­Â ê±Í,WM£Jݦ#ÖB”Èc>š§º­TvY‘FæáZ‡Â f†-.ñ¡d7¿'LŽåTVcÄÂþc”Q%‹Þs`«‡Ô>B]Õ‰m Ãa‘ã´rჷÜÝ™wÎLÀl8ç}‹ClÒä?ˆ"5`«nJ³ƒ— !­Oxù€mH9ña±©T6ÓàkbÙ©PXµ`êá…îUuR'"Ö2²÷ôw"ä‹YMM†‹âNÓ'):o%úQÛ²7(üÐÔGWïµÙl§ßN ŒÍã7ƒVà|x°pGÌo[ ÏCöÔ‰N– •8:{sÇÿ:ö›Ê˜øˆö¨DæºH3ÏlEo,jq”eczÄþ°Ÿ¢ÌÇk£ ”åz ÷3ß? Ëpzëz¡ÐWóÖƒପô'8QGý ã>»+û#Þ›®ò¶ä &2·e %óK鱆œþÏw$B2ÛH;¸Îש\é; ó8«ÿ ‰ž®½¬m–§Wò£A7Á½/$ëk!™ìò1)ôŸFâ’(Äœ[¦^îlÏ`.LDæ·g/ãÿw[(Œ•Sب‰¤™Þá$÷Fèl¡ò %vÃáccIÞk‡}þÖτZ¢á¥„·„Ͻgøð¹HŒ`… ÛWáÖ•-!ðA>9=-¥ÊoRžÀ‹Ûxê¶su]FJÒ‘0­í•ùÀâLãÞ¶Ì^}ý\ª¿”7èÛ_?ŸYB˜w[ºé´›Ú¯Eâ5ü“ãkÑ8š–| <Γuíì·4åCžœuHñ|¸mÊö’!óH•Ï/TÑÁ Ö7Hq븕L:î{Éé Ó¯äñ)yÒIfqÕü¨ëó°Y»sWöbç„©•p¹Î~ˆÝÚÀ ‘~‚,Eå‹êRyÔ°B4Hþ%ïõëÇo¹ýI‡?A™‚ÞÐ4Žð¨C` ¾ù(—ü>~6µoÚh'€²q¨b)óTð=ê0O‘î‰bJ^–3ŠÔ]µ99âxžõuû2íÔô<ºŒ|6˜Ò v¸¤6w–JÑ®y–¯@Fǯ¦Â”“”o%2GŠôYHÎjƒHG{¾¦1 ÓŽîu]š(»1êÔÉW‚8Qœ»³9÷a(‹¥æhÜç“p÷'4Û—©ê_r¤æ¨ÂæHDaªë…4NþAQy$»«¯¿°ûþ¾_èóΩೳ_¿z¿ý3¤=;-ïѰM[£¼ŽoŒä¬_PÓûñTóp¬ :áa²¹5J`оÄF%¾ ¢©0Ÿ;»¬~ý§ºur²Ã3ů¡ Æ»öQc½â¿Uº'®þè|)Oh,Æ]ŒÞŒ[çÚV\ã€Z¨b.{1rí0܉¾s4=ÙrLØùÄ_­Þ+ÕcdŠàˆ6 çÏ:òX„M¹ŒaßBMýè‹u¸VÖv}§¸AÉÐ÷ú¾?“ž.ÑäØ jÃÐúÔÑÝŽöä²¾Aé„ åð)¨g4É7Ê…¼âKã>–HÒà‡ðó@vÑãxÒPt ôá:Þ r¶>ú/ Ø®3$ &÷ˆ˜x'Ú*¦z( @F%Y¤³×È™7DÀ›¡¦* oŽ‚{v>¬pž.ssôyUþ #ǃùkKoèêôÍÀo·%ô»â[˜åH‡é‡ô”KÇ2ÚaìÛÉK¬Ý„3†šÏä|sLYcÒzQÂæ|T­ao„`[_ε°ÅC:Ðg„¬š‡{‘ä ¾G(m„Z³.òZBÈ62™®þJBÎ#1ÄÂúØ©Ë^m6¼¡ÛZÖ¯1ÅúiŜݜQ+ôn^Ž6®vÞ–r?T& QwÝA%´ÞÚ¨ƒO+¤CYÓc…HT¿Cõq ††!½ £sW|hŒgcÀjjÈð9oæºvrì¯Ú|0Ù7±OgòV“¦[_sz7ï0q§¼ kÚaNÓº^ň­ ‚êšÃ$‘{™ï bòJpÅíuš¹i Öæé¼Ó“ïî%ý鋞I£#@å°UUèo¦±hwé.ö %f®·ý³§K½±ÖÇOË£æŠð»KØôËmžÅI´ë#1ûcqT„\ï8ŒjÉRZ™ê7TÿÄ×Jõ£jås?R”ÃúàD9çóp,G€Bñ-õ„fПvtïÏú¬ùò\Ó«(aóNÔ ÁÞ›yü‚‘„k-;“ÏíùØ;¦ <é a‘’õ´9sÐ$ëÞ‡ÕBFï5¶æ:Ç.ÂtÝFVĤÍ3ö!Z9f!÷ñÑÒ!ûuFÇ—+Ú‚LÁ[¾Å Ò)×ë(:ÜÊñÊ›Ïa¸j=‰~¡jLôàzҒ̆B+/ô»PꃤœÛëÅ89ykš[ᘨncÔŒ‘°JÏ¿ÈR¶uIù¹µáP¸RÚÈk¶ÃŒ÷ÅSÉA,©w´ß\‹^€#Ê}*kÌ¢ÃnSR\¢©Ü’ÇFÛß¿,[?:5âTáöŸ¿µsٲݜĆ\WW'fVeÈ2í²¦g[£rIÂÍÜ"6$ÌÔxNlEŠ–ÔÀ`Æ0e"yÊÛÚ>õè]ôÍ,Ùšåc"ÍLz–Ä$SQîâÒdl­ß-»åЇݖøßV´ú^‘®r¯­†´L5po÷œ°µ©‘™£*4ï_b¶VÉäoc'×#IòÆyÒ0óqQ.P‚XÖ€YN,Öú¶;‘H.ÃÂËödVRmØŸ.4{Zn/RÊT¯©i Œ:ÏØõ¢˜MÄS 0˜Š]Ž tŸ•`÷sG4¡5YQ*St‰šY1lð¢Ej‡UiVE…¹³Î@®±b§Z:žç×ããce¢ 1µV&™ðŸÐrÝÿZÈ!S„<“镬ƒIZ aXªi<Í0™Ü¯¨be–¶Š;¿y$†É£Î6/xÌ•˜N²B;s¥M¦–PCà\Ðs¸Æ`³¬©ÏEqë•Rk¢1*ªç@$PÍ÷ºx­Áû\|êªñ€ª·è¤[‘£’ÞÉyAt“ endstream endobj 2839 0 obj << /Length1 1644 /Length2 10726 /Length3 0 /Length 11575 /Filter /FlateDecode >> stream xÚ­yU\Ü]²-î4hãîÁÝÝ-Hã4îîÜ]ƒ;×à ¸»îpÉ÷Ý™9¿9÷¼œ;Oýßµv­’U»^š‚DI•AØÔÎ(arf`adæ(XÚ»8©ØÙ*ØñÈ1¨Í]ïv QG ‘³¥HÌÈÈ ÐšÄ€&VV @ÔÎÞÃÑÒÜÂ@­®¢ICGGÿ/ËŸ+c ïžN–æ åû‡+ÐÆÎÞr~§ø_;ªg ÀÌÒUTÒ–VPK*¨$  £‘ @ÉÅØÆÒ gi9ifvŽ›¿;©åŸÒœß¹„F'{ ‰å»ÐÝhÿ¢Øm-œÞ¿–NsG#ó{œí– Ó? ¼ÛÍìþJÈÞÑîý†í;öN¦dçäìdâhiï xª$&ñwžÎFÎb;Y¾Ã;³÷›¦v&.Jú {§yG,ANg »óŸXÆ@€©¥“½‘Ç{ìw2{GË¿Òpq²™ÿ+z€#ÐÜÈÑÔèäôNóÎý§;ÿªð_ª7²··ñøËÛî¯[ÿÌÁÒÙ hcƈÀÂúÓÄù=¶¹%éϬHƒÌì,ÌÛM]ìÿ¹ÿjõŸ™¡yOÂÈÔdã0š!0)Ø9¿‡PÿïTfüωüø?"ðDÞÿ?qÿ]£ÿòˆÿßó¿SK¸ØØ(Ù¾Àß;ð¾dŒ@€÷=üY46FŽÿÍÇÈÖÒÆãòú÷ÛšÀ¿ÓýȤÞÛ" 2—†‡‘›™çoÀÒIÂÒhªdélb03²yïÛ_vu)ÐÑÆ|×÷¯ÖX˜™ÿ S³°4±ý‚ão2ý÷*Þ%û«&y%5Ii1ºÿ¾dTmއͅ“ëo¥÷±pVó°þo+·¥Ãɬ±·5®¬bðõ†ðG;›#Üù?™k?&ù­=НIj},VZ#؇ÚÂãÊÄû[ªþ‘¡Áî èÞ]|ºœXx >#ßäc’$gÏŽ× &¯Ð®\N•sYÍšÕè‰ênžøOó.Ää71›,é¿ØˆÌß„Áw˜…æceÝÎÂBcX‹è‰GE'Õd ê:æ¥O9—OëxÓ¬3yb,÷£æ%ÓÈŠ8Ö_Ñ5¨…¤úg3uBãM¥4˜¹ÑÒ•µ5¢ø'¹Øëð)ÄP¢„jýGÊ“¶„Š¿´;ûÁñwU©¥}¯Ë>Qbä·„døÂ²ïyíð‰YHHÛ*”ö$úöQ¥Œ=FpûDÊZ#¶Hù„UåÏÁ%hXÁ´¦˜Nô7Ù³ ¶ÇaèRk¶Ä¼ÑÒ¹WÞWÉÍݺ]iâÈ3‚Ÿ'úe¿nÁy4 jKuý+•…ˆQÈóeOÖ9yA™5®hl¤×:ÔÛ¬ÀÏjIÉìŽäÜNâ#ÌÜž³coSº ªç§Œ"‡ºGZ£ÌÄ Ô~¿1d2g¶9’©Ö‚¯ðµëDáêšÕßçGŠÛBÄ/nùÉ=O¬ÂŠ>AhøA$U¸­æµÚGQRØïÀ{»ºfÎÅååVa‘ítͽ»ô4y%ƒãhOëÙ7¤Û¯NºÂd­¤ÄY[›Tj¦@c¨Mt*7Éà—¹çºº«Y¯ßÊe)Ùå(4£ùd½éº«$MÉ*´ü¤ê‹å²Åª8lÑlBK CÜëœ4Ðn]݃ì1Yn ”Ø„Á”ßx®µÐÄP¯„iÞW‘b@G²Y‚›ªàçl+ Á@˜æ),ûBµÔüºMPdÈ«zÛ=c±9‚Ü-±Ù·¢…=.cWÌz­èàN•‹ŒÐ˜ß¶f{óÅAUÐøà# ú9Gr!zWø-{bûa—Ûe¹‹¡:³ ­4¢(3=i2zÜŒØå  ï|¹Ú(Ú‚©¹ˆ+Q3˜k®‰¦öô§iäÚ„2/Zœ­RÏ9Z7ð&9ïŠÞÊS©¡,|˜QŠó0ÎZôajâhU4 \áÚÊ\uI­|‹`-vcöž*3VÄ“âèWf+?®“s%s<‰»O*”kCVQvKîE“ŸO¶¹ú^¯àò&ÓÁKŽNOµF6©s¿£e°YºPÑËœ€êèÍö}ÄîÀÖçõÕþYyþCCPþûËê÷f[éë‘Á C³Q\x:ìïQ¤ãaŽ>ŠfCû⋲·f¼’-îË–rgk9O|qŽf8­R[Á€û‰ÏiP}w„9¬xß]=Ó‚.Ù¶B®·ÌÖ”OF–¹GEÀßD¾ë9›À w€ZÆ<Ø ˜}V´ T4'•ÙïiwÚ1]`E‘<ŽždóM7‰±¹RÞjFæ³ÜZØ+ p_ Ùê××ù‘3]é ZcS—?vx¯¦bÒÊ(ÌÍîB¦’XB<õ {™©íj¾9×Ír•Éç·À¶±þ6ê%ökæy[.:ýö4E²'f@îbTý!O…¸¸!—.Òk䄞†2š !±xDPÖ ÙpÎVœ®¨“%¹©#[nF/ij×¼,ˆñY[cç±é88˜Î‹›-è–vÓ[~CŠ. äãÚ #:Õf€éDÀ©hé`¦å¢‚ÌwYî9þTY#}“ñ="5£çójÿgSµ8ÅÖƒŽÜQÎß9XH—_ P?ÆÜrŠA4«¦ª÷Ä@;bŽj*wH›™P°—Öhæ*™›düDJ*:²¼W—NÔLì|êÏÝ& [ÎïÂë…·ÿÕ˜X)s¢Èjл …Wæ eûwH­õ+ï&Ež²ŸþÍ9ѤÞ(€ØSñÅÌACÑÃŽ‹ˆ`±)ÚöH?6úÎeÇB…9þŠ%õÉìkR*:VÉ­åô÷Ôyî¡óg¿=±y¢É½ìþˆItz3^ýŸAR$à=IÐP?I »Y®µŽêã«V/óVQ¼yM}÷j:gË(âN6âŒeëÉ×Z‘/Õ4”ÝìFÉ;èèøA³§fèµt²Æci²]@.PާU6ú Ü·ã!棽M‹³ói, SZ&‰p|QŸg?‡ -@4«ÜNj85C±ÿÉ@œ«ªëËïØ‡bÖi¡ZÂh"™Ý½ùä/\êÄÚA¬{à«g2"ùÈ '~þÓ&¤:£:ðòÁËÅ[™>c—Ôrõ'x«ä]€„GÜðãZjyˆk•…AK‰ õúOËcë*³;Õ…®tx [Tøqb?]‚&!A}2ô¦ð“>ÖA,œ zk-Öå¨6/Ãb|úH‰Š€}Ή/6¤_x±eˆ«ûÒ}jiù¼ ›~ö|½Ãþ°cíXÜÒ{GË þ<×V)#¾ŽÝR D$ü:2žr®·‹ö³-3¢DäL.o‹(zÆzc×ñ£U"ª¯Ú"9úøñ­ÊÆÔ1»ðÊ–‡Û¥5&DIÊLÔC[†»ÿÝ™X‘rÍ/•=ætaב@B:©ÄËV¿IÃÉE]Ë l.ëä™¶¢H}ä&cšã:T¸‘®Ò‹Ó¢ö¤;½ H°õTŽyxÖÜà}n†âB³pÑåiT¦tPbUMµ.’¿QÉÐæS¶Ü2S7„?‘@ñÂ7Ÿøts.*Ý ikƒçÅáOq7y¥ahßýô<Òär“@æVWÄV6µf‹¹àO¹.×F(4žÚU«á5Tbüš•Ñu0ªìÎÕÙ•v_€gÆmNGï͘%q½)·º!_‹*fXâÁ’íà±”¶n”ÑÔF^”L8›c—é`×ùõA¹vÛ&F¬ÜzÅJÆ}$Ù8¨H2y–‚Ô-ý ŠÖçƒ}®ò8lsNâºöÞÏ’FãdÍìDI/I½KádáÐø’ÿØ ‘é·¢í0HÇz®DïÆ \S­!\3ôzÃÁYRý¥|gj肪=OvE,hŠžd‚"NòaµI’Çí‚÷Î)@—¶X½KÛZDÚm2‡"¨9œ3¤8tm‘ýv‹ºÄšÂÁ$¼O†g`«aPvÏǹĶڛ‰;×ݾµ€ìˆ£;@MM-§1[þók?}ø«ög%qV>ò{¡rÎOÑ0§¨òZ`ê赤¿B_ùˆ]ÃÛFî³>1v ¯½ZÉæ&ħ䆃ƒþ!WÖf¥_¹º8kÂn¬,î „‡A$ &mÔºà‘Ö GP„˜„“¿‚?2¹PB¹"8cR8µ•M:o¥øM§›B1_…¡à¸êºn/†]é2*scð¨ó&J ì1©§¡©Ñ%òŠñ0â£LíàsXÑæÐÚT†; +úy3Ý@ý¤š¾f…l– 3mmD’`ú™ðu3Ü|ñ0&jéÈq|·ª50OLˆS¢v'â;dèWÑVð¨á=b&IIÙ/h2nõ,޾[hmÅ“ÍÝÕ»F¸kÚ<[´ò+%ü2ˬû‚8½çYŒmŽMÄÈMj=ùkSpr.[ oÚ‡œœ´¾Ä1 š`ÔaäˆUÔÀK‚©Á2þ3Á½ïtÐ2NÐbYQ4ãöŠ÷éÇÛ‘ʳє¾“ãã>H s^Êa_dB;yío–¡ŸC’¶AI”×3ÊšÌqópÉ5ÏqϪû¿jÊìf\“zjï-࣊ƴ!é“vÎØ•õ‡“^x£9ô =§°‰€gL$ÒÑØu4½žTL؈ë`dkFïû¹Þé' >åEãT²¦bÑÜTÓÀ/" A¾‰Q}>LôI•¦üö3ã7¿Øòõ®y9´OKéÂÕÖ€AÆUÅ})mHJ“ÈÉBöV/ÀòvýŸâ}u m8$–ÓŽy º*È¢‹PºÝéW Öö™/ø¶vC}ÌêŠÃ¬ž¶p„6ÍapoùƒL%*…n­½÷‚¥!LIUçUÊ¥Ôq?ò·&Œ=p˜õq;¿ßeÆ®[¸gUû/…{M•§‹Ðl|C·Y6‡õs“BÖ WRÇ ‚wx«²ÃIO1ЦSlÃt9ã£Öêx D-"÷¦9ÊÔîæ @cnª¨U†æ— ÈG ‘n{Jÿˆ>2)Ö-†­ÿIȃÔ|`–u>ÄÎ"<¸CmBbdmS7AÓcK`#•@¿ ñÒ‰DXºƒM¥u}JÅïÄÒÿ¦™ª]fms5• ñƒµ$ît dRÜ"(½®z…^ûÐL$5ÏB,Oo½®÷˜á‚eœ«75µò†GØ&ŽßYnwì…oN™>¾‡¬5+ Š>Î*‰·Ÿ­RÔ ia‰wÅH9$•µ6è»apÒ­ü+ÿI –'bÞí껆ÈglâÐ1ûeïðM›š¦¶ÂD½¦a[ )[)hšœ‡…±½}+ZwJ¹7 …½5áüûöŠ}ò)Ákðv=&R¾Oò|¸è=-kù´/xy¯P¾÷-<šë[:€u4l½²ú#¨!ÁÓËîÞÏ€ÁoQÊFH‡’?ž$–Û*ª5A´vhª8“ª<áZ q5öôzƒÞ–ãH=ßµq—³]¦1™¿÷œ <É‹…´‰ÊMƹL£˜<þãh×êê~õS«,ÉrÓc}n´jcc(^S³¢‡Ï,…\¨Vß‚v AôÒ°ºË?Öi ‘ìÌ®åÖ—\ ýÊ bK•e·ÄX¾¯†Îx§J žJtàÒ6Üòôç›~zä6Ük†ˆc–WµýÙbP²»_{®Õi0".è/õ(é×_ào¾Ž›<£ñàÃzàÅÀ ÚŽiiöœ'ýÙ»t|¶=áÝ-¸½­c‰9ÎE8BS¥ Ù¥AºSM•¼%ü¨Ý¼Ó«€½ŸB,ð(la(”#yÚuðÈ{œßú¾ÜÄoò£!¾™Ø|bêÚ™(nwäYñDÀV‚ìç¸ãÑ•ô:?¨ŸA*þÕs°7Ö‚tvíÊz'|zbý§U7Q­OQtTÓñ+{…ää?§B<ØEªòïëË’½¬ø¤u©Ø¸ —%²Æ1›¾v\â™ÊÕß?p‹¹[̬QDgŒüzó+x,­2*AüÅ‚6J/ p“´ÅÍ5kd=¾Žû2‡UŒ8e­á€ð*:}9ñxÁ±ÅñìŸvR»…¿#|± "ÄL•±S|ß& αӈ$’N³v7pdéŽãW¬¦ák s5Ö!»+/(«Óþ’.»©©ã0ܘ–ldÐ_ô÷ƒ•íC-ø‚Âãw¾¡ |D—}½*¶U±ýøÐ¬h2{SúVl­ÃTàöÃÓçWúÎ~0_í„UÆì¤«°…$b#6ñ–:x©m"‚HǽZÙDÞý£õœIQ%cw~'1Ћ2Õ‚ÙSÑŒãl&‰%ƒEYó¹Ìd÷\ø-¿ö5÷SM74ÿÃ4ÝÕ€ÿ|>moG(ŠÝwLã>‰‘”+UAAÒv`æ7G`0™„â4óš(]EÃ9Ó2^ÚÂç`»&M+J¶ö|±È+È^%µÒ§ üC{…kWIJׇ?ŽÉßüz¢†Ñ“£[£F‡ú½ÔæS熠´ðg"fûzã l¯R•ÔW2ˆššŽéh™\O_ê?°ˆwb0¯y zúÄkÎG*¹Âwë÷PƨuÕµ4LƼ¬H_OŽ5Ûˆ h¨ê‡õß®aîë ¹6d®Þt ¢äJW3~ÑÒ)Xm/mÍɺD}>ÿ–:1nÍZXÅ¿qyãm/'ÂíPB€]®aÔdæ®sññƒtüh4bÒˆaœE5OiåüYð''b®ž<ëp’¥á^ÙvúOx8Bݱe/Ö‘*jÅÙc:Æ-¾~Ñ*„ˆ²@Lî•%ít%E®…¤8O·Š—y`wß'p²8:õ?]ÿ6³nõ³¸€¦²œÙW¢>úÿÂõ*â“ZÒ=Vør˜¼¡îÁOfö#øÂËi/:þ£º ¨Áå’‹W´‰Ûpè¬tX Êzf^ ;,ùâ`à’ßÎP¥("’õþûÁR"D¤Z'12‚n¯³ÊÄxTôEðÃiŠvJé` ¬\€ŠÛI7¤H$›â‹,íÐÅ-ëÝÛ(›ÑüЯH7½Â6Oî¹ôZW%h×{…ØÓ-Æp›t§ Â*/Å åÒÞ¶­4qÄÒžÕt+]Øû‚z3ç R¦u­¤úMC ün{£Ø|NU®Ê›Ï0ªBˆû”Þ„v0ul!*c‚Ùç“‹:›œU·£ƒWÉNæ«õ'¨0´¹“‚¤ð›ÍÛ¡çUB„gç.YË v6ý%^£ÉßnÕ!PhL««Ü¸Þ¤íl¿_iàä ®°YÏþ>z•Ò-€hÄÙñîdclr•rŸÄ9$ÝIvå5`5,tq¦Åg ä4O1öñÄå"–5â>?îÕ¿^T[7‹È¸6Æ/í¥»"Hl%°E¸ae»UZß™ÖgÎ&·èŠ£tx<Òèæ•ØÝ½ùK¥aZDܯxIxC M*ÂB0ª‘‰¤È  ÿôô?Tœ!ì:u!S餞…¼ÓëÝûà¾Öù BÈ~tÊå{—¸XBL’ãKÝUìܾlA' ¨ý¾mƒ¦BÖS4¢[9Šd–{éc»Ó‡`!ã­; 0DKi¨KÙ(=+Àãɶ-¡ºN¥ Hjî}kg/~ý¶ÞóØþï[€ñÜ­h._±˜•Ú@ÊN³FTè¿v-dÕbWÞvökW›˜2‹òóf ô¬VyÍ|¶–À.i4Ü}àÒ™9‡)tXW¢ùP“{6­¿ÞLs ŒVlD9ÛÊOZžÆÖ}àý€å³¥eŽ…uøIÂø|äÆf0Œ÷ruKs—âQ›óLGººŒôSß"Œ°zøëà×G\!c-†§˜z/6îËš~L""¼A©LLœÃöü:'!wqW7!E±`VkÛ»\«Ue©ó¿(¸4ÙØ§üÎ6µ…’˜Ê_~ç ðŒÉžÇl^d],@có`ƒñ>çô‰N,Z¢Ãz3¯¢õ-~=—á0ÐQ~s9ºMCPšIü¼êÁŸE‰šaÁ•I È ³ÃX‹µ—AX?¬'¦Ø£‹÷Ø‹¥_Ðì¥m×bJW׾ʔØWõs³îÿ@>¤g2^Êèc­Ì4L}Åÿåè•S¬À;si~+!ŽÒ¼¢™~ø™VÊXDõׯ¸k è7żCLʃËjÛï0‡Å²†€cIé™»«q_Y}¨öC‡Y+wåánÑŒóÄØ”°6ù0û3PÃKl+Ô¨ÐkX¾\_O¼•EÄOb/T‹dõªE_ölÐÁ)9„Ä:¼<¿¹/³xÂÑõæ£?h ?úX#Öá¡RçÜt ŠöŸZ:µNb·Ç¤à2)‡õÕZ2öߟ­—¼áŠâú­¯Z-¦‰Ó¡…½Â˜‡1Ëëa–ƒu´&üÕ0ÏM£yØv¤NFk×—AW¼ß‰àx†>¢Á±h«ú8öRY­¶þ zĪ U¾à—ÞTdTÒòÝÍ/À öi¹,>'ûb@¤6XšµÕ¯ æ¤q\†^ìUþ"[®/5nËV ƒ9"_³M¿1¥9µû<äNL ïTŸŠ®û+òÍÁD‘ØëW-ÆP!û’O] fFQ Á:'ü—Qîj5»ØÌfÁ3«dGB3–*ØpeÑ?Àj>uÖ¿èÈQ¥ÕbÑK_.¥Â™Ý&³DÌ]÷Ú¶Þ-·ýÖ¬zˆ¬ yÚ²}Æ!ƒìaO¼Á¤¬Ç÷íÍ]Z“¨g¼ë哸fIv͹˜á/O•<­)3€|¤¹œÿä—/Þ5ñûfn ,¬ûD´Â›ú-QùÈîÖ¤ áL*½1wíÈ»F´ƒfËMO“„†d>4˪b)–¬¼xÅóKO¦ën“NhVÊs ï"Ò§à/YpBU[ËQä£^%Q6 ö؈¥œ×kPOëXv±XŒ#ëý†½-û•”+”Š#ÐÁayµã sƒ>Òwç»ë¯G®‚ÛÜAŸG|&æJ°„|jÿR )€DøÑX;zeøá›Ä—nC³Ië î³pM–[Òç  @Om{þ ÿâ¦6^+N#0d:±ÁœªoÐÐAæ‡6ó$ÃˇËÝJ £8z´S2ÎÐ,fsâšcŸÊÁc£tøÀ!*×e¼kJ™yõb_¬Ãiygo ¨u³Uýq5ò… LiaNæÍ_ZH²i²÷7ÜbBáVûšd—„G‰^ŽÏ2@>ÓÔT‰ßhT3U¶ÿrÁ’×!{ƘÛÀ¢}N»/}@¢Š‡ž%¯ P7§Q†õGçhJû®­Çl+r¸l$[D¯¡ï¨½úlÄß±Âó©R(pŽòˆ|ä¨SñÉ!)Ïìd ?÷—k6 zÆ÷‘!Â`x,~1Ç CòO¤aì›C÷óÝÿa’\̩ж­FúT™Œ–sÑŽrÞI4æé'‚ñ±¯6Ê‘^#©ûbÚÓÇýBQ‹Ýõ%S'hŸ’IÛlIlA—½=¡b³½™Ö³^GäÜæG˱Ìʼn©ïa ´Ýž6èGƒ³·«G {–fcÚ1è)ñ‚°»ŸZÆH°(ZW¸¼^ºÛË ïo¯Í:&ÊïõªóóYÃ$£`¿ð K‹ÒÜž@_ÞÏ=‚¸æ¹ϦRO™ƒÿ|ª>6Ìå 2JÕøfèñPš¡Ý}‚§WxóâøÆôÔgÛ™°­N¾XŒe§jl»êo$8aMƒ¬ObÂ=AYV™œCÈüª>WB!2òš:i„ MLU6['½p«1âRs̺òÃÄ2}ΕC(ÉVÛ3QU?q‹ËßRê@ÊPšˆ_à¸gcàÁÀHOgùZ¾ÃDÜ16•d¨0DÝV^HJÜ J8oa§íëR } üªå0rÁC|þ/rD‡j»TÃsWthÖÎñ“ööãCåo\&³æ¸ÝüŠ »… -×PÒÇ]ø ÌÛiadg²þ‚Ž ¤ ±Ü³êÅ/2â-ùaÂg$_º •©g–Ô1æ6ì_ |¿*ˆLÓjikuù|Å¢i"-X[ýçTãøÔÌh•"û–º£êŸ“ÙûvÜéþñÏž2A0 ×Ê7¾¸Ü{'ŒŠÙæGâ r´ò±—KÔÊo7·Æ;eøí\U쌗sŸrO3']^Y5‚@—^lç5›0Õ48ó¥Ù cÐ_Ñ«iÃè¸eáà6IJ•‹íÛšJ|ηº‡V$˜~\ºSGÏ7œ +îE=A/;Ø~j_2/”:¥X ƒh?›¿øö¸}úö²îíK«QÆuˆÓ×­%je°Œ©¬‡×á0B½¨±• »®½ð*ë"ÇšOL>d‹5Öð™ˆA§Õ}ë…JcWçì3CZÃy2Á ýóRé1ÅNöKäcZNK=S„ÒÜyð‡±!µÚ0Õ——î[ÄþµiÅZýqÈŒ¿(&iqîA6 ˆš<Û!G™Œm¡ü_ÒkßšRPõ…‘îÜBkÒ_î—&¦*Ýú²zºqy‚…†z·•È"Y¬œ²lt‡«/Ž\p¸HâÞäÔë8žP¾Æ´D“Ì_8sÁúØ¿x*wp¾ÿ2ÝŠµ2DáÿŠ·Å·ß ôÅ}ÐÕ×q~”û+vµzxõÀE¼­ûÅF‹6Uã|¦köæöb³N1ѤÎÒâÇf½¾òZ3ä—Áɧªû ÁW< KÞa5ûW§®‘¾Oâ½y~5‚=–2ù`á%Uë\p¯Õ°ºŠ<ÃMŒf®V±ÓƒmüJÁ»rx¶ ¶˜ÕŒæMå]XKeŠpæ þ¿gÚWØÉ»Nm4v¥àk†IµR\W# ?Séð.6,:P*èžÔH`‡†¶bž¦*gŠ|yZ¹ÁŠz‰Ã¯U6Ác¤ÃŸ¨±š;˜ï>å ¾FÕX7PŒiè]‹B5´†&—Òc4Í û ôÁq³N!®õ! ¤! }ã#O1»3Gü(¡Ø=S#X€÷*G•ŒÚ0áÇ4®ks>OZ-YÒI•‚\Ä}ÁÉÛ‰òø„ü!KäKÜ “q n¨) :™ŒŽL•|Øa‡³q¯·Mô`•¹Æ`Ü´4hBQèòwë§u‰&)ÙQÝf+ÉÚ;he³÷]±Áö½mŸdþjÓ·è%Éžùû ¸º@öW ^—¯®7”‚£^8_jNxiØ(uš ‹«ÿ/¾”žÈ~ö—ŸÒê3Vó¨¸V"/wæŽHUZ5W†æ×…œ Á&M›ƒC>œÍÅõþ¼‹8 šá•NiçEëÿŽNï䃑°²åÙ®îµÀ¾¦+̤z*åÅêŠB44]ø_zYX±•ñ{l?$~½eü¼¼øô¡2>LÇIcvp§þôá%yïÂz6ÃuB‹V›{øjóÚƒÔ{…ê[‰ñÚG7Y.o )fEÎñ3Åͼ(‚Áô[<žž[Ø´¢e”ãm;DÉÃqÜgäʸ©^1GA5Hqüá0Þ­ê”Wq¾ Õ0ÌUw)Œ¨Ÿ:zÏ”ê†Æ_¶ñ¤ÁC†k´>ôеo{Møë3Cܺg§ÆÒ ŒÚPBïTì€>Ø™Š^r±ØüV1­þ‘w±J¨[TKÛðYÃ$¦a’ªbǹ'£yäZë·Ï«yþâ ù(+ºö… ~µ©áÄÛ¡«ò·s %#»æÿË7Ù$ endstream endobj 2841 0 obj << /Length1 1647 /Length2 15184 /Length3 0 /Length 16044 /Filter /FlateDecode >> stream xÚ­¶eX\]³& îNww'8Áݽƥq—@àîîîî.ÁÝÝ-èð¼ïœ9sï›?3çG÷µWÕª»ä®ª½)¿(©2ŠšÙ›%ííÀŒ¬L,|­‰‹³Š½­‚=¯£ ÐÂElløÐq"RRŠ9Á {;qc0  4ˆMllV^^^DJ€˜½ƒ‡È  QWѤ¥§gøOÉ?W&ÿ¡ù°tYب>\6ö¶@;ðÄÿµ¡*[æ  @LQI[FA @#¥ Ú>’Pr1±™ä@¦@;g -ÀÜÞ `óïÀÔÞÎ ôOjÎLX¢Îc€³Ðôat7:ü£b8lAÎÎÏ3ÀÂÉØüQ°=dgjãböOrsûäàdÿqÃöC÷¦dï v6u9€^•Ä%ÿ'ØÒüogЇ`oþqÓÌÞÔ埔þ¥û€ùЂAvÎ0Ðü/ À äì`cìñáûÌÁ ô¯0\œAvÿÀ haìdftvþ€ùÀþ§:ÿ™'àËÞØÁÁÆã_Ööÿºõ¿b6æLˆ¬l>MÁ¾-@vˆÌÿô‹Œ¹=€•åßr3‡ÿйþU šz†ö#c3{;€Ð‘YÁüá@óÇ2ÓÉÿ ÿ·üßBïÿ¹ÿ•£ÿmˆÿ_çù¿BKºØØ(Û~4À¿÷ àcÑÛ>v @ðϲ±1vü³p@¦ÿSc[ÇÿÉø¿ÞÖþ;êÿ‰ù_Õÿv!jgñÁ#+'ç¿Å gI;ÐL 6µ˜Û|ï_ru;3 “ ÈøAò¿êûaÄÂò_tj– Sk»Øàü· hgö_søàí_0kS“Ѥÿ?lÛ]Vúè °š‡ð?=iÊÛ›ý¯Ã?P_¿Ú»¼Y¹xŒlÜ,Ãø1޼lßÿÜþ ˆõ?ÏòÆ`';@—…‰……ðñÿ¿ÿ<éÿ ;S{³úHllgöÑzÿKðÚÔÅÉéƒñmƒÌÿãü¯!ݦˆKóö¦üVI©Éà*ÜÌ1qÝž.ÖOA…µjy9~ö¾I¡›¼¥F/•ALu|oÍŽ^weéö†ºpl¨;€çÙDßÉi»sÐרZ¹é÷ü™ ‘“O4z]ÌÉm@ëp±hìm)«¼ÀO´²;Á_<Ðú‘»æøaQÜ; ø˜&ÖüÂnC«ƒÀ¨Ê=>¡Š;|¸§îè"éÞ%¤Ïø…@ÉoŒëüå7ØÃÈé¶Öô æÉ•Ûå³²fò« ù;²${±jÏ™¿l~4­…7z_k—,ëX1‘O)¿ ÌÑ,ë“weƒ’EyœMJ¿g[^W%ÖéNZM OÓ™3Ç Ïôó!K¯-—¯˜™¡’t7jâZÕ)@åß°<Ê ]öT*åp¹¡¾/'™^Öõ¶¤­ˆõÄAŠÛŠd#ÀŽ ›ezXÖ½Ï ¨?×°¡¨?áÇEÉq»\gé ¡OÞîÞ¨¶µø…9RâQ#þ…ì4´õR™’pþ.ã»sËB0þÒпõ¤³ ïl%3ýTKeTÿ©›vaïk{\]ÓVŠû7b€|kNtÀ),âö‚ÍÑÔ*Kö9A<)#u0öÔ¤KÚ‚ËïÚî£]QÎÀqDçÖ¨†É—f¶[q!¼ym…Zµ4!˜Õ{kÏηÈNô øRáp>Œ¯ÈÎäðÅiÇìˆøm/ü}ìŒêŠègήIs(e½÷ì0ö Üwçsi-u lUDÂ=ªòÓÛ~­È ‡ÌfP0®½³s×eˆ·Üs(:Ò–#å]˜T{<™÷$g³YÜf's½! ˜Du«´»4Z(™æÔ¶ çÔnn*,Púß)ë<ÈxÆìº"Ý>Q©?§±åô‚ºÖÏkÙè/l£—­úÂÎu),u ü`fAU ³Súx5»&ùÁ’@!"¬Ã7å—T\pxUh‚óôÑ8i “5/«úxK¤”T3þ ³eüÚä,€|ËŨ•x­ÏÒ=Þ”Ÿ¨[øU“ ln‚m•°™e¤Q-®,#Zö}zƒ ÚœzlQõë³eô¸ÆOÍË@-4èñÉ_xi›¯PU¯çáHJ}´§¸é®vžÝ’NvîXPî&²•¿‡hÜU‚U˜LÍ îÉ÷žFܽ£X¬‡$¦n3cuosõ|De Íצ®Ù…g$‰~»r!ñ6Tµ1óÿþkÒŽk;ª]­oþÃSCÉ ÚÆgˆkQbY“î3¨ãN’ Y‹·ßûLpõÅÚOû±G‚;«‰qšù¬"Ó…î¸S;´Hœ0W×R`°¤q›1Ö¾çªú\Î矹ñ¯Î,hDP–i‘Lµó™/r- û eòWo{T[=¾Åy"VòäøýmßiÚÙÀØ<ï`õxo+XyDãåj|Smš‹I-›Zå*è~ù!õRéÙ¡ùì$.†¬&1iêñj.ªDŸÿm2ŒØb{åmM\´Žv>[MO=I’òü€XFâüIãžýÜÛ±‹­µ”ÍÁCÊ"hcLYìíÂË™sÖ_fQ)Ðø5ù cTœ€É¯_EYPÚ£¿ö¦ãîöâ«S–±Q‘MåêEMï!N‡(ê1û"5× RtU¸euam>_×ñ“L ͼ UÂðô*h¡|°z’žè$Üçl·£1â$ýù™UpWûÒû€ÉªéÀ¡T bŸ :]¿ÜxE÷K2ôÛ·—Imã©•yvª!eâàVº5ø%nÂHüÜêÉ“ö¸N¯Ús»ÍR c«µú_ü¢Žg(ÊŠÒ4¶ô¥Z¡»“2e4@ì yâHöÝò“ý“¿øÙçK(œv‹•Pë¹Âµ+u6\ðÛ#cshÓd?jõ;C5¾}þÊxµá­xômQÅÐä»™ŠgÿK%Lÿ!IqÇâò9/{Å–º s%Õ…H–­ÌiË[äO®U]XÛ""Ç5‰¬@u72N¾?Øà¾i°4‹"ŒpY0©Çx›Žƒ^}Í‚Þ&Oôí¼'7ñŽqð‘¢Ì fD (1h©±MA6O"ñʾÅÑiF>&’VÍy]Å|*&üYEx$&5~­Š¥GŠÞÞj?J•'U=Wý 8é™ìjÕt 5e©³j2¬²heÃ!«£Ùuž%Ç符t‹Gò‰O(©[,ÌÈañÊÂ\Âoˆ c‰ß•½»¨ñ˜Úä+§Ü·ûV ù¸8S#°åøÄtôÊÅý¼«®¬^\­iø”Çež” VãçøÔ!Òî`tØmXn4u-äzùÄÇ0™5­ éL‹ž¨¶|":àŠ´‘#›©ÑéÞ¾ªÙ#ZîÇRX+k_bXÕèèå̪vM] ù ­Q!v¶%¶ÖCúÍ:L£Î1…Œî‹m ÖWô5‹²òºõq¤ü¾w¼kAzܶ易,§"é—WÃN<M=;úTž<$È#í7°?Û[ “[  N ;©¼ncà!íÆ±ã'¾[¤å~ô=…”Ž3KÉŸ´ékMlãA›ÒV%÷,–Ã%Ïa =ñdPy`Ï6B¦sŽ,ï_•¡eó¨']Ø C$(YÎMb_ƒ|ó¨Ù£ØhÕ,Úî09 ² òš5 ³*ßßU¥t‡+mÆ.¢ "µlIn÷{*`?^Û\J¿S­tÂO–v8Ѧ¢ßEpÇû<é6ÇѤç½Ñ[ñaù½Ðíz™‚êc{]ñ6ô¼{îÃA»Eâ‘«U×­Á‡ÇÌ/Ãt ZÑú_¸±„¼Z»¢GÕ?9 `Ðõ?‡%ˆm¯¡øw4xïf^èèk²V£1(§‹þð>Æ{õøZÞÃ,¯ÇØÂ®¡mËüóÄÿ'Í]Ó `Rè·(>¯†5O[ÍÛUÛÓ)H 3ùtt|ÙúpzâÕ µØG khç 3½öì½ñ¬úòœ_²Äü;RaiEúÔ9í‰Ú ŠsϦ]ZþÝý4¬·(žhW'0I ºÓ×R¨“œ3†•+ÓDûüºÇü¥Sstâ\ˆUõ¥”¥PYãˆ>†ðç²qÝdó'è˜Aºþ6Mö©°’8­™Yi»nHìõKy¢úm®@s¥4Çò~r¹äÕŠ©NÒ½Ú…3yÅÏAš^ ×xA׌Ëoà‚qç(oÃhêe’Úä5öl V7^2d\§;±+s²ŸÌþ3ìë’»cÝzŸæÐçÉ‘˜ˆš¶uË„™A=7ÜoösXAþS¶ö!ã,IåZjfCfñî8xÿ;(‹&ÝØŒ í–unØjvB›-Ì­]‰uš†Èé‡õï:bÝ »ýÒ);ÈÔÂýÞ¡g#i=VÞˆ^ÁÖ^þ¡þÇœòÙØNš"ÓæS}p\FdÍ f 9=Z­°‰°+•#òÓ¿B fIÿôµ:˜²¬îoc„Ÿÿ¶ÑK'£è‹V9œcAÒm–ÅñÎÌo¤ôC­*ìGS2x—Ü­ör¾1¯Qt)Òž…¡Z3eMR‹ÖaƒCû¦ãMöÇ{\ŠìŠœÄ jªvïøÐr¥Äßäð¬wb;?Od˜8²OæD&‡£øp …0‡¸°qï”üŽjr¹^÷‰9v?YFý“±LlÑнM¯ `©WEFSª-’&’ y°HR2et0Âræ 6Oï¹p‘ëáXU¹#ƒ”>>³ó±}¡œ¸ö¬j‡ïÊÑÂuªî.B\0‹À:zkÒɰ¦F›ÉØlE+˜¯ä)‹·|eÚ[¡~쬚;Û­[½ÐÜ@Íȯ¾ÄôLúñºº0Ÿ`ëЬ¸‘cTP§Û ­qRéöZýbA(h=À¦f½?/Û)>tÔ¹× ÐL6}bVžÊh“–7ëKÊO¨‡˜ö»QCÁ¨` ï3¥q(Q4óè–hÀ Œ×[Ê<@rÍ´eM…æÈ=ŸèQ:ܽâ“蹵⎉¹PÉeâçÆ<3ô óJg,à À¶‹7•köÛ³¯Ùò¡Š\í.hÒ0t©Û[é ÜšPi–!0<yDª#õn'ôåòîÚî·¡¹V’ òëy¬÷Þ>,V’švÒO‹ÕÑ@¥ßIj¹¾e_‘|]3ŒZ>ù“7ìâ—¾¨‡Å¹©>„Ò—w}»âï´JÒ‘‚7ðÎ\Œzl=²æ)š™‚ È„`Ó€ÿq®u‹‰ÃBϺ‡xÓºa9&Â!/ö3}4C…I´˜AhTÕ¾iÆ3¡À„Á7”™Àà[øå‡ý!z]SÏ,Ì/|ôÁ<r•8iZÉ-^¨ð±±ª)2¶å­´%Lµ’Y§Àµyš“oôHH#+Ú>fhja©é×y&ÖÚ±Û”kÃ"ˆw˜gg'wHÆKÅ æ=:Rƒû  nÖw‡>zËj$ñïêZ¯PÉd8òÈœfã30(Ò+—ßéÂ<ÿp/”…äÿ~=^ü¦Õ¦ðƒN’6nê´IÎ_´êÑÄHÓ <ö,Ô)½³c:>dÉA¼ä™,“4ÖáÊ# Ô Ô¤dÏÛE¾¯×’ÑǤŸ¦Á>â£/RÅl°$«·–Q-ÅÏ«‡l 9R®%‹oÓ¯ów˜}2kS@™3aÅÑ`÷[仫â¨*Šjh†Ü j¢Jl¶Ž’—·ÝÌ@g†XÛÖO)ëQñì œ— »Çf:r^#À¨([ž‹_ûÖUP½Ã»Nõ™cíûÔ#ÉíÀÎì²É®Ï%–«ë j×õƒæ~œ}UeÉ¥+íQÝ|¡o^vâ…RÞ§ø)¶¾#ã>gzÌA!üò¤E\óýw.Â[ïm€ú)ó@¹îIƺ-ƒJ¦ ø$ ‹ƒ‹á’ Á¸4Õf³^šÙ›Ák¼lͯƃÊ=«–ׇ¨ðU$ü4C¡~ýÃKyøÆÜJš×ˆe¾âmïÁéryŰ¹èç̰7¼RÖ:Š.¸­Â‘¸¾Oæ¿í­" 9Qé·×gðnI+ઓ—чb™½]N 'æ4¡9ÄxQ˜\ÐÓáÒàl/@Ž$ß$.àÌÐ+mÒ Ç¸ÞŠº…Ùh¬Å Á9Xã7 ×ûÖß´Î7n˜NNˆ`½èi-«·×ÄX­ågmt:R\BÛ¶¯£Æ[Cc„€m¤l­‘ë4±ÇBÒ:¼¿nK"3³Kà…oa 6êö®Œ5Çi `ŠÏ“¥}ÊH`Ðöœ¦üó£´ Š ³k{÷™E¹ÖRA–]‘B+Ë¿b#Šÿ“þœvT|ôZOaÈ·ìo|µ˜Ï7º8ð)6òÇJ¹ÒgªÆµ~¼3½ñ òa ò '¬aRg3ó‹ˆI…)d'¶ï|fŸš -æêûØÑOàò ¼%ͤõ1Û6ó@{†vs¤•áó“¡üi<_`£=ãÜF»!,ÀzÑ/ˆƒŸhbŠp£x„Õ=Îzßó¢˜Ô.¹™¾Y¿ô/\\ÿ ^òMµÉDŠ©W-múmûv}A—õ¯Ÿ@$Á$­^Žßü>‡åVÔö0GeWñA¤`cÊü{ß8ßf=6.h~x×ìr“HZÁS*“ÚËü¢zïiwS#9’='mߘ$Â8ób[nf;N~Ïwó“磿“”~NìË1q+„­ØîØópáFæ+g}øí$¨uj¾v÷ãÝõ‡p´?w ÒàøyjMpøèü€V‹UO$€Ž°Ë¹—ƒªë©WHÉi=Úp˳*{˜³´.ùï § ºrÐRK\d{q=„Þ+½HÅD}où9…ï¶eà½aím¹¶ÊŽW [6•:3×ýù &2jCýdR߉q¥{ôy²•Zøô÷º‰fî>3·Z²óþ3šÞɦ·,ør‚ñFi¦À.Õt¾éÑ]!¢ÿ,qBc“ÆoŽ:'ýòµBU‘±t!”ã­~í‡?¶k5Ô;¿²‹ëç)ðÏçÒ!´6b i¯›“óº[ô4¦¾eßÐÕ“Blûˆ«|Bšeαý(LÑŒ¸ð2½—Œ`]ÀàRUYþ ìy“Fv?·~½…Ú ­ ëãSÌ`yã³ó«¦ZvÄ%-ÃŒAAÅäDvôˆv1Z¥Eã¾öQßÉà_ŒpÜqq‡κ»DV•öÔJ)q…#å¹û]Mr9¢Õê ®êço•Oß °,6ã$>J‘Ï7¿Ë\*F “ޱD¼mïP®”°%y¬Scè›{ùAó¡åi<€>ÜÕ,¶NÞý§$7×”~W¸#„d©;pG„4”‹{ô»ØJVoœ‘^n¹¥)÷Ó9,¤Ô¤ªÖtG¿—‘{Ž O⊩´‰Îƒß‚ààZØDŽÚyä n=Õæ9}~w7žðâsÊÁGÅ©§ËœsUÍ>¶/²¬N7×{ûèü=Ó6•ùû"s˜ÓT›èŽÕ'»GÉýÃñ+âУiÖbÄC žæRMûW—,u’ÁÞŸJŸY ž)×Êá˜ÐžÕ‰Õ.š`»ÁʳÄïΟÄ|<'f¡k;hz—š‹¯ `CA7yËzwœ?ëÖ9å˜Ú’&Ÿ§Ÿ—4b“}×ù#U& –ª ך•õ¶âã‡"94ßá Æq<׿FÂj«g¦+ó¼™YúeârÈÆÛÃ2c”–¼;? ¡HEð£A)^U§&ÝÈ5Ö”È\]®ÿÁýü=N$E@dÑ_gã ,(éÞkËýè„%R¡ê—ho²¿W1'{ÆP˜ ™ÆP~~D8•ôk:†©•J¿§Ù7ÜŸ½ËŸ—_°U¶Ù(&J‚^¿£‡«nÆ’ÓÄž¼¿äüy¸‘µ4÷æ3<¾(¼»£ÀðTd¸U¯JdŸÙm¾û!ƽfÒœ×mÃI>Çç}yÔVŒóEv9ð„Í9ýìHÀÓæ¦{ý¶ ȹ™¬á7,4q§z÷[3ÂãÑ‚Ué mxhv¾=ò¦†%ÖŠG‡eü§s€C߯c¶zrŽ<#ÐÙS”š69¥Ï*TÝÞa¹Èü £5_¿ä<‹£‹gd´d?h»T3xxç›JÌ4õ•ÿŠOOdb€šNVë‰<߇ãŒm4ʺKI[6ÓA>üØŽßõÊàølÓ|7á)+à%oƒ¬CÔ«“e ‹Hô,Së}]c|há*†®üŠB-“BŸ]3%EUO/;¯£|g°î˜–žã©%ŸTQÔŽË!ñÝwß’qÜs¬qV&N,R{ê»ÓfîvE˜gˆ–F¡à%uº¥¬Z6àÞ½@¦)ÆyÂér«ý&ÄO4Û©~!y{T•Â|«ÈÓî·ÔüyŽžö œ.¥¶¬ûì}»÷1Œ¬p?À õqT·µ†Þ5i€E!o1Ë·SX]|\#!”3šÕ†`¶(l-üülŒO‘eò–-}§K¬˜Mò¹ýo_ë$¢¦¸©ca•7Ü7G£’¨¢—%‘¿ÒŽ­¦Zºì}ÚBÚ¨¿BŒ³(YMzASõÎ8¤ ´ˆ(Ø÷òÿr˜/î½mA˜‚(@cOìѳW—œ©’‚W±oÏ–êwê RFf1sˆÀ{ßc.T ÃŒËzlläÄw\á±)ÄÔñDò<7ÀmÁÏeѧ~458r¼Œ ®ð]V,ò^h wq¬¸ˆóÇgÃ%t¿`IéR«æãÔ—ïÆ-㢫=êá“gAþlæ;hˆ­"FÕ9ß³Ú;t:ædí?ÇüÅxÄ1»®XÖª˜<³ ìªÕ„ÏÐLç¬oú‰)IàºÀãB›£#¾ߎ{ð¶Åx¢²È2¤¤“¥ãº0 ÑÙHö{Ÿn–uk@g ¹{ôÏ|”8,PSE’uÉõG3S„MÂ.<1']}¯‘«‘'äá”jyǤc%**G'ÈLcáf}YÖ‚¤æÙ˜xX%þULÙŽGÈ{@_Ûâ (=Méšçu–—Þýy5Æ¿þjÂHB•롈ýJÂèzÿõÙËçt‹ÞÐ个¼Ç×ù윤Š£{ÍDFÔ&ŬîRÍe@_Åš…ó=®~ÿ¨¨«Vû%Üz[Z*_|¹pWzÖè"·ŽP oM—ø4¡À´% ”XÓZÝwƒP¥L"ÖänÅkõA뾋¬½¢Žâ&†¤ƒ>B#.ú¾CIUåÄ€ÃDRp‘õíšëÇE3¯'nLÔ,WÇ]‡€AÚσ[Þ#—ÞÍØÀîz©`OÉÉ·B³¡GÍšgfþÃ}u‹KTF¶5g¤o8lHÙâ+¢ AÛ×+ü½ºeùõ?šï³ÁË*Ó°Ø.DÌ-BZH8÷(DÛΜ®Ë©Ø´ÅÀ"´ðƒ/oË¿PmÞbÎêèÖÛp,×ÜÑXrütÚø×x}u¿èÂ&-®æ­¤Ñ£<`L£Û»)˜ˆÖ{‹|=xXe Ý&@LŠo˜ä%*åG5Ó‘âèmrŠL V)‹!Ï…ãT»r+í*hÊ…©}™¸dï@©¼x‘ ¬É½ïBÞ9¾õ b²ò•â±’Ø;ޢ̂*ز@l­ºCádÙnþÔ Hð­ÿ½ÉPMVê“ú÷ÒŒ¿ÁY ÅÂ|Ù¦Ap ÑDocX´«Jã¸ãÒdÕB‰öî¶gÍñQšè¶ “‰°V {ûKæµÐ]S8KÊÐDܰAä.äà“ûC͸èÚBC›÷GŸKçåù¼VgJý¯òqµ7è@¥x@šó]]Ñâx\Ìz3ÓfÙж§&æ³R»äXÀÚÛÐ10À'¡Ç<¢íS3ó­¨sÑüŠòYÙÍèLÑÌÕœóxÕ´‰æÝÞ•éýK×cÑ{‰†Àë¦_ÁЕV^9©‡Š¹Õ Ÿùš€*é£&'»üR§¤MñÁ)b¦ÒéÀwê… ¾7Û׳ˆuÛ5N¤Ç©Ý¾¿˜ìóã<É“þÀq¼]&ŵŠ¢°×fÇöÎ’ÛÌâxë!èý.1:V™ÆœŸy¡…Y”_ªÀ¬b×Wt 3—ûÚ0Á€Ô²TO6¥èúts{žtÆ7ˆwÈ膀§66::a“N£ùk± F¥ÕÎ{—|D‘šÌnÏ,äzóšÓßëÚLW4З†ë¤¢rrÉý‚*ªLˆ¢ü_åkíMlQ…{û÷Z‹‘ê·5%gŽ9-ðÛ_³ô!uRØüÒÿÿe[;ópª|ÉL_´ ™j>ØZü¬oÄÕâ$­T¾G¤q³(ÜÅF«®U›&J+cz‚®*kV¼âoa1BÔH”P‚â[PŽuøk"ºC±²‹„ÉsD­½%OuT™-¯ÛÓtäÉï=qþd‡ùB”‹§n7®T4„ÏëÚJèÖŽÅC:@ÅY_#Ñ;Rw†®cýä ‘FÁ¿<Ö(ÝÕç7D6’®-mN¸øðY3$Ÿ¦zLx±¥"ÖÄTã– ·í­ßKÐÛÄݼ’î¢3¡_/ c5ãîcdé^ü‚Λ ¤ÈYbÙOÛì3g…=%;[4k«'ŠTØÊÀ<ѯVµµo¬ƒXk­Vx× 3QëE÷]œœWد&ç u)dàtlò(3á‘G’F+¯¸çÄ•‚±õ¬Ê¢©á!üûà<†¨†·ŒlZœ§¯ö¤<K&9~3"OJܼ¬ûiïÝîQþ°‹™ÅÞ+>_-…eîäNî£ãz^ëlXrK”8¨î1¸®“ÓØ’$›’ý^ñb‹­JŸ{ÛhôI–¡§±/› ñÞú£ ͪjÅ!¡²Ÿ’$Ñ:Ïž¬”øeëM eítóY‚­t#¥þæ_'Î-D²0÷T’9Ý6\—€j ý…þäqªoT‘Ø_ˆÕðS’%&ÄçèFa‹ÝHN¡Ù}’²ƒ¾¥k³­ òêxú¸^¡»¤Na]±?´DY¢ÿu_@ãàu¡ÿ‚ßÇ¢3ïui)Wo¬Ø¢ÛèSuO7ìÚ_̺HNgû™±Vÿ”CzRãÍ.½<¹N#êTr¯3æ¾U… %Æ7g.M¶ûþªò¨·ûßýñú‹„pÏüì5!¿õm"Ô–së•=ž§Ta/ÁeešàeøÞºäL4¯IG¿*¾ ¢—îóE%ÍÂ{ž\•Ð*µn¯%׿^i‹ù6 ®³ßNÖ]±‹Km8£—ñ*ÍÓïâEºæà¯bµ#¾2'­NÔù´¸âð£äÁÎzÃÈH¢d7«¸.©øÄ0”wÈéâÂæÇu ²×(2?V%jËd §âZdù],&r "¿ý¾×DvÂ@¸fîÏ"©m¾wû¬S2 åJÂHb^ßÔÞú òù[x¸\÷Âë—XÜ6F„GU º3V !…<îœé½z»®4.Û·æSdqØýl…³¡pa…=ÜY½–ºÍkCpÐK+gÚiÙ›f¦óó×!8~C;¯W”ÁÄåËÀž]3‘ªÿi+6“ù÷ûc?7çD~Åýhs–ûþ˜„Q… FŠ1sRYZªùâë4VûÙu$F¡|q¾¯ ÓþŸJÎÈÆùUê•OþÔ]vU?ªhrCäÂ96·÷Þ,˲Ç`ÆîÁPz‘¨¦úT^_F£´‘êͯc÷ð…ÞÏ7fžƒ{Ý)”~Äå畚.PïzñZB#ažRĦtªÁš?>±ˆ¬@·Xm<ÃýC?õz`g@¾Z2ØÏß.6¥B6Xޝ¬÷òï;F“¶ çö¦L§ª1©ÿ¬ËÎâ(ÎË2«g¬3+âÐ^üÞ@káÔͶu‘{Sze;m½åD¸0“ÃüÒ£†Ø)àÐw‰Íˆ{iUf§V(ܶ°gìÁ³\Is¶áYç iW»ø¹]£Ø.Wå´3¶ ¼è{|ã÷~Â<ƒXôú1€ÖÓ笆:ƒ>n‚€±«mÙF[¦x’‚0߆ÉÜaR¡ðÅûÈTÆÏ76D42uT4Ú»ÒîºLoÍ„G×~¤kŸïêJñt“H¬Êx¨›DŽ…Á .h÷ЧÚj¶ÿ|:Óñâad†i@:ŞͿ¼aÝŽ¼…2\\fC˜XÄçou¸:—Øð@&ìVÞ&‘U¶_PNÕV•µ˜H â¨`UàËæòñk ¡}¥½«å¤‘©F£Ç*в¢ŽDðÃQ‹æ…¾ 6›Ê YT=ߤÍz lž^ï2¡Ü QMÐ~QÃ*Ã|Ò]‡îÐHeÝá; e Ô_á#rTIœ$Zœ´EÁÌéÞ"M‰A£©Q1|…ëè·W·Ôð[:WÀPï¤åN„?˜üʺN&Ñ—í±pã7’?¾óš¦ì,ÿ úxkQ³ÚŒþ›"–¢ç[ªt˜t÷æA>vƒWß Ø‹©@¶‹¨îˆáùeÿ3t Árò›Û⌹•`'ìf•gø.LB…±ýôÍ&¿Œ_–©>%RfÃ_b¡&ãA y,Öd?Ä~Ëa:µ¤ÎÑf›’áiËà l$Ï8a^ÒÜßVý Jºƒ¦èvŒ¾ù]©ýBŽl]ì%/ãNž&ßM%²Dd᎔¼|Ik5½š57ñq< }ƒžà]ÄŸ ñãbÀeGð¹Fq®ÄÔõ®3[gÿŠfüݬ+µŠ(È/Ç/½¿)»Ù4ï{<äÔJŠÜÂÊ;ý~ó>M!£ð;}¡µ´ÛC[ù¾]N¿ÞápáÆIiàÛ<Ú8oñ—¢b?ð TuÂ+2¢Ü®E‡VËá16÷àöjÇäaÌÃæŠ·Uú úFúZãú* Ô:Óä^p”vyz«ó\3 ‡‚PÍïH„…63ùã­”Xĺ8j …¸hɘŒcf¯™Ø ­8Äà2*Z‹›I£ ´§é:øÍf‡…ÃÉßzÃêÎK$r w6*›ÁbŸ;mY¨¹ïlPrÆšJ‹¿âGk>¼øù–Ý-–Y 3°?~A¼fýziù«’ÿP,ÑÇ8å6óõ[Ô”½ªq0ó¨Is]©áôzÎõð©Š[ÉÅÌÉcï‹Þdê°9ÀpIîTÞêàއ!"Z;ˆ'z^™Š8Ý@tc¼5ØE¶2‹±×ü¶"zwS/,ö Øéi§Ðöª»í99Þåe±ŒQ!ÚÕ8îœ]²z9(Ë}»¨{‹þE5Ú󦾌f@3sQ@¸û}›Ð½ëžViz3í˜]¼Î͸ Û†⢬Þ`ëNyh¹YØÍ÷M³~É+½A‚ÆwÈ1Ë=GØŒo¹8Jô}©Pžz»AžnÜ.8ÂBCŠðââp“`ÓþX Åî rr¨ÒTƒÆbª„æ >ƒ ¨ÑÔÿ ¶Ùã…GÆbpJŒ'íÚij|˜0¨f¯ß‘[;nƒ‡™øÐ|F¶qûâÅÞ9gH¯ÆãT#¸{H³ËÌWÉy+kmŠÅ%!{áw0Ð+®º¥¡ALýÑ̹bþVÎþŘS¶ÀL„nÆ)èT•Ï熋û½§N˜â𓈱޻ßÌÍy]?‰3(ö(¾é"nå³ÔùOðîWFM讞_ŠËY~„Ô »OÜÅY^³ÎiX0Å?žî.,tïßà g_åeú\|#4~½÷ÚÊï†%OŒT'O²3\j`ìuõSyYâÎ-#7ÊTcÚ%‡¤ñ;&1á"¿¡òôŽÕꢦ&œþ^#£ýý¥Ã0$‰Ïýa§ÌÝê½ý§ÍÓïÁò55ü‹Ýõ\îèJ¶Î±¡¥A¶±P¦âÞ§¤|¸z?ü8EÍîÉÈ 1¹%q’OCFe]¬Ulù> ÜB—1¹íí“<ËäašmJmkŸ|« +7ñÃýjx§h“wDD®¥ æêkÌdl<+£‡‹t~ÆÕ÷ÛXmkP!æ5û£ð?DmâB` MÑ/Ì2%ñ¦Ò¶Eí>8¨DƒÝŽf¨Ç×ä.säJÂ=~1œÊ¯úH ’LqÃwïûÓ ®.zÃíuàä7ÖXî` þ­|Ÿy3Jƒ€<+u¢VèòÁÊ´R&5ž*dæT™’¯¡Û ª Õ³T ·ß¡x40(Ún5[0ZøÑk½àÁb <: ¸í|ëwy¯WC‰˜Ëñ×QÀ‰út­z±‚f ÜgƇ¸EŽŠ9!ÓíÌ r=JÜû˜ÕL;—SÂÞp•…ʼn› =ðP~°^©WÃ.§êùΠ:á9îä˜srÚsî`þm4±’ cL‡N®Í¶?a¿êLAÉ~)Oÿ_Itµ˜»™ C¦˜õ[VP™ðáéô)a¼ê·ŒÛ)+²\bÇx: 쥛íBà™(ÎO8„ú ”Ê¿«o—Š~·£G3‘Ä¡÷Š8 òÉ×'xûLª¸Ô’¬ê£l;DŽDúZE6§¹@°ö$Þ¬Q`-•ö¯+¿%JÌdñ¹Û¢n8É}!c™T÷eióT‘].Oºµ-W](rU p ^dê3žùV¢%íö"Ix,ÖÉ[+ëÿÚ§‚KÀ–FWà­>ŸùÅñ`U(j-Ó‘º)U¸{Šõ°úgÏÝ6°+7HL#ËoØ?k‡U›>˜ iIjlŒbµú»Q}B­Yó€…´¤2ŠðÄG„£qZÝ]b–vÁTÈD›ŒÈúøü1ŒÉeŽèØÆVtDÍïPòÛ÷Ajl¾Áÿ:–HÅ#mÞ•£)cäv¥ój­×× !€Ú|¡ÝE36‚úbõ]ë)v-ˆÜ€ wUX¯t(»¡„bR–ÄÄZ°úº|¤¡NΞ9rNøÀ˵Ê4–i£Íg«ŽrðJ½Š¹‘¯nºB>¶”Ä«´š™ÿ&Qȭ醈8f“‘ÛˆR™ý†ÈjXÞ£¸…òBS{>õ¾¾VÏ90jmœ™#ÞeRÞÕ÷µ$âRâ™…Àò@š@ý`ë¦üWt‘2I‚§¼ïo;(3ûqy©L·™*GîpôcœÄPr-×3ãºwO3Ž^p§Rå«¥”Ŧ©\sNèù^ÖÁ=ˆÕ ¸, œ"üó§ãÁÍ´ê««óŹyR•BÀûØÑç£,ƒGº¬¸SiG\~‰¸È€÷¯«¼Bª i¬ $.kÝ‚°'{lÛ)¯Ôû2¢-Óü5zÑR"Ië>Ÿ|x:¼dÄÈväÅÔ|¾¬Ò~ÁÀÉ>6oD0$ËtÖSû{"9bÜõÎî9ç{d®¿´uԽ#~$ Ôx>ñøû·ÍŽ¡•f¸KîxAB*ë>¶ÎYñv]quÒSÒ>YÍpp¦m315 @IúLØÒD‡rÿÈÐû¨“„ºM軵.ä“eX.Lª³šá~@2‘RÀ„'JK• Ñ—˜`+}Í:¾:51ÞÎk9¦†§aV»<+ÕÁÝ9ÚÓ30òK·ÊöÿÎWúl¥ CSòY‰½Ö›H^· G&Þ2[ÛcÊ'NgN(ùÄUó5kŸî@P¹¶¸S}N㫟<Ó9‰ØCU© bb/&ŠFgþœEä®ìlÕO=°-Um¶ø­üÝè+±õE}uÖi'B”^WK²:õΌس¶¸Ô[þ²a ²¢Ë€_l}SuFØYCW¬ÂtŒœm绋Q—‰œ‘lé¤"‚ga”ˆ0Ô9±ûÜ5h§”l¡¹¿HT ®81¾çŒPáŸ#˜,Rá}|–Ÿ­W] uÀõV`'GoÓ{xÈIm½¿?$#sÔä~ó½!ÒF™IϨÈ©Âh¸kôˆÀÜÓîÑ”Ned̤ԉ2f1xš; Þœ'}Åö us :¿Xïv—r7ÀªyÅäT¼øñ/Paê—<Èž¢%ecúæ7c™ÑE—Cìª_ì‹Í;0W·oógÜ™ÊCŸØ0äÆ+‘±iió}ïÛ€@xªy‡ŠÌ¨;;F¤ÁÆ¢ZŠAÚÅ€YKóÅÂc[ÌRM¡7µk‚Xt®ÂR,Ô[Då„ÓVT_«"‘€(k9f DÉéH³êV~”ñ'÷ú]ô¡:N]á²5ºD’kÑWÛa†¬yY‚[ Ñb¹I""eÑ£—S˜½Ûbº6ü?ɈºRO:”ÖÌÈ»Ì^-ÄŸ+ü]l^;eÜ·°ïÍ»-»å9ƒ´ÈQ8Òº f#6ÁQÀ?m‰ù"\l‚b)³’<ͧ*X'po-6Ì¢/læÇˆäÔ¥¹?3P[–{œ4—N ú w½Z_dxÖT8´OHŠƒ:o¢J|Uwç7é¸I%â8:äÁ1»ó±tã×Õ5£.kÈ‹r6zf0ñ/óe Ì2VÀÕÚ³¾_d™þáÈ+;šSÒ\j>ó¹…_Q=­¦1OóÔGh¬$ ,ÕÉ…ZÄW[TéN=g^ ¯wK9þ¸û•bp÷þ¥~ Oà7ù•=Í„ªÌóåL¦›Óo’‚AÑõà”Ó€~ õzúƒ«l™yg·ábý“Ü”¢©Å¦œ@«‹_ˆÂÖµû¨rà}BuWïjCÂ+ŠËùõ9ט.òoŸ«Åƒ-˜ŸNi‚BÇUF!ÝÕäj¥£X|±í”Óï˼$åÝÜÅʬò6H)“/G$žì{ÊêB”ª#I¤ÐÌf,ò]ƒüó’ã´ùõ¡RÀF1»ƒáÊsO>…]×cÉÏòÝO¤zÞaÙªŽÓEÆ™Cv—ôÖú^>9Ô©»Ô‰odŸÒì0ÕêÏa3™')_*bšOÀÕÙæ'ž; ¡^!åýB‘0p}óŽZ"€ ^¥ÞÚ•f\'nšZÅày¤qf²(ÔGs-|æì$‚P…pÉ#_Õ}|¡A‹Ãñ²-~™‰*>Û/x¡j>;«ÊÄ=9æ[ºHœs™vN}0Jà§}úU«¸£…H¬n!Þê^nçÌ#?ñ`ª¤—YÜŽ“¢ÄöYßéqêX®§Ì2d+ƒßWò㫌îE§VÈA1‡ìš+jï_Ÿ9Š¥õˆ˜ðW’)ã‘ÞGÓñ'šÌèpSÙtæÒ§Ô)Ož§Ê&ÏãrþžÂ–]…ÏUxÿ‰ ߬dB¦fHwÎA-Ò›JåíÄü¨¤ endstream endobj 2817 0 obj << /Type /ObjStm /N 100 /First 925 /Length 2950 /Filter /FlateDecode >> stream xÚíZYoG~ç¯èÇ]Ú¾/ `;v¢õ˱ãÆ‚¢Æ×)ópœüúýªá IQ—³»1œêžîª¯Îî&G-™`Òh|YÜ¥fDjç˜A[ÅÈÚÊ*æÑ–A±(è.™©ƒžRCKÛ”ÒƒõHÃR¯Ó4NJÅdD–)‰á Sʲˆ^e‹ª,Úým˜ v•.j[¦4ŠÀ4€F~Ì Ú0  A?€ú€6€z˜N@0½‰Ì¥Hƒ>/¡'0:Œ5€èž‹ ŽYt°ƒ…L‡1ÖPÛ0 |*ÈÀ,ª®Ö»˜H¦¨«œ& °Þå@…ÔóD'‰‚nV3h¢¢§>­˜¶‘fF&ŒBˆÐÐÆ ©°XAF F1«-™II ñô”+ &üGÊ(m sÐ \éügL`^hFñÀ4pÖ1¯1ÆÂ,ÞBÅd#Œ†<ŒŠ©ÆjP{\AÒ@Ø ²=œAŽÀ,)à–` .— ÓÜAÊi² 켡0ƒä ,b¨hÉ^` ·"¾9\ƒ¸vŠÐ<Õh"#Âþ’úE ü2"®"tbJÀê1;$˜ÆxŠ44•¬BÂe !T(•¬J´Nà08 ðëɆ”³! 9Ñ ‰zš¤º‡µ …¾“¢<‚M$d"À` P¡ «R h#!ÍœNfÓÊ~#£ö’ñGã廯ͯÍk7­ù›ÕO¦é»Û»ýÙÿôzŸ*e‚.éI‘.ÓnœØ ûK!&§8)÷n;§Ð¡Ðõy;§lAê³­Šûí·þê‹û­Ùtù}³ÍÇËÙ|ÚφçxòüÇÃ?þæp:šM³Ép9üsl^6§«ÉN†§ fòŒû÷gŸÙo‚Hœ[¬ÀYHÛw~o1j¦K&üÁðâÇf|z–$¯ô.‡“ñèÞôtÒPóhÙœ¿Üÿ¥ 7ÖcöÙp~Ô,Ùßø=~Ÿ?àßó‡üÿÿÈù?ùþ”?ãÏù þÉø+þ3Ãßò_ù£ñx4žVç™^Ž'' Èe3/>ðá’óãáèÃb2\œšóãùpÔLš÷ËLÍ F"?4˶t~0â£Ùd6Å÷ùùŸð“Ùæá Oðyóq5œðæóh2<çïùûñ§†¿Ÿ­æü”ŸÎ‡Ÿš¼ÆàÓy3~ÆÏþ¸8k¦|ÌÿÍ?ð Ÿ4‹?çS>O>]7óÅøtÊg|†Ž ~1œ7Ó*QÒE3'óÒ}<;á“Õ‚äWÍb9Ò«Ù²99ždb1&Û's¾à‹æ|œZ4Ÿ€d1þ̳i–|y6o¾ü}ÆW|5=”ÑlÞðOüwþ™ÿÁÿä6óÙßs@<á*ä]ýà»ï®q??<üõí›o<=z+ÅÎ;ÃèÒo1(˾dÞöÂ̽´M?Ö¤©ÑfD'Ú´ìF[ “óáò¬¯XúÙéÚŠ=y}øÏÃGß<Ÿ¯GÃé“”F»5”Þ°ÒQ_²huGE©º*¦f«¢’ú’t v­ Uº«àË ­ôM´:zõôᣣ¢ÕËÙù³Y|rð´9_¢˜ ì@™Ë!œ¸VÌžï¢è*&â%ŠÉžëœ¼¬Pî,¯Q$†ÈþšÁ'HÚš¡äçY›†”WeeÚf’¥a‰ÊÃ(Án•FÚÞÄ/O_¿øéÉà ¿ì 8ò‹ Õ/ÊtüâCÏ/VöÎ]#àLJ˽õûñ¥îy»UÁKÙîÕì^½ÞY¤W“I³]«Û"==!F[µº †¶bé:}u}ÎC;¥ú¯(ÓÚß(¾^¼úáðûñup4N—ÿÂþð/Ž´ƒxP£ ;DXý²#ËO»>\§øüP’ôRómXîF ÜÛÇϾÙa9Rî2›aÅ£¿¤›6s±g3jvV<½¹âÙv:F3r~æÜìff5çÎ$êäMNš­diódort"ü¾0ßÛfÇJý{Údì5~ÿ¾ÐQ³`¿©„}´ì&vÒµ(´©¹Nq¦c7QwêÒ–­”êÙpÅ(¥d¥|² i•õKFLæLº'+d{'ÖP«A*D¹ŽÕbU͈œºaõý…¿eQö«j¯ê¶õµ[£;9³^sȬs¯¿²®Ó®ëʶ®cµ„ç({w-wîõ[ݨ—Í2vÿǾ£cÊß1ïv9Ïß°ÓèÖÞcÑßÍmëÃTGL:~]Ó}qó„‚MãúÔôn»è¢¾­Ž—©I(l÷‡‹†žlŸ-z5:ÿqIe‚?ÏKª‡ õóÉpM¿Ÿ,ÏùŸÓ%ŸôK[0Ì&Œ :8¨ÑQelµ_þ õÆØömã·à¹}V’ª/|xûv³[ðÂ&¼®ñ$íÖðüwÕ’¾ Ѩ@T_Æ‚×Ú¯m›@½Ü×ú‹ ½ê'§-oaÔýxt]Œn£ýŸ`ŒŒ±QlA”;6˜/†§Í»¶ÙŠv´ç´„¥·ÒüÇãÐúŸª•©›9)òÝ–¶÷ùSœ½»•z[˜øìoæsÜ0oM¾;•ï^ßAHÌLƒÈˆK¼±¤8”~o/$Ä ŒÞµH÷ük‹6 ‰®ôs{!éäC\Òv>9ÍéÍJX['Q1d62‡>SK[ùÚÂD™ž(YE)a Q‚u¢>*Î’*«wKQÊ+©R—”Zá:wyÁº¥(]Í¥m1 ®ÂéžLÄ"œ^Óº½(#‹£ tc*áê£PEEQ¶ºÈ–,’¶ž5•puŒ¿“¨+t¢èઞ®d—t¦öØ›‰²=QΗhp¡ØÍÅ"Ü‹âF_cÒ«pQ^WƦ„v-rÒ‡‚Â×°(%ë–¢Ê 6ùg¦2¶Ef(uIïî"ªFtE«P“:Ö¼Š5P¢•wËÂ#cÌZ)QRX‰JèÚcìíE)QY‰Pù•2¯dYL”ÌË.7[>\O”Ì»O°q•_•Y«¢R²êJ­ìå¢tñ½2Õ€6e|É4ì®\puOßÛ;”=½%™î1ßcÍ%Q3šÞ¼½œôZe.絺ÑK•¹Ì•ýKz¥²”qY®†¸¯5'TôfÉ`Kœ\]ù¤¼TVzm3ñÑW¯vX>Ûy5¿k-mCº‚ NÏWËÉxJÌÒ“• LLfêž·È®;^Nf:ú.3±Ã:†53»Ÿ™î1“»˜™53¹—Yˆfç3Ñ2 ~?3ÛcÖþŸùòA@: endstream endobj 2849 0 obj << /Type /ObjStm /N 100 /First 862 /Length 1805 /Filter /FlateDecode >> stream xÚ…™MsG†ïúà "fÞùÚM*TåBUŠ"&œ²­$®“2 •?>ïÈ–z[´›özÕûª{ž±ž]“§bÈS ½‡Ì©~Ï9…ÜæãÄï•%ü×R( !×jæk5‡–ZÈemΫ\*cWR˜ ór3˜—sH123:QCJ•‘H!!33ñ½sdhbqž˜ÊRiŒu´Å\F¤ÆBÌ,nsá‹{O‹§2ñ€Å3ãÁ™#8bŸyÀ±Rmœ ÈyÆA#ϰ8O,äh(Éœ •ƒ€Ãñe&s:^É/ãlïLæ|˜Æë3˜Œ±b‘Éì€KÇd˜ÓHeß™É0ç4ºcqž˜Ìs½DY 8A«=Q†Æá¦Á'¯8å€y†Å3¸½…cáx0EšBIuâA ™KÒb(91™ó—€¢ @Ù€bÈ û²P,Yd€lÈ>(ÙX ’ )°$|I€ €äˆ @²$}QH€(¢ *Ñ0»ÆÍÒ2Ì€y’°ê‡)1YaEÂ\˜–}ž„`ê~XUaˆ„áKJ°$ ‘0| CI–„!†/a( Ã’0DÂð% %aX†H¾„¡$ K ×0”„aI"aø†’0, C$ _ÂP†%aˆ„áKJ°$ ‘0| CI–„!†/a( Ã’0DÂð% %aX†H¾„¡$ K ×0”„aI"aø†’0, C$ _ÂP†%aˆ„áKJ°$ ‘0| CI–„!†/a( Ã’0DÂð% %aX†H…>—a–„qðôK>¨O^Øx _†ÒÁÓ#¬øaPaÑ ËݰiZ„úÔaO3ì ÐÇŠ ƒV% ~ØÀ¡Ï“0Ð}½©°b„uÐ}*ÌÐ@÷4 [šh>€¦t @ÍЀfh úªÐ,UT@Uš  €ê( @µP|E¨€"Š (ÅP@öd X²È>€¬ @Ù [ à€-ð@€ ù’ @ÉX’H>€¨$ @Ñ€dˆÀ—pR>ôyvà;X)øÐ¥ŠûVþM–E¿¾}•|-÷Šz}ó*ñZÞíúÖUÒµœ+Êõ«„kùVtëÛVÉÖr­¨Ö7­­åYѬoY%Y˱¢Xß°J°–_E¯¾]•\-·ŠZ}³*±Z^­úVURµœ*Jõª„jùTtêÛTÉÔr©¨Ô7©©åQѨoQ%QË¡¢Pß J –?EŸ¾=•<-wŠ:ñ§'õg*ë©Nü›Põ´oÝiËÝ”ïrõÐdݰˆ”ÜOHuëi|ö÷Ýݨômüž›y$åþãpyáë͇í§ðÛÓŸ>^~÷v·¹Ûÿááé«ÝöÃ:;²8ƒý™º8“÷g®:ÿãvýäÉÙxh+Ë3÷§ö—½_=ûùúÃõîä…ïO»/¬_Ýî¶w·››³ñ‘%zýæn„]Þî_Áâ•ó›‹»ÍåVF÷ŸPU¬ÏïNöפå5ÿ\rY×?FÁì<_Ÿ_m>ýu_ˆÓ8îöÚl–øÍÅDZ9Z­'çÆÖ\Œ¸¹[à÷XâÅõíÕõퟟ8MY]]­Ïÿ½Y_l.ÿÞ ²-Þj?Ü\Úíß>Z³ì{[îøf endstream endobj 2855 0 obj << /Type /ObjStm /N 100 /First 1053 /Length 5367 /Filter /FlateDecode >> stream xÚ•\M“Û<޾¿¿ÂÇÉ2â7™zkªf÷4U»{x/{Ø™ƒÚVw»â¶$éùõ €’ Š Ò“C¢ç!ø)Ê::»é6::¿ÑÆâCØ8EqœÆ‡´QÃ"ßm”Q ŸÔF¹àðIoTôôd6Zé„O lbøM“À¬Åƒƒ¨>…é"Õ7Æh²Mã4–…nc‚¥'µ1‰Ì «=™µÖìÆ:òaب°fPq]@8P1‡¸qΓEÚ¸¨0¾Øm|G5C^c¸1êwTK4<éÙMèŒÑmÁ2´P1lüÁ§¸‰A¿1m¢öX–ºMtÖœÔjGiÒ›¤4úMf“L@Én’7|$·I©#=Œ+"5x´Ù&£ôˆM’k4PJ-B«¨ˆ„¦Îl”î½á(m:õ<:xt™7)€7 Aà#x3%uàÍ8d.)̀ء.ä² S0Á£qX™oÖwèDÊBö€7Þœ2dÞœITxs^‘.xsÉÑ#xƒ6A My ìÂ#xóiðæ“EǼA!Æ ­‚u¼AF©³©,F¹§¢¢Ð5xËÍ„ªh5º€T®ÆGðF¥˜ßÔ, ˜U‰zB‚®¢ <ôfÀ[2žÌÀ[¢Þ žPð–(’o)DaáÿÂäO˜íèÍB55X™…vì\$¨±ƒNÞJ‡ ðtL¬×ìzÔò´kï@%Ö‹Z#C’Áêb÷†?XƒƒÿkKmŒµWþ·ßÿí/ÿÓ¿ ×Íÿýéçãçþòòùûáó[Û¾~‚®á`èøcSË>+2Ù•DO§ŸP Í-Т!Á÷Ïh©+ùöpºÞ/¡/ðŸ¿ýå¿öoû[#bÉôŸ¿ýõ¯5Ò¬³ëoýhý N´­"(T…këœ/§ãé~Äšj­áø}ò·áxo×ÈQª4žïÇímBM".±Š5^&% iÆ¡CjˆÈ¬Î#8B+Y‚F¦Îo÷1"tß6b±d¾†vÔ¡\+€+4Hˆu£]o—ýñÂò"˨^Ö–O=øúc×__?ßÞÏÓãù2ìöÛþ†Žpfü°:VoÍ 5 ÞG+Ùzê¯Ã”§Ø Ê ¯Ã—/Ÿÿ~¼ —cøÇŸþñ T¼ªTþžE8'-$í¶?Œ¦8®×rL“,ÆòëûÛÓé0iX‰“DÓ¼I*^÷/Ç¡ŠÝ2ާÓî}”ZUEÉ!º¥p7ú÷a÷·Òƒ^ª ß'†a¡²>Ÿ.oýá:Z»`Z,”H5¬ð°×±9.!ì¯Ã\N‘¨Pk@¶ôÐm¿OÕxk+¥ëgÔ{.“Ž®\½õ_‡¿Q=ÿ±?î ËÍÜ©Z§/˜6F•oóÃ6«Xa(+²OU‹ƒÉµ}x_%ýÛÚhÆLÅṿ<ÁVöÐ÷o“8„J|½Î“oÛ&b Dªa…ïÛ ASßU÷3Œ?×ëg:Æœñ1µÿ·¿—I1UÝG¶Óóè°ÎªÙ~ÂÎÛ1¸o²±€3[É ä¥ …‡a‡ÙÉ×;OÔRŸp­ÊA¿Ó|‹<6lÉ–@ÃИ9 Ú¸Ô“‚Ï‘bà… ºÔð8ÏàäÛ Zϰ`I¡%Xµ—Àì×ó°…¥Rо-&ó á­´ì×á¿vûçwì¼Jˆ"Ki9,‰óŠ'…Б¡“„¸Üèx‚Ì¢ë­?îúËnŪ“_Å>Eß®b=Ó¤X9 !µ,£dY°1\“.î—B2u¢ôù’Wj½±˵41ÓJúV G¢"q4¤-ÆûqglCˆDžÛ¯ûÃŽ-¡`÷Ì…êé¶…‚›Ue óv‰¯TÇ0£+ŠÆý×îe¶«e° ÙÇ$ŧÜIü|‚ëBƪ–¾ýn”jЩd%cuÆ)ÅÖ~G)1j1.xú†åUKжIâ”B–Üíù@æDŒËˆgàíçmÊáíW\>Þ*÷Ë7†¬%Y:öòÀTåÓU–Ñø±§±Eù ˲¡kiv¦u;j… cš]­ r¡|èÿõN¾b IÔ#4ߛŒ&ÕÒÝp¾½¢©•„dªM-}°gh­eðbüU«àA!{¢wÞAµák¥&ö¢ˆª6BjLû?¬Öê¶ÆŽ*cj(Q’_¦)IÄ«Uâà\„Þ²^ýüvÀݯý£$Çæd?Xóú: {²TwVQ§¨Æ­0’q5ÍeJò«z5Ä{"[ÛË唕§ûá0ÐzÃòóÛ5ÝL&Ëçiy›ÓÃt(¢\ç{²Y–縑ûЇ Lm#‚9œžÆY1ÇSìÐ_‹—¤ÊñX_¯I5ßG¿ößnéùòþˆQ~Úxxá¸t¦qëpÀ#yqR[F,[‹`K­ã;-ÈT+†#õ}¼¨ +œŽ‡\ƒæ 7b¢óÿå~Æ;dž‚ýèævzÛâ¯óhëcìõ±P+]1+gû1˜¶ÎöµÇdxù’}©·;ÝŸøŽœ/{–JÅýåø©ŠIs?ô¨Å·î-Ä«µ}ˆ»ñebñíG­ýõ•Þ® Î;ÛVÐN/û-ž ÆÛZÇû8¤VMm­KÿìC¤ÍP›5}ˆ±ùÛ¹Tú>lo'd5 )y:h ! ÏoÃÀÓ›)~r<ʶ4¦(§ýGX˜Â¯jXOçý4dXÑ}OÝ!éëR|ÍØ|0­\ª©ÚžÎï¹n¥|u»áyÜ߯wt+ø' ó5ð»=]ué/ïcþ»º èXvnAÕ ¹1 @C ”ŽQ„ñ²,³_ó»eÖr`¤UÍ‹;SÚPØ6¨x»ZÉs 5àg˜æijÆj6T ãÂ(¥ŠíÚ °À!×±F»ëÄ,.tÙºÏì×¾%ÛÑÒ,¶å¹IaËtqòTJ§áÚ®ñÀѨ`„‡Åé´Ée>sö&®iäJê|8ôoO»™®;^žo€…šäyžéÚÐP¢jXã`¼2B×Ejü¸H¤FÚd„Ùw¢ðzί¼Kmy® F¼2ôµa¾²\ƒ|¾`U¹I]ªÓo–ç®ÖS¢‚¦ý…æø¶À¥ºC=®%:Õæ+ƒµ-­ôxÈÚ ‚AZš®1q…ìè/Å’ æõºµ˜Þ4“wÂ,ÂÔø¼Ù ˜™ê<±tBdz1£sæŠÓð±–@¿®ôƒŒŽ]»sv-ØG/ïœ[SÌiÐ ã SšÖm W¯`§¥^#¯…t› “OïZø„:Vù!•Üé[A`+$a¥v}?Þp¤ÝŽîqॕ£_·Ë=OÁZå+ǵlæo¼kÑbaF!¯Áÿ1ô_/Ã3EVÃ¥9¸ºÿÕŸqÅoWzº-£vèÏgÚÿþîÐ_Ù1^‡XOæ8%[`©Cøt7‹§wÒÅm½ÃK¾oÀ(™ïز ï `Yv'®ê¸ 3 õ¾ž?œ¶Óë•|e”k~0Ykä ¢¤²\V$IétÆ… 9RaEüÈïÇÓ;AÉH„þÖ¿? Õ€ ·cñtUŽˆ MqŽ¥!ÍûšÞ¸tËRºùβŽÃö¥ˆ|¡_¸²‘N ÕG¾ Ü¥(>CN*…}ñ­ÆBœ!Jòy«?Ð_ÊsâØÔÔªf•ö…L±`1myþFC× a0ðÅÒBœÍysœvãA׎VdA¯ñ0c¨meìãrúí|ºÜ®ìàµØ¯Ó'°ý¾ã>/ðég)& ü ò¡)±¥\|Sš­YºœÎ£˜Îé©¿ÝèÍj»G Ôjm"= åbB<ö&úûáF÷þõ©J#jÞñÞæ²Rþn`E5WËÈ>÷ûË8¥@§·X+ UˆœÍbòÍϾè­/kàø2±”f㦻a2¢8_+Kü‚j!̦â¹]²”ÃW6ÍÐÜÅrc!ÎsLÏ__ø==ny¿¾.-y·úö-/Ì^O?°3ðÕï·{Ýã}ù~ IÉ—ªØ%k5Ñù„%Å…©ñ…#ßlV*9ŒtÊ“ÒâÖüBå1k'¾XhåÍ5¨ˆMOpšf-¸â¼™HeCJ¸ØµX«MoáS² aþO×Òù"‚PíuÑ$¶A„§YÑ*)×ÅûA~2ë`ž½âw¾%Ìhñøj¾ø^h¾;Zê·.l¬’PÆ¿VU‹†i-±púŠÒ–Í4wÔ¨ÊìÉ_¼ðnÎã‹ÅSÞÙò‰…ù®“-–V"¦Ii<¿–û½Ý/ã;îËé ÷l|tÁMÛøRcû5_WÍo-ËýYü÷L2@»0úò¥Üåtq ÚÓ¯~c*//<|´:‘Ó_Ûeˆ‘G~:»Å¾Lw •b×ZáWZäŸ0µy‚ŠX¾ýeü¢Æº4%‚ò1´b2{÷EOàð†oËø ,Ëý¢°¨†¿G^ Ñ "#t'¿3_Y[6 Ýʵ?X˜„ãÅÝ¥ÔfSgüº£8Ÿ¾Âèsýò,)„±¿(þÛ×ûÓõ¶¿ÝÇáHÉH˘—†2P¼Ú_ zP’ÃŽE½JåßÐÒMþy„R|©â|Ç2«Àkà×Ï•ü%º¸Ç¢HWìDxqë‰>ñü°»f×^O—°aLµ\þþŸùG´âŸw¶†3~úÔþN¾½%ŽÕJD&îG:ÒHü°#ŸŽUlOÃeK“ V¼.”ŽùãÒQ‘ßùj*f\Œxü¶?je¡üØßòpÓ?Á®?˜{óˆB2Q—:9$x-ŽØ¢ ðÚw‡6>„*òÁ¿”™5'pVBÏ·b'¯É¬³q`̹`§…u›–à*|Þ餆,ƒ ‚º%‚G>Ð)râgvPBuüä#NfUAÛ¾ög öÏTãtitøù¹CcæÇ¯î¬- :^âá&úž)rÚ­RåöŒóÌ”Z3S¢-oª„$™"ï B&Q1U%¤(ƒbBÔy)ÍóRjÍK fÝ´ ½´5ý3­ÿý´íg¥îXºª˜~çAWÅxEdZ^²bƒÅò8‡á”ªUØLji­S;Èk [•{*¯±úÑžºžHåu=‰Ê+ÎËÈJƒøû<]E5¶þÖlUN¿ü0Q¬\Sy¬Ê –ë „"òô õi¡¿†(×u´D¹®£%Êu-Q>ubVN”›ªé4rV0¸O¥ú MŒ› ƒÎ?FRaÐĸ©0hbÜT41n«4ËKv·‚#+ Ö`宋(wuXD¹¯z¯&Ê}®AÊ«Ú ‘ü ÿia°Âäß7©87Äy¨Ýç¡G€.Và qkpD^}­Œ¬4Xƒè¸0q3åª*OT^…e‘ó nÔü+0¬œ~î¤Þ¯—q•+ pÏ¡”àÞÐK• œ¥M—©Ë•W i{¡LÕF–È3¦ #+ Æÿõ ¤Å endstream endobj 2956 0 obj << /Type /ObjStm /N 100 /First 1041 /Length 4139 /Filter /FlateDecode >> stream xÚ\Á®¹Ýû+j™`œ’H‰bÐÈjvÌ¢g9Éâµý:1à¶÷ì ™¯ò¼+úç^!@覫DòHE#ÖuõÖŽó¨Þì(ny1ñž~4—¸èça^ó¢>F^Ô£”¡y%G‘»ô(mäP½ÅÌßÄUÏAñ·1t1 H÷¼Š?Zþ¯[F(*þÖŽ^jæ@t)émøÑ[Io~ÝJzórt/é-³RÒ[€ir¦7×ÃÚ™ãy;ÌÎ>só3GŽiåÌŒ|£bVÜ¡1€œçyŒƒÆU9ÆçqU?# ¸’ÃëÀßêá©ÆU;ÿñ&®zL`ÀW1Ýñ‡æåˆËjÛãRc6䌈ËÙ{Ž^J\Ž˜ž¸Ì‰?{ŽÉ•R;î©/ÚrÜs_zëá¬ô\$-Ç pJ=[†ˆ~ŠqÃ[UͰkx«]ÓE ouhF89cVâ2×YÜÞD%c¨áMzLQ\ö\ˆ÷†7Í!ã2¼i=3†ÞT’„·7ÉaŠB—ðë"Ç•ðÖ “\ÖRr°ð^šz{ƒ˜JkJÂ[¬b 6ð d±¨Jó’iÆJ+ýĸñG,é|ÃN o½Ž¼7e鱆ó2¼ÅZ½á­÷šHjxëV1XxëC3Þ®t¼gÀYìÌ7áláÍ ¬ñRÄ+‡‰ è‹Éë áÍt$¾-¼YÃZjùÎv÷7?ýôæÿýøÛÓËñ¿¿{yz÷õÃçO¿oÕCLf`q??Ú=íáóÊÞbѳõÄÝ…ìöJö »¤ý¯oþðç¿}øÊq­üõÍŸþt'‰&Ž’hšöÎa5Ø9¬»Ý`çñ^T¢»iddë»4€¹S¸=1§ :0wJ¢sçû¹SàyÛ$áWl’èÀp?ƒzb"ÌÉ &bœdÇD 1*Ù1´…Ôá÷'‘­ìÒÀDx#7˜'ÀOL„º%1'0Jbü‡ìö¾Ib‹x`“D©Ž‚-;‡•˜ í_5™UØiŽr÷;o°ß_Rˆl}`—ÆÀpnb.ŒnŒmJ ¤sÚ)jæ´SÔ ðÄ7I,<0Ø$Q¹²{`®ì˜+­ÿ Ì•0¯À¼Ñ¬ïµÞN£ÊÃÕ»4€9ÕÍÃh ‰}wSÌ©ÌÅ^švãqžµM Ì6I0çª)ÀÜCæ\Ó˜sM`>:ÙÞ°ûiˆ>\=°ICsÂPù $˜JB¹S ̹Ò)ÀóÍ˽栺Í;G•ëÉQì|B®\º •KWjEÝÔY]x`ݨ …©…V9¦“®P˜Z9&ÇQØ©¢A*jÝlyí|¸z`— g‚…©BCa*W4HE劖R‘Z…TÔ×:w'‰…æ›$ 0•«?¦òÛ…©JÉA**‘Ù ©¨7ÒxmóVô•~ô-ý€ÂÔÆaóÎaóNs—R‘÷HE5ZhŠj²Ib¥¶¥P˜ÊÕ Sæ Sa ­¨\Ñ •+´¢úf˳•~Ø–~@b*}THL¥CŽÜp·6ˆEåB±ØNb±í¨ ­ôclé4fc*Ù舣Bc6®³‹ë,Äb£“  ±ØÊ¦F•~Œ-ý€Æl…ÐMIê¨Bc¶ÊwsÒ¤b±q„XluCÇJ?|K? 13QhÌFç³ §Ì…ÓæÂi<ÝÌ…¯[·ïèG`Ò‰&á³ndÅDPõˆÅFG ±Ø¨* Äbk÷ßìe-åí›ø¡0 fkBvLÃä0 “À4tNÓ`›$N}¸z`“F*Lª¥…ÙHV f#Y-ŠmPÒŠm(Ùžß?¾‘e»Ëûw9r:˜ÌFT 0©mRlTdJ±S5K¹aÖ79,,PvV /{a‰x'(ЗX @(vb¡Ø‰ „b¯÷E"[Ø¥Ñ1A }Ù© ôe§CJPìTœRÉ™±àéf9Õ…æ›$ /;‰g¾ìÄú²Ó‰™@(v.ŠK„bo÷+¬\½Ò·ióF˜C_vb}y£(§PäR¡ØIœ „bï»$˜l’€¾ìDˆú²Ó¦-ЗX£@)v®tPŠÝx€g›÷BëÃÕ»4€9f§3€\!ÆeR±ó\@*vçQޮ̮ÍHÙ6# ³Óá©@av:í(ÌÎuRÑNNÏ`çñì÷ ”¬ÍHÙ6# “[½ùöoaP˜FG©hÄ%RÑ % ©hµn’XX l›‘…i\Ï¡0:c…i•ÃæÂ`sá´žl^ïµ)Ûfd–# $P˜Æ»¦ñn©h\°!ù0W mCe¯JÔ¶)˜|”&˜ÆÛ¦ñ¶¥h¼-@)}eÜ|—ÃJ?¶ïô¥ñ^}ÉzT /Y3 „â ¡hÌr!­o^íµ)Ûf¤@_šÑj†¾4:²èK3‚BÑx ó`¡x)×w’XéǶ)ЗFç¿}itÀ!ЗF¡h\~!i1„¢mŽfemFʶ)ЗÆlúrÐÙ¬@_úÒ@S(^O\’A\!GÙ¬¦µ©Ûf¤B_"³ }9Hi+ôå ²¥ŠC;ÙìFöûý‰Ðµ©Ûf¤BaŽb"ŒQÄDØuÝJb7 [9½Z ©86_éÚŒÔm3R¡0%…ƒ0‡ÂÄUZqзB ­è'o°ß§Pº6#uÛŒTHL?Ù½ÃNiÔÄœ°…Xô“Ä¢Ó1B,ú¹YPk3R·ÍH…ÆôÂnvz_ 1´­B,:i[…XtÒ¶ ±è ¥k3R·ÍH…Æt¢P©,Fa+0'b¥‹NJU!ŽÑbÑ7a]›‘ºmF*4¦S»D¡1(‘BcºrzÀ\9=`Þø~€·i ëÚŒÔm32UÛ ÒÓI‘*4¦s1€XôÁ÷sÒS ±èã~ÇB×¶ÍH…ÄôÁYr.E˜Nû³¦&«'¿Ý©ëÉow¸µmrXx î”¦Â¬'èk*ÌzòŽ› ³ž¼+¤ «'—‚”ŠõäRR±žu³œÖf¤¶}ÃqX;-„ÈIiäôÝ`Îè¸ax²™Šµ©Ûf¤v`.ì˜sÅéÀœ:­Ú9uZµs¦àµM…Z›‘ºmFjæÝs~¹;0'i‘oË ¦‹0gcÏ6ûöÚŒÔm3R ˜3Ë1`NÇJjÀÜ8 `ÎtÅ€ùàûÞæ›]›‘ºmFªsêyªs:@ÊJtƒÿ`N-MÀœä¼€ç›2»6#uÛŒÔÌÃJÌ S¸Ô˜µœn‡Ã5Ø©^§X û}Å­k3R·ÍHMY —ÔÔ˜ôUš¦ÆŒ»)‰”da§$R,†’H±ö]+ýØ6#Õ9SAæ\h˜3çr`ÎØ9—Zx›¶…®ÍHÝ6#[jÌë˜rÃôyv;17ì˜áQ0ÔŒl'&bÓŒ\ví¶mF¶Ó@GMíÄ44ÓÐ8XLCç`1 TeÛ‰iØTÙ¶6#Û¶™$cemˆÛ8Þ´ĩƶĩƶð65¶-Û]Û6#[ätÓ §ÒÛR`ÖzrTv#»ÃNã§RÜ|ÔßÖfäö ¿¥¾¬üK”–ú²V:Ûn©/+ÿx¤¥«üã‘–B±ÖÊ÷7ØïëÔ¶6#Û¶ÙR_VþuG«€œÎ¶[äüjW@ίv ERLÉp‡¶M lÛŔԞΒDò©QRÛAßB$±Ľ’Öb^1쥷t;ðeí(_ò`>oJÒ8¨Ê&™ôû³¤²ƒz1Id髤±— ›q÷eÉôÝŠIæ;¨@$QtìšôÕ‰T$yu¢–È’ñÌ[￱}Y'¶“ IvùP)™!Ÿ®$c峕ä«NÛu²U> I®ê•cK¹´ÝJIzë¤p’ ò‰JrT'3Úë“ ò™HÒSß|*j‹ ;=Œ–Q’þ9m¶IK:+IJ½]gž”ÔéóÐ$¤¾ù8t,`ì@rX§C“ò9U‰0rS7y¨AHêtbœÔí>àcaý¾Û’’¶:mõÉñœº4É=$Y2O'A–¼ÓéÝNÖéã>à¾ð|ßÑü$ª>îki_Øö,õ¿>¼;ë¸|Ee^Ôy!óBç}ŽôŸŸßýÇÿ|}|þ~~þõÓÛÇ—·?ûøö×oŸàó†?›cyá—‹>Cé3”N³{ÃÇÛrñýËãËÓÿøòõó—¿üî/ìºÏ|úÌçÒyŒ‹>/fx}Ür=]<{÷õÛóü¼:÷÷çgj6S³™šM”mFezË㻟_ÂÓÅËÓ§ ÷_>|z‹Ç€àOìÙff63³™™MàmF7Î[žÉ×ÇÇÿû׌ãŸ_n¤;frc&7frcB>f`£ßtÃÙû§/Ï/3ïøSþÛÇ—ŸÞþüþñåïoo¸ŸŽ™á˜úÄßgˆ~siýúùù·Ç/¯^Ú»ÇÙ›ÏÔ|¦æ35Ÿ˜ûŒÈo®¦Æÿ¾ˆ/¶Oßnú¼ä3;IuR„:YA½ìùy¡Ÿ_žÓ˜KçÕíÇ/_ëÛB.gÓ¨Î~P  zéøäÅ «Ü\H‘É«“/žáˆÝ”™G™y”™Çåà>.f(åæÒù>úw,ŸŸ¾¼¾$?úÛ­äÊL¥ÌTÊL¥N„댬Þ\1Óǧ(Íï/~¿þëËÓe•~y~zÿáÝã×§—[þë̱Îë̱N¸ëŒ±Þ\Cß>ýòùŸá÷ËãßžÞ–rÚ:S’™’Ì”d‚-3þôæ2°L?~é1]ÈŒZfÔ2£–‰¬Ì0ô¼é"[>¯W?’ÑéAgÈ:CÖ²NìtFÁ¿zwý±ógßÝ̰u†­3ì¹QúÜ(/\ìöϒ׃‰òã§”Ó×Ü^}n¯“ÆÕÉѪÏMÒ7çåeýœhù÷¦¯¹µÎnþÁ¢ËÅ cîŠÞÛ¿ùÏ(,¿¶þîj.¹•zŸIÌíÐçv蛳ëŸDÏFåÿƒ˜ûc endstream endobj 3077 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.17)/Keywords() /CreationDate (D:20200128060918-08'00') /ModDate (D:20200128060918-08'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.14159265-2.6-1.40.17 (TeX Live 2016) kpathsea version 6.2.2) >> endobj 3057 0 obj << /Type /ObjStm /N 20 /First 188 /Length 643 /Filter /FlateDecode >> stream xÚ¥•M‹Û@ †ïþs욌FÍ „…Ò½õ“´=•=¸‰wȱí¿ïØÉ 1¶ÛB!‡7ƒ¤WF¶Ùz5Ö°õÑ­HÆ‘f¡ùعVncÔÏmŒ²QébÄ/­ð&j¬&[drÁÚ£\šr@VÉ‹”U°†Är«È3¤ÔÆ6:ï YÅ.Îб­ÔP²©X,ŠùÛͺ6ß\ʹÖ,M !B!B+‹ù»ÍnÓäüuµj6‡ýË™c¹37Uï‹ûû¾WDtÑBú‰<í¥¡ç•ÒÐ+‚"‚"‚"ôÓ¤ß:1Û¡SCCCÂLºI~Ú‰©ç¥<ↆ†t™)[k!hÚK{·Åip[9Ý¡C„‡PˆéÍàÔ»-qqÄ+¢(D臦7C\êy©z( 臦7C´w_’xèå@á@á@á0U‡~ÜônHêÝ—w~Ä SeôÃÓ»áÞzEZ1  ž†ˆî¶îð¡ÍÉ@` 0 <V¯>7å©É>˧ý,ÿ–çíìi·­³åº¬̆ž‹€E° ‚¾d°æÏá´+·õÕµùu¬®nÇSµÞ¬Ê¦ªg#S° Ø<Ø<ÖÅ£;ÏcÎçý÷ÃÏÛ©’ŽŒÕÈÈÈ£ÔN^ …¿¼ ºOÞµ WŒUÑ…¢ Õ}A-¡†ÿØ4·‚;`öÿ´i£>U»ÏpNÅé—¼fþ¦lÊíṘ*Ÿ«Ú¸xÙªbþñÜl7ûËQ¼}(wU}ùˆwÿÛ”÷‡u5ÿZWωÇjÿºëÂÈå¡o¦A° endstream endobj 3078 0 obj << /Type /XRef /Index [0 3079] /Size 3079 /W [1 3 1] /Root 3076 0 R /Info 3077 0 R /ID [ ] /Length 7105 /Filter /FlateDecode >> stream xÚ%Ûy¨do~×ñóÔí}¹½ÝÞ÷õôí};½ïÛíþõÞ}{¹½ÿºk¤‰3 *† % è+N:ŒâfÄ É`( œ?R2EBÀ *5˜ (†Ê "bÔd¼¯ïüó¾õ|«êܪóþ<ç<çyNeY–ý¨‘e,eÙ²Ù?O{ÙâíïÔ4ÔÕƒ9jOÔÞhÎ…yjoÔ^k·³µáFµWš a‘Zü—š‹a‰Z¡6£¹ÆÕn¨½Ð\ËÕž«=×\+ÙØô˜Ú3ÍU0¡¶Ní©æjX£vDmZs-¬S»¦öDs=lP{¬öXs#lR{¯öHs3l™­õ«=ÔÜ ÛÔâû>ÐÜ;Ô¶«Ý×Ü »ÔŽ©ÝÓÜ {Ô®¨ÝÕÌa¯Zìû;š“°O-öýšûá@#›39Wí¶æA8¤¶Ví–æa8¢vPmJó(S‹}Só8œP»®vC³€“jÏÔ®kž‚Ó³µöRµkšgà¬Ú.µ«šçà¼Úaµ+šà¢Ú)µËš—à²ÚUµhÆ‹¯ª=P»¨ÿèºÚ´Zl*>äMµwjç5ã Î~ó9£p#vÎj›ÕÎjÆŽ½«¶C-¾BH¹¯ûê´f}¨Ÿ/¾~„á±ÚSµ“š¤Ù6w&S‹]!|¦¶Hí„fø…Ú*µØíþ—jÛÔŽiFÇy­¶_-”E§{«vZíˆftØ÷j—ÕB÷—ðAí‘Ú!ͳèÏvö9ßÊ<ñÊòÒ×Ùû³}nwÚM½?Gmƒš¬õuöþ<µIµ}š:{ZINû:{‘Zt°½š:{‰Z•ñ¾ÎÞW{©¶GSgï/W‹N§ôuöþlgŸ71¡¶KSgïO¨ÅÓ·ú:{Z„k‡¦ÎÞ_§vQM¿ìëìý jÑÁ¶iêìýMjt}º¯³÷·¨}PÛ¢O̾c^+<ñ’ØèµÜ&Íø@»ÔVªÅæãËìQÛª¶A3vÄ^µè8ñÑb'îS;®¶N3P‹ï_+äR»¯¶F“ýþµè±K$§?©yƒ…jšR×?¡¶B-v§ÄöOªmR[©)íýÓjáØà cÑ´œpSì«PÀI8§á œ…spâÐr4e»ÏÆÿytœOá’¾ðØ—yèÄÐ`‹on°˜\¤m^w®¤ìÈØÔ5¸.~Ò%_:¾Â-¸ 3ð¦RV¼Œ·Ý{p€þûé<†ix ÎjɵF2IB3åaD9âý"eg¿[~¯á-¼ƒ÷ð%|p(ˆC©0Ô†zÀPêø Ô†qíq³'¥;Km~¨C ãP‡Æeß²”ýͯ:‚ŒâC8$òAawNy‰^1\‘²§[Ñg†úÌPŸê)C=e¨/ פìÍ/Äëô™¡î2Ô]†[lÙáf’ýávØR2Ü–²Ÿ˜oÓ†úÑÐéd˜ƒ„ %lHÏP†®R *ãÿJçð(ÈÐP¤†‡SÖüñFåeÿ×*]õíâ!ûC ÜP¸†q@fè\6¤{xboœNÙOýרè%ÎáÖ¡H oÕ?‘íÉËP^†ò2$ygÉ[)û« c{â3Ÿá¡¡ ŸÁ ˜ñé×Ã:]6†o ¾Ì;ÿ7Âð*e?w-6*9Ãðѳ$˜qgo\²½)ûµÅñ'›é…°VÀü”ýf<»–ÀR‡e°VAÌ ¬†IX™²¯ÿ“xïZp›ŽËÿý›Á¥þôVp?½\ÖOïóÓ»Á%üt{íâð¥=þVm?€ƒpNþ”ýƒ?ã0…ãp 8 ÆÅÉÅTZkEhâÄ|ÎÃpžvô™¾ _À-8“²ôkñ®Âu¸‘)5~N1NœÐ+bt¸Ê‘+¾ê¸ /àvÊ~ùû±½ûðÂ#xÓðž¹›äZ(…¼—ð ^;X†ý™”ýËG±ÑØkŸ/!Ž4òÒólO^z sò¿WSöýƳó`>˜êÍMÙ¿þÅxB|zâÓ•ž¨ôD¥'*=Qéùh=zòÒ“—žýÜ“’ž9£ݽU)ûoÄF…¦'/=yéÅÔ¼ôbB(f€ì¿^œlâÄ Í7ïÉKO,z{Rö›·b{1ï#¢½˜íqåŸØê‚õ¤¤'>½ƒ)ûÞâòÒ“—ž¼ôä¥w $¬w¤' ½)8—f/Sâ½q¢’ˆÞ5ˆ$=±èݺ{³…ß™ŒwÈAÏ °G|øñ=â{œ÷8ïqÞ{L÷Br ©íQÛ3¼ìñÛã·÷QêAŒ,gÃð¿CÉ óÄ+æÀ<˜o-Kiáýx±1æäX ã° –ÃØ Söß¾ïX « r¿ÖÀ:X .8ŒZšW4·Â6؆µ“;aì†=ƒí䘽”ùÃGñ÷Á~ˆùºÃ³tG!ææŽC̾S>)†&ÞÒXì8c³ÓÄþ;&Þ&/€qöä%0¦žŒOΦìþU|–kpÌ¥MN´ÉÛ£¯x‰Ñú¤é±É`Rlò¨O>÷ðî¦ìÿü»ØüSx/`^B¸4úŸ|_ÂWá÷]Jÿ¶Gmah CÛüKrÑÐöÚKRºü£x‰X´çÈ—Ø/m×$í¹)­ ñmÙhËF{¹M™ûJ‘¦yN@qu"m±h‹E{3¬Lic'6 %íµ *mQi‹JÛ°¢-fmioIiÇÙxGŒ¹bº’ø¶ë£öö”öü¥xV|Ú’Ó–œ¶ä´%§m’·3©ûRÚ÷x±Ð´å¥-/myiËKÛ n»ÉiÇD­èµczV6ÚÔ¶/¤tø×cS²ÑŽ X’Û1Å* íø¤ÂÐvaך6yíÛ)ˆÎÙ†¶´å -m9hsÞ~¦XÛì·_øús="~DrûeJg~56%mÉiËP[ÚöG1&dÄþh,¥ŸýqîÝ#ºGlf%ß:Ï?r<9Œ8q>r<IÄÈ`d*6ùª#VG¬ŽX±:buÄÌhuJ÷ÿql™ß‘ÊÈ¡`ÄôÈ¡`Dã(Ž÷1àrDÔhOJÓ?Þû#G‘0ŒH±:r(Q;"tÄàèXJ/ã7âwÄïˆß‘#ÈÚµ#)éö#Q;¢qt&¥÷b$H‘<Š™rý|óã1Ñ=•Ò_üa¼˜óQL’ëû£˜``Ïò;z”ÒOýn4‰™œO±Q}¤ŸBw\å¿q²óèyJ?vôäjDüˆøñ£^œ a£q¶ŸðÏ÷¦ô+ÿ)f±g–Áœ”~~sÔæƒ9é™…°L=Ï,Î3ayJeïX «a d͘I˜Y`3˜X˜Ù”Ò/þóxÛVØ;`'ì‚ݰŽÃ 8 yJÿOã½ûà³3‡ÁBU2?SÀM˜µÿ{ñ¶SpÎÂ98à"\kpâ„qÄVnÁmx ±@ñfÅÿÓ?Œ—˜4™¹ ÷à><€‡ðX²ÃÌtJßú³xG,iÌ@,dÄÊEèŽ œw«_B¬MðÛÍRú/»l Ëo7úŒ‰ž.«ÝFJ¿þ×âÙXx ¶Ëj7Ö¨íƪµÝXK಻ &€Õ.«Ý:sÔÿo²Ø¨t7¿]sK]V»Û€ÚîgØRŸ€Úî~Ø•R½6¶’Ý]V»„v™éH©÷[ñj»G@ºÇ@6º²Ñeµ{¨íÆ´ælo\œÅ¢¶Km×P·kÆ«Ë`÷|Jÿþcóœw¯çÝ 9ÝÚ‡­Ùcöïüåx1«]V»¬v í>‹Wݧ®a©í>Iéw›ñŽ˜_ã·Ëo÷ðÛå·Ëo—ÐîGïÍì0“ÆÙ‡ÔXõ]ƒ“‰1˜sÁvÂ<ÒćYÓ¿ÿ“ñbsP‹`1,#žÌ%Jf](s8±V@\wÏÿàtlÀeËÄjˆÕ µk@.U³·ÅRÏ~˜„)ýÏ¿ïõží`Úfb'XÇ™Ø Vo&L{MXÇNw<²*3q¬ÅL«-³'ë?¾µ 3qÔ?·Lž™=Ϭ¿e/=amâOéÏ~¼Ã,ÃLXw™8æá&Î5–‰ p .Ã0uŸÍxtnÂc¸žs~ü1nÁmøâÓ߃ûð‚¥…ì…G±¯ž¤Æâw±ÈÆsˆgã¿ÅWx¯Áa+Ô¾Kå?oûd£#Õ ˆ–D´æ¥Æí¯Æ³Dµxk-HQ†–´–‚¼´–´D —ª[q {×#“”­@w+–ÔÖ¦ÆæÿU<¦[1A sÔ¶¤©kr²Ñ²‡Z¬¶ö§ÆÎß÷ÆJç­X#ªu$5öÏgÙo±Ú2ÅÚâ²u L¶¶Î¤ÆÑ¯#´Eh‹Ð¡-B[„¶Ì µÄ¢uXm±Úb°eʶu+5N/‰MqÙŠ/Mc‹ÆÖ#–‰ýŒ·Q­§©qþOâmfÅ[ñ¡-B[c“/=Q¯SãúïÅ‹…¡³Ä„¶>«ƒ,5Z«¼d ŸX°:ˆ‘´Ž8h¤Æƒ/Ñã„ôî«V¬X°:°à;`uà”?uÁWðqºó@J¼ Ö¤ÆôØ2oº&°zò`+0=`z 'ôäÝV;ScæÅ8HÉÀ‘a@ò€äÁ!W@wAO˜Ä‚êq g0kÿËŸ­0=ˆ%S]w ¥Lby”éÉ’1õgf'37œ±: y *Ýtp#5þB7¶¬ÿâTƒéÁÔøÊwâYöá-žeÀþà Ä–õßAìD9à²Ãe‡ËŽtŽQ©ñ¾ïeµÃjÇÒV‡éÎ8ÔvíÚ¹DuΦÆ^ ¶CmG,:îlèÜ!¹Cr‡äNŒúâž„{âz+¾åK¸›¿·$6÷$0ÝaºCm瘗Ïb5m ,V;¯Rã¿¿Ž÷†é÷óÔ ¦­Ý/0žÀ]ãcàÞ€ñ¹àŽ€ñùà>€ñ…ilãWâ›`VÙèY4—ÁrX ÖóÆ'`5¬µ°6@̯=òh l…m°Ç7§ÆŸÜÍï„]°öÀ$X3ßà ³p85~´>6p ŽC,,„SpÜC9Þ›û?—Ææüíx[, ˜Á¿Wá\‡p nCl ƾ‹ ܇ëƒO n#y ¯ày[17^÷Ì@Ü-òâ~wNE±‚ú:­þí¸Å#À[3îîà­÷tðÖŒ;9xkÆýújs,)iƤâã4vsclмæ `°ÉBsYÛþ§ñ,—M›46×—M.›A"š›Ð&¡M7kew{"ÞFm“Ú&µMj›¡6ÖÀgûåB¯[x"AÆ`Ì…y0ÀBp/ΉŰ–Â8,ƒå°VÂ*˜€Õ°ÖÂ:X`#l‚Ͱ¶Â6Ø;`'ì‚ݰrØ “°öÃ8‡à0£p ŽÃ (à$œ‚ÓpÎÂ98à"\‚Ëp®Â5¸7à&LÁ-¸ _À¸ ÷à><€‡ð؆§ð žƒ›NÌÀKx¯á ¼…wðÂôøèΠΠΠΠΠΠΠΠΠ΋¸ÿŠó‚ó‚ó‚ó‚ó‚ß":ñÇ4vQ¤§XKx’ÆœÊÒØûÿÿR (D B (D B (D B (D B (D B (D B (D B (D B (D B (D B (D B (D B (D B (D B (D B (D B (D ˆûUD B (D B (D Bj>j¨E Zj¨E Zj¨E Zj¨E Z·¯uûZ·¯uûZ,jÎkÎkÎkÎkÎkÎkÎkÎkÎkÎkÎkÎkÎkÎkÎkÎkÎkÎkÎkÎkÎkÎkÎkÎkÎkÎkÎkÎkÎk’k’k’ë°¿*½øØ%ÇÒØ×ªxÄ~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~Í~=kÑÞ 4` æÀ\˜óa,„E°–ÀR‡e°VÀJX°ÖÀZXëal„M°¶ÀVØÛaì„]°ö@{aöÁ~8á†#pŽÁq8œ„SpÂù‰4ö•¯Æn:Æ~áñè<\€‹p .ø ×à:Ü€›0·à6|wà.܃ûðÂ#x O`žÂ3x/`^Â+x oà-¼ƒ÷ð%|öÅ{QÅ~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~Å~uÎÀY†ŠóŠóŠäŠä*ÄŸMc?÷ÝØ“ÓØ7/Ä#ö+ö+ö+ö+ö+ö+ö+ö+ö+ö+ö+ö+ö+ö+ö+ö+ö+ö+ö+ö+ö+ö+ö+ö+ö+ö+ö+ö+ö+ö+ö+ö«†—ÎΙ•šÌšWf•;›~ä“͋ԙåêÌýü™_–d~y¹# ‹™òqXÖ¶3·fgn¾É¬sf~F‘™&ÍÖ€Ÿ efN²˜÷ƒÌÕXæ~êÌ5væn¹Ìêu#x·0f~5“í‹™û²=àVÌÌüxæ7™ý37²dî)ÊÜ(—·bf1}Ãx¿ŠÊüâ!s[|æ÷$™;2w?e,Y\—YÉÜô‡˜tÓ|v ÜÞŸ¹w0‹ ñ˜Zó{¦,t_Nc_ÿÉØÅ7ÒØ·~&KsÏíñžâ6«¸‘Ô?O1Åï+$_!Å]WqCNÜu0ýêoÆ{¥9[§9ç¾ޤ97Æ££iÎßøåxt,ÍùíGñèxšóÿñÈWM±d÷†Æí™q«T¬•Ϥ¹SÛâ×Dñk˜ø‰CüETòÙOkÑ‹syÉå%——\^ryÉå%——\^ryÉå%——\^ryÉå%——\^ryÉå%——\^ryÉå%——\^ryÉå%——\^ryÉå%——\^ryÉå%——\^ryÉíöÜÏíìÜÎÎíìÜ~Îíç\^ryÉå%——\^ryÉå%·sÊrŽrsyÉå%——\^ryÉå%——\^ryÉå%——\^ryÉ­›æ~x‘»öË]ûåæ^s—›ùðó¡ÜJWî)¹_6åfÕr (¹_æ&Qs~s~s~s~s~só4¹ÉÖÜjPn](·B”¿¿6ɉωωω/gÅÿD„«$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$¾$þó¬øŸvGÔâÏÄ&þ3ñŸ‰ÿLügâ?ÿ™øÏÄ&þ3ñŸ‰ÿLügâ?ÿ™øÏÄ&þóª4÷kßžýGeýµú© endstream endobj startxref 358620 %%EOF rlang/tests/0000755000176200001440000000000013614040227012516 5ustar liggesusersrlang/tests/sink.R0000644000176200001440000000115513562501424013612 0ustar liggesusers library(rlang) # `inform(file = )` tests cannot be performed with testthat because # `message` conditions are muffled. # inform() prints to stdout by default in interactive sessions local({ file <- tempfile("inform-file-default") do <- function() capture.output(inform("hello"), file = file) with_interactive(do(), value = FALSE) stopifnot(identical(readLines(file), chr())) with_interactive(do()) stopifnot(identical(readLines(file), "hello")) }) # inform() prints to file local({ file <- tempfile("inform-file-custom") inform("foo", file = file) stopifnot(identical(readLines(file), "foo")) }) rlang/tests/testthat/0000755000176200001440000000000013614116052014356 5ustar liggesusersrlang/tests/testthat/test-trace-collapse-magrittr-incomplete.txt0000644000176200001440000000110613612375026024762 0ustar liggesusersFull: â–ˆ 1. └─NA %>% F() %>% T() %>% F() %>% F() 2. ├─base::withVisible(eval(quote(`_fseq`(`_lhs`)), env, env)) 3. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 4. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 5. └─rlang:::`_fseq`(`_lhs`) 6. └─magrittr::freduce(value, `_function_list`) 7. └─function_list[[i]](value) 8. └─rlang:::T(.) Collapsed: â–ˆ 1. └─[ NA %>% F() %>% T() %>% F() %>% F() ] with 6 more calls 8. └─rlang:::T(.) Branch: 1. rlang:::F(.) 8. rlang:::T(.) rlang/tests/testthat/helper-print.R0000644000176200001440000000014313351410655017114 0ustar liggesusers expect_fixed_output <- function(object, output) { expect_output(object, output, fixed = TRUE) } rlang/tests/testthat/test-with-abort.txt0000644000176200001440000000163613612375012020163 0ustar liggesusersprint(): High-level message Backtrace: 1. base::identity(catch_cnd(a())) 9. rlang:::a() 10. rlang:::b() 11. rlang:::c() summary(): High-level message Backtrace: â–ˆ 1. ├─base::identity(catch_cnd(a())) 2. ├─rlang::catch_cnd(a()) 3. │ ├─rlang::eval_bare(...) 4. │ ├─base::tryCatch(...) 5. │ │ └─base:::tryCatchList(expr, classes, parentenv, handlers) 6. │ │ └─base:::tryCatchOne(expr, names, parentenv, handlers[[1L]]) 7. │ │ └─base:::doTryCatch(return(expr), name, parentenv, handler) 8. │ └─base::force(expr) 9. └─rlang:::a() 10. └─rlang:::b() 11. └─rlang:::c() Low-level message Backtrace: â–ˆ 1. ├─rlang::with_abort(f()) 2. │ └─base::withCallingHandlers(...) 3. └─rlang:::f() 4. └─rlang:::g() 5. └─rlang:::h() rlang/tests/testthat/test-trace-local-prefix.txt0000644000176200001440000000027113612375027021564 0ustar liggesusersFull: â–ˆ 1. └─rlang:::g(current_env()) 2. └─f(e) Collapsed: â–ˆ 1. └─rlang:::g(current_env()) 2. └─f(e) Branch: 1. rlang:::g(current_env()) 2. f(e) rlang/tests/testthat/test-trace-collapse-magrittr-complete2.txt0000644000176200001440000000114713612375027024523 0ustar liggesusersFull: â–ˆ 1. └─NA %>% F() %>% T() 2. ├─base::withVisible(eval(quote(`_fseq`(`_lhs`)), env, env)) 3. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 4. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 5. └─rlang:::`_fseq`(`_lhs`) 6. └─magrittr::freduce(value, `_function_list`) 7. ├─base::withVisible(function_list[[k]](value)) 8. └─function_list[[k]](value) 9. └─rlang:::T(.) Collapsed: â–ˆ 1. └─[ NA %>% F() %>% T() ] with 7 more calls 9. └─rlang:::T(.) Branch: 1. rlang:::F(.) 9. rlang:::T(.) rlang/tests/testthat/test-trace-collapse-magrittr-before-after2.txt0000644000176200001440000000124513612375027025253 0ustar liggesusersFull: â–ˆ 1. └─NA %>% C() 2. ├─base::withVisible(eval(quote(`_fseq`(`_lhs`)), env, env)) 3. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 4. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 5. └─rlang:::`_fseq`(`_lhs`) 6. └─magrittr::freduce(value, `_function_list`) 7. ├─base::withVisible(function_list[[k]](value)) 8. └─function_list[[k]](value) 9. └─rlang:::C(.) 10. └─rlang:::f() Collapsed: â–ˆ 1. └─[ NA %>% C() ] with 7 more calls 9. └─rlang:::C(.) 10. └─rlang:::f() Branch: 9. rlang:::C(.) 10. rlang:::f() rlang/tests/testthat/test-cnd-message.R0000644000176200001440000000457513565176436017700 0ustar liggesuserscontext("cnd-message") test_that("format_error_bullets() formats bullets depending on names", { local_options( crayon.enabled = FALSE, cli.unicode = FALSE ) expect_identical(format_error_bullets(c("foo", "bar")), "* foo\n* bar") expect_identical(format_error_bullets(c(i = "foo", "baz", x = "bar")), "i foo\n* baz\nx bar") expect_error(format_error_bullets(c(i = "foo", u = "bar"))) expect_identical(format_error_bullets(chr()), chr()) }) test_that("default conditionMessage() method for rlang errors calls cnd_message()", { # Fallback out <- conditionMessage(error_cnd("rlang_foobar", message = "embedded")) expect_identical(out, "embedded") # Only `cnd_header()` method out <- with_methods( cnd_header.rlang_foobar = function(cnd, ...) "dispatched!", conditionMessage(error_cnd("rlang_foobar", message = "embedded")) ) expect_identical(out, "dispatched!") # Both `cnd_header()` and `cnd_body()` methods out <- with_methods( cnd_header.rlang_foobar = function(cnd, ...) "dispatched!", cnd_body.rlang_foobar = function(cnd, ...) c("one", "two", "three"), conditionMessage(error_cnd("rlang_foobar", message = "embedded")) ) exp <- paste0("dispatched!\n", paste_line(c("one", "two", "three"))) expect_identical(out, exp) # All three methods defined out <- with_methods( cnd_header.rlang_foobar = function(cnd, ...) "dispatched!", cnd_body.rlang_foobar = function(cnd, ...) c("one", "two", "three"), cnd_footer.rlang_foobar = function(cnd, ...) c("foo", "bar"), conditionMessage(error_cnd("rlang_foobar", message = "embedded")) ) exp <- paste0(exp, "\nfoo\nbar") expect_identical(out, exp) }) test_that("can override body method with `body` fields", { local_methods(cnd_body.rlang_foobar = function(...) "wrong") expect_error( stop(error_cnd("rlang_foobar", message = "header", body = "body")), "header\nbody", class = "rlang_foobar" ) expect_error( stop(error_cnd("rlang_foobar", message = "header", body = ~ "body")), "header\nbody", class = "rlang_foobar" ) expect_error( stop(error_cnd("rlang_foobar", message = "header", body = function(...) "body")), "header\nbody", class = "rlang_foobar" ) expect_error( stop(error_cnd("rlang_foobar", message = "header", body = ~ format_error_bullets("body"))), "header\n* body", fixed = TRUE, class = "rlang_foobar" ) }) rlang/tests/testthat/test-trace-collapse-evalq.txt0000644000176200001440000000107413612375026022110 0ustar liggesusersFull: â–ˆ 1. └─rlang:::f() 2. ├─base::evalq(g()) 3. │ └─base::evalq(g()) 4. └─rlang:::g() 5. ├─base::evalq(trace_back(e, bottom = 0)) 6. │ └─base::evalq(trace_back(e, bottom = 0)) 7. └─rlang::trace_back(e, bottom = 0) Collapsed: â–ˆ 1. └─rlang:::f() 2. ├─[ base::evalq(...) ] with 1 more call 4. └─rlang:::g() 5. ├─[ base::evalq(...) ] with 1 more call 7. └─rlang::trace_back(e, bottom = 0) Branch: 1. rlang:::f() 4. rlang:::g() 7. rlang::trace_back(e, bottom = 0) rlang/tests/testthat/fixtures/0000755000176200001440000000000013612375027016236 5ustar liggesusersrlang/tests/testthat/fixtures/error-backtrace-rethrown.R0000644000176200001440000000046613610575110023274 0ustar liggesusers options( crayon.enabled = FALSE, cli.unicode = FALSE ) if (nzchar(Sys.getenv("rlang_interactive"))) { options(rlang_interactive = TRUE) } f <- function() tryCatch(g()) g <- function() h() h <- function() rlang::abort("Error message") tryCatch( f(), error = function(cnd) rlang::cnd_signal(cnd) ) rlang/tests/testthat/fixtures/error-backtrace-empty.R0000644000176200001440000000047413610575116022567 0ustar liggesusers options( crayon.enabled = FALSE, cli.unicode = FALSE ) library(rlang) opt <- Sys.getenv("rlang_backtrace_on_error") if (nzchar(opt)) { options(rlang_backtrace_on_error = opt) } depth <- as.integer(Sys.getenv("trace_depth")) if (depth == 1) { f <- function() abort("foo") f() } else { abort("foo") } rlang/tests/testthat/fixtures/Makefile0000644000176200001440000000027013614040227017666 0ustar liggesusers SRC_DIR = $(CURDIR)/../../../src ZIP_FILE = $(CURDIR)/lib.zip lib: rm -f $(ZIP_FILE) && \ cd "$(SRC_DIR)" && \ zip $(ZIP_FILE) config.h lib.c lib/** print-%: ; @echo $* = $($*) rlang/tests/testthat/fixtures/lib.zip0000644000176200001440000011146013405732277017537 0ustar liggesusersPK TLMæ3»¢!!config.hUT ;\À[;\À[ux ÷#define RLANG_HAS_RINTERFACE_H 1 PKƒTIMX˜ñ,ï÷lib.cUT uh¼[Z\À[ux ÷mÑAnÄ Ð}Na¥ë$çè¾pÀ ¨Ä0¢™Û—"Íf°Ä½/Ùoü8/Ð2x6¡Z‚=8b†âü•]Ä‹,Î9 ŸÓ¶Að{ÆüZỀ¸Xƒ…Þµl»‚x>µ„f,&^ɇ^ô¿Le_Öiúz?bnu·Þduó§c)YV3°a;¢¥½ž#ß*.»gÛž«„7EŸ)æ2úÁŠÅ|Õ€cÐÇ”£¥QÛ÷‰ÂGÌ”ZXé™õ¦B"m%ZðLŠ>*ŠS¼ ùUøu©¸T&1˜”Án2*.Æe=§²§xé›úPK$_6M #?|–h lib/attrs.cUT ó¦[Z\À[ux ÷½VmoÓ0þž_q ¥UY¯¨*/‚iñ¡4MÜÖ̵+ÛÙ:Pÿ;çsç¥[‹DÓ–ù.ÏÝ=¾{ìÇ\f¢Èœi‘ÊÕùú,ŠØÎ2-Á°Ýv´œ¬˜MRk5_–™Ø›vƒ—ßd«®ÙÇQéà,¿Šjÿ¬ƒ×ݦ«êõ&À¯šP0A Én©r“ÏW:Ùîœ'zù9&„‘ Rš»ÉcUÂhf¶ÀBiáe´¢ñ¾HÁ¯\-]Ä ú0 âšì†iH…PYŠ`uÅ­Ü|¸Æ^EÈ!Àíš ¾xD\Bx¾„¸¬¹.w“IˆâžÉ“éܳTÇ¡r÷èd“êëĬSÍr²S Æ/íéwc2oBî£À¨Oš(­8"ÇÄPÍqƒŠŠ&‡xoc&-—L´c» ]"”=“:~r~?^VÔ nl’ %YR °ˆëL|˜<©Àúm戬¬£2UŠôæj:Ÿl¬6 ?Óí_’àüþCá‘o¸€ßmGœ—¹³Ì§Ã®,¹6–Òµ„9ÁÏOè`°´EvÞ$»»÷¡ïNàžÊ~QËÜŒ$Vy©qô¥…`„¥VX0.W@Ðù}zSRöK–¢åÅVp§$ÎËꂤY=3‡@.·Ð©Tù=íšÊ^+©Þ•=z]Ê}©…Ž–éívOæœeÛoÌvǵƮlùöøú/Zmx¢”¯‡ jq=¶Mîi´mCviç<ý ³ÝS¾}5£ž‡Øºï œÈ4ÏÁ*?¢Za#ã7un+ìg©,° Ü1ÛÙJAª3¹QI™ú‘c¸/ ¥C“»#ŒuèºgꫦÆÃaCøÊíèB[Í–Ü’1ņ‘\iætK*˜g—ç J¸t‚Øw ¦Wìfî*€?K¥A¨Û§¥A@¦¤ÁÎ,WÒiŸZü`™5ç1¦‹Åk¼7àíaã¶ÃUJ›á½`Ám=§ž(—2%U_¸|·QÈðÌÒԚ椺ÿ“l­Û{æœÓ ¯t1ù7†öÀ}«‚ðÝýÐKûüs·9ùüëÔT¨QVãÂdS˳®Í|{ñsþgg#øøåÃØ»dyæ,øÖÈá¡»‘§ŽZåFñ¼ºµ¶ß¡ûˆ0vN¼V€0 ¾·?OgÉÅlvõöU[íÝú§W羚gný9eÜKøßÒx?u¿PK!”8Mß²ÎD lib/attrs.hUT ½©[;\À[ux ÷UMOë0¼ûWXô’¢êIœ‡"xzO¥½[n²i ŽSÙN@üwü‘¦ë´½EöÌÎìl6™°RPâìÿüõ™Ì—ËlA^ÐÄ1Á)š0‘ó¦|£>«?›„ÒT³3Á-^A»½Å’¬Aªµd«FƒJüq;Åßc º‘Û¢“vz~P@ßÖáÏ:€½Q¾Ø"]’}¥Ywqimñ¸Eµ‘hñþ—¦o‰$E³å,§¬˜– Lؘ‰§,M“»?(šRè@Óµaö‰4js»ÜQnlˆê‚FÈ ÒÚÕ¬ØË Zåy~°¡KÊÈ«e->«UÍg½ÊQ¢.ÀsN•:VÈk¡4Î7TÞ:¯ê¨¯€%u¢ã&®9!œ-Ol𠇩™õ‰˜•v\sG²á9Ô!²qÀ£è:íg34d`Òóˆ“Ù£ýlF7æ²’]—ðµ3Vâ¤;À–+Î}-뻕¤^½C®Ýçã \A‰ÐU߀uØÑà .è°‹sIí nËåºÞ×ut EuvÌ}í™C:㫺ææjC•»6”CQ3>ž3ípÌʾ!3:ó?Q°ýPKæ¶HMrÔûŠx lib/cnd.cUT 0Ä»[Z\À[ux ÷µYÝsÛ6×_±QL6<×nîá"Å×ISùšišËØI{sI†‚HPâ™9å4ùßoÁOIÉ8ÕƒbØÝß~/‡©ˆ²mÌa*3&ÖÇ›éd2yó$~z{~ùâ¿ øÇ铚կÞ,.^{¸Àùooøùßo.}|ÞOþ.ïùÀ5 ³TU•š)…ª˜¬<"Ñ ü„–B‰R¦¢JŒVQ«qi1p2¸ˆ½ÞÞ>_ó1ã]mó¿Áé8ƒ£÷'G£âˆâód‚zWiŠß–ßA®ÖaIJ é^½}ùr>¹.Òd˜Š¤¹Ím˜ü’¼ àøøØ‡?‘­Áj›ÔÒ?ÌqÑú—ƒæø|‚;2ä×, oÒjÞzµÔ×WLq´Óu¿.¯=FI|ßPž_,Þ)þ݇~#Æ¡ß0)þ*àµÌ{çRŽg«ò/B^ ýä7›4ã@ØáûïáU’W[)P£…GÅe‰)$¿!^-4CË©t-P%U$UóRòˆU<5æøÑZŒÂà@Úµ§ñל.YtÅÖü‰qmL†ÐÏèëGúšB²nã2}ÿ¨¿gäÛ¼¬îȉt MÀ{€‡áÓ'x`%†àâjú‚|†6¡ø+äL› –Hµ„BÂÒ’-!»ÍçOý¹©"Ð* ®H¸âëSæ@÷öÓ¸½mÅöÎÔ: #ùæö'ºñMè‚8A¶v“¡;q¦£Ç²Ç€L%Ϲè&¥*¶2âAÇÛ&\;±ÚÂeüg³]¥v&F|³´ê…žèû½}—“[ôyÌø?"âPr‰G•J aÃL’6á†)¯« ¶²ï‚Nç² í?¤)‹+>FDS¨.UrË Å¤›K¢¨øÜÉGÙaTdèÏÉ£¨Éô½xòøñ»''ù›Mª€ŒœŠ5àŸqªÊŒÝñx Ø±&yü$Ÿj¼À3Ål¿‚ÝÔeáÅ™q¡ë<û‹øÒÏSxZµ&xÍc©5ù6ˆÊéñÏMQúŸÁ­? ÀÏvcÁ`K¶"ú† f2@3ÙS‰Þ ŒF¡u` ž€¥cç/§ß*Mµ¦&ümß°u§dRqϵ+”Q¥ß)GZìhùiUšF:šà7Ì"N+ P°œ+ÏÖV1Û¨ºcÏUzJÚ”÷ç5ù5Þ°kš@³‚$åY¬õ›öB‘+]®yd1hó‰K:Ô['w^M@Çàï> &˜"µÂ:‹Ž× æó^¤G*Ã^dH—-À¼ªõY1W…ÄÕ]ÉC‚Â0’$9Sm]mŒ.”mÆ«F]´'ºU8Û¯=‡¾>J¡£¡0‡OhÔ?i ÁŸ&ðÞìçÆÜŸ·¨Žß­ÇÕveL!cxŒƒŽHò—ØfYm^¦®”šù5mµ&Æ*“µLÓÞé(°f1‘µ"gƒµÜƒ’UúC.ÔÞ;ëٿɧHÄ£ü}ñüò?¯ƒšõ—æL—;ã1$Öv7™ÕóÞ´êzwZÞ‘–@Gº&ÒhÆrÑ䚥©´‹ZTL¬,é¦×8ÐjWG•ãŠqÕ¹ü½"ÈSˆn…ÀÕzë̹ƒ»ÐÁCt;T·‰F’çD”Kv¦`å‹6º> -% ¶´í&X¡Ù m ÍtŒY^õEp®W’³«ù©m¼ÒžÊ8˜NÓ¦ïYã½¾ðÈmYÍlЏÏŸ÷Fl´l›Ui=/ö¤}þ’fB–5ññ0MP\¼|öê_á/Ï.à ݤϟ=_„¿à®}Ÿyz¡A&,âÇ›67{\»é" 4.Þäl”ïhÒ—i¾ÍhÒÇ(e¡gyl:ôCª4m <_ñ8æño—?‘-ÐP§â"|¾áÑ­¿èÚùþð0“É„‹mNþuéN^n9|GPvsÓ+×¼jjߌ§D]$¦â< ƒ:~ôóÔ§Oö6Øœ2 Û']M®Ëñº¨ £åH­m#ªkå©34Á«WOñØÉÿyÚPÎáÑ£´ÕnçzŸ*˜é*•ÄRòÄΨ}-‡xßæ@]í»“Ž7eÔQt4³6°Ãq”—Íñ:¥ÒRZdU*¶|nW:cz“~í”uœM G~G3Ü…å3†áæ[öîÁòÃÀaÐwo.|ûòÓCò]6߃ãÔÅÑ©Ö}ÆŸmƹöáêÏù.é&HE† 6(VÿÃy¦¾®˜qÞÉC¡LÖ´/¶8cøMNEZa¥XI&ï·-­7Úú–R‡§wk_dd˜3yÒm0-¶Ê½°Ú=1ä`ƒÂ» t:ƽóg//;Ö, ÃÖ¦c¨µœÍŒ}v᪠\݉dožik?Uå^TfbØ´osA„3SêÖ\ÿW‚òŒŸóm’dôl ¯®4ÞûzÐ ì…ÕMÕÇ×ï†=; ¿GoàÞŸ:Q8­·©÷áþ´s¥ßñÀÚwõlÇ+áM`^nÝ«þ¸ ì;æÇNØ#['ÓÿPKUDM,Y0•ô lib/cnd.hUT ÑÒµ[;\À[ux ÷SMOÛ@½ï¯ 9ÈŠèÇ­ mEPUå´Úxg“ö¬µ;†Tÿ½ã8qpÚ7ï{o>ÞÌxäYtpóíìê‹>¿ºÐ_ÕHO8ÀÔÈSQ6á$±…PN§J©‡à-DíÉ…XeE ÄP,L<Wq“Édüi#z4‘^‘˜Yˆü hm˜£Ÿ5ŒZg…ˆÜDo£=1ÆØÔœ ¶“Ÿ“)u ޵Å:baí F•æ9<¼¾kSÜ›9æpYÒÃÐվĻyö–p×P±Ç¸XéÊ® Ö:q|UJø¨Ec=û@Y‡òïº÷°òÜ}ZÃfʆ}žÊvûíŽÛ’éŸ4Ë1üQÝøáÇÝõå÷Ï™€Ó)ü¼<¿ýu ‡‡pã¤ÛFÏ)[æpÐ'9ROýv ²ë ­“ °NË®O«g󮳪q®4³‡êÕ½QÛÛKb…ÔT­zÓ¼nGع_¥hŸ[¦pœ¹ S’ËæÝÓvêi.ÌûFn8DÁ?ìàýy ÷Q=ímo2˜©üÃ(:§þPKŒ\?è`7}Ò÷ÒÆ¸ÎÎ=`‹îg;ˆªª–ÑôÀÚÓ:iãüD] <ÁªàVСµðïMs”¬'dORlß\ vhåC¹*%”ÚGkZÐê« ƒ^e’×q×¢'Mn©£{b½~6|Žãý¯IËã5š—ðÔbl73“ úÌx‰Œ,û§J´Ò7f‡Ý¾‚ïÃâ…É{3:0QO=´Ôáì Æ3 Xs1Cf8hN§Ü!¿›ÿ‘â%Š¥Ú×»¨s\jó PK…\3¯¸ 5¹DÄÑR¨Ð´†É&å—§j  Ä'ÂÔ¦æ•%Ö¤æ¥d¦qPK!”8M%½=ºclib/env-binding.cUT ½©[Z\À[ux ÷½U[oA~ß_qĤYZbëkWZ] ±bƒ¶/Æ,³»³0:Ì™YÚjøïž¹ì|1ñ˜sýÎw.¼d¢âmM¡§8³Wó^’$¥”TAŪ(™¨™˜LK%LÓTÓÇå) rþ§~ZôáwÀHUaž–T6©“¾‚ø,%÷v€BRJeÒÞHªá@•’êòÇ%­ ­ÁÛòB€‚oZ³ŠÚëglà‡"Ë0 À´N=Hb 5­¢u†`—æän'÷W7wù–E+JÙŠÚV‘%ë#‘ʰÕÿçǧ=NO¬|R\{›‘¾ PŸ‹´o‹J´!†U´ ±6 P#r­Ù/ ƒôfNåH·+Ä&U¨±`ˆ}FÕ=2Û$|‡bi”sBQQSE›ÔÉâ]hjÒh8€ È#f— œFªsRWÇù9LœLÃøîæÆÒN8‡á-b5ô’( DX±¬_Én;}É{­ jí)pc€1ŠzFµÔr*ß#m‹ÒÌTó­öÇH>TEpôoœisÙ9wA¡T”üÌž™Vs¢°ÿTmÛ7„ëm‡š6¤åòèTÝ ÚÍÕ´6uŒÚ›¢¦?ÝZ¿8®©œŠ™™o*Ìö¦Å¶%;4^šF*ˆÇPs‘áל±nMâ~eîi÷+ÐÐY€ÕzTÈj1ÃÁêp €õ½ß(2¶ç¡ ¦Ãf"˜j®öt÷EE»80HžÉ!.`>¾/®Gãw£ñ‡Âݘ ð£÷6±MM;3çÛ43ÝN>}ÉwŠ=˜2\°Ïxõöëè>ßáÆ&´¶›˜VòÂï}”Aœ‘y~›î_!ÑQmÿzL<€gÖߨw»Vøì”ѦÒxŒ»?Ñrîf~{^ÞOò<}’íÞ"uüPK!”8M ÙÉ¢Llib/env-binding.hUT ½©[;\À[ux ÷uÁ ‚@†ïó^*†ßáBåT`úÑFQ"—"Z “·àÀŠþ2R÷Iª“)«œÕU¶}MøÄøë:ñÃs€ œ»:Äû86ðW'‘˜ýËH«êö󉵬›ªdMMz†º8DÝ—SoDºd-w£ÎíNÚ>X À!3ðPKq‚HM8ªgÊT lib/env.cUT vg»[Z\À[ux ÷•XmoÛ6þž_qõ0TN…´ öeõ²¢/n¬Í /- ƒ"Ë´­E"Šríþï»ã›(K6Úu$ñøÜÝs/<ö‡œgE³`0’EÊWëÑÙYͶÕ9°MZ$_rµN¶‘ù’¥EƒyÞŽ'}¹Ý {Ø îx8¹Å=<à^g—Lx0¾‰2ÁkÙ:•çPݯÆðõ ¬<¯á Q*Yæ|Í’›´du•flÆVy­$BˤޕíDt€| í£ Ÿ‹†/HÀÀ~LçBªhô:å,p w?Öw£X›AX{ü'™j$GS&g{´]¥*ϼyÚ´SÖ{|‹!ô‡C‡Äü¿®Gz‡ñ@ËAOŸšs)TR”yÍ@ |)Ò‡Ý{‘.Þ¼Z2•­£±&Üz-µ«˜XF¨eL|œýù᯿?:×ÿ˜N?êµ )øÈl}¯×¼aS’!£XY©™ª¹x;›N£Ÿ,1ÆÊ[™¯VLÒv–)à%ÆI)¤µKc ‡Ö0ƒÓ¨•Xúƒøw©3OkFùCÔóíÃæCdwiƵœh7¢ºxlb"7ŸÞ¿Ÿø„ukߥ4<®–³/zÓ«”HªT2®.°ÖOKÖùëʵ•gdr)x‰h6{ ´NGÚ ôcü2+ˆc^¸‡çašP̤֘Tâž¡72²;¶»M®kUWæÏ óç9\þrÌ»FÆæä™jñ\%¶ùÒC›¾ØÞJÆ0q%¬²oö¥š¢06^pñëe½êDtiù²—>\´’Ö IE®m‡ù¶øŽ¶X÷÷¶lôBZÄÞ÷jšï {Ï]Ôq*& >ìû®oY!8 [hßê#ÎÃë ÞHƒe^£N±…QÒi¢› Õm_KjQ#E-ô@nŽ:Ç*ÖK¦c#V'ÝD£4¹Ý.f*P¸• ‰CóŒUÄ5ïÊ¥Ÿ%A·æŸmŸv-³Qmµ%Í5Oã+µŽÈ o•æ'©”ÔÙZ& &ÙÒ a•Yr¼~²Bú»¯¦Û5~„¼†¬‘d~±Ãƒ¾¤;KH³Œ¡-|j5×ðLå‚뎋*ß0ƒbY¶ÍX¥PZŠfµöÕtjPE™Þ#¹‚¼¬âÎ :) B%YÍä†YX‡Xe(+>#öˆ­/Èj‘ã+GGŸMðϯÀ'ðäIã%Š=!.Œ7%ôÓF3‡Xç~ƒ • )Et–Lo>'¯®oÞ\ß¼K^¾¾½þxYØ`}ÙÕñ; –šbºŠUŽO‘w´ï–B f7ØÝ=56ÙðÕ¯ [­­½cÖ`¹®|CN3ÅÌ”m…ÞÛä:fÍ©‹Ó ¶‚eë.ÿÅ"ú #¼¾Q)ÁžH4KÏh‰'G!J†JÂÎê‘/ôy—«$è#KM÷Òà/¶æ*>êº^2<{uïŽê(ò9u™@ÅÁAÒ˜C3,M·£´¾ ïzà¢aõB»r;û45T˜ßñxt0ûRr–©¼Oð ÌrÑÔAÙœGîvDÎ y¸ †o ~ÇðôÃ) J”ºÐ!CYòw<t«k4NÜ^“[ x­Í†(nÍ] ë´^ŸÖÙQàn a¿÷ÍçÈŽ»Ví6èÍWðpDQ€jÕôsì0_üÿ¢D­ìã^vìÏþPKC‚HM“sÇ× lib/env.hUT g»[;\À[ux ÷­UÛNÛ@}÷W äÅAV©Ê#P‰¶†"¡%(jŸÌÆÇ[Ö»Öî&$-ü{g}‹s!R_¢õÌì9³g.éñT&˜Âèîjp…ƒIôÝë‘Kܰy=.c1O.ŒM¦J‰ÙçŽq´@m¸’Îêµ:š 5e"B¹€QtS~„rÑ ˜2ƒµû 7˜vU{Cwvn—µƒËâ„‚r´™JL$‹E0tÞ¨½L~éh. éÍ]…›nî"¸½Aq¿hÿ…ô±pÃ휩®±¦ú+UQeõ[HsÁ1'x‡aK’•9ª\އš©XƒÉã#¬ˆ†gáu€ÁÞ í4§óv×Ê1¡„ÚR–¥ÄòZ¿ÂF¨üp®rªD#\ØFï`Ã,œ%‡ü4ù\),”Ì A, äÎÎA8"ª½ÌAio‰EU¢¢ 4TÅ /Y€Ñ™Å½ tèf§C|)6†™fÏG@­dsDt:€`¯ï z}°Á‚6PxÅÐÊF :ÜMÊߨ‰¥õœœ²á®sPØE]ÇOðnhšføªÓ³¸köA kg±€X­Qb Vž-¿ê6ú…¼”—Úñc³ýtš\ÞŒhNŽ0š+ÒXäÙé ÷ç,—GÁ1L¯&@ã•7%¶SØP_oÐIj•]Å'·âv7@t䯎±Ð±;Sºƒ{`>QdgüEö3¬TÖ&X­±O_¦ »áû0‰á aü‘ĸÈê~uŸ©‚¸2PKý^6M ^E˜ï lib/export.cUT ­¦[Z\À[ux ÷uS]kÛ0}÷¯¸$Pä"¶ö­Ý ËëÒàd¡oB±eÇ«sm$Åk)ûﻲìØËº!éêÜsî—¦&å1U0Ñ¥Ä|¶ŸÓ“I=ו¶ÙnãFiST8Û ÈœKUV JY,¶Q¼þú° áâN7¸ugïÄ®8\sx†!òKzù.ŸTôl•FY®¬^ ûr/?–s¨9x•y¬ueCx 2µÕ@ë†n´Í2„P»›Vö¨ñ_ræ`DÛ¶T7Áï ×‹Åz—¦.¯jþ'Y“bô¸YmbA‹™p¤îCrS…i‘]Êmʃ2µLK*4’½Ô—€’G¢ÆêsRùE+gâð´nMŒ ­š‡&²,{”æåÀ&¹²Ë^dâ±cq¹@>0gäƒÖ˜•Œ òÐB5²ì ±ø,аi‘‹8ŠØÕ8qï嚪H»„µÊ CåuU ígysß©vm…8ôÍÉp\׆>7&(CN!ãÑEëw—ÕØ[T»ŸC½PýJl¥Ù6š¯WÞû:¬£ Íñ|ó@Ãq¿a'M0w,ç¤I)y«Y7:>ï®ôj”½³ô¾hc1wë—î*ùÀ9:5Å6MýX¿ÿ—[©»‰è‹r8 z²¡‘×íøPKæSLMQ>áÌU lib/export.hUT Ï[À[;\À[ux ÷SïkÛ0ýî¿â Pc¶ÁöÍeò£+¸iQÖÑoBµÎ‰ˆ*I. ¥ÿûÎqd{¥ceþëNï½{wçLTi$–ÀòÙúŠ/înÙOþ#šPN|›Ž&ʺ‘—ì­S•ù´û>Îr<øÏL®„lïZN q§'cÆ-Ùæúv=…‹ è#¸lÏbü5…o)|™N#¬±u×ÊÃËs¥du‹œ¯î×s(MöJ?¼ö6‹ê„dnÄ—Ö}çíÊÄ^§Ð¼Ø†cm+?Í¢a|DIÙÒ; #ÔTeÔû ,˃‰pÃø\h}ƒ~WÉÅ–‹GcL¨5Æá97àZ_›²¢;©5WtÌh¬í0Àja¶ÜâV9bñºR†ÞqQç¡Ø ›€q)Œc²ÉxÂt4Ej-r^xU€2º]|§>(½ÿ?Äëýöoêa&­<¼D@í²³Ú|´Nüsròú//Ã,]<Ì$:¥Tç£Og{KB#AüÄÂö‚Xˆ]˜Aè‚U§æ\ܺ†õ}ž§£ÊçÄÀÎNäÆáâH£RÅæøôXé3{5Ë7Ë÷&×ï€> Äý‡·Pi‹¾±†Ê_¡³ºx*þ¿PK$_6MÁ@)*ª%lib/fn.cUT ó¦[Z\À[ux ÷uޱÂ0 D÷|EKŠ cÅÄDië–J®ƒ’¦P!þ¤¡E l>ûÞùÖ-•è+à+‹ššÝuÅsð¸m¸UwU{*ûÖHËÚØN£Ûò$ Só 4düÉøGjÛ8~à')Ï"E‘©@$",®³äl?ql4¶IÑé8÷,7D˜œOųˆÂ,†ŽÆ¿km~ou³\åË¿*ÇFý:¹O¶Bzjj:Z´ù¬”kóéœZkLh§¢>U°[tÍ;ÏŒp»´Ìúy šÊOT4J[oàr‚kÊ!M±í ÁJE|z1g<ä„oQyåÎ2ö á>ng3 %ûPK$_6M;{%Õ—r lib/formula.cUT ó¦[Z\À[ux ÷ÍTÛjÛ@}÷WLTr¡uÞ,[J )-…R”µ´²D×+³»²‚óí½Iò¥ íSäÝ™3çÌœ7ÏX“S#|qYƒÁ@ÒíêDZ¤¢”¡ýU áiPŠT=®h]„xv–ÀôföñË÷;{˜FæµPað°}€e#Ì)(j±l †1FíøOn*••ŽQ¾P%ÂYŒŒH £1ªÁ×9M3’ ‰}ÀUðþæööÞ]å´ SãŽÆ'¾&¬Ê ìz*Ùÿ¡²a섺cùÿ¤‘òõ¾Æ~AUJ”Õ¼Q4,"<’Ë0¸œðu%j¾¤\C„D=óºf®$òÈÊ\úäÐ×/öQ0Ê®dé¶T\ÌêÍí7NÇÂKET•AVslwVq]~ÊÉ’Ê£ŸÀÏAÁ8 `º=9P˽ LÒnx†SIIލí "ÄôÌÈÀ~Ík–þêàèˆW£á‹•4– × ¼õ±Z¿kµaàø†n4I`2û†Jb›Ñ¡H—ëᎋëò= Øë“õõ¹®ï<Œ¼†QWP_»jí´^©æ®”h¨ñ„³*§›T7†s‚Fn¢ûl…9cØSU1œN ϾN§í¤Ú ϯé<ÿìŸNº}+›šç纶Vl_íñRÀëÞZà@ûOéÀ^EÜ~±qoÉa€l?O&whÝ,ãIVI|eØy‹ ûýzÆ(4}íòð¯ØÍcaÛ§È éàŽ1.ŽøºO‘çnÀÝëYÕ¿hªÈ"4‰Þ5:ÁĶ›IêÕd²lý÷“IxeCÍâÞÆÓLþÎDv^Ë¡}«"“á6øÀ3F¤!ôÖ¯'øîˆàoPKý^6M°ÚxÂ}Ó lib/formula.hUT ­¦[;\À[ux ÷uͱ Â@ Æñ=Oqp‹ŠoàÔEªB¡s¨^ÂÎ\¹héã[hAQÜÂïÿA¼°b×ÔÕù€ûKsjë à'¥¸æœ\A1ä\îÏÔ‰Å•ÑØoܸu¢g·ÜS˜ïm½˜{AÆmYóÞžþ8éðáËsÆØÙWð¤A^PK$_6MaìÕS lib/lang.cUT ó¦[Z\À[ux ÷ÍUQkÛ0~÷¯¸¸£ÄÅ {J¬oËBiV(Œ![I ŠìI2Khóßw’œÄrâ’AK–ÇöîûôÝ}ÖU.R^e BÉ©X¼_†A0+ ’䊤”ó¾bëòÖ1¤…PÒ%•7 èŠEðäsèK¢7%+æýu½Œo'_§w. ™®¤€9åŠ ñÍÞùASF#˜<ŒÇðüìàÕf5+8VEÆŒÄú±ƒ¶u‚m›,¡bs’°c¬bÈ…ñšÌL-ú ¶+Œƒ«ŒÍsÁàžL>O“drû=™’ | ¥©ÎÓ&ó@UÍÓÄ–úÙ^õ Fðá»0†ð“¹ î:a;l TJÄ]³ì­ÚàÅU]2š!-OŠa]´ç7ˤÆàï1>’&zÔ”=0ß‘KÕäÉ}kðÖÀF–S“Õnà–ª³]Åc`]Ã×!-+Œl;ïšMx­á¼˜þ”ÊESðlê¨m«fMèpÞzþñ¤]ÑÍŒ]@`·ì<Ë· ¹ñ‡¦cLÖÝ·ïKš¾ìcuA_×3e>DgøVù®åG®µVíp*·NUçùôŸ?voþ‘h5´ó3M­qº~gx½“Cdæ sÍéûÿY]•,Í)'EéM¼ãé :±íÇ®¯ë¨_ !}ã:Øz(þI4f¡Yª}Äúˆvï~W˜y¹Ù±‘oo‡C$ò³$™QňPdÁt?´±ÁÛê~K’;Ãý±,Mð©âIúšÀ…f¿PK$_6M—)h  lib/lang.hUT ó¦[;\À[ux ÷RÏOÂ0¾÷¯xa—I¸†&%ÀAOMi;iRÚ¥í"Äø¿Ûv 8˜\¶î½ï}?ÞšˆB1^ÀìéîùÇÇJ|E(Þ.¢D(*+Æa 4ã׫BÈ:â¡dÀ[¾)‡`°â˜)Óº@‰Év=ÊÌ|"Ã]eÌ ,©V6˜Ð½A_¬ËJHyq0p‚¼þÔ•ƒ[xÌóiºŽs?R^ `ž/ðâmš¿LR?AH;ÆÞd–çé(w~=$<ëpgnÅ kå=N YØY%e¯ð£÷>91:u½$ÂHa]'{éŽ;tçñEÆiM ¢´ÔZzœ°Íenü_óWÅ]3EÖÜ£ÛPLÔöOx·™Ïç@ù¹Æ`iüußpö±ÖL—*Ëþ2¬ÉvÉ/æiÅNIèéöL –ÎE2rfKN‘X—-g´¿_þeü´ãÔ5û(኉}PK$_6M0+À³a lib/node.cUT ó¦[Z\À[ux ÷TÁnÛ0 ½û+¸ìâÞº][ä˜ÅŠbè°³£Úr-T“ Y^S ù÷‘¢d;I³ ðÁ¢(ò=ò‘ï•©õØHX9-ÌÓÇn•eÙ ÷}®2ò¥òâéI6•±Ìkku'\h/ká¦ßÆ­áwñH¯`_·Ûo9‡ã8ô€\×7èꂱêí³¤l9J´¯?s<³Ó—‡í6ÿÌþÒ΄Ø7Ù!Ë®®à{'´¶/PÛþl ‚3{'åL†’¥ªµ52gûžáª í¥ms´½Û«^(§ÕàÙЊGë|¾º5^:#4H笻†í¾—µ—ÍœZë`X@[ü`?—¥{­jáe¾/ñÝ(‰ñTB'±äØÓË—Ni‰@ÉšQëŒÝ;)Ø$ºXèàòž°$Ï5l.=nLŠT¾QÉ)¦8p‘tBÑ,PöçÝÜs+‹"ƒ>Àm »A¯ŒÔ;P–r4 (¾Ãº*‡ñ)ö5ìzáб²£Ž;®ÊîBc=Ǻ†Gë»”þ—У)–ñ(žÿ5]cÿ:<â§Õ3ƃ­“R£•5ùqôÀ€ó¤t „WWÇ¢¥®p©«“ê|®4w M<0³XÎ#[!Içfº¨G‡V)Ô ú˜ªwÖ£¢Ñþ)è1ª/(4j„žn&³|B“§0QÅ Có!Ýö,'œð¾¹ÿqwGYS¶£–žB:žÿ4Wfhi NuÃý4뜖¦Ž¹¤‹­·˜Iò*—ãA†øîtâUIyx)0ÁÔÇsŽ´Sª{~tN5îc¼\@êA¾=ðˆŠÓ”0“Šä'M‘&¶KFÓ¼_Xš4Ï—4¾¦eyÈÞ˜„V™&Tæ| ¨LMÔjà{¶)y N-£Ÿ°§×‘b¬à‚hx>3=Ì!ûPK$_6M°Ô¹Ž&v lib/node.hUT ó¦[;\À[ux ÷¥VMoã ½ûW°ÊÅYù÷åÕnwÕ*‰ïª=!H‹áÈŠ¥jÿûb°)¸Æqº·0ü÷†yàÌè‘crÉãzs7Û(†?¼™ˆPNì ç%*éPΚdAêÓwCža(÷U žƒw€œ”UÎÁí:ñëùÒû;ZŒÅÑ”b䤞Ä\äëIìØÅMëÜÙúöQf—Ÿß(#ÀW'¾­@7”ýF¬"s‘ +}®š­nxƈNÙkÆA›æä,¢Šz§rÚAí\ÄǃøØÀ4>þ>r4Ðë@y6йëy†±h¢ÿ;©áN0²ÏÊì‰gÒH”Ÿœswðë ÿÓõýeûKB'Q„˜%L Ë1M/YÆ*-à ќѢVõ¼‹·wÍÍZ­ÀãÏ}ºÚI4—Jr–J[01êN¢>Â99ÂCÆ _nQ‡Øˆ4pD¯+¸fk o(—ÍjPyI4Õî$J*ÆÆÆa"† CZ¨ðÕ:«Jñ=ÄñÎ7˜BM%M¤6y'b2w—ı¿0½&2#n{©(׆±K¶i|›úÝÔëÖÕ¦ö‰ðkÓ•„×Jë¯?«ƒiC±qǧâ`YŸõɢɴ7Zã÷͵ÂÖ+²¶wS䣒ñv±Œ}‹—öŽEí€/õG´Éu "œ°vý€Ê‚€â?6Þ#M¾@☎éÑûPK!”8M±EXëV3 lib/parse.cUT ½©[Z\À[ux ÷µZ[Sã6~ϯiaÃ6YˆÙm·Î†6³d6$Ô^†I]ã(ÄScglÈ,ìo¯.–#Érpn<–?}ç¦#ë;×w¼é‚rèÙþÝ»q¹ôúdZð)>¸´Ã¾—J¥(¶c×;ömÆÖ߬Dðiò8ÁVÑo?Š3¶Ã·àq<Û_K¸#P ­ „ÿYÁ$v¿BåYÖ oƒZ0 ƒ0*ïƒ&-êyt&@W˜Þš„®W°Œý)á;D‰J¹íÇ0ômìFå*Þ(½ ­‰va¢+¯_‡T … K 4ÁøDÚ:ã°‚ˆ!ˆúÈþi"ò§‘Î ¦1›fZøtâ€L·ª V¯‚=:§Êl#6`¯ÐqlõeËìVï ³[p0!*cn׿#Ûõà°œ:‚º×ƒþ]<® mˆë ˆŒ§ Ò¢(LèA€ a¡Ð0Zô‹†˜Ý(¶î`Œ¹«àzäÌ4ŒŠFÀ!Œ§¡áØá‚¿-ø`{²Ó«‰ã ÿÀûŸ‰#S’(¤jïïW ¾ÁD×¢KT‚O1xÝ@¡ï@rq7¦Õ»´.Z X¬èöºÆÌÐ=ðn<Âý Àa€wv¾$WSßgèjd{ÄCè¹÷.vp2^ª)ÿÙu÷äªÝëÔüþ:Ï]¯óÿ~môóùë‚þµúòú3~ëºÛ2ÿ,Á_Lÿ?ÏÛ>"¿¶¬þD¨àÿžÉ‡wãü¦qi´®[ãoŸ êKüG‡ùë§«ßoîÖjþ÷ËògâKùµ­ñŸô:hq¿_·:ƒíé? òX›ÿªÝ9Í_ÿ?®¿„Ÿ%ïRüÅò·gÖä×Okëß3µ­ò·º§‚"ÿÇMðkÛäÿ­Õý\Ï]??¯_Ì´EþÏ&Ú> S½?Ô×~þ&üioš¿côû¹ñÝ?·½mœŸ£Þ ·w%ÈØ4ÿeçzÿׯ.Ú]AÀ¦ù¯ÚF>ÿÒõC†ßl¡êm‹ü½Óë'@ä?Z›¿iœ´¹ºi~R?Ôóô¿‘ýYËõÿ‡µ÷O¼þ¹ÇûÆùÉúÏ«6ÀÎÏþ×®¯N{NËÌ‹ïêQýó“õ©åéÿqíý“ðmÿ²eÝ«s£Ÿìr"ÿÏ ø•ë'óþò›Ù:ùb\õëÊçË¢ú¤`þ&üÚùù€À¯-ý|LüSzi”JПޓ6 í8Ñ¿c×§¬“g³öí,ų F:LtxÄšÃÒ>LÚ@I{H”q m¬KhùÁO )YCq¼ˆhv¼.„ï/ùö=$¢Ð\˱¢8¤¬D–úè6FÿT0˜Ü¹ ¸‘Å\É4UA“5&I÷+ztcg ÁÍá€jèØ(’oßèD[ÚÞ û AUA9ÛƒeBuÈl­"½¹ñ ^ uÄð&wSq£\q£ \(ì¬g ¢ S߉IOpMÒÏZNí0WíN /I[,Ë tsº£…ÂÚgÅ¥’~á$‘ÕÆ5cé([hóQQ¤Øbk$Iõ”¼œÎŸÙºFz3å ®+<ƒßDsŒÆ0BrÔs+©¬Ú] IN Ô”@󷆑=õb]¶ŠÙNxŽtÎí‰>8 È`°·G6‹ŽÔÞä…#éXåÆ!G¦à«Î?^ÅùÉk¬Êÿ²­Í\Ë„wá­Ù×\Å>¾Í¶ž‘Û5N_Å8úޱBîÈiÁ5;ÅüÑU@m3¹£grGÏu>­&Wõþ¿[{—å¡…¶X‚_q}^e•ôLå‘Ãñœëüž¹½Mko¥¤îž2i//îžnϦUl"ýÖRyGÊPÒXüL[g›ÉãLïäút}·æøÖNæy×£P.cøŠ©\[[W®ƒRHY‚_QÛ· µ·· £¿d©{P˜t—dß-šŽÅâ½e7wÓÎåš‹<‡ýQ¯ MÚ™ËJåÜôOá œ/ûÒô}ajÚU[Žý×ÂìËê])ÌÌu£–\7+=,XsªÈJ½ÉßYjk;òפýªÂÎטZÐDÝÙIôÐÎ9ÏcG´©ãúw¹L’ãDIDØ5±(åÖÁü'‘[.7iÃèYmàˆØ³žÉ3¦XÜ}‘´k¡gIÃC·ÏÖìŽdùIûE—å³Þg}þKŽ>¦ô9Ž<Ù$pò¯ËÊ~ª)Z˜ƒ¤ÕŽÎ!›Ž{ÒyF]’ê]Óo*³šÇ© Gº2øÏœ¦ÆÉ@\ «è^§)q2T§ ³w¸#nGF&=ƒL Õ¸46)NŽ ní¨lù¤Àq‘žãdB#›20­§uÉhˆËE•Š?H8R©)$Ë«›ÔZ Ü[yËÀU“w Ë%•KvkÙÝ•€Iµ‘ ^4Žk{ªäªgiuÅâÑ”‹GáG.·æ~T%W& ™XSÏù•ÿ#áh’5é{9ÁDº÷«ÊEšÂE²h#D”‘\I"Ø]‘½Îj iõÞäà4§òË’¿Êiý%úšľö!;Yü¯ôpþ<ØÞr§‹@=NñÉÜ{7ŠíÿP•á‰ÌG;ôñQçÀŸONJœŒ.|€!RÍvÆô 4"#_oPq0¶ùó½–{?ñ2EÂ>G,Mìúq•|ŠÜ!œûzÇ©Éàù9ArƒóSê9gѳ~ÀÇœƒ¸ ¦þ0q?á2+-T¤Ï^ø;Nt)4EêCÑO–ëòÅK:ý4häO›åN£j ÈW2bAÎ?I¾bÕl1œ|âLmš¢ˆ}´bdû>šH#— 1K3‘*™Ün2$“K>¡5! Ê‹÷µO¶Ò‘‹r`è"·à Ç›|²uíØ}pã ;+ÊÛ`z›d]»ù ;™È´?fʧå3I ;15Šg5™³W§šÌRè$d"ÖGD#Ô:ÂÉt&¾Vç凅ä‡ëÉyùTüÿPK$_6M eðµl lib/parse.hUT ó¦[;\À[ux ÷Vmo£Fþί)ªdGŽsN¿œU-‰¹Ä*Øj«ªÂkŸQñ.Z–ħÓý÷ÎæÍvrê7žgggž™å"Þð7àÙ¦óÌMÏ·‚'エ˜c52ܧ— ƒ”É ¡à™‚pËä%dJïºë¾°¤o4‚Òù Ù××°ØÆž|…˜‡I!¡%SBf ¶L UÎ2`iŠL’ñ¦¿kÖžíÒDoÛ@'ÈUË“+L2\ã¬b¾Èó©æ…„ŽÁ\g"É ’aË2àvÈ8Ê¡A“@{˜P°!#ÔÂaê‘·¦öPmqY–‰ð®&o Á ÍÄ…§|Ð4üªÃÆ2þ²íX—sÎä×[XmX1sÈÁ:Öd%ƒÒQZF˜Ä»XaDÖ”Ãʘ7fÄÿÒð¬èD°ú¶ÒÛ®3ùÖ#,¹ú¨2{wDT¸©ñZˆ …5ªUÜ•e³W(9”õp&”ÆY‹øûPxÿÜÕUQì¡l·ÌC*Š© 9Ý9ä–Ñ•µ¼‹”d!è^å¯Uyx$RÏwN'jŠªz['¨gãs‡ŠEL1½÷§¾Üñ¡æöôô`Ñå3óJű9½‰N`ë™A<Æqó8+ë.ËÓTdýà ˛¦×P?Jç¢Ñ“FÇ;Oðª¼ËM’¥)–µPÜà©T÷[v?‚>UŠ¢N®œÈmöŽÈê}WɹJÞtEuNwRRýRyÖéëû-ÙþðcQy(B¢Ê©šOeèhã!Y9#=ßO ÒG=/ª8â²N'êH™ý/qòMqòq§ âH…|_œa\ ÍõñPKý^6MúÚÇN¹ lib/quo.cUT ­¦[Z\À[ux ÷SÎÌKÎ)MIUP*ÊIÌK×ËPââ*N­(ÐRÐÐ*Š/,ÍOO-‰ ij@ÄbšÖhjŠ1Õè(@˜`atõ`3óʉ¢n"PÔš PKý^6MÝ]Dgô lib/quo.hUT ­¦[;\À[ux ÷SÎLËKIMSòqôs õ÷àR d楢ˆqq¥V”¤å)§Vh)hhÅ–æÇ§§–ÄŠ45 â@1MkìJ‹1•ê@•€…qhÛWF¬(*áæE­^PNÍKÉLãPKý^6MÇÛÅr lib/replace-na.cUT ­¦[Z\À[ux ÷½TQoÚ0~ϯ8ч%-ªØÇx@ÌChE¤ª²Lâ4Y];2ÎÈ4ñßëÄI“ЮcíHÜw÷ù»³ï»ˆ¹ÏÒ€BO2ÂﯣžemQ±[š%— iˆO1'Ø6‘¬ß†)W}ˆ¹](•3Ô ÏqMðF½¿,(88Œ@bFù½ŠìL“™p¬ÃÍ °ÝÅÊl‰ÕÏ„ŠPç˜bŸl)¸Sw¹^|,Eá%)u­{3MÆnÉ öPÓ~>„««Ø)ktU¶.ºï`4‚ù—µuÀFRò0,ÿî­úû ì­JÓl¾z]“Ðy4•µ]5yhÜT Ò £•®Q4—_Y §8›9ìt‡–ÒÞ4¬ÛÁÝYœ¤ÂëÏm+‡ÝTøÉݼâA»9Þ Ôê¨À»´ó;÷êÜFÛÊÌo*m¸WëÝŽsÛ£Ío‰Vø ¹_ qþ‰-¤´ú®ò^\Òi^Úåžþ›±~ñ²ß±Ú÷ÖPK!”8M ]í¡W% lib/rlang.cUT ½©[Z\À[ux ÷ÅVÁnÛ0 ½ç+¸ìb§YÓ]›µ@ÙP k‡¦‡aà*6m U$O’Ó¦Cÿ}”ì­vâØzèÅ0ô¨ÇGQ¤øV¨DV)Â#¹Ê‹ÓÁ`0™ÀLJ}gAj•ç§a‰ TŠ÷˜Âp¤ºZJ´ì†q[ÿFï˨~ ,Y'D†¹M‰:‹TìBný6¿Ìj¶ã°@dÞ^¢Ê]AöðæÞÇ k’#ÔšK‘NÃÚcøÖ +'Ä›.%ËÑEj Gñô/¯‡OáŠ-gßæìóìë1…°ÔÆEÃuÂG­Ar“#pPÕj‰f·t•Q^jˆ;†Ljm¼‡`ö¸¤Ps4/‹rÇ©ñ¼ÝHƒçfï1ý¦˜ñJºãA'Êù}Ié¥|r° §@¡Ú4‡9lèˆp­E| ÇÂ…aÊ2TëˆLÚ˜KÃ͆%*Ý=³Ë"E¥Õ^Øñäv/¸Yíƒè³¤0Ô·“ޝàSæL…ÓíÅŒK‹ÞÖq'¨Ñ»÷ú§ýÐæ9ì¡}]t½F«Êº‘/,:}IyXb¦ ÂŠß ª=®6Õç „¬R‰£Ã±ž¡4z-RÚ$T›Hû¢êKÕ{ZÄu˜þ©ñLëOæÛ©Þáiò¼³¾Ï¾•á]ìOzwv¡›¼Pì ïXݬšFäÎߘjªæ[qsËJƒ‰Ð•:m‹z¹Q­æ’¥h0Û‚IÂû®°p^¨,p<'íÉ _[“Š£ ®}ƒ´’‹ ©MDC’yèSVp[øqv¾˜,Pùvº¤62:†Ðí)àóx8&xÆÞXÚ.㎈Í+¨ØôÈxx OB ûYiß½5 CLÍëâú/ö¾D¼eTÔ8µåhÊ’<Ö?ŽaãÛ¯Ùý¼cø7zÛC\†ã{™jµÞÝËú_škrbŸŒ äø0wD KRƒ)ª¿ÿ€Ñ„Œ®ÎgŸØl±˜_]G‘Ï®öÕ5Ža d©$.е ¨êNhȸü&Œàžz;Dô‚€º¸¼˜ÃµZúð×z "îÌ[RÅÃRßÑ;M>ŽzÆ—3zÆâÐMãÆÍ6C˜n”vô¤H¹ßiÍ Óö€ãŸýßPK!”8MÒƒÐK lib/rlang.hUT ½©[Z\À[ux ÷mTkoÚ0ýž_áµÒú`ƒvݪn“P—­h-EmhÓ9‰VMm‡Â¦ý÷]‡nBùæßãû>ä™LYFÂÛÞàK´ù¾ñâ’5PÏ;ä2yÊÈ{.­]/˜iÏ>"ÔØ4VJ8p§ î£0¸ë ÑÅì™–T˜ÍÝŠ8h·_%Jf|Úžxž{Âyg¬ÎKFÁd×İÕâjK†ñÚ2¢#÷Y„'j¾lTyr쎎V‚ÉÈm ÿîǣQÿgÝõ&pžÜƒhìþx^yL¨Ù}çË‘-Pf2Ÿå =R#™ AÊÏòúdǘõ–'ä¯Z­º`ô£?¾‰úƒOÁÄÝæ­ê…ñ’·êv}Õ«…Ø‚pìâJ¹Ëxà/O[n#¨Ìwø«CNI÷èºõÛù†vËG±ævµV‡í ”Åù´%2­0ú{ÀiÌáaÙ0eK*Èj¡´­c™lüWzž ZmŠKh÷:² Ú4 Ç\Õ³ ø˜S3k`–&{mèÃR­K–ì§ÉLïƒb*žaú‹*¹ C÷rÉ-¬„XS½ö[Eÿ2HtæýPK\|;Mð'õûE´ lib/session.cUT €Ü¬[Z\À[ux ÷mQ=oÂ0Ýó+®éâ ¨RWPÇt)B*óÉ8±0vzNhPůMh›u~÷¾îQ[eÚ’ e#íö©J“ÄSWO€Òà—n*ìD?QÒ˜úw—Í’€ld£ÕïH{Ô6LŒ¡#^`±šÏpíœÆ¿¡\x‚ª$O Þm3øN``@ᯅފâ]0ªŠE$É‚-€³œk›°>a4[ƒ%1mÄe9šx]…x>o05-Û¸3KNã`•ô¨œq-ßuý} ½ñ0Š›*–GgÓ¬‡\$7ÒxŠNÉÕÇ?׌±1r‘áµô„d1ut}pºŒ5[Ý Ñk–|DOÞkggwnÄXKö$R¦ÏV3-äž|-‰.‡0¡Æìc¹*²´o ÷’wX3)íZ{—¾ßÛÞ.R}Óé ÍݧqœƒþPKÜSLM¦¸ž~_v lib/session.hUT ¿[À[;\À[ux ÷SÎLËKIMSòqôsv öô÷‹÷àR fæ¥bˆsq%åçç(ÅgÇgæ—$æä¤¦h$ç™ É‰EZ ÙéšÖ0U‰ÅñÉù9ù¥E@A..åÔ¼”Ì4.PK!”8M#eP£Ån lib/sexp.cUT ½©[Z\À[ux ÷…M‚0…÷œb¬‰¡†xÃŒºp×Ô:H(d¦ÐxwË7ºìëûÚï-­3EsAThwÝä"ŠÎUU)ËÊé/1c[¯¡•ðˆÆƒ+Òй¡J·r…k›ALÊw5VYZ)ŽûÃi7ò„¾!™.·!y~8““Ê5÷`BÈŸÈzjBöœµ?()íßæIˆ™íÁþñ~xüøkJšNAÕ¤G‚Õj(.fy…eí;Åž¬»öÃ+{ÇPK!”8M¤zŸŒ lib/sexp.hUT ½©[;\À[ux ÷•ßOÛ0ÇßóWœÄÃZT‰Á 4Ȇ6úCm7Á“•&×âáÚ‘í””Áÿ¾Ë/š¤I·—¦òù>÷½³}wÄ—2Ä%LïÝÑ76ó&ìÎ9¢.±¾è8Æú–À¥HšÃ_Ó¯@¹²O=ƒIt Iþ8m¬%L—,)ÌIÿÒyoBPÆk"Øm„ÅG-[Aólj7þZBJš­}ýÌ"W±)›h4¨78^üÆÀV6Ʋ¹uŠ}SîlÛ(–xóäk 벆îôçløsî^ß{…²:d¡” 7­ˆ"³¡ûxí±Ù;õnÛ‹TÕ¢2µuÐÌ›³ñõwïfÞKpÚ"¤ 5ø7ãóÁdÚü‹dJD[%@>¡æÖ”þ”4*Ñ1XÕ¼@´55· s•ˆÓ”+æëU¯ŽaÃÜäêÕ¡Ô @kn \]í:I2âfÄÅ/_Äx ›0Ž|‹»Re|ºLB¨—œÊ—Ы-TKW*¤ôdÞ…Á½í{Ûö*UJ T´ízðuJ'A(‰]ˆvÝÝÇîoøÿ媾ȤߨZµìD(»ª–”uê©gÌúÚNTµç¥?»X6¹A¾~éTÃt2‹`¬nD©=ªŽ(i¥­>˳={!1«Ð< ó RJújÚ3+x7Ôáz15œ‘ÃGÄÈl× E‡ÑvOòS(g™èY¥ójö0··6ëìqHÆî›¡Áe£·‘èIºš½×ýÍ0¢$ƒ/vG‘ÿÙæ°“8=§BjT‘’¡«`AsèâbçÚÿd€&— krŸ[/1Æd'AsŽ4lH?jÃiáKµájÅ+‚HÊ–æÃyž€s„2äKç/PK!”8Mo_cŸŽ lib/squash.cUT ½©[Z\À[ux ÷íYKsÛ6¾ëWÀÊŒ‡JäÄÎѧãq•4Sã‘Ý67†¢ ª (+môß»X¼IÊÏÌôÒ¢ÝÅ>¾ý€¼`¿NŒ¿* V4êWfpp€ µãÐJÍ!Ùß'‘ÃÍb«“èÀÄ0]tŠ`Rh«†:Ø:ȱÀ¡Ž9 GÆÊ-¡P hˆ1ØkÓv¯Ê¯4ÍK*ršò$­µíYí±ôÁ|z‘6”|Y9ÇèøYv]”S°|@NNLU¤ù"Y.C[ö¢¡Z²3„4ŒµÛNPÊŽTØDh¨&9 v ¼À˜žý‚þêÄ'«]†KÞOÆãD‡ÓÀnpxu•ö<´êÀ+U¾6;Ð)B ‡AÕÿèdÑéÇBѳp& ó3ÆŠVµ[ãÉ. ÑÅh¢Ø.¢{áÁàlsÝ[¾ï­mõåÖ·‹öè‘åúž ¨×UVUO+Õ°Z×%›Yò ¨9¦Ö®™Ìqp!ÏŠ|Á뢒þ'ÌMÍ™ ¤TE+Ê[„JΚë T°/Ø@ã«ZVªP¶± õj–Iª!ƒÆËÔp•Â|ï©eï ‹SYŒßž¾ÝØmo˜ØE¢OÐ_ªë}»ó$˜¯9É0DŽAD®=[hžé'hDÇÝÂZÂ3J_4=ðߪ]P£=_[ï\q…p¨ˆîyæONº‹ÑIG1¶oíÃŽœ–¼\}óév|ÿNÂ=Š–[îÅò°­ÛSú…>½¸»Îqg>aZF è(Äž¢Ê`M`j¯ËÇwääά´,Ai÷žò»ÏdQhÛ jÏýɼ³-?ª%7h‹ÿ}R­xR>©Á¶Q»ºaPtç;ð3x}Ãbå¾w匎Ýî»*NÏJ òQ9ÑÂ%OU¹&jèè6Õ„u­·ÿl0Š÷$ûú Úº.êxº„÷TŽÓ[|YŠàÂ…Ïš×u_xÂËN[P![BUè댥'x‹1s“ðh¿˜§²w:¡AÛvÝ7*«›øÀ>G{.±Òò9´Ç>^uå]*mæAˆu®¥nÁ,ÍÑódÓqmØà•ÁLù4îþ=ik© J/§B¨awc¹ï2nÖóLVÉXp騶ÍýQ–>@·-û†3ÉÊ 2*Y¡Ð¦ê–É|Ù¥'ò ²J—ô±ƒNà¡‘sn¥öšÔÐÝ µ8 z'*]ɰƒCßDCÿÀR”1þ|}y= n€’fæºkxV\Jq:›‰÷%yÞïÿž š}EÁ³:EǽG«Øh<‚œÎêB‡âMU¹{ë/dYÃn®É‹²ªd^ó\²’çÙ /~;?X´q/ÙwØ‚²ý-ÝrøhÖ5çæ|§Ny•ÞP8Ÿ¯áJÑâ»ôÚ-ÕÁÎ]Ú'ú1ænT:uŸÊxw?¬Ý%â­Múv£òuÁ/ëÂä?¥‹lÍÊZ(ȹ)ÊiVu&˜Òö:nê°)0Å9Ð.BjY«Ô´ñh/–ÕzfùhÒˆP! 9o¬0/-pµÆÛ÷ÙéÏ“$–6$›v£)]CZ6WNÒxæ1_‡ †T©:>͸64Æÿ yr 2·o´J¤–yÌ“µ)Ó㨳Vµ5@ÔóçbðóãÅuø9ŸFÓg—çŸÃï+PzùéágˆÖÆ}¸“N5ÐË%À•‰5ì#¼2·\tI!-ô ƒ\À„rRßR!8õFá®æÚÕX­ÆÝqJîò¹ék;.'0µNÕ<¤VœSJw«RÝAS–¼M´\õ ø­{WÑ¿ƒAWòúdÑ&k3÷;Ë-"«-Sœå£uµhWÛu‘Ëô¿•Çbg™5JªýÕt.˜'¯¤x«†’³_N'Ið‚¦E o¶¾×»²Jà ° £AßàÝ(úÖ¾lÒ elÈ8,×ÖÂ)¶ßÊòaWŠAS WQ »‹µÁš‰3WÔE½fÇùõ{YZþmfkÊýU§µÃ‹‚ ƒù,ÁPÓ0䛳8Qâx2&༔¸½´KIg=©Ëc$˜˜¯k=% o^Š  µx ‡×­ß•±7á”D â#°ÓÓ¶¸íÚÉî)®#ßx\Ö zÀíþ(=kuçÙÑõÔ±ßCÃSþ¾cÈáúkwñÿ…ô´K¯*ãZᓃx 47b4b:a :×Y vö(¹Ó\_˜5³z¢±+é4p©ß|55îc?ÿ^Ãsæ %§RÔ®©/ØìÊ­Ô BóUgöÍórâ&§»{Hõì;¨Œl€úú¯Ì<ÍíD^Mj_øâ³97•Ü_:bs²ñQºíš¾ó[µ§ ¦sÒw}ò^¼@⾎hàà+õPKý^6M(Ký¤  lib/stack.hUT ­¦[;\À[ux ÷mÁ Â0 †ïyŠÀ.›ø;TSÏ¥v)·n¤lˆïnuex Éÿý "£mI‹]¶_‰Ã1Ë·b QŒ¥™ pkL‰,+¨7>vÔ· …—8öšeMI 0Ž,TÇLÖ‹7ˆù7¸I4Ö£øµ)YUÿ]à¼ôF¡±Õ+ÙDX æ®õq‚w@,D~!u=9âÍ¥ðEdK£á PKý^6MW°Ò­}™ lib/state.hUT ­¦[;\À[ux ÷]1 Â0F÷û]ÒnÎN¤¢P»‡^ð0^Br‚ þwcGÇï}^ÇAV 8ŸÆód¯Ë¸ìº†XèTuÊYâï­ôÊ›‰î6eå$Æ'©ŠþæÊ€âÔã é³ÎÁN¤—ÍÜ™¶¸É.F³™ý>­Ñ‘¬à PK!”8Môá ñ<hlib/sym-unescape.cUT ½©[Z\À[ux ÷­VmO#7þž_1ÇI°Iö i¥m ¡pw*E(µÒ YŽã$‹7²½@Tñß;~ÙÍîf“z|Öž×gfžñG!Y’M9ì©„Êùáb¯õ1?:þb޾(º\¦‡r.$?\œ•$´QÂjUϦ‰˜Ø³ÖÑ|“†«ef™dF¤Rç÷þ´ZO©˜K—+ÂTQ†Æ#Í_–0sƒÿW+ȼ$\ø»=hŸ™äšÑ%_ Bkòß 4Óò,¢W“4 jl¡Úðw rU‡ œÂíxôíú ^#‰¡‡V7™’ ¬h4#FQ©jøFyå6J¾6y$&ÝH¿æ^ÒGŽÎoÐ÷øúü¡õ]sl¡ºdÇeRs%h"4ÇÿK§<²Æ‚ÙD²K¹ æi¿çfQ„³ïw”F™%I %Å "Ô:uÎóÂ{,RŽ¢Ù߇Ãk€?“'ÎLª"¬Éí_7±Ót¶j…zÁ•p×»«‰^Ž†Ã¨_šÃOXã1 v´¡F°k%FÛ!ö8²ØÒKŒ(ˆOÒ4–>”—x½ˆa<¼‚/OP²65Ñ"³4“Óm¢K•2®5™¬ σœ;$¸ ÅM wlHÐàÓ†LlËE+I ~MVh²à/%¡Ø{iÅ5ù,U؈ҷpo€Nìåº]á%n‡cR"gTÄenðÉún|µíòC«i  3èñW©Z•…!ú‡ÍFÙvÃä2lNÌ»M“)ቩ²]ÈhP’³#èå¶“M°ôì‡Ør—þ0wùá4·Zp€ðª¯ÀÍ ¥-%È•ƒŽC=»¢Lz[C.Ý[Úv.-¨Œ{<çÜXZ¿F…Œ'J¯¢ìÅ×óQY&°Ü‡†iµÅË)s:*ò$ÊjJæãQ|(™¯ã1\ ÉÝøòØójp™‹Ÿº) ~ÁÆ ž¯¶gªA¦ÆŽàS˜pF3Äû™(Žé´ú钔фæ®9 ›ÃâìfBaˆèѬ c¶@å*¨û|µ×·¨¦J̉oeTÀB°¡„n¬‘ð¾r]èßû»GþÈplð6€ÄP &žÍŒê¹´Ö^UdlŽ&4:a4h:ã6u “Éf3®Š McRžÛ>¾·äZõ-+¡hTf•ãs³Á7¶Íãƒíâ+.±‘„¨VtOx¼mŸž"áuŠß5^ÇË5„˜ŒÊøznyÉ­ÿêÏ(–©Ü®uVC¤çæáýú¶j^‹ªÝHSEþÃòm#3¹‹Im¬_ç!Mš)ÇMÁUèªæî½N·Áൠ$¼Ôz=*ÇH¯h ²í½Ÿ8DÃ~}»»}áCìž6‘†KtáÚ•3X§H¬7؉ßÿy“øÆÉ¹zÝešF’¸À­ ©LVŽï<ùk"|U#Äü|à–è,¿¶c Ó'*wF:¦ÒAÃ>ëN%¼êW8£_à€›KÌ%ЏՔGèYÔ¤YbcÅn œºwr×ÝCß×wWW1ôquÙðU~ÁŸ³=¿A0Ó?9À‡c°p"÷-©-váWCÊX†h$h Ñ Òþ2¿­+dßTm¤Œi ÏÌŽýÎ.,43Îö§`Q"üøÞ»·/‡ƒ“ƒv'Ö"}/r·Cä'/Òm©¼ ö§Ï•§“ë–ð"µÆÄ}{ÓÌkÉÛgïí¬Á[…k¨4?z 4ðÎÐlïö÷íœàׯk'9Ë–…Ï+—›ÂuòýPKg;MÑú õ°Ð lib/sym.cUT g·¬[Z\À[ux ÷½TMOã0¼çW¼ ÒöH)BHË„ ‡]!ÜÄi,¹ve;mʪûÛ÷9ެö´‡í¡­ç}ÍÌ‹sÀDÆ«œÂµ6Љù¨¼‰¢ÆŠ‹ÅQŸÃƒÉs˜ÂŠ*ͤÐðAôHMKªAHF¡91ŒA [QX—,+m.5¦™’™ÌíHx-™½YÌ$‡ ÛUeF* |M6ºï§G‘¦õr*tºŠÄAõ)0a†@•Àï@¯™ÉJHTj6K*‹¤¸@F4…—_/?Ÿ¯ð ¨©”€zÜ_§]¶§bnJl“ \º>öÓ°…¬$jÎ@˜À´H;ÊwÂú¬T霚Y^ 㶺¬¬’Ä•·±- U”#—‚pnJ%«y‰‘œ¤âæª%`Éu‚ígˆ'dpv¹3BTœûÞMã}¬SXî,K‰N³ÔÑ \ìz§d&•Iâ;"ޱ…¢vçÄoý/ñt¨ãÓ¦±—†ßÛm´¢™Ä,•2½³É][D·ŒŽ |›´‹ô´rÑ4Mí¸@kĆÙb™Üý¸&ÏÓ‡§×§ÛÇ{«ë´›…K¾hÊ÷ÑL‰Øì¥ê¹êæQñ¯œ£(ÜŠ½`¸•]Âc›YàEIì<–5þ\ƒÃÉ |yJZѶ•—©ßØ»“Ú??-¼€ô˶ì˜ehË’fŒðT.݃ì¬ùê¡ñï&ÆQþi:_\ãf†Í¸ïptÔmÎÛÅ»•~|x 6ó .}¬Ú½sriR*VLI± ÂX±ã.XT"3øN Q­ðV!fÏ©ƒ:l¦Ôáq?Ûâ•d¹Ý€`&ål¦ˆjgí^¾Íå¶9ñè¾Ä—¡†>Ó£>«×Ôç8Ìgt û„?q»'µ¬}QâµÇ7!¾ñøgˆZ|ýPKg;M5Õ²OY lib/sym.hUT g·¬[;\À[ux ÷}‘ANÃ0E÷>…¥nÒŠtD‘h„R@be¹Î¤XrÆ•í@âîØu’uçùÿÍ÷x¼%PÒü1ÍîÙþmǶdá‰0ÑÈ VãA×X0ÛV4g/±z媆TIk%;h«ÔGò ldá¼o«ƒV#B(n{bÎÿˆB»¸õÇÎ'Ð80H-4§U¤à‡4+@Ö—LY£pRã¬i0PÎZNª¢si}Î64³j;«~uÁ¤Ρþ‘I”š*Ñ­(³ô uÜIá%ö3ŒßV‰Ðhïܬ¨`ÖÿKúM(5àjg^2é®T2økòs%3Pݾš„=åÙs–îî’à„˜iÊxš˜%®¤m¶ižL#ãh­•ï—vº_ÜL®žsÙÀ8¶›µô=ö¼_Ša¹£æÉÓ§ón»€À`!Kò PKЭBMY±^Qkç lib/vec-chr.cUT ˳[Z\À[ux ÷½VßoÚ0~Ï_q£/² ^G[išØV­ª*ÚI“¦É5‰V'rœ¶låßÙŽóRÆ4m<@bßÝwßç»3'\„I18-”äbõf}L¨^xž'IQð r% B¥¤’0±Rkÿ!ãÑhd6†ðÓp¦Î`2ópåqÍþ¨±õÛ¬zúa«m%S¥€ øZ°§|„{$ášJ*&ý0…ýޏ6ïèýL«T‡µµY©Ðåó|~í[´ªLú7·‹›¯×ˆáÐ0‰3 ¾CᆠþœbºH‚;n“•$Ïî™àÎÌ€úö7þ}8¬IXÌçþÔ¼WüÑÏ(à°lȈ)Ì‹p±'ßfŽË´°BÚWD:!ÐçWg;|:áK‰vï?½[hq.®>’ùå­o²à–Aó ÓÜGó •ÒB¸¨5Wn½¶;%ðzªXfYR±_ÓâÏHóèÉÐÞ“Îú;Ÿ–ìÚãÜ”-fÒ…&Tl^€oð{êð¿¨n\›í$Ów"m›î™ÔR(Y²Yµ¸­~ÇãÚ¯ÿÌbš̶®¢Š‡ [hÂ#ª˜‘²`J7qKI×åí#Ô K¢69Ëb£œÖÇ.4“ é7ºÌ¤òwhyi‰º-P¨-Áöó j¹ø tÒN¦àl[0X61M`QÍ´õjž$—,g":Ž9/ˆ(“ÄP¯“°s‚ÙLDÙ.å-0<„ʧOzÝuÑGˆ$ú öè c˜Vµ(õ¦€DØ8 ,㉞¥¦ávf䤓ҡ™Ø(Jó‚þ¥šu¥VÐæúO¥›üN:ÑÉå廤¾MS}12•yÂC¤æ$ÄÌÔ‹e–’„ª§Ñê¸n¼p]Á¤Ìä[˜?åÈ›E= Y ‚¦¬0Ã1\³ð \†<MëÚ\q«p¢.â6â!àdí™È:† ‹çg#ü×`-V ^’Å‘Á5"ÕVöbÑVZ”#þ!øåpôsÌI§uÕ¥¹ÚèÃ…çgèn¥AĪ©uýµXTø3§÷«C;˜ò¨ë£ÀÃaQ1ÔÕ—ËËYmÐ$åv<3ç±ÑW$áKIåÆ2ºûõ¸×HèU]§TÞë9ò¬,ü}w–íì)¬˜ê±Ç¦jn¿PKЭBMŒ‘{·˜ lib/vec-chr.hUT ˳[;\À[ux ÷•UÁnÛ0 ½û+Ô(ì!ºsÖEP,‚ p²]Õ¦¡²lHÊ–lí¿’åXvœ6»Y"ùH>òÉ^È ’.ïW_éχùæ{Jç‹”.¢ Þs c¦hÂe&v9ÏÚ(.Ÿ>n¿DÑ1BÑ’k×­$¥+¶v^Q{J ûúºé-SS(ks ÙV͆Qf¯ 3<#\ ›¤uÁ0ú&nÎxšZ`Íÿá ù¢Àìs½I¿a#ËMì¼x2‹^ ¿*ž{̺z†QЩO Â4øë‡ =Ÿ:»Í0H‘UR„dÊ1`ÍAAáSá¹Wô|qŸÆöò]$ÏÍh3’0c‚9ë9^\Š€Ç €'cy[æe©æñt’$Æ{rwgÝwB4ׄx@Od;drGV?–Ë™s±±WGSÒóJ Z>ϱñøú:iÜ}3ÁÂòŠ3ÐàSz‡®QW0w᯶ÉǪÞ¼e:}HtK/Æõ(“‡3A]”ư–£&2™¡U¸¿ '΢e~Skf*&îeër™œßÑájt<%œÝ¬ûBȵÏߎÝÓZA 2ùè—Ž7«ßuTì'Çu÷ÀŠi%xÒ n^ ÇcKxÌʺéfJp#í¾ßŽ5X˜07e¼`§wÛÜ×k P|ai¾«Ϙ<«+§PUIÓÆ±ÔñFwRƒâLp øÍ³*oŸÃKxí1ºï¯s¸V劚C Uïre_ {ìv›¼¼àùd¶ÞåSÒuÁPçÈ&¹¹i‡3ò>bU·ÉôX ÂÞ¾ëïŒÚÁ°Ìáhõ¡|¬Ä™7]YsŒB0ŠI-p,NbÖmä—4@î$﹪kíÞo¯°ý˜^ý”, NJ²†…z ›w;ø—¿Gûˆ¤lSÿÁj4A)ó"úPKЭBM8•ËŽ lib/vec-lgl.cUT ˳[Z\À[ux ÷mS]oÓ0}ϯ8-ÒH[غׅMhš&U€H¥^zÓZòìpí”Ôÿ¾ë|´…òÆõ½Ççã:¯´-M³"ŒÙ(»¾ÜŒ“äÑ9.”/â*õ´«§ØMð't…”‹ð\“«RÙåXÜ/¾|ûŒ‹ Á²ë°é ×ñ¬GÇ!ßíj*­ àKeøµ–Õx’Iç>Ø d5r¤q9ÁâÓýÇۅœ[˜BÃÓ]%û$‘–N©«ƒvV™SÉfmŽ¢åò\šmcÌAXwÚÛë–d<ý]9¦ë4î i_nè<¡Q[ë,½E1ðm¥„ïŒ9ZÚ*ÓDpôþ}þ#;Åö9>Þ}ÞcŽ›®rPÊ…÷ú7ÅѬMá›§ÿesh»;Š)ÅAùÙl –°AÌŽop·+©ŽcíØÊ”£’G(‡áÆñõr,"‰´ 7¦‹÷¤CpÒ3φ+Qn1ÑÆŠ˜ª#$Ò¤N·(y½ƒÍ0›é7ò#àÁÄÕ¾n´G©ìë·%®Œû/ßa)¬KHÕRIÞ+ÖæþIC a¡Ÿ2Ã1Á!lhðÚù€„Ë‚”,´Å²µ¼l1ÑÒ,ÇTÔéÆ)¥xŸ_PK¯BM™šqe¿x lib/vec-lgl.hUT _ͳ[;\À[ux ÷uOË Â0¼ç+ziýO"¢‡¢PÅëÛM]ˆ‰$)Å7±R*êm˜摱2 )¨ÊÅvÇÕò°«°\—¸YäÙÐ/Iˆ“µJ åžúë úb.Ø„·×ÀÖH=5èVG‹ðA®Nùƒä0Šù+¶/à.…Ψîk©¥+mËä©å1.`Áu4Yð'ÞŸ¥£æ«…äo8VŽæ”<ÊH{úcR2j/WšiÏ7þ ï.Ÿ×EF¦a%žPKý^6M„âæP¿Flib/vec-list.cUT ­¦[Z\À[ux ÷}Á‚0DïýŠ ^Š!FÎÄ#^¼ iê Pȶ(Æðï¶TÑ“ÇÙé¼™®´QÍpFH¨‘¦ÚÔ cÌâØ¯„Á»h´u<Æ Tg¬UKZƒ‘-¦ðdÑî;8”å‘Çè •ëÈ ÷èqe§iá4KÑwWä>—Á6ƒÑ;ÞÒà_ônZûIå–†ÐѶe¹ßî‹£jŠåþ8—“°Ž´©bõûÝþT–<ŸÅ¦ýhB7 .ØÄ^PK!”8MþÞ$üñÝlib/vec-list.hUT ½©[;\À[ux ÷mPMOƒ@½ï¯ÃÞ+cHmB4i‰× Âl;‘Î’Ý­¢¦ÿÝ……°Çyó¾f"RÜ ‚]ñø²‘oùSùº“Åv_Êgù1ÞÜ a]å¨âvàXì»Ù’uò€.À0¦¶–~(_`Ð Ãd˜eh”¬Åeáû©©™m;ý·}Ó)["öy)ÿû§#as_ƯÑ|òíS¨5[õ±2+àꄞ¿èô®uë¥dʹ‡¤ 6Ò}w¨UÜ'p—AGYà\Ÿ¡ªÖâÚ#—IÉð÷ ’3ç+g‚ükî8dðxœˆRâPK{eHMÊ®Si lib/vec.cUT ê4»[Z\À[ux ÷ÍY[S7~÷¯8iê%NBÉm€˜BÊÔ!‡´ÌtÒE^˶ÈZëJ2Ømøï=ZI»Úõ®!$aâš•ŽÎMß¹©ëŒGñl@aMÄ„×ëné儨ñ£ñž·"Õ€q¥×RÅ"è'I c"Ã(‚F*Œ)©qSÒùtæ-¡”ì_ <€ÿ‚ª™àÀá%lÂçϸmÌh·ï6®”©™ ‰J&,ªå&/™ŠÆMªÅ”&CdbÖ#")t»ïOßí¸Ï£ãÿ³×Ù/l¼ëžúßïOzòý?ígfC…Õ¨!v‘h@‡d«ýÄ’êÍ+´17QF$&¢diÁY¾'PÂ/AÉI¨A"~('¥Ÿt¾©Ï<“ãdÄÐo×Á̳Y£Ë|ºÃpÿþ } ↌3EK—ã$BÛGñnã:—[-0舊t?7`ªDÊ ?Ât˜2ÔÛÃD@Ó‰dH´¹‹ÿy‰°þÁ³å…܆ÐÜH¹µáx?Äkívzùþ²ƒõ晴ÿí J>Ïõ$³~LÚæ+×|п^ó{LZk‚o¢v”L¦1;½…[=·GÓoªÔÃ_ß~xÕíè|OŸm>y¶½ý|ëÅ“›O·Ÿ7–ÆdU£p½ãÛe•ÜQ@±ö~˱ó=þ®Ò+ $R3‡KÕáú”™ºÉ·÷ß¶·Ù¨ÏHN^Ub²6ÑX!½N©)§rºÂm/-•(d§(áŠñ™ý¾Ê¹i{•xÈ9/§;ËAv°½ £/"ÐæL*Ê# ÉÔ˜jd 3‰Táq¨@_˜l½@´&Üñ˜hŒ¨”x€(´ÿ¬2ðÁÔxBuçšp¸d5†ã‚ú…f&æùÓPÚq«Õ·&TÄqÑš·Ø«‘TŠãõÇx«t®[Ñ݇¹¿¾!\Ùeǯkr‰‚\ÞN¼¶ sü„nsKÓÅ ú[+‰Ïâ¸ÐXnî–(lS¸Ó¨îÒª› š£¼ì\ZÞ@ûËK1¾¼&•`|TP_çêÓß\FùÒž Ø  —CGTYãW~¡Ì÷¶—=‘¨Âá›=Dc‘ HY³`é¬ùÞ ½T>r3ƒ?p¦ïcB¹¶ZóÇüg¹•Á™ç‹g½‡Á9À?³žÖÀ _ä(7ÿXdÞÙ@Î:¿®OжhÄWïf>ËÒBegó3˜ÌW ¤\±,ä¡kî׳¶Ö¢Ü%½+õ^ÜRïÅ÷лvó¶ÒØÄì/.}²E°²ªšrêì2·nÊhŽ¢¹Aåò¼pnøœk>¾|Íó¼84˜ŽÅY¨ëPË“€8; #ƒ>ã!Îý6Ò5Ëv³Õ«òœa JyÌðKŽ­C¸¤¿ƒdº€‡_õk4.6°M“O˜—+F2JªZž9îWŽ6ŠdR*5¿MÿAé¡åèXçÑA¤­EtK¬ãªO#2ÃŒÄÒVW% È ‰ãb˜4=¡­ÏÍ„hÊ4 ®S•i«nü×)¢0Ò†îÛãƒýn ïl@1ŒJ«Ý{möV21x`½û©ètYÛøq·f·/L5zÛ‡Šz½ÁëížÂJïžîš"SÜíûº§w®¸{³«zøð´?xûæ]·sšP ó­p„wæu1³£¿P´d’x8‚ ÅknŸIËUäfZd ÞÔäu„ý§{¢Ë‚¸„þ¾sz$sCbSk:Èä3K•ªöÍö›¨Š¼NÞöVªê‘|‰ªÕý_Z¨ýgÆN¦—^‡W®A8eŽ*^~êëÐ j‘JÜë°Wê¹3 šXmLÝ@›í‹¾)¶TD gÓ¯)¶¶›×ÿG'U#ÒL³Pã¹zrJw*jŒëÅS†\¦=ÉÉ^á×ò6Þe÷ºvœòNdyµîˆÉ¤Þ‰,¡Õ°‰Ë;â°ö„ë@}Ålº©;£³‹E—ƒcÅã"w“þ¢#èì'y¶Ö‚Þ0uûNw娇¬¹É/ëžn\^1»,¼aÝë?n€nî’°q^qÂÀV7éŸcx¢€š†INcá½=C)½¾£äõÑé›ÎœŒ±uBÆ}}ÒM”¹%èE¼DøÇáW ’öaΖH7óK¡bj„¥C Hô{§ó®‰·¦i·š–m|Òtuà¨EH/°× ðÂÃWˆ«¿Ì´PçDË£èÊ×½N§¹eòD (n•ÎnÕ2$Þ,¹ýPK!”8Mܯ¸ìî lib/vec.hUT ½©[;\À[ux ÷–ßkÛ0ÇßýW % lì±ô¡”ⶤa”aùœˆ)’‘•6ÞÈÿ>%Ç¿dÏi˾ûÜIßÓÉ,1$d¹¸}¸¿ÏîVËðkpaž1íÇA Â,c€¨ðhÈAlôv’Á!’ÇkcéH3J˜àèÏ„ž[¾áa ’“)ù¢@ï• ‹ÇûùÝíb‚€£`þó‡Õì~¶ôb¹_s@F¼Jb9ëÉ@…TîR‡°È„¦C”»ÇoO‹ÙÏÐ:×`)*zÊåö‡—PØIlÕ€ûój97ª=­ü+r¢p– ­ªS½Ât¥qÒn@—„+RVëÑø…ýòÊìTÁªäö²¬âNð8§¼—Ußi?XAÓÖ+ƒ1õà`-Ú«d±“!•¿Áƒº*V7·Ä†ä†äÝüÅCl¨1HD=z‰N5­4$¢ ½ÄºvÛPfŒÊ ‚e¶¥>%2°^¶IV›Q]bl—k)9.v†¦ZªnáÌU ¤¾%lib/export.hUTÏ[À[ux ÷PK$_6MÁ@)*ª%¤Ð'lib/fn.cUTó¦[ux ÷PKgeHM¯zU¤¼(lib/fn.hUTÁ4»[ux ÷PK$_6M;{%Õ—r ¤*lib/formula.cUTó¦[ux ÷PKý^6M°ÚxÂ}Ó ¤ä,lib/formula.hUT­¦[ux ÷PK$_6MaìÕS ¤¨-lib/lang.cUTó¦[ux ÷PK$_6M—)h  ¤?0lib/lang.hUTó¦[ux ÷PK$_6M0+À³a ¤ë1lib/node.cUTó¦[ux ÷PK$_6M°Ô¹Ž&v ¤â4lib/node.hUTó¦[ux ÷PK!”8M±EXëV3 ¤L7lib/parse.cUT½©[ux ÷PK$_6M eðµl ¤|@lib/parse.hUTó¦[ux ÷PKý^6MúÚÇN¹ ¤vDlib/quo.cUT­¦[ux ÷PKý^6MÝ]Dgô ¤Elib/quo.hUT­¦[ux ÷PKý^6MÇÛÅr ¤±Elib/replace-na.cUT­¦[ux ÷PK!”8M ]í¡W% ¤Hlib/rlang.cUT½©[ux ÷PK!”8MÒƒÐK ¤¶Klib/rlang.hUT½©[ux ÷PK\|;Mð'õûE´ ¤ËNlib/session.cUT€Ü¬[ux ÷PKÜSLM¦¸ž~_v ¤WPlib/session.hUT¿[À[ux ÷PK!”8M#eP£Ån ¤ýPlib/sexp.cUT½©[ux ÷PK!”8M¤zŸŒ ¤Rlib/sexp.hUT½©[ux ÷PK!”8Mo_cŸŽ ¤ÖTlib/squash.cUT½©[ux ÷PKý^6M·Q ‹Ð ¤»\lib/squash.hUT­¦[ux ÷PK!”8MŽPûƒq… ¤Œ]lib/stack.cUT½©[ux ÷PKý^6M(Ký¤  ¤B`lib/stack.hUT­¦[ux ÷PKý^6MW°Ò­}™ ¤+alib/state.hUT­¦[ux ÷PK!”8Môá ñ<h¤íalib/sym-unescape.cUT½©[ux ÷PKg;MÑú õ°Ð ¤uglib/sym.cUTg·¬[ux ÷PKg;M5Õ²OY ¤hjlib/sym.hUTg·¬[ux ÷PKЭBMY±^Qkç ¤úklib/vec-chr.cUT˳[ux ÷PKЭBMŒ‘{·˜ ¤¬olib/vec-chr.hUT˳[ux ÷PKЭBM8•ËŽ ¤ªrlib/vec-lgl.cUT˳[ux ÷PK¯BM™šqe¿x ¤¼tlib/vec-lgl.hUT_ͳ[ux ÷PKý^6M„âæP¿F¤Âulib/vec-list.cUT­¦[ux ÷PK!”8MþÞ$üñݤÉvlib/vec-list.hUT½©[ux ÷PK{eHMÊ®Si ¤xlib/vec.cUTê4»[ux ÷PK!”8Mܯ¸ìî ¤˜lib/vec.hUT½©[ux ÷PK33*ð‚rlang/tests/testthat/fixtures/error-backtrace-parent.R0000644000176200001440000000064213610575114022715 0ustar liggesusers options( crayon.enabled = FALSE, cli.unicode = FALSE ) if (nzchar(Sys.getenv("rlang_interactive"))) { options(rlang_interactive = TRUE) } options(rlang_trace_format_srcrefs = FALSE) f <- function() g() g <- function() h() h <- function() rlang::abort("foo") a <- function() b() b <- function() c() c <- function() { tryCatch( f(), error = function(err) rlang::abort("bar", parent = err) ) } a() rlang/tests/testthat/fixtures/error-backtrace-conditionMessage.R0000644000176200001440000000053713610575121024720 0ustar liggesusers options( crayon.enabled = FALSE, cli.unicode = FALSE ) if (nzchar(Sys.getenv("rlang_interactive"))) { options(rlang_interactive = TRUE) } options(rlang_trace_format_srcrefs = FALSE) conditionMessage.foobar_error <- function(c) { "dispatched!" } f <- function() g() g <- function() h() h <- function() rlang::abort("", "foobar_error") f() rlang/tests/testthat/fixtures/rlanglibtest/0000755000176200001440000000000013351410655020725 5ustar liggesusersrlang/tests/testthat/fixtures/rlanglibtest/NAMESPACE0000644000176200001440000000013413351410655022142 0ustar liggesusers# Generated by roxygen2: do not edit by hand useDynLib(rlanglibtest, .registration = TRUE) rlang/tests/testthat/fixtures/rlanglibtest/DESCRIPTION0000644000176200001440000000052113351410655022431 0ustar liggesusersPackage: rlanglibtest Title: What the Package Does (one line, title case) Version: 0.0.0.9000 Authors@R: 'Lionel Henry [aut, cre]' Description: What the package does (one paragraph). Depends: R (>= 3.1.0) Imports: rlang LinkingTo: rlang License: GPL-3 Encoding: UTF-8 LazyData: true RoxygenNote: 6.0.1 rlang/tests/testthat/fixtures/rlanglibtest/tests/0000755000176200001440000000000013351410655022067 5ustar liggesusersrlang/tests/testthat/fixtures/rlanglibtest/tests/testthat/0000755000176200001440000000000013614116052023723 5ustar liggesusersrlang/tests/testthat/fixtures/rlanglibtest/tests/testthat/test-quo-accessors.R0000644000176200001440000000140113351410655027612 0ustar liggesuserscontext("quo_accessors") test_that("r_quo_get_expr() gets expression", { r_quo_get_expr <- function(quo) { .Call(rlanglibtest_r_quo_get_expr, quo) } r_quo_set_expr <- function(quo, expr) { .Call(rlanglibtest_r_quo_set_expr, quo, expr) } r_quo_get_env <- function(quo) { .Call(rlanglibtest_r_quo_get_env, quo) } r_quo_set_env <- function(quo, env) { .Call(rlanglibtest_r_quo_set_env, quo, env) } quo <- rlang::quo(foo) expect_identical(r_quo_get_expr(quo), rlang::quo_get_expr(quo)) expect_identical(r_quo_get_env(quo), rlang::quo_get_env(quo)) expect_identical(r_quo_set_expr(quo, NULL), rlang::quo_set_expr(quo, NULL)) expect_identical(r_quo_set_env(quo, rlang::empty_env()), rlang::quo_set_env(quo, rlang::empty_env())) }) rlang/tests/testthat/fixtures/rlanglibtest/tests/testthat.R0000644000176200001440000000011013351410655024042 0ustar liggesuserslibrary("testthat") library("rlanglibtest") test_check("rlanglibtest") rlang/tests/testthat/fixtures/rlanglibtest/src/0000755000176200001440000000000013366255562021526 5ustar liggesusersrlang/tests/testthat/fixtures/rlanglibtest/src/init.c0000644000176200001440000000153613405732277022637 0ustar liggesusers#include "lib/rlang.h" extern sexp* rlanglibtest_r_quo_get_expr(sexp*); extern sexp* rlanglibtest_r_quo_set_expr(sexp*, sexp*); extern sexp* rlanglibtest_r_quo_get_env(sexp*); extern sexp* rlanglibtest_r_quo_set_env(sexp*, sexp*); sexp* rlanglibtest_library_load() { r_init_library(); return r_null; } static const r_callable r_callables[] = { {"rlanglibtest_library_load", (r_fn_ptr) &rlanglibtest_library_load, 0}, {"rlanglibtest_r_quo_get_expr", (r_fn_ptr) &rlanglibtest_r_quo_get_expr, 1}, {"rlanglibtest_r_quo_set_expr", (r_fn_ptr) &rlanglibtest_r_quo_set_expr, 2}, {"rlanglibtest_r_quo_get_env", (r_fn_ptr) &rlanglibtest_r_quo_get_env, 1}, {"rlanglibtest_r_quo_set_env", (r_fn_ptr) &rlanglibtest_r_quo_set_env, 2}, {NULL, NULL, 0} }; void R_init_rlanglibtest(r_dll_info* dll) { r_register_r_callables(dll, r_callables, NULL); } rlang/tests/testthat/fixtures/rlanglibtest/src/Makevars0000644000176200001440000000003013351410655023201 0ustar liggesusersPKG_CPPFLAGS = -I./lib/ rlang/tests/testthat/fixtures/rlanglibtest/src/test-quo-accessors.c0000644000176200001440000000056313351410655025430 0ustar liggesusers#include "lib/rlang.h" sexp* rlanglibtest_r_quo_get_expr(sexp* quo) { return r_quo_get_expr(quo); } sexp* rlanglibtest_r_quo_set_expr(sexp* quo, sexp* expr) { return r_quo_set_expr(quo, expr); } sexp* rlanglibtest_r_quo_get_env(sexp* quo) { return r_quo_get_env(quo); } sexp* rlanglibtest_r_quo_set_env(sexp* quo, sexp* env) { return r_quo_set_env(quo, env); } rlang/tests/testthat/fixtures/rlanglibtest/R/0000755000176200001440000000000013366255562021140 5ustar liggesusersrlang/tests/testthat/fixtures/rlanglibtest/R/rlanglibtest.R0000644000176200001440000000053313405732277023753 0ustar liggesusers#' @useDynLib rlanglibtest, .registration = TRUE NULL .onLoad <- function(lib, pkg) { # Causes rlang package to load and register native routines rlang::dots_list() .Call(rlanglibtest_library_load) } test_trace_unexported <- function(e) { trace_back(e) } test_trace_unexported_child <- local(function(e) { test_trace_unexported(e) }) rlang/tests/testthat/fixtures/trace-srcref.R0000644000176200001440000000011113405732277020736 0ustar liggesusersf <- function(e) { g(e) } g <- function(e) { rlang::trace_back(e) } rlang/tests/testthat/fixtures/error-backtrace.R0000644000176200001440000000062113610575105021423 0ustar liggesusers options( crayon.enabled = FALSE, cli.unicode = FALSE ) opt <- Sys.getenv("rlang_backtrace_on_error") if (nzchar(opt)) { options(rlang_backtrace_on_error = opt) } if (nzchar(Sys.getenv("rlang_interactive"))) { options(rlang_interactive = TRUE) } options(rlang_trace_format_srcrefs = FALSE) f <- function() tryCatch(g()) g <- function() h() h <- function() rlang::abort("Error message") f() rlang/tests/testthat/test-deparse.R0000644000176200001440000004746313614037775017135 0ustar liggesuserscontext("deparse") test_that("line_push() adds indentation", { out <- line_push("foo", "bar", width = 4, indent = 2) expect_identical(out, c("foo", " bar")) }) test_that("line_push() doesn't make a new line if current is only spaces", { expect_identical(line_push(" ", "foo", width = 2L), " foo") }) test_that("line_push() trims trailing spaces", { expect_identical(line_push("foo ", "bar", width = 1L), c("foo", "bar")) }) test_that("line_push() doesn't trim trailing spaces on sticky inputs", { expect_identical(line_push("tag", " = ", sticky = TRUE, width = 3L, indent = 2L), "tag = ") }) test_that("sticky input sticks", { expect_identical(line_push("foo ", "bar", sticky = TRUE, width = 1L), "foo bar") }) test_that("line_push() respects boundaries", { expect_identical(line_push("foo, ", "bar", boundary = 4L, width = 1L, indent = 2L), c("foo,", " bar")) expect_identical(line_push("foo, ", "bar", sticky = TRUE, boundary = 4L, width = 1L, indent = 2L), c("foo,", " bar")) expect_identical(line_push("foo, bar", "baz", boundary = 4L, width = 1L, indent = 2L), c("foo, bar", " baz")) }) test_that("line_push() handles the nchar(line) == boundary case", { expect_identical(line_push(" tag = ", "bar", sticky = TRUE, boundary = 8L, width = 3L, indent = 2L), " tag = bar") }) test_that("line_push() strips ANSI codes before computing overflow", { if (!has_crayon()) { skip("test needs crayon") } expect_identical(length(line_push("foo", open_blue(), width = 3L)), 2L) expect_identical(length(line_push("foo", open_blue(), width = 3L, has_colour = TRUE)), 1L) }) test_that("can push several lines (useful for default base deparser)", { expect_identical(new_lines()$push(c("foo", "bar"))$get_lines(), "foobar") }) test_that("control flow is deparsed", { expect_identical(fn_call_deparse(expr(function(a, b) 1)), "function(a, b) 1") expect_identical(fn_call_deparse(expr(function(a = 1, b = 2) { 3; 4; 5 })), c("function(a = 1, b = 2) {", " 3", " 4", " 5", "}")) expect_identical(while_deparse(quote(while(1) 2)), "while (1) 2") expect_identical(for_deparse(quote(for(a in 2) 3)), "for (a in 2) 3") expect_identical(repeat_deparse(quote(repeat 1)), "repeat 1") expect_identical(if_deparse(quote(if (1) 2 else { 3 })), c("if (1) 2 else {", " 3", "}")) }) test_that("functions defs increase indent", { ctxt <- new_lines(width = 3L) expect_identical(sexp_deparse(quote(function() 1), ctxt), c("function()", " 1")) ctxt <- new_lines(width = 3L) expect_identical(sexp_deparse(function() 1, ctxt), c("")) }) test_that("blocks are deparsed", { expect_identical(braces_deparse(quote({1; 2; { 3; 4 }})), c("{", " 1", " 2", " {", " 3", " 4", " }", "}")) expect_identical_(sexp_deparse(quote({{ 1 }})), c("{", " {", " 1", " }", "}")) ctxt <- new_lines(width = 3L) expected_lines <- c("{", " 11111", " 22222", " {", " 33333", " 44444", " }", "}") expect_identical(braces_deparse(quote({11111; 22222; { 33333; 44444 }}), ctxt), expected_lines) }) test_that("multiple openers on the same line only trigger one indent", { ctxt <- new_lines(width = 3L) expect_identical(sexp_deparse(quote(function() { 1 }), ctxt), c("function()", " {", " 1", " }")) ctxt <- new_lines(width = 12L) expect_identical(sexp_deparse(quote(function() { 1 }), ctxt), c("function() {", " 1", "}")) }) test_that("multiple openers on the same line are correctly reset", { expect_identical(sexp_deparse(quote({ 1(2()) })), c("{", " 1(2())", "}")) }) test_that("parentheses are deparsed", { expect_identical(parens_deparse(quote((1))), "(1)") expect_identical(parens_deparse(quote(({ 1; 2 }))), c("({", " 1", " 2", "})")) expect_identical(sexp_deparse(quote(({({ 1 })}))), c("({", " ({", " 1", " })", "})")) }) test_that("spaced operators are deparsed", { expect_identical(spaced_op_deparse(quote(1 ? 2)), "1 ? 2") expect_identical(spaced_op_deparse(quote(1 <- 2)), "1 <- 2") expect_identical(spaced_op_deparse(quote(1 <<- 2)), "1 <<- 2") expect_identical(spaced_op_deparse(quote(`=`(1, 2))), "1 = 2") expect_identical(spaced_op_deparse(quote(1 := 2)), "1 := 2") expect_identical(spaced_op_deparse(quote(1 ~ 2)), "1 ~ 2") expect_identical(spaced_op_deparse(quote(1 | 2)), "1 | 2") expect_identical(spaced_op_deparse(quote(1 || 2)), "1 || 2") expect_identical(spaced_op_deparse(quote(1 & 2)), "1 & 2") expect_identical(spaced_op_deparse(quote(1 && 2)), "1 && 2") expect_identical(spaced_op_deparse(quote(1 > 2)), "1 > 2") expect_identical(spaced_op_deparse(quote(1 >= 2)), "1 >= 2") expect_identical(spaced_op_deparse(quote(1 < 2)), "1 < 2") expect_identical(spaced_op_deparse(quote(1 <= 2)), "1 <= 2") expect_identical(spaced_op_deparse(quote(1 == 2)), "1 == 2") expect_identical(spaced_op_deparse(quote(1 != 2)), "1 != 2") expect_identical(spaced_op_deparse(quote(1 + 2)), "1 + 2") expect_identical(spaced_op_deparse(quote(1 - 2)), "1 - 2") expect_identical(spaced_op_deparse(quote(1 * 2)), "1 * 2") expect_identical(spaced_op_deparse(quote(1 / 2)), "1 / 2") expect_identical(spaced_op_deparse(quote(1 %% 2)), "1 %% 2") expect_identical(spaced_op_deparse(quote(1 %>% 2)), "1 %>% 2") expect_identical(sexp_deparse(quote({ 1; 2 } + { 3; 4 })), c("{", " 1", " 2", "} + {", " 3", " 4", "}")) }) test_that("unspaced operators are deparsed", { expect_identical(unspaced_op_deparse(quote(1:2)), "1:2") expect_identical(unspaced_op_deparse(quote(1^2)), "1^2") expect_identical(unspaced_op_deparse(quote(a$b)), "a$b") expect_identical(unspaced_op_deparse(quote(a@b)), "a@b") expect_identical(unspaced_op_deparse(quote(a::b)), "a::b") expect_identical(unspaced_op_deparse(quote(a:::b)), "a:::b") }) test_that("operands are wrapped in parentheses to ensure correct predecence", { skip("FIXME r-devel") expect_identical_(sexp_deparse(expr(1 + !!quote(2 + 3))), "1 + (2 + 3)") expect_identical_(sexp_deparse(expr((!!quote(1^2))^3)), "(1^2)^3") expect_identical_(sexp_deparse(quote(function() 1 ? 2)), "function() 1 ? 2") expect_identical_(sexp_deparse(expr(!!quote(function() 1) ? 2)), "(function() 1) ? 2") }) test_that("unary operators are deparsed", { expect_identical(unary_op_deparse(quote(?1)), "?1") expect_identical(unary_op_deparse(quote(~1)), "~1") expect_identical(unary_op_deparse(quote(!1)), "!1") expect_identical_(unary_op_deparse(quote(!!1)), "!!1") expect_identical_(unary_op_deparse(quote(!!!1)), "!!!1") expect_identical_(unary_op_deparse(quote(`!!`(1))), "!!1") expect_identical_(unary_op_deparse(quote(`!!!`(1))), "!!!1") expect_identical(unary_op_deparse(quote(+1)), "+1") expect_identical(unary_op_deparse(quote(-1)), "-1") }) test_that("brackets are deparsed", { expect_identical(sexp_deparse(quote(1[2])), c("1[2]")) expect_identical(sexp_deparse(quote(1[[2]])), c("1[[2]]")) ctxt <- new_lines(width = 1L) expect_identical(sexp_deparse(quote(1[2]), ctxt), c("1[", " 2]")) ctxt <- new_lines(width = 1L) expect_identical(sexp_deparse(quote(1[[2]]), ctxt), c("1[[", " 2]]")) }) test_that("calls are deparsed", { expect_identical(call_deparse(quote(foo(bar, baz))), "foo(bar, baz)") expect_identical(call_deparse(quote(foo(one = bar, two = baz))), "foo(one = bar, two = baz)") }) test_that("call_deparse() respects boundaries", { ctxt <- new_lines(width = 1L) expect_identical(call_deparse(quote(foo(bar, baz)), ctxt), c("foo(", " bar,", " baz)")) ctxt <- new_lines(width = 7L) expect_identical(call_deparse(quote(foo(bar, baz)), ctxt), c("foo(", " bar,", " baz)")) ctxt <- new_lines(width = 8L) expect_identical(call_deparse(quote(foo(bar, baz)), ctxt), c("foo(bar,", " baz)")) ctxt <- new_lines(width = 1L) expect_identical(call_deparse(quote(foo(one = bar, two = baz)), ctxt), c("foo(", " one = bar,", " two = baz)")) }) test_that("call_deparse() handles multi-line arguments", { ctxt <- new_lines(width = 1L) expect_identical(sexp_deparse(quote(foo(one = 1, two = nested(one = 1, two = 2))), ctxt), c("foo(", " one = 1,", " two = nested(", " one = 1,", " two = 2))")) ctxt <- new_lines(width = 20L) expect_identical(sexp_deparse(quote(foo(one = 1, two = nested(one = 1, two = 2))), ctxt), c("foo(one = 1, two = nested(", " one = 1, two = 2))")) }) test_that("call_deparse() delimits CAR when needed", { call <- expr((!!quote(function() x + 1))()) expect_identical(call_deparse(call), "(function() x + 1)()") # Only equal because of the extra parentheses expect_equal(parse_expr(expr_deparse(call)), call) call <- expr((!!quote(f + g))(x)) expect_identical(call_deparse(call), "`+`(f, g)(x)") expect_identical(parse_expr(expr_deparse(call)), call) call <- expr((!!quote(+f))(x)) expect_identical(call_deparse(call), "`+`(f)(x)") expect_identical(parse_expr(expr_deparse(call)), call) call <- expr((!!quote(while (TRUE) NULL))(x)) expect_identical(call_deparse(call), "`while`(TRUE, NULL)(x)") expect_identical(parse_expr(expr_deparse(call)), call) call <- expr(foo::bar(x)) expect_identical(call_deparse(call), "foo::bar(x)") expect_identical(parse_expr(expr_deparse(call)), call) }) test_that("literal functions are deparsed", { expect_identical_(sexp_deparse(function(a) 1), "") expect_identical_(sexp_deparse(expr(foo(!!function(a) 1))), "foo()") }) test_that("literal dots are deparsed", { dots <- (function(...) env_get(, "..."))(NULL) expect_identical_(sexp_deparse(expr(foo(!!dots))), "foo(<...>)") }) test_that("environments are deparsed", { expect_identical(sexp_deparse(expr(foo(!! env()))), "foo()") }) test_that("atomic vectors are deparsed", { expect_identical(sexp_deparse(set_names(c(TRUE, FALSE, TRUE), c("", "b", ""))), "") expect_identical(sexp_deparse(set_names(1:3, c("", "b", ""))), "") expect_identical(sexp_deparse(set_names(c(1, 2, 3), c("", "b", ""))), "") expect_identical(sexp_deparse(set_names(as.complex(1:3), c("", "b", ""))), "") expect_identical(sexp_deparse(set_names(as.character(1:3), c("", "b", ""))), "") expect_identical(sexp_deparse(set_names(as.raw(1:3), c("", "b", ""))), "") }) test_that("boundaries are respected when deparsing vectors", { ctxt <- new_lines(width = 1L) vec <- set_names(1:3, c("", "b", "")) expect_identical_(sexp_deparse(expr(foo(!!vec)), ctxt), c("foo(", " )")) ctxt <- new_lines(width = 12L) expect_identical(sexp_deparse(list(c("foo", "bar", "baz")), ctxt), c(">")) }) test_that("scalar atomic vectors are simply printed", { expect_identical(sexp_deparse(TRUE), "TRUE") expect_identical(sexp_deparse(1L), "1L") expect_identical(sexp_deparse(1), "1") expect_identical(sexp_deparse(1i), "0+1i") expect_identical(sexp_deparse("1"), "\"1\"") }) test_that("scalar raw vectors are printed in long form", { expect_identical(sexp_deparse(as.raw(1)), "") }) test_that("literal lists are deparsed", { expect_identical(sexp_deparse(list(TRUE, b = 2L, 3, d = "4", as.raw(5))), ">") }) test_that("long vectors are truncated", { expect_identical(sexp_deparse(1:10), "") expect_identical(sexp_deparse(as.list(1:10)), "") }) test_that("other objects are deparsed with base deparser", { expect_identical_(sexp_deparse(expr(foo((!!base::list)(1, 2)))), "foo(.Primitive(\"list\")(1, 2))") expect_identical_(sexp_deparse(expr(foo((!!base::`if`)(1, 2)))), "foo(.Primitive(\"if\")(1, 2))") }) test_that("S3 objects are deparsed", { expr <- expr(list(!!factor(1:3), !!structure(list(), class = c("foo", "bar", "baz")))) expect_identical(sexp_deparse(expr), "list(, )") }) test_that("successive indentations on a single line are only counted once", { ctxt <- new_lines(5L) broken_output <- c(">") expect_identical(sexp_deparse(list(c(foo = "bar", baz = "bam")), ctxt), broken_output) ctxt <- new_lines(12L) unbroken_output <- c(">") expect_identical(sexp_deparse(list(c(foo = "bar", baz = "bam")), ctxt), unbroken_output) }) test_that("successive indentations close off properly", { expect_identical(sexp_deparse(quote(1(2(), 3(4())))), "1(2(), 3(4()))") expect_identical(sexp_deparse(quote(1(2(), 3(4()))), new_lines(width = 1L)), c("1(", " 2(),", " 3(", " 4()))")) expect_identical(sexp_deparse(expr(c((1), function() { 2 }))), c("c((1), function() {", " 2", "})")) }) test_that("empty quosures are deparsed", { expect_identical(strip_style(quo_deparse(quo())), "^") }) test_that("missing values are deparsed", { expect_identical(expr_deparse(NA), "NA") expect_identical(expr_deparse(NaN), "NaN") expect_identical(expr_deparse(NA_integer_), "NA_integer_") expect_identical(expr_deparse(NA_real_), "NA_real_") expect_identical(expr_deparse(NA_complex_), "NA_complex_") expect_identical(expr_deparse(NA_character_), "NA_character_") expect_identical(expr_deparse(c(NaN, 2, NA)), "") expect_identical(expr_deparse(c(foo = NaN)), "") expect_identical(sexp_deparse(c(name = NA)), "") expect_identical(sexp_deparse(c(NA, "NA")), "") expect_identical(sexp_deparse(quote(call(NA))), "call(NA)") expect_identical(sexp_deparse(quote(call(NA_integer_))), "call(NA_integer_)") expect_identical(sexp_deparse(quote(call(NA_real_))), "call(NA_real_)") expect_identical(sexp_deparse(quote(call(NA_complex_))), "call(NA_complex_)") expect_identical(sexp_deparse(quote(call(NA_character_))), "call(NA_character_)") }) test_that("needs_backticks() detects non-syntactic symbols", { expect_true(all(map_lgl(reserved_words, needs_backticks))) expect_false(any(map_lgl(c(".", "a", "Z"), needs_backticks))) expect_true(all(map_lgl(c("1", ".1", "~", "!"), needs_backticks))) expect_true(all(map_lgl(c("_", "_foo", "1foo"), needs_backticks))) expect_true(all(map_lgl(c(".fo!o", "b&ar", "baz <- _baz", "~quux.", "h~unoz_"), needs_backticks))) expect_false(any(map_lgl(c(".foo", "._1", "bar", "baz_baz", "quux.", "hunoz_", "..."), needs_backticks))) expect_false(needs_backticks(expr())) }) test_that("expr_text() and expr_name() interpret unicode tags (#611)", { expect_identical(expr_text(quote(``)), "o") expect_identical(expr_name(quote(`~f`)), "~foo") expect_identical(as_label(quote(`~f`)), "~foo") }) test_that("expr_text() deparses non-syntactic symbols with backticks (#211)", { expect_identical(expr_text(sym("~foo")), "`~foo`") expect_identical(expr_text(sym("~f")), "`~foo`") expect_identical(expr_text(call("~foo")), "`~foo`()") }) test_that("expr_text() deparses empty arguments", { expect_identical(expr_text(expr()), "") expect_identical(quo_text(expr()), "") expect_identical(quo_text(quo()), "") }) test_that("expr_name() deparses empty arguments", { expect_identical(expr_name(expr()), "") expect_identical(quo_name(quo()), "") expect_identical(names(quos_auto_name(quos(, ))), "") expect_identical(as_label(expr()), "") }) test_that("expr_deparse() handles newlines in strings (#484)", { x <- "foo\n" expect_identical(expr_deparse(x), "\"foo\\n\"") expect_output(expr_print(x), "foo\\n", fixed = TRUE) roundtrip <- parse_expr(expr_deparse(x)) expect_identical(x, roundtrip) }) test_that("expr_deparse() handles ANSI escapes in strings", { expect_identical(expr_deparse("\\"), deparse("\\")) expect_identical(expr_deparse("\\a"), deparse("\\a")) expect_identical(expr_deparse("\\b"), deparse("\\b")) expect_identical(expr_deparse("\\f"), deparse("\\f")) expect_identical(expr_deparse("\\n"), deparse("\\n")) expect_identical(expr_deparse("\\r"), deparse("\\r")) expect_identical(expr_deparse("\\t"), deparse("\\t")) expect_identical(expr_deparse("\\v"), deparse("\\v")) expect_identical(expr_deparse("\\0"), deparse("\\0")) }) test_that("as_label() and expr_name() handles .data pronoun", { expect_identical(expr_name(quote(.data[["bar"]])), "bar") expect_identical(quo_name(quo(.data[["bar"]])), "bar") expect_identical(as_label(quote(.data[["bar"]])), "bar") expect_identical(as_label(quo(.data[["bar"]])), "bar") }) test_that("as_label() handles literals", { expect_identical(as_label(1:2), "") expect_identical(as_label(c(1, 2)), "") expect_identical(as_label(letters), "") expect_identical(as_label(base::list), "") expect_identical(as_label(base::mean), "") }) test_that("as_label() handles objects", { expect_identical(as_label(mtcars), "") expect_identical(as_label(structure(1, class = "foo")), "") }) test_that("bracket deparsing is a form of argument deparsing", { expect_identical(expr_deparse(call("[", iris, missing_arg(), drop = FALSE)), "[, drop = FALSE]") expect_identical(expr_deparse(quote(foo[bar, , baz()])), "foo[bar, , baz()]") expect_identical(expr_deparse(quote(foo[[bar, , baz()]])), "foo[[bar, , baz()]]") }) test_that("non-syntactic symbols are deparsed with backticks", { expect_identical(expr_deparse(quote(`::foo`)), "`::foo`") expect_identical(expr_deparse(quote(x(`_foo`))), "x(`_foo`)") expect_identical(expr_deparse(quote(x[`::foo`])), "x[`::foo`]") }) test_that("symbols with unicode are deparsed consistently (#691)", { skip_unless_utf8() skip_if(getRversion() < "3.2") expect_identical(expr_text(sym("\u00e2a")), "\u00e2a") expect_identical(expr_deparse(sym("\u00e2a")), "\u00e2a") expect_identical(expr_text(sym("a\u00e2")), "a\u00e2") expect_identical(expr_deparse(sym("a\u00e2")), "a\u00e2") }) test_that("formal parameters are backticked if needed", { expect_identical(expr_deparse(function(`^`) {}), c("")) }) test_that("empty blocks are deparsed on the same line", { expect_identical(expr_deparse(quote({ })), "{ }") }) test_that("top-level S3 objects are deparsed", { f <- structure(function() { }, class = "lambda") expect_identical(expr_deparse(f), "") }) # This test causes a parsing failure in R CMD check >= 3.6 # # test_that("binary operators with 0 or 1 arguments are properly deparsed", { # expect_identical_(expr_deparse(quote(`/`())), "`/`()") # expect_identical(expr_deparse(quote(`/`("foo"))), "`/`(\"foo\")") # expect_identical_(expr_deparse(quote(`::`())), "`::`()") # expect_identical(expr_deparse(quote(`::`("foo"))), "`::`(\"foo\")") # }) test_that("as_label() supports symbols, calls, and literals", { expect_identical(as_label(quote(foo)), "foo") expect_identical(as_label(quote(foo(bar))), "foo(bar)") expect_identical(as_label(1L), "1L") expect_identical(as_label("foo"), "\"foo\"") expect_identical(as_label(function() NULL), "") expect_identical(as_label(expr(function() { a; b })), "function() ...") expect_identical(as_label(1:2), "") expect_identical(as_label(env()), "") }) test_that("as_label() supports special objects", { expect_match(as_label(quote(foo := bar)), ":=") expect_identical(as_label(quo(foo)), "foo") expect_identical(as_label(quo(foo(!!quo(bar)))), "foo(bar)") expect_identical(as_label(~foo), "~foo") expect_identical(as_label(NULL), "NULL") }) test_that("as_name() supports quosured symbols and strings", { expect_identical(as_name(quo(foo)), "foo") expect_identical(as_name(quo("foo")), "foo") expect_error(as_name(quo(foo())), "Can't convert a call to a string") }) test_that("named empty lists are marked as named", { expect_identical(expr_deparse(set_names(list(), chr())), "") }) test_that("infix operators are sticky", { expect_identical(expr_deparse(quote(foo %>% bar), width = 3L), c("foo %>%", " bar")) expect_identical(expr_deparse(quote(foo + bar), width = 3L), c("foo +", " bar")) }) rlang/tests/testthat/test-vec-utils.R0000644000176200001440000000072013477732122017401 0ustar liggesuserscontext("vec-utils") test_that("seq2() creates increasing sequences", { expect_identical(seq2(2, 3), 2:3) expect_identical(seq2(3, 2), int()) }) test_that("seq2_along() creates increasing sequences", { expect_identical(seq2_along(3, 1:2), int()) expect_identical(seq2_along(-1, 1:2), -1:2) }) test_that("seq2() fails with non-scalar inputs", { expect_error(seq2(int(), 1), "must be length one") expect_error(seq2(1, int()), "must be length one") }) rlang/tests/testthat/test-expr.R0000644000176200001440000000464313535661230016450 0ustar liggesuserscontext("expr") # expr_text() -------------------------------------------------------- test_that("always returns single string", { out <- expr_text(quote({ a + b })) expect_length(out, 1) }) test_that("can truncate lines", { out <- expr_text(quote({ a + b }), nlines = 2) expect_equal(out, "{\n...") }) # expr_label() ------------------------------------------------------- test_that("quotes strings", { expect_equal(expr_label("a"), '"a"') expect_equal(expr_label("\n"), '"\\n"') }) test_that("backquotes names", { expect_equal(expr_label(quote(x)), "`x`") }) test_that("converts atomics to strings", { expect_equal(expr_label(0.5), "0.5") }) test_that("expr_label() truncates blocks", { expect_identical(expr_label(quote({ a + b })), "`{ ... }`") expect_identical(expr_label(expr(function() { a; b })), "`function() ...`") }) test_that("expr_label() truncates long calls", { long_call <- quote(foo()) long_arg <- quote(longlonglonglonglonglonglonglonglonglonglonglong) long_call[c(2, 3, 4)] <- list(long_arg, long_arg, long_arg) expect_identical(expr_label(long_call), "`foo(...)`") }) # expr_name() -------------------------------------------------------- test_that("expr_name() with symbols, calls, and literals", { expect_identical(expr_name(quote(foo)), "foo") expect_identical(expr_name(quote(foo(bar))), "foo(bar)") expect_identical(expr_name(1L), "1") expect_identical(expr_name("foo"), "foo") expect_identical(expr_name(function() NULL), "function () ...") expect_identical(expr_name(expr(function() { a; b })), "function() ...") expect_identical(expr_name(NULL), "NULL") expect_error(expr_name(1:2), "must quote") expect_error(expr_name(env()), "must quote") }) # -------------------------------------------------------------------- test_that("get_expr() supports closures", { expect_true(TRUE) return("Disabled because causes dplyr to fail") expect_identical(get_expr(identity), quote(x)) }) test_that("set_expr() supports closures", { fn <- function(x) x expect_equal(set_expr(fn, quote(y)), function(x) y) }) test_that("expressions are deparsed and printed", { expect_output(expr_print(1:2), "") expect_identical(expr_deparse(1:2), "") }) test_that("imaginary numbers with real part are not syntactic", { expect_true(is_syntactic_literal(0i)) expect_true(is_syntactic_literal(na_cpl)) expect_false(is_syntactic_literal(1 + 1i)) }) rlang/tests/testthat/helper-stack.R0000644000176200001440000000071313351410454017065 0ustar liggesusers fixup_calls <- function(x) { cur_pos <- sys.nframe() - 1 x[seq(n+1, length(x))] } fixup_ctxt_depth <- function(x) { x - (sys.nframe() - 1) } fixup_call_depth <- function(x) { x - (call_depth() - 1) } fixup_call_trail <- function(trail) { eval_callers <- ctxt_stack_callers() cur_trail <- trail_make(eval_callers) cur_pos <- eval_callers[1] indices <- seq(1, length(trail) - length(cur_trail)) trail <- trail[indices] trail - cur_pos } rlang/tests/testthat/test-cnd-error-print-no-message.txt0000644000176200001440000000001413612375014023153 0ustar liggesusers rlang/tests/testthat/test-trace-collapse-magrittr-complete-leading2.txt0000644000176200001440000000117713612375027026127 0ustar liggesusersFull: â–ˆ 1. └─F(NA) %>% F() %>% T() 2. ├─base::withVisible(eval(quote(`_fseq`(`_lhs`)), env, env)) 3. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 4. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 5. └─rlang:::`_fseq`(`_lhs`) 6. └─magrittr::freduce(value, `_function_list`) 7. ├─base::withVisible(function_list[[k]](value)) 8. └─function_list[[k]](value) 9. └─rlang:::T(.) Collapsed: â–ˆ 1. └─[ F(NA) %>% F() %>% T() ] with 7 more calls 9. └─rlang:::T(.) Branch: 1. rlang:::F(NA) 1. rlang:::F(.) 9. rlang:::T(.) rlang/tests/testthat/test-trace-collapse-children.txt0000644000176200001440000000053513612375026022571 0ustar liggesusersFull: â–ˆ 1. └─rlang:::f() 2. └─base::eval(quote(g()), env()) 3. └─base::eval(quote(g()), env()) 4. └─rlang:::g() Collapsed: â–ˆ 1. └─rlang:::f() 2. └─[ base::eval(...) ] with 1 more call 4. └─rlang:::g() Branch: 1. rlang:::f() 2. [ base::eval(...) ] with 1 more call 4. rlang:::g() rlang/tests/testthat/test-trace.R0000644000176200001440000004326613612027671016575 0ustar liggesuserscontext("trace.R") # These tests must come first because print method includes srcrefs test_that("tree printing only changes deliberately", { skip_unless_utf8() local_options( rlang_trace_format_srcrefs = TRUE, `rlang:::trace_force_dangling_srcrefs` = TRUE ) dir <- normalizePath(test_path("..")) e <- environment() i <- function(i) j(i) j <- function(i) { k(i) } k <- function(i) { NULL l(i) } l <- function(i) trace_back(e) trace <- i() expect_known_output(file = test_path("test-trace-print.txt"), { print(trace, dir = dir) cat("\n") print(trace_subset(trace, 0L), dir = dir) }) }) test_that("can print tree with collapsed branches", { skip_unless_utf8() # Fake eval() call does not have same signature on old R skip_if(getRversion() < "3.4") local_options( rlang_trace_format_srcrefs = TRUE, `rlang:::trace_force_dangling_srcrefs` = TRUE ) dir <- normalizePath(test_path("..")) e <- environment() f <- function() { g() } g <- function() { tryCatch(h(), foo = identity, bar = identity) } h <- function() { tryCatch(i(), baz = identity) } i <- function() { tryCatch(trace_back(e, bottom = 0)) } trace <- eval(quote(f())) expect_known_trace_output(trace, file = test_path("test-trace-collapsed1.txt"), dir = dir, srcrefs = TRUE ) # With multiple siblings f <- function() eval(quote(eval(quote(g())))) g <- function() tryCatch(eval(quote(h())), foo = identity, bar = identity) h <- function() trace_back(e) trace <- eval(quote(f())) expect_known_trace_output(trace, file = test_path("test-trace-collapsed2.txt"), dir = dir, srcrefs = TRUE ) }) test_that("trace_simplify_branch() extracts last branch", { e <- environment() j <- function(i) k(i) k <- function(i) l(i) l <- function(i) eval(quote(m()), parent.frame(i)) m <- function() trace_back(e) x1 <- j(1) expect_trace_length(x1, 6) expect_trace_length(trace_simplify_branch(x1), 3) x2 <- j(2) expect_trace_length(x2, 6) expect_trace_length(trace_simplify_branch(x2), 2) x3 <- j(3) expect_trace_length(x2, 6) expect_trace_length(trace_simplify_branch(x3), 1) }) test_that("integerish indices are allowed", { trace <- trace_back() expect_identical(trace_subset(trace, 0), trace_subset(trace, 0L)) }) test_that("cli_branch() handles edge case", { e <- environment() f <- function() trace_back(e) trace <- f() call <- paste0(" ", cli_style$h, "rlang:::f()") tree <- trace_as_tree(trace, srcrefs = FALSE) expect_identical(cli_branch(tree$call[-1], trace$indices), call) }) test_that("trace formatting picks up `rlang_trace_format_srcrefs`", { local_options(`rlang:::trace_force_dangling_srcrefs` = TRUE) e <- environment() f <- function() trace_back(e) trace <- f() with_options( rlang_trace_format_srcrefs = FALSE, expect_false(any(grepl("testthat", format(trace)))) ) with_options( rlang_trace_format_srcrefs = TRUE, expect_true(any(!!grepl("test-trace\\.R", format(trace)))) ) }) test_that("trace picks up option `rlang_trace_top_env` for trimming trace", { e <- current_env() f1 <- function() trace_back() f2 <- function() trace_back(e) with_options(rlang_trace_top_env = current_env(), expect_identical(trace_length(f1()), trace_length(f2())) ) }) test_that("collapsed formatting doesn't collapse single frame siblings", { e <- current_env() f <- function() eval_bare(quote(g())) g <- function() trace_back(e) trace <- f() full <- capture.output(print(trace, simplify = "none", srcrefs = FALSE))[[3]] expect_match(full, "rlang::eval_bare(quote(g()))", fixed = TRUE) collapsed <- capture.output(print(trace, simplify = "collapse", srcrefs = FALSE))[[3]] expect_match(collapsed, "[ rlang::eval_bare(...) ]", fixed = TRUE) }) test_that("recursive frames are rewired to the global env", { skip_unless_utf8() dir <- normalizePath(test_path("..")) e <- environment() f <- function() g() g <- function() trace_back(e) trace <- eval_tidy(quo(f())) expect_known_trace_output(trace, file = "test-trace-recursive.txt") }) test_that("long backtrace branches are truncated", { skip_unless_utf8() e <- current_env() f <- function(n) { if (n) { return(f(n - 1)) } trace_back(e) } trace <- f(10) expect_known_output(file = test_path("test-trace-truncate-backtrace-branch.txt"), { cat("Full:\n") print(trace, simplify = "branch", srcrefs = FALSE) cat("\n5 frames:\n") print(trace, simplify = "branch", max_frames = 5, srcrefs = FALSE) cat("\n2 frames:\n") print(trace, simplify = "branch", max_frames = 2, srcrefs = FALSE) cat("\n1 frame:\n") print(trace, simplify = "branch", max_frames = 1, srcrefs = FALSE) }) expect_error(print(trace, simplify = "none", max_frames = 5), "currently only supported with") expect_error(print(trace, simplify = "collapse", max_frames = 5), "currently only supported with") }) test_that("eval() frames are collapsed", { skip_unless_utf8() # Fake eval() call does not have same signature on old R skip_if(getRversion() < "3.4") e <- current_env() f <- function() base::eval(quote(g())) g <- function() eval(quote(trace_back(e, bottom = 0))) trace <- f() expect_known_trace_output(trace, file = "test-trace-collapse-eval.txt") f <- function() base::evalq(g()) g <- function() evalq(trace_back(e, bottom = 0)) trace <- f() expect_known_trace_output(trace, file = "test-trace-collapse-evalq.txt") }) test_that("%>% frames are collapsed", { skip_unless_utf8() skip_if_not_installed("magrittr") # Fake eval() call does not have same signature on old R skip_if(getRversion() < "3.4") `%>%` <- magrittr::`%>%` e <- current_env() f <- function(x, ...) x g <- function(x, ...) x h <- function(x, ...) trace_back(e) trace <- NULL %>% f() %>% g(1, 2) %>% h(3, ., 4) expect_known_trace_output(trace, "test-trace-collapse-magrittr.txt") trace <- f(NULL) %>% g(list(.)) %>% h(3, ., list(.)) expect_known_trace_output(trace, "test-trace-collapse-magrittr2.txt") trace <- f(g(NULL %>% f()) %>% h()) expect_known_trace_output(trace, "test-trace-collapse-magrittr3.txt") }) test_that("children of collapsed %>% frames have correct parent", { skip_unless_utf8() skip_if_not_installed("magrittr") # Fake eval() call does not have same signature on old R skip_if(getRversion() < "3.4") `%>%` <- magrittr::`%>%` e <- current_env() F <- function(x, ...) x G <- function(x, ...) x H <- function(x) f() f <- function() h() h <- function() trace_back(e) trace <- NA %>% F() %>% G() %>% H() expect_known_trace_output(trace, "test-trace-collapse-magrittr-children.txt") }) test_that("children of collapsed frames are rechained to correct parent", { skip_unless_utf8() # Fake eval() call does not have same signature on old R skip_if(getRversion() < "3.4") e <- current_env() f <- function() eval(quote(g()), env()) g <- function() trace_back(e) trace <- f() expect_known_output(file = test_path("test-trace-collapse-children.txt"), { cat("Full:\n") print(trace, simplify = "none", srcrefs = FALSE) cat("\nCollapsed:\n") print(trace, simplify = "collapse", srcrefs = FALSE) cat("\nBranch:\n") print(trace, simplify = "branch", srcrefs = FALSE) }) }) test_that("pipe_collect_calls() collects calls", { exprs2 <- function(...) unname(exprs(...)) placeholder <- function() NULL call <- quote(a(A %>% B) %>% b) out <- pipe_collect_calls(call, placeholder) expect_identical(out$calls, exprs2(rlang:::a(A %>% B), rlang:::b(.))) expect_true(out$leading) call <- quote(a %>% b %>% c) out <- pipe_collect_calls(call, placeholder) expect_identical(out$calls, exprs2(rlang:::b(.), rlang:::c(.))) expect_false(out$leading) call <- quote(a() %>% b %>% c) out <- pipe_collect_calls(call, placeholder) expect_identical(out$calls, exprs2(rlang:::a(), rlang:::b(.), rlang:::c(.))) expect_true(out$leading) }) test_that("combinations of incomplete and leading pipes collapse properly", { skip_unless_utf8() skip_if_not_installed("magrittr") # Fake eval() call does not have same signature on old R skip_if(getRversion() < "3.4") `%>%` <- magrittr::`%>%` e <- current_env() F <- function(x, ...) x T <- function(x) trace_back(e) trace <- NA %>% F() %>% T() %>% F() %>% F() expect_known_trace_output(trace, "test-trace-collapse-magrittr-incomplete.txt") trace <- T(NA) %>% F() expect_known_trace_output(trace, "test-trace-collapse-magrittr-incomplete-leading1.txt") trace <- F(NA) %>% F() %>% T() %>% F() %>% F() expect_known_trace_output(trace, "test-trace-collapse-magrittr-incomplete-leading2.txt") trace <- NA %>% T() expect_known_trace_output(trace, "test-trace-collapse-magrittr-complete1.txt") trace <- NA %>% F() %>% T() expect_known_trace_output(trace, "test-trace-collapse-magrittr-complete2.txt") trace <- F(NA) %>% T() expect_known_trace_output(trace, "test-trace-collapse-magrittr-complete-leading1.txt") trace <- F(NA) %>% F() %>% T() expect_known_trace_output(trace, "test-trace-collapse-magrittr-complete-leading2.txt") }) test_that("calls before and after pipe are preserved", { skip_unless_utf8() skip_if_not_installed("magrittr") # Fake eval() call does not have same signature on old R skip_if(getRversion() < "3.4") `%>%` <- magrittr::`%>%` e <- current_env() F <- function(x, ...) x T <- function(x) trace_back(e) C <- function(x) f() f <- function() trace_back(e) trace <- F(NA %>% T()) expect_known_trace_output(trace, "test-trace-collapse-magrittr-before-after1.txt") trace <- NA %>% C() expect_known_trace_output(trace, "test-trace-collapse-magrittr-before-after2.txt") trace <- F(NA %>% C()) expect_known_trace_output(trace, "test-trace-collapse-magrittr-before-after3.txt") }) test_that("always keep very first frame as part of backtrace branch", { skip_unless_utf8() # Fake eval() call does not have same signature on old R skip_if(getRversion() < "3.4") e <- current_env() gen <- function(x) UseMethod("gen") gen.default <- function(x) trace_back(e) trace <- gen() expect_known_trace_output(trace, "test-trace-backtrace-branch-first-frame.txt") }) test_that("can take the str() of a trace (#615)", { e <- current_env() f <- function(n) if (n < 10) f(n - 1) else trace_back(e) expect_output(expect_no_error(str(f(10)))) }) test_that("anonymous calls are stripped from backtraces", { skip_unless_utf8() e <- current_env() trace <- (function() { "foo" "bar" trace_back(e) })() expect_identical(format(trace, simplify = "branch"), chr()) expect_known_trace_output(trace, "test-trace-backtrace-anonymous.txt") }) test_that("collapsing of eval() frames detects when error occurs within eval()", { skip_unless_utf8() e <- NULL trace <- NULL fn <- function() { local_options( rlang_trace_format_srcrefs = FALSE ) e <<- current_env() eval() } catch_cnd(with_handlers( fn(), error = calling(function(err) trace <<- trace_back(e)) )) expect_known_trace_output(trace, "test-trace-non-collapsed-eval") }) test_that("can print degenerate backtraces", { skip_unless_utf8() trace_sym <- new_trace(list(quote(foo)), int(0), chr("")) expect_known_trace_output(trace_sym, file = "test-trace-degenerate-sym.txt") trace_null <- new_trace(list(NULL), int(0), chr("")) expect_known_trace_output(trace_null, file = "test-trace-degenerate-null.txt") trace_scalar <- new_trace(list(1L), int(0), chr("")) expect_known_trace_output(trace_scalar, file = "test-trace-degenerate-scalar.txt") }) test_that("check for dangling promise in call CAR (#492)", { skip_unless_utf8() expect_known_trace_output(file = "test-trace-call-car-promise.txt", local({ e <- current_env() print.foo <- function(x) { rlang::trace_back(e) } foo <- structure(list(), class = "foo") print(foo) })) }) test_that("dangling srcrefs are not printed", { skip_unless_utf8() from <- test_path("fixtures", "trace-srcref.R") to <- test_path("fixtures", "trace-srcref2.R") file.copy(from, to) on.exit(unlink(to)) source(to, local = TRUE, keep.source = TRUE) unlink(to) expect_known_trace_output( local(f(current_env())), file ="test-trace-dangling-srcref.txt", srcrefs = TRUE ) }) test_that("summary.rlang_trace() prints the full tree", { skip_unless_utf8() e <- current_env() f <- function() g() g <- function() h() h <- function() trace_back(e) trace <- f() expect_known_output(summary(trace, srcrefs = FALSE), file = test_path("test-trace-summary.txt")) }) test_that("unexported functions have `:::` prefix", { skip_unless_utf8() # Should be installed as part of the C API tests skip_if_not_installed("rlanglibtest") test_trace_unexported_child <- env_get(ns_env("rlanglibtest"), "test_trace_unexported_child") e <- current_env() f <- function() test_trace_unexported_child(e) trace <- f() expect_known_trace_output(trace, file = "test-trace-unexported-prefix.txt") }) test_that("global functions have `global::` prefix", { skip_unless_utf8() f <- eval_bare(expr(function(e) rlang::trace_back(e)), global_env()) g <- function(e) f(e) trace <- g(current_env()) expect_known_trace_output(trace, file = "test-trace-global-prefix.txt") }) test_that("local functions inheriting from global do not have `global::` prefix", { skip_unless_utf8() f <- eval_bare(expr(function(e) rlang::trace_back(e)), env(global_env())) g <- function(e) f(e) trace <- g(current_env()) expect_known_trace_output(trace, file = "test-trace-local-prefix.txt") }) test_that("can trim layers of backtraces", { skip_unless_utf8() e <- current_env() f <- function(n) identity(identity(g(n))) g <- function(n) identity(identity(h(n))) h <- function(n) identity(identity(trace_back(e, bottom = n))) trace0 <- f(0) trace1 <- f(1) trace2 <- f(2) trace3 <- f(3) expect_known_output(file = test_path("test-trace-trim.txt"), { local_options(rlang_trace_format_srcrefs = FALSE) cat_line("No trimming:") summary(trace0) cat_line("", "", "One layer (the default):") summary(trace1) cat_line("", "", "Two layers:") summary(trace2) cat_line("", "", "Three layers:") summary(trace3) }) # Test that trimming with frame environment is equivalent e <- current_env() f <- function(n) identity(identity(g(n))) g <- function(n) identity(identity(h(n))) h <- function(n) identity(identity(trace_back(e, bottom = caller_env(n - 1L)))) trace1_env <- f(1) trace2_env <- f(2) trace3_env <- f(3) expect_equal_trace(trace1, trace1_env) expect_equal_trace(trace2, trace2_env) expect_equal_trace(trace3, trace3_env) }) test_that("can subset from bottom tree level", { idx <- int(0, 1, 1, 1) expect_identical(chain_indices(4L, idx), c(1L, 4L)) expect_identical(parents_indices(4L, idx), c(1L, 4L)) expect_identical(children_indices(4L, idx), int()) e <- current_env() f <- function() identity(identity(g())) g <- function() trace_back(e) trace <- f() out <- trace_subset_across(trace, 3) f <- function() g() expected <- f() expect_equal_trace(out, expected) }) test_that("can subset from top tree level", { idx <- int(0, 1, 0, 3, 3, 3) expect_identical(chain_indices(3L, idx), 3:6) expect_identical(parents_indices(3L, idx), 3L) expect_identical(children_indices(3L, idx), 4:6) e <- current_env() f <- function() identity(identity(g())) g <- function() trace_back(e) trace <- tryCatch(f()) out <- trace_subset_across(trace, -1, 1) expected <- f() expect_equal_trace(out, expected) }) test_that("can subset in middle level", { idx <- int(0, 1, 1, 1, 4, 4, 4) expect_identical(chain_indices(3L, idx), c(1L, 3L)) expect_identical(parents_indices(3L, idx), c(1L, 3L)) expect_identical(children_indices(3L, idx), int()) e <- current_env() f <- function() identity(identity(g())) g <- function() identity(identity(h())) h <- function() trace_back(e) trace <- f() out <- trace_subset_across(trace, 2, 2) expect_equal(out$calls, alist(rlang:::f(), base::identity(g()))) expect_identical(out$parents, 0:1) idx <- int(0, 1, 1, 1, 4, 4, 4) expect_identical(chain_indices(4L, idx), c(1L, 4:7)) expect_identical(parents_indices(4L, idx), c(1L, 4L)) expect_identical(children_indices(4L, idx), 5:7) out <- trace_subset_across(trace, 3, 2) exp <- alist( rlang:::f(), rlang:::g(), base::identity(identity(h())), base::identity(h()), rlang:::h() ) expect_equal(out$calls, exp) expect_identical(out$parents, c(0L, 1L, 2L, 2L, 2L)) }) test_that("fails when `bottom` is not on the stack", { expect_error(trace_back(bottom = env()), "Can't find `bottom`") }) test_that("caught error does not display backtrace in knitted files", { skip_if(!rmarkdown::pandoc_available()) skip_if_not_installed("knitr") local_options( rlang_backtrace_on_error = NULL, rlang_interactive = FALSE ) lines <- render_md("test-trace.Rmd") error_line <- lines[[length(lines)]] expect_match(error_line, "foo$") }) test_that("empty backtraces are dealt with", { foo <- NULL local({ env <- new.env() local_options(rlang_trace_top_env = env) tryCatch( error = identity, withCallingHandlers( error = function(cnd) foo <<- cnd_entrace(cnd), eval(quote(stop("stop")), env) ) ) }) expect_identical(trace_length(foo$trace), 0L) }) test_that("can trace back with quosured symbol", { e <- current_env() f <- function(foo = g()) { # This will create a call in the call stack that isn't really a call quo <- quo(foo) # Quosure must be nested otherwise `eval_tidy()` unwraps it eval_tidy(expr(identity(!!quo))) } g <- function() trace_back(e) # FIXME: Weird trace structure trace <- f() expect_is(trace, "rlang_trace") }) rlang/tests/testthat/test-cnd-error.txt0000644000176200001440000000336313612375006020000 0ustar liggesusers> # Default (interactive) > cat_line(default_interactive) Error: Error message Run `rlang::last_error()` to see where the error occurred. Execution halted > # Default (non-interactive) > cat_line(default_non_interactive) Error: Error message Backtrace: x 1. \-global::f() 2. +-base::tryCatch(g()) 3. | \-base:::tryCatchList(expr, classes, parentenv, handlers) 4. \-global::g() 5. \-global::h() Execution halted > # Reminder > cat_line(reminder) Error: Error message Execution halted > # Branch > cat_line(branch) Error: Error message Backtrace: 1. global::f() 4. global::g() 5. global::h() Execution halted > # Collapse > cat_line(collapse) Error: Error message Backtrace: x 1. \-global::f() 2. +-[ base::tryCatch(...) ] with 1 more call 4. \-global::g() 5. \-global::h() Execution halted > # Full > cat_line(full) Error: Error message Backtrace: x 1. \-global::f() 2. +-base::tryCatch(g()) 3. | \-base:::tryCatchList(expr, classes, parentenv, handlers) 4. \-global::g() 5. \-global::h() Execution halted > # Rethrown (interactive) > cat_line(rethrown_interactive) Error: Error message Run `rlang::last_error()` to see where the error occurred. Execution halted > # Rethrown (non-interactive) > cat_line(rethrown_non_interactive) Error: Error message Backtrace: x 1. +-base::tryCatch(f(), error = function(cnd) rlang::cnd_signal(cnd)) 2. | \-base:::tryCatchList(expr, classes, parentenv, handlers) 3. | \-base:::tryCatchOne(expr, names, parentenv, handlers[[1L]]) 4. | \-base:::doTryCatch(return(expr), name, parentenv, handler) 5. \-global::f() 6. +-base::tryCatch(g()) 7. | \-base:::tryCatchList(expr, classes, parentenv, handlers) 8. \-global::g() 9. \-global::h() Execution halted rlang/tests/testthat/test-env.R0000644000176200001440000003471013563536242016265 0ustar liggesuserscontext("env") test_that("env_parent() returns enclosure frame by default", { enclos_env <- child_env(pkg_env("rlang")) fn <- with_env(enclos_env, function() env_parent()) expect_identical(fn(), enclos_env) }) test_that("child_env() has correct parent", { env <- child_env(empty_env()) expect_false(env_has(env, "list", inherit = TRUE)) fn <- function() list(new = child_env(current_env()), env = environment()) out <- fn() expect_identical(env_parent(out$new), out$env) expect_identical(env_parent(child_env(NULL)), empty_env()) expect_identical(env_parent(child_env("base")), base_env()) }) test_that("env_parent() reports correct parent", { env <- child_env(child_env(NULL, obj = "b"), obj = "a") expect_identical(env_parent(env, 1)$obj, "b") expect_identical(env_parent(env, 2), empty_env()) expect_error(env_parent(env, 3), "empty environment has no parent") }) test_that("env_tail() climbs env chain", { expect_identical(env_tail(global_env()), base_env()) }) test_that("env_tail() stops at the global env", { tail <- env(global_env()) env <- env(tail) expect_reference(env_tail(env), tail) }) test_that("with_env() evaluates within correct environment", { fn <- function() { g(current_env()) "normal return" } g <- function(env) { with_env(env, return("early return")) } expect_equal(fn(), "early return") }) test_that("locally() evaluates within correct environment", { env <- child_env("rlang") local_env <- with_env(env, locally(current_env())) expect_identical(env_parent(local_env), env) }) test_that("as_environment() dispatches correctly", { expect_identical(as_environment("base"), base_env()) expect_false(env_has(as_environment(set_names(letters)), "map")) expect_identical(as_environment(NULL), empty_env()) expect_true(all(env_has(as_environment(mtcars), names(mtcars)))) expect_identical(env_parent(as_environment(mtcars)), empty_env()) expect_identical(env_parent(as_environment(mtcars, base_env())), base_env()) }) test_that("env_inherits() finds ancestor", { env <- env(env(current_env())) expect_true(env_inherits(env, current_env())) expect_false(env_inherits(env, ns_env("utils"))) }) test_that("env_inherits() detects empty environment", { expect_false(env_inherits(empty_env(), empty_env())) expect_true(env_inherits(env(empty_env()), empty_env())) }) test_that("env() creates child of current environment", { env <- env(a = 1, b = "foo") expect_identical(env_parent(env), current_env()) expect_identical(env$b, "foo") }) test_that("set_env() sets current env by default", { quo <- set_env(locally(~foo)) expect_identical(f_env(quo), current_env()) }) test_that("finds correct env type", { expect_identical(env_type(global_env()), "global") expect_identical(env_type(empty_env()), "empty") expect_identical(env_type(base_env()), "base") }) test_that("current_env() fails if no default", { expect_error(get_env(list()), "Can't extract an environment from a list") }) test_that("current_env() picks up default", { dft <- env() expect_identical(get_env(list(), dft), dft) expect_identical(get_env("a", dft), dft) }) test_that("with_env() handles data", { expect_identical(with_env(mtcars, cyl), mtcars$cyl) foo <- "foo" expect_identical(with_env(mtcars, foo), "foo") }) test_that("with_env() evaluates in env", { env <- env() expect_identical(with_env(env, current_env()), env) }) test_that("env_depth() counts parents", { expect_identical(env_depth(child_env(child_env(NULL))), 2L) expect_identical(env_depth(empty_env()), 0L) }) test_that("env_parents() returns all parents", { expect_identical(env_parents(empty_env()), new_environments(list())) env1 <- env(empty_env()) env2 <- env(env1) expect_identical(env_parents(env2), new_environments(list(env1, empty_env()))) }) test_that("env() doesn't partial match on env_bind()'s .env", { expect_true(all(env_has(env(.data = 1, . = 2), c(".data", ".")))) }) test_that("new_environment() creates a child of the empty env", { env <- new_environment(list(a = 1, b = 2)) expect_true(all(env_has(env, c("a", "b")))) expect_identical(env_parent(env), empty_env()) }) test_that("new_environment() accepts empty vectors", { expect_identical(length(new_environment()), 0L) expect_identical(length(new_environment(dbl())), 0L) }) test_that("env_tail() detects sentinel", { sentinel <- current_env() env <- env() descendant <- child_env(child_env(child_env(env))) expect_identical(env_tail(descendant, sentinel), env) }) test_that("as_environment() treats named strings as vectors", { env <- as_environment(c(foo = "bar")) expect_true(is_environment(env)) expect_true(env_has(env, "foo")) }) test_that("as_environment() converts character vectors", { env <- as_environment(set_names(letters)) expect_true(is_environment(env)) expect_true(all(env_has(env, letters))) }) test_that("child_env() requires named elements", { expect_error(child_env(env(), 1), "all arguments must be named") }) test_that("env() requires named elements", { expect_error(env(env(), 1), "Expected 0 or 1 unnamed arguments") }) test_that("env() and child_env() requires uniquely named elements", { expect_error(env(a = 1, a = 2), "some arguments have the same name") expect_error(child_env(env(), a = 1, a = 2), "some arguments have the same name") }) test_that("env_clone() clones an environment", { data <- list(a = 1L, b = 2L) env <- env(!!! data) clone <- env_clone(env) expect_false(is_reference(env, clone)) expect_reference(env_parent(env), env_parent(clone)) expect_identical(env_get_list(clone, c("a", "b")), data) }) test_that("friendly_env_type() returns a friendly env name", { expect_identical(friendly_env_type("global"), "the global environment") expect_identical(friendly_env_type("empty"), "the empty environment") expect_identical(friendly_env_type("base"), "the base environment") expect_identical(friendly_env_type("frame"), "a frame environment") expect_identical(friendly_env_type("local"), "a local environment") }) test_that("new_environment() accepts optional parent", { env <- new_environment(parent = base_env()) expect_reference(env_parent(env), base_env()) }) test_that("env() accepts one unnamed argument to specify parent", { env <- env(base_env()) expect_reference(env_parent(env), base_env()) env <- env(global_env(), a = 1) expect_reference(env_parent(env), global_env()) expect_identical(env_names(env), "a") }) test_that("env_parents() stops at the global env by default", { env <- env(env(global_env())) expect_identical(env_parents(env), new_environments(list(env_parent(env), global_env()))) rlang_parents <- env_parents(ns_env("rlang")) expected <- list(`namespace:base` = ns_env("base"), global = global_env()) expect_identical(unclass(rlang_parents[2:3]), expected) }) test_that("env_parents() always stops at the empty env", { expect_identical(env_parents(empty_env()), new_environments(list())) expect_identical(env_parents(pkg_env("base")), new_environments(list(empty_env()))) }) test_that("env_parents() stops at the sentinel if supplied", { expect_reference(last(env_parents(pkg_env("utils"))), empty_env()) expect_reference(last(env_parents(pkg_env("utils"), base_env())), base_env()) }) test_that("env_parents() returns a named list", { env <- env(structure(env(base_env()), name = "foobar")) expect_identical(names(env_parents(env)), c("foobar", "package:base", "empty")) }) test_that("can lock environments", { env <- env() expect_false(env_is_locked(env)) expect_false(env_lock(env)) expect_true(env_is_locked(env)) expect_true(env_lock(env)) }) test_that("can unlock environments", { env <- env() env_lock(env) expect_true(env_unlock(env)) expect_false(env_is_locked(env)) expect_no_error(env_bind(env, a = 1)) }) test_that("env_print() has flexible input", { # because it's primarily used interactively f <- function() 1 expect_output(env_print(f), "environment: ") }) test_that("active and promise bindings are pretty-printed", { env <- env() env_bind_lazy(env, a = "foo") env_bind_active(env, b = ~"foo") expect_output(env_print(env), "a: .*b: ") }) test_that("locked environments are pretty-printed", { env <- env() expect_output(env_print(env), sprintf("\n", sexp_address(env))) env_lock(env) expect_output(env_print(env), sprintf(" \\[L\\]\n", sexp_address(env))) }) test_that("locked bindings are pretty-printed", { env <- env(a = 1, b = 2) env_binding_lock(env, "a") expect_output(env_print(env), "a: \\[L\\].*b: ") }) test_that("large environments are truncated", { n_truncated <- length(env_names(base_env())) - 20L expected <- sprintf("\\.\\.\\. with %s more bindings", n_truncated) expect_output(env_print(base_env()), expected) }) test_that("special names are backticked", { env <- env(`<-` = 1, `:` = 2) expect_output(env_print(env), "`:`:") expect_output(env_print(env), "`<-`:") }) test_that("empty environment is pretty printed", { expect_output(env_print(empty_env()), "\nparent: NULL$") }) test_that("envs printer: padding is added to right-align indices", { x <- c(rep(list(empty_env()), 9L), global_env()) x <- new_environments(x) expect_output(print(x), "^ \\[\\[1\\]\\]") expect_output(print(x), "\n\\[\\[10\\]\\]") }) test_that("envs printer: name tag is added to named elements", { x <- list(empty_env(), env(), empty_env()) x <- new_environments(x) expect_output(print(x), "[[1]] $ <", fixed = TRUE) expect_output(print(x), "\n[[2]] <", fixed = TRUE) expect_output(print(x), "\n[[3]] $ <", fixed = TRUE) }) test_that("envs printer: no name tag if no named elements", { x <- list(env(), env()) x <- new_environments(x) expect_output(print(x), "[[1]] <", fixed = TRUE) expect_output(print(x), "\n[[2]] <", fixed = TRUE) names(x) <- c("", NA) expect_output(print(x), "[[1]] <", fixed = TRUE) expect_output(print(x), "\n[[2]] <", fixed = TRUE) }) test_that("envs printer: long lists are truncated", { x <- rep(list(empty_env()), 20L) x <- new_environments(x) expect_output(print(x), "empty>$") x <- rep(list(empty_env()), 25L) x <- new_environments(x) expect_output(print(x), "empty>\n... and 5 more environments$") }) test_that("can print environment containing missing argument", { env <- env(x = missing_arg(), y = quote(foo)) expect_output(env_print(env), "x: ") expect_output(env_print(env), "y: ") }) test_that("parent environment is printed with full header", { env <- env(global_env()) expect_output(env_print(env), "parent: ") }) test_that("environment is printed with class if any", { env <- env() out <- capture.output(env_print(env)) expect_false(any(grepl("class", out))) env <- structure(env(), class = "foo") expect_output(env_print(env), "class: foo") env <- structure(env(), class = c("foo", "bar")) expect_output(env_print(env), "class: foo, bar") }) test_that("env_clone() invokes active bindings in all R versions", { if (getRversion() >= "4.0") { skip("Until the workaround is in place") } e <- env() env_bind_active(e, foo = function() "foo") out <- env_clone(e) expect_identical(out$foo, "foo") }) test_that("env_poke_parent() pokes parent", { e <- env() env_poke_parent(e, empty_env()) expect_reference(env_parent(e), empty_env()) }) test_that("env_poke_parent() fails with namespaces, package envs, and locked envs", { expect_error(env_poke_parent(ns_env("rlang"), env()), "namespace environment") expect_error(env_poke_parent(pkg_env("rlang"), env()), "package environment") expect_error(env_poke_parent(global_env(), env()), "global") expect_error(env_poke_parent(empty_env(), env()), "empty") expect_error(env_poke_parent(base_env(), env()), "base") env <- env() env_lock(env) expect_error(env_poke_parent(env, env()), "locked environment") }) test_that("env_length() gives env length", { expect_error(env_length(1), "must be an environment") expect_identical(env_length(env()), 0L) expect_identical(env_length(env(a = "a")), 1L) }) test_that("env_clone() duplicates frame", { skip_silently("Would fail on non-GNU R") e <- new.env(hash = FALSE) e$x <- 1 c <- env_clone(e) expect_false(is_reference(env_frame(e), env_frame(c))) }) test_that("env_clone() duplicates hash table", { skip_silently("Would fail on non-GNU R") e <- env(x = 1) c <- env_clone(e) e_hash <- env_hash_table(e) c_hash <- env_hash_table(c) expect_false(is_reference(e_hash, c_hash)) i <- detect_index(e_hash, is_null, .p = is_false) expect_false(is_reference(e_hash[[i]], c_hash[[i]])) }) test_that("env_clone() increases refcounts (#621)", { e <- env(x = 1:2) c <- env_clone(e) c$x[1] <- NA expect_identical(e$x, c(1L, 2L)) expect_identical(c$x, c(NA, 2L)) }) test_that("can subset `rlang_envs` list", { envs <- new_environments(list(env(), env(), env())) out <- envs[1:2] expect_length(out, 2) expect_is(out, "rlang_envs") out <- envs[3] expect_length(out, 1) expect_is(out, "rlang_envs") }) test_that("can concatenate `rlang_envs` lists", { envs1 <- new_environments(list(env())) envs2 <- new_environments(list(env(), env())) out <- c(envs1, envs2) expect_length(out, 3) expect_is(out, "rlang_envs") }) test_that("env_name() requires an environment", { expect_error(env_name("base"), "must be an environment") }) # Lifecycle --------------------------------------------------------- test_that("env API warns with non-environments", { local_options(lifecycle_verbose_soft_deprecation = TRUE) f <- local(~foo) expect_warning(env_parent(f) <- empty_env(), "deprecated") expect_warning(env_depth(function() foo), "deprecated") expect_warning(env_poke_parent(local(~foo), empty_env()), "deprecated") expect_warning(env_parent(~foo), "deprecated") expect_warning(env_tail(~foo), "deprecated") expect_warning(set_env(~foo, ~bar), "deprecated") expect_warning(env_clone(~foo), "deprecated") expect_warning(env_inherits(~foo, empty_env()), "deprecated") expect_warning(env_bind(~foo, a = 1), "deprecated") expect_warning(local_bindings(.env = ~foo), "deprecated") expect_warning(with_bindings(NULL, a = 1, .env = ~foo), "deprecated") expect_warning(env_poke(~foo, "a", NULL), "deprecated") expect_warning(env_has(~foo, "a"), "deprecated") expect_warning(env_get(~foo, "a"), "deprecated") expect_warning(env_names(~foo), "deprecated") expect_warning(env_bind_lazy(~foo, foo = list()), "deprecated") expect_warning(env_bind_active(~foo, a = function() "foo"), "deprecated") }) rlang/tests/testthat/test-parse.R0000644000176200001440000000312713563536060016603 0ustar liggesuserscontext("parse") test_that("parse_quo() etc return quosures", { expect_identical(parse_quo("foo(bar)", "base"), set_env(quo(foo(bar)), base_env())) expect_identical(parse_quos("foo(bar)\n mtcars", "base"), new_quosures(list(set_env(quo(foo(bar)), base_env()), set_env(quo(mtcars), base_env())))) }) test_that("parse_quosure() and parse_quosures() are deprecated", { local_lifecycle_warnings() expect_warning(parse_quosure("foo"), "deprecated") expect_warning(parse_quosures("foo; bar"), "deprecated") }) test_that("temporary connections are closed", { path <- tempfile("file") cat("1; 2; mtcars", file = path) conn <- file(path) parse_exprs(conn) expect_error(summary(conn), "invalid connection") }) test_that("parse_expr() throws meaningful error messages", { expect_error(parse_expr(""), "No expression to parse") expect_error(parse_expr("foo; bar"), "More than one expression parsed") }) test_that("parse_exprs() and parse_quos() handle character vectors", { exprs <- parse_exprs(c("foo; bar", "baz")) attributes(exprs) <- NULL # For srcrefs expect_identical(exprs, unname(exprs(foo, bar, baz))) quos <- parse_quos(c("foo; bar", "baz"), current_env()) expect_identical(quos, quos(foo, bar, baz)) }) test_that("parse_exprs() requires connections or character vectors", { expect_error(parse_exprs(env()), "must be a character vector or an R connection") }) test_that("parse_exprs() and parse_quos() support empty input", { expect_identical(zap_srcref_attributes(parse_exprs(chr())), list()) expect_identical(zap_srcref_attributes(parse_quos(chr(), env())), quos_list()) }) rlang/tests/testthat/test-trace-call-car-promise.txt0000644000176200001440000000032713612375027022333 0ustar liggesusersFull: â–ˆ 1. ├─base::print(foo) 2. └─rlang:::print.foo(foo) Collapsed: â–ˆ 1. ├─[ base::print(...) ] 2. └─rlang:::print.foo(foo) Branch: 1. base::print(foo) 2. rlang:::print.foo(foo) rlang/tests/testthat/test-types.R0000644000176200001440000001132413504161362016625 0ustar liggesuserscontext("types") test_that("predicates match definitions", { expect_true(is_character(letters, 26)) expect_false(is_character(letters, 1)) expect_false(is_list(letters, 26)) expect_true(is_list(mtcars, 11)) expect_false(is_list(mtcars, 0)) expect_false(is_double(mtcars, 11)) }) test_that("can bypass string serialisation", { bar <- chr(list("cafe", string(c(0x63, 0x61, 0x66, 0xE9)))) Encoding(bar) <- "latin1" bytes <- list(bytes(c(0x63, 0x61, 0x66, 0x65)), bytes(c(0x63, 0x61, 0x66, 0xE9))) expect_identical(map(bar, as_bytes), bytes) expect_identical(Encoding(bar[[2]]), "latin1") }) test_that("types are friendly", { expect_identical(friendly_type("character"), "a character vector") expect_identical(friendly_type("integer"), "an integer vector") expect_identical(friendly_type("language"), "a call") }) test_that("friendly_type_of() supports objects", { expect_identical(friendly_type_of(mtcars), "a `data.frame` object") expect_identical(friendly_type_of(quo(1)), "a `quosure/formula` object") }) test_that("is_integerish() heeds type requirement", { for (n in 0:2) { expect_true(is_integerish(integer(n))) expect_true(is_integerish(double(n))) expect_false(is_integerish(double(n + 1) + .000001)) } types <- c("logical", "complex", "character", "expression", "list", "raw") for (type in types) { expect_false(is_integerish(vector(type))) } }) test_that("is_integerish() heeds length requirement", { for (n in 0:2) { expect_true(is_integerish(double(n), n = n)) expect_false(is_integerish(double(n), n = n + 1)) } }) test_that("non finite double values are integerish", { expect_true(is_integerish(dbl(1, Inf, -Inf, NaN), finite = NULL)) expect_true(is_integerish(dbl(1, NA))) expect_true(is_integerish(int(1, NA))) }) test_that("is_finite handles numeric types", { expect_true(is_finite(1L)) expect_false(is_finite(na_int)) expect_true(is_finite(1)) expect_false(is_finite(na_dbl)) expect_false(is_finite(Inf)) expect_false(is_finite(-Inf)) expect_false(is_finite(NaN)) expect_false(is_finite(c(1, 2, NaN))) # Should we upcoerce later on? expect_error(expect_false(is_finite(NA)), "expected a numeric vector") expect_true(is_finite(0i)) expect_false(is_finite(complex(real = NA))) expect_false(is_finite(complex(imaginary = Inf))) }) test_that("check finiteness", { expect_true( is_double(dbl(1, 2), finite = TRUE)) expect_true(is_integerish(dbl(1, 2), finite = TRUE)) expect_false( is_double(dbl(1, 2), finite = FALSE)) expect_false(is_integerish(dbl(1, 2), finite = FALSE)) expect_false( is_double(dbl(1, Inf), finite = TRUE)) expect_false(is_integerish(dbl(1, Inf), finite = TRUE)) expect_true( is_double(dbl(1, Inf), finite = FALSE)) expect_true(is_integerish(dbl(1, Inf), finite = FALSE)) expect_true( is_double(dbl(-Inf, Inf), finite = FALSE)) expect_true(is_integerish(dbl(-Inf, Inf), finite = FALSE)) }) test_that("scalar predicates heed type and length", { expect_true_false <- function(pred, pass, fail_len, fail_type) { expect_true(pred(pass)) expect_false(pred(fail_len)) expect_false(pred(fail_type)) } expect_true_false(is_scalar_list, list(1), list(1, 2), logical(1)) expect_true_false(is_scalar_atomic, logical(1), logical(2), list(1)) expect_true_false(is_scalar_vector, list(1), list(1, 2), quote(x)) expect_true_false(is_scalar_vector, logical(1), logical(2), function() {}) expect_true_false(is_scalar_integer, integer(1), integer(2), double(1)) expect_true_false(is_scalar_double, double(1), double(2), integer(1)) expect_true_false(is_scalar_character, character(1), character(2), logical(1)) expect_true_false(is_string, character(1), character(2), logical(1)) expect_true_false(is_scalar_logical, logical(1), logical(2), character(1)) expect_true_false(is_scalar_raw, raw(1), raw(2), NULL) expect_true_false(is_scalar_bytes, raw(1), raw(2), NULL) }) test_that("is_integerish() supports large numbers (#578)", { expect_true(is_integerish(1e10)) expect_true(is_integerish(2^52)) expect_false(is_integerish(2^52 + 1)) expect_false(is_integerish(2^50 - 0.1)) expect_false(is_integerish(2^49 - 0.05)) expect_false(is_integerish(2^40 - 0.0001)) }) test_that("is_string() matches on string", { expect_true(is_string("foo")) expect_true(is_string("foo", "foo")) expect_false(is_string("foo", "bar")) expect_false(is_string(NA, NA)) expect_true(is_string("foo", c("foo", "bar"))) expect_true(is_string("foo", c("bar", "foo"))) expect_false(is_string("foo", c("bar", "baz"))) }) test_that("is_bool() checks for single `TRUE` or `FALSE`", { expect_true(is_bool(TRUE)) expect_true(is_bool(FALSE)) expect_false(is_bool(NA)) expect_false(is_bool(c(TRUE, FALSE))) }) rlang/tests/testthat/test-node.R0000644000176200001440000000674413563536242016430 0ustar liggesuserscontext("node") test_that("node() creates a pairlist node", { x <- new_node("foo", "bar") expect_is(x, "pairlist") expect_identical(node_car(x), "foo") expect_identical(node_cdr(x), "bar") }) test_that("node getters and pokers work", { A <- as.pairlist(c(a = "a", b = "b")) B <- as.pairlist(c(A = "A", B = "B")) x <- pairlist(foo = A, bar = B, baz = "baz") expect_identical(node_car(x), A) expect_identical(node_cdr(x), pairlist(bar = B, baz = "baz")) expect_identical(node_caar(x), "a") expect_identical(node_cadr(x), B) expect_identical(node_cdar(x), pairlist(b = "b")) expect_identical(node_cddr(x), pairlist(baz = "baz")) expect_identical(node_tag(x), sym("foo")) node_poke_car(x, B) expect_identical(node_car(x), B) node_poke_cdr(x, pairlist(foo = A)) expect_identical(node_cdr(x), pairlist(foo = A)) node_poke_cdar(x, "cdar") expect_identical(node_cdar(x), "cdar") node_poke_caar(x, "caar") expect_identical(node_caar(x), "caar") node_poke_cadr(x, "cadr") expect_identical(node_cadr(x), "cadr") node_poke_cddr(x, "cddr") expect_identical(node_cddr(x), "cddr") node_poke_tag(x, sym("tag")) expect_identical(node_tag(x), sym("tag")) }) test_that("node_tree_clone() clones all nodes", { x <- pairlist(1, pairlist(2)) clone <- node_tree_clone(x) # Outer vector expect_false(sexp_address(x) == sexp_address(clone)) # Outer node list expect_true(sexp_address(node_car(x)) == sexp_address(node_car(clone))) cdr <- node_cdr(x) clone_cdr <- node_cdr(clone) expect_false(sexp_address(cdr) == sexp_address(clone_cdr)) # Inner node list cadr <- node_car(cdr) clone_cadr <- node_car(clone_cdr) expect_false(sexp_address(cadr) == sexp_address(clone_cadr)) # Inner vector caadr <- node_car(cadr) clone_caadr <- node_car(clone_cadr) expect_true(sexp_address(caadr) == sexp_address(clone_caadr)) }) test_that("as_pairlist() converts to pairlist", { expect_identical(as_pairlist(letters), as.pairlist(letters)) expect_error(as_pairlist(quote(foo)), "Can't convert a symbol to a pairlist node") expect_identical(as_pairlist(NULL), NULL) x <- pairlist(1, 2) expect_identical(as_pairlist(x), x) }) test_that("pairlist predicates detect pairlists", { node <- new_node(NULL) call <- quote(foo(bar)) expect_true(is_pairlist(node)) expect_true(is_node(node)) expect_true(is_node(call)) expect_true(is_node_list(node)) expect_true(is_node_list(NULL)) }) test_that("pairlist2() converts to pairlist", { expect_identical_(pairlist2(1, !!!c(2, 3), 4), pairlist(1, 2, 3, 4)) expect_identical_(pairlist2(1, !!!mtcars[1:2], 4), pairlist(1, mpg = mtcars$mpg, cyl = mtcars$cyl, 4)) local_bindings(.env = global_env(), as.list.rlang_foobar = function(x) list("foo", "bar") ) foobar <- structure(NA, class = "rlang_foobar") expect_identical_(pairlist2(1, !!!foobar, 4), pairlist(1, "foo", "bar", 4)) }) test_that("pairlist2() duplicates spliced pairlists", { x <- pairlist("foo", "bar") pairlist2(1, !!!x, 4) expect_identical(x, pairlist("foo", "bar")) }) test_that("pairlist2() preserves empty arguments", { expect_identical(pairlist2(1, x = , , 4), pairlist(1, x = missing_arg(), missing_arg(), 4)) }) test_that("pairlist2() supports splice boxes", { expect_identical(pairlist2(1, splice(list("foo", "bar")), 4), pairlist(1, "foo", "bar", 4)) }) test_that("pairlist2() supports empty spliced vectors", { expect_null_(pairlist2(!!!NULL)) expect_null_(pairlist2(!!!lgl())) expect_null_(pairlist2(!!!list())) }) rlang/tests/testthat/helper-rlang.R0000644000176200001440000000202413612347726017073 0ustar liggesusers zap_attributes <- function(x) { attributes(x) <- NULL x } zap_srcref_attributes <- function(x) { attr(x, "srcref") <- NULL attr(x, "srcfile") <- NULL attr(x, "wholeSrcref") <- NULL x } run_script <- function(file, envvars = chr()) { skip_on_os("windows") # Suppress non-zero exit warnings suppressWarnings(system2( file.path(R.home("bin"), "Rscript"), c("--vanilla", file), stdout = TRUE, stderr = TRUE, env = envvars )) } local_methods <- function(..., .frame = caller_env()) { local_bindings(..., .env = global_env(), .frame = .frame) } with_methods <- function(.expr, ...) { local_methods(...) .expr } # Some backtrace tests use Rscript, which requires the last version of # the backtrace code to be installed locally skip_if_stale_backtrace <- local({ current_backtrace_ver <- "1.0.0" ver <- system.file("backtrace-ver", package = "rlang") has_stale_backtrace <- ver == "" || !identical(readLines(ver), current_backtrace_ver) function() { skip_if(has_stale_backtrace) } }) rlang/tests/testthat/output-cnd-abort-trace-reminder.txt0000644000176200001440000000145013612375012023226 0ustar liggesusers> # Normal case > print(err) foo Backtrace: 1. rlang::catch_cnd(f()) 8. rlang:::f() 9. rlang:::g() 10. rlang:::h() > # From `last_error()` > print(last_error()) foo Backtrace: 1. rlang::catch_cnd(f()) 8. rlang:::f() 9. rlang:::g() 10. rlang:::h() Run `rlang::last_trace()` to see the full context. > # Saved from `last_error()` > saved <- last_error() > print(saved) foo Backtrace: 1. rlang::catch_cnd(f()) 8. rlang:::f() 9. rlang:::g() 10. rlang:::h() Run `rlang::last_trace()` to see the full context. > # Saved from `last_error()`, but no longer last > last_error_env$cnd <- error_cnd("foo") > print(saved) foo Backtrace: 1. rlang::catch_cnd(f()) 8. rlang:::f() 9. rlang:::g() 10. rlang:::h() rlang/tests/testthat/test-trace-print.txt0000644000176200001440000000034113612375026020330 0ustar liggesusers â–ˆ 1. └─rlang:::i() testthat/test-trace.R:22:2 2. └─rlang:::j(i) testthat/test-trace.R:15:7 3. └─rlang:::k(i) testthat/test-trace.R:16:21 4. └─rlang:::l(i) testthat/test-trace.R:19:4 â–ˆ rlang/tests/testthat/test-cnd-error.R0000644000176200001440000000721313612346744017367 0ustar liggesuserscontext("cnd-error") test_that("error_cnd() checks its fields", { expect_no_error(error_cnd(trace = NULL)) expect_error(error_cnd(trace = env()), "`trace` must be NULL or an rlang backtrace") expect_no_error(error_cnd(parent = NULL)) expect_error(error_cnd(parent = env()), "`parent` must be NULL or a condition object") }) test_that("can use conditionMessage() method in subclasses of rlang errors", { skip_unless_utf8() skip_if_stale_backtrace() run_error_script <- function(envvars = chr()) { run_script( test_path("fixtures", "error-backtrace-conditionMessage.R"), envvars = envvars ) } non_interactive <- run_error_script() interactive <- run_error_script(envvars = "rlang_interactive=true") verify_output(test_path("test-cnd-error-conditionMessage.txt"), { "Interactive" cat_line(interactive) "Non-interactive" cat_line(non_interactive) }) }) test_that("rlang_error.print() calls conditionMessage() method", { local_bindings(.env = global_env(), conditionMessage.foobar = function(c) c$foobar_msg ) local_options( rlang_trace_format_srcrefs = FALSE, rlang_trace_top_env = current_env() ) f <- function() g() g <- function() h() h <- function() abort("", "foobar", foobar_msg = "Low-level message") # Handled error err <- catch_cnd(f()) verify_output(test_path("test-error-print-conditionMessage.txt"), print(err)) }) test_that("error is printed with parent backtrace", { skip_unless_utf8() # Test low-level error can use conditionMessage() local_bindings(.env = global_env(), conditionMessage.foobar = function(c) c$foobar_msg ) f <- function() g() g <- function() h() h <- function() abort("", "foobar", foobar_msg = "Low-level message") a <- function() b() b <- function() c() c <- function() { tryCatch( f(), error = function(err) { abort("High-level message", parent = err) } ) } local_options( rlang_trace_format_srcrefs = FALSE, rlang_trace_top_env = current_env(), rlang_backtrace_on_error = "none" ) err <- catch_cnd(a()) err_force <- with_options( catch_cnd(a()), `rlang:::force_unhandled_error` = TRUE ) expect_known_output(file = test_path("test-cnd-error-parent-default.txt"), { print(err) print(err_force) }) expect_known_output(file = test_path("test-cnd-error-parent-full.txt"), { print(err, simplify = "none") }) expect_known_trace_output(err, file = "test-cnd-error-parent-trace.txt") }) test_that("summary.rlang_error() prints full backtrace", { skip_unless_utf8() local_options( rlang_trace_top_env = current_env(), rlang_trace_format_srcrefs = FALSE ) f <- function() tryCatch(g()) g <- function() h() h <- function() abort("The low-level error message", foo = "foo") handler <- function(c) { abort("The high-level error message", parent = c) } a <- function() tryCatch(b()) b <- function() c() c <- function() tryCatch(f(), error = handler) err <- catch_cnd(a()) expect_known_output(file = test_path("test-cnd-error-str.txt"), summary(err)) }) test_that("can take the str() of an rlang error (#615)", { err <- catch_cnd(abort("foo")) expect_output(expect_no_error(str(err))) }) test_that("don't print message or backtrace fields if empty", { err <- error_cnd("foo", message = "") expect_known_output(print(err), test_path("test-cnd-error-print-no-message.txt")) }) test_that("base parent errors are printed with rlang method", { base_err <- simpleError("foo") rlang_err <- error_cnd("bar", message = "", parent = base_err) expect_known_output(print(rlang_err), test_path("test-cnd-error-print-base-parent.txt")) }) rlang/tests/testthat/test-vec-squash.R0000644000176200001440000001135413610366361017547 0ustar liggesuserscontext("vec-squash") # Squashing ---------------------------------------------------------- test_that("vectors and names are squashed", { expect_identical( squash_dbl(list(a = 1e0, list(c(b = 2e1, c = 3e1), d = 4e1, list(5e2, list(e = 6e3, c(f = 7e3)))), 8e0)), c(a = 1e0, b = 2e1, c = 3e1, d = 4e1, 5e2, e = 6e3, f = 7e3, 8e0) ) }) test_that("bad outer names warn even at depth", { expect_warning(regex = "Outer names", expect_identical(squash_dbl(list(list(list(A = c(a = 1))))), c(a = 1)) ) }) test_that("lists are squashed", { expect_identical(squash(list(a = 1e0, list(c(b = 2e1, c = 3e1), d = 4e1, list(5e2, list(e = 6e3, c(f = 7e3)))), 8e0)), list(a = 1, c(b = 20, c = 30), d = 40, 500, e = 6000, c(f = 7000), 8)) }) test_that("squash_if() handles custom predicate", { is_foo <- function(x) inherits(x, "foo") || is_bare_list(x) foo <- structure(list("bar"), class = "foo") x <- list(1, list(foo, list(foo, 100))) expect_identical(squash_if(x, is_foo), list(1, "bar", "bar", 100)) }) # Flattening --------------------------------------------------------- test_that("vectors and names are flattened", { expect_identical(flatten_dbl(list(a = 1, c(b = 2), 3)), c(a = 1, b = 2, 3)) expect_identical(flatten_dbl(list(list(a = 1), list(c(b = 2)), 3)), c(a = 1, b = 2, 3)) expect_error(flatten_dbl(list(1, list(list(2)), 3)), "Can't convert") }) test_that("bad outer names warn when flattening", { expect_warning(expect_identical(flatten_dbl(list(a = c(A = 1))), c(A = 1)), "Outer names") expect_warning(expect_identical(flatten_dbl(list(a = 1, list(b = c(B = 2)))), c(a = 1, B = 2)), "Outer names") }) test_that("lists are flattened", { x <- list(1, list(2, list(3, list(4)))) expect_identical(flatten(x), list(1, 2, list(3, list(4)))) expect_identical(flatten(flatten(x)), list(1, 2, 3, list(4))) expect_identical(flatten(flatten(flatten(x))), list(1, 2, 3, 4)) expect_identical(flatten(flatten(flatten(flatten(x)))), list(1, 2, 3, 4)) }) test_that("flatten() checks type of splice box contents and coerces to list", { expect_identical(flatten(list(1L, splice(2:3))), list(1L, 2L, 3L)) }) test_that("is_spliced_bare() is TRUE for bare lists", { expect_true(is_spliced_bare(list())) }) test_that("flatten_if() handles custom predicate", { obj <- structure(list(1:2), class = "foo") x <- list(obj, splice(obj), unclass(obj)) expect_identical(flatten_if(x), list(obj, obj[[1]], unclass(obj))) expect_identical(flatten_if(x, is_bare_list), list(obj, splice(obj), obj[[1]])) pred <- function(x) is_bare_list(x) || is_spliced(x) expect_identical(flatten_if(x, pred), list(obj, obj[[1]], obj[[1]])) }) test_that("flatten_if() handles external pointers", { obj <- structure(list(1:2), class = "foo") x <- list(obj, splice(obj), unclass(obj)) expect_identical(flatten_if(x, rlang_test_is_spliceable), list(obj[[1]], splice(obj), unclass(obj))) ptr <- rlang_test_is_spliceable[[1]] expect_identical(flatten_if(x, ptr), list(obj[[1]], splice(obj), unclass(obj))) expect_is(rlang_test_is_spliceable, "fn_pointer") }) test_that("flatten() splices names", { expect_warning(regexp = "Outer names", expect_identical( flatten(list(a = list(A = TRUE), b = list(B = FALSE))) , list(A = TRUE, B = FALSE) ) ) expect_warning(regexp = "Outer names", expect_identical( flatten(list(a = list(TRUE), b = list(FALSE))) , list(TRUE, FALSE) ) ) }) test_that("typed flatten return typed vectors", { x <- list(list(TRUE), list(FALSE)) expect_identical(flatten_lgl(x), lgl(TRUE, FALSE)) expect_identical(flatten_int(x), int(TRUE, FALSE)) expect_identical(flatten_dbl(x), dbl(TRUE, FALSE)) expect_identical(flatten_cpl(x), cpl(TRUE, FALSE)) x <- list(list("foo"), list("bar")) expect_identical(flatten_chr(x), chr("foo", "bar")) x <- list(bytes(0L), bytes(1L)) expect_identical(flatten_raw(x), as.raw(0:1)) }) test_that("typed squash return typed vectors", { x <- list(list(list(TRUE)), list(list(FALSE))) expect_identical(squash_lgl(x), lgl(TRUE, FALSE)) expect_identical(squash_int(x), int(TRUE, FALSE)) expect_identical(squash_dbl(x), dbl(TRUE, FALSE)) expect_identical(squash_cpl(x), cpl(TRUE, FALSE)) x <- list(list(list("foo")), list(list("bar"))) expect_identical(squash_chr(x), chr("foo", "bar")) x <- list(list(bytes(0L)), list(bytes(1L))) expect_identical(squash_raw(x), as.raw(0:1)) }) test_that("flatten_if() and squash_if() handle primitive functions", { expect_identical(flatten_if(list(list(1), 2), is.list), list(1, 2)) expect_identical(squash_if(list(list(list(1)), 2), is.list), list(1, 2)) }) test_that("only lists can be flattened (#868, #885)", { expect_error(flatten(1), "Only lists") expect_error(flatten_if(list(1), function(x) TRUE), "Only lists") }) rlang/tests/testthat/test-quo.R0000644000176200001440000002167013563536104016277 0ustar liggesuserscontext("quo") test_that("quo_get_expr() and quo_get_env() retrieve quosure components", { quo <- quo(foo) expect_identical(quo_get_expr(quo), quote(foo)) expect_identical(quo_get_env(quo), environment()) }) test_that("quo_set_expr() and quo_set_env() set quosure components", { orig <- quo() env <- env() quo <- quo_set_expr(orig, quote(foo)) expect_identical(quo_get_expr(quo), quote(foo)) expect_identical(quo_get_expr(orig), missing_arg()) quo <- quo_set_env(orig, env) expect_identical(quo_get_env(quo), env) expect_identical(quo_get_env(orig), empty_env()) }) test_that("quosure getters and setters check inputs", { expect_error(quo_get_expr(10L), "`quo` must be a quosure") expect_error(quo_set_expr(10L, NULL), "`quo` must be a quosure") expect_error(quo_get_env(10L), "`quo` must be a quosure") expect_error(quo_set_env(10L, env()), "`quo` must be a quosure") expect_error(quo_set_env(quo(), 10L), "`env` must be an environment") }) test_that("generic getters work on quosures", { expect_identical(get_expr(quo(foo)), quote(foo)) expect_identical(get_env(quo(foo)), environment()) }) test_that("generic setters work on quosures", { orig <- quo() env <- env() quo <- set_env(set_expr(orig, quote(foo)), env) expect_identical(quo_get_expr(quo), quote(foo)) expect_identical(quo_get_env(quo), env) }) test_that("can flatten empty quosure", { expect_identical(quo_squash(quo()), missing_arg()) }) test_that("new_quosure() checks inputs", { expect_error(new_quosure(quote(a), env = list()), "must be an environment") }) test_that("new_quosure() produces expected internal structure", { quo <- new_quosure(quote(abc)) expect_identical(structure(~abc, class = c("quosure", "formula")), quo) }) test_that("new_quosure() double wraps", { quo1 <- quo(foo) quo2 <- new_quosure(quo1) expect_identical(quo_get_expr(quo2), quo1) }) test_that("as_quosure() uses correct env", { fn <- function(expr, env = caller_env()) { f <- as_quosure(expr, env) list(env = current_env(), quo = g(f)) } g <- function(expr, env = caller_env()) { as_quosure(expr, env) } quo_env <- child_env(NULL) quo <- new_quosure(quote(expr), quo_env) out_expr_default <- fn(quote(expr)) out_quo_default <- fn(quo) expect_identical(quo_get_env(out_expr_default$quo), current_env()) expect_identical(quo_get_env(out_quo_default$quo), quo_env) user_env <- child_env(NULL) out_expr <- fn(quote(expr), user_env) out_quo <- fn(quo, user_env) expect_identical(quo_get_env(out_expr$quo), user_env) expect_identical(out_quo$quo, quo) }) test_that("explicit promise makes a formula", { capture <- function(x) enquo(x) f1 <- capture(1 + 2 + 3) f2 <- ~ 1 + 2 + 3 expect_equal(f1, f2) }) test_that("explicit promise works only one level deep", { f <- function(x) list(env = current_env(), f = g(x)) g <- function(y) enquo(y) out <- f(1 + 2 + 3) expected_f <- with_env(out$env, quo(x)) expect_identical(out$f, expected_f) }) test_that("can capture optimised constants", { arg <- function() { quo("foobar") } arg_bytecode <- compiler::cmpfun(arg) expect_identical(arg(), quo("foobar")) expect_identical(arg_bytecode(), quo("foobar")) dots <- function() { quos("foo", "bar") } dots_bytecode <- compiler::cmpfun(dots) expect_identical(dots(), quos("foo", "bar")) expect_identical(dots_bytecode(), quos("foo", "bar")) }) test_that("quosures are spliced", { q <- quo(foo(!! quo(bar), !! quo(baz(!! quo(baz), 3)))) expect_identical(quo_text(q), "foo(bar, baz(baz, 3))") q <- expr_interp(~foo::bar(!! function(x) ...)) expect_identical(f_text(q), "foo::bar(function (x) \n...)") q <- quo(!! quo(!! quo(foo(!! quo(!! quo(bar(!! quo(!! quo(!! quo(baz)))))))))) expect_identical(quo_text(q), "foo(bar(baz))") }) test_that("formulas are not spliced", { expect_identical(quo_text(quo(~foo(~bar))), "~foo(~bar)") }) test_that("splicing does not affect original quosure", { f <- ~foo(~bar) quo_text(f) expect_identical(f, ~foo(~bar)) }) test_that("as_quosure() doesn't convert functions", { expect_identical(as_quosure(base::mean), set_env(quo(!! base::mean), empty_env())) }) test_that("as_quosure() coerces formulas", { expect_identical(as_quosure(~foo), quo(foo)) }) test_that("quo_squash() warns", { expect_warning(regex = NA, quo_squash(quo(foo), warn = TRUE)) expect_warning(quo_squash(quo(list(!! quo(foo))), warn = TRUE), "inner quosure") }) test_that("quo_deparse() indicates quosures with `^`", { x <- quo(list(!! quo(NULL), !! quo(foo()))) ctxt <- new_quo_deparser(crayon = FALSE) expect_identical(quo_deparse(x, ctxt), "^list(^NULL, ^foo())") }) test_that("quosure deparser respects width", { x <- quo(foo(quo(!!quo(bar)))) expect_identical(length(quo_deparse(x, new_quo_deparser(width = 8L))), 3L) expect_identical(length(quo_deparse(x, new_quo_deparser(width = 9L))), 2L) }) test_that("quosure predicates work", { expect_true(quo_is_missing(quo())) expect_true(quo_is_symbol(quo(sym), "sym")) expect_false(quo_is_symbol(quo(sym), "foo")) expect_true(quo_is_call(quo(call()))) expect_true(quo_is_call(quo(ns::call()), "call", 0L, "ns")) expect_false(quo_is_call(quo(ns::call()), "call", 1L, "ns")) expect_true(quo_is_symbolic(quo(sym))) expect_true(quo_is_symbolic(quo(call()))) expect_true(quo_is_null(quo(NULL))) expect_false(quo_is_missing(quo(10L))) expect_false(quo_is_symbol(quo(10L))) expect_false(quo_is_call(quo(10L))) expect_false(quo_is_symbolic(quo(10L))) expect_false(quo_is_symbolic(quo(10L))) expect_false(quo_is_null(quo(10L))) }) test_that("new_quosures() checks that elements are quosures", { expect_error(new_quosures(list(1)), "list of quosures") }) test_that("new_quosures() and as_quosures() return named lists", { exp <- structure(list(), names = chr(), class = "quosures") expect_identical(new_quosures(list()), exp) expect_identical(as_quosures(list()), exp) }) test_that("as_quosures() applies default environment", { out <- as_quosures(list(quote(foo), quote(bar)), env = base_env()) exp <- quos_list(new_quosure(quote(foo), base_env()), new_quosure(quote(bar), base_env())) expect_identical(out, exp) }) test_that("as_quosures() auto-names if requested", { x <- list(quote(foo), quote(bar)) expect_named(as_quosures(x, global_env(), named = TRUE), c("foo", "bar")) }) test_that("quosures class has subset assign methods", { local_options(lifecycle_verbose_soft_deprecation = TRUE) x <- quos(1, 2) x[1:2] <- list(quo(3), quo(4)) expect_identical(x, quos(3, 4)) expect_warning(x[2] <- list(4), "deprecated") ## expect_error(x[2] <- list(4), "Can't assign a double vector to a list of quosures") x[[2]] <- quo(10) expect_identical(x, quos(3, 10)) ## expect_error(x[[2]] <- list(4), "Can't assign a list to a list of quosures") x <- quos(foo = 1, bar = 2) x$bar <- quo(100) expect_identical(x, quos(foo = 1, bar = 100)) ## expect_error(x$foo <- list(4), "Can't assign a list to a list of quosures") }) test_that("can remove quosures by assigning NULL", { x <- quos(1, b = 2) x[[1]] <- NULL expect_identical(x, quos(b = 2)) x$b <- NULL expect_identical(x, quos()) }) test_that("can't cast a quosure to base types (#523)", { local_options(lifecycle_verbose_soft_deprecation = TRUE) expect_warning(as.character(quo(foo)), "`as.character\\(\\)` on a quosure") expect_identical(as.character(quo(foo)), c("~", "foo")) }) test_that("quosures fail with common operations (#478, tidyverse/dplyr#3476)", { q <- quo(NULL) expect_error(q + 10, "!!myquosure \\+ rhs") expect_error(q > q, "!!myquosure1 > !!myquosure2") expect_error(10 == q, "lhs == !!myquosure") expect_error(abs(q), "abs\\(!!myquosure\\)") expect_error(mean(q), "mean\\(!!myquosure\\)") expect_error(stats::median(q), "median\\(!!myquosure\\)") expect_error(stats::quantile(q), "quantile\\(!!myquosure\\)") expect_error(-q, "-!!myquosure") expect_error(-q, "+!!myquosure") }) test_that("negating quosure fails with informative message", { expect_error(!quo(), "can only be unquoted within a quasiquotation") }) test_that("can cast quosure lists to bare lists", { expect_identical(as.list(quos(a)), named_list(quo(a))) }) test_that("can concatenate quosure lists", { expect_identical(c(quos(a, b), quos(foo = c)), quos(a, b, foo = c)) }) test_that("new_quosure() checks input", { expect_error(new_quosure(NULL, NULL), "`env` must be an environment") }) test_that("as_string(quo) produces informative error message", { expect_error(as_string(quo(foo)), "a `quosure/formula` object to a string") }) # Lifecycle ---------------------------------------------------------- test_that("as_quosure() still provides default env", { local_lifecycle_warnings() quo <- expect_warning(as_quosure(quote(foo)), "explicit environment") expect_reference(quo_get_env(quo), current_env()) }) test_that("can still concatenate quosure lists and non-quosures", { local_lifecycle_silence() expect_identical(c(quos(foo), list(1)), named_list(quo(foo), 1)) }) rlang/tests/testthat/test-cnd-error-parent-full.txt0000644000176200001440000000120013612375014022212 0ustar liggesusers High-level message Backtrace: â–ˆ 1. ├─rlang::catch_cnd(a()) 2. │ ├─rlang::eval_bare(...) 3. │ ├─base::tryCatch(...) 4. │ │ └─base:::tryCatchList(expr, classes, parentenv, handlers) 5. │ │ └─base:::tryCatchOne(expr, names, parentenv, handlers[[1L]]) 6. │ │ └─base:::doTryCatch(return(expr), name, parentenv, handler) 7. │ └─base::force(expr) 8. └─rlang:::a() 9. └─rlang:::b() 10. └─rlang:::c() Low-level message Backtrace: â–ˆ 1. └─rlang:::f() 2. └─rlang:::g() 3. └─rlang:::h() rlang/tests/testthat/test-eval-tidy.R0000644000176200001440000003343213563536105017371 0ustar liggesuserscontext("eval-tidy") test_that("accepts expressions", { expect_identical(eval_tidy(10), 10) expect_identical(eval_tidy(quote(letters)), letters) }) test_that("eval_tidy uses quosure environment", { x <- 10 quo <- local({ y <- 100 quo(x + y) }) expect_equal(eval_tidy(quo), 110) }) test_that("data must be uniquely named", { expect_error(eval_tidy(NULL, list(x = 1, x = 2)), "has duplicate columns") data <- set_names(data.frame(x = 1, x = 2, y = 3, y = 4), c("x", "x", "y", "y")) expect_error(eval_tidy(NULL, data), "has duplicate columns") }) test_that("can supply unnamed empty data", { expect_identical(eval_tidy("foo", list()), "foo") expect_identical(eval_tidy("foo", data.frame()), "foo") }) test_that("looks first in `data`", { x <- 10 data <- list(x = 100) expect_equal(eval_tidy(quo(x), data), 100) }) test_that("pronouns resolve ambiguity looks first in `data`", { x <- 10 data <- list(x = 100) expect_equal(eval_tidy(quo(.data$x), data), 100) expect_equal(eval_tidy(quo(.env$x), data), 10) }) test_that("pronouns complain about missing values", { expect_data_pronoun_error(eval_tidy(quo(.data$x), list()), "Column `x` not found in `.data`") expect_data_pronoun_error(eval_tidy(quo(.data$x), data.frame()), "Column `x` not found in `.data`") }) test_that("nested quosures look in their own env", { n <- 10 f <- function() { n <- 100 quo(n) } quo <- quo(!!f()) expect_equal(eval_tidy(quo), 100) }) test_that("nested quosure thunks rechain properly in the non-data mask", { bar <- "foo" quo <- quo(identity(!!quo(toupper(!!quo(identity(bar)))))) expect_identical(eval_tidy(quo), "FOO") }) test_that("unquoted formulas can use data", { f1 <- function() { z <- 100 x <- 2 quo(x + z) } f2 <- function() { z <- 100 quo(.data$x + .env$z) } z <- 10 expect_identical(eval_tidy(f2(), list(x = 1)), 101) expect_identical(eval_tidy(quo(!! f1()), data = list(x = 1)), 101) expect_identical(eval_tidy(quo(!! f2()), data = list(x = 1)), 101) }) test_that("bare formulas are not evaluated", { f <- local(~x) expect_identical(eval_tidy(quo(!! f)), f) f <- a ~ b expect_identical(eval_tidy(quo(!! f)), f) }) test_that("quosures are not evaluated if not forced", { fn <- function(arg, force) { if (force) arg else "bar" } f1 <- quo(fn(!! quo(stop("forced!")), force = FALSE)) f2 <- quo(fn(!! local(quo(stop("forced!"))), force = FALSE)) expect_identical(eval_tidy(f1), "bar") expect_identical(eval_tidy(f2), "bar") f_forced1 <- quo(fn(!! quo(stop("forced!")), force = TRUE)) f_forced2 <- quo(fn(!! local(quo(stop("forced!"))), force = TRUE)) expect_error(eval_tidy(f_forced1), "forced!") expect_error(eval_tidy(f_forced2), "forced!") }) test_that("can unquote captured arguments", { var <- quo(cyl) fn <- function(arg) eval_tidy(enquo(arg), mtcars) expect_identical(fn(var), quo(cyl)) expect_identical(fn(!!var), mtcars$cyl) }) test_that("quosures are evaluated recursively", { foo <- "bar" expect_identical(eval_tidy(quo(foo)), "bar") expect_identical(eval_tidy(quo(!!quo(!! quo(foo)))), "bar") }) test_that("quosures have lazy semantics", { fn <- function(arg) "unforced" expect_identical(eval_tidy(quo(fn(~stop()))), "unforced") }) test_that("can unquote hygienically within captured arg", { fn <- function(df, arg) eval_tidy(enquo(arg), df) foo <- "bar"; var <- quo(foo) expect_identical(fn(mtcars, list(var, !!var)), list(quo(foo), "bar")) var <- quo(cyl) expect_identical(fn(mtcars, (!!var) > 4), mtcars$cyl > 4) expect_identical(fn(mtcars, list(var, !!var)), list(quo(cyl), mtcars$cyl)) expect_equal(fn(mtcars, list(~var, !!var)), list(~var, mtcars$cyl)) expect_equal(fn(mtcars, list(~~var, !!quo(var), !!quo(quo(var)))), list(~~var, quo(cyl), quo(var))) }) test_that("can unquote for old-style NSE functions", { var <- quo(foo) fn <- function(x) substitute(x) expect_identical(quo(fn(!!quo_get_expr(var))), quo(fn(foo))) expect_identical(eval_tidy(quo(fn(!!quo_get_expr(var)))), quote(foo)) }) test_that("all quosures in the call are evaluated", { foobar <- function(x) paste0("foo", x) x <- new_quosure(call("foobar", local({ bar <- "bar"; quo(bar) }))) f <- new_quosure(call("identity", x)) expect_identical(eval_tidy(f), "foobar") }) test_that("two-sided formulas are not treated as quosures", { expect_identical(eval_tidy(new_quosure(a ~ b)), a ~ b) }) test_that("formulas are evaluated in evaluation environment", { f <- eval_tidy(quo(foo ~ bar), list(foo = "bar")) expect_false(identical(f_env(f), current_env())) }) test_that("evaluation env is cleaned up", { f <- local(quo(function() list(f = ~letters, env = environment()))) fn <- eval_tidy(f) out <- fn() expect_identical(out$f, with_env(env = out$env, ~letters)) }) test_that("inner formulas are rechained to evaluation env", { env <- child_env(NULL) f1 <- quo(env$eval_env1 <- current_env()) f2 <- quo({ !! f1 env$eval_env2 <- current_env() }) eval_tidy(f2, mtcars) expect_identical(env$eval_env1, env$eval_env2) expect_true(env_inherits(env$eval_env2, get_env(f2))) }) test_that("empty quosure self-evaluates", { quo <- quo(is_missing(!! quo())) expect_true(eval_tidy(quo)) }) test_that("cannot replace elements of pronouns", { expect_error(eval_tidy(quo(.data$foo <- "bar"), mtcars), "Can't modify the data pronoun") }) test_that("formulas are not evaluated as quosures", { expect_identical(eval_tidy(~letters), ~letters) }) test_that("tilde calls are evaluated in overscope", { quo <- quo({ foo <- "foo" ~foo }) f <- eval_tidy(quo) expect_true(env_has(f, "foo")) }) test_that(".env pronoun refers to current quosure (#174)", { inner_quo <- local({ var <- "inner" quo(.env$var) }) outer_quo <- local({ var <- "outer" quo(identity(!! inner_quo)) }) expect_identical(eval_tidy(outer_quo, list()), "inner") }) test_that("can call tilde with named arguments (#226)", { expect_equal(eval_tidy(quote(`~`(foo = x, bar = y))), x ~ y) expect_equal(eval_tidy(quote(`~`(foo = x, bar = y, baz = z))), `~`(foo = x, bar = y, baz = z)) }) test_that("Arguments to formulas are not stripped from their attributes (#227)", { quo <- quo(x) f <- eval_tidy(quo(~!!quo)) expect_identical(f_rhs(f), quo) f <- eval_tidy(quo(!!quo(x) ~ a)) expect_identical(f_lhs(f), quo) }) test_that("evaluating an empty quosure fails", { expect_error(eval_tidy(quo()), "not found") }) test_that("can supply a data mask as data", { mask <- as_data_mask(list(x = 1L)) eval_tidy(quo(x <- 2L), mask) expect_identical(eval_tidy(quo(x), mask), 2L) }) test_that("as_data_pronoun() creates pronoun", { data <- as_data_pronoun(mtcars) expect_is(data, "rlang_data_pronoun") data_env <- .subset2(data, 1) expect_reference(env_parent(data_env), empty_env()) expect_true(all(env_names(data_env) %in% names(mtcars))) expect_data_pronoun_error(data$foobar, "Column `foobar` not found in `.data`") expect_identical(data[["cyl"]], mtcars$cyl) }) test_that("can create pronoun from a mask", { top <- env(a = 1) bottom <- env(top, b = 2) mask <- new_data_mask(bottom, top) .data <- as_data_pronoun(mask) expect_is(.data, "rlang_data_pronoun") expect_identical(.data$a, 1) expect_identical(.data$b, 2) }) test_that("pronoun has print() and str() method", { data <- as_data_pronoun(mtcars) expect_output(print(data), "") expect_output(str(data), "") data <- as_data_pronoun(list(a = 1)) expect_output(print(data), "") }) test_that("data mask can escape", { fn <- eval_tidy(quote(function() cyl), mtcars) expect_identical(fn(), mtcars$cyl) }) test_that("inner formulas are evaluated in the current frame", { quo <- quo(local(list(f_env = f_env(~foo), env = current_env()))) envs <- eval_tidy(quo) expect_identical(envs$f_env, envs$env) quo <- quo(as_function(~list(f_env = get_env(~foo), env = current_env()))()) envs <- eval_tidy(quo) expect_identical(envs$f_env, envs$env) }) test_that("names are translated to native when creating data mask", { with_latin1_locale({ str_utf8 <- "\u00fc" str_native <- enc2native(str_utf8) d <- set_names(list("value"), str_utf8) s <- sym(str_native) expect_identical(eval_tidy(s, data = d), "value") foreign_utf8 <- "\u5FCD" foreign_native <- enc2native(foreign_utf8) d <- setNames(list("value"), foreign_utf8) s <- sym(foreign_native) expect_identical(eval_tidy(s, data = d), "value") }) }) test_that("new_data_mask() checks `top` is a parent of `bottom`", { top <- env() bottom <- env(top) expect_no_error(new_data_mask(bottom, top)) expect_error(new_data_mask(top, bottom), "`top` is not a parent of `bottom`") }) test_that("data mask inherits from last environment", { mask <- new_data_mask(NULL, NULL) expect_reference(env_parent(mask), empty_env()) eval_tidy(NULL, mask) expect_reference(env_parent(mask), current_env()) env <- env() quo <- new_quosure(NULL, env) eval_tidy(quo, mask) expect_reference(env_parent(mask), env) }) test_that("is_data_pronoun() detects pronouns", { expect_true(!!is_data_pronoun(quote(.data$foo))) expect_true(!!is_data_pronoun(quote(.data[[foo]]))) expect_false(!!is_data_pronoun(quote(.data[foo]))) expect_false(!!is_data_pronoun(quote(data[[foo]]))) }) test_that("data_pronoun_name() extracts name", { expr <- quote(.data[[foo]]) expect_null(data_pronoun_name(expr)) expr <- quote(.data[[toupper("foo")]]) expect_null(data_pronoun_name(expr)) expr <- quote(`$`(.data, toupper("foo"))) expect_null(data_pronoun_name(expr)) expect_identical(data_pronoun_name(quote(.data[["foo"]])), "foo") expect_identical(data_pronoun_name(quote(.data$foo)), "foo") }) test_that(".data pronoun walks the ancestry of environments", { e <- 0 e1 <- env(a = 1, b = 1, c = 1) e2 <- env(a = 2, b = 2, e1) e3 <- env(a = 3, e2) data_mask <- new_data_mask(e3, e1) .data <- as_data_pronoun(data_mask) expect_equal(.data$a, 3) expect_equal(.data$b, 2) expect_equal(.data$c, 1) expect_data_pronoun_error(.data$d, "Column `d` not found in `.data`") expect_data_pronoun_error(.data$e, "Column `e` not found in `.data`") expect_data_pronoun_error(.data$.data, "Column `.data` not found in `.data`") expect_data_pronoun_error(.data$.env, "Column `.env` not found in `.data`") expect_data_pronoun_error(.data$.top_env, "Column `.top_env` not found in `.data`") expect_equal(.data[["a"]], 3) expect_equal(.data[["b"]], 2) expect_equal(.data[["c"]], 1) expect_data_pronoun_error(.data[["d"]], "Column `d` not found in `.data`") expect_data_pronoun_error(.data[["e"]], "Column `e` not found in `.data`") expect_data_pronoun_error(.data[[".data"]], "Column `.data` not found in `.data`") expect_data_pronoun_error(.data[[".env"]], "Column `.env` not found in `.data`") expect_data_pronoun_error(.data[[".top_env"]], "Column `.top_env` not found in `.data`") expect_error(.data["a"]) }) test_that("can inspect the exported pronoun", { expect_output(print(rlang::.data), "") }) test_that("data pronoun always skips functions", { top <- env(c = "c") bottom <- env(top, c = base::c) mask <- new_data_mask(bottom, top) .data <- as_data_pronoun(mask) expect_identical(.data$c, "c") }) test_that("leaked quosure masks are not mistaken with data masks", { local_lifecycle_silence() e <- eval_tidy(quote(current_env())) expect_no_error(eval_tidy("foo", e)) }) test_that("quosures look for data masks lexically", { out <- eval_tidy(data = mtcars, expr({ fn <- as_function(~ !!quo(cyl)) list( fn(), local(!!quo(disp)) ) })) expect_identical(out, list(mtcars$cyl, mtcars$disp)) }) test_that("can evaluate quosures created in the data mask without infloop", { quo <- eval_tidy(quote(quo(a)), list(a = "foo")) expect_identical(eval_bare(quo, quo_get_env(quo)), "foo") }) test_that("`.env` pronoun is constructed", { pronoun <- eval_tidy(quote(.env), mtcars) expect_is(pronoun, "rlang_ctxt_pronoun") expect_reference(env_parent(pronoun), current_env()) }) test_that("the `.env` pronoun is not an environment", { pronoun <- eval_tidy(quote(.env), mtcars) expect_error(length(pronoun), "Can't take the") skip_if(getRversion() < "3.2") expect_error(names(pronoun), "Can't take the") }) test_that("subsetting `.env` evaluates", { expect_error(eval_tidy(quote(.env[["cyl"]]), mtcars, env()), "not found") cyl <- "foo" expect_identical(eval_tidy(quote(.env$cyl), mtcars, env()), "foo") expect_identical(eval_tidy(quote(.env[["cyl"]]), mtcars, env()), "foo") }) test_that("mask inherits from `env` after evaluation", { flag <- env(empty_env()) mask <- new_data_mask(env()) eval_tidy(NULL, mask, flag) expect_true(env_inherits(mask, flag)) }) test_that("can't take the names() and length() of the `.data` pronoun", { pronoun <- as_data_pronoun(mtcars) expect_error(names(pronoun), "Can't take") expect_error(length(pronoun), "Can't take") }) test_that("eval_tidy() does not infloop when the quosure inherits from the mask", { mask <- as_data_mask(list(foo = 1)) quo <- new_quosure(quote(foo), mask) expect_identical(eval_tidy(quo, mask), 1) top <- env(foo = 1) bottom <- env(top) mask <- new_data_mask(bottom, top) quo <- new_quosure(quote(foo), top) expect_identical(eval_tidy(quo, mask), 1) }) # Lifecycle ---------------------------------------------------------- test_that("as_data_mask() and new_data_mask() are deprecated", { expect_defunct(as_data_mask(mtcars, env())) expect_defunct(new_data_mask(NULL, NULL, parent = env())) }) test_that("supplying environment as data is deprecated", { local_options(lifecycle_verbose_soft_deprecation = TRUE) `_x` <- "foo" expect_warning(eval_tidy("foo", current_env()), "deprecated") expect_identical(eval_tidy(quo(`_x`), current_env()), "foo") expect_error(eval_tidy(quo(`_y`), current_env()), "not found") }) rlang/tests/testthat/test-env-binding.R0000644000176200001440000002477013604123766017701 0ustar liggesuserscontext("env-binding") test_that("promises are created", { env <- child_env(NULL) env_bind_lazy(env, foo = bar <- "bar") expect_false(env_has(current_env(), "bar")) force(env$foo) expect_true(env_has(current_env(), "bar")) env_bind_lazy(env, stop = stop("forced")) expect_error(env$stop, "forced") }) test_that("env_bind_active() creates active bindings", { env <- env() env_bind_active(env, a = function() "foo") expect_identical(env$a, "foo") expect_identical(env$a, "foo") }) test_that("env_poke() returns previous value", { env <- env(env(empty_env(), bar = "bar")) expect_identical(env_poke(env, "foo", "foo"), zap()) expect_identical(env_poke(env, "foo", "FOO"), "foo") expect_identical(env_poke(env, "bar", "foo", inherit = TRUE), "bar") }) test_that("env_poke() creates binding if `create` is TRUE", { env <- new_environment() env_poke(env, "foo", "foo") expect_identical(env_get(env, "foo"), "foo") expect_error(env_poke(env, "bar", "BAR", create = FALSE), "Can't find existing binding") env_poke(env, "foo", "FOO", create = FALSE) expect_identical(env_get(env, "foo"), "FOO") }) test_that("env_poke() inherits from parents if `inherit` is TRUE", { env <- child_env(new_environment(), foo = "foo") env <- child_env(env) env_has(env, "foo") env_has(env, "foo", TRUE) env_poke(env, "foo", "FOO", inherit = TRUE, create = FALSE) expect_identical(env_get(env_parent(env), "foo", inherit = FALSE), "FOO") expect_error(env_poke(env, "bar", "bar", inherit = TRUE, create = FALSE), "Can't find existing binding") expect_error(env_poke(env, "bar", "bar", inherit = TRUE), "Can't find existing binding") env_poke(env, "bar", "bar", inherit = TRUE, create = TRUE) expect_identical(env_get(env, "bar"), "bar") }) test_that("env_get() evaluates promises and active bindings", { e <- env() env_bind_lazy(e, x = 1) env_bind_active(e, y = function() 2) expect_equal(env_get(e, "x"), 1) expect_equal(env_get(e, "y"), 2) }) test_that("env_get_list() retrieves multiple bindings", { env <- env(foo = 1L, bar = 2L) expect_identical(env_get_list(env, c("foo", "bar")), list(foo = 1L, bar =2L)) baz <- 0L expect_error(env_get_list(env, "baz"), "'baz' not found") expect_identical(env_get_list(env, c("foo", "baz"), inherit = TRUE), list(foo = 1L, baz =0L)) }) test_that("local_bindings binds temporarily", { env <- env(foo = "foo", bar = "bar") local({ old <- local_bindings(.env = env, foo = "FOO", bar = "BAR", baz = "BAZ" ) expect_identical(old, list3(foo = "foo", bar = "bar", baz = zap())) temp_bindings <- env_get_list(env, c("foo", "bar", "baz")) expect_identical(temp_bindings, list(foo = "FOO", bar = "BAR", baz = "BAZ")) }) bindings <- env_get_list(env, c("foo", "bar")) expect_identical(bindings, list(foo = "foo", bar = "bar")) expect_false(env_has(env, "baz")) }) test_that("with_bindings() evaluates with temporary bindings", { foo <- "foo" baz <- "baz" expect_identical(with_bindings(paste(foo, baz), foo = "FOO"), "FOO baz") expect_identical(foo, "foo") }) test_that("env_unbind() with `inherits = TRUE` wipes out all bindings", { bindings <- list(`_foo` = "foo", `_bar` = "bar") env_bind(global_env(), !!! bindings) env <- child_env(global_env(), !!! bindings) env_unbind(env, "_foo", inherit = TRUE) expect_false(all(env_has(env, names(bindings)))) expect_false(all(env_has(global_env(), names(bindings)))) }) test_that("env_bind() requires named elements", { expect_error(env_bind(env(), 1), "all arguments must be named") expect_error(env_bind(env(), !!! list(1)), "all arguments must be named") }) test_that("env_bind() requires uniquely named elements", { expect_error(env_bind(env(), a = 1, a = 2), "some arguments have the same name") }) test_that("env_bind() works with empty unnamed lists", { expect_no_error(env_bind(env())) expect_no_error(env_bind(env(), !!! list())) }) test_that("env_names() unserialises unicode", { env <- env(`` = "foo") expect_identical(env_names(env), "\u5E78\u798F") }) test_that("env_has() returns a named vector", { expect_identical(env_has(env(a = TRUE), c("a", "b", "c")), c(a = TRUE, b = FALSE, c = FALSE)) }) test_that("env_bind_impl() fails if data is not a vector", { expect_error(env_bind_impl(env(), env()), "must be a vector") }) test_that("env_unbind() doesn't warn if binding doesn't exist (#177)", { expect_no_warning(env_unbind(env(), c("foo", "bar"))) }) test_that("env_get() and env_get_list() accept default value", { env <- env(a = 1) expect_error(env_get(env, "b"), "not found") expect_error(env_get_list(env, "b"), "not found") expect_identical(env_get(env, "b", default = "foo"), "foo") expect_identical(env_get_list(env, c("a", "b"), default = "foo"), list(a = 1, b = "foo")) }) test_that("env_bind_active() uses as_function()", { env_bind_active(current_env(), foo = ~2 + 3) expect_identical(foo, 5) }) test_that("env_bind_active() and env_bind_lazy() redefine bindings", { env <- env(a = 1, b = 2) env_bind_active(env, a = ~"foo") env_bind_lazy(env, b = "bar") expect_identical(c(env$a, env$b), c("foo", "bar")) }) test_that("binding predicates detect special bindings", { env <- env() env_bind_active(env, a = ~toupper("foo")) env_bind_lazy(env, b = toupper("foo")) env_bind(env, c = toupper("foo"), d = "irrelevant") expect_identical(env_binding_are_active(env, c("a", "b", "c")), c(a = TRUE, b = FALSE, c = FALSE)) expect_identical(env_binding_are_lazy(env, c("a", "b", "c")), c(a = FALSE, b = TRUE, c = FALSE)) force(env$b) expect_identical(env_binding_are_lazy(env, c("a", "b", "c")), c(a = FALSE, b = FALSE, c = FALSE)) env <- env(a = 1, b = 2) expect_identical(env_binding_are_active(env), c(a = FALSE, b = FALSE)) expect_identical(env_binding_are_lazy(env), c(a = FALSE, b = FALSE)) }) test_that("applies predicates to all bindings by default", { env <- env() env_bind_active(env, a = ~toupper("foo")) env_bind_lazy(env, b = toupper("foo")) env_bind(env, c = toupper("foo")) expect_identical(env_binding_are_active(env), c(a = TRUE, b = FALSE, c = FALSE)) expect_identical(env_binding_are_lazy(env), c(a = FALSE, b = TRUE, c = FALSE)) }) test_that("env_binding_are_active() doesn't force promises", { env <- env() env_bind_lazy(env, foo = stop("kaboom")) expect_no_error(env_binding_are_active(env)) expect_identical(env_binding_are_lazy(env), lgl(foo = TRUE)) expect_identical(env_binding_are_lazy(env), lgl(foo = TRUE)) }) test_that("env_binding_type_sum() detects types", { env <- env() env_bind_active(env, a = ~"foo") env_bind_lazy(env, b = identity("foo")) env_bind(env, c = "foo", d = 1L, e = 2 ) expect_error(env_binding_type_sum(env, 1L), "must be a character vector") types <- c(a = "active", b = "lazy", c = "chr", d = "int", e = "dbl") expect_identical(env_binding_type_sum(env), types) }) test_that("can lock and unlock bindings", { env <- env(a = "A", b = "B") expect_identical(env_binding_are_locked(env), lgl(a = FALSE, b = FALSE)) expect_identical(env_binding_lock(env, "a"), lgl(a = FALSE)) locked <- env_binding_are_locked(env) expect_identical(locked, lgl(a = TRUE, b = FALSE)) expect_identical(env_binding_unlock(env), locked) expect_identical(env_binding_are_locked(env), lgl(a = FALSE, b = FALSE)) }) test_that("can pluck missing arg from environment", { env <- env(x = missing_arg()) expect_identical(env_get(env, "x"), missing_arg()) expect_identical(env_get_list(env, "x"), list(x = missing_arg())) skip("Failing") child <- env(env) env_get(child, "x", inherit = TRUE) }) test_that("can call local_bindings() and with_bindings() without arguments", { expect_no_error(local_bindings()) expect_no_error(with_bindings("foo")) }) test_that("can bind missing args", { e <- env() expect_no_error(env_bind(e, foo = )) expect_identical(e$foo, missing_arg()) args <- list(bar = expr(), baz = expr()) expect_no_error(env_bind(e, !!!args)) expect_identical(env_get_list(e, c("bar", "baz")), args) }) test_that("can remove bindings by supplying zaps", { empty <- env() expect_no_error(env_bind(empty, foo = zap())) env <- env(foo = "foo", bar = "bar") env_bind(env, foo = zap(), bar = zap()) expect_identical(env_names(env), chr()) env <- env(foo = "foo", bar = "bar") env_bind(env, !!!rep_named(c("foo", "bar"), list(zap()))) expect_identical(env_names(env), chr()) env <- env(foo = "foo", bar = "bar") env_bind_active(env, foo = zap()) expect_identical(env_names(env), "bar") env_bind_lazy(env, bar = !!zap()) expect_identical(env_names(env), chr()) env_bind(current_env(), !!!rep_named(c("foo", "bar"), list(zap()))) }) test_that("env_bind_lazy() supports quosures", { env <- env() foo <- "foo" quo <- local({ foo <- "quux" quo(paste(foo, "bar")) }) env_bind_lazy(env, x = !!quo) expect_identical(env$x, "quux bar") foo <- "FOO" expect_identical(env$x, "quux bar") }) test_that("env_bind_active() supports quosures", { env <- env() foo <- "foo" env_bind_active(env, x = quo(paste(foo, "bar"))) expect_identical(env$x, "foo bar") foo <- "FOO" expect_identical(env$x, "FOO bar") }) test_that("env_bind_lazy() supports nested quosures", { env <- env() quo <- local({ lhs <- "quux" rhs <- local({ rhs <- "hunoz"; quo(rhs) }) quo(paste(lhs, !!rhs)) }) env_bind_lazy(env, x = !!quo) expect_identical(env$x, "quux hunoz") }) test_that("env_bind_active() supports nested quosures", { env <- env() quo <- local({ lhs <- "quux" rhs <- local({ rhs <- "hunoz"; quo(rhs) }) quo(paste(lhs, !!rhs)) }) env_bind_active(env, x = quo) expect_identical(env$x, "quux hunoz") quo <- quo_set_env(quo, env(lhs = "QUUX")) env_bind_active(env, x = quo) expect_identical(env$x, "QUUX hunoz") }) test_that("env_get() survives native encoding", { with_non_utf8_locale({ e <- env(empty_env()) funs <- list(function() 42) native <- enc2native("\u4e2d") s <- as_string(native) names(funs) <- native env_bind_active(e, !!!funs) names(funs) <- s env_bind_active(e, !!!funs) expect_equal(e[[s]], 42) expect_equal(e[[native]], 42) }) }) # Lifecycle ---------------------------------------------------------- test_that("env_bind_exprs() and env_bind_fns() still work", { local_options(lifecycle_disable_warnings = TRUE) e <- env() env_bind_exprs(e, foo = cat("foo\n")) expect_output(e$foo, "foo") expect_null(e$foo) env_bind_fns(e, bar = ~ cat("foo\n")) expect_output(e$bar, "foo") expect_output(e$bar, "foo") }) rlang/tests/testthat/test-trace-trim.txt0000644000176200001440000000160113612375027020150 0ustar liggesusersNo trimming: â–ˆ 1. └─rlang:::f(0) 2. ├─base::identity(identity(g(n))) 3. ├─base::identity(g(n)) 4. └─rlang:::g(n) 5. ├─base::identity(identity(h(n))) 6. ├─base::identity(h(n)) 7. └─rlang:::h(n) 8. ├─base::identity(identity(trace_back(e, bottom = n))) 9. ├─base::identity(trace_back(e, bottom = n)) 10. └─rlang::trace_back(e, bottom = n) One layer (the default): â–ˆ 1. └─rlang:::f(1) 2. ├─base::identity(identity(g(n))) 3. ├─base::identity(g(n)) 4. └─rlang:::g(n) 5. ├─base::identity(identity(h(n))) 6. ├─base::identity(h(n)) 7. └─rlang:::h(n) Two layers: â–ˆ 1. └─rlang:::f(2) 2. ├─base::identity(identity(g(n))) 3. ├─base::identity(g(n)) 4. └─rlang:::g(n) Three layers: â–ˆ 1. └─rlang:::f(3) rlang/tests/testthat/test-cnd.R0000644000176200001440000000312113554012136016220 0ustar liggesuserscontext("cnd") test_that("cnd() constructs all fields", { cond <- cnd("cnd_class", message = "cnd message") expect_identical(conditionMessage(cond), "cnd message") expect_is(cond, "cnd_class") }) test_that("cnd() throws with unnamed fields", { expect_error(cnd("class", "msg", 10), "must have named data fields") }) test_that("restarts are established", { with_restarts(foo = function() {}, expect_true(rst_exists("foo"))) }) test_that("restarting() handlers pass along all requested arguments", { signal_foo <- function() { signal("", "foo", foo_field = "foo_field") } fn <- function() { with_handlers(signal_foo(), foo = restart_handler) } restart_handler <- restarting("rst_foo", a = "a", splice(list(b = "b")), .fields = c(field_arg = "foo_field") ) rst_foo <- function(a, b, field_arg) { expect_equal(list(a, b, field_arg), list("a", "b", "foo_field")) } with_restarts(fn(), rst_foo = rst_foo) }) test_that("cnd_type() detects condition type", { expect_error(cnd_type(list()), "not a condition object") expect_error(cnd_type(mtcars), "not a condition object") expect_error(cnd_type(env()), "not a condition object") expect_identical(cnd_type(cnd("foo")), "condition") expect_identical(cnd_type(message_cnd()), "message") expect_identical(cnd_type(warning_cnd()), "warning") expect_identical(cnd_type(error_cnd()), "error") expect_identical(cnd_type(catch_cnd(interrupt())), "interrupt") }) test_that("bare conditions must be subclassed", { expect_error(cnd(), "must be subclassed") expect_error(signal(""), "must be subclassed") }) rlang/tests/testthat/test-vec-new.R0000644000176200001440000001101213500432472017016 0ustar liggesuserscontext("vec-new") test_that("atomic vectors are spliced", { lgl <- lgl(TRUE, c(TRUE, FALSE), list(FALSE, FALSE)) expect_identical(lgl, c(TRUE, TRUE, FALSE, FALSE, FALSE)) int <- int(1L, c(2L, 3L), list(4L, 5L)) expect_identical(int, 1:5) dbl <- dbl(1, c(2, 3), list(4, 5)) expect_identical(dbl, as_double(1:5)) cpl <- cpl(1i, c(2i, 3i), list(4i, 5i)) expect_identical(cpl, c(1i, 2i, 3i, 4i, 5i)) chr <- chr("foo", c("foo", "bar"), list("buz", "baz")) expect_identical(chr, c("foo", "foo", "bar", "buz", "baz")) raw <- bytes(1, c(2, 3), list(4, 5)) expect_identical(raw, bytes(1:5)) }) test_that("can create empty vectors", { expect_identical(lgl(), logical(0)) expect_identical(int(), integer(0)) expect_identical(dbl(), double(0)) expect_identical(cpl(), complex(0)) expect_identical(chr(), character(0)) expect_identical(bytes(), raw(0)) expect_identical(list2(), list()) }) test_that("objects are not spliced", { expect_error(lgl(structure(list(TRUE, TRUE), class = "bam")), "Can't splice S3 objects") }) test_that("explicitly spliced lists are spliced", { expect_identical(lgl(FALSE, splice(list(TRUE, TRUE))), c(FALSE, TRUE, TRUE)) }) test_that("splicing uses inner names", { expect_identical(lgl(c(a = TRUE, b = FALSE)), c(a = TRUE, b = FALSE)) expect_identical(lgl(list(c(a = TRUE, b = FALSE))), c(a = TRUE, b = FALSE)) }) test_that("splicing uses outer names when scalar", { expect_identical(lgl(a = TRUE, b = FALSE), c(a = TRUE, b = FALSE)) expect_identical(lgl(list(a = TRUE, b = FALSE)), c(a = TRUE, b = FALSE)) }) test_that("warn when outer names unless input is unnamed scalar atomic", { expect_warning(expect_identical(dbl(a = c(1, 2)), c(1, 2)), "Outer names") expect_warning(expect_identical(dbl(list(a = c(1, 2))), c(1, 2)), "Outer names") expect_warning(expect_identical(dbl(a = c(A = 1)), c(A = 1)), "Outer names") expect_warning(expect_identical(dbl(list(a = c(A = 1))), c(A = 1)), "Outer names") }) test_that("warn when spliced lists have outer name", { expect_warning(lgl(list(c = c(cc = FALSE))), "Outer names") }) test_that("list2() doesn't splice bare lists", { expect_identical(list2(list(1, 2)), list(list(1, 2))) expect_identical(list2(!!! list(1, 2)), list(1, 2)) }) test_that("atomic inputs are implicitly coerced", { expect_identical(lgl(10L, FALSE, list(TRUE, 0L, 0)), c(TRUE, FALSE, TRUE, FALSE, FALSE)) expect_identical(dbl(10L, 10, TRUE, list(10L, 0, TRUE)), c(10, 10, 1, 10, 0, 1)) expect_error(lgl("foo"), "Can't convert a character vector to a logical vector") expect_error(chr(10), "Can't convert a double vector to a character vector") }) test_that("type errors are handled", { expect_error(lgl(env(a = 1)), "Internal error: expected a vector") expect_error(lgl(list(env())), "Internal error: expected a vector") }) test_that("empty inputs are spliced", { expect_identical(lgl(NULL, lgl(), list(NULL, lgl())), lgl()) expect_warning(regexp = NA, expect_identical(lgl(a = NULL, a = lgl(), list(a = NULL, a = lgl())), lgl())) }) test_that("list2() splices names", { expect_identical(list2(a = TRUE, b = FALSE), list(a = TRUE, b = FALSE)) expect_identical(list2(c(A = TRUE), c(B = FALSE)), list(c(A = TRUE), c(B = FALSE))) expect_identical(list2(a = c(A = TRUE), b = c(B = FALSE)), list(a = c(A = TRUE), b = c(B = FALSE))) }) test_that("ll() is an alias to list2()", { expect_identical(ll(!!! list(1, 2)), list(1, 2)) }) test_that("vector ctors take names arguments", { expect_identical(new_logical(2, letters[1:2]), c(a = NA, b = NA)) expect_identical(new_integer(2, letters[1:2]), c(a = na_int, b = na_int)) expect_identical(new_double(2, letters[1:2]), c(a = na_dbl, b = na_dbl)) expect_identical(new_complex(2, letters[1:2]), c(a = na_cpl, b = na_cpl)) expect_identical(new_character(2, letters[1:2]), c(a = na_chr, b = na_chr)) expect_identical(new_raw(2, letters[1:2]), set_names(raw(2), c("a", "b"))) expect_identical(new_list(2, letters[1:2]), list(a = NULL, b = NULL)) }) test_that("rep_named() repeats along names", { expect_error(rep_named(1, list(1)), "must be `NULL` or a character vector") expect_identical(rep_named(NULL, list(1)), named_list()) expect_identical(rep_named(chr(), list(1)), named_list()) expect_identical(rep_named(c("foo", "bar"), list(1)), list(foo = 1, bar = 1)) }) test_that("rep_along() reps along vector", { expect_identical(rep_along(1:2, list(zap())), list(zap(), zap())) }) test_that("chr() supports logical NA", { expect_identical(chr(NA), na_chr) expect_identical(chr(NA, NA), c(na_chr, na_chr)) }) rlang/tests/testthat/test-s3.R0000644000176200001440000000661413457603056016024 0ustar liggesuserscontext("s3") test_that("inherits from all classes", { x <- structure(list(), class = c("foo", "bar", "baz")) expect_true(inherits_all(x, c("foo"))) expect_true(inherits_all(x, c("foo", "baz"))) expect_true(inherits_all(x, c("foo", "bar", "baz"))) expect_false(inherits_all(x, c("fooz"))) expect_false(inherits_all(x, c("foo", "barz", "baz"))) expect_false(inherits_all(x, c("fooz", "bar", "baz"))) expect_error(inherits_all(x, chr()), "empty") }) test_that("inherits from any class", { x <- structure(list(), class = "bar") expect_true(inherits_any(x, c("bar", "foo"))) expect_true(inherits_any(x, c("foo", "bar"))) expect_true(inherits_any(x, c("foo", "bar", "baz"))) expect_false(inherits_any(x, c("foo", "baz"))) expect_error(inherits_any(x, chr()), "empty") }) test_that("inherits only from class", { x <- structure(list(), class = c("foo", "bar", "baz")) expect_false(inherits_only(x, c("foo", "baz"))) expect_true(inherits_only(x, c("foo", "bar", "baz"))) }) test_that("can box and unbox a value", { box <- new_box(letters, "foo") expect_true(is_box(box)) expect_true(is_box(box), "foo") expect_false(is_box(box, "bar")) expect_identical(unbox(box), letters) box <- new_box(NULL, c("foo", "bar", "baz")) expect_true(is_box(box, c("foo", "baz"))) expect_false(is_box(box, c("baz", "foo"))) }) test_that("as_box() ensures boxed value", { box <- as_box(NULL) expect_true(inherits_only(box, "rlang_box")) boxbox <- as_box(box) expect_true(inherits_only(box, "rlang_box")) expect_null(unbox(box)) some_box <- as_box(NULL, "some_box") some_boxbox <- as_box(some_box, "other_box") expect_true(inherits_only(some_boxbox, c("other_box", "rlang_box"))) expect_true(inherits_only(unbox(some_boxbox), c("some_box", "rlang_box"))) expect_null(unbox(unbox(some_boxbox))) }) test_that("as_box_if() ensures boxed value if predicate returns TRUE", { box <- as_box_if(NULL, is_null, "null_box") expect_true(inherits_only(box, c("null_box", "rlang_box"))) boxbox <- as_box_if(box, is_null, "null_box") expect_true(inherits_only(box, c("null_box", "rlang_box"))) expect_null(unbox(boxbox)) expect_null(as_box_if(NULL, is_vector, "null_box")) expect_error(as_box_if(NULL, ~ 10), "Predicate functions must return a single") }) test_that("unboxing a non-boxed value is an error", { expect_error(unbox(NULL), "must be a box") }) test_that("zap() creates a zap", { expect_is(zap(), "rlang_zap") expect_true(is_zap(zap())) }) test_that("can pass additional attributes to boxes", { box <- new_box(NA, "foo", bar = "baz") expect_identical(box %@% bar, "baz") }) test_that("done() boxes values", { expect_true(is_done_box(done(3))) expect_identical(unbox(done(3)), 3) expect_identical(done(3) %@% empty, FALSE) }) test_that("done() can be empty", { empty <- done() expect_identical(unbox(empty), missing_arg()) expect_true(is_done_box(empty)) expect_is(empty, "rlang_box_done") expect_identical(empty %@% empty, TRUE) expect_true(is_done_box(empty, empty = TRUE)) expect_false(is_done_box(empty, empty = FALSE)) nonempty <- done(missing_arg()) expect_false(is_done_box(nonempty, empty = TRUE)) expect_true(is_done_box(nonempty, empty = FALSE)) }) test_that("splice box is constructed", { box <- splice(list(NA)) expect_true(is.object(box)) expect_identical(box, structure(list(list(NA)), class = c("rlang_box_splice", "rlang_box"))) }) rlang/tests/testthat/test-cnd-entrace.R0000644000176200001440000001214413612043675017653 0ustar liggesuserscontext("cnd-entrace") test_that("with_abort() promotes base errors to rlang errors", { skip_unless_utf8() f <- function() g() g <- function() h() h <- function() stop("Low-level message") a <- function() b() b <- function() c() c <- function() { tryCatch( with_abort(f()), error = function(err) { abort("High-level message", parent = err) } ) } local_options( rlang_trace_format_srcrefs = FALSE, rlang_trace_top_env = current_env() ) err <- identity(catch_cnd(a())) expect_known_output(file = test_path("test-with-abort.txt"), { cat_line("print():", "") print(err) cat_line("", "", "summary():", "") summary(err) }) }) test_that("with_abort() entraces conditions properly", { catch_abort <- function(signaller, arg, classes = "error") { f <- function() g() g <- function() h() h <- function() signaller(arg) catch_cnd(with_abort(f(), classes = classes)) } expect_abort_trace <- function(signaller, arg, native = NULL, classes = "error") { err <- catch_abort(signaller, arg, classes = classes) expect_is(err, "rlang_error") trace <- err$trace n <- trace_length(err$trace) if (is_null(native)) { calls <- trace$calls[seq2(n - 2, n)] expect_true(all( is_call(calls[[1]], "f"), is_call(calls[[2]], "g"), is_call(calls[[3]], "h") )) } else { calls <- trace$calls[seq2(n - 4, n)] expect_true(all( is_call(calls[[1]], "f"), is_call(calls[[2]], "g"), is_call(calls[[3]], "h"), is_call(calls[[4]], "signaller"), is_call(calls[[5]], native) )) } } local_options( rlang_trace_top_env = current_env() ) msg <- catch_abort(base::message, "") expect_true(inherits_all(msg, c("message", "condition"))) err <- catch_abort(base::message, "", classes = "message") expect_is(err, "rlang_error") expect_abort_trace(base::stop, "") expect_abort_trace(base::stop, cnd("error")) expect_abort_trace(function(msg) errorcall(NULL, msg), "", "errorcall") expect_abort_trace(abort, "") expect_abort_trace(base::warning, "", classes = "warning") expect_abort_trace(base::warning, cnd("warning"), classes = "warning") expect_abort_trace(function(msg) warningcall(NULL, msg), "", "warningcall", classes = "warning") expect_abort_trace(warn, "", classes = "warning") expect_abort_trace(base::message, "", classes = "message") expect_abort_trace(base::message, cnd("message"), classes = "message") expect_abort_trace(inform, "", classes = "message") expect_abort_trace(base::signalCondition, cnd("foo"), classes = "condition") }) test_that("signal context is detected", { get_signal_info <- function(cnd) { nframe <- sys.nframe() - 1 out <- signal_context_info(nframe) info <- list(out[[1]], sys.call(out[[2]])) invokeRestart("out", info) } signal_info <- function(signaller, arg) { f <- function() signaller(arg) withRestarts( out = identity, withCallingHandlers(condition = get_signal_info, f()) ) } expect_equal(signal_info(base::stop, ""), list("stop_message", quote(f()))) expect_equal(signal_info(base::stop, cnd("error")), list("stop_condition", quote(f()))) expect_equal(signal_info(function(msg) errorcall(NULL, msg), ""), list("stop_native", quote(errorcall(NULL, msg)))) # No longer works since we switched to signalCondition approach # expect_equal(signal_info(abort, "")[[1]], "stop_rlang") expect_equal(signal_info(base::warning, ""), list("warning_message", quote(f()))) expect_equal(signal_info(base::warning, cnd("warning")), list("warning_condition", quote(f()))) expect_equal(signal_info(function(msg) warningcall(NULL, msg), ""), list("warning_native", quote(warningcall(NULL, msg)))) expect_equal(signal_info(warn, "")[[1]], "warning_rlang") expect_equal(signal_info(base::message, ""), list("message", quote(f()))) expect_equal(signal_info(base::message, cnd("message")), list("message", quote(f()))) expect_equal(signal_info(inform, "")[[1]], "message_rlang") expect_equal(signal_info(base::signalCondition, cnd("foo")), list("condition", quote(f()))) # Warnings won't be promoted if `condition` is handled. We need to # handle `error` instead. signal_info_error <- function(signaller, arg) { f <- function() signaller(arg) withRestarts( out = identity, withCallingHandlers(error = get_signal_info, f()) ) } expr <- quote(with_options(warn = 2, signal_info_error(base::warning, ""))) expect_equal(eval_top(expr), list("warning_promoted", quote(f()))) }) test_that("cnd_entrace() skips capture context", { capture <- function(expr) { env <- environment() withCallingHandlers( expr, error = function(err) { err <- cnd_entrace(err) return_from(env, err) } ) } foo <- function() bar() bar <- function() stop("foobar") local_options(rlang_trace_top_env = current_env()) err <- capture(foo()) last <- err$trace$calls[[4]] expect_match(deparse(last), "bar") }) rlang/tests/testthat/test-stack.R0000644000176200001440000000207213405732277016577 0ustar liggesuserscontext("stack") test_that("can return from frame", { fn <- function() { val <- g() paste(val, "to fn()") } g <- function(env) { h(environment()) stop("g!\n") } h <- function(env) { return_from(env, "returned from h()") stop("h!\n") } expect_equal(fn(), "returned from h() to fn()") }) test_that("can return to frame", { fn <- function() { val <- identity(g(environment())) paste(val, "to fn()") } g <- function(env) { h(env) stop("g!\n") } h <- function(env) { return_to(env, "returned from h()") stop("h!\n") } expect_equal(fn(), "returned from h() to fn()") }) test_that("detects frame environment", { expect_true(identity(is_frame_env(sys.frame(-1)))) }) test_that("current_env() and current_fn() return current frame props", { fn <- function() { list( rlang = list(identity(current_env()), current_fn()), base = list(environment(), sys.function()) ) } out <- fn() expect_identical(out$rlang[[1]], out$base[[1]]) expect_identical(out$rlang[[2]], out$base[[2]]) }) rlang/tests/testthat/test-cnd-error-str.txt0000644000176200001440000000155313612375014020604 0ustar liggesusers The high-level error message Backtrace: â–ˆ 1. ├─rlang::catch_cnd(a()) 2. │ ├─rlang::eval_bare(...) 3. │ ├─base::tryCatch(...) 4. │ │ └─base:::tryCatchList(expr, classes, parentenv, handlers) 5. │ │ └─base:::tryCatchOne(expr, names, parentenv, handlers[[1L]]) 6. │ │ └─base:::doTryCatch(return(expr), name, parentenv, handler) 7. │ └─base::force(expr) 8. └─rlang:::a() 9. ├─base::tryCatch(b()) 10. │ └─base:::tryCatchList(expr, classes, parentenv, handlers) 11. └─rlang:::b() 12. └─rlang:::c() The low-level error message Backtrace: â–ˆ 1. └─rlang:::f() 2. ├─base::tryCatch(g()) 3. │ └─base:::tryCatchList(expr, classes, parentenv, handlers) 4. └─rlang:::g() 5. └─rlang:::h() rlang/tests/testthat/test-formula.R0000644000176200001440000000566013405732277017145 0ustar liggesuserscontext("formula") # Creation ---------------------------------------------------------------- test_that("is_formula works", { expect_true(is_formula(~10)) expect_false(is_formula(10)) }) # Getters ----------------------------------------------------------------- test_that("throws errors for bad inputs", { expect_error(f_rhs(1), "must be a formula") expect_error(f_rhs(`~`()), "Invalid formula") expect_error(f_rhs(`~`(1, 2, 3)), "Invalid formula") expect_error(f_lhs(1), "must be a formula") expect_error(f_lhs(`~`()), "Invalid formula") expect_error(f_lhs(`~`(1, 2, 3)), "Invalid formula") expect_error(f_env(1), "must be a formula") }) test_that("extracts call, name, or scalar", { expect_identical(f_rhs(~ x), quote(x)) expect_identical(f_rhs(~ f()), quote(f())) expect_identical(f_rhs(~ 1L), 1L) }) # Setters ----------------------------------------------------------------- test_that("can replace RHS of one-sided formula", { f <- ~ x1 f_rhs(f) <- quote(x2) expect_equal(f, ~ x2) }) test_that("can replace both sides of two-sided formula", { f <- x1 ~ y1 f_lhs(f) <- quote(x2) f_rhs(f) <- quote(y2) expect_equal(f, x2 ~ y2) }) test_that("can remove lhs of two-sided formula", { f <- x ~ y f_lhs(f) <- NULL expect_equal(f, ~ y) }) test_that("can modify environment", { f <- x ~ y env <- new.env() f_env(f) <- env expect_equal(f_env(f), env) }) test_that("setting RHS preserves attributes", { attrs <- list(foo = "bar", class = "baz") f <- structure2(~foo, !!!attrs) f_rhs(f) <- quote(bar) expect_identical(f, structure2(~bar, !!!attrs)) }) test_that("setting LHS preserves attributes", { attrs <- list(foo = "bar", class = "baz") f <- structure2(~foo, !!!attrs) f_lhs(f) <- quote(bar) expect_identical(f, structure2(bar ~ foo, !!!attrs)) f_lhs(f) <- quote(baz) expect_identical(f, structure2(baz ~ foo, !!!attrs)) }) test_that("setting environment preserves attributes", { attrs <- list(foo = "bar", class = "baz") env <- env() f <- structure2(~foo, !!!attrs) f_env(f) <- env expect_identical(f, structure2(~foo, !!!attrs, .Environment = env)) }) # Utils -------------------------------------------------------------- test_that("quosures are not recognised as bare formulas", { expect_false(is_bare_formula(quo(foo))) }) test_that("lhs is inspected", { expect_true(is_formula(~foo)) expect_false(is_formula(~foo, lhs = TRUE)) expect_true(is_formula(~foo, lhs = FALSE)) expect_true(is_formula(foo ~ bar, lhs = TRUE)) expect_false(is_formula(foo ~ bar, lhs = FALSE)) }) test_that("definitions are not formulas but are formulaish", { expect_false(is_formula(quote(foo := bar))) expect_true(is_formulaish(quote(foo := bar), lhs = TRUE)) expect_false(is_formulaish(quote(foo := bar), lhs = FALSE)) `:=` <- `~` expect_false(is_formulaish(foo := bar, scoped = TRUE, lhs = FALSE)) expect_false(is_formulaish(foo := bar, scoped = FALSE, lhs = TRUE)) }) rlang/tests/testthat/test-cnd-error-print-base-parent.txt0000644000176200001440000000001413612375014023316 0ustar liggesusers rlang/tests/testthat/test-cnd-handlers.R0000644000176200001440000000476113552030327020031 0ustar liggesuserscontext("cnd-handlers") test_that("with_handlers() establishes inplace and exiting handlers", { handlers <- list( error = function(c) "caught error", message = function(c) "caught message", warning = calling(function(c) "warning"), foobar = calling(function(c) cat("foobar")) ) expect_equal(with_handlers(identity(letters), !!!handlers), identity(letters)) expect_equal(with_handlers(stop(letters), !!!handlers), "caught error") expect_equal(with_handlers(message(letters), !!!handlers), "caught message") expect_warning(expect_equal(with_handlers({ warning("warn!"); letters }, !!!handlers), identity(letters)), "warn!") expect_output(expect_equal(with_handlers({ signal("", "foobar"); letters }, !!!handlers), identity(letters)), "foobar") }) test_that("bare functions are treated as exiting handlers", { expect_identical(with_handlers(abort("foo"), error = function(cnd) "caught"), "caught") }) test_that("with_handlers() supports formula shortcut for lambdas", { err <- with_handlers(abort("foo", "bar"), error = ~.x) expect_true(inherits(err, "bar")) }) test_that("can muffle conditions", { expect_no_message( expect_identical(with_handlers({ message(""); "foo" }, message = calling(cnd_muffle)), "foo") ) expect_no_warning( expect_identical(with_handlers({ warning(""); "foo" }, warning = calling(cnd_muffle)), "foo") ) cnd_expect_muffle <- calling(function(cnd) { expect_is(findRestart("rlang_muffle"), "restart") cnd_muffle(cnd) }) expect_identical(with_handlers({ signal("", "cnd"); "foo" }, cnd = cnd_expect_muffle), "foo") }) test_that("can catch condition of specific classes", { expect_null(catch_cnd(signal("", "bar"), "foo")) expect_is(catch_cnd(signal("", "bar"), "bar"), "bar") expect_is(catch_cnd(stop(""), "error"), "error") expect_is(catch_cnd(stop("tilt")), "error") expect_error(catch_cnd(stop("tilt"), "foo"), "tilt") classes <- c("foo", "bar") expect_is(catch_cnd(signal("", "bar"), classes), "bar") expect_is(catch_cnd(signal("", "foo"), classes), "foo") }) test_that("with_handlers() registers calling handlers first (#718)", { out <- with_restarts( RESTART = ~ "good", with_handlers( CND = calling(~ rst_jump("RESTART")), CND = ~ "bad", signal("", "CND") ) ) expect_identical(out, "good") out <- with_restarts( RESTART = ~ "good", with_handlers( CND = ~ "bad", CND = calling(~ rst_jump("RESTART")), signal("", "CND") ) ) expect_identical(out, "good") }) rlang/tests/testthat/output-cnd-abort-parent-trace.txt0000644000176200001440000000073413612375012022716 0ustar liggesusers> wrapper <- FALSE > err <- catch_cnd(f()) > print(err) > wrapper <- TRUE > err <- catch_cnd(f()) > print(err) wrapper Backtrace: 1. rlang::catch_cnd(f()) 8. rlang:::f() 9. rlang:::g() 10. rlang:::h() > # FIXME? > parent <- FALSE > err <- catch_cnd(f()) > print(err) wrapper Backtrace: 1. rlang::catch_cnd(f()) 8. rlang:::f() 9. rlang:::g() 10. rlang:::h() rlang/tests/testthat/test-exec.R0000644000176200001440000000055213405732277016417 0ustar liggesuserscontext("test-exec") test_that("supports tidy dots", { expect_equal(exec(list, x = 1), list(x = 1)) args <- list(x = 1) expect_equal(exec(list, !!!args), list(x = 1)) expect_equal(exec(list, !!!args, y = 2), list(x = 1, y = 2)) }) test_that("does not inline expressions", { expect_equal(exec(list, x = expr(x), y = expr(y)), exprs(x = x, y = y)) }) rlang/tests/testthat/test-cnd-signal-trace.txt0000644000176200001440000000016413612375014021213 0ustar liggesusers Backtrace: 1. rlang::catch_cnd(f()) 8. rlang:::f() 9. rlang:::g() 10. rlang:::h() rlang/tests/testthat/test-trace-collapse-magrittr-children.txt0000644000176200001440000000147613612375026024425 0ustar liggesusersFull: â–ˆ 1. └─NA %>% F() %>% G() %>% H() 2. ├─base::withVisible(eval(quote(`_fseq`(`_lhs`)), env, env)) 3. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 4. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 5. └─rlang:::`_fseq`(`_lhs`) 6. └─magrittr::freduce(value, `_function_list`) 7. ├─base::withVisible(function_list[[k]](value)) 8. └─function_list[[k]](value) 9. └─rlang:::H(.) 10. └─rlang:::f() 11. └─rlang:::h() Collapsed: â–ˆ 1. └─[ NA %>% F() %>% G() %>% H() ] with 7 more calls 9. └─rlang:::H(.) 10. └─rlang:::f() 11. └─rlang:::h() Branch: 1. rlang:::F(.) 1. rlang:::G(.) 9. rlang:::H(.) 10. rlang:::f() 11. rlang:::h() rlang/tests/testthat/test-encoding.R0000644000176200001440000000122213500432472017242 0ustar liggesuserscontext("encoding") test_that("can roundtrip symbols in non-UTF8 locale", { with_non_utf8_locale({ expect_identical( as_string(sym(get_alien_lang_string())), get_alien_lang_string() ) }) }) test_that("Unicode escapes are always converted to UTF8 characters on roundtrip", { expect_identical( as_string(sym("")), "\u5E78\u798F" ) }) test_that("Unicode escapes are always converted to UTF8 characters with env_names()", { with_non_utf8_locale({ env <- child_env(empty_env()) env_bind(env, !! get_alien_lang_string() := NULL) expect_identical(env_names(env), get_alien_lang_string()) }) }) rlang/tests/testthat/test-vec.R0000644000176200001440000000414713405732277016254 0ustar liggesuserscontext("vec") test_that("can poke a range to a vector", { y <- 11:15 x <- 1:5 x_addr <- sexp_address(x) expect_error(vec_poke_range(x, 2L, y, 2L, 6L), "too small") vec_poke_range(x, 2L, y, 2L, 4L) expect_identical(x, int(1L, 12:14L, 5L)) expect_identical(x_addr, sexp_address(x)) }) test_that("can poke `n` elements to a vector", { y <- 11:15 x <- 1:5 x_addr <- sexp_address(x) expect_error(vec_poke_n(x, 2L, y, 2L, 5L), "too small") vec_poke_n(x, 2L, y, 2L, 4L) expect_identical(x, int(1L, 12:15)) expect_identical(x_addr, sexp_address(x)) }) test_that("can poke to a vector with default parameters", { y <- 11:15 x <- 1:5 x_addr <- sexp_address(x) vec_poke_range(x, 1L, y) expect_identical(x, y) expect_identical(x_addr, sexp_address(x)) x <- 1:5 x_addr <- sexp_address(x) vec_poke_n(x, 1L, y) expect_identical(x, y) expect_identical(x_addr, sexp_address(x)) }) test_that("can poke to a vector with double parameters", { y <- 11:15 x <- 1:5 x_addr <- sexp_address(x) vec_poke_range(x, 2, y, 2, 5) expect_identical(x, int(1L, 12:15L)) expect_identical(x_addr, sexp_address(x)) y <- 11:15 x <- 1:5 x_addr <- sexp_address(x) vec_poke_n(x, 2, y, 2, 4) expect_identical(x, int(1L, 12:15)) expect_identical(x_addr, sexp_address(x)) }) test_that("vector pokers fail if parameters are not integerish", { y <- 11:15 x <- 1:5 expect_error(vec_poke_n(x, 2.5, y, 2L, 5L), "integerish") expect_error(vec_poke_n(x, 2L, y, 2.5, 5L), "integerish") expect_error(vec_poke_n(x, 2L, y, 2L, 5.5), "integerish") expect_error(vec_poke_range(x, 2.5, y, 2L, 4L), "integerish") expect_error(vec_poke_range(x, 2L, y, 2.5, 4L), "integerish") expect_error(vec_poke_range(x, 2L, y, 2L, 4.5), "integerish") }) test_that("is_string() returns FALSE for `NA`", { expect_false(is_string(na_chr)) }) test_that("are_na() requires vector input but not is_na()", { expect_error(are_na(base::eval), "must be an atomic vector") expect_false(is_na(base::eval)) }) test_that("are_na() fails with lists (#558)", { expect_error(are_na(mtcars), "must be an atomic vector") }) rlang/tests/testthat/test-retired.R0000644000176200001440000004372713563536105017141 0ustar liggesuserscontext("retired") local_lifecycle_silence() # Deprecated in rlang 0.4.0 ------------------------------------------ test_that("type_of() returns correct type", { expect_identical(type_of("foo"), "string") expect_identical(type_of(letters), "character") expect_identical(type_of(base::`$`), "primitive") expect_identical(type_of(base::list), "primitive") expect_identical(type_of(base::eval), "closure") expect_identical(type_of(~foo), "formula") expect_identical(type_of(quo(foo)), "formula") expect_identical(type_of(quote(a := b)), "definition") expect_identical(type_of(quote(foo())), "language") }) test_that("Unicode escapes are always converted to UTF8 characters in as_list()", { with_non_utf8_locale({ env <- child_env(empty_env()) env_bind(env, !! get_alien_lang_string() := NULL) list <- as_list(env) expect_identical(names(list), get_alien_lang_string()) }) }) test_that("no method dispatch", { as.logical.foo <- function(x) "wrong" expect_identical(as_integer(structure(TRUE, class = "foo")), 1L) as.list.foo <- function(x) "wrong" expect_identical(as_list(structure(1:10, class = "foo")), as.list(1:10)) }) test_that("input is left intact", { x <- structure(TRUE, class = "foo") y <- as_integer(x) expect_identical(x, structure(TRUE, class = "foo")) }) test_that("as_list() zaps attributes", { expect_identical(as_list(structure(list(), class = "foo")), list()) }) test_that("as_list() only coerces vector or dictionary types", { expect_identical(as_list(1:3), list(1L, 2L, 3L)) expect_error(as_list(quote(symbol)), "a symbol to a list") }) test_that("as_list() bypasses environment method and leaves input intact", { as.list.foo <- function(x) "wrong" x <- structure(child_env(NULL), class = "foo") y <- as_list(x) expect_is(x, "foo") expect_identical(y, set_names(list(), character(0))) }) test_that("as_integer() and as_logical() require integerish input", { expect_error(as_integer(1.5), "a fractional double vector to an integer vector") expect_error(as_logical(1.5), "a fractional double vector to a logical vector") }) test_that("names are preserved", { nms <- as.character(1:3) x <- set_names(1:3, nms) expect_identical(names(as_double(x)), nms) expect_identical(names(as_list(x)), nms) }) test_that("as_character() support logical NA", { expect_identical(as_character(NA), na_chr) expect_identical(as_character(lgl(NA, NA)), c(na_chr, na_chr)) }) test_that("can convert strings (#138)", { expect_identical(as_character("a"), "a") expect_identical(as_list("a"), list("a")) }) # -------------------------------------------------------------------- test_that("parse_quosure() forwards to parse_quo()", { env <- env() expect_identical(parse_quosure("foo", env), parse_quo("foo", env)) expect_identical(parse_quosures("foo; bar", env), parse_quos("foo; bar", env)) }) test_that("lang() forwards to call2() and is_lang() to is_call()", { lang <- lang("foo", !!! list(1, 2), .ns = "bar") call <- call2("foo", !!! list(1, 2), .ns = "bar") expect_identical(lang, call) expect_true(is_lang(lang, "foo", 2, "bar")) expect_false(is_unary_lang(lang, "foo", "bar")) expect_true(is_binary_lang(lang, "foo", "bar")) }) test_that("new_language() forwards to new_call()", { expect_identical( new_language(quote(foo), pairlist("bar")), new_call(quote(foo), pairlist("bar")) ) }) test_that("lang_modify() forwards to call_modify()", { fn <- function(foo = "bar") NULL call <- quote(fn(f = "foo")) expect_identical( lang_modify(call, baz = "bam", .standardise = TRUE), call_modify(call, baz = "bam", .standardise = TRUE) ) }) test_that("lang_standardise() forwards to call_standardise()", { fn <- function(foo = "bar") NULL call <- quote(fn(f = "foo")) expect_identical( lang_standardise(call), call_standardise(call) ) }) test_that("`lang_` accessors forward to `call_` accessors", { fn <- function(foo = "bar") NULL call <- quote(fn(f = "foo")) expect_identical(lang_fn(call), fn) expect_identical(lang_name(call), "fn") expect_identical(lang_args(call), list(f = "foo")) expect_identical(lang_args_names(call), "f") }) test_that("lang_tail() still works", { expect_identical( pairlist(sym("a")), lang_tail(expr(foo(a))) ) }) test_that("lang_head() still works", { expect_identical( lang_head(expr(foo(a))), expr(foo) ) }) test_that("as_overscope() forwards to as_data_mask()", { quo <- quo(foo) mask <- as_overscope(quo, mtcars) expect_true(".__tidyeval_data_mask__." %in% env_names(mask)) }) test_that("overscope functions forward to mask functions", { top <- env() bottom <- child_env(top, foo = "bar") mask <- new_overscope(bottom, top) expect_true(env_has(mask, ".__tidyeval_data_mask__.")) overscope_clean(mask) expect_false(env_has(env_parent(mask), "foo")) mask <- as_data_mask(mtcars) x <- 10 expect_identical(overscope_eval_next(mask, quote(cyl * x), current_env()), mtcars$cyl * x) expect_identical(overscope_eval_next(mask, quote(am * x), current_env()), mtcars$am * x) }) test_that("as_env() forwards to as_environment()", { x <- as_env(mtcars, base_env()) y <- as_environment(mtcars, base_env()) expect_equal(x, y) expect_identical(env_parent(x), env_parent(y)) }) test_that("is_expr() forwards to is_expression()", { expect_true(is_expr(1L)) expect_false(is_expr(1:2)) }) test_that("node() still works", { expect_identical(node(1, NULL), new_node(1, NULL)) }) test_that("set_attrs() fails with uncopyable types", { expect_error(set_attrs(env(), foo = "bar"), "is uncopyable") }) test_that("mut_attrs() fails with copyable types", { expect_error(mut_attrs(letters, foo = "bar"), "is copyable") }) test_that("set_attrs() called with NULL zaps attributes", { obj <- set_attrs(letters, foo = "bar") expect_identical(set_attrs(obj, NULL), letters) }) test_that("set_attrs() does not zap old attributes", { obj <- set_attrs(letters, foo = "bar") obj <- set_attrs(obj, baz = "bam") expect_named(attributes(obj), c("foo", "baz")) }) # Stack ------------------------------------------------------------- test_that("can standardise call frame", { fn <- function(foo = "bar") call_standardise(call_frame()) expect_identical(fn(), quote(fn())) expect_identical(fn("baz"), quote(fn(foo = "baz"))) }) test_that("can modify call frame", { fn <- function(foo = "bar") call_modify(call_frame(), baz = "bam", .standardise = TRUE) expect_identical(fn(), quote(fn(baz = "bam"))) expect_identical(fn("foo"), quote(fn(foo = "foo", baz = "bam"))) }) # Beware some sys.x() take `n` and some take `which` test_that("ctxt_frame() caller agrees with sys.parent()", { parent <- sys.parent(n = 1) caller <- ctxt_frame()$caller_pos expect_equal(caller, parent) }) test_that("ctxt_frame() expr agrees with sys.call()", { n <- sys.nframe() syscall <- sys.call(which = n) expr <- ctxt_frame()$expr expect_identical(expr, syscall) frame <- identity(ctxt_frame()) expect_equal(frame$expr, quote(identity(ctxt_frame()))) }) test_that("ctxt_frame() env agrees with sys.frame()", { n <- sys.nframe() sysframe <- sys.frame(which = n) env <- ctxt_frame()$env expect_identical(env, sysframe) }) test_that("context position is correct", { pos1 <- identity(ctxt_frame()$pos) pos2 <- identity(identity(ctxt_frame()$pos)) pos1 <- fixup_ctxt_depth(pos1) expect_equal(pos1, 1) pos2 <- fixup_ctxt_depth(pos2) expect_equal(pos2, 2) }) test_that("ctxt_frame(n_depth) returns global frame", { n_depth <- ctxt_depth() frame <- ctxt_frame(n_depth) global <- global_frame() expect_identical(frame, global) }) test_that("call_depth() returns correct depth", { depth1 <- identity(call_depth()) expect_equal(fixup_call_depth(depth1), 0) f <- function() identity(call_depth()) g <- function() f() depth2 <- f() depth3 <- g() expect_equal(fixup_call_depth(depth2), 1) expect_equal(fixup_call_depth(depth3), 2) expect_equal(fixup_call_depth(f()), 1) expect_equal(fixup_call_depth(g()), 2) }) test_that("call_frame()$env is the same as parent.frame()", { f <- function(n) call_frame(n + 1)$env f_base <- function(n) parent.frame(n) env1 <- f(1) env1_base <- f_base(1) expect_identical(env1, env1_base) g <- function(n) list(f(n), f_base(n)) envs <- g(1) expect_identical(envs[[1]], envs[[2]]) }) test_that("call_frame()$expr gives expression of caller not previous ctxt", { f <- function(x = 1) call_frame(x)$expr expect_equal(f(), quote(f())) g <- function() identity(f(2)) expect_equal(g(), quote(g())) }) test_that("call_frame(n_depth) returns global frame", { n_depth <- call_depth() expect_identical(call_frame(n_depth), global_frame()) }) test_that("call_frame(n) throws at correct level", { n <- call_depth() expect_error(call_frame(n + 1), "not that many frames") }) test_that("call frames are cleaned", { ctxt_frame_messy <- eval(quote(call_frame(clean = FALSE)), new.env()) expect_identical(ctxt_frame_messy$fn, prim_eval) ctxt_frame_clean <- eval(quote(call_frame(clean = TRUE)), new.env()) expect_identical(ctxt_frame_clean$fn, base::eval) }) test_that("ctxt_stack_callers() agrees with sys.parents()", { parents <- sys.parents() callers <- ctxt_stack_callers() expect_equal(callers, rev(parents)) }) test_that("ctxt_stack_exprs() agrees with sys.call()", { pos <- sys.nframe() syscalls <- map(seq(pos, 1), sys.call) exprs <- ctxt_stack_exprs() expect_identical(exprs, syscalls) }) test_that("ctxt_stack_envs() agrees with sys.frames()", { sysframes <- sys.frames() sysframes <- rev(as.list(sysframes)) envs <- ctxt_stack_envs() expect_identical(envs, sysframes) }) test_that("ctxt_stack_trail() returns a vector of size nframe", { trail <- ctxt_stack_trail() n <- sys.nframe() expect_equal(length(trail), n) }) test_that("ctxt_stack_fns() returns functions in correct order", { f1 <- function(x) f2(x) f2 <- function(x) ctxt_stack_fns() expect_identical(f1()[1:2], list(f2, f1)) }) test_that("ctxt_stack_fns() handles intervening frames", { fns <- ctxt_stack_fns() intervened_fns <- identity(identity(ctxt_stack_fns())) expect_identical(c(identity, identity, fns), intervened_fns) }) test_that("ctxt_stack() handles intervening frames", { stack <- ctxt_stack() intervened_stack <- identity(ctxt_stack())[-1] expect_identical(intervened_stack, stack) }) test_that("call_stack() trail ignores irrelevant frames", { f1 <- function(x) f2(x) f2 <- function(x) f3() f3 <- function(x) call_stack() stack1 <- f1() trail1 <- pluck_int(stack1, "pos") expect_equal(fixup_call_trail(trail1), c(3, 2, 1)) stack2 <- identity(identity(f1())) trail2 <- pluck_int(stack2, "pos") expect_equal(fixup_call_trail(trail2), c(5, 4, 3)) }) test_that("ctxt_stack() exprs is in opposite order to sys calls", { syscalls <- sys.calls() stack <- ctxt_stack() stack <- drop_last(stack) # global frame exprs <- pluck(stack, "expr") expect_equal(exprs[[length(exprs)]], syscalls[[1]]) expect_equal(exprs[[1]], syscalls[[length(syscalls)]]) }) test_that("ctxt_stack() and call_stack() agree", { call_stack <- call_stack() call_stack <- drop_last(call_stack) # global frame positions <- map_int(call_stack, `[[`, "pos") ctxt_stack <- ctxt_stack() ctxt_stack <- drop_last(ctxt_stack) # global frame ctxt_stack <- rev(ctxt_stack)[positions] call_exprs <- map(call_stack, `[[`, "expr") eval_exprs <- map(ctxt_stack, `[[`, "expr") expect_identical(call_exprs, eval_exprs) is_eval <- map_lgl(call_stack, function(frame) { identical(frame$fn, base::eval) }) call_envs <- map(call_stack[!is_eval], `[[`, "env") eval_envs <- map(ctxt_stack[!is_eval], `[[`, "env") expect_identical(call_envs, eval_envs) }) test_that("ctxt_stack() subsets n frames", { stack <- ctxt_stack() stack_2 <- ctxt_stack(2) expect_identical(stack_2, stack[1:2]) n <- ctxt_depth() stack_n <- ctxt_stack(n) expect_identical(stack_n, stack) # Get correct eval depth within expect_error() expect_error({ n <- ctxt_depth(); stop() }) expect_error(ctxt_stack(n + 1), "not that many frames") }) test_that("call_stack() subsets n frames", { stack <- call_stack() stack_2 <- call_stack(2) expect_identical(stack_2, stack[1:2]) n <- call_depth() stack_n <- call_stack(n) expect_identical(stack_n, stack) # Get correct eval depth within expect_error() expect_error({ n <- call_depth(); stop() }) expect_error(call_stack(n + 1), "not that many frames") }) test_that("call stacks are cleaned", { stack_messy <- eval(quote(call_stack(clean = FALSE)), new.env())[1:2] expect_identical(stack_messy[[1]]$fn, prim_eval) expect_identical(stack_messy[[2]]$fn, base::eval) stack_clean <- eval(quote(call_stack(clean = TRUE)), new.env()) expect_identical(stack_clean[[1]]$fn, base::eval) }) test_that("ctxt_stack() trims layers of calls", { current_stack <- ctxt_stack() expect_identical(identity(identity(ctxt_stack(trim = 1))), current_stack) fn <- function(trim) identity(identity(ctxt_stack(trim = trim))) stack <- identity(identity(fn(2))) expect_identical(stack, current_stack) }) test_that("frame_position() returns correct position", { fn <- function() { env <- environment() pos <- ctxt_frame()$pos g(env, pos) } g <- function(env, fn_pos) { pos <- frame_position(env) expect_identical(pos, fn_pos) burried_pos <- identity(identity(frame_position(env))) expect_identical(burried_pos, pos) } fn() }) test_that("frame_position_current() computes distance from a frame", { fn <- function() { g(environment()) } g <- function(env) { distance <- frame_position(env, from = "current") frame <- ctxt_frame(distance) expect_identical(frame$env, env) burried_distance <- identity(frame_position(env, from = "current")) expect_equal(distance, burried_distance) } fn() }) test_that("evaluation stack is trimmed from layers of calls", { stack <- ctxt_stack() trimmed_stack <- identity(stack_trim(identity(ctxt_stack()))) expect_identical(stack, trimmed_stack) }) test_that("call is not modified in place", { f <- function(...) g(...) g <- function(...) call_stack()[1:2] stack <- f(foo) expect_equal(stack[[1]]$expr, quote(g(...))) }) test_that("finds correct env type - frame", { expect_identical(identity(env_type(ctxt_frame(2)$env)), "frame") }) test_that("retired _len() ctors still work", { local_options(lifecycle_verbose_soft_deprecation = FALSE) expect_identical(lgl_len(2), new_logical(2)) expect_identical(int_len(2), new_integer(2)) expect_identical(dbl_len(2), new_double(2)) expect_identical(chr_len(2), new_character(2)) expect_identical(cpl_len(2), new_complex(2)) expect_identical(raw_len(2), new_raw(2)) expect_identical(bytes_len(2), new_raw(2)) expect_identical(list_len(2), new_list(2)) }) test_that("retired _along() ctors still work", { local_options(lifecycle_verbose_soft_deprecation = FALSE) expect_identical(lgl_along(1:2), new_logical_along(1:2)) expect_identical(int_along(1:2), new_integer_along(1:2)) expect_identical(dbl_along(1:2), new_double_along(1:2)) expect_identical(chr_along(1:2), new_character_along(1:2)) expect_identical(cpl_along(1:2), new_complex_along(1:2)) expect_identical(raw_along(1:2), new_raw_along(1:2)) expect_identical(bytes_along(1:2), new_raw_along(1:2)) expect_identical(list_along(1:2), new_list_along(1:2)) }) test_that("whole scope is purged", { local_options(lifecycle_verbose_soft_deprecation = FALSE) outside <- child_env(NULL, important = TRUE) top <- child_env(outside, foo = "bar", hunoz = 1) mid <- child_env(top, bar = "baz", hunoz = 2) data_mask_objects <- list( .top_env = top, .env = 1, `~` = 2, .__tidyeval_data_mask__. = env() ) bottom <- child_env(mid, !!! data_mask_objects) overscope_clean(bottom) expect_identical(names(bottom), character(0)) expect_identical(names(mid), character(0)) expect_identical(names(top), character(0)) expect_identical(names(outside), "important") }) test_that("pattern match on string encoding", { expect_defunct(is_character(letters, encoding = "unknown")) }) test_that("vector _along() ctors pick up names", { x <- list(a = NULL, b = NULL) expect_identical(new_logical_along(x), c(a = NA, b = NA)) expect_identical(new_integer_along(x), c(a = na_int, b = na_int)) expect_identical(new_double_along(x), c(a = na_dbl, b = na_dbl)) expect_identical(new_complex_along(x), c(a = na_cpl, b = na_cpl)) expect_identical(new_character_along(x), c(a = na_chr, b = na_chr)) expect_identical(new_raw_along(x), set_names(raw(2), c("a", "b"))) expect_identical(new_list_along(x), list(a = NULL, b = NULL)) }) test_that("vector _along() ctors pick up names", { x <- list(a = NULL, b = NULL) expect_identical(new_logical_along(x, toupper), c(A = NA, B = NA)) expect_identical(new_integer_along(x, toupper), c(A = na_int, B = na_int)) expect_identical(new_double_along(x, toupper), c(A = na_dbl, B = na_dbl)) expect_identical(new_complex_along(x, toupper), c(A = na_cpl, B = na_cpl)) expect_identical(new_character_along(x, toupper), c(A = na_chr, B = na_chr)) expect_identical(new_raw_along(x, toupper), set_names(raw(2), c("A", "B"))) expect_identical(new_list_along(x, toupper), list(A = NULL, B = NULL)) }) test_that("vector is modified", { x <- c(1, b = 2, c = 3, 4) out <- modify(x, 5, b = 20, splice(list(6, c = "30"))) expect_equal(out, list(1, b = 20, c = "30", 4, 5, 6)) }) test_that("invoke() buries arguments", { expect_identical(invoke(call_inspect, 1:2, 3L), quote(.fn(`1`, `2`, `3`))) expect_identical(invoke("call_inspect", 1:2, 3L), quote(call_inspect(`1`, `2`, `3`))) expect_identical(invoke(call_inspect, 1:2, 3L, .bury = c("foo", "bar")), quote(foo(`bar1`, `bar2`, `bar3`))) expect_identical(invoke(call_inspect, 1:2, 3L, .bury = NULL), as.call(list(call_inspect, 1L, 2L, 3L))) }) test_that("invoke() can be called without arguments", { expect_identical(invoke("list"), list()) expect_identical(invoke(list), list()) }) test_that("quo_expr() still works", { x <- quo(foo(!!quo(bar), !!local(quo(baz)))) expect_identical(quo_expr(x), quo_squash(x)) }) rlang/tests/testthat/test-trace-summary.txt0000644000176200001440000000012013612375027020665 0ustar liggesusers â–ˆ 1. └─rlang:::f() 2. └─rlang:::g() 3. └─rlang:::h() rlang/tests/testthat/test-trace-recursive.txt0000644000176200001440000000041713612375026021207 0ustar liggesusersFull: â–ˆ 1. ├─rlang::eval_tidy(quo(f())) 2. └─rlang:::f() 3. └─rlang:::g() Collapsed: â–ˆ 1. ├─[ rlang::eval_tidy(...) ] 2. └─rlang:::f() 3. └─rlang:::g() Branch: 1. rlang::eval_tidy(quo(f())) 2. rlang:::f() 3. rlang:::g() rlang/tests/testthat/test-trace-degenerate-null.txt0000644000176200001440000000012213612375027022245 0ustar liggesusersFull: â–ˆ 1. └─NULL Collapsed: â–ˆ 1. └─NULL Branch: 1. NULL rlang/tests/testthat/test-nse-defuse.R0000644000176200001440000003762113604137652017535 0ustar liggesuserscontext("nse-defuse") test_that("quos() creates quosures", { fs <- quos(x = 1 + 2, y = 2 + 3) expect_identical(fs$x, as_quosure(~ 1 + 2)) expect_identical(fs$y, as_quosure(~ 2 + 3)) }) test_that("quos() captures correct environment", { fn <- function(x = a + b, ...) { list(dots = quos(x = x, y = a + b, ...), env = environment()) } out <- fn(z = a + b) expect_identical(get_env(out$dots$x), out$env) expect_identical(get_env(out$dots$y), out$env) expect_identical(get_env(out$dots$z), current_env()) }) test_that("dots are interpolated", { fn <- function(...) { baz <- "baz" fn_var <- quo(baz) g(..., toupper(!! fn_var)) } g <- function(...) { foo <- "foo" g_var <- quo(foo) h(toupper(!! g_var), ...) } h <- function(...) { quos(...) } bar <- "bar" var <- quo(bar) dots <- fn(toupper(!!var)) expect_identical(map(dots, deparse), named_list("~toupper(~foo)", "~toupper(~bar)", "~toupper(~baz)")) expect_identical(map(dots, eval_tidy), named_list("FOO", "BAR", "BAZ")) }) test_that("dots capture is stack-consistent", { fn <- function(...) { g(quos(...)) } g <- function(dots) { h(dots, foo(bar)) } h <- function(dots, ...) { dots } expect_identical(fn(foo(baz)), quos_list(quo(foo(baz)))) }) test_that("dots can be spliced in", { fn <- function(...) { var <- "var" list( out = g(!!! quos(...), bar(baz), !!! list(a = var, b = ~foo)), env = current_env() ) } g <- function(...) { quos(...) } out <- fn(foo(bar)) expected <- quos_list( quo(foo(bar)), set_env(quo(bar(baz)), out$env), a = quo("var"), b = set_env(quo(!! with_env(out$env, ~foo)), out$env) ) expect_identical(out$out, expected) }) test_that("spliced dots are wrapped in formulas", { args <- alist(x = var, y = foo(bar)) expect_identical(quos(!!! args), quos_list(x = quo(var), y = quo(foo(bar)))) }) test_that("dot names are interpolated", { var <- "baz" expect_identical(quos(!!var := foo, !!toupper(var) := bar), quos_list(baz = quo(foo), BAZ = quo(bar))) expect_identical(quos(!!var := foo, bar), quos_list(baz = quo(foo), quo(bar))) var <- quote(baz) expect_identical(quos(!!var := foo), quos_list(baz = quo(foo))) }) test_that("corner cases are handled when interpolating dot names", { var <- na_chr expect_identical(names(quos(!!var := NULL)), "NA") var <- NULL expect_error(quos(!!var := NULL), "must be a string or a symbol") }) test_that("definitions are interpolated", { var1 <- "foo" var2 <- "bar" dots <- dots_definitions(def = foo(!!var1) := bar(!!var2)) pat <- list(lhs = quo(foo("foo")), rhs = quo(bar("bar"))) expect_identical(dots$defs$def, pat) }) test_that("dots are forwarded to named arguments", { outer <- function(...) inner(...) inner <- function(...) fn(...) fn <- function(x) enquo(x) env <- child_env(current_env()) expect_identical(with_env(env, outer(foo(bar))), new_quosure(quote(foo(bar)), env)) }) test_that("pronouns are scoped throughout nested captures", { outer <- function(data, ...) eval_tidy(quos(...)[[1]], data = data) inner <- function(...) map(quos(...), eval_tidy) data <- list(foo = "bar", baz = "baz") baz <- "bazz" expect_identical(outer(data, inner(foo, baz)), set_names(list("bar", "baz"), c("", ""))) }) test_that("Can supply := with LHS even if .named = TRUE", { expect_warning(regexp = NA, expect_identical( quos(!!"nm" := 2, .named = TRUE), quos_list(nm = as_quosure(quote(2), empty_env())) )) }) test_that("Can't supply both `=` and `:=`", { expect_error(regexp = "both `=` and `:=`", quos(foobar = !!"nm" := 2)) expect_error(regexp = "both `=` and `:=`", quos(foobar = !!"nm" := 2, .named = TRUE)) }) test_that("RHS of tidy defs are unquoted", { expect_identical(quos(foo := !!"bar"), quos_list(foo = as_quosure(quote("bar"), empty_env()))) }) test_that("can capture empty list of dots", { fn <- function(...) quos(...) expect_identical(fn(), quos_list()) }) test_that("quosures are spliced before serialisation", { quosures <- quos(!! quo(foo(!! quo(bar))), .named = TRUE) expect_identical(names(quosures), "foo(bar)") }) test_that("missing arguments are captured", { q <- quo() expect_true(is_missing(quo_get_expr(q))) expect_identical(quo_get_env(q), empty_env()) }) test_that("empty quosures are forwarded", { inner <- function(x) enquo(x) outer <- function(x) inner(!! enquo(x)) expect_identical(outer(), quo()) }) test_that("quos() captures missing arguments", { expect_identical(quos(, , .ignore_empty = "none"), quos_list(quo(), quo()), c("", "")) }) test_that("quos() ignores missing arguments", { expect_identical(quos(, , "foo", ), quos_list(quo(), quo(), new_quosure("foo", empty_env()))) expect_identical(quos(, , "foo", , .ignore_empty = "all"), quos_list(new_quosure("foo", empty_env()))) }) test_that("quosured literals are forwarded as is", { expect_identical(quo(!! quo(NULL)), new_quosure(NULL, empty_env())) expect_identical(quos(!! quo(10L)), set_names(quos_list(new_quosure(10L, empty_env())), "")) }) test_that("expr() returns missing argument", { expect_true(is_missing(expr())) }) test_that("expr() supports forwarded arguments", { fn <- function(...) g(...) g <- function(...) expr(...) expect_identical(fn(foo), quote(foo)) }) test_that("can take forced arguments", { fn <- function(allow, x) { force(x) captureArgInfo(x) } expect_identical(fn(TRUE, letters), list(expr = letters, env = empty_env())) if (getRversion() < "3.2.0") { skip("lapply() does not force arguments in R 3.1") } expect_error(lapply(1:2, captureArgInfo), "must be an argument name") args <- list(list(expr = 1L, env = empty_env()), list(expr = 2L, env = empty_env())) expect_identical(lapply(1:2, function(x) captureArgInfo(x)), args) }) test_that("capturing an argument that doesn't exist fails", { fn <- function(x) captureArgInfo(`_foobar`) expect_error(fn(), "object '_foobar' not found") fn <- function() enquo(`_foobar`) expect_error(fn(), "not found") fn <- function() enexpr(`_foobar`) expect_error(fn(), "not found") expect_error((function() rlang::enexpr(`_foobar`))(), "not found") }) test_that("can capture arguments across ancestry", { y <- "foo" fn <- function() captureArgInfo(y) expect_identical(fn(), list(expr = "foo", env = empty_env())) }) test_that("can capture arguments that do exist", { fn <- function() { x <- 10L captureArgInfo(x) } expect_identical(fn(), list(expr = 10L, env = empty_env())) }) test_that("can capture missing argument", { expect_identical(captureArgInfo(), list(expr = missing_arg(), env = empty_env())) }) test_that("serialised unicode in `:=` LHS is unserialised", { nms <- with_latin1_locale({ exprs <- exprs("\u5e78" := 10) names(exprs) }) expect_identical(as_bytes(nms), as_bytes("\u5e78")) }) test_that("exprs() supports auto-naming", { expect_identical(exprs(foo(bar), b = baz(), .named = TRUE), list(`foo(bar)` = quote(foo(bar)), b = quote(baz()))) }) test_that("dots_interp() supports unquoting", { expect_identical(exprs(!!(1 + 2)), named_list(3)) expect_identical(exprs(!!(1 + 1) + 2), named_list(quote(2 + 2))) expect_identical(exprs(!!(1 + 1) + 2 + 3), named_list(quote(2 + 2 + 3))) expect_identical(exprs(!!"foo" := bar), named_list(foo = quote(bar))) }) test_that("dots_interp() has no side effect", { f <- function(x) exprs(!! x + 2) expect_identical(f(1), named_list(quote(1 + 2))) expect_identical(f(2), named_list(quote(2 + 2))) }) test_that("exprs() handles forced arguments", { if (getRversion() < "3.2.0") { skip("lapply() does not force arguments in R 3.1") } exprs <- list(named_list(1L), named_list(2L)) expect_identical(lapply(1:2, function(...) exprs(...)), exprs) expect_identical(lapply(1:2, exprs), exprs) }) test_that("quos() handles forced arguments", { if (getRversion() < "3.2.0") { skip("lapply() does not force arguments in R 3.1") } quos <- list(quos_list(quo(1L)), quos_list(quo(2L))) expect_identical(lapply(1:2, function(...) quos(...)), quos) expect_identical(lapply(1:2, quos), quos) }) test_that("enexpr() and enquo() handle forced arguments", { foo <- "foo" expect_identical(enexpr(foo), "foo") expect_identical(enquo(foo), quo("foo")) if (getRversion() < "3.2.0") { skip("lapply() does not force arguments in R 3.1") } expect_identical(lapply(1:2, function(x) enexpr(x)), list(1L, 2L)) expect_identical(lapply(1:2, function(x) enquo(x)), list(quo(1L), quo(2L))) }) test_that("default arguments are properly captured (#201)", { fn <- function(x = x) enexpr(x) expect_identical(fn(), quote(x)) # This is just for consistency. This causes an infinite recursion # when evaluated as Hong noted fn <- function(x = x) list(enquo(x), quo(x)) out <- fn() expect_identical(out[[1]], out[[2]]) }) test_that("names-unquoting can be switched off", { foo <- "foo" bar <- "bar" expect_identical(exprs(foo := bar, .unquote_names = FALSE), named_list(quote(foo := bar))) expect_identical(exprs(!! foo := !! bar, .unquote_names = FALSE), named_list(quote("foo" := "bar"))) expect_identical(quos(foo := bar, .unquote_names = FALSE), quos_list(new_quosure(quote(foo := bar)))) expect_identical(quos(!! foo := !! bar, .unquote_names = FALSE), quos_list(new_quosure(quote("foo" := "bar")))) }) test_that("endots() captures arguments", { # enquos() fn <- function(foo, ..., bar) enquos(foo, bar, ...) expect_identical(fn(arg1, arg2, bar = arg3()), quos(arg1, arg3(), arg2)) # enexprs() fn <- function(foo, ..., bar) enexprs(foo, bar, ...) expect_identical(fn(arg1, arg2, bar = arg3()), exprs(arg1, arg3(), arg2)) }) test_that("endots() requires symbols", { expect_error(enquos(foo(bar)), "must be argument names") expect_error(enquos(1), "must be argument names") expect_error(enquos("foo"), "must be argument names") expect_error(enexprs(foo(bar)), "must be argument names") expect_error(enexprs(1), "must be argument names") expect_error(enexprs("foo"), "must be argument names") }) test_that("endots() returns a named list", { # enquos() fn <- function(foo, bar) enquos(foo, bar) expect_identical(names(fn()), c("", "")) fn <- function(arg, ...) enquos(other = arg, ...) expect_identical(fn(arg = 1, b = 2), quos(other = 1, b = 2)) # enexprs() fn <- function(foo, bar) enexprs(foo, bar) expect_identical(names(fn()), c("", "")) fn <- function(arg, ...) enexprs(other = arg, ...) expect_identical(fn(arg = 1, b = 2), exprs(other = 1, b = 2)) }) test_that("endots() captures missing arguments", { # enquos() fn <- function(foo) enquos(foo)[[1]] expect_identical(fn(), quo()) fn <- function(...) enquos(...) expect_identical(fn(), quos()) # enexprs() fn <- function(foo) enexprs(foo)[[1]] expect_identical(fn(), expr()) fn <- function(...) enexprs(...) expect_identical(fn(), exprs()) }) test_that("endots() supports `.named`", { # enquos() fn <- function(arg, ...) enquos(arg, ..., .named = TRUE) expect_identical(fn(foo, bar), quos(foo = foo, bar = bar)) # enexprs() fn <- function(arg, ...) enexprs(arg, ..., .named = TRUE) expect_identical(fn(foo, bar), exprs(foo = foo, bar = bar)) }) test_that("endots() supports `.unquote_names`", { # enquos() fn <- function(...) enquos(..., .unquote_names = TRUE) expect_identical(fn(!!"foo" := bar), quos(foo = bar)) fn <- function(...) enquos(..., .unquote_names = FALSE) expect_identical(fn(!!"foo" := bar), quos(!!"foo" := bar, .unquote_names = FALSE)) # enexprs() fn <- function(...) enexprs(..., .unquote_names = TRUE) expect_identical(fn(!!"foo" := bar), exprs(foo = bar)) fn <- function(...) enexprs(..., .unquote_names = FALSE) expect_identical(fn(!!"foo" := bar), exprs(!!"foo" := bar, .unquote_names = FALSE)) }) test_that("endots() supports `.ignore_empty`", { # enquos() fn <- function(...) enquos(..., .ignore_empty = "all") expect_identical(fn(, ), quos()) fn <- function(...) enquos(..., .ignore_empty = "trailing") expect_identical(fn(foo, ), quos(foo)) # enexprs() fn <- function(...) enexprs(..., .ignore_empty = "all") expect_identical(fn(, ), exprs()) fn <- function(...) enexprs(..., .ignore_empty = "trailing") expect_identical(fn(foo, ), exprs(foo)) }) test_that("ensyms() captures multiple symbols", { fn <- function(arg, ...) ensyms(arg, ...) expect_identical(fn(foo, bar, baz), exprs(foo, bar, baz)) expect_error(fn(foo()), "Only strings can be converted to symbols") }) test_that("enquos() works with lexically scoped dots", { capture <- function(...) { eval_bare(quote(enquos(...)), child_env(env())) } expect_identical(capture("foo"), quos_list(quo("foo"))) }) test_that("enquo() works with lexically scoped arguments", { capture <- function(arg) { eval_bare(quote(enquo(arg)), child_env(env())) } expect_identical(capture(foo), quo(foo)) }) test_that("dots_definitions() uses tidy eval", { var1 <- "foo" var2 <- "bar" dots <- dots_definitions(pat = foo(!!var1) := bar(!!var2)) pat <- list(lhs = quo(foo("foo")), rhs = quo(bar("bar"))) expect_identical(dots$defs$pat, pat) }) test_that("dots_definitions() accepts other types of arguments", { dots <- dots_definitions(A = a := b, B = c) expect_identical(dots$defs$A, list(lhs = quo(a), rhs = quo(b))) expect_identical(dots$dots$B, quo(c)) }) test_that("closures are captured with their calling environment", { expect_reference(quo_get_env(quo(!!function() NULL)), environment()) }) test_that("the missing argument is captured", { expect_equal_(quos(!!missing_arg()), quos(, )) fn <- function(x) { g(!!enquo(x)) } g <- function(...) { quos(...) } expect_equal_(fn(), quos(!!missing_arg())) }) test_that("missing names are forwarded", { x <- set_names(1:2, c(NA, NA)) expect_identical_(names(exprs(!!!x)), chr(na_chr, na_chr)) }) test_that("`.named` must be integerish", { expect_error(exprs(foo, .named = 100.5), "must be a scalar logical") }) test_that("auto-naming uses type_sum() (#573)", { expect_named(quos(foo, !!(1:3), .named = TRUE), c("foo", "")) x <- list(env(), 1:3, letters) expect_named(exprs_auto_name(x), c("", "", "")) }) test_that("auto-naming supports the .data pronoun", { exprs <- exprs(.data[[toupper("foo")]], .data$bar, .named = TRUE) expect_named(exprs, c("FOO", "bar")) }) test_that("enexprs() and enquos() support `.ignore_empty = 'all'` (#414)", { myexprs <- function(what, x, y) enexprs(x = x, y = y, .ignore_empty = what) expect_identical(myexprs("none"), exprs(x = , y = )) expect_identical(myexprs("trailing"), exprs(x = , y = )) expect_identical(myexprs("all"), exprs()) myquos <- function(what, x, y) enquos(x = x, y = y, .ignore_empty = what) expect_identical(myquos("none"), quos(x = , y = )) expect_identical(myquos("trailing"), quos(x = , y = )) expect_identical(myquos("all"), quos()) }) test_that("enexprs() and enquos() support empty dots", { myexprs <- function(what, ...) enexprs(..., .ignore_empty = what) expect_identical(myexprs("none"), exprs()) expect_identical(myexprs("trailing"), exprs()) expect_identical(myexprs("all"), exprs()) myquos <- function(what, ...) enquos(..., .ignore_empty = what) expect_identical(myquos("none"), quos()) expect_identical(myquos("trailing"), quos()) expect_identical(myquos("all"), quos()) }) test_that("supplying `!!!` with a name warns", { local_options(lifecycle_verbose_soft_deprecation = TRUE) expect_no_warning_(quos(!!!1, 2, !!!NULL)) expect_defunct(quos(foo = !!!1, 2, bar = !!!NULL), "Only the operand's names are retained") }) test_that("ensym() unwraps quosures", { fn <- function(arg) ensym(arg) expect_identical(fn(!!quo(foo)), quote(foo)) expect_identical(fn(!!quo("foo")), quote(foo)) expect_error(fn(!!quo(foo())), "Only strings can be converted to symbols") }) test_that("ensyms() unwraps quosures", { fn <- function(...) ensyms(...) expect_identical(fn(!!!quos(foo, "bar")), exprs(foo, bar)) expect_error(fn(!!!quos(foo, bar())), "Only strings can be converted to symbols") }) rlang/tests/testthat/test-trace-collapsed2.txt0000644000176200001440000000251213612375026021226 0ustar liggesusersFull: â–ˆ 1. └─rlang:::f() 2. ├─base::eval(quote(eval(quote(g())))) testthat/test-trace.R:58:7 3. │ └─base::eval(quote(eval(quote(g())))) 4. ├─base::eval(quote(g())) 5. │ └─base::eval(quote(g())) 6. └─rlang:::g() 7. ├─base::tryCatch(eval(quote(h())), foo = identity, bar = identity) testthat/test-trace.R:59:7 8. │ └─base:::tryCatchList(expr, classes, parentenv, handlers) 9. │ ├─base:::tryCatchOne(...) 10. │ │ └─base:::doTryCatch(return(expr), name, parentenv, handler) 11. │ └─base:::tryCatchList(expr, names[-nh], parentenv, handlers[-nh]) 12. │ └─base:::tryCatchOne(expr, names, parentenv, handlers[[1L]]) 13. │ └─base:::doTryCatch(return(expr), name, parentenv, handler) 14. ├─base::eval(quote(h())) 15. │ └─base::eval(quote(h())) 16. └─rlang:::h() Collapsed: â–ˆ 1. └─rlang:::f() 2. ├─[ base::eval(...) ] with 1 more call testthat/test-trace.R:58:7 4. ├─[ base::eval(...) ] with 1 more call 6. └─rlang:::g() 7. ├─[ base::tryCatch(...) ] with 6 more calls testthat/test-trace.R:59:7 14. ├─[ base::eval(...) ] with 1 more call 16. └─rlang:::h() Branch: 1. rlang:::f() 6. rlang:::g() 16. rlang:::h() rlang/tests/testthat/test-trace-dangling-srcref.txt0000644000176200001440000000032113612375027022240 0ustar liggesusersFull: â–ˆ 1. └─rlang:::f(current_env()) 2. └─rlang:::g(e) Collapsed: â–ˆ 1. └─rlang:::f(current_env()) 2. └─rlang:::g(e) Branch: 1. rlang:::f(current_env()) 2. rlang:::g(e) rlang/tests/testthat/helper-cnd.R0000644000176200001440000000476713500241611016532 0ustar liggesusers expect_condition <- function(expr, class = NULL, regex = NULL, info = NULL, label = NULL) { object <- tryCatch(expr, condition = identity) if (is_na(class)) { expect_false(inherits(object, "condition"), info = info, label = label) return(invisible(object)) } expect_is(object, "condition", info = info, label = label) if (!is_null(class)) { expect_is(object, class, info = info, label = label) } if (!is_null(regex)) { expect_match(object$message, regex, class, info = info, label = label) } invisible(object) } expect_no_error <- function(...) { expect_error(regexp = NA, ...) } expect_no_error_ <- function(object, ...) { expect_error(object, regexp = NA, ...) } expect_no_warning <- function(...) { expect_warning(regexp = NA, ...) } expect_no_warning_ <- function(object, ...) { expect_warning(object, regexp = NA, ...) } expect_no_message <- function(...) { expect_message(regexp = NA, ...) } expect_no_message_ <- function(object, ...) { expect_message(object, regexp = NA, ...) } catch_wngs <- function(expr) { wngs <- list() withCallingHandlers({ expr }, warning = function(wng) { wngs <<- c(wngs, list(wng)) invokeRestart("muffleWarning") }) wngs } catch_warning_msgs <- function(expr) { wngs <- catch_wngs(expr) flatten_chr(pluck(wngs, "message")) } catch_cnds <- function(expr) { wngs <- list() msgs <- list() err <- tryCatch( withCallingHandlers({ force(expr) NULL }, message = function(msg) { msgs <<- c(msgs, list(msg)) invokeRestart("muffleMessage") }, warning = function(wng) { wngs <<- c(wngs, list(wng)) invokeRestart("muffleWarning") }), error = identity ) list(messages = msgs, warnings = wngs, error = err) } catch_conditions_msgs <- function(expr) { pluck_conditions_msgs(catch_cnds(expr)) } pluck_conditions_msgs <- function(cnds) { cnds$messages <- flatten_chr(pluck(cnds$messages, "message")) cnds$warnings <- flatten_chr(pluck(cnds$warnings, "message")) cnds$error <- cnds$error$message cnds } skip_silently <- function(reason, env = caller_env()) { expect_true(TRUE) return_from(env) } expect_data_pronoun_error <- function(object, regexp = NULL, ...) { expect_error(object, regexp, ..., class = "rlang_error_data_pronoun_not_found") } expect_defunct <- function(object, ...) { expect_error(object, class = "defunctError") } rlang/tests/testthat/test-trace-backtrace-anonymous.txt0000644000176200001440000000014213612375027023141 0ustar liggesusersFull: â–ˆ 1. └─(function() {... Collapsed: â–ˆ 1. └─(function() {... Branch: rlang/tests/testthat/test-trace-degenerate-scalar.txt0000644000176200001440000000011413612375027022541 0ustar liggesusersFull: â–ˆ 1. └─1L Collapsed: â–ˆ 1. └─1L Branch: 1. 1L rlang/tests/testthat/test-trace-collapse-magrittr-before-after1.txt0000644000176200001440000000125613612375027025254 0ustar liggesusersFull: â–ˆ 1. ├─rlang:::F(NA %>% T()) 2. └─NA %>% T() 3. ├─base::withVisible(eval(quote(`_fseq`(`_lhs`)), env, env)) 4. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 5. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 6. └─rlang:::`_fseq`(`_lhs`) 7. └─magrittr::freduce(value, `_function_list`) 8. ├─base::withVisible(function_list[[k]](value)) 9. └─function_list[[k]](value) 10. └─rlang:::T(.) Collapsed: â–ˆ 1. ├─[ rlang:::F(...) ] 2. └─[ NA %>% T() ] with 7 more calls 10. └─rlang:::T(.) Branch: 1. rlang:::F(NA %>% T()) 10. rlang:::T(.) rlang/tests/testthat/test-cnd-error-conditionMessage.txt0000644000176200001440000000045213612375014023264 0ustar liggesusers> # Interactive > cat_line(interactive) Error: dispatched! Run `rlang::last_error()` to see where the error occurred. Execution halted > # Non-interactive > cat_line(non_interactive) Error: dispatched! Backtrace: x 1. \-global::f() 2. \-global::g() 3. \-global::h() Execution halted rlang/tests/testthat/test-call.R0000644000176200001440000005072013554012136016376 0ustar liggesuserscontext("call") # Creation ---------------------------------------------------------------- test_that("character vector must be length 1", { expect_error(call2(letters), "must be a string") }) test_that("args can be specified individually or as list", { out <- call2("f", a = 1, splice(list(b = 2))) expect_equal(out, quote(f(a = 1, b = 2))) }) test_that("creates namespaced calls", { expect_identical(call2("fun", foo = quote(baz), .ns = "bar"), quote(bar::fun(foo = baz))) }) test_that("fails with non-callable objects", { expect_error(call2(1), "non-callable") expect_error(call2(current_env()), "non-callable") }) test_that("succeeds with literal functions", { expect_error(regex = NA, call2(base::mean, 1:10)) expect_error(regex = NA, call2(base::list, 1:10)) }) test_that("call2() preserves empty arguments", { expect_identical(call2("[", quote(x), , drop = ), quote(x[, drop = ])) }) test_that("call2() requires a symbol when namespace is supplied", { expect_identical(call2("foo", .ns = "bar"), quote(bar::foo())) expect_error(call2(function() NULL, .ns = "bar"), "must be a string or symbol") expect_error(call2(quote(foo()), .ns = "bar"), "must be a string or symbol") }) # Standardisation --------------------------------------------------------- test_that("call_standardise() supports quosures", { fn <- function(foo, bar) "Not this one" quo <- local({ fn <- function(baz, quux) "This one" quo(fn(this, that)) }) exp <- new_quosure(quote(fn(baz = this, quux = that)), quo_get_env(quo)) expect_identical(call_standardise(quo), exp) }) test_that("can standardise primitive functions (#473)", { expect_identical(call_standardise(foo ~ bar), foo ~ bar) expect_identical(call_standardise(quote(1 + 2)), quote(1 + 2)) }) # Modification ------------------------------------------------------------ test_that("can modify formulas inplace", { expect_identical(call_modify(~matrix(bar), quote(foo)), ~matrix(bar, foo)) }) test_that("new args inserted at end", { call <- quote(matrix(1:10)) out <- call_modify(call_standardise(call), nrow = 3) expect_equal(out, quote(matrix(data = 1:10, nrow = 3))) }) test_that("new args replace old", { call <- quote(matrix(1:10)) out <- call_modify(call_standardise(call), data = 3) expect_equal(out, quote(matrix(data = 3))) }) test_that("can modify calls for primitive functions", { expect_identical(call_modify(~list(), foo = "bar"), ~list(foo = "bar")) }) test_that("can modify calls for functions containing dots", { expect_identical(call_modify(~mean(), na.rm = TRUE), ~mean(na.rm = TRUE)) }) test_that("accepts unnamed arguments", { expect_identical( call_modify(~get(), "foo", envir = "bar", "baz"), ~get("foo", envir = "bar", "baz") ) }) test_that("allows duplicated arguments (#398)", { expect_identical(call_modify(~mean(), na.rm = TRUE, na.rm = FALSE), ~mean(na.rm = FALSE)) expect_identical(call_modify(~mean(), TRUE, FALSE), ~mean(TRUE, FALSE)) expect_identical(call_modify(~mean(), foo = zap(), foo = zap()), ~mean()) }) test_that("zaps remove arguments", { expect_identical(call_modify(quote(foo(bar = )), bar = zap()), quote(foo())) expect_identical_(call_modify(quote(foo(bar = , baz = )), !!!rep_named(c("foo", "bar", "baz"), list(zap()))), quote(foo())) }) test_that("can remove unexisting arguments (#393)", { expect_identical(call_modify(quote(foo()), ... = zap()), quote(foo())) }) test_that("can add a missing argument", { expect_identical(call_modify(quote(foo()), bar = expr()), quote(foo(bar = ))) expect_identical(call_modify(quote(foo()), bar = ), quote(foo(bar = ))) }) test_that("can refer to dots as named argument", { expect_error(call_modify(quote(foo()), ... = NULL), "must be `zap\\(\\)` or empty") expect_error(call_modify(quote(foo()), ... = "foo"), "must be `zap\\(\\)` or empty") expect_identical(call_modify(quote(foo(x, ..., y)), ... = ), quote(foo(x, ..., y))) expect_identical(call_modify(quote(foo(x)), ... = ), quote(foo(x, ...))) expect_identical(call_modify(quote(foo(x, ..., y)), ... = zap()), quote(foo(x, y))) }) test_that("can't supply unnamed zaps", { expect_error(call_modify(quote(foo(bar)), zap()), "can't be unnamed") }) test_that("positions are not changed", { expect_identical(call_modify(quote(fn(1)), x = "foo"), quote(fn(1, x = "foo"))) expect_identical(call_modify(quote(fn(x = 1)), x = "foo"), quote(fn(x = "foo"))) expect_identical(call_modify(quote(fn(1, x = 1)), x = "foo"), quote(fn(1, x = "foo"))) expect_identical(call_modify(quote(fn(x = 1, 1)), x = "foo"), quote(fn(x = "foo", 1))) expect_identical(call_modify(quote(fn(1)), ... = ), quote(fn(1, ...))) expect_identical(call_modify(quote(fn(...)), ... = ), quote(fn(...))) expect_identical(call_modify(quote(fn(1, ...)), ... = ), quote(fn(1, ...))) expect_identical(call_modify(quote(fn(..., 1)), ... = ), quote(fn(..., 1))) expect_identical(call_modify(quote(fn()), 1, x = "foo"), quote(fn(1, x = "foo"))) expect_identical(call_modify(quote(fn()), x = 1, x = "foo"), quote(fn(x = "foo"))) expect_identical(call_modify(quote(fn()), 1, x = 1, x = "foo"), quote(fn(1, x = "foo"))) expect_identical(call_modify(quote(fn()), x = 1, 1, x = "foo"), quote(fn(x = "foo", 1))) expect_identical(call_modify(quote(fn()), 1, ... = ), quote(fn(1, ...))) expect_identical(call_modify(quote(fn()), ... = , ... = ), quote(fn(...))) expect_identical(call_modify(quote(fn()), 1, ... = , ... = ), quote(fn(1, ...))) expect_identical(call_modify(quote(fn()), ... = , 1, ... = ), quote(fn(..., 1))) }) test_that("empty quosures are treated as empty args", { expect_identical(call_modify(quote(fn()), ... = quo()), quote(fn(...))) }) # Utils -------------------------------------------------------------- test_that("NULL is a valid language object", { expect_true(is_expression(NULL)) }) test_that("is_call() pattern-matches", { expect_true(is_call(quote(foo(bar)), "foo")) expect_false(is_call(quote(foo(bar)), "bar")) expect_true(is_call(quote(foo(bar)), quote(foo))) expect_true(is_call(quote(foo(bar)), "foo", n = 1)) expect_false(is_call(quote(foo(bar)), "foo", n = 2)) expect_true(is_call(quote(+3), n = 1)) expect_true(is_call(quote(3 + 3), n = 2)) expect_true(is_call(quote(foo::bar())), quote(foo::bar())) expect_false(is_call(1)) expect_false(is_call(NULL)) }) test_that("quosures are not calls", { skip("Disabled") expect_false(is_call(quo())) }) test_that("is_call() vectorises name", { expect_false(is_call(quote(foo::bar), c("fn", "fn2"))) expect_true(is_call(quote(foo::bar), c("fn", "::"))) expect_true(is_call(quote(foo::bar), quote(`::`))) expect_true(is_call(quote(foo::bar), list(quote(`@`), quote(`::`)))) expect_false(is_call(quote(foo::bar), list(quote(`@`), quote(`:::`)))) }) test_that("call_name() handles namespaced and anonymous calls", { expect_equal(call_name(quote(foo::bar())), "bar") expect_equal(call_name(quote(foo:::bar())), "bar") expect_null(call_name(quote(foo@bar()))) expect_null(call_name(quote(foo$bar()))) expect_null(call_name(quote(foo[[bar]]()))) expect_null(call_name(quote(foo()()))) expect_null(call_name(quote(foo::bar()()))) expect_null(call_name(quote((function() NULL)()))) }) test_that("call_name() handles formulas", { expect_identical(call_name(~foo(baz)), "foo") }) test_that("call_fn() extracts function", { fn <- function() call_fn(call_frame()) expect_identical(fn(), fn) expect_identical(call_fn(~matrix()), matrix) }) test_that("call_fn() looks up function in `env`", { env <- local({ fn <- function() "foo" current_env() }) expect_identical(call_fn(quote(fn()), env = env), env$fn) }) test_that("Inlined functions return NULL name", { call <- quote(fn()) call[[1]] <- function() {} expect_null(call_name(call)) }) test_that("call_args() and call_args_names()", { expect_identical(call_args(~fn(a, b)), set_names(list(quote(a), quote(b)), c("", ""))) fn <- function(a, b) call_args_names(call_frame()) expect_identical(fn(a = foo, b = bar), c("a", "b")) }) test_that("qualified and namespaced symbols are recognised", { expect_true(is_qualified_call(quote(foo@baz()))) expect_true(is_qualified_call(quote(foo::bar()))) expect_false(is_qualified_call(quote(foo()()))) expect_false(is_namespaced_call(quote(foo@bar()))) expect_true(is_namespaced_call(quote(foo::bar()))) }) test_that("can specify ns in namespaced predicate", { expr <- quote(foo::bar()) expect_false(is_namespaced_call(expr, quote(bar))) expect_true(is_namespaced_call(expr, quote(foo))) expect_true(is_namespaced_call(expr, "foo")) }) test_that("can specify ns in is_call()", { expr <- quote(foo::bar()) expect_true(is_call(expr, ns = NULL)) expect_false(is_call(expr, ns = "")) expect_false(is_call(expr, ns = "baz")) expect_true(is_call(expr, ns = "foo")) expect_true(is_call(expr, name = "bar", ns = "foo")) expect_false(is_call(expr, name = "baz", ns = "foo")) }) test_that("can check multiple namespaces with is_call()", { expect_true(is_call(quote(foo::quux()), ns = c("foo", "bar"))) expect_true(is_call(quote(bar::quux()), ns = c("foo", "bar"))) expect_false(is_call(quote(baz::quux()), ns = c("foo", "bar"))) expect_false(is_call(quote(quux()), ns = c("foo", "bar"))) expect_false(is_call(quote(baz::quux()), ns = c("foo", "bar", ""))) expect_true(is_call(quote(quux()), ns = c("foo", "bar", ""))) }) test_that("can unnamespace calls", { expect_identical(call_unnamespace(quote(bar(baz))), quote(bar(baz))) expect_identical(call_unnamespace(quote(foo::bar(baz))), quote(bar(baz))) expect_identical(call_unnamespace(quote(foo@bar(baz))), quote(foo@bar(baz))) }) test_that("precedence of regular calls", { expect_true(call_has_precedence(quote(1 + 2), quote(foo(1 + 2)))) expect_true(call_has_precedence(quote(foo()), quote(1 + foo()))) }) test_that("precedence of associative ops", { expect_true(call_has_precedence(quote(1 + 2), quote(1 + 2 + 3), "lhs")) expect_false(call_has_precedence(quote(2 + 3), quote(1 + 2 + 3), "rhs")) expect_false(call_has_precedence(quote(1^2), quote(1^2^3), "lhs")) expect_true(call_has_precedence(quote(2^3), quote(1^2^3), "rhs")) }) test_that("call functions type-check their input (#187)", { x <- list(a = 1) expect_error(call_modify(x, NULL), "must be a quoted call") expect_error(call_standardise(x), "must be a quoted call") expect_error(call_fn(x), "must be a quoted call") expect_error(call_name(x), "must be a quoted call") expect_error(call_args(x), "must be a quoted call") expect_error(call_args_names(x), "must be a quoted call") q <- quo(!!x) expect_error(call_modify(q, NULL), "must be a quoted call") expect_error(call_standardise(q), "must be a quoted call") expect_error(call_fn(q), "must be a quoted call") expect_error(call_name(q), "must be a quoted call") expect_error(call_args(q), "must be a quoted call") expect_error(call_args_names(q), "must be a quoted call") }) test_that("call_print_type() returns correct enum", { expect_error(call_print_type(""), "must be a call") expect_identical(call_print_type(quote(foo())), "prefix") expect_identical(call_print_type(quote(~a)), "prefix") expect_identical(call_print_type(quote(?a)), "prefix") expect_identical_(call_print_type(quote(!b)), "prefix") expect_identical_(call_print_type(quote(`!!`(b))), "prefix") expect_identical_(call_print_type(quote(`!!!`(b))), "prefix") expect_identical(call_print_type(quote(+a)), "prefix") expect_identical(call_print_type(quote(-a)), "prefix") expect_identical(call_print_type(quote(while (a) b)), "special") expect_identical(call_print_type(quote(for (a in b) b)), "special") expect_identical(call_print_type(quote(repeat a)), "special") expect_identical(call_print_type(quote(if (a) b)), "special") expect_identical(call_print_type(quote((a))), "special") expect_identical(call_print_type(quote({ a })), "special") expect_identical(call_print_type(quote(a[b])), "special") expect_identical(call_print_type(quote(a[[b]])), "special") expect_identical(call_print_type(quote(a ? b)), "infix") expect_identical(call_print_type(quote(a ~ b)), "infix") expect_identical(call_print_type(quote(a <- b)), "infix") expect_identical(call_print_type(quote(a <<- b)), "infix") expect_identical(call_print_type(quote(a < b)), "infix") expect_identical(call_print_type(quote(a <= b)), "infix") expect_identical(call_print_type(quote(a > b)), "infix") expect_identical(call_print_type(quote(a >= b)), "infix") expect_identical(call_print_type(quote(`=`(a, b))), "infix") expect_identical(call_print_type(quote(a == b)), "infix") expect_identical(call_print_type(quote(a:b)), "infix") expect_identical(call_print_type(quote(a::b)), "infix") expect_identical(call_print_type(quote(a:::b)), "infix") expect_identical(call_print_type(quote(a := b)), "infix") expect_identical(call_print_type(quote(a | b)), "infix") expect_identical(call_print_type(quote(a || b)), "infix") expect_identical(call_print_type(quote(a & b)), "infix") expect_identical(call_print_type(quote(a && b)), "infix") expect_identical(call_print_type(quote(a + b)), "infix") expect_identical(call_print_type(quote(a - b)), "infix") expect_identical(call_print_type(quote(a * b)), "infix") expect_identical(call_print_type(quote(a / b)), "infix") expect_identical(call_print_type(quote(a ^ b)), "infix") expect_identical(call_print_type(quote(a$b)), "infix") expect_identical(call_print_type(quote(a@b)), "infix") expect_identical(call_print_type(quote(a %% b)), "infix") expect_identical(call_print_type(quote(a %>% b)), "infix") expect_identical(call_print_type(quote(`?`(a, b, c))), "prefix") expect_identical(call_print_type(quote(`~`(a, b, c))), "prefix") expect_identical(call_print_type(quote(`<`(a, b, c))), "prefix") expect_identical(call_print_type(quote(`<=`(a, b, c))), "prefix") expect_identical(call_print_type(quote(`>`(a, b, c))), "prefix") expect_identical(call_print_type(quote(`>=`(a, b, c))), "prefix") expect_identical(call_print_type(quote(`==`(a, b, c))), "prefix") expect_identical(call_print_type(quote(`:`(a, b, c))), "prefix") expect_identical(call_print_type(quote(`:=`(a, b, c))), "prefix") expect_identical(call_print_type(quote(`|`(a, b, c))), "prefix") expect_identical(call_print_type(quote(`||`(a, b, c))), "prefix") expect_identical(call_print_type(quote(`&`(a, b, c))), "prefix") expect_identical(call_print_type(quote(`&&`(a, b, c))), "prefix") expect_identical(call_print_type(quote(`+`(a, b, c))), "prefix") expect_identical(call_print_type(quote(`-`(a, b, c))), "prefix") expect_identical(call_print_type(quote(`*`(a, b, c))), "prefix") expect_identical(call_print_type(quote(`/`(a, b, c))), "prefix") expect_identical(call_print_type(quote(`^`(a, b, c))), "prefix") expect_identical(call_print_type(quote(`%%`(a, b, c))), "prefix") expect_identical(call_print_type(quote(`%>%`(a, b, c))), "prefix") expect_identical(call_print_type(quote(`<-`(a, b, c))), "infix") expect_identical(call_print_type(quote(`<<-`(a, b, c))), "infix") expect_identical(call_print_type(quote(`=`(a, b, c))), "infix") expect_identical(call_print_type(quote(`::`(a, b, c))), "infix") expect_identical(call_print_type(quote(`:::`(a, b, c))), "infix") expect_identical(call_print_type(quote(`$`(a, b, c))), "infix") expect_identical(call_print_type(quote(`@`(a, b, c))), "infix") }) test_that("call_print_fine_type() returns correct enum", { expect_error(call_print_fine_type(""), "must be a call") expect_identical(call_print_fine_type(quote(foo())), "call") expect_identical(call_print_fine_type(quote(~a)), "prefix") expect_identical(call_print_fine_type(quote(?a)), "prefix") expect_identical_(call_print_fine_type(quote(!b)), "prefix") expect_identical_(call_print_fine_type(quote(`!!`(b))), "prefix") expect_identical_(call_print_fine_type(quote(`!!!`(b))), "prefix") expect_identical(call_print_fine_type(quote(+a)), "prefix") expect_identical(call_print_fine_type(quote(-a)), "prefix") expect_identical(call_print_fine_type(quote(while (a) b)), "control") expect_identical(call_print_fine_type(quote(for (a in b) b)), "control") expect_identical(call_print_fine_type(quote(repeat a)), "control") expect_identical(call_print_fine_type(quote(if (a) b)), "control") expect_identical(call_print_fine_type(quote((a))), "delim") expect_identical(call_print_fine_type(quote({ a })), "delim") expect_identical(call_print_fine_type(quote(a[b])), "subset") expect_identical(call_print_fine_type(quote(a[[b]])), "subset") expect_identical(call_print_fine_type(quote(a ? b)), "infix") expect_identical(call_print_fine_type(quote(a ~ b)), "infix") expect_identical(call_print_fine_type(quote(a <- b)), "infix") expect_identical(call_print_fine_type(quote(a <<- b)), "infix") expect_identical(call_print_fine_type(quote(a < b)), "infix") expect_identical(call_print_fine_type(quote(a <= b)), "infix") expect_identical(call_print_fine_type(quote(a > b)), "infix") expect_identical(call_print_fine_type(quote(a >= b)), "infix") expect_identical(call_print_fine_type(quote(`=`(a, b))), "infix") expect_identical(call_print_fine_type(quote(a == b)), "infix") expect_identical(call_print_fine_type(quote(a:b)), "infix") expect_identical(call_print_fine_type(quote(a::b)), "infix") expect_identical(call_print_fine_type(quote(a:::b)), "infix") expect_identical(call_print_fine_type(quote(a := b)), "infix") expect_identical(call_print_fine_type(quote(a | b)), "infix") expect_identical(call_print_fine_type(quote(a || b)), "infix") expect_identical(call_print_fine_type(quote(a & b)), "infix") expect_identical(call_print_fine_type(quote(a && b)), "infix") expect_identical(call_print_fine_type(quote(a + b)), "infix") expect_identical(call_print_fine_type(quote(a - b)), "infix") expect_identical(call_print_fine_type(quote(a * b)), "infix") expect_identical(call_print_fine_type(quote(a / b)), "infix") expect_identical(call_print_fine_type(quote(a ^ b)), "infix") expect_identical(call_print_fine_type(quote(a$b)), "infix") expect_identical(call_print_fine_type(quote(a@b)), "infix") expect_identical(call_print_fine_type(quote(a %% b)), "infix") expect_identical(call_print_fine_type(quote(a %>% b)), "infix") expect_identical(call_print_fine_type(quote(`?`(a, b, c))), "call") expect_identical(call_print_fine_type(quote(`~`(a, b, c))), "call") expect_identical(call_print_fine_type(quote(`<`(a, b, c))), "call") expect_identical(call_print_fine_type(quote(`<=`(a, b, c))), "call") expect_identical(call_print_fine_type(quote(`>`(a, b, c))), "call") expect_identical(call_print_fine_type(quote(`>=`(a, b, c))), "call") expect_identical(call_print_fine_type(quote(`==`(a, b, c))), "call") expect_identical(call_print_fine_type(quote(`:`(a, b, c))), "call") expect_identical(call_print_fine_type(quote(`:=`(a, b, c))), "call") expect_identical(call_print_fine_type(quote(`|`(a, b, c))), "call") expect_identical(call_print_fine_type(quote(`||`(a, b, c))), "call") expect_identical(call_print_fine_type(quote(`&`(a, b, c))), "call") expect_identical(call_print_fine_type(quote(`&&`(a, b, c))), "call") expect_identical(call_print_fine_type(quote(`+`(a, b, c))), "call") expect_identical(call_print_fine_type(quote(`-`(a, b, c))), "call") expect_identical(call_print_fine_type(quote(`*`(a, b, c))), "call") expect_identical(call_print_fine_type(quote(`/`(a, b, c))), "call") expect_identical(call_print_fine_type(quote(`^`(a, b, c))), "call") expect_identical(call_print_fine_type(quote(`%%`(a, b, c))), "call") expect_identical(call_print_fine_type(quote(`%>%`(a, b, c))), "call") expect_identical(call_print_fine_type(quote(`<-`(a, b, c))), "infix") expect_identical(call_print_fine_type(quote(`<<-`(a, b, c))), "infix") expect_identical(call_print_fine_type(quote(`=`(a, b, c))), "infix") expect_identical(call_print_fine_type(quote(`::`(a, b, c))), "infix") expect_identical(call_print_fine_type(quote(`:::`(a, b, c))), "infix") expect_identical(call_print_fine_type(quote(`$`(a, b, c))), "infix") expect_identical(call_print_fine_type(quote(`@`(a, b, c))), "infix") }) test_that("call_name() fails with namespaced objects (#670)", { expect_true(TRUE) return("Disabled for the 0.3.1 release") expect_error(call_name(~foo::bar), "`call` must be a quoted call") expect_error(call_name(~foo:::bar), "`call` must be a quoted call") }) test_that("call_ns() retrieves namespaces", { expect_error(call_ns(quote(foo)), "must be a quoted call") expect_null(call_ns(quote(foo()))) expect_identical(call_ns(quote(foo::bar())), "foo") expect_identical(call_ns(quote(foo:::bar())), "foo") }) rlang/tests/testthat/test-sym.R0000644000176200001440000000222213413464247016275 0ustar liggesuserscontext("sym") test_that("ensym() fails with calls", { capture_sym <- function(arg) ensym(arg) expect_identical(capture_sym(foo), quote(foo)) expect_error(capture_sym(foo(bar)), "Only strings can be converted to symbols") }) test_that("ensym() supports strings and symbols", { capture_sym <- function(arg) ensym(arg) expect_identical(capture_sym("foo"), quote(foo)) expect_identical(capture_sym(!!"foo"), quote(foo)) expect_identical(capture_sym(!!sym("foo")), quote(foo)) }) test_that("empty string is treated as the missing argument", { expect_identical(sym(""), missing_arg()) }) test_that("syms() supports symbols as well", { expect_identical(syms(list(quote(a), "b")), list(quote(a), quote(b))) }) test_that("is_symbol() matches `name`", { expect_true(is_symbol(sym("foo"))) expect_true(is_symbol(sym("foo"), "foo")) expect_false(is_symbol(sym("foo"), "bar")) }) test_that("is_symbol() matches any name in a vector", { expect_false(is_symbol(quote(C), letters)) expect_true(is_symbol(quote(c), letters)) }) test_that("must supply strings to sym()", { expect_error(sym(letters), "strings") expect_error(sym(1:2), "strings") }) rlang/tests/testthat/test-events.R0000644000176200001440000000101213563536377016777 0ustar liggesuserscontext("events") test_that("can't add an exit event at top-level", { expect_true(TRUE) # This can only be tested interactively if (FALSE) { local_exit(1) # Can't add an exit event at top level } }) test_that("can add an exit event within a non-top-level global frame", { local(envir = global_env(), { `_x` <- list() rlang:::local_exit(`_x` <- c(`_x`, "bar")) `_x` <- c(`_x`, "foo") }) expect_identical(env_get(global_env(), "_x"), list("foo", "bar")) env_unbind(global_env(), "_x") }) rlang/tests/testthat/test-nse-force.R0000644000176200001440000005452213611313634017351 0ustar liggesuserscontext("nse-force") test_that("interpolation does not recurse over spliced arguments", { var2 <- quote({foo; !! stop(); bar}) expr_var2 <- tryCatch(expr(list(!!! var2)), error = identity) expect_false(inherits(expr_var2, "error")) }) test_that("formulas containing unquote operators are interpolated", { var1 <- quo(foo) var2 <- local({ foo <- "baz"; quo(foo) }) f <- expr_interp(~list(!!var1, !!var2)) expect_identical(f, new_formula(NULL, call2("list", as_quosure(var1), as_quosure(var2)))) }) test_that("interpolation is carried out in the right environment", { f <- local({ foo <- "foo"; ~!!foo }) expect_identical(expr_interp(f), new_formula(NULL, "foo", env = f_env(f))) }) test_that("interpolation now revisits unquoted formulas", { f <- ~list(!!~!!stop("should not interpolate within formulas")) f <- expr_interp(f) # This used to be idempotent: expect_error(expect_false(identical(expr_interp(f), f)), "interpolate within formulas") }) test_that("formulas are not treated as quosures", { expect_identical(expr(a ~ b), quote(a ~ b)) expect_identical(expr(~b), quote(~b)) expect_identical(expr(!!~b), ~b) }) test_that("unquote operators are always in scope", { env <- child_env("base", foo = "bar") f <- with_env(env, ~(!!foo)) expect_identical(expr_interp(f), new_formula(NULL, "bar", env)) }) test_that("can interpolate in specific env", { foo <- "bar" env <- child_env(NULL, foo = "foo") expanded <- expr_interp(~!!foo) expect_identical(expanded, set_env(~"bar")) expanded <- expr_interp(~!!foo, env) expect_identical(expanded, set_env(~"foo")) }) test_that("can qualify operators with namespace", { expect_identical(quo(other::UQ(toupper("a"))), quo(other::"A")) expect_identical(quo(x$UQ(toupper("a"))), quo(x$"A")) }) test_that("unquoting is frame-consistent", { defun <- quote(!! function() NULL) env <- child_env("base") expect_identical(fn_env(expr_interp(defun, env)), env) }) test_that("unquoted quosure has S3 class", { quo <- quo(!! ~quo) expect_is(quo, "quosure") }) test_that("unquoted quosures are not guarded", { quo <- eval_tidy(quo(quo(!! ~quo))) expect_true(is_quosure(quo)) }) # !! ---------------------------------------------------------------------- test_that("`!!` binds tightly", { expect_identical_(expr(!!1 + 2 + 3), quote(1 + 2 + 3)) expect_identical_(expr(1 + !!2 + 3), quote(1 + 2 + 3)) expect_identical_(expr(1 + 2 + !!3 + 4), quote(1 + 2 + 3 + 4)) expect_identical_(expr(1 + !!(2) + 3), quote(1 + 2 + 3)) expect_identical_(expr(1 + 2 + !!3), quote(1 + 2 + 3)) expect_identical_(expr(1 + !!2 * 3), quote(1 + 2 * 3)) expect_identical_(expr(1 + !!2 * 3 + 4), quote(1 + 2 * 3 + 4)) expect_identical_(expr(1 * !!2:!!3 + 4), quote(1 * 2:3 + 4)) expect_identical_(expr(1 + 2 + !!3 * 4 + 5 + 6), quote(1 + 2 + 3 * 4 + 5 + 6)) expect_identical_(expr(1 + 2 * 3 : !!4 + 5 * 6 + 7), quote(1 + 2 * 3 : 4 + 5 * 6 + 7)) expect_identical_(expr(1 + 2 * 3 : !!4 + 5 * 6 + 7 * 8 : !!9 + 10 * 11), quote(1 + 2 * 3 : 4 + 5 * 6 + 7 * 8 : 9 + 10 * 11)) expect_identical_(expr(!!1 + !!2 * !!3:!!4 + !!5 * !!6 + !!7 * !!8:!!9 + !!10 * !!11), quote(1 + 2 * 3 : 4 + 5 * 6 + 7 * 8 : 9 + 10 * 11)) expect_identical_(expr(!!1 + !!2 + !!3 + !!4), quote(1 + 2 + 3 + 4)) expect_identical_(expr(!!1 + !!2 * !!3), quote(1 + 2 * 3)) # Local roots expect_identical_(expr(!!1 + !!2 * !!3 * !!4), quote(1 + 2 * 3 * 4)) expect_identical_(expr(1 == 2 + !!3 + 4), quote(1 == 2 + 3 + 4)) expect_identical_(expr(!!1 == !!2 + !!3 + !!4 + !!5 * !!6 * !!7), quote(1 == 2 + 3 + 4 + 5 * 6 * 7)) expect_identical_(expr(1 + 2 * 3:!!4:5), quote(1 + 2 * 3:4:5)) expect_identical_(expr(!!1 == !!2), quote(1 == 2)) expect_identical_(expr(!!1 <= !!2), quote(1 <= 2)) expect_identical_(expr(!!1 >= !!2), quote(1 >= 2)) expect_identical_(expr(!!1 * 2 != 3), quote(1 * 2 != 3)) expect_identical_(expr(!!1 * !!2 / !!3 > !!4), quote(1 * 2 / 3 > 4)) expect_identical_(expr(!!1 * !!2 > !!3 + !!4), quote(1 * 2 > 3 + 4)) expect_identical_(expr(1 <= !!2), quote(1 <= 2)) expect_identical_(expr(1 >= !!2 : 3), quote(1 >= 2 : 3)) expect_identical_(expr(1 > !!2 * 3 : 4), quote(1 > 2 * 3 : 4)) expect_identical_(expr(!!1^2^3), quote(1)) expect_identical_(expr(!!1^2^3 + 4), quote(1 + 4)) expect_identical_(expr(!!1^2 + 3:4), quote(1 + 3:4)) }) test_that("`!!` handles binary and unary `-` and `+`", { expect_identical_(expr(!!1 + 2), quote(1 + 2)) expect_identical_(expr(!!1 - 2), quote(1 - 2)) expect_identical_(expr(!!+1 + 2), quote(1 + 2)) expect_identical_(expr(!!-1 - 2), expr(`!!`(-1) - 2)) expect_identical_(expr(1 + -!!3 + 4), quote(1 + -3 + 4)) expect_identical_(expr(1 + ---+!!3 + 4), quote(1 + ---+3 + 4)) expect_identical_(expr(+1), quote(+1)) expect_identical_(expr(+-!!1), quote(+-1)) expect_identical_(expr(+-!!(1 + 1)), quote(+-2)) expect_identical_(expr(+-!!+-1), bquote(+-.(-1))) expect_identical_(expr(+-+-!!+1), quote(+-+-1)) expect_identical_(expr(+-+-!!-1), bquote(+-+-.(-1))) expect_identical_(expr(+-+-!!1 - 2), quote(+-+-1 - 2)) expect_identical_(expr(+-+-!!+-+1 + 2), bquote(+-+-.(-1) + 2)) expect_identical(expr(+-+-!!+-!1 + 2), quote(+-+-0L)) expect_identical_(expr(+-+-!!+-identity(1)), bquote(+-+-.(-1))) expect_identical_(expr(+-+-!!+-identity(1) + 2), bquote(+-+-.(-1) + 2)) }) test_that("`!!` handles special operators", { expect_identical(expr(!! 1 %>% 2), quote(1 %>% 2)) }) test_that("LHS of nested `!!` is expanded (#405)", { expect_identical_(expr(!!1 + foo(!!2) + !!3), quote(1 + foo(2) + 3)) expect_identical_(expr(!!1 + !!2 + foo(!!3) + !!4), quote(1 + 2 + foo(3) + 4)) }) test_that("operators with zero or one argument work (#652)", { expect_identical(quo(`/`()), new_quosure(quote(`/`()))) expect_identical(expr(`/`(2)), quote(`/`(2))) }) test_that("evaluates contents of `!!`", { expect_identical(expr(!!(1 + 2)), 3) }) test_that("quosures are not rewrapped", { var <- quo(!! quo(letters)) expect_identical(quo(!!var), quo(letters)) var <- new_quosure(local(~letters), env = child_env(current_env())) expect_identical(quo(!!var), var) }) test_that("UQ() fails if called without argument", { local_lifecycle_silence() quo <- quo(UQ(NULL)) expect_equal(quo, ~NULL) quo <- tryCatch(quo(UQ()), error = identity) expect_is(quo, "error") expect_match(quo$message, "must be called with an argument") }) # !!! --------------------------------------------------------------------- test_that("values of `!!!` spliced into expression", { f <- quo(f(a, !!! list(quote(b), quote(c)), d)) expect_identical(f, quo(f(a, b, c, d))) }) test_that("names within `!!!` are preseved", { f <- quo(f(!!! list(a = quote(b)))) expect_identical(f, quo(f(a = b))) }) test_that("`!!!` handles `{` calls", { expect_identical(quo(list(!!! quote({ foo }))), quo(list(foo))) }) test_that("splicing an empty vector works", { expect_identical(expr_interp(~list(!!! list())), ~list()) expect_identical(expr_interp(~list(!!! character(0))), ~list()) expect_identical(expr_interp(~list(!!! NULL)), ~list()) }) # This fails but doesn't seem needed if (FALSE) { test_that("serialised unicode in argument names is unserialised on splice", { skip("failing") nms <- with_latin1_locale({ exprs <- exprs("\u5e78" := 10) quos <- quos(!!! exprs) names(quos) }) expect_identical(as_bytes(nms), as_bytes("\u5e78")) expect_true(all(chr_encoding(nms) == "UTF-8")) }) } test_that("can't splice at top level", { expect_error_(expr(!!! letters), "top level") }) test_that("can splice function body even if not a `{` block", { fn <- function(x) { x } expect_identical(exprs(!!!fn_body(fn)), named_list(quote(x))) fn <- function(x) x expect_identical(exprs(!!!fn_body(fn)), named_list(quote(x))) }) test_that("splicing a pairlist has no side effect", { x <- pairlist(NULL) expr(foo(!!! x, y)) expect_identical(x, pairlist(NULL)) }) test_that("`!!!` works in prefix form", { expect_identical(exprs(`!!!`(1:2)), named_list(1L, 2L)) expect_identical(expr(list(`!!!`(1:2))), quote(list(1L, 2L))) expect_identical(quos(`!!!`(1:2)), quos_list(quo(1L), quo(2L))) expect_identical(quo(list(`!!!`(1:2))), new_quosure(quote(list(1L, 2L)))) }) test_that("can't use prefix form of `!!!` with qualifying operators", { expect_error_(expr(foo$`!!!`(bar)), "Prefix form of `!!!` can't be used with `\\$`") expect_error_(expr(foo@`!!!`(bar)), "Prefix form of `!!!` can't be used with `@`") expect_error_(expr(foo::`!!!`(bar)), "Prefix form of `!!!` can't be used with `::`") expect_error_(expr(foo:::`!!!`(bar)), "Prefix form of `!!!` can't be used with `:::`") expect_error_(expr(rlang::`!!!`(bar)), "Prefix form of `!!!` can't be used with `::`") expect_error_(expr(rlang:::`!!!`(bar)), "Prefix form of `!!!` can't be used with `:::`") }) test_that("can't supply multiple arguments to `!!!`", { expect_error_(expr(list(`!!!`(1, 2))), "Can't supply multiple arguments to `!!!`") expect_error_(exprs(`!!!`(1, 2)), "Can't supply multiple arguments to `!!!`") }) test_that("`!!!` doesn't modify spliced inputs by reference", { x <- 1:3 quos(!!! x) expect_identical(x, 1:3) x <- as.list(1:3) quos(!!! x) expect_identical(x, as.list(1:3)) x <- quote({ 1L; 2L; 3L }) quos(!!! x) expect_equal(x, quote({ 1L; 2L; 3L })) # equal because of srcrefs }) test_that("exprs() preserves spliced quosures", { out <- exprs(!!!quos(a, b)) expect_identical(out, exprs(!!quo(a), !!quo(b))) expect_identical(out, named_list(quo(a), quo(b))) }) test_that("!!! fails with non-vectors", { expect_error_(exprs(!!!env()), "not a vector") expect_error_(exprs(!!!function() NULL), "not a vector") expect_error_(exprs(!!!base::c), "not a vector") expect_error_(exprs(!!!base::`{`), "not a vector") expect_error_(exprs(!!!expression()), "not a vector") expect_error_(quos(!!!env()), "not a vector") expect_error_(quos(!!!function() NULL), "not a vector") expect_error_(quos(!!!base::c), "not a vector") expect_error_(quos(!!!base::`{`), "not a vector") expect_error_(quos(!!!expression()), "not a vector") expect_error_(expr(list(!!!env())), "not a vector") expect_error_(expr(list(!!!function() NULL)), "not a vector") expect_error_(expr(list(!!!base::c)), "not a vector") expect_error_(expr(list(!!!base::`{`)), "not a vector") expect_error_(expr(list(!!!expression())), "not a vector") expect_error_(list2(!!!env()), "not a vector") expect_error_(list2(!!!function() NULL), "not a vector") expect_error_(list2(!!!base::c), "not a vector") expect_error_(list2(!!!base::`{`), "not a vector") expect_error_(list2(!!!expression()), "not a vector") }) test_that("!!! succeeds with vectors, pairlists and language objects", { expect_identical_(exprs(!!!NULL), named_list()) expect_identical_(exprs(!!!pairlist(1)), named_list(1)) expect_identical_(exprs(!!!list(1)), named_list(1)) expect_identical_(exprs(!!!TRUE), named_list(TRUE)) expect_identical_(exprs(!!!1L), named_list(1L)) expect_identical_(exprs(!!!1), named_list(1)) expect_identical_(exprs(!!!1i), named_list(1i)) expect_identical_(exprs(!!!"foo"), named_list("foo")) expect_identical_(exprs(!!!bytes(0)), named_list(bytes(0))) expect_identical_(quos(!!!NULL), quos_list()) expect_identical_(quos(!!!pairlist(1)), quos_list(quo(1))) expect_identical_(quos(!!!list(1)), quos_list(quo(1))) expect_identical_(quos(!!!TRUE), quos_list(quo(TRUE))) expect_identical_(quos(!!!1L), quos_list(quo(1L))) expect_identical_(quos(!!!1), quos_list(quo(1))) expect_identical_(quos(!!!1i), quos_list(quo(1i))) expect_identical_(quos(!!!"foo"), quos_list(quo("foo"))) expect_identical_(quos(!!!bytes(0)), quos_list(quo(!!bytes(0)))) expect_identical_(expr(foo(!!!NULL)), quote(foo())) expect_identical_(expr(foo(!!!pairlist(1))), quote(foo(1))) expect_identical_(expr(foo(!!!list(1))), quote(foo(1))) expect_identical_(expr(foo(!!!TRUE)), quote(foo(TRUE))) expect_identical_(expr(foo(!!!1L)), quote(foo(1L))) expect_identical_(expr(foo(!!!1)), quote(foo(1))) expect_identical_(expr(foo(!!!1i)), quote(foo(1i))) expect_identical_(expr(foo(!!!"foo")), quote(foo("foo"))) expect_identical_(expr(foo(!!!bytes(0))), expr(foo(!!bytes(0)))) expect_identical_(list2(!!!NULL), list()) expect_identical_(list2(!!!pairlist(1)), list(1)) expect_identical_(list2(!!!list(1)), list(1)) expect_identical_(list2(!!!TRUE), list(TRUE)) expect_identical_(list2(!!!1L), list(1L)) expect_identical_(list2(!!!1), list(1)) expect_identical_(list2(!!!1i), list(1i)) expect_identical_(list2(!!!"foo"), list("foo")) expect_identical_(list2(!!!bytes(0)), list(bytes(0))) }) test_that("!!! calls as.list()", { as_quos_list <- function(x, env = empty_env()) { new_quosures(map(x, new_quosure, env = env)) } exp <- as.list(mtcars) expect_identical_(exprs(!!!mtcars), exp) expect_identical_(quos(!!!mtcars), as_quos_list(exp)) expect_identical_(expr(foo(!!!mtcars)), do.call(call, c(list("foo"), exp))) expect_identical_(list2(!!!mtcars), as.list(mtcars)) fct <- factor(c("a", "b")) exp <- set_names(as.list(fct), c("", "")) expect_identical_(exprs(!!!fct), exp) expect_identical_(quos(!!!fct), as_quos_list(exp)) expect_identical_(expr(foo(!!!fct)), do.call(call, c(list("foo"), exp))) expect_identical_(list2(!!!fct), as.list(fct)) }) test_that("!!! calls methods::as()", { as_quos_list <- function(x, env = empty_env()) { new_quosures(map(x, new_quosure, env = env)) } .Person <- setClass("Person", slots = c(name = "character", species = "character")) fievel <- .Person(name = "Fievel", species = "mouse") methods::setAs("Person", "list", function(from, to) list(name = from@name, species = from@species)) exp <- list(name = "Fievel", species = "mouse") expect_identical_(exprs(!!!fievel), exp) expect_identical_(quos(!!!fievel), as_quos_list(exp)) expect_identical_(expr(foo(!!!fievel)), quote(foo(name = "Fievel", species = "mouse"))) expect_identical_(list2(!!!fievel), exp) }) # bang --------------------------------------------------------------- test_that("single ! is not treated as shortcut", { expect_identical(quo(!foo), as_quosure(~!foo)) }) test_that("double and triple ! are treated as syntactic shortcuts", { var <- local(quo(foo)) expect_identical(quo(!! var), as_quosure(var)) expect_identical(quo(!! quo(foo)), quo(foo)) expect_identical(quo(list(!!! letters[1:3])), quo(list("a", "b", "c"))) }) test_that("`!!` works in prefixed calls", { var <- quo(cyl) expect_identical(expr_interp(~mtcars$`!!`(quo_squash(var))), ~mtcars$cyl) expect_identical(expr_interp(~foo$`!!`(quote(bar))), ~foo$bar) expect_identical(expr_interp(~base::`!!`(quote(list))()), ~base::list()) }) test_that("one layer of parentheses around !! is removed", { foo <- "foo" expect_identical(expr((!! foo)), "foo") expect_identical(expr(((!! foo))), quote(("foo"))) expect_identical(expr((!! foo) + 1), quote("foo" + 1)) expect_identical(expr(((!! foo)) + 1), quote(("foo") + 1)) expect_identical(expr((!! sym(foo))(bar)), quote(foo(bar))) expect_identical(expr(((!! sym(foo)))(bar)), quote((foo)(bar))) expect_identical(exprs((!! foo), ((!! foo))), named_list("foo", quote(("foo")))) }) test_that("parentheses are not removed if there's a tail", { expect_identical(expr((!! "a" + b)), quote(("a" + b))) }) test_that("can use prefix form of `!!` with qualifying operators", { expect_identical(expr(foo$`!!`(quote(bar))), quote(foo$bar)) expect_identical(expr(foo@`!!`(quote(bar))), quote(foo@bar)) expect_identical(expr(foo::`!!`(quote(bar))), quote(foo::bar)) expect_identical(expr(foo:::`!!`(quote(bar))), quote(foo:::bar)) expect_identical(expr(rlang::`!!`(quote(bar))), quote(rlang::bar)) expect_identical(expr(rlang:::`!!`(quote(bar))), quote(rlang:::bar)) }) test_that("can unquote within for loop (#417)", { # Checks for an issue caused by wrong refcount of unquoted objects x <- new_list(3) for (i in 1:3) { x[[i]] <- expr(!!i) } expect_identical(x, as.list(1:3)) for (i in 1:3) { x[[i]] <- quo(!!i) } expect_identical(x, map(1:3, new_quosure, env = empty_env())) for (i in 1:3) { x[[i]] <- quo(foo(!!i)) } exp <- list(quo(foo(1L)), quo(foo(2L)), quo(foo(3L))) expect_identical(x, exp) for (i in 1:3) { x[[i]] <- quo(foo(!!!i)) } expect_identical(x, exp) }) # quosures ----------------------------------------------------------- test_that("quosures are created for all informative formulas", { foo <- local(quo(foo)) bar <- local(quo(bar)) interpolated <- local(quo(list(!!foo, !!bar))) expected <- new_quosure(call2("list", as_quosure(foo), as_quosure(bar)), env = get_env(interpolated)) expect_identical(interpolated, expected) interpolated <- quo(!!interpolated) expect_identical(interpolated, expected) }) # dots_values() ------------------------------------------------------ test_that("can unquote-splice symbols", { spliced <- list2(!!! list(quote(`_symbol`))) expect_identical(spliced, list(quote(`_symbol`))) }) test_that("can unquote symbols", { expect_error_(dots_values(!! quote(.)), "`!!` in a non-quoting function") }) # := ----------------------------------------------------------------- test_that("`:=` unquotes its LHS as name unless `.unquote_names` is FALSE", { expect_identical(exprs(a := b), list(a = quote(b))) expect_identical(exprs(a := b, .unquote_names = FALSE), named_list(quote(a := b))) expect_identical(quos(a := b), quos_list(a = quo(b))) expect_identical(quos(a := b, .unquote_names = FALSE), quos_list(new_quosure(quote(a := b)))) expect_identical(dots_list(a := NULL), list(a = NULL)) expect_identical(dots_splice(a := NULL), list(a = NULL)) }) test_that("`:=` chaining is detected at dots capture", { expect_error(exprs(a := b := c), "chained") expect_error(quos(a := b := c), "chained") expect_error(dots_list(a := b := c), "chained") expect_error(dots_splice(a := b := c), "chained") }) # -------------------------------------------------------------------- test_that("Unquote operators fail when called outside quasiquoted arguments", { expect_qq_error <- function(object) expect_error(object, regexp = "within a quasiquoted argument") expect_qq_error(UQ()) expect_qq_error(UQS()) expect_qq_error(`!!`()) expect_qq_error(`!!!`()) expect_qq_error(a := b) }) test_that("`.data[[` unquotes", { foo <- "bar" expect_identical_(expr(.data[[foo]]), quote(.data[["bar"]])) expect_identical_(expr(deep(.data[[foo]])), quote(deep(.data[["bar"]]))) expect_identical_(exprs(.data[[foo]]), named_list(quote(.data[["bar"]]))) }) test_that("it is still possible to unquote manually within `.data[[`", { local_lifecycle_silence() foo <- "baz" expect_identical(expr(.data[[!!toupper(foo)]]), quote(.data[["BAZ"]])) }) test_that(".data[[ argument is not masked", { cyl <- "carb" expect_identical_(eval_tidy(expr(.data[[cyl]]), mtcars), mtcars$carb) }) test_that(".data[[ on the LHS of := fails", { expect_error(exprs(.data[["foo"]] := foo), "Can't use the `.data` pronoun on the LHS") }) test_that("it is still possible to use .data[[ in list2()", { .data <- mtcars expect_identical_(list2(.data$cyl), list(mtcars$cyl)) }) test_that("can defuse-and-label and interpolate with glue", { skip_if_not_installed("glue") env_bind_lazy(current_env(), var = letters) suffix <- "foo" expect_identical(glue_first_pass("{{var}}_{suffix}"), glue::glue("letters_{{suffix}}")) expect_identical(glue_unquote("{{var}}_{suffix}"), glue::glue("letters_foo")) expect_identical(exprs("{{var}}_{suffix}" := 1), exprs(letters_foo = 1)) }) test_that("unquoted strings are not interpolated with glue", { expect_identical_( list2(!!"{foo}" := 1), list(`{foo}` = 1) ) }) # Lifecycle ---------------------------------------------------------- test_that("unquoting with rlang namespace is deprecated", { expect_warning_(exprs(rlang::UQS(1:2)), regexp = "deprecated as of rlang 0.3.0") expect_warning_(quo(list(rlang::UQ(1:2))), regexp = "deprecated as of rlang 0.3.0") # Old tests expect_identical(quo(rlang::UQ(toupper("a"))), new_quosure("A", empty_env())) expect_identical(quo(list(rlang::UQS(list(a = 1, b = 2)))), quo(list(a = 1, b = 2))) quo <- quo(rlang::UQ(NULL)) expect_equal(quo, ~NULL) quo <- tryCatch(quo(rlang::UQ()), error = identity) expect_is(quo, "error") expect_match(quo$message, "must be called with an argument") expect_error_(dots_values(rlang::UQ(quote(.))), "`!!` in a non-quoting function") }) test_that("splicing language objects still works", { local_lifecycle_silence() expect_identical_(exprs(!!!~foo), named_list(~foo)) expect_identical_(exprs(!!!quote(foo(bar))), named_list(quote(foo(bar)))) expect_identical_(quos(!!!~foo), quos_list(quo(!!~foo))) expect_identical_(quos(!!!quote(foo(bar))), quos_list(quo(foo(bar)))) expect_identical_(expr(foo(!!!~foo)), expr(foo(!!~foo))) expect_identical_(expr(foo(!!!quote(foo(bar)))), expr(foo(foo(bar)))) expect_identical_(list2(!!!~foo), list(~foo)) expect_identical_(list2(!!!quote(foo(bar))), list(quote(foo(bar)))) }) test_that("can unquote string in function position", { expect_identical_(expr((!!"foo")()), quote("foo"())) }) test_that("{{ is a quote-unquote operator", { fn <- function(foo) expr(list({{ foo }})) expect_identical_(fn(bar), expr(list(!!quo(bar)))) expect_identical_(expr(list({{ letters }})), expr(list(!!quo(!!letters)))) expect_error_(expr(list({{ quote(foo) }})), "must be a symbol") }) test_that("{{ only works in quoting functions", { expect_error_( list2({{ "foo" }}), "Can't use `{{` in a non-quoting function", fixed = TRUE ) }) test_that("{{ on the LHS of :=", { foo <- "bar" expect_identical_(exprs({{ foo }} := NA), exprs(bar = NA)) foo <- quote(bar) expect_identical_(exprs({{ foo }} := NA), exprs(bar = NA)) foo <- quo(bar) expect_identical_(exprs({{ foo }} := NA), exprs(bar = NA)) fn <- function(foo) exprs({{ foo }} := NA) expect_identical_(fn(bar), exprs(bar = NA)) expect_error_(exprs({{ foo() }} := NA), "must be a symbol") }) test_that("can unquote-splice in atomic capture", { expect_identical_(chr("a", !!!c("b", "c"), !!!list("d")), c("a", "b", "c", "d")) }) test_that("can unquote-splice multiple times (#771)", { expect_identical(call2("foo", !!!list(1, 2), !!!list(3, 4)), quote(foo(1, 2, 3, 4))) expect_identical(list2(!!!list(1, 2), !!!list(3, 4)), list(1, 2, 3, 4)) expect_identical(exprs(!!!list(1, 2), !!!list(3, 4)), named_list(1, 2, 3, 4)) expect_identical(expr(foo(!!!list(1, 2), !!!list(3, 4))), quote(foo(1, 2, 3, 4))) }) rlang/tests/testthat/test-trace-collapse-eval.txt0000644000176200001440000000112213612375026021721 0ustar liggesusersFull: â–ˆ 1. └─rlang:::f() 2. ├─base::eval(quote(g())) 3. │ └─base::eval(quote(g())) 4. └─rlang:::g() 5. ├─base::eval(quote(trace_back(e, bottom = 0))) 6. │ └─base::eval(quote(trace_back(e, bottom = 0))) 7. └─rlang::trace_back(e, bottom = 0) Collapsed: â–ˆ 1. └─rlang:::f() 2. ├─[ base::eval(...) ] with 1 more call 4. └─rlang:::g() 5. ├─[ base::eval(...) ] with 1 more call 7. └─rlang::trace_back(e, bottom = 0) Branch: 1. rlang:::f() 4. rlang:::g() 7. rlang::trace_back(e, bottom = 0) rlang/tests/testthat/test-cnd-error-empty.txt0000644000176200001440000000050413612375010021121 0ustar liggesusers> # Branch (depth 0) > cat_line(branch0) Error: foo Execution halted > # Full > cat_line(full0) Error: foo Execution halted > # Branch (depth 1) > cat_line(branch1) Error: foo Backtrace: 1. global::f() Execution halted > # Full (depth 1) > cat_line(full1) Error: foo Backtrace: x 1. \-global::f() Execution halted rlang/tests/testthat/test-trace-collapse-magrittr-complete1.txt0000644000176200001440000000110613612375027024515 0ustar liggesusersFull: â–ˆ 1. └─NA %>% T() 2. ├─base::withVisible(eval(quote(`_fseq`(`_lhs`)), env, env)) 3. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 4. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 5. └─rlang:::`_fseq`(`_lhs`) 6. └─magrittr::freduce(value, `_function_list`) 7. ├─base::withVisible(function_list[[k]](value)) 8. └─function_list[[k]](value) 9. └─rlang:::T(.) Collapsed: â–ˆ 1. └─[ NA %>% T() ] with 7 more calls 9. └─rlang:::T(.) Branch: 9. rlang:::T(.) rlang/tests/testthat/setup-tests.R0000644000176200001440000000014413405732277017013 0ustar liggesusers # Until https://github.com/r-lib/testthat/issues/787 is fixed Sys.setenv("TESTTHAT_PKG" = "rlang") rlang/tests/testthat/test-trace-collapse-magrittr-incomplete-leading2.txt0000644000176200001440000000113613612375027026451 0ustar liggesusersFull: â–ˆ 1. └─F(NA) %>% F() %>% T() %>% F() %>% F() 2. ├─base::withVisible(eval(quote(`_fseq`(`_lhs`)), env, env)) 3. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 4. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 5. └─rlang:::`_fseq`(`_lhs`) 6. └─magrittr::freduce(value, `_function_list`) 7. └─function_list[[i]](value) 8. └─rlang:::T(.) Collapsed: â–ˆ 1. └─[ F(NA) %>% F() %>% T() %>% F() %>% F() ] with 6 more calls 8. └─rlang:::T(.) Branch: 1. rlang:::F(NA) 1. rlang:::F(.) 8. rlang:::T(.) rlang/tests/testthat/test-env-special.R0000644000176200001440000000522113460040614017663 0ustar liggesuserscontext("env-special") test_that("search_envs() includes the global and base env", { envs <- search_envs() expect_identical(envs[[1]], global_env()) expect_identical(envs[[length(envs)]], base_env()) }) test_that("search_envs() returns named environments", { expect_identical(names(search_envs()), c("global", search()[-1])) }) test_that("search_envs() returns an rlang_envs object", { expect_is(search_envs(), "rlang_envs") }) test_that("is_namespace() recognises namespaces", { expect_false(is_namespace(env())) expect_true(is_namespace(get_env(is_namespace))) }) test_that("env_name() returns proper environment name", { expect_identical(env_name(global_env()), "global") expect_identical(env_name(empty_env()), "empty") expect_identical(env_name(base_env()), "package:base") expect_identical(env_name(pkg_env("rlang")), "package:rlang") expect_identical(env_name(ns_imports_env("rlang")), "imports:rlang") expect_identical(env_name(ns_env("rlang")), "namespace:rlang") env <- structure(env(), name = "foobar") expect_identical(env_label(env), "foobar") }) test_that("env_label() returns memory address for anonymous envs", { env <- env() expect_identical(env_label(env), sexp_address(env)) }) test_that("is_attached() detects environments on the search path", { expect_false(is_attached("utils")) expect_true(is_attached("package:utils")) expect_true(is_attached(base_env())) expect_true(is_attached(global_env())) expect_false(is_attached(ns_env("base"))) }) test_that("ns_env() and ns_env_name() support primitive functions", { expect_true(is_reference(ns_env(base::list), ns_env("base"))) expect_true(is_reference(ns_env(base::`{`), ns_env("base"))) expect_identical(ns_env_name(base::list), "base") expect_identical(ns_env_name(base::`{`), "base") }) test_that("ns_env() and ns_env_name() support closures", { fn <- function() NULL environment(fn) <- env(ns_env("rlang")) expect_true(is_reference(ns_env(fn), ns_env("rlang"))) expect_identical(ns_env_name(fn), "rlang") }) test_that("ns_env_name() accepts environments", { expect_identical(ns_env_name(ns_env("base")), "base") }) test_that("ns_env() and ns_env_name() take the topenv()", { ns <- ns_env("rlang") local <- env(ns) expect_true(is_reference(ns_env(local), ns)) expect_identical(ns_env_name(local), "rlang") }) test_that("ns_env() and variants have default argument", { fn <- function() list(ns_env(), ns_imports_env(), ns_env_name()) environment(fn) <- ns_env("rlang") out <- fn() expect_true(is_reference(out[[1]], ns_env("rlang"))) expect_true(is_reference(out[[2]], ns_imports_env("rlang"))) expect_identical(out[[3]], "rlang") }) rlang/tests/testthat/test-trace-non-collapsed-eval0000644000176200001440000000054213612375027022045 0ustar liggesusersFull: â–ˆ 1. ├─base::eval() 2. └─base::.handleSimpleError(...) 3. └─rlang:::h(simpleError(msg, call)) Collapsed: â–ˆ 1. ├─[ base::eval() ] 2. └─base::.handleSimpleError(...) 3. └─rlang:::h(simpleError(msg, call)) Branch: 1. base::eval() 2. base::.handleSimpleError(...) 3. rlang:::h(simpleError(msg, call)) rlang/tests/testthat/test-arg.R0000644000176200001440000000207713557763676016267 0ustar liggesuserscontext("arg") test_that("matches arg", { myarg <- c("foo", "baz") expect_identical(arg_match(myarg, c("bar", "foo")), "foo") expect_error( regex = "`myarg` must be one of \"bar\" or \"baz\"", arg_match(myarg, c("bar", "baz")) ) }) test_that("informative error message on partial match", { myarg <- "f" expect_error( regex = "Did you mean \"foo\"?", arg_match(myarg, c("bar", "foo")) ) }) test_that("gets choices from function", { fn <- function(myarg = c("bar", "foo")) arg_match(myarg) expect_error(fn("f"), "Did you mean \"foo\"?") expect_identical(fn("foo"), "foo") }) test_that("is_missing() works with symbols", { x <- missing_arg() expect_true(is_missing(x)) }) test_that("is_missing() works with non-symbols", { expect_true(is_missing(missing_arg())) l <- list(missing_arg()) expect_true(is_missing(l[[1]])) expect_error(missing(l[[1]]), "invalid use") }) test_that("maybe_missing() forwards missing value", { x <- missing_arg() expect_true(is_missing(maybe_missing(x))) expect_false(is_missing(maybe_missing(1L))) }) rlang/tests/testthat/test-compat.R0000644000176200001440000000631013405732277016754 0ustar liggesuserscontext("compat") test_that("names() dispatches on environment", { env <- child_env(NULL, foo = "foo", bar = "bar") expect_identical(sort(names(env)), c("bar", "foo")) }) test_that("lazy objects are converted to tidy quotes", { env <- child_env(current_env()) lazy <- structure(list(expr = quote(foo(bar)), env = env), class = "lazy") expect_identical(compat_lazy(lazy), new_quosure(quote(foo(bar)), env)) lazy_str <- "foo(bar)" expect_identical(compat_lazy(lazy_str), quo(foo(bar))) lazy_lang <- quote(foo(bar)) expect_identical(compat_lazy(lazy_lang), quo(foo(bar))) lazy_sym <- quote(foo) expect_identical(compat_lazy(lazy_sym), quo(foo)) }) test_that("lazy_dots objects are converted to tidy quotes", { env <- child_env(current_env()) lazy_dots <- structure(class = "lazy_dots", list( lazy = structure(list(expr = quote(foo(bar)), env = env), class = "lazy"), lazy_lang = quote(foo(bar)) )) expected <- list( lazy = new_quosure(quote(foo(bar)), env), lazy_lang = quo(foo(bar)), quo(foo(bar)) ) expect_identical(compat_lazy_dots(lazy_dots, current_env(), "foo(bar)"), expected) }) test_that("unnamed lazy_dots are given default names", { lazy_dots <- structure(class = "lazy_dots", list( "foo(baz)", quote(foo(bar)) )) expected <- list( `foo(baz)` = quo(foo(baz)), `foo(bar)` = quo(foo(bar)), foobarbaz = quo(foo(barbaz)) ) dots <- compat_lazy_dots(lazy_dots, current_env(), foobarbaz = "foo(barbaz)", .named = TRUE) expect_identical(dots, expected) }) test_that("compat_lazy() handles missing arguments", { expect_identical(compat_lazy(), quo()) }) test_that("compat_lazy_dots() takes lazy objects", { lazy <- structure(list(expr = quote(foo), env = empty_env()), class = "lazy") expect_identical(compat_lazy_dots(lazy), named_list(new_quosure(quote(foo), empty_env()))) }) test_that("compat_lazy_dots() takes symbolic objects", { expect_identical(compat_lazy_dots(quote(foo), empty_env()), named_list(new_quosure(quote(foo), empty_env()))) expect_identical(compat_lazy_dots(quote(foo(bar)), empty_env()), named_list(new_quosure(quote(foo(bar)), empty_env()))) }) test_that("compat_lazy() demotes character vectors to strings", { expect_identical(compat_lazy_dots(NULL, current_env(), c("foo", "bar")), named_list(as_quosure(~foo))) }) test_that("compat_lazy() handles numeric vectors", { expect_identical(compat_lazy_dots(NULL, current_env(), NA_real_), named_list(set_env(quo(NA_real_)))) expect_warning(expect_identical(compat_lazy_dots(NULL, current_env(), 1:3), named_list(set_env(quo(1L)))), "Truncating vector") }) test_that("compat_lazy() handles bare formulas", { expect_identical(compat_lazy(~foo), quo(foo)) expect_identical(compat_lazy_dots(~foo), named_list(quo(foo))) }) test_that("trimws() trims", { x <- " foo. " expect_identical(trimws(x), "foo.") expect_identical(trimws(x, "l"), "foo. ") expect_identical(trimws(x, "r"), " foo.") }) test_that("map2() sets names", { expect_identical(map2(list(foo = NULL, bar = NULL), 1:2, function(...) NULL), list(foo = NULL, bar = NULL)) }) test_that("map2() discards recycled names", { expect_identical(map2(list(foo = NULL), 1:3, function(...) NULL), new_list(3)) }) rlang/tests/testthat/test-state.R0000644000176200001440000000205713563536377016625 0ustar liggesuserscontext("state") test_that("can't add an exit event at top-level", { expect_error(local_exit(1, global_env()), "Can't add an exit event at top-level") }) test_that("options are set temporarily", { local_options(foo = "foo") expect_identical(with_options(foo = "bar", peek_option("foo")), "bar") expect_identical(peek_option("foo"), "foo") }) test_that("peek_options() returns a named list", { local_options(foo = "FOO", bar = "BAR") expect_identical(peek_options("foo", "bar"), list(foo = "FOO", bar = "BAR")) }) test_that("is_interactive() is FALSE when testthat runs", { expect_false(is_interactive()) }) test_that("is_interactive() honors rlang_interactive option, above all else", { expect_true(with_options(rlang_interactive = TRUE, is_interactive())) expect_false(with_options(rlang_interactive = FALSE, is_interactive())) expect_error(with_options(rlang_interactive = NA, is_interactive()), "must be a single") local_interactive(FALSE) expect_false(is_interactive()) expect_true(with_interactive(value = TRUE, is_interactive())) }) rlang/tests/testthat/test-trace-global-prefix.txt0000644000176200001440000000032113612375027021726 0ustar liggesusersFull: â–ˆ 1. └─rlang:::g(current_env()) 2. └─global::f(e) Collapsed: â–ˆ 1. └─rlang:::g(current_env()) 2. └─global::f(e) Branch: 1. rlang:::g(current_env()) 2. global::f(e) rlang/tests/testthat/test-trace-collapse-magrittr-incomplete-leading1.txt0000644000176200001440000000015513612375027026450 0ustar liggesusersFull: â–ˆ 1. └─rlang:::T(NA) Collapsed: â–ˆ 1. └─rlang:::T(NA) Branch: 1. rlang:::T(NA) rlang/tests/testthat/helper-cli.R0000644000176200001440000000014313442745110016525 0ustar liggesusers cli_style <- cli_box_chars() skip_unless_utf8 <- function() { skip_if(!cli_is_utf8_output()) } rlang/tests/testthat/test-fn.R0000644000176200001440000002130513563536242016074 0ustar liggesuserscontext("function") test_that("new_function equivalent to regular function", { f1 <- function(x = a + b, y) { x + y } attr(f1, "srcref") <- NULL f2 <- new_function(alist(x = a + b, y =), quote({x + y})) expect_equal(f1, f2) env <- current_env() expect_true(is_reference(fn_env(f2), env)) }) test_that("prim_name() extracts names", { expect_equal(prim_name(c), "c") expect_equal(prim_name(prim_eval), "eval") }) test_that("as_closure() returns closure", { expect_identical(typeof(as_closure(base::list)), "closure") expect_identical(typeof(as_closure("list")), "closure") }) test_that("as_closure() handles primitive functions", { expect_identical(as_closure(`c`)(1, 3, 5), c(1, 3, 5)) expect_identical(as_closure(is.null)(1), FALSE) expect_identical(as_closure(is.null)(NULL), TRUE) }) test_that("as_closure() supports base-style and purrr-style arguments to binary operators", { and <- as_closure(`&&`) expect_error(and(), "Must supply `e1` or `.x` to binary operator") expect_error(and(TRUE), "Must supply `e2` or `.y` to binary operator") expect_error(and(.x = TRUE, e1 = TRUE), "Can't supply both `e1` and `.x` to binary operator") expect_error(and(TRUE, .y = TRUE, e2 = TRUE), "Can't supply both `e2` and `.y` to binary operator") expect_identical(and(FALSE, FALSE), FALSE) expect_identical(and(TRUE, FALSE), FALSE) expect_identical(and(FALSE, TRUE), FALSE) expect_identical(and(TRUE, TRUE), TRUE) expect_identical(and(.y = FALSE, TRUE), FALSE) expect_identical(and(e2 = FALSE, TRUE), FALSE) expect_identical(and(.y = FALSE, e1 = TRUE), FALSE) expect_identical(and(e2 = FALSE, .x = TRUE), FALSE) expect_identical(and(.y = FALSE, TRUE), FALSE) expect_identical(and(e2 = FALSE, TRUE), FALSE) }) test_that("as_closure() supports base-style and purrr-style arguments to versatile operators", { minus <- as_closure(`-`) expect_error(minus(), "Must supply `e1` or `.x` to binary operator") expect_error(minus(.y = 3), "Must supply `e1` or `.x` to binary operator") expect_error(minus(.x = 3, e1 = 1), "Can't supply both `e1` and `.x` to binary operator") expect_error(minus(0, .y = 3, e2 = 1), "Can't supply both `e2` and `.y` to binary operator") expect_identical(minus(3), -3) expect_identical(minus(e1 = 3), -3) expect_identical(minus(.x = 3), -3) expect_identical(minus(1, 3), -2) expect_identical(minus(3, 1), 2) expect_identical(minus(.y = 3, 1), -2) expect_identical(minus(e2 = 3, 1), -2) expect_identical(minus(.y = 3, e1 = 1), -2) expect_identical(minus(e2 = 3, .x = 1), -2) expect_identical(minus(.y = 1, 3), 2) expect_identical(minus(e2 = 1, 3), 2) }) test_that("as_closure(`||`) shortcircuits", { or <- as_closure(`||`) expect_error(or(), "Must supply `e1` or `.x` to binary operator") expect_error(or(FALSE), "Must supply `e2` or `.y` to binary operator") expect_identical(or(TRUE), TRUE) expect_identical(or(.x = TRUE), TRUE) expect_identical(or(e1 = TRUE), TRUE) }) test_that("as_closure() handles operators", { expect_identical(as_closure(`-`)(.y = 10, .x = 5), -5) expect_identical(as_closure(`-`)(5), -5) expect_identical(as_closure(`$`)(mtcars, cyl), mtcars$cyl) expect_identical(as_closure(`~`)(foo), ~foo) expect_identical(as_closure(`~`)(foo, bar), foo ~ bar) expect_warning(expect_identical(as_closure(`{`)(warn("foo"), 2, 3), 3), "foo") x <- "foo" as_closure(`<-`)(x, "bar") expect_identical(x, "bar") x <- list(a = 1, b = 2) as_closure(`$<-`)(x, b, 20) expect_identical(x, list(a = 1, b = 20)) x <- list(1, 2) as_closure(`[[<-`)(x, 2, 20) expect_identical(x, list(1, 20)) x <- data.frame(x = 1:2, y = 3:4) expect_identical(as_closure(`[<-`)(x, 2, 2, 10L), 10L) expect_identical(x, data.frame(x = 1:2, y = c(3L, 10L))) expect_error(as_closure(`[<-`)(), "Must supply operands") methods::setClass("rlang_test", methods::representation(foo = "character")) s4 <- methods::new("rlang_test") as_closure(`@<-`)(s4, "foo", "FOO") expect_identical(s4@foo, "FOO") x <- list(1, 2) expect_identical(as_closure(`[[<-`)(x, 2, 20), 20) expect_identical(x, list(1, 20)) x <- list2(list2(a = "A"), list2(a = "B")) expect_identical(lapply(x, as_closure(`[[`), "a"), list("A", "B")) }) test_that("lambda shortcut handles positional arguments", { expect_identical(as_function(~ ..1 + ..3)(1, 2, 3), 4) }) test_that("lambda shortcut fails with two-sided formulas", { expect_error(as_function(lhs ~ ..1 + ..3), "two-sided formula") }) test_that("as_function() handles strings", { expect_identical(as_function("mean"), mean) env <- env(fn = function() NULL) expect_identical(as_function("fn", env), env$fn) }) test_that("fn_fmls_syms() unnames `...`", { expect_identical(fn_fmls_syms(lapply), list(X = quote(X), FUN = quote(FUN), quote(...))) }) test_that("fn_fmls_syms() works with functions of zero arguments", { expect_identical(fn_fmls_syms(function() NULL), list()) }) test_that("as_closure() gives informative error messages on control flow primitives (#158)", { expect_error(as_closure(`if`), "Can't coerce the primitive function `if`") }) test_that("fn_fmls<- and fn_fmls_names<- change formals", { fn <- function() NULL fn_fmls(fn) <- list(a = 1) expect_identical(fn_fmls(fn), pairlist(a = 1)) fn_fmls_names(fn) <- c("b") expect_identical(fn_fmls(fn), pairlist(b = 1)) }) test_that("fn_ functions requires closures", { msg <- "must be an R function, not a primitive function" expect_error(fn_fmls(`+`), msg) expect_error(fn_fmls_names(`+`), msg) expect_error(fn_fmls_syms(`+`), msg) expect_error(fn_fmls(`+`) <- list(a = 1, b = 2), msg) expect_error(fn_fmls_names(`+`) <- c("A", "B"), msg) }) test_that("assignment methods preserve attributes", { orig <- structure(function(foo) NULL, foo = "foo", bar = "bar") fn <- orig fn_fmls(fn) <- list(arg = 1) expect_identical(attributes(fn), attributes(orig)) fn <- orig fn_fmls_names(fn) <- "bar" expect_identical(attributes(fn), attributes(orig)) fn <- orig fn_body(fn) <- "body" orig_attrs <- attributes(orig) orig_attrs$srcref <- NULL expect_identical(attributes(fn), orig_attrs) }) test_that("print method for `fn` discards attributes", { fn <- structure(function() NULL, foo = "foo") fn <- new_fn(fn) temp <- file() sink(temp) on.exit({ sink() close(temp) }) print(fn) output <- paste0(readLines(temp, warn = FALSE), collapse = "\n") expect_false(grepl("attr", output)) }) test_that("fn_body() requires a closure to extract body", { expect_error(fn_body(c), "`fn` is not a closure") expect_equal(fn_body(function() { NULL }), quote({ NULL })) expect_equal(fn_body(function() NULL), quote({ NULL })) }) test_that("fn_env() requires a function to extract env", { expect_error(fn_env(1L), "`fn` is not a function") expect_identical(fn_env(function() NULL), current_env()) }) test_that("`fn_env<-`() sets environment", { fn <- function() NULL fn_env(fn) <- base_env() expect_reference(fn_env(fn), base_env()) }) test_that("primitive predicates work", { expect_true(is_primitive_eager(c)) expect_true(is_primitive_lazy(`$`)) expect_false(is_primitive_eager(`$`)) expect_false(is_primitive_lazy(`c`)) }) test_that("quosures converted to functions ignore their arguments", { fn <- as_function(quo("foo")) expect_no_error(expect_identical(fn(NULL), "foo")) }) test_that("as_function() supports nested quosures", { quo <- local({ lhs <- "quux" rhs <- local({ rhs <- "hunoz"; quo(rhs) }) quo(paste(lhs, !!rhs)) }) fn <- as_function(quo) expect_identical(fn(), "quux hunoz") }) test_that("fn_body() always returns a `{` block", { expect_equal(fn_body(function() "foo"), quote({ "foo" })) }) test_that("as_function() adds a class to lambda functions", { out <- as_function(~foo) expect_is(out, c("rlang_lambda_function", "function")) expect_output(print(out), "") }) test_that("fn_env() returns base namespace for primitives", { expect_reference(fn_env(base::list), ns_env("base")) }) test_that("as_closure() wrappers dispatch properly", { local_bindings(.env = global_env(), as.character.foobar = function(...) "dispatched!" ) x <- structure(list(), class = "foobar") expect_identical(as_closure(as.character)(x), "dispatched!") }) test_that("as_closure() wrappers are not masked", { local_bindings( .env = global_env(), as.character = function(...) abort("tilt") ) expect_identical(as_closure(as.character)(1), "1") }) test_that("arguments of closured primitives are matched by name before `...` (tidyverse/purrr#411)", { expect_false(as_closure(isS4)("foo")) }) test_that("arguments of closured primitives are matched by name after `...`", { fn <- as_closure(min) expect_true(is_na(fn(1, NA))) expect_identical(fn(na.rm = TRUE, 1, NA), 1) }) rlang/tests/testthat/test-c-api.R0000644000176200001440000003610013567443111016455 0ustar liggesuserscontext("C API") r_string <- function(str) { stopifnot(is_string(str)) .Call(rlang_r_string, str) } test_that("chr_prepend() prepends", { out <- .Call(rlang_test_chr_prepend, c("foo", "bar"), r_string("baz")) expect_identical(out, c("baz", "foo", "bar")) }) test_that("chr_append() appends", { out <- .Call(rlang_test_chr_append, c("foo", "bar"), r_string("baz")) expect_identical(out, c("foo", "bar", "baz")) }) test_that("r_warn() signals", { handler <- function(c) expect_null(c$call) expect_warning(regexp = "foo", with_handlers(warning = calling(handler), .Call(rlang_test_r_warn, "foo") )) }) test_that("r_on_exit() adds deferred expr", { var <- chr() fn <- function() { .Call(rlang_test_r_on_exit, quote(var <<- c(var, "foo")), current_env()) var <<- c(var, "bar") } fn() expect_identical(var, c("bar", "foo")) }) test_that("r_is_special_op_sym() detects special operators", { is_special_op <- function(x) .Call(rlang_test_is_special_op_sym, x) expect_false(is_special_op(quote(foo))) expect_true(is_special_op(quote(`%>%`))) expect_false(is_special_op(quote(`%>>`))) expect_false(is_special_op(quote(`%%`))) }) test_that("r_base_ns_get() fail if object does not exist", { expect_error(.Call(rlang_test_base_ns_get, "foobar")) }) test_that("r_current_frame() returns current frame", { current_frame <- function() { list(.Call(rlang_test_current_frame), environment()) } out <- current_frame() expect_identical(out[[1]], out[[2]]) }) test_that("r_sys_frame() returns current frame environment", { sys_frame <- function(..., .n = 0L) { list(.Call(rlang_test_sys_frame, .n), sys.frame(.n)) } out <- sys_frame(foo(), bar) expect_identical(out[[1]], out[[2]]) wrapper <- function(...) { sys_frame(.n = -1L) } out <- wrapper(foo(), bar) expect_identical(out[[1]], out[[2]]) }) test_that("r_sys_call() returns current frame call", { sys_call <- function(..., .n = 0L) { list(.Call(rlang_test_sys_call, .n), sys.call(.n)) } out <- sys_call(foo(), bar) expect_identical(out[[1]], out[[2]]) wrapper <- function(...) { sys_call(.n = -1L) } out <- wrapper(foo(), bar) expect_identical(out[[1]], out[[2]]) }) test_that("r_which_operator() returns correct tokens", { expect_identical(which_operator(quote(foo())), "") expect_identical(which_operator(""), "") expect_identical(which_operator(quote(?a)), "?unary") expect_identical(which_operator(quote(a ? b)), "?") expect_identical(which_operator(quote(while (a) b)), "while") expect_identical(which_operator(quote(for (a in b) b)), "for") expect_identical(which_operator(quote(repeat a)), "repeat") expect_identical(which_operator(quote(if (a) b)), "if") expect_identical(which_operator(quote(a <- b)), "<-") expect_identical(which_operator(quote(a <<- b)), "<<-") expect_identical(which_operator(quote(a < b)), "<") expect_identical(which_operator(quote(a <= b)), "<=") expect_identical(which_operator(quote(`<--`(a, b))), "") expect_identical(which_operator(quote(`<<--`(a, b))), "") expect_identical(which_operator(quote(`<==`(a, b))), "") expect_identical(which_operator(quote(a > b)), ">") expect_identical(which_operator(quote(a >= b)), ">=") expect_identical(which_operator(quote(`>-`(a, b))), "") expect_identical(which_operator(quote(`>==`(a, b))), "") expect_identical(which_operator(quote(`=`(a, b))), "=") expect_identical(which_operator(quote(a == b)), "==") expect_identical(which_operator(quote(`=-`(a, b))), "") expect_identical(which_operator(quote(`==-`(a, b))), "") expect_identical(which_operator(quote(~a)), "~unary") expect_identical(which_operator(quote(a ~ b)), "~") expect_identical(which_operator(quote(`~-`(a))), "") expect_identical(which_operator(quote(a:b)), ":") expect_identical(which_operator(quote(a::b)), "::") expect_identical(which_operator(quote(a:::b)), ":::") expect_identical(which_operator(quote(a := b)), ":=") expect_identical(which_operator(quote(`:-`(a, b))), "") expect_identical(which_operator(quote(`::-`(a, b))), "") expect_identical(which_operator(quote(`:::-`(a, b))), "") expect_identical(which_operator(quote(`:=-`(a, b))), "") expect_identical(which_operator(quote(a | b)), "|") expect_identical(which_operator(quote(a || b)), "||") expect_identical(which_operator(quote(`|-`(a, b))), "") expect_identical(which_operator(quote(`||-`(a, b))), "") expect_identical(which_operator(quote(a & b)), "&") expect_identical(which_operator(quote(a && b)), "&&") expect_identical(which_operator(quote(`&-`(a, b))), "") expect_identical(which_operator(quote(`&&-`(a, b))), "") expect_identical_(which_operator(quote(!b)), "!") expect_identical_(which_operator(quote(`!!`(b))), "!!") expect_identical_(which_operator(quote(`!!!`(b))), "!!!") expect_identical_(which_operator(quote(`!-`(a, b))), "") expect_identical_(which_operator(quote(`!!-`(a, b))), "") expect_identical_(which_operator(quote(`!!!-`(a, b))), "") expect_identical_(which_operator(quote(!?b)), "!") expect_identical_(which_operator(quote(!!?b)), "!") expect_identical(which_operator(quote(+a)), "+unary") expect_identical(which_operator(quote(a + b)), "+") expect_identical(which_operator(quote(`+-`(a))), "") expect_identical(which_operator(quote(-a)), "-unary") expect_identical(which_operator(quote(a - b)), "-") expect_identical(which_operator(quote(`--`(a))), "") expect_identical(which_operator(quote(a * b)), "*") expect_identical(which_operator(quote(a / b)), "/") expect_identical(which_operator(quote(a ^ b)), "^") expect_identical(which_operator(quote(a$b)), "$") expect_identical(which_operator(quote(a@b)), "@") expect_identical(which_operator(quote(a[b])), "[") expect_identical(which_operator(quote(a[[b]])), "[[") expect_identical(which_operator(quote(`*-`(a, b))), "") expect_identical(which_operator(quote(`/-`(a, b))), "") expect_identical(which_operator(quote(`^-`(a, b))), "") expect_identical(which_operator(quote(`$-`(a, b))), "") expect_identical(which_operator(quote(`@-`(a, b))), "") expect_identical(which_operator(quote(`[-`(a, b))), "") expect_identical(which_operator(quote(`[[-`(a, b))), "") expect_identical(which_operator(quote(a %% b)), "%%") expect_identical(which_operator(quote(a %>% b)), "special") expect_identical(which_operator(quote(`%%-`(a))), "") expect_identical(which_operator(quote((a))), "(") expect_identical(which_operator(quote({ a })), "{") expect_identical(which_operator(quote(`(-`(a))), "") expect_identical(which_operator(quote(`{-`(a))), "") }) test_that("client library passes tests", { skip_on_cran() skip_on_ci() # Silence package building and embedded tests output temp <- file() sink(temp) on.exit({ sink() close(temp) }) # tools::testInstalledPackage() can't find the package if we install # to a temporary library if (FALSE) { old_libpaths <- .libPaths() temp_lib <- tempfile("temp_lib") dir.create(temp_lib) .libPaths(c(temp_lib, old_libpaths)) on.exit(.libPaths(old_libpaths), add = TRUE) } else { temp_lib <- .libPaths() } zip_file <- normalizePath(file.path("fixtures", "lib.zip")) src_path <- normalizePath(file.path("fixtures", "rlanglibtest")) # Set temporary dir to install and test the embedded package so we # don't have to clean leftovers files temp_test_dir <- tempfile("temp_test_dir") dir.create(temp_test_dir) old <- setwd(temp_test_dir) on.exit(setwd(old), add = TRUE) file.copy(src_path, temp_test_dir, overwrite = TRUE, recursive = TRUE) pkg_path <- file.path(temp_test_dir, "rlanglibtest") # We store the library as a zip to avoid VCS noise. Use # fixtures/Makefile to regenerate it. utils::unzip(zip_file, exdir = file.path(pkg_path, "src")) install.packages(pkg_path, repos = NULL, type = "source", lib = temp_lib, INSTALL_opts = "--install-tests", verbose = FALSE, quiet = TRUE ) result <- tools::testInstalledPackage("rlanglibtest", lib.loc = temp_lib, types = "test") expect_identical(result, 0L) }) test_that("r_env_unbind() removes objects", { env <- env(a = 1L) r_env_unbind(env, "a") expect_false(env_has(env, "a")) env <- env(a = 1L) child <- child_env(env) expect_warning(r_env_unbind(child, "a"), "not found") r_env_unbind(child, "a", inherits = TRUE) expect_false(env_has(env, "a")) }) node_list_clone_until <- function(node, sentinel) { .Call(rlang_test_node_list_clone_until, node, sentinel) } test_that("can clone-until with NULL list", { expect_identical(node_list_clone_until(NULL, pairlist()), list(NULL, NULL)) }) test_that("can clone-until with NULL sentinel", { node <- pairlist(a = 1, b = 2, c = 3) out <- node_list_clone_until(node, NULL) sentinel_out <- out[[2]] expect_reference(node_cddr(out[[1]]), sentinel_out) node_out <- out[[1]] expect_identical(node_out, pairlist(a = 1, b = 2, c = 3)) while (!is_null(node_out)) { expect_false(is_reference(node_out, node)) node_out <- node_cdr(node_out) node <- node_cdr(node) } }) test_that("returned sentinel and value are NULL if couldn't be found", { node <- pairlist(a = NULL) out <- node_list_clone_until(node, pairlist(NULL)) expect_false(is_reference(out[[1]], node)) expect_null(out[[1]]) expect_null(out[[2]]) }) test_that("can clone until sentinel", { node1 <- pairlist(a = 1, b = 2, c = 3) node2 <- node_cdr(node1) node3 <- node_cdr(node2) out <- node_list_clone_until(node1, node2) # No modification by reference of original list expect_false(is_reference(out, node1)) expect_true(is_reference(node_cdr(node1), node2)) expect_true(is_reference(node_cdr(node2), node3)) node_out <- out[[1]] expect_identical(node_out, pairlist(a = 1, b = 2, c = 3)) expect_false(is_reference(node_out, node1)) expect_true(is_reference(node_cdr(node_out), node2)) expect_true(is_reference(node_out, out[[2]])) }) get_attributes <- function(x) { .Call(rlang_get_attributes, x) } c_set_attribute <- function(x, name, value) { .Call(rlang_test_set_attribute, x, sym(name), value) } test_that("r_set_attribute() sets elements", { x <- list() out1 <- c_set_attribute(x, "foo", 1L) attrs1 <- get_attributes(out1) expect_identical(attrs1, pairlist(foo = 1L)) expect_false(is_reference(x, out1)) expect_null(get_attributes(x)) out2 <- c_set_attribute(out1, "bar", 2L) attrs2 <- get_attributes(out2) expect_identical(attrs2, pairlist(bar = 2L, foo = 1L)) expect_reference(get_attributes(out1), attrs1) expect_reference(node_cdr(attrs2), attrs1) }) test_that("r_set_attribute() zaps one element", { x <- structure(list(), foo = 1) attrs <- get_attributes(x) out <- c_set_attribute(x, "foo", NULL) expect_reference(get_attributes(x), attrs) expect_null(get_attributes(out)) }) test_that("r_set_attribute() zaps several elements", { x <- structure(list(), foo = 1, bar = 2, baz = 3) attrs <- get_attributes(x) out1 <- c_set_attribute(x, "foo", NULL) attrs1 <- get_attributes(out1) expect_identical(attrs1, pairlist(bar = 2, baz = 3)) expect_true(is_reference(attrs1, node_cdr(attrs))) expect_true(is_reference(node_cdr(attrs1), node_cddr(attrs))) out2 <- c_set_attribute(x, "bar", NULL) attrs2 <- get_attributes(out2) expect_identical(attrs2, pairlist(foo = 1, baz = 3)) expect_false(is_reference(attrs2, attrs)) expect_true(is_reference(node_cdr(attrs2), node_cddr(attrs))) out3 <- c_set_attribute(x, "baz", NULL) attrs3 <- get_attributes(out3) expect_identical(attrs3, pairlist(foo = 1, bar = 2)) expect_false(is_reference(attrs3, attrs)) expect_false(is_reference(node_cdr(attrs3), node_cdr(attrs))) }) test_that("can zap non-existing attributes", { x <- list() out <- c_set_attribute(x, "foo", NULL) expect_identical(out, list()) expect_false(is_reference(x, out)) x2 <- structure(list(), foo = 1, bar = 2) out2 <- c_set_attribute(x2, "baz", NULL) attrs2 <- get_attributes(out2) expect_identical(attrs2, pairlist(foo = 1, bar = 2)) expect_reference(attrs2, get_attributes(x2)) }) test_that("r_parse()", { expect_equal(.Call(rlang_test_parse, "{ foo; bar }"), quote({ foo; bar })) expect_error(.Call(rlang_test_parse, "foo; bar"), "single expression") expect_error(.Call(rlang_test_parse, "foo\n bar"), "single expression") }) test_that("r_parse_eval()", { foo <- "quux" expect_identical(r_parse_eval("toupper(foo)"), "QUUX") expect_error(r_parse_eval("toupper(foo); foo"), "single expression") }) test_that("failed parses are printed if `rlang__verbose_errors` is non-NULL", { err <- catch_cnd(expect_output( regexp = "foo; bar", with_options(rlang__verbose_errors = TRUE, .Call(rlang_test_parse, "foo; bar") ) )) expect_error(cnd_signal(err), regexp = "single expression") }) test_that("r_warn_deprecated() warns once", { expect_warning(warn_deprecated("retired", "foo"), "retired") expect_no_warning(warn_deprecated("retired", "foo")) expect_warning(warn_deprecated("retired", "bar"), "retired") }) test_that("r_nms_are_duplicated() detects duplicates", { out <- r_nms_are_duplicated(letters) expect_identical(out, rep(FALSE, length(letters))) out <- r_nms_are_duplicated(c("a", "b", "a", "a", "c", "c")) expect_identical(out, c(FALSE, FALSE, TRUE, TRUE, FALSE, TRUE)) }) test_that("r_nms_are_duplicated() handles empty and missing names", { out <- r_nms_are_duplicated(c("a", NA, NA, "b", "", "", "a")) expect_identical(out, c(FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE)) }) test_that("r_lgl_sum() handles NA", { expect_identical(r_lgl_sum(lgl(TRUE, FALSE), TRUE), 1L) expect_identical(r_lgl_sum(lgl(TRUE, NA), TRUE), 2L) expect_identical(r_lgl_sum(lgl(TRUE, NA), FALSE), 1L) }) test_that("r_lgl_which() handles NA", { expect_identical(r_lgl_which(lgl(TRUE, FALSE), TRUE), 1L) expect_identical(r_lgl_which(lgl(TRUE, FALSE), FALSE), 1L) expect_identical(r_lgl_which(lgl(TRUE, NA), TRUE), int(1L, NA)) expect_identical(r_lgl_which(lgl(TRUE, NA), FALSE), 1L) }) test_that("r_lgl_which() handles empty vectors", { expect_identical(r_lgl_which(lgl(), TRUE), int()) expect_identical(r_lgl_which(lgl(), FALSE), int()) }) test_that("r_lgl_which() handles `NA` when propagation is disabled (#750)", { expect_identical(r_lgl_which(lgl(TRUE, FALSE, NA), FALSE), int(1)) expect_identical(r_lgl_which(lgl(TRUE, FALSE, NA, TRUE), FALSE), int(1, 4)) expect_identical(r_lgl_which(lgl(TRUE, NA, FALSE, NA, TRUE, FALSE, TRUE), FALSE), int(1, 5, 7)) }) test_that("r_node_list_reverse() reverses destructively", { x <- pairlist(1) y <- node_list_reverse(x) expect_true(is_reference(x, y)) x <- pairlist(1, 2) n1 <- x n2 <- node_cdr(x) y <- node_list_reverse(x) expect_identical(y, pairlist(2, 1)) expect_true(is_reference(x, n1)) expect_true(is_reference(y, n2)) expect_true(is_reference(node_cdr(y), n1)) expect_true(is_null(node_cdr(n1))) x <- pairlist(1, 2, 3) n1 <- x n2 <- node_cdr(x) n3 <- node_cddr(x) y <- node_list_reverse(x) expect_identical(y, pairlist(3, 2, 1)) expect_true(is_reference(x, n1)) expect_true(is_reference(y, n3)) expect_true(is_reference(node_cdr(y), n2)) expect_true(is_reference(node_cddr(y), n1)) expect_true(is_null(node_cdr(n1))) }) rlang/tests/testthat/test-attr.R0000644000176200001440000000322713552030327016435 0ustar liggesuserscontext("attributes") test_that("names2() takes care of missing values", { x <- set_names(1:3, c("a", NA, "b")) expect_identical(names2(x), c("a", "", "b")) }) test_that("names2() fails for environments", { expect_error(names2(env()), "Use `env_names()` for environments.", fixed = TRUE) }) test_that("inputs must be valid", { expect_error(set_names(environment()), "must be a vector") expect_error(set_names(1:10, letters[1:4]), "same length") }) test_that("can supply vector or ...", { expect_named(set_names(1:2, c("a", "b")), c("a", "b")) expect_named(set_names(1:2, "a", "b"), c("a", "b")) expect_named(set_names(1:2, 1, 2), c("1", "2")) }) test_that("can supply function/formula to rename", { x <- c(a = 1, b = 2) expect_named(set_names(x, toupper), c("A", "B")) expect_named(set_names(x, ~ toupper(.)), c("A", "B")) expect_named(set_names(x, paste, "foo"), c("a foo", "b foo")) }) test_that("set_names() zaps names", { expect_null(names(set_names(mtcars, NULL))) }) test_that("set_names() coerces to character", { expect_identical(set_names(1L, TRUE), c(`TRUE` = 1L)) expect_identical(set_names(1:2, "a", TRUE), c(a = 1L, `TRUE` = 2L)) }) test_that("has_name() works with pairlists", { expect_true(has_name(fn_fmls(`[.data.frame`), "drop")) }) test_that("set_names() first names the vector before applying a function (#688)", { exp <- set_names(letters, toupper(letters)) expect_identical(set_names(set_names(letters), toupper), exp) expect_identical(set_names(letters, toupper), exp) }) test_that("set_names2() fills in empty names", { chr <- c("a", b = "B", "c") expect_equal(set_names2(chr), c(a = "a", b = "B", c = "c")) }) rlang/tests/testthat/test-trace-unexported-prefix.txt0000644000176200001440000000064513612375027022674 0ustar liggesusersFull: â–ˆ 1. └─rlang:::f() 2. └─rlanglibtest:::test_trace_unexported_child(e) 3. └─rlanglibtest:::test_trace_unexported(e) Collapsed: â–ˆ 1. └─rlang:::f() 2. └─rlanglibtest:::test_trace_unexported_child(e) 3. └─rlanglibtest:::test_trace_unexported(e) Branch: 1. rlang:::f() 2. rlanglibtest:::test_trace_unexported_child(e) 3. rlanglibtest:::test_trace_unexported(e) rlang/tests/testthat/test-trace-backtrace-branch-first-frame.txt0000644000176200001440000000031313612375027024563 0ustar liggesusersFull: â–ˆ 1. ├─rlang:::gen() 2. └─rlang:::gen.default() Collapsed: â–ˆ 1. ├─[ rlang:::gen() ] 2. └─rlang:::gen.default() Branch: 1. rlang:::gen() 2. rlang:::gen.default() rlang/tests/testthat/test-sexp.R0000644000176200001440000000166013405732277016453 0ustar liggesuserscontext("sexp") test_that("poke_type() changes object type", { x <- new_node(quote(foo), NULL) out <- withVisible(poke_type(x, "language")) expect_false(out$visible) expect_identical(out$value, x) expect_identical(typeof(x), "language") }) test_that("can access promise properties", { fn <- function(...) { list(node_car(get("..."))) } prom <- fn(foo) expect_identical(promise_expr(prom[[1]]), quote(foo)) expect_identical(promise_env(prom[[1]]), current_env()) }) test_that("can pluck promise and its properties from env", { fn <- function(x) { list( promise_expr("x"), promise_env("x") ) } expect_identical(fn(foo), list(quote(foo), current_env())) }) test_that("can pluck promise value", { fn <- function(x) promise_value("x") expect_identical(fn(foo), sym("R_UnboundValue")) fn <- function(x) { force(x); promise_value("x") } foo <- "foo" expect_identical(fn(foo), "foo") }) rlang/tests/testthat/test-cnd-error-parent-default.txt0000644000176200001440000000046613612375014022711 0ustar liggesusers High-level message Backtrace: 1. rlang::catch_cnd(a()) 8. rlang:::a() 9. rlang:::b() 10. rlang:::c() High-level message Backtrace: 1. rlang::with_options(catch_cnd(a()), `rlang:::force_unhandled_error` = TRUE) 9. rlang:::a() 10. rlang:::b() 11. rlang:::c() rlang/tests/testthat/test-cnd-error-parent.txt0000644000176200001440000000060313612375012021256 0ustar liggesusers> # Interactive > cat_line(interactive) Error: bar Run `rlang::last_error()` to see where the error occurred. Execution halted > # Non-interactive > cat_line(non_interactive) Error: bar Backtrace: x 1. \-global::a() 2. \-global::b() 3. \-global::c() Backtrace: x 1. \-global::f() 2. \-global::g() 3. \-global::h() Execution halted rlang/tests/testthat/test-trace-degenerate-sym.txt0000644000176200001440000000011713612375027022107 0ustar liggesusersFull: â–ˆ 1. └─foo Collapsed: â–ˆ 1. └─foo Branch: 1. foo rlang/tests/testthat/test-weakref.R0000644000176200001440000000276213500531447017114 0ustar liggesuserscontext("weakref") test_that("weakref with key and no value allows key to be GC'd", { # This is the case when a weakref is used like a weak pointer (with no # value). k <- env() w_finalized <- FALSE w <- new_weakref(key = k, finalizer = function(e) { message("w finalized"); w_finalized <<- TRUE }) expect_identical(wref_key(w), k) expect_identical(wref_value(w), NULL) expect_false(w_finalized) rm(k) gc() expect_identical(wref_key(w), NULL) expect_true(w_finalized) }) test_that("key keeps value alive", { # Key and value: key keeps value alive k <- env() k_finalized <- FALSE reg.finalizer(k, function(e) { k_finalized <<- TRUE }) v <- env() v$x <- "hello" v_finalized <- FALSE reg.finalizer(v, function(e) { v_finalized <<- TRUE }) w_finalized <- FALSE w <- new_weakref( key = k, value = v, finalizer = function(e) { w_finalized <<- TRUE } ) expect_identical(wref_key(w), k) expect_identical(wref_value(w), v) # As long as the key is reachable, the value stays alive. rm(v) gc() expect_false(v_finalized) expect_identical(wref_value(w)$x, "hello") # Even if the weakref object is unreachable, it still exists, so as long as the key is # reachable, it keeps the value alive. rm(w) gc() expect_false(v_finalized) expect_false(w_finalized) # When the key becomes unreachable, that allows the weakref and value to be # GC'd. rm(k) gc() expect_true(k_finalized) expect_true(v_finalized) expect_true(w_finalized) }) rlang/tests/testthat/test-lifecycle.R0000644000176200001440000001051613563536104017427 0ustar liggesuserscontext("lifecycle") test_that("signal_soft_deprecated() warns when called from global env", { old <- Sys.getenv("TESTTHAT_PKG") Sys.setenv("TESTTHAT_PKG" = "") on.exit(Sys.setenv("TESTTHAT_PKG" = old)) retired <- function(id) signal_soft_deprecated("foo", id) env_bind(global_env(), retired = retired) on.exit(env_unbind(global_env(), "retired"), add = TRUE) with_options(lifecycle_verbose_soft_deprecation = FALSE, { locally({ expect_no_warning(retired("rlang_test3"), "foo") }) }) with_options(lifecycle_verbose_soft_deprecation = FALSE, { with_env(global_env(), { expect_warning(retired("rlang_test4"), "foo") }) }) }) test_that("signal_soft_deprecated() warns when called from package being tested", { Sys.setenv("NOT_CRAN" = "true") on.exit(Sys.setenv("NOT_CRAN" = "")) retired <- function() signal_soft_deprecated("warns from package being tested") expect_warning(retired(), "warns from") }) test_that("signal_soft_deprecated() warns when option is set", { retired <- function(id) signal_soft_deprecated("foo", id) with_options(lifecycle_verbose_soft_deprecation = TRUE, { expect_warning(retired("rlang_test5"), "foo") }) }) test_that("warn_deprecated() repeats warnings when option is set", { local_options(lifecycle_verbose_soft_deprecation = TRUE) retired1 <- function() signal_soft_deprecated("soft deprecated repeats") retired2 <- function() warn_deprecated("deprecated repeats") expect_warning(retired1(), "repeats") expect_warning(retired2(), "repeats") expect_no_warning(retired1()) expect_no_warning(retired2()) local_options(lifecycle_repeat_warnings = TRUE) expect_warning(retired1(), "repeats") expect_warning(retired2(), "repeats") }) test_that("lifecycle warnings helper enable warnings", { retired1 <- function() signal_soft_deprecated("soft deprecated wrn enabled by helper") retired2 <- function() warn_deprecated("deprecated wrn enabled by helper") with_options( lifecycle_disable_warnings = TRUE, { evalq({ local_lifecycle_warnings() expect_warning(retired1(), "enabled") expect_warning(retired1(), "enabled") expect_warning(retired2(), "enabled") expect_warning(retired2(), "enabled") }) } ) }) test_that("can disable lifecycle warnings", { local_lifecycle_silence() local_options( lifecycle_verbose_soft_deprecation = TRUE, lifecycle_repeat_warnings = TRUE ) expect_no_warning(signal_soft_deprecated("foo")) expect_no_warning(warn_deprecated("foo")) }) test_that("can promote lifecycle warnings to errors", { local_lifecycle_errors() expect_defunct(signal_soft_deprecated("foo"), "foo") expect_defunct(warn_deprecated("foo"), "foo") }) test_that("can enable warnings and errors with `with_` helpers", { expect_warning(with_lifecycle_warnings(signal_soft_deprecated("foo")), "foo") expect_defunct(with_lifecycle_errors(signal_soft_deprecated("foo")), "foo") expect_no_warning(with_lifecycle_warnings(with_lifecycle_silence(warn_deprecated("foo")))) }) test_that("soft-deprecation warnings are issued when called from child of global env as well", { fn <- function() signal_soft_deprecated("called from child of global env") expect_warning(eval_bare(call2(fn), env(global_env())), "child of global env") }) test_that("once-per-session note is not displayed on repeated warnings", { wrn <- catch_cnd(warn_deprecated("foo", "once-per-session-note")) expect_true(grepl("once per session", wrn$message)) local_options(lifecycle_repeat_warnings = TRUE) wrn <- catch_cnd(warn_deprecated("foo", "once-per-session-no-note")) expect_false(grepl("once per session", wrn$message)) }) test_that("inputs are type checked", { expect_error(signal_soft_deprecated(1), "is_character") expect_error(signal_soft_deprecated("foo", "bar", 1), "is_environment") expect_error(warn_deprecated(1), "is_character") expect_error(stop_defunct(1), "is_character") }) test_that("lifecycle signallers support character vectors", { local_lifecycle_errors() expect_defunct(signal_soft_deprecated(c("foo", "bar")), "foo\nbar") expect_defunct(warn_deprecated(c("foo", "bar")), "foo\nbar") expect_defunct(stop_defunct(c("foo", "bar")), "foo\nbar") }) test_that("the topenv of the empty env is not the global env", { expect_silent(signal_soft_deprecated("topenv empty env", env = empty_env())) }) rlang/tests/testthat/test-utils.R0000644000176200001440000000167513612344312016627 0ustar liggesuserscontext("utils") test_that("locale setters report old locale", { tryCatch( old <- suppressMessages(poke_mbcs_locale()), warning = function(e) skip("Cannot set MBCS locale") ) mbcs <- suppressMessages(poke_latin1_locale()) suppressMessages(Sys.setlocale("LC_CTYPE", old)) expect_true(tolower(mbcs) %in% tolower(c("ja_JP.SJIS", "English_United States.932"))) }) old_digits <- getOption("digits") test_that("local_options() sets options", { old <- local_options(digits = 2L) expect_identical(old$digits, old_digits) expect_identical(getOption("digits"), 2L) }) test_that("local_options() restores options", { expect_identical(getOption("digits"), old_digits) }) test_that("trailing newlines are trimmed", { expect_identical(strip_trailing_newline("foo"), "foo") expect_identical(strip_trailing_newline(""), "") expect_identical(strip_trailing_newline("foo\n"), "foo") expect_identical(strip_trailing_newline("\n"), "") }) rlang/tests/testthat/helper-locale.R0000644000176200001440000000422713500433004017213 0ustar liggesusersget_lang_strings <- function() { lang_strings <- c( de = "Gl\u00fcck", cn = "\u5e78\u798f", ru = "\u0441\u0447\u0430\u0441\u0442\u044c\u0435", ko = "\ud589\ubcf5" ) native_lang_strings <- enc2native(lang_strings) same <- (lang_strings == native_lang_strings) list( same = lang_strings[same], different = lang_strings[!same] ) } get_native_lang_string <- function() { lang_strings <- get_lang_strings() if (length(lang_strings$same) == 0) testthat::skip("No native language string available") lang_strings$same[[1L]] } get_alien_lang_string <- function() { lang_strings <- get_lang_strings() if (length(lang_strings$different) == 0) testthat::skip("No alien language string available") lang_strings$different[[1L]] } with_non_utf8_locale <- function(code) { old_locale <- mut_non_utf8_locale() on.exit(poke_ctype_locale(old_locale), add = TRUE) code } mut_non_utf8_locale <- function() { if (.Platform$OS.type == "windows") return(NULL) tryCatch( locale <- poke_ctype_locale("en_US.ISO8859-1"), warning = function(e) { testthat::skip("Cannot set latin-1 locale") } ) locale } with_latin1_locale <- function(expr) { old_locale <- suppressMessages(poke_latin1_locale()) on.exit(poke_ctype_locale(old_locale)) expr } poke_utf8_locale <- function() { if (.Platform$OS.type == "windows") { warn("UTF-8 is not supported on Windows") } else { inform("Locale codeset is now UTF-8") poke_ctype_locale("en_US.UTF-8") } } poke_latin1_locale <- function() { if (.Platform$OS.type == "windows") { locale <- "English_United States.1252" } else { locale <- "en_US.ISO8859-1" } inform("Locale codeset is now latin1") poke_ctype_locale(locale) } poke_mbcs_locale <- function() { if (.Platform$OS.type == "windows") { locale <- "English_United States.932" } else { locale <- "ja_JP.SJIS" } inform("Locale codeset is now of non-UTF-8 MBCS type") poke_ctype_locale(locale) } poke_ctype_locale <- function(x) { if (is_null(x)) return(x) # Workaround bug in Sys.setlocale() old <- Sys.getlocale("LC_CTYPE") Sys.setlocale("LC_CTYPE", locale = x) invisible(old) } rlang/tests/testthat/test-trace.Rmd0000644000176200001440000000023413446672635017115 0ustar liggesusers ```{r} getOption("rlang_backtrace_on_error") ``` ```{r, error = TRUE} f <- function() g() g <- function() h() h <- function() rlang::abort("foo") f() ``` rlang/tests/testthat/test-cnd-abort.R0000644000176200001440000001415113612346770017343 0ustar liggesuserscontext("cnd-abort") test_that("errors are signalled with backtrace", { fn <- function() abort("") err <- catch_cnd(fn()) expect_is(err$trace, "rlang_trace") }) test_that("can pass classed strings as error message", { message <- structure("foo", class = c("glue", "character")) err <- catch_cnd(abort(message)) expect_identical(err$message, message) }) test_that("errors are saved", { # `outFile` argument skip_if(getRversion() < "3.4") file <- tempfile() on.exit(unlink(file)) # Verbose try() triggers conditionMessage() and thus saves the error. # This simulates an unhandled error. local_options(`rlang:::force_unhandled_error` = TRUE) try(abort("foo", "bar"), outFile = file) expect_true(inherits_all(last_error(), c("bar", "rlang_error"))) try(cnd_signal(error_cnd("foobar")), outFile = file) expect_true(inherits_all(last_error(), c("foobar", "rlang_error"))) }) test_that("No backtrace is displayed with top-level active bindings", { local_options( rlang_trace_top_env = current_env() ) env_bind_active(current_env(), foo = function() abort("msg")) expect_error(foo, "^msg$") }) test_that("Invalid on_error option resets itself", { with_options( `rlang:::force_unhandled_error` = TRUE, rlang_backtrace_on_error = NA, { expect_warning(tryCatch(abort("foo"), error = identity), "Invalid") expect_null(peek_option("rlang_backtrace_on_error")) } ) }) test_that("format_onerror_backtrace handles empty and size 1 traces", { local_options(rlang_backtrace_on_error = "branch") trace <- new_trace(list(), int(), chr()) expect_identical(format_onerror_backtrace(trace), NULL) trace <- new_trace(list(quote(foo)), int(0), chr("")) expect_identical(format_onerror_backtrace(trace), NULL) trace <- new_trace(list(quote(foo), quote(bar)), int(0, 1), chr("", "")) expect_match(format_onerror_backtrace(error_cnd(trace = trace)), "foo.*bar") }) test_that("error is printed with backtrace", { skip_unless_utf8() skip_if_stale_backtrace() run_error_script <- function(envvars = chr()) { run_script(test_path("fixtures", "error-backtrace.R"), envvars = envvars) } default_interactive <- run_error_script(envvars = "rlang_interactive=true") default_non_interactive <- run_error_script() reminder <- run_error_script(envvars = "rlang_backtrace_on_error=reminder") branch <- run_error_script(envvars = "rlang_backtrace_on_error=branch") collapse <- run_error_script(envvars = "rlang_backtrace_on_error=collapse") full <- run_error_script(envvars = "rlang_backtrace_on_error=full") rethrown_interactive <- run_script( test_path("fixtures", "error-backtrace-rethrown.R"), envvars = "rlang_interactive=true" ) rethrown_non_interactive <- run_script( test_path("fixtures", "error-backtrace-rethrown.R") ) verify_output(test_path("test-cnd-error.txt"), { "Default (interactive)" cat_line(default_interactive) "Default (non-interactive)" cat_line(default_non_interactive) "Reminder" cat_line(reminder) "Branch" cat_line(branch) "Collapse" cat_line(collapse) "Full" cat_line(full) "Rethrown (interactive)" cat_line(rethrown_interactive) "Rethrown (non-interactive)" cat_line(rethrown_non_interactive) }) }) test_that("empty backtraces are not printed", { skip_unless_utf8() skip_if_stale_backtrace() run_error_script <- function(envvars = chr()) { run_script(test_path("fixtures", "error-backtrace-empty.R"), envvars = envvars) } branch0 <- run_error_script(envvars = c("rlang_backtrace_on_error=branch", "trace_depth=0")) full0 <- run_error_script(envvars = c("rlang_backtrace_on_error=full", "trace_depth=0")) branch1 <- run_error_script(envvars = c("rlang_backtrace_on_error=branch", "trace_depth=1")) full1 <- run_error_script(envvars = c("rlang_backtrace_on_error=full", "trace_depth=1")) verify_output(test_path("test-cnd-error-empty.txt"), { "Branch (depth 0)" cat_line(branch0) "Full" cat_line(full0) "Branch (depth 1)" cat_line(branch1) "Full (depth 1)" cat_line(full1) }) }) test_that("parent errors are not displayed in error message and backtrace", { skip_unless_utf8() skip_if_stale_backtrace() run_error_script <- function(envvars = chr()) { run_script( test_path("fixtures", "error-backtrace-parent.R"), envvars = envvars ) } non_interactive <- run_error_script() interactive <- run_error_script(envvars = "rlang_interactive=true") verify_output(test_path("test-cnd-error-parent.txt"), { "Interactive" cat_line(interactive) "Non-interactive" cat_line(non_interactive) }) }) test_that("backtrace reminder is displayed when called from `last_error()`", { local_options( rlang_trace_format_srcrefs = FALSE, rlang_trace_top_env = current_env() ) f <- function() g() g <- function() h() h <- function() abort("foo") err <- catch_cnd(f()) last_error_env$cnd <- err verify_output(test_path("output-cnd-abort-trace-reminder.txt"), { "Normal case" print(err) "From `last_error()`" print(last_error()) "Saved from `last_error()`" saved <- last_error() print(saved) "Saved from `last_error()`, but no longer last" last_error_env$cnd <- error_cnd("foo") print(saved) }) }) test_that("capture context doesn't leak into low-level backtraces", { local_options( rlang_trace_format_srcrefs = FALSE, rlang_trace_top_env = current_env() ) stop_wrapper <- function(...) abort("wrapper", ...) f <- function() g() g <- function() h() h <- function() { tryCatch( stop("low-level"), error = function(err) { if (wrapper) { stop_wrapper(parent = err) } else { if (parent) { abort("no wrapper", parent = err) } else { abort("no wrapper") } } } ) } verify_output(test_path("output-cnd-abort-parent-trace.txt"), { wrapper <- FALSE err <- catch_cnd(f()) print(err) wrapper <- TRUE err <- catch_cnd(f()) print(err) "FIXME?" parent <- FALSE err <- catch_cnd(f()) print(err) }) }) rlang/tests/testthat/test-trace-collapse-magrittr3.txt0000644000176200001440000000137713612375026022722 0ustar liggesusersFull: â–ˆ 1. ├─rlang:::f(g(NULL %>% f()) %>% h()) 2. └─g(NULL %>% f()) %>% h() 3. ├─base::withVisible(eval(quote(`_fseq`(`_lhs`)), env, env)) 4. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 5. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 6. └─rlang:::`_fseq`(`_lhs`) 7. └─magrittr::freduce(value, `_function_list`) 8. ├─base::withVisible(function_list[[k]](value)) 9. └─function_list[[k]](value) 10. └─rlang:::h(.) Collapsed: â–ˆ 1. ├─[ rlang:::f(...) ] 2. └─[ g(NULL %>% f()) %>% h() ] with 7 more calls 10. └─rlang:::h(.) Branch: 1. rlang:::f(g(NULL %>% f()) %>% h()) 2. rlang:::g(NULL %>% f()) 10. rlang:::h(.) rlang/tests/testthat/test-trace-collapse-magrittr.txt0000644000176200001440000000127213612375026022631 0ustar liggesusersFull: â–ˆ 1. └─NULL %>% f() %>% g(1, 2) %>% h(3, ., 4) 2. ├─base::withVisible(eval(quote(`_fseq`(`_lhs`)), env, env)) 3. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 4. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 5. └─rlang:::`_fseq`(`_lhs`) 6. └─magrittr::freduce(value, `_function_list`) 7. ├─base::withVisible(function_list[[k]](value)) 8. └─function_list[[k]](value) 9. └─rlang:::h(3, ., 4) Collapsed: â–ˆ 1. └─[ NULL %>% f() %>% g(1, 2) %>% h(3, ., 4) ] with 7 more calls 9. └─rlang:::h(3, ., 4) Branch: 1. rlang:::f(.) 1. rlang:::g(., 1, 2) 9. rlang:::h(3, ., 4) rlang/tests/testthat/helper-trace.R0000644000176200001440000000207513610376552017071 0ustar liggesusers expect_known_trace_output <- function(trace, file, dir = normalizePath(test_path("..")), srcrefs = FALSE) { expect_known_output(file = test_path(file), { cat("Full:\n") print(trace, simplify = "none", dir = dir, srcrefs = srcrefs) cat("\nCollapsed:\n") print(trace, simplify = "collapse", dir = dir, srcrefs = srcrefs) cat("\nBranch:\n") print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs) }) } expect_trace_length <- function(x, n) { expect_equal(trace_length(x), n) } expect_equal_trace <- function(x, y) { expect_identical(x$parents, y$parents) expect_equal(x$calls, y$calls) } render_md <- function(file) { skip_if_not_installed("rmarkdown") skip_if_not_installed("knitr") out_file <- tempfile(file) on.exit(file.remove(out_file)) rmarkdown::render( test_path(file), output_format = "md_document", output_file = out_file, quiet = TRUE, envir = globalenv() ) readLines(out_file) } rlang/tests/testthat/teardown-tests.R0000644000176200001440000000013713405732277017500 0ustar liggesusers # Until https://github.com/r-lib/testthat/issues/787 is fixed Sys.setenv("TESTTHAT_PKG" = "") rlang/tests/testthat/test-trace-collapse-magrittr-complete-leading1.txt0000644000176200001440000000113613612375027026121 0ustar liggesusersFull: â–ˆ 1. └─F(NA) %>% T() 2. ├─base::withVisible(eval(quote(`_fseq`(`_lhs`)), env, env)) 3. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 4. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 5. └─rlang:::`_fseq`(`_lhs`) 6. └─magrittr::freduce(value, `_function_list`) 7. ├─base::withVisible(function_list[[k]](value)) 8. └─function_list[[k]](value) 9. └─rlang:::T(.) Collapsed: â–ˆ 1. └─[ F(NA) %>% T() ] with 7 more calls 9. └─rlang:::T(.) Branch: 1. rlang:::F(NA) 9. rlang:::T(.) rlang/tests/testthat/test-trace-truncate-backtrace-branch.txt0000644000176200001440000000072713612375026024201 0ustar liggesusersFull: 1. rlang:::f(10) 2. rlang:::f(n - 1) 3. rlang:::f(n - 1) 4. rlang:::f(n - 1) 5. rlang:::f(n - 1) 6. rlang:::f(n - 1) 7. rlang:::f(n - 1) 8. rlang:::f(n - 1) 9. rlang:::f(n - 1) 10. rlang:::f(n - 1) 11. rlang:::f(n - 1) 5 frames: 1. rlang:::f(10) 2. rlang:::f(n - 1) 3. rlang:::f(n - 1) ... 10. rlang:::f(n - 1) 11. rlang:::f(n - 1) 2 frames: 1. rlang:::f(10) ... 11. rlang:::f(n - 1) 1 frame: 1. rlang:::f(10) ... rlang/tests/testthat/test-operators.R0000644000176200001440000000427213517571557017522 0ustar liggesuserscontext("operators") test_that("%|% returns default value", { lgl <- c(TRUE, TRUE, NA, FALSE) %|% FALSE expect_identical(lgl, c(TRUE, TRUE, FALSE, FALSE)) int <- c(1L, 2L, NA, 4L) %|% 3L expect_identical(int, 1:4) dbl <- c(1, 2, NA, 4) %|% 3 expect_identical(dbl, as.double(1:4)) chr <- c("1", "2", NA, "4") %|% "3" expect_identical(chr, as.character(1:4)) cpx <- c(1i, 2i, NA, 4i) %|% 3i expect_equal(cpx, c(1i, 2i, 3i, 4i)) }) test_that("%|% also works when y is of same length as x", { lgl <- c(TRUE, TRUE, NA, FALSE) %|% c(TRUE, TRUE, FALSE, TRUE) expect_identical(lgl, c(TRUE, TRUE, FALSE, FALSE)) int <- c(1L, 2L, NA, 4L) %|% c(10L, 11L, 12L, 13L) expect_identical(int, c(1L, 2L, 12L, 4L)) dbl <- c(1, 2, NA, 4) %|% c(10, 11, 12, 13) expect_identical(dbl, c(1, 2, 12, 4)) chr <- c("1", "2", NA, "4") %|% c("10", "11", "12", "13") expect_identical(chr, c("1", "2", "12", "4")) cpx <- c(1i, 2i, NA, 4i) %|% c(10i, 11i, 12i, 13i) expect_equal(cpx, c(1i, 2i, 12i, 4i)) }) test_that("%|% fails with wrong types", { expect_error(c(1L, NA) %|% 2) expect_error(c(1, NA) %|% "") }) test_that("%|% fails with wrong length", { expect_error(c(1L, NA) %|% 1:3) expect_error(1:10 %|% 1:4) }) test_that("%@% returns attribute", { expect_identical(mtcars %@% row.names, row.names(mtcars)) expect_identical(mtcars %@% "row.names", row.names(mtcars)) expect_null(mtcars %@% "row") }) test_that("%@% has replacement version", { x <- structure(list(), foo = "bar") x %@% foo <- NULL x %@% baz <- "quux" expect_identical(x, structure(list(), baz = "quux")) }) test_that("new_definition() returns new `:=` call", { def <- "foo" ~ "bar" node_poke_car(def, quote(`:=`)) expect_identical(new_definition("foo", "bar"), def) }) test_that("%@% works with S4 objects (#207)", { .Person <- setClass("Person", slots = c(name = "character", species = "character")) fievel <- .Person(name = "Fievel", species = "mouse") expect_identical(fievel %@% name, "Fievel") expect_identical(fievel %@% "species", "mouse") fievel %@% name <- "Bernard" fievel %@% "species" <- "MOUSE" expect_identical(fievel@name, "Bernard") expect_identical(fievel@species, "MOUSE") }) rlang/tests/testthat/test-cnd-signal.R0000644000176200001440000000754213610371174017511 0ustar liggesuserscontext("cnd-signal") test_that("cnd_signal() creates muffle restarts", { withCallingHandlers(cnd_signal(cnd("foo")), foo = function(c) { expect_true(rst_exists("rlang_muffle")) } ) }) test_that("signallers support character vectors as `message` parameter", { expect_message(inform(c("foo", "bar")), "foo\n* bar", fixed = TRUE) expect_warning(warn(c("foo", "bar")), "foo\n* bar", fixed = TRUE) expect_error(abort(c("foo", "bar")), "foo\n* bar", fixed = TRUE) expect_condition(signal(c("foo", "bar"), "quux"), "quux", regex = "foo\n\\* bar") }) test_that("cnd_signal() and signal() returns NULL invisibly", { expect_identical(withVisible(cnd_signal(cnd("foo"))), withVisible(invisible(NULL))) expect_identical(withVisible(signal("", "foo")), withVisible(invisible(NULL))) }) test_that("signal() accepts character vectors of classes (#195)", { expect <- calling(function(cnd) { expect_identical(class(cnd), c("foo", "bar", "condition")) }) with_handlers(signal("", c("foo", "bar")), foo = expect) }) test_that("can pass condition metadata", { msg <- catch_cnd(inform("type", foo = "bar")) expect_identical(msg$foo, "bar") wng <- catch_cnd(warn("type", foo = "bar")) expect_identical(wng$foo, "bar") err <- catch_cnd(abort("type", foo = "bar")) expect_identical(err$foo, "bar") }) test_that("can signal and catch interrupts", { expect_is(catch_cnd(interrupt()), "interrupt") }) test_that("can signal interrupts with cnd_signal()", { intr <- catch_cnd(interrupt()) with_handlers(cnd_signal(intr), condition = function(cnd) expect_is(cnd, "interrupt") ) }) test_that("conditions have correct subclasses", { expect_true(inherits_all(catch_cnd(signal("", "foo")), c("foo", "condition", "condition"))) expect_true(inherits_all(catch_cnd(inform("", "foo")), c("foo", "message", "condition"))) expect_true(inherits_all(catch_cnd(warn("", "foo")), c("foo", "warning", "condition"))) expect_true(inherits_all(catch_cnd(abort("", "foo")), c("foo", "rlang_error", "error", "condition"))) }) test_that("cnd_signal() creates a backtrace if needed", { skip_unless_utf8() local_options( rlang_trace_top_env = current_env(), rlang_trace_format_srcrefs = FALSE ) err <- error_cnd("rlang_error_foobar", trace = NULL) f <- function() g() g <- function() h() h <- function() cnd_signal(err) err <- catch_cnd(f()) expect_known_output(file = test_path("test-cnd-signal-trace.txt"), print(err)) }) test_that("`inform()` appends newline to message", { expect_identical( catch_cnd(inform("foo"))$message, "foo\n" ) }) test_that("condition signallers can be called without arguments", { # For pragmatic reasons we don't require a class because we now use # `inform()` in places where `cat()` would be more appropriate expect_message(inform(), "", fixed = TRUE) expect_warning(warn(class = "foo"), "", fixed = TRUE) expect_error(abort(class = "foo"), "", fixed = TRUE, class = "foo") }) test_that("`inform()` returns invisibly", { expect_invisible(inform("foo")) }) # Lifecycle ---------------------------------------------------------- test_that("deprecated arguments of cnd_signal() still work", { local_lifecycle_silence() observed <- catch_cnd(cnd_signal("foo")) expected <- catch_cnd(signal("", "foo")) expect_identical(observed, expected) with_handlers(cnd_signal(cnd("foo"), .mufflable = TRUE), foo = calling(function(cnd) expect_true(rst_exists("rlang_muffle"))) ) }) test_that("can still use `.subclass`", { expect_error(abort("foo", .subclass = "baz"), class = "baz") expect_warning(warn("foo", .subclass = "baz"), class = "baz") expect_message(inform("foo", .subclass = "baz"), class = "baz") expect_is(cnd(.subclass = "baz"), "baz") expect_is(error_cnd(.subclass = "baz"), "baz") expect_is(warning_cnd(.subclass = "baz"), "baz") expect_is(message_cnd(.subclass = "baz"), "baz") }) rlang/tests/testthat/helper-capture.R0000644000176200001440000000163713457603056017442 0ustar liggesusers named <- function(x) { set_names(x, names2(x)) } named_list <- function(...) { named(list(...)) } quos_list <- function(...) { structure(named_list(...), class = "quosures") } expect_error_ <- function(object, ...) { expect_error(object, ...) } expect_warning_ <- function(object, ...) { expect_warning(object, ...) } expect_identical_ <- function(object, expected, ...) { expect_identical(object, expected, ...) } expect_equal_ <- function(object, expected, ...) { expect_equal(object, expected, ...) } expect_no_warning <- function(object, ...) { expect_warning(!!enquo(object), NA, ...) } expect_no_warning_ <- function(object, ...) { expect_warning(object, NA, ...) } expect_no_error <- function(object, ...) { expect_error(!!enquo(object), NA, ...) } expect_no_error_ <- function(object, ...) { expect_error(object, NA, ...) } expect_null_ <- function(object, ...) { expect_null(object, ...) } rlang/tests/testthat/test-cnd-error-parent-trace.txt0000644000176200001440000000213413612375014022355 0ustar liggesusersFull: High-level message Backtrace: █ 1. ├─rlang::catch_cnd(a()) 2. │ ├─rlang::eval_bare(...) 3. │ ├─base::tryCatch(...) 4. │ │ └─base:::tryCatchList(expr, classes, parentenv, handlers) 5. │ │ └─base:::tryCatchOne(expr, names, parentenv, handlers[[1L]]) 6. │ │ └─base:::doTryCatch(return(expr), name, parentenv, handler) 7. │ └─base::force(expr) 8. └─rlang:::a() 9. └─rlang:::b() 10. └─rlang:::c() Low-level message Backtrace: █ 1. └─rlang:::f() 2. └─rlang:::g() 3. └─rlang:::h() Collapsed: High-level message Backtrace: █ 1. ├─[ rlang::catch_cnd(...) ] with 6 more calls 8. └─rlang:::a() 9. └─rlang:::b() 10. └─rlang:::c() Low-level message Backtrace: █ 1. └─rlang:::f() 2. └─rlang:::g() 3. └─rlang:::h() Branch: High-level message Backtrace: 1. rlang::catch_cnd(a()) 8. rlang:::a() 9. rlang:::b() 10. rlang:::c() rlang/tests/testthat/test-trace-collapse-magrittr-before-after3.txt0000644000176200001440000000137713612375027025262 0ustar liggesusersFull: █ 1. ├─rlang:::F(NA %>% C()) 2. └─NA %>% C() 3. ├─base::withVisible(eval(quote(`_fseq`(`_lhs`)), env, env)) 4. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 5. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 6. └─rlang:::`_fseq`(`_lhs`) 7. └─magrittr::freduce(value, `_function_list`) 8. ├─base::withVisible(function_list[[k]](value)) 9. └─function_list[[k]](value) 10. └─rlang:::C(.) 11. └─rlang:::f() Collapsed: █ 1. ├─[ rlang:::F(...) ] 2. └─[ NA %>% C() ] with 7 more calls 10. └─rlang:::C(.) 11. └─rlang:::f() Branch: 1. rlang:::F(NA %>% C()) 10. rlang:::C(.) 11. rlang:::f() rlang/tests/testthat/test-trace-collapse-magrittr2.txt0000644000176200001440000000133213612375026022710 0ustar liggesusersFull: █ 1. └─f(NULL) %>% g(list(.)) %>% h(3, ., list(.)) 2. ├─base::withVisible(eval(quote(`_fseq`(`_lhs`)), env, env)) 3. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 4. └─base::eval(quote(`_fseq`(`_lhs`)), env, env) 5. └─rlang:::`_fseq`(`_lhs`) 6. └─magrittr::freduce(value, `_function_list`) 7. ├─base::withVisible(function_list[[k]](value)) 8. └─function_list[[k]](value) 9. └─rlang:::h(3, ., list(.)) Collapsed: █ 1. └─[ f(NULL) %>% g(list(.)) %>% h(3, ., list(.)) ] with 7 more calls 9. └─rlang:::h(3, ., list(.)) Branch: 1. rlang:::f(NULL) 1. rlang:::g(., list(.)) 9. rlang:::h(3, ., list(.)) rlang/tests/testthat/helper-c-api.R0000644000176200001440000000111613457603056016760 0ustar liggesusers r_env_unbind <- function(env, names, inherits = FALSE) { invisible(.Call(rlang_env_unbind, env, names, inherits)) } r_parse_eval <- function(x, env = caller_env()) { .Call(rlang_test_parse_eval, x, env) } r_nms_are_duplicated <- function(nms, from_last = FALSE) { .Call(rlang_nms_are_duplicated, nms, from_last) } r_lgl_sum <- function(x, na_true) { stopifnot(is_logical(x), is_bool(na_true)) .Call(rlang_test_lgl_sum, x, na_true) } r_lgl_which <- function(x, na_propagate) { stopifnot(is_logical(x), is_bool(na_propagate)) .Call(rlang_test_lgl_which, x, na_propagate) } rlang/tests/testthat/test-dots.R0000644000176200001440000002241013563535650016442 0ustar liggesuserscontext("dots") test_that("exprs() without arguments creates an empty named list", { expect_identical(exprs(), named_list()) }) test_that("exprs() captures arguments forwarded with `...`", { wrapper <- function(...) exprs(...) expect_identical(wrapper(a = 1, foo = bar), list(a = 1, foo = quote(bar))) }) test_that("exprs() captures empty arguments", { expect_identical(exprs(, , .ignore_empty = "none"), set_names(list(missing_arg(), missing_arg()), c("", ""))) }) test_that("dots are always named", { expect_named(dots_list("foo"), "") expect_named(dots_splice("foo", list("bar")), c("", "")) expect_named(exprs(foo, bar), c("", "")) }) test_that("dots can be spliced", { spliced_dots <- dots_values(!!! list(letters)) expect_identical(spliced_dots, list(splice(list(letters)))) expect_identical(flatten(dots_values(!!! list(letters))), list(letters)) expect_identical(list2(!!! list(letters)), list(letters)) wrapper <- function(...) list2(...) expect_identical(wrapper(!!! list(letters)), list(letters)) }) test_that("interpolation by value does not guard formulas", { expect_identical(dots_values(~1), list(~1)) }) test_that("dots names can be unquoted", { expect_identical(dots_values(!! paste0("foo", "bar") := 10), list(foobar = 10)) }) test_that("can take forced dots with `allowForced = FALSE`", { fn <- function(...) { force(..1) captureDots() } expect_identical(fn(a = letters), pairlist(a = list(expr = letters, env = empty_env()))) }) test_that("captured dots are only named if names were supplied", { fn <- function(...) captureDots() expect_null(names(fn(1, 2))) expect_identical(names(fn(a = 1, 2)), c("a", "")) }) test_that("dots_values() handles forced dots", { fn <- function(...) { force(..1) dots_values(...) } expect_identical(fn("foo"), list("foo")) expect_identical(lapply(1:2, function(...) dots_values(...)), list(list(1L), list(2L))) expect_identical(lapply(1:2, dots_values), list(list(1L), list(2L))) }) test_that("empty arguments trigger meaningful error", { expect_error(list2(1, , 3), "Argument 2 is empty") expect_error(dots_list(1, , 3), "Argument 2 is empty") }) test_that("cleans empty arguments", { expect_identical(dots_list(1, ), named_list(1)) expect_identical(list2(1, ), list(1)) expect_identical(exprs(1, ), named_list(1)) expect_identical(dots_list(, 1, , .ignore_empty = "all"), named_list(1)) }) test_that("doesn't clean named empty argument arguments", { expect_error(dots_list(1, a = ), "Argument 2 is empty") expect_identical(exprs(1, a = ), alist(1, a = )) expect_identical(exprs(1, a = , b = , , .ignore_empty = "all"), alist(1, a = , b = )) }) test_that("capturing dots by value only unquote-splices at top-level", { expect_identical_(dots_list(!!! list(quote(!!! a))), named_list(quote(!!! a))) expect_identical_(dots_list(!!! exprs(!!! 1:3)), named_list(1L, 2L, 3L)) }) test_that("can't unquote when capturing dots by value", { expect_identical(dots_list(!!! list(!!! TRUE)), named_list(FALSE)) }) test_that("can splice NULL value", { expect_identical(dots_list(!!! NULL), named_list()) expect_identical(dots_list(1, !!! NULL, 3), named_list(1, 3)) }) test_that("dots_splice() flattens lists", { expect_identical(dots_splice(list("a", list("b"), "c"), "d", list("e")), named_list("a", list("b"), "c", "d", "e")) expect_identical(dots_splice(list("a"), !!! list("b"), list("c"), "d"), named_list("a", "b", "c", "d")) expect_identical(dots_splice(list("a"), splice(list("b")), list("c"), "d"), named_list("a", "b", "c", "d")) }) test_that("dots_splice() doesn't squash S3 objects", { s <- structure(list(v1 = 1, v2 = 2), class = "foo") expect_identical(dots_splice(s, s), named_list(s, s)) }) test_that("dots_node() doesn't trim attributes from arguments", { x <- ~foo dots <- eval(expr(dots_node(!! x))) expect_identical(node_car(dots), x) }) test_that("dots_split() splits named and unnamed dots", { dots <- dots_split(1, 2) expect_identical(dots$named, list()) expect_identical(dots$unnamed, list(1, 2)) dots <- dots_split(a = 1, 2) expect_identical(dots$named, list(a = 1)) expect_identical(dots$unnamed, list(2)) dots <- dots_split(a = 1, b = 2) expect_identical(dots$named, list(a = 1, b = 2)) expect_identical(dots$unnamed, list()) }) test_that("dots_split() handles empty dots", { dots <- dots_split() expect_identical(dots$named, list()) expect_identical(dots$unnamed, list()) }) test_that("dots_split() fails if .n_unnamed doesn't match", { expect_error(dots_split(1, 2, .n_unnamed = 1), "Expected 1 unnamed") expect_error(dots_split(1, 2, .n_unnamed = 0:1), "Expected 0 or 1 unnamed") dots <- dots_split(a = 1, 2, .n_unnamed = 1) expect_identical(dots$named, list(a = 1)) expect_identical(dots$unnamed, list(2)) }) test_that("can splice NULL and atomic vectors", { expect_identical(list2(!!!letters), as.list(letters)) expect_identical(list2(!!!NULL), list()) }) test_that("can unquote quosures in LHS", { quo <- quo(foo) expect_identical(list2(!!quo := NULL), list(foo = NULL)) expect_identical(exprs(!!quo := bar), exprs(foo = bar)) }) test_that("can preserve empty arguments", { list3 <- function(...) unname(dots_list(..., .preserve_empty = TRUE)) expect_identical(list3(, ), list(missing_arg())) expect_identical(list3(, , .ignore_empty = "none"), list(missing_arg(), missing_arg())) expect_identical(list3(, , .ignore_empty = "all"), list()) }) test_that("forced symbolic objects are not evaluated", { x <- list(quote(`_foo`)) expect_identical_(lapply(x, list2), list(x)) expect_identical_(list2(!!!x), x) x <- unname(exprs(stop("tilt"))) expect_identical_(lapply(x, list2), list(x)) }) test_that("dots collectors do not warn by default with bare `<-` arguments", { expect_no_warning(list2(a <- 1)) expect_no_warning(dots_list(a <- 1)) expect_no_warning(exprs(a <- 1)) expect_no_warning(quos(a <- 1)) myexprs <- function(...) enexprs(...) myquos <- function(...) enexprs(...) expect_no_warning(myexprs(a <- 1)) expect_no_warning(myquos(a <- 1)) }) test_that("dots collectors can elect to warn with bare `<-` arguments", { expect_warning(dots_list(a <- 1, .check_assign = TRUE), "`<-` as argument") myexprs <- function(...) enexprs(..., .check_assign = TRUE) myquos <- function(...) enexprs(..., .check_assign = TRUE) expect_warning(myexprs(TRUE, a <- 1), "`<-` as argument") expect_warning(myquos(TRUE, a <- 1), "`<-` as argument") }) test_that("dots collectors never warn for <- when option is set", { local_options(rlang_dots_disable_assign_warning = TRUE) expect_no_warning(list2(a <- 1)) myexprs <- function(...) enexprs(..., .check_assign = TRUE) myquos <- function(...) enquos(..., .check_assign = TRUE) expect_no_warning(myexprs(a <- 1)) expect_no_warning(myquos(a <- 1)) }) test_that("`.homonyms` is matched exactly", { expect_error(dots_list(.homonyms = "k"), "must be one of") }) test_that("`.homonyms = 'first'` matches first homonym", { list_first <- function(...) { dots_list(..., .homonyms = "first") } out <- list_first(1, 2) expect_identical(out, named_list(1, 2)) out <- list_first(a = 1, b = 2, 3, 4) expect_identical(out, list(a = 1, b = 2, 3, 4)) out <- list_first(a = 1, b = 2, a = 3, a = 4, 5, 6) expect_identical(out, list(a = 1, b = 2, 5, 6)) }) test_that("`.homonyms = 'last'` matches last homonym", { list_last <- function(...) { dots_list(..., .homonyms = "last") } out <- list_last(1, 2) expect_identical(out, named_list(1, 2)) out <- list_last(a = 1, b = 2, 3, 4) expect_identical(out, list(a = 1, b = 2, 3, 4)) out <- list_last(a = 1, b = 2, a = 3, a = 4, 5, 6) expect_identical(out, list(b = 2, a = 4, 5, 6)) }) test_that("`.homonyms` = 'error' fails with homonyms", { list_error <- function(...) { dots_list(..., .homonyms = "error") } expect_identical(list_error(1, 2), named_list(1, 2)) expect_identical(list_error(a = 1, b = 2), list(a = 1, b = 2)) expect_error(list_error(1, a = 2, a = 3), "multiple arguments named `a` at positions 2 and 3") expect_error(list_error(1, a = 2, b = 3, 4, b = 5, b = 6, 7, a = 8), "\\* Multiple arguments named `a` at positions 2 and 8") expect_error(list_error(1, a = 2, b = 3, 4, b = 5, b = 6, 7, a = 8), "\\* Multiple arguments named `b` at positions 3, 5, and 6") }) test_that("`.homonyms` works with spliced arguments", { args <- list(a = 1, b = 2, a = 3, a = 4, 5, 6) expect_identical(dots_list(!!!args, .homonyms = "first"), list(a = 1, b = 2, 5, 6)) myexprs <- function(...) enexprs(..., .homonyms = "last") expect_identical(myexprs(!!!args), list(b = 2, a = 4, 5, 6)) myquos <- function(...) enquos(..., .homonyms = "first") expect_identical(myquos(!!!args), quos_list(a = quo(1), b = quo(2), quo(5), quo(6))) }) test_that("can mix `!!!` and splice boxes", { expect_identical(list2(1L, !!!(2:3), splice(list(4L))), as.list(1:4)) }) test_that("list2() and dots_values() support splice boxes", { expect_identical(list2(1, splice(c("foo", "bar")), 3), list(1, "foo", "bar", 3)) expect_identical(dots_values(1, splice(c("foo", "bar")), 3), list(1, splice(list("foo", "bar")), 3)) }) test_that("dots_values() doesn't splice", { expect_identical_(dots_values(!!!c(1:3)), list(splice(as.list(1:3)))) expect_identical_(dots_values(!!!list("foo", "bar")), list(splice(list("foo", "bar")))) }) rlang/tests/testthat/test-trace-collapsed1.txt0000644000176200001440000000346613612375026021236 0ustar liggesusersFull: █ 1. └─rlang:::f() 2. └─rlang:::g() testthat/test-trace.R:45:20 3. ├─base::tryCatch(h(), foo = identity, bar = identity) testthat/test-trace.R:46:20 4. │ └─base:::tryCatchList(expr, classes, parentenv, handlers) 5. │ ├─base:::tryCatchOne(...) 6. │ │ └─base:::doTryCatch(return(expr), name, parentenv, handler) 7. │ └─base:::tryCatchList(expr, names[-nh], parentenv, handlers[-nh]) 8. │ └─base:::tryCatchOne(expr, names, parentenv, handlers[[1L]]) 9. │ └─base:::doTryCatch(return(expr), name, parentenv, handler) 10. └─rlang:::h() 11. ├─base::tryCatch(i(), baz = identity) testthat/test-trace.R:47:20 12. │ └─base:::tryCatchList(expr, classes, parentenv, handlers) 13. │ └─base:::tryCatchOne(expr, names, parentenv, handlers[[1L]]) 14. │ └─base:::doTryCatch(return(expr), name, parentenv, handler) 15. └─rlang:::i() 16. ├─base::tryCatch(trace_back(e, bottom = 0)) testthat/test-trace.R:48:20 17. │ └─base:::tryCatchList(expr, classes, parentenv, handlers) 18. └─rlang::trace_back(e, bottom = 0) Collapsed: █ 1. └─rlang:::f() 2. └─rlang:::g() testthat/test-trace.R:45:20 3. ├─[ base::tryCatch(...) ] with 6 more calls testthat/test-trace.R:46:20 10. └─rlang:::h() 11. ├─[ base::tryCatch(...) ] with 3 more calls testthat/test-trace.R:47:20 15. └─rlang:::i() 16. ├─[ base::tryCatch(...) ] with 1 more call testthat/test-trace.R:48:20 18. └─rlang::trace_back(e, bottom = 0) Branch: 1. rlang:::f() 2. rlang:::g() testthat/test-trace.R:45:20 10. rlang:::h() 15. rlang:::i() 18. rlang::trace_back(e, bottom = 0) rlang/tests/testthat/test-error-print-conditionMessage.txt0000644000176200001440000000021013612375014023644 0ustar liggesusers> print(err) Low-level message Backtrace: 1. rlang::catch_cnd(f()) 8. rlang:::f() 9. rlang:::g() 10. rlang:::h() rlang/tests/testthat.R0000644000176200001440000000020713607315732014510 0ustar liggesusers# Workaround for loadNamespace() failure on R 3.2 requireNamespace("rlang") library("testthat") library("rlang") test_check("rlang") rlang/src/0000755000176200001440000000000013614040227012143 5ustar liggesusersrlang/src/config.h0000644000176200001440000000004113336316756013572 0ustar liggesusers#define RLANG_HAS_RINTERFACE_H 1 rlang/src/internal/0000755000176200001440000000000013614116052013757 5ustar liggesusersrlang/src/internal/env-binding.c0000644000176200001440000000070613604123766016337 0ustar liggesusers#include sexp* rlang_env_get(sexp* env, sexp* nm) { sexp* sym = Rf_installChar(r_chr_get(nm, 0)); sexp* out = KEEP(r_env_find(env, sym)); // Trigger `symbol not found` error if needed if (out == r_unbound_sym) { r_eval(sym, r_empty_env); r_abort("Internal error: `rlang_env_get()` should have failed earlier"); } if (r_typeof(out) == r_type_promise) { out = r_eval(out, r_empty_env); } FREE(1); return out; } rlang/src/internal/dots.h0000644000176200001440000000105213500406362015077 0ustar liggesusers#ifndef RLANG_INTERNAL_DOTS_H #define RLANG_INTERNAL_DOTS_H #define DOTS_CAPTURE_TYPE_MAX 3 enum dots_capture_type { DOTS_EXPR, DOTS_QUO, DOTS_VALUE }; enum dots_expansion_op { OP_EXPR_NONE, OP_EXPR_UQ, OP_EXPR_UQS, OP_EXPR_UQN, OP_EXPR_FIXUP, OP_EXPR_DOT_DATA, OP_EXPR_CURLY, OP_QUO_NONE, OP_QUO_UQ, OP_QUO_UQS, OP_QUO_UQN, OP_QUO_FIXUP, OP_QUO_DOT_DATA, OP_QUO_CURLY, OP_VALUE_NONE, OP_VALUE_UQ, OP_VALUE_UQS, OP_VALUE_UQN, OP_VALUE_FIXUP, OP_VALUE_DOT_DATA, OP_VALUE_CURLY, OP_DOTS_MAX }; #endif rlang/src/internal/expr-interp.c0000644000176200001440000002450013523027707016410 0ustar liggesusers#include #include "expr-interp.h" #include "expr-interp-rotate.h" #include "utils.h" struct expansion_info which_bang_op(sexp* second, struct expansion_info info); struct expansion_info which_curly_op(sexp* second, struct expansion_info info); struct expansion_info which_uq_op(sexp* first) { struct expansion_info info = init_expansion_info(); if (r_is_call(first, "(")) { sexp* paren = r_node_cadr(first); if (r_is_call(paren, "(")) { return info; } struct expansion_info inner_info = which_uq_op(paren); // Check that `root` is NULL so we don't remove parentheses when // there's an operation tail (i.e. when the parse tree was fixed // up to bind tightly) if (inner_info.op == OP_EXPAND_UQ && inner_info.root == r_null) { return inner_info; } else { return info; } } if (r_typeof(first) != r_type_call) { return info; } sexp* head = r_node_car(first); if (r_typeof(head) != r_type_symbol) { return info; } const char* nm = r_sym_get_c_string(head); if (strcmp(nm, "!") == 0) { return which_bang_op(r_node_cadr(first), info); } else if (strcmp(nm, "{") == 0) { return which_curly_op(r_node_cadr(first), info); } else { return info; } } struct expansion_info which_bang_op(sexp* second, struct expansion_info info) { if (!r_is_call(second, "!")) { return info; } sexp* third = r_node_cadr(second); // Need to fill in `info` for `!!` because parse tree might need changes if (!r_is_call(third, "!")) { if (is_problematic_op(third)) { info.op = OP_EXPAND_FIXUP; info.operand = third; } else { info.op = OP_EXPAND_UQ; info.parent = r_node_cdr(second); info.operand = third; } return info; } info.op = OP_EXPAND_UQS; info.operand = r_node_cadr(third); return info; } struct expansion_info which_curly_op(sexp* second, struct expansion_info info) { if (!r_is_call(second, "{")) { return info; } info.op = OP_EXPAND_CURLY; info.parent = r_node_cdr(second); info.operand = r_node_cadr(second); return info; } // These functions are questioning and might be soft-deprecated in the // future void signal_uq_soft_deprecation() { return ; signal_soft_deprecated( "`UQ()` is soft-deprecated as of rlang 0.2.0. " "Please use the prefix form of `!!` instead." ); } void signal_uqs_soft_deprecation() { return ; signal_soft_deprecated( "`UQS()` is soft-deprecated as of rlang 0.2.0. " "Please use the prefix form of `!!!` instead." ); } void signal_namespaced_uq_deprecation() { r_warn_deprecated("namespaced rlang::UQ()", "Prefixing `UQ()` with the rlang namespace is deprecated as of rlang 0.3.0.\n" "Please use the non-prefixed form or `!!` instead.\n" "\n" " # Bad:\n" " rlang::expr(mean(rlang::UQ(var) * 100))\n" "\n" " # Ok:\n" " rlang::expr(mean(UQ(var) * 100))\n" "\n" " # Good:\n" " rlang::expr(mean(!!var * 100))\n" ); } void signal_namespaced_uqs_deprecation() { r_warn_deprecated("namespaced rlang::UQS()", "Prefixing `UQS()` with the rlang namespace is deprecated as of rlang 0.3.0.\n" "Please use the non-prefixed form or `!!!` instead.\n" "\n" " # Bad:\n" " rlang::expr(mean(rlang::UQS(args)))\n" "\n" " # Ok:\n" " rlang::expr(mean(UQS(args)))\n" "\n" " # Good:\n" " rlang::expr(mean(!!!args))\n" ); } void maybe_poke_big_bang_op(sexp* x, struct expansion_info* info) { if (r_is_call(x, "!!!")) { if (r_node_cddr(x) != r_null) { r_abort("Can't supply multiple arguments to `!!!`"); } info->op = OP_EXPAND_UQS; info->operand = r_node_cadr(x); return ; } // Handle expressions like foo::`!!`(bar) or foo$`!!`(bar) if (r_is_prefixed_call(x, "!!!")) { const char* name = r_sym_get_c_string(r_node_caar(x)); r_abort("Prefix form of `!!!` can't be used with `%s`", name); } bool namespaced_uqs = r_is_namespaced_call(x, "rlang", "UQS"); if (namespaced_uqs) { signal_namespaced_uqs_deprecation(); } if (namespaced_uqs || r_is_call(x, "UQS")) { signal_uqs_soft_deprecation(); info->op = OP_EXPAND_UQS; info->operand = r_node_cadr(x); return ; } } static sexp* dot_data_sym = NULL; struct expansion_info which_expansion_op(sexp* x, bool unquote_names) { struct expansion_info info = which_uq_op(x); if (r_typeof(x) != r_type_call) { return info; } if (info.op) { return info; } if (is_problematic_op(x)) { info.op = OP_EXPAND_FIXUP; return info; } if (unquote_names && r_is_call(x, ":=")) { info.op = OP_EXPAND_UQN; return info; } if (r_is_call(x, "!!")) { info.op = OP_EXPAND_UQ; info.operand = r_node_cadr(x); return info; } // Handle expressions like foo::`!!`(bar) or foo$`!!`(bar) if (r_is_prefixed_call(x, "!!")) { info.op = OP_EXPAND_UQ; info.operand = r_node_cadr(x); info.parent = r_node_cdr(r_node_cdar(x)); info.root = r_node_car(x); return info; } maybe_poke_big_bang_op(x, &info); if (info.op == OP_EXPAND_UQS) { return info; } // This logic is complicated because rlang::UQ() gets fully unquoted // but not foobar::UQ(). The functional form UI is now retired so // we'll be able to simplify this in the future. if (r_is_prefixed_call(x, "UQ")) { signal_uq_soft_deprecation(); info.op = OP_EXPAND_UQ; info.operand = r_node_cadr(x); if (r_is_namespaced_call(x, "rlang", NULL)) { signal_namespaced_uq_deprecation(); } else { info.parent = r_node_cdr(r_node_cdar(x)); info.root = r_node_car(x); } return info; } if (r_is_call(x, "UQ")) { signal_uq_soft_deprecation(); info.op = OP_EXPAND_UQ; info.operand = r_node_cadr(x); return info; } if (r_is_call(x, "[[") && r_node_cadr(x) == dot_data_sym) { info.op = OP_EXPAND_DOT_DATA; info.root = x; info.parent = r_node_cddr(x); info.operand = r_node_car(info.parent); // User had to unquote operand manually before .data[[ was unquote syntax struct expansion_info nested = which_expansion_op(info.operand, false); if (nested.op == OP_EXPAND_UQ) { const char* msg = "It is no longer necessary to unquote within the `.data` pronoun"; r_signal_soft_deprecated(msg, msg, r_empty_env); info.operand = nested.operand; } return info; } return info; } struct expansion_info is_big_bang_op(sexp* x) { struct expansion_info info = which_uq_op(x); if (info.op != OP_EXPAND_UQS) { maybe_poke_big_bang_op(x, &info); } return info; } static sexp* bang_bang_teardown(sexp* value, struct expansion_info info) { r_mark_shared(value); if (info.parent != r_null) { r_node_poke_car(info.parent, value); } if (info.root == r_null) { return value; } else { return info.root; } } static sexp* bang_bang(struct expansion_info info, sexp* env) { sexp* value = r_eval(info.operand, env); return bang_bang_teardown(value, info); } // From dots.c sexp* big_bang_coerce_pairlist(sexp* x, bool deep); sexp* big_bang(sexp* operand, sexp* env, sexp* prev, sexp* node) { sexp* value = KEEP(r_eval(operand, env)); value = big_bang_coerce_pairlist(value, true); if (value == r_null) { // Remove `!!!foo` from pairlist of args r_node_poke_cdr(prev, r_node_cdr(node)); node = prev; } else { // Insert coerced value into existing pairlist of args sexp* tail = r_node_tail(value); r_node_poke_cdr(tail, r_node_cdr(node)); r_node_poke_cdr(prev, value); node = tail; } FREE(1); return node; } static sexp* curly_curly(struct expansion_info info, sexp* env) { sexp* value = rlang_enquo(info.operand, env); return bang_bang_teardown(value, info); } // Defined below static sexp* call_list_interp(sexp* x, sexp* env); static sexp* node_list_interp(sexp* x, sexp* env); static void call_maybe_poke_string_head(sexp* call); sexp* call_interp(sexp* x, sexp* env) { struct expansion_info info = which_expansion_op(x, false); return call_interp_impl(x, env, info); } sexp* call_interp_impl(sexp* x, sexp* env, struct expansion_info info) { if (info.op && info.op != OP_EXPAND_FIXUP && r_node_cdr(x) == r_null) { r_abort("`UQ()` and `UQS()` must be called with an argument"); } switch (info.op) { case OP_EXPAND_NONE: if (r_typeof(x) != r_type_call) { return x; } else { sexp* out = call_list_interp(x, env); call_maybe_poke_string_head(out); return out; } case OP_EXPAND_UQ: return bang_bang(info, env); case OP_EXPAND_CURLY: return curly_curly(info, env); case OP_EXPAND_DOT_DATA: return bang_bang(info, env); case OP_EXPAND_FIXUP: if (info.operand == r_null) { return fixup_interp(x, env); } else { return fixup_interp_first(info.operand, env); } case OP_EXPAND_UQS: r_abort("Can't use `!!!` at top level."); case OP_EXPAND_UQN: r_abort("Internal error: Deep `:=` unquoting."); } // Silence noreturn warning on GCC r_abort("Never reached."); } // Make (!!"foo")() and "foo"() equivalent static void call_maybe_poke_string_head(sexp* call) { sexp* head = r_node_car(call); if (r_typeof(head) != r_type_character) { return ; } r_ssize n = r_length(head); if (n != 1) { r_abort("Unquoted function name must be a character vector of length 1"); } r_node_poke_car(call, r_sym(r_chr_get_c_string(head, 0))); } static sexp* call_list_interp(sexp* x, sexp* env) { r_node_poke_car(x, call_interp(r_node_car(x), env)); r_node_poke_cdr(x, node_list_interp(r_node_cdr(x), env)); return x; } static sexp* node_list_interp(sexp* node, sexp* env) { sexp* prev = KEEP(r_new_node(r_null, node)); sexp* out = prev; while (node != r_null) { sexp* arg = r_node_car(node); struct expansion_info info = which_expansion_op(arg, false); if (info.op == OP_EXPAND_UQS) { node = big_bang(info.operand, env, prev, node); } else { r_node_poke_car(node, call_interp_impl(arg, env, info)); } prev = node; node = r_node_cdr(node); } FREE(1); return r_node_cdr(out); } sexp* rlang_interp(sexp* x, sexp* env) { if (!r_is_environment(env)) { r_abort("`env` must be an environment"); } if (r_typeof(x) != r_type_call) { return x; } x = KEEP(r_duplicate(x, false)); x = call_interp(x, env); FREE(1); return x; } void rlang_init_expr_interp() { dot_data_sym = r_sym(".data"); } rlang/src/internal/quo.h0000644000176200001440000000104113361376453014744 0ustar liggesusers#ifndef RLANG_INTERNAL_QUO_H #define RLANG_INTERNAL_QUO_H sexp* rlang_new_quosure(sexp* expr, sexp* env); bool rlang_is_quosure(sexp* x); sexp* rlang_get_expression(sexp* x, sexp* alternate); sexp* rlang_quo_get_env(sexp* quo); sexp* rlang_quo_get_expr(sexp* quo); static inline sexp* rlang_quo_get_expr_(sexp* quo) { return r_node_cadr(quo); } void check_quosure(sexp* x); bool quo_is_missing(sexp* quo); bool quo_is_symbol(sexp* quo); bool quo_is_call(sexp* quo); bool quo_is_symbolic(sexp* quo); bool quo_is_null(sexp* quo); #endif rlang/src/internal/internal.c0000644000176200001440000000205013610376546015750 0ustar liggesusers#include #include "internal.h" sexp* rlang_zap = NULL; sexp* as_list_call = NULL; sexp* as_list_s4_call = NULL; sexp* rlang_objs_keep = NULL; sexp* rlang_objs_trailing = NULL; sexp* fns_function = NULL; sexp* fns_quote = NULL; void rlang_init_utils(); void rlang_init_dots(); void rlang_init_expr_interp(); void rlang_init_eval_tidy(); void rlang_init_internal(sexp* ns) { rlang_init_utils(); rlang_init_dots(ns); rlang_init_expr_interp(); rlang_init_eval_tidy(); rlang_zap = rlang_ns_get("zap!"); as_list_call = r_parse("as.list(x)"); r_mark_precious(as_list_call); as_list_s4_call = r_parse("as(x, 'list')"); r_mark_precious(as_list_s4_call); rlang_objs_keep = r_chr("keep"); r_mark_precious(rlang_objs_keep); rlang_objs_trailing = r_chr("trailing"); r_mark_precious(rlang_objs_trailing); fns_function = r_eval(r_sym("function"), r_base_env); fns_quote = r_eval(r_sym("quote"), r_base_env); /* dots.c - enum dots_expansion_op */ RLANG_ASSERT(OP_DOTS_MAX == DOTS_CAPTURE_TYPE_MAX * EXPANSION_OP_MAX); } rlang/src/internal/utils.c0000644000176200001440000000104213610376546015274 0ustar liggesusers#include sexp* new_preserved_empty_list() { sexp* empty_list = r_new_vector(r_type_list, 0); r_mark_precious(empty_list); r_mark_shared(empty_list); sexp* nms = KEEP(r_new_vector(r_type_character, 0)); r_poke_names(empty_list, nms); FREE(1); return empty_list; } void signal_soft_deprecated(const char* msg) { sexp* opt = r_peek_option("lifecycle_verbose_soft_deprecation"); if (r_is_true(opt)) { r_warn(msg); } } sexp* rlang_ns_env = NULL; void rlang_init_utils() { rlang_ns_env = r_ns_env("rlang"); } rlang/src/internal/eval.c0000644000176200001440000000134713500141715015055 0ustar liggesusers#include #include "internal.h" // From call.c sexp* rlang_call2(sexp* fn, sexp* args, sexp* ns); sexp* rlang_exec(sexp* call, sexp* op, sexp* args, sexp* rho) { args = r_node_cdr(args); sexp* fn = KEEP(r_eval(r_sym(".fn"), rho)); sexp* env = KEEP(r_eval(r_sym(".env"), rho)); sexp* dots = KEEP(rlang_dots(rho)); sexp* exec_call = KEEP(rlang_call2(fn, dots, r_null)); sexp* node = r_node_cdr(exec_call); while (node != r_null) { sexp* arg = r_node_car(node); // Protect all symbolic arguments from being evaluated if (r_is_symbolic(arg)) { r_node_poke_car(node, r_call2(fns_quote, arg)); } node = r_node_cdr(node); } sexp* out = r_eval(exec_call, env); FREE(4); return out; } rlang/src/internal/eval-tidy.c0000644000176200001440000003573613610373777016056 0ustar liggesusers#include #include "internal.h" static sexp* quo_mask_flag_sym = NULL; static sexp* data_mask_flag_sym = NULL; enum rlang_mask_type { RLANG_MASK_DATA, // Full data mask RLANG_MASK_QUOSURE, // Quosure mask with only `~` binding RLANG_MASK_NONE }; struct rlang_mask_info { sexp* mask; enum rlang_mask_type type; }; static struct rlang_mask_info mask_info(sexp* mask) { if (r_typeof(mask) != r_type_environment) { return (struct rlang_mask_info) { r_null, RLANG_MASK_NONE }; } sexp* flag; flag = r_env_find_anywhere(mask, data_mask_flag_sym); if (flag != r_unbound_sym) { return (struct rlang_mask_info) { flag, RLANG_MASK_DATA }; } flag = r_env_find_anywhere(mask, quo_mask_flag_sym); if (flag != r_unbound_sym) { return (struct rlang_mask_info) { flag, RLANG_MASK_QUOSURE }; } return (struct rlang_mask_info) { r_null, RLANG_MASK_NONE }; } static sexp* data_pronoun_class = NULL; static sexp* ctxt_pronoun_class = NULL; static sexp* data_mask_env_sym = NULL; static sexp* rlang_new_data_pronoun(sexp* mask) { sexp* pronoun = KEEP(r_new_vector(r_type_list, 1)); r_list_poke(pronoun, 0, mask); r_poke_attribute(pronoun, r_class_sym, data_pronoun_class); FREE(1); return pronoun; } static sexp* rlang_new_ctxt_pronoun(sexp* top) { sexp* pronoun = KEEP(r_new_environment(r_env_parent(top), 0)); r_poke_attribute(pronoun, r_class_sym, ctxt_pronoun_class); FREE(1); return pronoun; } void poke_ctxt_env(sexp* mask, sexp* env) { sexp* ctxt_pronoun = r_env_find(mask, data_mask_env_sym); if (ctxt_pronoun == r_unbound_sym) { r_abort("Internal error: Can't find context pronoun in data mask"); } r_env_poke_parent(ctxt_pronoun, env); } static sexp* empty_names_chr; static void check_unique_names(sexp* x) { // Allow empty lists if (!r_length(x)) { return ; } sexp* names = r_vec_names(x); if (names == r_null) { r_abort("`data` must be uniquely named but does not have names"); } if (r_vec_find_first_duplicate(names, empty_names_chr, NULL)) { r_abort("`data` must be uniquely named but has duplicate columns"); } } sexp* rlang_as_data_pronoun(sexp* x) { int n_kept = 0; switch (r_typeof(x)) { case r_type_logical: case r_type_integer: case r_type_double: case r_type_complex: case r_type_character: case r_type_raw: x = KEEP_N(r_vec_coerce(x, r_type_list), n_kept); // fallthrough case r_type_list: check_unique_names(x); x = KEEP_N(r_list_as_environment(x, r_empty_env), n_kept); break; case r_type_environment: break; default: r_abort("`data` must be an uniquely named vector, list, data frame or environment"); } sexp* pronoun = rlang_new_data_pronoun(x); FREE(n_kept); return pronoun; } static sexp* data_mask_top_env_sym = NULL; static void check_data_mask_input(sexp* env, const char* arg) { if (r_typeof(env) != r_type_environment) { r_abort("Can't create data mask because `%s` must be an environment", arg); } } static void check_data_mask_top(sexp* bottom, sexp* top) { sexp* cur = bottom; while (cur != r_empty_env) { if (cur == top) { return ; } cur = r_env_parent(cur); } r_abort("Can't create data mask because `top` is not a parent of `bottom`"); } static sexp* env_sym = NULL; static sexp* old_sym = NULL; static sexp* mask_sym = NULL; static sexp* tilde_fn = NULL; static sexp* restore_mask_fn = NULL; static void on_exit_restore_lexical_env(sexp* mask, sexp* old, sexp* frame) { sexp* fn = KEEP(r_duplicate(restore_mask_fn, true)); sexp* env = KEEP(r_new_environment(r_base_env, 2)); r_env_poke(env, mask_sym, mask); r_env_poke(env, old_sym, old); r_fn_poke_env(fn, env); sexp* call = KEEP(r_new_call(fn, r_null)); r_on_exit(call, frame); FREE(3); } sexp* rlang_new_data_mask(sexp* bottom, sexp* top) { sexp* data_mask; if (bottom == r_null) { bottom = KEEP(r_new_environment(r_empty_env, 0)); data_mask = bottom; } else { check_data_mask_input(bottom, "bottom"); // Create a child because we don't know what might be in `bottom` // and we need to clear its contents without deleting any object // created in the data mask environment data_mask = KEEP(r_new_environment(bottom, 0)); } if (top == r_null) { top = bottom; } else { check_data_mask_input(top, "top"); } if (top != bottom) { check_data_mask_top(bottom, top); } sexp* ctxt_pronoun = KEEP(rlang_new_ctxt_pronoun(top)); r_env_poke(data_mask, r_tilde_sym, tilde_fn); r_env_poke(data_mask, data_mask_flag_sym, data_mask); r_env_poke(data_mask, data_mask_env_sym, ctxt_pronoun); r_env_poke(data_mask, data_mask_top_env_sym, top); FREE(2); return data_mask; } sexp* rlang_is_data_mask(sexp* env) { return r_lgl(mask_info(env).type == RLANG_MASK_DATA); } static sexp* mask_find(sexp* env, sexp* sym) { if (r_typeof(sym) != r_type_symbol) { r_abort("Internal error: Data pronoun must be subset with a symbol"); } sexp* top_env = r_env_find(env, data_mask_top_env_sym); if (r_typeof(top_env) == r_type_environment) { // Start lookup in the parent if the pronoun wraps a data mask env = r_env_parent(env); } else { // Data pronouns created from lists or data frames are converted // to a simple environment whose ancestry shouldn't be looked up. top_env = env; } KEEP(top_env); // Help rchk sexp* cur = env; do { sexp* obj = r_env_find(cur, sym); if (obj != r_unbound_sym && !r_is_function(obj)) { FREE(1); return obj; } if (cur == top_env) { break; } else { cur = r_env_parent(cur); } } while (cur != r_empty_env); FREE(1); return r_unbound_sym; } sexp* rlang_data_pronoun_get(sexp* pronoun, sexp* sym) { if (r_typeof(pronoun) != r_type_environment) { r_abort("Internal error: Data pronoun must wrap an environment"); } sexp* obj = mask_find(pronoun, sym); if (obj == r_unbound_sym) { sexp* call = KEEP(r_parse("rlang:::abort_data_pronoun(x)")); r_eval_with_x(call, r_base_env, sym); r_abort("Internal error: .data subsetting should have failed earlier"); } r_mark_shared(obj); return obj; } static void warn_env_as_mask_once() { const char* msg = "Passing an environment as data mask is deprecated.\n" "Please use `new_data_mask()` to transform your environment to a mask.\n" "\n" " env <- env(foo = \"bar\")\n" "\n" " # Bad:\n" " as_data_mask(env)\n" " eval_tidy(expr, env)\n" "\n" " # Good:\n" " mask <- new_data_mask(env)\n" " eval_tidy(expr, mask)"; r_warn_deprecated(msg, msg); } static sexp* data_pronoun_sym = NULL; sexp* rlang_as_data_mask(sexp* data) { if (mask_info(data).type == RLANG_MASK_DATA) { return data; } if (data == r_null) { return rlang_new_data_mask(r_null, r_null); } int n_protect = 0; sexp* bottom = NULL; switch (r_typeof(data)) { case r_type_environment: warn_env_as_mask_once(); bottom = KEEP_N(r_env_clone(data, NULL), n_protect); break; case r_type_logical: case r_type_integer: case r_type_double: case r_type_complex: case r_type_character: case r_type_raw: data = r_vec_coerce(data, r_type_list); KEEP_N(data, n_protect); // fallthrough: case r_type_list: { check_unique_names(data); sexp* names = r_vec_names(data); bottom = KEEP_N(r_new_environment(r_empty_env, 0), n_protect); if (names != r_null) { r_ssize n = r_length(data); for (r_ssize i = 0; i < n; ++i) { // Ignore empty or missing names sexp* nm = r_chr_get(names, i); if (r_str_is_name(nm)) { sexp* elt = r_list_get(data, i); r_env_poke(bottom, r_str_as_symbol(nm), elt); } } } break; } default: r_abort("`data` must be a vector, list, data frame, or environment"); } sexp* data_mask = KEEP_N(rlang_new_data_mask(bottom, bottom), n_protect); sexp* data_pronoun = KEEP_N(rlang_as_data_pronoun(data_mask), n_protect); r_env_poke(bottom, data_pronoun_sym, data_pronoun); FREE(n_protect); return data_mask; } // For compatibility of the exported C callable // TODO: warn sexp* rlang_new_data_mask_compat(sexp* bottom, sexp* top, sexp* parent) { return rlang_new_data_mask(bottom, top); } sexp* rlang_as_data_mask_compat(sexp* data, sexp* parent) { return rlang_as_data_mask(data); } static sexp* tilde_prim = NULL; static sexp* base_tilde_eval(sexp* tilde, sexp* quo_env) { if (r_f_has_env(tilde)) { return tilde; } // Inline the base primitive because overscopes override `~` to make // quosures self-evaluate tilde = KEEP(r_new_call(tilde_prim, r_node_cdr(tilde))); tilde = KEEP(r_eval(tilde, quo_env)); // Change it back because the result still has the primitive inlined r_node_poke_car(tilde, r_tilde_sym); FREE(2); return tilde; } sexp* env_get_top_binding(sexp* mask) { sexp* top = r_env_find(mask, data_mask_top_env_sym); if (top == r_unbound_sym) { r_abort("Internal error: Can't find .top pronoun in data mask"); } if (r_typeof(top) != r_type_environment) { r_abort("Internal error: Unexpected .top pronoun type"); } return top; } static sexp* env_poke_parent_fn = NULL; static sexp* env_poke_fn = NULL; sexp* rlang_tilde_eval(sexp* tilde, sexp* current_frame, sexp* caller_frame) { // Remove srcrefs from system call r_poke_attribute(tilde, r_srcref_sym, r_null); if (!rlang_is_quosure(tilde)) { return base_tilde_eval(tilde, caller_frame); } if (quo_is_missing(tilde)) { return(r_missing_arg()); } sexp* expr = rlang_quo_get_expr(tilde); if (!r_is_symbolic(expr)) { return expr; } sexp* quo_env = rlang_quo_get_env(tilde); if (r_typeof(quo_env) != r_type_environment) { r_abort("Internal error: Quosure environment is corrupt"); } int n_protect = 0; sexp* top; struct rlang_mask_info info = mask_info(caller_frame); switch (info.type) { case RLANG_MASK_DATA: top = KEEP_N(env_get_top_binding(info.mask), n_protect); // Update `.env` pronoun to current quosure env temporarily poke_ctxt_env(info.mask, quo_env); break; case RLANG_MASK_QUOSURE: top = info.mask; break; case RLANG_MASK_NONE: r_abort("Internal error: Can't find the data mask"); } // Unless the quosure was created in the mask, swap lexical contexts // temporarily by rechaining the top of the mask to the quosure // environment if (!r_env_inherits(info.mask, quo_env, top)) { // Unwind-protect the restoration of original parents on_exit_restore_lexical_env(info.mask, r_env_parent(top), current_frame); r_env_poke_parent(top, quo_env); } FREE(n_protect); return r_eval(expr, info.mask); } static const char* data_mask_objects_names[5] = { ".__tidyeval_data_mask__.", "~", ".top_env", ".env", NULL }; // Soft-deprecated in rlang 0.2.0 sexp* rlang_data_mask_clean(sexp* mask) { sexp* bottom = r_env_parent(mask); sexp* top = r_eval(data_mask_top_env_sym, mask); KEEP(top); // Help rchk if (top == r_null) { top = bottom; } // At this level we only want to remove our own stuff r_env_unbind_all(mask, data_mask_objects_names, false); // Remove everything in the other levels sexp* env = bottom; sexp* parent = r_env_parent(top); while (env != parent) { sexp* nms = KEEP(r_env_names(env)); r_env_unbind_names(env, nms, false); FREE(1); env = r_env_parent(env); } FREE(1); return mask; } static sexp* new_quosure_mask(sexp* env) { sexp* mask = KEEP(r_new_environment(env, 3)); r_env_poke(mask, r_tilde_sym, tilde_fn); r_env_poke(mask, quo_mask_flag_sym, mask); FREE(1); return mask; } sexp* rlang_eval_tidy(sexp* expr, sexp* data, sexp* env) { int n_protect = 0; if (rlang_is_quosure(expr)) { env = r_quo_get_env(expr); expr = r_quo_get_expr(expr); } // If there is no data, we only need to mask `~` with the definition // for quosure thunks. Otherwise we create a heavier data mask with // all the masking objects, data pronouns, etc. if (data == r_null) { sexp* mask = KEEP_N(new_quosure_mask(env), n_protect); sexp* out = r_eval(expr, mask); FREE(n_protect); return out; } sexp* mask = KEEP_N(rlang_as_data_mask(data), n_protect); sexp* top = KEEP_N(env_get_top_binding(mask), n_protect); // Rechain the mask on the new lexical env but don't restore it on // exit. This way leaked masks inherit from a somewhat sensible // environment. We could do better with ALTENV and two-parent data // masks: // // * We'd create a new two-parents evaluation env for each quosure. // The first parent would be the mask and the second the lexical // environment. // // * The data mask top would always inherit from the empty // environment. // // * Look-up in leaked environments would proceed from the data mask // to the appropriate lexical environment (from quosures or from // the `env` argument of eval_tidy()). if (!r_env_inherits(mask, env, top)) { poke_ctxt_env(mask, env); r_env_poke_parent(top, env); } sexp* out = r_eval(expr, mask); FREE(n_protect); return out; } void rlang_init_eval_tidy() { sexp* rlang_ns_env = KEEP(r_ns_env("rlang")); tilde_fn = r_parse_eval( "function(...) { \n" " .Call(rlang_tilde_eval, \n" " sys.call(), # Quosure env \n" " environment(), # Unwind-protect env \n" " parent.frame() # Lexical env \n" " ) \n" "} \n", rlang_ns_env ); r_mark_precious(tilde_fn); data_pronoun_class = r_chr("rlang_data_pronoun"); r_mark_precious(data_pronoun_class); ctxt_pronoun_class = r_chr("rlang_ctxt_pronoun"); r_mark_precious(ctxt_pronoun_class); empty_names_chr = r_new_vector(r_type_character, 2); r_mark_precious(empty_names_chr); r_chr_poke(empty_names_chr, 0, r_string("")); r_chr_poke(empty_names_chr, 1, r_missing_str); quo_mask_flag_sym = r_sym(".__tidyeval_quosure_mask__."); data_mask_flag_sym = r_sym(".__tidyeval_data_mask__."); data_mask_env_sym = r_sym(".env"); data_mask_top_env_sym = r_sym(".top_env"); data_pronoun_sym = r_sym(".data"); tilde_prim = r_base_ns_get("~"); env_poke_parent_fn = rlang_ns_get("env_poke_parent"); env_poke_fn = rlang_ns_get("env_poke"); env_sym = r_sym("env"); old_sym = r_sym("old"); mask_sym = r_sym("mask"); restore_mask_fn = r_parse_eval( "function() { \n" " ctxt_pronoun <- `mask`$.env \n" " if (!is.null(ctxt_pronoun)) { \n" " parent.env(ctxt_pronoun) <- `old` \n" " } \n" " \n" " top <- `mask`$.top_env \n" " if (is.null(top)) { \n" " top <- `mask` \n" " } \n" " \n" " parent.env(top) <- `old` \n" "} \n", r_base_env ); r_mark_precious(restore_mask_fn); FREE(1); } rlang/src/internal/quo.c0000644000176200001440000000373313457603056014747 0ustar liggesusers#include static const char* quo_tags[3] = { "quosure", "formula", NULL }; sexp* new_raw_formula(sexp* lhs, sexp* rhs, sexp* env); sexp* rlang_new_quosure(sexp* expr, sexp* env) { if (r_typeof(env) != r_type_environment) { r_abort("`env` must be an environment"); } sexp* quo = KEEP(new_raw_formula(r_null, expr, env)); r_push_classes(quo, quo_tags); FREE(1); return quo; } bool rlang_is_quosure(sexp* x) { return r_typeof(x) == r_type_call && Rf_inherits(x, "quosure"); } inline void check_quosure(sexp* quo) { if (!rlang_is_quosure(quo)) { r_abort("`quo` must be a quosure"); } } sexp* rlang_quo_get_expr(sexp* quo) { check_quosure(quo); return r_node_cadr(quo); } sexp* rlang_quo_set_expr(sexp* quo, sexp* expr) { check_quosure(quo); quo = r_duplicate(quo, true); return r_node_poke_cadr(quo, expr); } sexp* rlang_quo_get_env(sexp* quo) { check_quosure(quo); return r_get_attribute(quo, r_dot_environment_sym); } sexp* rlang_quo_set_env(sexp* quo, sexp* env) { check_quosure(quo); if (r_typeof(env) != r_type_environment) { r_abort("`env` must be an environment"); } return r_set_attribute(quo, r_dot_environment_sym, env); } sexp* rlang_get_expression(sexp* x, sexp* alternate) { switch (r_typeof(x)) { case LANGSXP: if (r_is_formulaish(x, -1, 0)) { return r_f_rhs(x); } break; // case CLOSXP: // return r_fn_body(x); case VECSXP: if (r_inherits(x, "frame")) { return r_list_get(x, 2); } break; default: break; } if (alternate) { return alternate; } else { return x; } } bool quo_is_missing(sexp* quo) { return r_node_cadr(quo) == R_MissingArg; } bool quo_is_symbol(sexp* quo) { return r_typeof(r_node_cadr(quo)) == r_type_symbol; } bool quo_is_call(sexp* quo) { return r_typeof(r_node_cadr(quo)) == r_type_call; } bool quo_is_symbolic(sexp* quo) { return r_is_symbolic(r_node_cadr(quo)); } bool quo_is_null(sexp* quo) { return r_node_cadr(quo) == r_null; } rlang/src/internal/utils.h0000644000176200001440000000040613610376546015304 0ustar liggesusers#ifndef RLANG_INTERNAL_UTILS_H #define RLANG_INTERNAL_UTILS_H sexp* new_preserved_empty_list(); void signal_soft_deprecated(const char* msg); sexp* rlang_ns_get(const char* name); sexp* rlang_enquo(sexp* sym, sexp* frame); extern sexp* rlang_ns_env; #endif rlang/src/internal/env.c0000644000176200001440000000055013351410763014717 0ustar liggesusers#include #define FRAME_LOCK_MASK (1 << 14) #define FRAME_IS_LOCKED(e) (ENVFLAGS(e) & FRAME_LOCK_MASK) #define UNLOCK_FRAME(e) SET_ENVFLAGS(e, ENVFLAGS(e) & (~FRAME_LOCK_MASK)) // Should only be used in development tools sexp* rlang_env_unlock(sexp* env) { UNLOCK_FRAME(env); return FRAME_IS_LOCKED(env) == 0 ? r_shared_true : r_shared_false; } rlang/src/internal/fn.c0000644000176200001440000000106113457603056014536 0ustar liggesusers#include #include "internal.h" sexp* rlang_new_function(sexp* args, sexp* body, sexp* env) { if (r_typeof(env) != r_type_environment) { r_abort("`env` must be an environment"); } args = KEEP(r_vec_coerce(args, r_type_pairlist)); sexp* node = args; while (node != r_null) { if (r_node_tag(node) == r_null) { r_abort("All formal parameters in `args` must be named"); } node = r_node_cdr(node); } sexp* call = KEEP(r_call3(fns_function, args, body)); sexp* out = r_eval(call, env); FREE(2); return out; } rlang/src/internal/dots.c0000644000176200001440000006762413611314006015107 0ustar liggesusers#include #include "dots.h" #include "expr-interp.h" #include "internal.h" #include "utils.h" sexp* rlang_ns_get(const char* name); // Initialised at load time static sexp* empty_spliced_arg = NULL; static sexp* splice_box_attrib = NULL; sexp* rlang_new_splice_box(sexp* x) { sexp* out = KEEP(r_new_vector(r_type_list, 1)); r_list_poke(out, 0, x); r_poke_attributes(out, splice_box_attrib); r_mark_object(out); FREE(1); return out; } bool is_splice_box(sexp* x) { return r_get_attributes(x) == splice_box_attrib; } sexp* rlang_is_splice_box(sexp* x) { return r_lgl(is_splice_box(x)); } sexp* rlang_unbox(sexp* x) { if (r_length(x) != 1) { r_abort("Internal error: Expected a list of size 1 in `rlang_unbox()`."); } return r_list_get(x, 0); } enum dots_homonyms { DOTS_HOMONYMS_KEEP = 0, DOTS_HOMONYMS_FIRST, DOTS_HOMONYMS_LAST, DOTS_HOMONYMS_ERROR }; struct dots_capture_info { enum dots_capture_type type; r_ssize count; sexp* named; bool needs_expansion; int ignore_empty; bool preserve_empty; bool unquote_names; enum dots_homonyms homonyms; bool check_assign; sexp* (*big_bang_coerce)(sexp*); bool splice; }; static int arg_match_ignore_empty(sexp* ignore_empty); static enum dots_homonyms arg_match_homonyms(sexp* homonyms); struct dots_capture_info init_capture_info(enum dots_capture_type type, sexp* named, sexp* ignore_empty, sexp* preserve_empty, sexp* unquote_names, sexp* homonyms, sexp* check_assign, sexp* (*coercer)(sexp*), bool splice) { struct dots_capture_info info; info.type = type; info.count = 0; info.needs_expansion = false; info.named = named; info.ignore_empty = arg_match_ignore_empty(ignore_empty); info.preserve_empty = r_lgl_get(preserve_empty, 0); info.unquote_names = r_lgl_get(unquote_names, 0); info.homonyms = arg_match_homonyms(homonyms); info.check_assign = r_lgl_get(check_assign, 0); info.big_bang_coerce = coercer; info.splice = splice; return info; } static bool has_glue = false; sexp* rlang_glue_is_there() { has_glue = true; return r_null; } static bool has_curly(const char* str) { for (char c = *str; c != '\0'; ++str, c = *str) { if (c == '{') { return true; } } return false; } static void require_glue() { sexp* call = KEEP(r_parse("is_installed('glue')")); sexp* out = KEEP(r_eval(call, rlang_ns_env)); if (!r_is_scalar_logical(out)) { r_abort("Internal error: Expected scalar logical from `requireNamespace()`."); } if (!r_lgl_get(out, 0)) { r_abort("Can't use `{` symbols in LHS of `:=` if glue is not installed."); } FREE(2); } // Initialised at load time static sexp* glue_unquote_fn = NULL; static sexp* glue_unquote(sexp* lhs, sexp* env) { if (r_typeof(lhs) != r_type_character || r_length(lhs) != 1 || !has_curly(r_chr_get_c_string(lhs, 0))) { return lhs; } if (!has_glue) { require_glue(); } sexp* glue_unquote_call = KEEP(r_call2(glue_unquote_fn, lhs)); lhs = r_eval(glue_unquote_call, env); FREE(1); return lhs; } static sexp* def_unquote_name(sexp* expr, sexp* env) { int n_kept = 0; sexp* lhs = r_node_cadr(expr); struct expansion_info info = which_expansion_op(lhs, true); switch (info.op) { case OP_EXPAND_NONE: lhs = KEEP_N(glue_unquote(lhs, env), n_kept); break; case OP_EXPAND_UQ: lhs = KEEP_N(r_eval(info.operand, env), n_kept); break; case OP_EXPAND_CURLY: lhs = KEEP_N(rlang_enquo(info.operand, env), n_kept); break; case OP_EXPAND_UQS: r_abort("The LHS of `:=` can't be spliced with `!!!`"); case OP_EXPAND_UQN: r_abort("Internal error: Chained `:=` should have been detected earlier"); case OP_EXPAND_FIXUP: r_abort("The LHS of `:=` must be a string or a symbol"); case OP_EXPAND_DOT_DATA: r_abort("Can't use the `.data` pronoun on the LHS of `:=`"); } // Unwrap quosures for convenience if (rlang_is_quosure(lhs)) { lhs = rlang_quo_get_expr_(lhs); } int err = 0; lhs = r_new_symbol(lhs, &err); if (err) { r_abort("The LHS of `:=` must be a string or a symbol"); } FREE(n_kept); return lhs; } void signal_retired_splice() { const char* msg = "Unquoting language objects with `!!!` is deprecated as of rlang 0.4.0.\n" "Please use `!!` instead.\n" "\n" " # Bad:\n" " dplyr::select(data, !!!enquo(x))\n" "\n" " # Good:\n" " dplyr::select(data, !!enquo(x)) # Unquote single quosure\n" " dplyr::select(data, !!!enquos(x)) # Splice list of quosures\n"; r_warn_deprecated(msg, msg); } static sexp* dots_big_bang_coerce(sexp* x) { switch (r_typeof(x)) { case r_type_null: case r_type_pairlist: case r_type_logical: case r_type_integer: case r_type_double: case r_type_complex: case r_type_character: case r_type_raw: if (r_is_object(x)) { return r_eval_with_x(as_list_call, r_global_env, x); } else { return r_vec_coerce(x, r_type_list); } case r_type_list: if (r_is_object(x)) { return r_eval_with_x(as_list_call, r_global_env, x); } else { return x; } case r_type_s4: return r_eval_with_x(as_list_s4_call, r_methods_ns_env, x); case r_type_call: if (r_is_symbol(r_node_car(x), "{")) { return r_vec_coerce(r_node_cdr(x), r_type_list); } // else fallthrough case r_type_symbol: signal_retired_splice(); return r_new_list(x, NULL); default: r_abort( "Can't splice an object of type `%s` because it is not a vector", r_type_as_c_string(r_typeof(x)) ); } } // Also used in expr-interp.c sexp* big_bang_coerce_pairlist(sexp* x, bool deep) { int n_protect = 0; if (r_is_object(x)) { x = KEEP_N(dots_big_bang_coerce(x), n_protect); } switch (r_typeof(x)) { case r_type_null: case r_type_pairlist: x = r_duplicate(x, true); break; case r_type_logical: case r_type_integer: case r_type_double: case r_type_complex: case r_type_character: case r_type_raw: case r_type_list: x = r_vec_coerce(x, r_type_pairlist); break; case r_type_call: if (deep && r_is_symbol(r_node_car(x), "{")) { x = r_node_cdr(x); break; } // fallthrough case r_type_symbol: { if (deep) { signal_retired_splice(); x = r_new_node(x, r_null); break; } // fallthrough } default: r_abort( "Can't splice an object of type `%s` because it is not a vector", r_type_as_c_string(r_typeof(x)) ); } FREE(n_protect); return x; } static sexp* dots_big_bang_coerce_pairlist(sexp* x) { return big_bang_coerce_pairlist(x, false); } static sexp* dots_big_bang_value(struct dots_capture_info* capture_info, sexp* value, sexp* env, bool quosured) { value = KEEP(capture_info->big_bang_coerce(value)); r_ssize n = r_length(value); if (quosured) { if (r_is_shared(value)) { sexp* tmp = r_duplicate(value, true); FREE(1); value = KEEP(tmp); } for (r_ssize i = 0; i < n; ++i) { sexp* elt = r_list_get(value, i); elt = forward_quosure(elt, env); r_list_poke(value, i, elt); } } // The dots_values() variant does not splice for performance if (capture_info->splice) { capture_info->needs_expansion = true; capture_info->count += n; } value = rlang_new_splice_box(value); FREE(1); return value; } static sexp* dots_big_bang(struct dots_capture_info* capture_info, sexp* expr, sexp* env, bool quosured) { sexp* value = KEEP(r_eval(expr, env)); sexp* out = dots_big_bang_value(capture_info, value, env, quosured); FREE(1); return out; } static inline bool should_ignore(int ignore_empty, r_ssize i, r_ssize n) { return ignore_empty == 1 || (i == n - 1 && ignore_empty == -1); } static inline sexp* dot_get_expr(sexp* dot) { return r_list_get(dot, 0); } static inline sexp* dot_get_env(sexp* dot) { return r_list_get(dot, 1); } static sexp* dots_unquote(sexp* dots, struct dots_capture_info* capture_info) { capture_info->count = 0; r_ssize n = r_length(dots); bool unquote_names = capture_info->unquote_names; sexp* node = dots; for (r_ssize i = 0; node != r_null; ++i, node = r_node_cdr(node)) { sexp* elt = r_node_car(node); sexp* expr = dot_get_expr(elt); sexp* env = dot_get_env(elt); // Unquoting rearranges expressions expr = KEEP(r_duplicate(expr, false)); if (unquote_names && r_is_call(expr, ":=")) { if (r_node_tag(node) != r_null) { r_abort("Can't supply both `=` and `:=`"); } sexp* nm = def_unquote_name(expr, env); r_node_poke_tag(node, nm); expr = r_node_cadr(r_node_cdr(expr)); } if (capture_info->check_assign && r_is_call(expr, "<-") && r_peek_option("rlang_dots_disable_assign_warning") == r_null) { r_warn( "Using `<-` as argument is often a mistake.\n" "Do you need to use `=` to match an argument?\n" "\n" "If you really want to use `<-`, please wrap in braces:\n" "\n" " # Bad:\n" " fn(a <- 1)\n" "\n" " # Good:\n" " fn(a = 1) # Match 1 to parameter `a`\n" " fn({ a <- 1 }) # Assign 1 to variable `a`" ); } struct expansion_info info = which_expansion_op(expr, unquote_names); enum dots_expansion_op dots_op = info.op + (EXPANSION_OP_MAX * capture_info->type); sexp* name = r_node_tag(node); // Ignore empty arguments if (expr == r_missing_sym && (name == r_null || name == r_empty_str) && should_ignore(capture_info->ignore_empty, i, n)) { capture_info->needs_expansion = true; r_node_poke_car(node, empty_spliced_arg); FREE(1); continue; } switch (dots_op) { case OP_EXPR_NONE: case OP_EXPR_UQ: case OP_EXPR_FIXUP: case OP_EXPR_DOT_DATA: case OP_EXPR_CURLY: expr = call_interp_impl(expr, env, info); capture_info->count += 1; break; case OP_EXPR_UQS: expr = dots_big_bang(capture_info, info.operand, env, false); break; case OP_QUO_NONE: case OP_QUO_UQ: case OP_QUO_FIXUP: case OP_QUO_DOT_DATA: case OP_QUO_CURLY: { expr = KEEP(call_interp_impl(expr, env, info)); expr = forward_quosure(expr, env); FREE(1); capture_info->count += 1; break; } case OP_QUO_UQS: { expr = dots_big_bang(capture_info, info.operand, env, true); break; } case OP_VALUE_NONE: case OP_VALUE_FIXUP: case OP_VALUE_DOT_DATA: if (expr == r_missing_sym) { if (!capture_info->preserve_empty) { r_abort("Argument %d is empty", i + 1); } } else if (env != r_empty_env) { // Don't evaluate when `env` is the empty environment. This // happens when the argument was forced (and thus already // evaluated), for instance by lapply() or map(). expr = r_eval(expr, env); } if (is_splice_box(expr)) { // Coerce contents of splice boxes to ensure uniform type KEEP(expr); expr = rlang_unbox(expr); expr = dots_big_bang_value(capture_info, expr, env, false); FREE(1); } else { capture_info->count += 1; } break; case OP_VALUE_UQ: r_abort("Can't use `!!` in a non-quoting function"); case OP_VALUE_UQS: { expr = KEEP(r_eval(info.operand, env)); expr = dots_big_bang(capture_info, info.operand, env, false); FREE(1); break; } case OP_VALUE_CURLY: r_abort("Can't use `{{` in a non-quoting function"); case OP_EXPR_UQN: case OP_QUO_UQN: case OP_VALUE_UQN: r_abort("`:=` can't be chained"); case OP_DOTS_MAX: r_abort("Internal error: `OP_DOTS_MAX`"); } r_node_poke_car(node, expr); FREE(1); } return dots; } static int arg_match_ignore_empty(sexp* ignore_empty) { if (r_typeof(ignore_empty) != r_type_character || r_length(ignore_empty) == 0) { r_abort("`.ignore_empty` must be a character vector"); } const char* arg = r_chr_get_c_string(ignore_empty, 0); switch(arg[0]) { case 't': if (!strcmp(arg, "trailing")) return -1; else break; case 'n': if (!strcmp(arg, "none")) return 0; else break; case 'a': if (!strcmp(arg, "all")) return 1; else break; } r_abort("`.ignore_empty` must be one of: \"trailing\", \"none\", or \"all\""); } static enum dots_homonyms arg_match_homonyms(sexp* homonyms) { if (r_typeof(homonyms) != r_type_character || r_length(homonyms) == 0) { r_abort("`.homonyms` must be a character vector"); } const char* arg = r_chr_get_c_string(homonyms, 0); switch(arg[0]) { case 'k': if (!strcmp(arg, "keep")) return DOTS_HOMONYMS_KEEP; else break; case 'f': if (!strcmp(arg, "first")) return DOTS_HOMONYMS_FIRST; else break; case 'l': if (!strcmp(arg, "last")) return DOTS_HOMONYMS_LAST; else break; case 'e': if (!strcmp(arg, "error")) return DOTS_HOMONYMS_ERROR; else break; } r_abort("`.homonyms` must be one of: \"keep\", \"first\", \"last\", or \"error\""); } static void warn_deprecated_width() { const char* msg = "`.named` can no longer be a width"; r_warn_deprecated(msg, msg); } static bool should_auto_name(sexp* named) { if (r_length(named) != 1) { goto error; } switch (r_typeof(named)) { case r_type_logical: return r_lgl_get(named, 0); case r_type_integer: warn_deprecated_width(); return INTEGER(named)[0]; case r_type_double: if (r_is_integerish(named, -1, true)) { warn_deprecated_width(); return REAL(named)[0]; } // else fallthrough default: break; } error: r_abort("`.named` must be a scalar logical"); } static sexp* auto_name_call = NULL; static sexp* maybe_auto_name(sexp* x, sexp* named) { sexp* names = r_vec_names(x); if (should_auto_name(named) && (names == r_null || r_chr_has(names, ""))) { x = r_eval_with_x(auto_name_call, r_base_env, x); } return x; } static bool any_name(sexp* x, bool splice) { while (x != r_null) { if (r_node_tag(x) != r_null) { return true; } sexp* elt = r_node_car(x); if (splice && is_splice_box(elt)) { if (r_vec_names(rlang_unbox(elt)) != r_null) { return true; } } x = r_node_cdr(x); } return false; } static void check_named_splice(sexp* node) { if (r_node_tag(node) != r_null) { const char* msg = "`!!!` can't be supplied with a name. Only the operand's names are retained."; r_stop_defunct(msg); } } sexp* dots_as_list(sexp* dots, struct dots_capture_info* capture_info) { int n_protect = 0; sexp* out = KEEP_N(r_new_vector(r_type_list, capture_info->count), n_protect); // Add default empty names unless dots are captured by values sexp* out_names = r_null; if (capture_info->type != DOTS_VALUE || any_name(dots, capture_info->splice)) { out_names = KEEP_N(r_new_vector(r_type_character, capture_info->count), n_protect); r_push_names(out, out_names); } for (r_ssize i = 0, count = 0; dots != r_null; ++i, dots = r_node_cdr(dots)) { sexp* elt = r_node_car(dots); if (elt == empty_spliced_arg) { continue; } if (capture_info->splice && is_splice_box(elt)) { check_named_splice(dots); elt = rlang_unbox(elt); sexp* nms = r_vec_names(elt); r_ssize n = r_length(elt); for (r_ssize i = 0; i < n; ++i) { sexp* value = r_list_get(elt, i); r_list_poke(out, count, value); sexp* name = r_nms_get(nms, i); if (name != r_empty_str) { r_chr_poke(out_names, count, name); } ++count; } } else { r_list_poke(out, count, elt); sexp* name = r_node_tag(dots); if (name != r_null) { r_chr_poke(out_names, count, r_string(r_sym_get_c_string(name))); } ++count; } } FREE(n_protect); return out; } sexp* dots_as_pairlist(sexp* dots, struct dots_capture_info* capture_info) { sexp* out = KEEP(r_new_node(r_null, dots)); sexp* prev = out; while (dots != r_null) { sexp* elt = r_node_car(dots); if (elt == empty_spliced_arg) { dots = r_node_cdr(dots); r_node_poke_cdr(prev, dots); continue; } if (capture_info->splice && is_splice_box(elt)) { check_named_splice(dots); elt = rlang_unbox(elt); if (elt == r_null) { dots = r_node_cdr(dots); r_node_poke_cdr(prev, dots); continue; } r_node_poke_cdr(prev, elt); sexp* next = r_node_cdr(dots); sexp* tail = r_node_tail(elt); r_node_poke_cdr(tail, next); prev = tail; dots = next; continue; } prev = dots; dots = r_node_cdr(dots); } FREE(1); return r_node_cdr(out); } static sexp* dots_keep(sexp* dots, sexp* nms, bool first) { r_ssize n = r_length(dots); sexp* dups = KEEP(r_nms_are_duplicated(nms, !first)); r_ssize out_n = n - r_lgl_sum(dups, false); sexp* out = KEEP(r_new_vector(r_type_list, out_n)); sexp* out_nms = KEEP(r_new_vector(r_type_character, out_n)); r_push_names(out, out_nms); sexp** nms_ptr = r_chr_deref(nms); int* dups_ptr = r_lgl_deref(dups); for (r_ssize i = 0, out_i = 0; i < n; ++i, ++nms_ptr, ++dups_ptr) { if (!*dups_ptr) { r_list_poke(out, out_i, r_list_get(dots, i)); r_chr_poke(out_nms, out_i, *nms_ptr); ++out_i; } } FREE(3); return out; } static sexp* abort_dots_homonyms_call = NULL; static void dots_check_homonyms(sexp* dots, sexp* nms) { sexp* dups = KEEP(r_nms_are_duplicated(nms, false)); if (r_lgl_sum(dups, false)) { r_eval_with_xy(abort_dots_homonyms_call, r_base_env, dots, dups); r_abort("Internal error: `dots_check_homonyms()` should have failed earlier"); } FREE(1); } // From capture.c sexp* capturedots(sexp* frame); static sexp* dots_capture(struct dots_capture_info* capture_info, sexp* frame_env) { sexp* dots = KEEP(capturedots(frame_env)); dots = dots_unquote(dots, capture_info); FREE(1); return dots; } sexp* rlang_unescape_character(sexp*); static sexp* dots_finalise(struct dots_capture_info* capture_info, sexp* dots) { sexp* nms = r_vec_names(dots); if (nms != r_null) { // Serialised unicode points might arise when unquoting lists // because of the conversion to pairlist nms = KEEP(rlang_unescape_character(nms)); r_poke_names(dots, nms); dots = KEEP(maybe_auto_name(dots, capture_info->named)); switch (capture_info->homonyms) { case DOTS_HOMONYMS_KEEP: break; case DOTS_HOMONYMS_FIRST: dots = dots_keep(dots, nms, true); break; case DOTS_HOMONYMS_LAST: dots = dots_keep(dots, nms, false); break; case DOTS_HOMONYMS_ERROR: dots_check_homonyms(dots, nms); break; } FREE(2); } return dots; } sexp* rlang_exprs_interp(sexp* frame_env, sexp* named, sexp* ignore_empty, sexp* unquote_names, sexp* homonyms, sexp* check_assign) { struct dots_capture_info capture_info; capture_info = init_capture_info(DOTS_EXPR, named, ignore_empty, r_shared_true, unquote_names, homonyms, check_assign, &dots_big_bang_coerce, true); sexp* dots; dots = KEEP(dots_capture(&capture_info, frame_env)); dots = KEEP(dots_as_list(dots, &capture_info)); dots = dots_finalise(&capture_info, dots); FREE(2); return dots; } sexp* rlang_quos_interp(sexp* frame_env, sexp* named, sexp* ignore_empty, sexp* unquote_names, sexp* homonyms, sexp* check_assign) { struct dots_capture_info capture_info; capture_info = init_capture_info(DOTS_QUO, named, ignore_empty, r_shared_true, unquote_names, homonyms, check_assign, &dots_big_bang_coerce, true); sexp* dots; dots = KEEP(dots_capture(&capture_info, frame_env)); dots = KEEP(dots_as_list(dots, &capture_info)); dots = KEEP(dots_finalise(&capture_info, dots)); r_push_class(dots, "quosures"); FREE(3); return dots; } static bool is_spliced_bare_dots_value(sexp* x) { if (r_typeof(x) != r_type_list) { return false; } if (is_splice_box(x)) { return true; } if (r_is_object(x)) { return false; } return true; } static sexp* dots_values_impl(sexp* frame_env, sexp* named, sexp* ignore_empty, sexp* preserve_empty, sexp* unquote_names, sexp* homonyms, sexp* check_assign, bool splice) { struct dots_capture_info capture_info; capture_info = init_capture_info(DOTS_VALUE, named, ignore_empty, preserve_empty, unquote_names, homonyms, check_assign, &dots_big_bang_coerce, splice); sexp* dots; dots = KEEP(dots_capture(&capture_info, frame_env)); if (capture_info.needs_expansion) { dots = KEEP(dots_as_list(dots, &capture_info)); } else { dots = KEEP(r_vec_coerce(dots, r_type_list)); } dots = dots_finalise(&capture_info, dots); FREE(2); return dots; } sexp* rlang_ext2_dots_values(sexp* call, sexp* op, sexp* args, sexp* env) { args = r_node_cdr(args); sexp* named = KEEP(r_eval(r_node_car(args), env)); args = r_node_cdr(args); sexp* ignore_empty = KEEP(r_eval(r_node_car(args), env)); args = r_node_cdr(args); sexp* preserve_empty = KEEP(r_eval(r_node_car(args), env)); args = r_node_cdr(args); sexp* unquote_names = KEEP(r_eval(r_node_car(args), env)); args = r_node_cdr(args); sexp* homonyms = KEEP(r_eval(r_node_car(args), env)); args = r_node_cdr(args); sexp* check_assign = KEEP(r_eval(r_node_car(args), env)); sexp* out = dots_values_impl(env, named, ignore_empty, preserve_empty, unquote_names, homonyms, check_assign, false); FREE(6); return out; } sexp* rlang_env_dots_values(sexp* env) { return dots_values_impl(env, r_shared_false, rlang_objs_trailing, r_shared_false, r_shared_true, rlang_objs_keep, r_shared_false, false); } sexp* rlang_env_dots_list(sexp* env) { return dots_values_impl(env, r_shared_false, rlang_objs_trailing, r_shared_false, r_shared_true, rlang_objs_keep, r_shared_false, true); } sexp* rlang_dots_list(sexp* frame_env, sexp* named, sexp* ignore_empty, sexp* preserve_empty, sexp* unquote_names, sexp* homonyms, sexp* check_assign) { return dots_values_impl(frame_env, named, ignore_empty, preserve_empty, unquote_names, homonyms, check_assign, true); } sexp* rlang_dots_flat_list(sexp* frame_env, sexp* named, sexp* ignore_empty, sexp* preserve_empty, sexp* unquote_names, sexp* homonyms, sexp* check_assign) { struct dots_capture_info capture_info; capture_info = init_capture_info(DOTS_VALUE, named, ignore_empty, preserve_empty, unquote_names, homonyms, check_assign, &dots_big_bang_coerce, true); sexp* dots; dots = KEEP(dots_capture(&capture_info, frame_env)); dots = KEEP(r_vec_coerce(dots, r_type_list)); dots = KEEP(r_squash_if(dots, r_type_list, is_spliced_bare_dots_value, 1)); dots = dots_finalise(&capture_info, dots); FREE(3); return dots; } sexp* dots_values_node_impl(sexp* frame_env, sexp* named, sexp* ignore_empty, sexp* preserve_empty, sexp* unquote_names, sexp* homonyms, sexp* check_assign, bool splice) { struct dots_capture_info capture_info; capture_info = init_capture_info(DOTS_VALUE, named, ignore_empty, preserve_empty, unquote_names, homonyms, check_assign, &dots_big_bang_coerce_pairlist, splice); sexp* dots; dots = KEEP(dots_capture(&capture_info, frame_env)); dots = KEEP(dots_as_pairlist(dots, &capture_info)); // dots = dots_finalise(&capture_info, dots); FREE(2); return dots; } sexp* rlang_dots_pairlist(sexp* frame_env, sexp* named, sexp* ignore_empty, sexp* preserve_empty, sexp* unquote_names, sexp* homonyms, sexp* check_assign) { return dots_values_node_impl(frame_env, named, ignore_empty, preserve_empty, unquote_names, homonyms, check_assign, true); } void rlang_init_dots(sexp* ns) { glue_unquote_fn = r_eval(r_sym("glue_unquote"), ns); auto_name_call = r_parse("rlang:::quos_auto_name(x)"); r_mark_precious(auto_name_call); abort_dots_homonyms_call = r_parse("rlang:::abort_dots_homonyms(x, y)"); r_mark_precious(abort_dots_homonyms_call); { sexp* splice_box_class = KEEP(r_new_vector(r_type_character, 2)); r_chr_poke(splice_box_class, 0, r_string("rlang_box_splice")); r_chr_poke(splice_box_class, 1, r_string("rlang_box")); splice_box_attrib = r_pairlist(splice_box_class); r_mark_precious(splice_box_attrib); r_mark_shared(splice_box_attrib); r_node_poke_tag(splice_box_attrib, r_class_sym); FREE(1); } { sexp* list = KEEP(r_new_vector(r_type_list, 0)); empty_spliced_arg = rlang_new_splice_box(list); r_mark_precious(empty_spliced_arg); r_mark_shared(empty_spliced_arg); FREE(1); } } rlang/src/internal/expr-interp-rotate.c0000644000176200001440000004441713500153265017707 0ustar liggesusers#include #include "expr-interp.h" #include "expr-interp-rotate.h" /** * DOC: Interpolation in operator calls whose precedence might need fixup * * We want `!!` to have the precedence of unary `-` and `+` instead of * the very low precedence of `!`. To that end we need to patch the * AST to reflect the new precedence. * * Let's take `1 + 2 + 3` as a motivating example. `+` is a * left-associative operator so the expression `1 + 2` on the left is * evaluated first and it is pulled downwards in the AST: * * > 1 + 2 + 3 * * █─`+` * ├─█─`+` * │ ├─1 * │ └─2 * └─3 * * After introducing an unary operator with low precedence in the * expression we get this AST: * * > 1 + !2 + 3 * * █─`+` * ├─1 * └─█─`!` * └─█─`+` * ├─2 * └─3 * * Every binary operation on the RHS of `!` that has a higher * precedence will be evaluated before `!`. As a result the second `+` * never gets the chance of being matched to the first one, it is cut * out of the LHS of `!`. The effect of `!` on the AST is equivalent * to wrapping the problematic expression in parentheses. * * > 1 + (2 + 3) * * █─`+` * ├─1 * └─█─`(` * └─█─`+` * ├─2 * └─3 * * This is only problematic when the precedence of the `!!` operand is * lower than the precedence of its parent operation. If it is higher, * the implicit grouping is the same as the one produced by `!`: * * > ast(1 + 2 * 3) // Implicit grouping * * █─`+` * ├─1 * └─█─`* * ├─2 * └─3 * * > ast(1 + !2 * 3) // `!` grouping * * █─`+` * ├─1 * └─█─`!` * └─█─`* * ├─2 * └─3 * * If the precedence of `!`'s operand is lower the R parser will * unduly pull it downward in the AST. We can fix that by swapping the * operand with the parent node of `!`. In addition the LHS of the * operand (e.g. `2`) must become the RHS of the expression it was cut * off from. It turns out that these two operations amount to a [tree * rotation](https://en.wikipedia.org/wiki/Tree_rotation). The parent * node of `!` is the root (or rotator) and the `!` operand is the * pivot. We also need to take care of the actual expression that * needs to be unquoted, which we will call "target": * * > 1 + !!2 + 3 * * █─`+` // root * ├─1 * └─█─`!` * └─█─`!` * └─█─`+` // pivot * ├─2 // target * └─3 * * Notice from the diagrams above that the leaves of the AST have the * same ordering no matter the operation precedence. When we patch up * the AST we only change the structure of the tree not the ordering * of the leaves. Tree rotation adequately preserves the ordering of * the leaves (which is why it useful for balancing ordered binary * trees). * * The rotation algorithm roughly goes as follows: * * - The `!!` target is unquoted and replaced with the unquoted value. * - The RHS of the root is attached to the LHS of the pivot. * - The LHS of the pivot is attached to the root. * - The root's parent is reattached to the pivot. * * The full story is a bit more complicated when complex expressions * are involved. There are three main complications. First the target * might not be a child of the pivot. Let's take this expression: * * > 1 + 2 * 3 + 4 * * █─`+` * ├─█─`+` * │ ├─1 * │ └─█─`*` * │ ├─2 * │ └─3 * └─4 * * and assume we want to unquote `2`: * * > 1 + !!2 * 3 + 4 * * █─`+` // root * ├─1 * └─█─`!` * └─█─`!` * └─█─`+` // pivot * ├─█─`*` * │ ├─2 // target * │ └─3 * └─4 * * The `*` call is not a pivot because it has higher precedence than * the root `+`. Instead the pivot is the second `+` call. However * `!!` has higher precedence than `*` so the target to unquote is * deeper than the LHS of the pivot. In this case it is the LHS of the * LHS (it might be deeper but always across LHS's). * * Another source of complication is that we might need to rotate * entire subsets of the AST. First the pivot might comprise several * expressions. In this case we distinguish the lower pivot as the * node whose LHS is attached to the root and the upper pivot which * becomes the new root after rotation. This complication arises when * the `!!` operand is a succession of operations with decreasing * precedence (which is the case for left-associative operators with * the same precedence). * * > 1 + 2 + 3 + 4 + 5 * * █─`+` * ├─█─`+` * │ ├─█─`+` * │ │ ├─█─`+` * │ │ │ ├─1 * │ │ │ └─2 * │ │ └─3 * │ └─4 * └─5 * * > 1 + !!2 + 3 + 4 + 5 * * █─`+` // root * ├─1 * └─█─`!` * └─█─`!` * └─█─`+` // upper pivot * ├─█─`+` * │ ├─█─`+` // lower pivot * │ │ ├─2 // target * │ │ └─3 * │ └─4 * └─5 * * Finally the root might also comprise several expressions. In the * following example we see an upper root (which becomes the pivot's * or lower pivot's LHS) and a lower root (whose RHS is attached to * the pivot's or lower pivot's LHS). This complication happens when * the operations before `!!` have increasing levels of precedence: * * > 1 + 2 * 3 + 4 * * █─`+` * ├─█─`+` * │ ├─1 * │ └─█─`*` * │ ├─2 * │ └─3 * └─4 * * > 1 + 2 * !!3 + 4 * * █─`+` // upper root * ├─1 * └─█─`*` // lower root * ├─2 * └─█─`!` * └─█─`!` * └─█─`+` // pivot * ├─3 // target * └─4 * * These three complications (deep target, root, and pivot) may arise * in conjunction. * * In addition we also need to deal with multiple `!!` calls in a * series of binary operations. This is handled by recursing from the * upper pivot (the new root) after rotation. Finally the possibility * of intervening unary `+` or `-` operations also needs special * handling. * * All operators whose precedence lies between prec(`!`) and * prec(`!!`) might be involved in such a fixup of the AST. We call * these the "problematic" operators. Since the root can be multiple * expressions deep, we can't tell in advance whether the current * operation in the AST is involved in a rotation. Hence we apply * node_list_interp_fixup() instead of node_list_interp() whenever we * reach a problematic operator. */ bool op_is_unary(enum r_operator op) { if (op == R_OP_NONE || op > R_OP_MAX) { r_abort("Internal error: `enum r_operator` out of bounds"); } return r_ops_precedence[op].unary; } bool is_unary(sexp* x) { return op_is_unary(r_which_operator(x)); } bool op_is_unary_plusminus(enum r_operator op) { switch (op) { case R_OP_PLUS_UNARY: case R_OP_MINUS_UNARY: return true; default: return false; } } bool is_unary_plusminus(sexp* x) { return op_is_unary_plusminus(r_which_operator(x)); } /** * struct ast_rotation_info - Rotation data gathered while recursing over AST * * @upper_pivot_op: The operation type of the upper pivot. * @upper_pivot: The expression that becomes the new root after rotation. * @lower_pivot: The expression whose LHS is attached to @upper_root. * @upper_root: The expression that becomes the LHS of @lower_pivot. * @lower_root: The expression whose RHS is attached to the LHS of @lower_pivot. * @root_parent: Node whose CAR should be reattached to @upper_pivot * after rotation. */ struct ast_rotation_info { enum r_operator upper_pivot_op; sexp* upper_pivot; sexp* lower_pivot; sexp* upper_root; sexp* lower_root; sexp* root_parent; }; static void initialise_rotation_info(struct ast_rotation_info* info) { info->upper_pivot_op = R_OP_NONE; info->upper_pivot = NULL; info->lower_pivot = NULL; info->upper_root = NULL; info->lower_root = NULL; info->root_parent = NULL; } // Defined below static sexp* node_list_interp_fixup(sexp* x, sexp* parent, sexp* env, struct ast_rotation_info* rotation_info, bool expand_lhs); /** * maybe_rotate() - Rotate if we found a pivot * * @op: Problematic operator. * @env: The unquoting environment. * @info: See &struct ast_rotation_info. * * If @op has precedence over the upper pivot, this is the upper * root. Otherwise use &ast_rotation_info->upper_root. If the latter * is not defined, this means no rotation is needed because the effect * of `!` on the AST corresponds to the implicit grouping (e.g. with * `1 + !!2 * 3`). */ static sexp* maybe_rotate(sexp* op, sexp* env, struct ast_rotation_info* info) { if (info->upper_pivot_op == R_OP_NONE) { return op; } // Rotate if `op` is the upper root if (r_lhs_op_has_precedence(r_which_operator(op), info->upper_pivot_op)) { // Swap the lower root's RHS with the lower pivot's LHS r_node_poke_car(info->lower_root, r_node_cadr(info->lower_pivot)); r_node_poke_cadr(info->lower_pivot, op); // After rotation the upper pivot is the new root op = info->upper_pivot; } else if (info->upper_root) { r_node_poke_car(info->lower_root, r_node_cadr(info->lower_pivot)); r_node_poke_cadr(info->lower_pivot, info->upper_root); r_node_poke_car(r_node_cddr(info->root_parent), info->upper_pivot); } // else there is no rotation needed // Reinitialise the `ast_rotation_info` on the stack in order to // reuse it in the recursion initialise_rotation_info(info); // Recurse on the RHS of the upper pivot (which is now the new root) node_list_interp_fixup(op, NULL, env, info, false); return maybe_rotate(op, env, info); } /** * fixup_interp() - Expand a problematic operation * * @x: A problematic operation, i.e. a call to an operator whose * precedence is between that of `!` and that of `!!`. * @env: The unquoting environment. * * The expression to expand is an operator that might need changes in * the AST if we find a `!!` call down the line. From this point on * there is a &struct ast_rotation_info on the stack. */ sexp* fixup_interp(sexp* x, sexp* env) { // Happens with constructed calls without arguments such as `/`() if (r_node_cdr(x) == r_null) { return x; } struct ast_rotation_info rotation_info; initialise_rotation_info(&rotation_info); // Look for problematic !! calls and expand arguments on the way. // If a pivot is found rotate it around `x`. node_list_interp_fixup(x, NULL, env, &rotation_info, true); return maybe_rotate(x, env, &rotation_info); } /** * fixup_interp_first() - Expand a problematic operation starting with `!!` * * @x: A problematic operation whose LHS is a `!!` call, e.g. `!!1 + 2 + 3`. * @env: The unquoting environment. * * If `!!` is the root expression there is no rotation needed. Just * unquote the leftmost child across problematic binary operators. * However the resulting root might be involved in a rotation for a * subsequent `!!` call. */ sexp* fixup_interp_first(sexp* x, sexp* env) { sexp* parent = NULL; // `parent` will always be initialised in the loop sexp* target = x; while (is_problematic_op((parent = target, target = r_node_cadr(target))) && !is_unary(target)); // Unquote target r_node_poke_cadr(parent, r_eval(target, env)); // Expand the new root but no need to expand LHS as we just unquoted it struct ast_rotation_info rotation_info; initialise_rotation_info(&rotation_info); node_list_interp_fixup(x, NULL, env, &rotation_info, true); return maybe_rotate(x, env, &rotation_info); } /** * find_upper_pivot() - Find upper pivot * * @x: An expression. * @info: See &struct ast_rotation_info. * * Detect `!!` call structures. The operand is the upper pivot. Fill * in &ast_rotation_info->upper_pivot_op and * &ast_rotation_info->upper_pivot within @info. */ static void find_upper_pivot(sexp* x, struct ast_rotation_info* info) { if (!r_is_call(x, "!")) { return; } x = r_node_cadr(x); if (!r_is_call(x, "!")) { return; } x = r_node_cadr(x); if (r_is_call(x, "!")) { return; } enum r_operator op = r_which_operator(x); if (!op_needs_fixup(op)) { return; } info->upper_pivot_op = op; info->upper_pivot = x; } /** * find_lower_pivot() - Find lower pivot and unquote target * * @x: This is the upper pivot in the first call and the LHS of the * previous node when recursing. * @parent_node: Used to handle unary `+` and `-`, e.g. `1 + !!-2 + 3`. * @env: Unquoting environment. * @info: See &struct ast_rotation_info. * * Climb through LHS's until we find an operator that has greater * precendence than the upper pivot. This node is the lower pivot * whose LHS will be attached to the upper root. Continue climbing the * LHS's until we find the target and unquote it in place. Expand all * RHS's on the way there. * * Fill in &ast_rotation_info->lower_pivot within @info. */ static void find_lower_pivot(sexp* x, sexp* parent_node, sexp* env, struct ast_rotation_info* info) { sexp* lhs_node = r_node_cdr(x); sexp* rhs_node = r_node_cdr(lhs_node); // We found an unary `+` or `-` on the way if (rhs_node == r_null) { sexp* target = r_eval(x, env); if (parent_node) { r_node_poke_car(parent_node, target); } else { r_node_poke_car(info->lower_root, target); // If there is no parent x there is no operator precedence to // fix so abort recursion initialise_rotation_info(info); } return; } // Only expand RHS if not the upper pivot because there might be // consecutive rotations needed. The upper pivot's RHS will be // expanded after the current rotation is complete. if (x != info->upper_pivot) { r_node_poke_car(rhs_node, call_interp(r_node_car(rhs_node), env)); } sexp* lhs = r_node_car(lhs_node); enum r_operator lhs_op = r_which_operator(lhs); if (!op_needs_fixup(lhs_op)) { if (!info->lower_pivot) { info->lower_pivot = x; } sexp* target = r_eval(lhs, env); r_node_poke_cadr(x, target); // Stop recursion as we found both target and lower pivot return; } if (!r_lhs_op_has_precedence(info->upper_pivot_op, lhs_op)) { info->lower_pivot = x; } // Recurse find_lower_pivot(lhs, lhs_node, env, info); } // Defined below static void node_list_interp_fixup_rhs(sexp* rhs, sexp* rhs_node, sexp* parent, sexp* env, struct ast_rotation_info* info); /** * node_list_interp_fixup() - Expansion for binary operators that might need fixup * * @x A call to a binary operator whith problematic precedence * (between prec(`!`) and prec(`!!`)). * @env The environment where to unquote the `!!` target. * @parent Needed to handle a mix of unary and binary operators * supplied to the unquote operator, e.g. `!!-1 + 2`. This is the * outer call of which `x` is an argument, or the C `NULL` if there * is none. * @info Information about the pivot, the root and the unquoted target. * @expand_lhs Whether to expand the LHS. In some cases (e.g. after a * rotation) it is not necessary to expand the LHS as it was already * visited. */ static sexp* node_list_interp_fixup(sexp* x, sexp* parent, sexp* env, struct ast_rotation_info* info, bool expand_lhs) { sexp* lhs_node = r_node_cdr(x); sexp* lhs = r_node_car(lhs_node); // If there's a unary `+` or `-` on the way recurse on its RHS if (is_unary_plusminus(x)) { node_list_interp_fixup_rhs(lhs, lhs_node, parent, env, info); return x; } sexp* rhs_node = r_node_cddr(x); sexp* rhs = r_node_car(rhs_node); if (expand_lhs) { // Expand the LHS normally, it never needs changes in the AST r_node_poke_car(lhs_node, call_interp(r_node_car(lhs_node), env)); } node_list_interp_fixup_rhs(rhs, rhs_node, x, env, info); return x; } /** * node_list_interp_fixup_rhs() - Expansion for binary operators that might need fixup * * @rhs: The right-hand side argument of an operator with problematic * precedence. * @rhs_node: Parent node of RHS. If `rhs` is a `!!` call, we reattach * the `!!` operand to its parent node `rhs_node`. * @parent: See node_list_interp_fixup(). * @env: The unquoting environment. * @info: See &struct ast_rotation_info. */ static void node_list_interp_fixup_rhs(sexp* rhs, sexp* rhs_node, sexp* parent, sexp* env, struct ast_rotation_info* info) { // Happens with constructed calls like `/`(1) if (rhs_node == r_null) { return; } // An upper pivot is an operand of a !! call that is a binary // operation whose precedence is problematic (between prec(`!`) and // prec(`!!`)) find_upper_pivot(rhs, info); if (info->upper_pivot) { info->lower_root = rhs_node; // There might be a lower pivot, so we need to find it. Also find // the target of unquoting (leftmost leaf whose predecence is // greater than prec(`!!`)) and unquote it. find_lower_pivot(info->upper_pivot, NULL, env, info); if (info->upper_pivot) { // Reattach the RHS to the upper pivot stripped of its !! call // in case there is no rotation around the lower root r_node_poke_car(rhs_node, info->upper_pivot); } return; } // If `rhs` is an operator that might be involved in a rotation // recurse with the fixup version if (is_problematic_op(rhs)) { node_list_interp_fixup(rhs, parent, env, info, true); // This might the upper root around which to rotate if (info->upper_pivot_op && r_lhs_op_has_precedence(r_which_operator(rhs), info->upper_pivot_op)) { info->upper_root = rhs; info->root_parent = parent; } return; } // RHS is not a binary operation that might need changes in the AST // so expand it as usual r_node_poke_car(rhs_node, call_interp(rhs, env)); } rlang/src/internal/arg.c0000644000176200001440000000352213457603056014710 0ustar liggesusers#include #include "expr-interp.h" // Capture sexp* rlang_ns_get(const char* name); sexp* capture(sexp* sym, sexp* frame, SEXP* arg_env) { static sexp* capture_call = NULL; if (!capture_call) { sexp* args = KEEP(r_new_node(r_null, r_null)); capture_call = r_new_call(rlang_ns_get("captureArgInfo"), args); r_mark_precious(capture_call); r_mark_shared(capture_call); FREE(1); } if (r_typeof(sym) != SYMSXP) { r_abort("`arg` must be a symbol"); } r_node_poke_cadr(capture_call, sym); sexp* arg_info = KEEP(r_eval(capture_call, frame)); sexp* expr = r_list_get(arg_info, 0); sexp* env = r_list_get(arg_info, 1); // Unquoting rearranges the expression expr = KEEP(r_duplicate(expr, false)); expr = call_interp(expr, env); if (arg_env) { *arg_env = env; } FREE(2); return expr; } sexp* rlang_enexpr(sexp* sym, sexp* frame) { return capture(sym, frame, NULL); } sexp* rlang_ensym(sexp* sym, sexp* frame) { sexp* expr = capture(sym, frame, NULL); if (rlang_is_quosure(expr)) { expr = rlang_quo_get_expr(expr); } switch (r_typeof(expr)) { case r_type_symbol: break; case r_type_character: if (r_length(expr) == 1) { KEEP(expr); expr = r_sym(r_chr_get_c_string(expr, 0)); FREE(1); break; } // else fallthrough default: r_abort("Only strings can be converted to symbols"); } return expr; } sexp* rlang_enquo(sexp* sym, sexp* frame) { sexp* env; sexp* expr = KEEP(capture(sym, frame, &env)); sexp* quo = forward_quosure(expr, env); FREE(1); return quo; } sexp* rlang_is_missing(sexp* _call, sexp* _op, sexp* args, sexp* env) { args = r_node_cdr(args); sexp* missing = r_eval(r_node_car(args), env); if (r_lgl_get(missing, 0)) { return r_shared_true; } return r_lgl(r_eval(r_x_sym, env) == r_missing_sym); } rlang/src/internal/expr-interp-rotate.h0000644000176200001440000000132213351410655017703 0ustar liggesusers#ifndef RLANG_INTERNAL_EXPR_INTERP_FIXUP_H #define RLANG_INTERNAL_EXPR_INTERP_FIXUP_H static inline bool op_needs_fixup(enum r_operator op) { switch (op) { case R_OP_GREATER: case R_OP_GREATER_EQUAL: case R_OP_LESS: case R_OP_LESS_EQUAL: case R_OP_EQUAL: case R_OP_NOT_EQUAL: case R_OP_PLUS: case R_OP_MINUS: case R_OP_TIMES: case R_OP_RATIO: case R_OP_MODULO: case R_OP_SPECIAL: case R_OP_COLON1: case R_OP_PLUS_UNARY: case R_OP_MINUS_UNARY: return true; default: return false; } } static inline bool is_problematic_op(sexp* x) { return op_needs_fixup(r_which_operator(x)); } sexp* fixup_interp(sexp* x, sexp* env); sexp* fixup_interp_first(sexp* x, sexp* env); #endif rlang/src/internal/call.c0000644000176200001440000000247713500140547015050 0ustar liggesusers#include #include "internal.h" static bool is_callable(sexp* x) { switch (r_typeof(x)) { case r_type_symbol: case r_type_call: case r_type_closure: case r_type_builtin: case r_type_special: return true; default: return false; } } sexp* rlang_call2(sexp* fn, sexp* args, sexp* ns) { if (r_typeof(fn) == r_type_character) { if (r_length(fn) != 1) { r_abort("`.fn` must be a string, a symbol, a call, or a function"); } fn = r_sym(r_chr_get_c_string(fn, 0)); } else if (!is_callable(fn)) { r_abort("Can't create call to non-callable object"); } int n_protect = 0; if (ns != r_null) { if (!r_is_string(ns, NULL)) { r_abort("`ns` must be a string"); } if (r_typeof(fn) != r_type_symbol) { r_abort("`fn` must be a string or symbol when a namespace is supplied"); } ns = r_sym(r_chr_get_c_string(ns, 0)); fn = KEEP_N(r_call3(r_namespace_sym, ns, fn), n_protect); } sexp* out = r_new_call(fn, args); FREE(n_protect); return out; } sexp* rlang_call2_external(sexp* call, sexp* op, sexp* args, sexp* env) { args = r_node_cdr(args); sexp* fn = KEEP(r_eval(r_sym(".fn"), env)); sexp* ns = KEEP(r_eval(r_sym(".ns"), env)); sexp* dots = KEEP(rlang_dots(env)); sexp* out = rlang_call2(fn, dots, ns); FREE(3); return out; } rlang/src/internal/internal.h0000644000176200001440000000221113610376546015754 0ustar liggesusers#ifndef RLANG_INTERNAL_INTERNAL_H #define RLANG_INTERNAL_INTERNAL_H #include "quo.h" extern sexp* rlang_zap; extern sexp* as_list_call; extern sexp* as_list_s4_call; extern sexp* rlang_objs_keep; extern sexp* rlang_objs_trailing; extern sexp* fns_function; extern sexp* fns_quote; void rlang_init_internal(sexp* ns); sexp* rlang_ns_get(const char* name); // From dots.c sexp* dots_values_node_impl(sexp* frame_env, sexp* named, sexp* ignore_empty, sexp* preserve_empty, sexp* unquote_names, sexp* homonyms, sexp* check_assign, bool splice); static inline sexp* rlang_dots(sexp* env) { return dots_values_node_impl(env, r_shared_false, rlang_objs_trailing, r_shared_true, r_shared_true, rlang_objs_keep, r_shared_false, true); } #endif rlang/src/internal/expr-interp.h0000644000176200001440000000361013523027707016414 0ustar liggesusers#ifndef RLANG_INTERNAL_EXPR_INTERP_H #define RLANG_INTERNAL_EXPR_INTERP_H #include "quo.h" #define UQ_N 2 #define UQS_N 2 static const char* uqs_names[UQS_N] = { "UQS", "!!!"}; static inline bool is_maybe_rlang_call(sexp* x, const char* name) { return r_is_call(x, name) || r_is_namespaced_call(x, "rlang", name); } static inline bool is_maybe_rlang_call_any(sexp* x, const char** names, int n) { return r_is_call_any(x, names, n) || r_is_namespaced_call_any(x, "rlang", names, n); } static inline bool is_splice_call(sexp* node) { return is_maybe_rlang_call_any(node, uqs_names, UQS_N); } #define EXPANSION_OP_MAX 7 enum expansion_op { OP_EXPAND_NONE, OP_EXPAND_UQ, OP_EXPAND_UQS, OP_EXPAND_UQN, OP_EXPAND_FIXUP, OP_EXPAND_DOT_DATA, OP_EXPAND_CURLY }; struct expansion_info { enum expansion_op op; sexp* operand; // Expression being unquoted sexp* parent; // Node pointing to the future unquoted value sexp* root; // Expression wrapping the unquoted value (optional) }; static inline struct expansion_info init_expansion_info() { struct expansion_info info; info.op = OP_EXPAND_NONE; info.operand = r_null; info.parent = r_null; info.root = r_null; return info; } struct expansion_info which_uq_op(sexp* x); struct expansion_info which_expansion_op(sexp* x, bool unquote_names); struct expansion_info is_big_bang_op(sexp* x); sexp* big_bang_coerce(sexp* expr); sexp* rlang_interp(sexp* x, sexp* env); sexp* call_interp(sexp* x, sexp* env); sexp* call_interp_impl(sexp* x, sexp* env, struct expansion_info info); static inline sexp* forward_quosure(sexp* x, sexp* env) { switch (r_typeof(x)) { case r_type_call: if (rlang_is_quosure(x)) { return x; } // else fallthrough case r_type_symbol: case r_type_closure: return rlang_new_quosure(x, env); default: return rlang_new_quosure(x, r_empty_env); } } #endif rlang/src/export/0000755000176200001440000000000013614116052013464 5ustar liggesusersrlang/src/export/init.c0000644000176200001440000004635113610376546014620 0ustar liggesusers#include #include #include // Callable from other packages extern sexp* r_squash_if(sexp*, enum r_type, bool (*is_spliceable)(sexp*), int); extern bool rlang_is_clevel_spliceable(sexp*); extern bool rlang_is_quosure(sexp*); // Callable from this package extern sexp* rlang_is_null(sexp*); extern sexp* r_f_lhs(sexp*); extern sexp* r_f_rhs(sexp*); extern sexp* r_new_condition(sexp*, sexp*, sexp*); extern sexp* r_env_clone(sexp*, sexp*); extern sexp* rlang_env_unbind(sexp*, sexp*, sexp*); extern sexp* rlang_env_poke_parent(sexp*, sexp*); extern sexp* rlang_env_frame(sexp* env); extern sexp* rlang_env_hash_table(sexp* env); extern sexp* rlang_poke_type(sexp*, sexp*); extern sexp* rlang_replace_na(sexp*, sexp*); extern sexp* rlang_node_car(sexp*); extern sexp* rlang_node_cdr(sexp*); extern sexp* rlang_node_caar(sexp*); extern sexp* rlang_node_cadr(sexp*); extern sexp* rlang_node_cdar(sexp*); extern sexp* rlang_node_cddr(sexp*); extern sexp* rlang_missing_arg(); extern sexp* rlang_node_poke_car(sexp*, sexp*); extern sexp* rlang_node_poke_cdr(sexp*, sexp*); extern sexp* rlang_node_poke_caar(sexp*, sexp*); extern sexp* rlang_node_poke_cadr(sexp*, sexp*); extern sexp* rlang_node_poke_cdar(sexp*, sexp*); extern sexp* rlang_node_poke_cddr(sexp*, sexp*); extern sexp* rlang_duplicate(sexp*, sexp*); extern sexp* r_node_tree_clone(sexp*); extern sexp* rlang_node_tag(sexp*); extern sexp* rlang_node_poke_tag(sexp*, sexp*); extern sexp* rlang_eval(sexp*, sexp*); extern sexp* rlang_interp(sexp*, sexp*); extern sexp* rlang_is_formulaish(sexp*, sexp*, sexp*); extern sexp* rlang_is_reference(sexp*, sexp*); extern sexp* rlang_sexp_address(sexp*); extern sexp* rlang_length(sexp*); extern sexp* rlang_true_length(sexp* x); extern sexp* rlang_squash(sexp*, sexp*, sexp*, sexp*); extern sexp* rlang_symbol(sexp*); extern sexp* rlang_symbol_to_character(sexp*); extern sexp* rlang_tilde_eval(sexp*, sexp*, sexp*); extern sexp* rlang_unescape_character(sexp*); extern sexp* rlang_capturearginfo(sexp*, sexp*, sexp*, sexp*); extern sexp* rlang_capturedots(sexp*, sexp*, sexp*, sexp*); extern sexp* rlang_new_call_node(sexp*, sexp*); extern sexp* rlang_cnd_signal(sexp*); extern sexp* rlang_r_string(sexp*); extern sexp* rlang_exprs_interp(sexp*, sexp*, sexp*, sexp*, sexp*, sexp*); extern sexp* rlang_quos_interp(sexp*, sexp*, sexp*, sexp*, sexp*, sexp*); extern sexp* rlang_dots_list(sexp*, sexp*, sexp*, sexp*, sexp*, sexp*, sexp*); extern sexp* rlang_dots_flat_list(sexp*, sexp*, sexp*, sexp*, sexp*, sexp*, sexp*); extern sexp* rlang_dots_pairlist(sexp*, sexp*, sexp*, sexp*, sexp*, sexp*, sexp*); extern sexp* r_new_formula(sexp*, sexp*, sexp*); extern sexp* rlang_new_quosure(sexp*, sexp*); extern sexp* rlang_enexpr(sexp*, sexp*); extern sexp* rlang_ensym(sexp*, sexp*); extern sexp* rlang_enquo(sexp*, sexp*); extern sexp* rlang_get_expression(sexp*, sexp*); extern sexp* rlang_vec_alloc(sexp*, sexp*); extern sexp* rlang_vec_coerce(sexp*, sexp*); extern sexp* rlang_mark_object(sexp*); extern sexp* rlang_promise_expr(sexp*, sexp*); extern sexp* rlang_promise_env(sexp*, sexp*); extern sexp* rlang_promise_value(sexp*, sexp*); extern sexp* rlang_unmark_object(sexp*); extern sexp* rlang_quo_is_missing(sexp*); extern sexp* rlang_quo_is_symbol(sexp*); extern sexp* rlang_quo_is_call(sexp*); extern sexp* rlang_quo_is_symbolic(sexp*); extern sexp* rlang_quo_is_null(sexp*); extern sexp* rlang_vec_poke_n(sexp*, sexp*, sexp*, sexp*, sexp*); extern sexp* rlang_vec_poke_range(sexp*, sexp*, sexp*, sexp*, sexp*); extern sexp* rlang_quo_get_expr(sexp*); extern sexp* rlang_quo_set_expr(sexp*, sexp*); extern sexp* rlang_quo_get_env(sexp*); extern sexp* rlang_quo_set_env(sexp*, sexp*); extern sexp* rlang_which_operator(sexp*); extern sexp* rlang_new_data_mask(sexp*, sexp*); extern sexp* rlang_new_data_mask_compat(sexp*, sexp*, sexp*); extern sexp* rlang_as_data_mask(sexp*); extern sexp* rlang_as_data_mask_compat(sexp*, sexp*); extern sexp* rlang_data_mask_clean(sexp*); extern sexp* rlang_eval_tidy(sexp*, sexp*, sexp*); extern sexp* rlang_as_data_pronoun(sexp*); extern sexp* rlang_env_get(sexp*, sexp*); extern sexp* rlang_env_unlock(sexp*); extern sexp* rlang_interrupt(); extern sexp* rlang_is_list(sexp*, sexp*); extern sexp* rlang_is_atomic(sexp*, sexp*); extern sexp* rlang_is_vector(sexp*, sexp*); extern sexp* rlang_is_finite(sexp*); extern sexp* rlang_is_logical(sexp*, sexp*); extern sexp* rlang_is_integer(sexp*, sexp*); extern sexp* rlang_is_double(sexp*, sexp*, sexp*); extern sexp* rlang_is_integerish(sexp*, sexp*, sexp*); extern sexp* rlang_is_character(sexp*, sexp*); extern sexp* rlang_is_raw(sexp*, sexp*); extern sexp* rlang_is_data_mask(sexp*); extern sexp* rlang_data_pronoun_get(sexp*, sexp*); extern sexp* rlang_cnd_type(sexp*); extern sexp* rlang_env_inherits(sexp*, sexp*); extern sexp* rlang_eval_top(sexp*, sexp*); extern sexp* rlang_attrib(sexp*); extern sexp* rlang_named(sexp*, sexp*); extern sexp* r_node_list_reverse(sexp*); extern sexp* rlang_new_splice_box(sexp*); extern sexp* rlang_is_splice_box(sexp*); extern sexp* rlang_unbox(sexp*); extern sexp* rlang_new_function(sexp*, sexp*, sexp*); extern sexp* rlang_is_string(sexp*, sexp*); extern sexp* rlang_new_weakref(sexp*, sexp*, sexp*, sexp*); extern sexp* rlang_wref_key(sexp*); extern sexp* rlang_wref_value(sexp*); extern sexp* rlang_is_weakref(sexp*); extern sexp* rlang_find_var(sexp*, sexp*); extern sexp* rlang_env_bind_list(sexp*, sexp*, sexp*); extern sexp* rlang_glue_is_there(); // Library initialisation defined below sexp* rlang_library_load(sexp*); sexp* rlang_library_unload(); // For unit tests extern sexp* chr_prepend(sexp*, sexp*); extern sexp* chr_append(sexp*, sexp*); extern sexp* rlang_test_r_warn(sexp*); extern sexp* rlang_on_exit(sexp*, sexp*); extern sexp* rlang_test_is_special_op_sym(sexp*); extern sexp* rlang_test_base_ns_get(sexp*); extern sexp* rlang_test_parse(sexp*); extern sexp* rlang_test_parse_eval(sexp*, sexp*); extern sexp* r_current_frame(); extern sexp* rlang_test_node_list_clone_until(sexp*, sexp*); extern sexp* rlang_test_sys_frame(sexp*); extern sexp* rlang_test_sys_call(sexp*); extern sexp* rlang_test_nms_are_duplicated(sexp*, sexp*); extern sexp* rlang_test_Rf_warningcall(sexp*, sexp*); extern sexp* rlang_test_Rf_errorcall(sexp*, sexp*); extern sexp* rlang_test_lgl_sum(sexp*, sexp*); extern sexp* rlang_test_lgl_which(sexp*, sexp*); static const r_callable r_callables[] = { {"r_init_library", (r_fn_ptr) &r_init_library, 0}, {"rlang_library_load", (r_fn_ptr) &rlang_library_load, 1}, {"rlang_library_unload", (r_fn_ptr) &rlang_library_unload, 0}, {"r_f_lhs", (r_fn_ptr) &r_f_lhs, 1}, {"r_f_rhs", (r_fn_ptr) &r_f_rhs, 1}, {"rlang_new_condition", (r_fn_ptr) &r_new_condition, 3}, {"rlang_replace_na", (r_fn_ptr) &rlang_replace_na, 2}, {"rlang_capturearginfo", (r_fn_ptr) &rlang_capturearginfo, 4}, {"rlang_capturedots", (r_fn_ptr) &rlang_capturedots, 4}, {"rlang_duplicate", (r_fn_ptr) &rlang_duplicate, 2}, {"rlang_node_tree_clone", (r_fn_ptr) &r_node_tree_clone, 1}, {"rlang_eval", (r_fn_ptr) &rlang_eval, 2}, {"rlang_interp", (r_fn_ptr) &rlang_interp, 2}, {"rlang_is_formulaish", (r_fn_ptr) &rlang_is_formulaish, 3}, {"rlang_is_null", (r_fn_ptr) &rlang_is_null, 1}, {"rlang_is_reference", (r_fn_ptr) &rlang_is_reference, 2}, {"rlang_length", (r_fn_ptr) &rlang_length, 1}, {"rlang_true_length", (r_fn_ptr) &rlang_true_length, 1}, {"rlang_get_attributes", (r_fn_ptr) &r_get_attributes, 1}, {"rlang_poke_attributes", (r_fn_ptr) &r_poke_attributes, 2}, {"rlang_missing_arg", (r_fn_ptr) &rlang_missing_arg, 0}, {"rlang_node_car", (r_fn_ptr) &rlang_node_car, 1}, {"rlang_node_cdr", (r_fn_ptr) &rlang_node_cdr, 1}, {"rlang_node_caar", (r_fn_ptr) &rlang_node_caar, 1}, {"rlang_node_cadr", (r_fn_ptr) &rlang_node_cadr, 1}, {"rlang_node_cdar", (r_fn_ptr) &rlang_node_cdar, 1}, {"rlang_node_cddr", (r_fn_ptr) &rlang_node_cddr, 1}, {"rlang_node_poke_car", (r_fn_ptr) &rlang_node_poke_car, 2}, {"rlang_node_poke_cdr", (r_fn_ptr) &rlang_node_poke_cdr, 2}, {"rlang_node_poke_caar", (r_fn_ptr) &rlang_node_poke_caar, 2}, {"rlang_node_poke_cadr", (r_fn_ptr) &rlang_node_poke_cadr, 2}, {"rlang_node_poke_cdar", (r_fn_ptr) &rlang_node_poke_cdar, 2}, {"rlang_node_poke_cddr", (r_fn_ptr) &rlang_node_poke_cddr, 2}, {"rlang_new_node", (r_fn_ptr) &r_new_node, 2}, {"rlang_nms_are_duplicated", (r_fn_ptr) &rlang_test_nms_are_duplicated, 2}, {"rlang_env_clone", (r_fn_ptr) &r_env_clone, 2}, {"rlang_env_unbind", (r_fn_ptr) &rlang_env_unbind, 3}, {"rlang_env_poke_parent", (r_fn_ptr) &rlang_env_poke_parent, 2}, {"rlang_env_frame", (r_fn_ptr) &rlang_env_frame, 1}, {"rlang_env_hash_table", (r_fn_ptr) &rlang_env_hash_table, 1}, {"rlang_poke_type", (r_fn_ptr) &rlang_poke_type, 2}, {"rlang_mark_object", (r_fn_ptr) &rlang_mark_object, 1}, {"rlang_promise_expr", (r_fn_ptr) &rlang_promise_expr, 2}, {"rlang_promise_env", (r_fn_ptr) &rlang_promise_env, 2}, {"rlang_promise_value", (r_fn_ptr) &rlang_promise_value, 2}, {"rlang_unmark_object", (r_fn_ptr) &rlang_unmark_object, 1}, {"rlang_node_tag", (r_fn_ptr) &rlang_node_tag, 1}, {"rlang_node_poke_tag", (r_fn_ptr) &rlang_node_poke_tag, 2}, {"rlang_squash", (r_fn_ptr) &rlang_squash, 4}, {"rlang_sexp_address", (r_fn_ptr) &rlang_sexp_address, 1}, {"rlang_symbol", (r_fn_ptr) &rlang_symbol, 1}, {"rlang_symbol_to_character", (r_fn_ptr) &rlang_symbol_to_character, 1}, {"rlang_tilde_eval", (r_fn_ptr) &rlang_tilde_eval, 3}, {"rlang_unescape_character", (r_fn_ptr) &rlang_unescape_character, 1}, {"rlang_new_call", (r_fn_ptr) &rlang_new_call_node, 2}, {"rlang_cnd_signal", (r_fn_ptr) &rlang_cnd_signal, 1}, {"rlang_test_chr_prepend", (r_fn_ptr) &chr_prepend, 2}, {"rlang_test_chr_append", (r_fn_ptr) &chr_append, 2}, {"rlang_test_r_warn", (r_fn_ptr) &rlang_test_r_warn, 1}, {"rlang_test_r_on_exit", (r_fn_ptr) &rlang_on_exit, 2}, {"rlang_test_is_special_op_sym", (r_fn_ptr) &rlang_test_is_special_op_sym, 1}, {"rlang_test_base_ns_get", (r_fn_ptr) &rlang_test_base_ns_get, 1}, {"rlang_test_current_frame", (r_fn_ptr) &r_current_frame, 0}, {"rlang_test_parse", (r_fn_ptr) &rlang_test_parse, 1}, {"rlang_test_parse_eval", (r_fn_ptr) &rlang_test_parse_eval, 2}, {"rlang_test_node_list_clone_until", (r_fn_ptr) &rlang_test_node_list_clone_until, 2}, {"rlang_test_set_attribute", (r_fn_ptr) &r_set_attribute, 3}, {"rlang_test_sys_frame", (r_fn_ptr) &rlang_test_sys_frame, 1}, {"rlang_test_sys_call", (r_fn_ptr) &rlang_test_sys_call, 1}, {"rlang_test_Rf_warningcall", (r_fn_ptr) &rlang_test_Rf_warningcall, 2}, {"rlang_test_Rf_errorcall", (r_fn_ptr) &rlang_test_Rf_errorcall, 2}, {"rlang_test_lgl_sum", (r_fn_ptr) &rlang_test_lgl_sum, 2}, {"rlang_test_lgl_which", (r_fn_ptr) &rlang_test_lgl_which, 2}, {"rlang_r_string", (r_fn_ptr) &rlang_r_string, 1}, {"rlang_exprs_interp", (r_fn_ptr) &rlang_exprs_interp, 6}, {"rlang_quos_interp", (r_fn_ptr) &rlang_quos_interp, 6}, {"rlang_dots_list", (r_fn_ptr) &rlang_dots_list, 7}, {"rlang_dots_flat_list", (r_fn_ptr) &rlang_dots_flat_list, 7}, {"rlang_dots_pairlist", (r_fn_ptr) &rlang_dots_pairlist, 7}, {"rlang_new_formula", (r_fn_ptr) &r_new_formula, 3}, {"rlang_new_quosure", (r_fn_ptr) &rlang_new_quosure, 2}, {"rlang_enexpr", (r_fn_ptr) &rlang_enexpr, 2}, {"rlang_ensym", (r_fn_ptr) &rlang_ensym, 2}, {"rlang_enquo", (r_fn_ptr) &rlang_enquo, 2}, {"rlang_get_expression", (r_fn_ptr) &rlang_get_expression, 2}, {"rlang_vec_alloc", (r_fn_ptr) &rlang_vec_alloc, 2}, {"rlang_vec_coerce", (r_fn_ptr) &rlang_vec_coerce, 2}, {"rlang_quo_is_symbol", (r_fn_ptr) &rlang_quo_is_symbol, 1}, {"rlang_quo_is_call", (r_fn_ptr) &rlang_quo_is_call, 1}, {"rlang_quo_is_symbolic", (r_fn_ptr) &rlang_quo_is_symbolic, 1}, {"rlang_quo_is_missing", (r_fn_ptr) &rlang_quo_is_missing, 1}, {"rlang_quo_is_null", (r_fn_ptr) &rlang_quo_is_null, 1}, {"rlang_quo_get_expr", (r_fn_ptr) &rlang_quo_get_expr, 1}, {"rlang_quo_set_expr", (r_fn_ptr) &rlang_quo_set_expr, 2}, {"rlang_quo_get_env", (r_fn_ptr) &rlang_quo_get_env, 1}, {"rlang_quo_set_env", (r_fn_ptr) &rlang_quo_set_env, 2}, {"rlang_vec_poke_n", (r_fn_ptr) &rlang_vec_poke_n, 5}, {"rlang_vec_poke_range", (r_fn_ptr) &rlang_vec_poke_range, 5}, {"rlang_which_operator", (r_fn_ptr) &rlang_which_operator, 1}, {"rlang_call_has_precedence", (r_fn_ptr) &rlang_call_has_precedence, 3}, {"rlang_new_data_mask", (r_fn_ptr) &rlang_new_data_mask, 2}, {"rlang_as_data_mask", (r_fn_ptr) &rlang_as_data_mask, 1}, {"rlang_is_data_mask", (r_fn_ptr) &rlang_is_data_mask, 1}, {"rlang_data_pronoun_get", (r_fn_ptr) &rlang_data_pronoun_get, 2}, {"rlang_data_mask_clean", (r_fn_ptr) &rlang_data_mask_clean, 1}, {"rlang_eval_tidy", (r_fn_ptr) &rlang_eval_tidy, 3}, {"rlang_as_data_pronoun", (r_fn_ptr) &rlang_as_data_pronoun, 1}, {"rlang_env_binding_types", (r_fn_ptr) &r_env_binding_types, 2}, {"rlang_env_get", (r_fn_ptr) &rlang_env_get, 2}, {"rlang_env_unlock", (r_fn_ptr) &rlang_env_unlock, 1}, {"rlang_interrupt", (r_fn_ptr) &rlang_interrupt, 0}, {"rlang_is_list", (r_fn_ptr) &rlang_is_list, 2}, {"rlang_is_atomic", (r_fn_ptr) &rlang_is_atomic, 2}, {"rlang_is_vector", (r_fn_ptr) &rlang_is_vector, 2}, {"rlang_is_finite", (r_fn_ptr) &rlang_is_finite, 1}, {"rlang_is_logical", (r_fn_ptr) &rlang_is_logical, 2}, {"rlang_is_integer", (r_fn_ptr) &rlang_is_integer, 2}, {"rlang_is_double", (r_fn_ptr) &rlang_is_double, 3}, {"rlang_is_integerish", (r_fn_ptr) &rlang_is_integerish, 3}, {"rlang_is_character", (r_fn_ptr) &rlang_is_character, 2}, {"rlang_is_raw", (r_fn_ptr) &rlang_is_raw, 2}, {"rlang_cnd_type", (r_fn_ptr) &rlang_cnd_type, 1}, {"rlang_env_inherits", (r_fn_ptr) &rlang_env_inherits, 2}, {"rlang_eval_top", (r_fn_ptr) &rlang_eval_top, 2}, {"rlang_attrib", (r_fn_ptr) &rlang_attrib, 1}, {"rlang_named", (r_fn_ptr) &rlang_named, 2}, {"rlang_node_list_reverse", (r_fn_ptr) &r_node_list_reverse, 1}, {"rlang_new_splice_box", (r_fn_ptr) &rlang_new_splice_box, 1}, {"rlang_is_splice_box", (r_fn_ptr) &rlang_is_splice_box, 1}, {"rlang_new_function", (r_fn_ptr) &rlang_new_function, 3}, {"rlang_is_string", (r_fn_ptr) &rlang_is_string, 2}, {"rlang_new_weakref", (r_fn_ptr) &rlang_new_weakref, 4}, {"rlang_wref_key", (r_fn_ptr) &rlang_wref_key, 1}, {"rlang_wref_value", (r_fn_ptr) &rlang_wref_value, 1}, {"rlang_is_weakref", (r_fn_ptr) &rlang_is_weakref, 1}, {"rlang_find_var", (r_fn_ptr) &rlang_find_var, 2}, {"rlang_env_bind_list", (r_fn_ptr) &rlang_env_bind_list, 3}, {"rlang_glue_is_there", (r_fn_ptr) &rlang_glue_is_there, 0}, {NULL, NULL, 0} }; extern sexp* rlang_is_missing(sexp*, sexp*, sexp*, sexp*); extern sexp* rlang_call2_external(sexp*, sexp*, sexp*, sexp*); extern sexp* rlang_ext2_dots_values(sexp*, sexp*, sexp*, sexp*); extern sexp* rlang_exec(sexp*, sexp*, sexp*, sexp*); static const r_external externals[] = { {"rlang_is_missing", (r_fn_ptr) &rlang_is_missing, 1}, {"rlang_call2_external", (r_fn_ptr) &rlang_call2_external, 2}, {"rlang_ext2_dots_values", (r_fn_ptr) &rlang_ext2_dots_values, 6}, {"rlang_exec", (r_fn_ptr) &rlang_exec, 2}, {NULL, NULL, 0} }; extern bool is_splice_box(sexp*); extern sexp* rlang_env_dots_values(sexp*); extern sexp* rlang_env_dots_list(sexp*); void R_init_rlang(r_dll_info* dll) { r_register_c_callable("rlang", "rlang_squash_if", (r_fn_ptr) &r_squash_if); // The quosure functions are stable r_register_c_callable("rlang", "rlang_new_quosure", (r_fn_ptr) &rlang_new_quosure); r_register_c_callable("rlang", "rlang_is_quosure", (r_fn_ptr) &rlang_is_quosure); r_register_c_callable("rlang", "rlang_quo_get_expr", (r_fn_ptr) &rlang_quo_get_expr); r_register_c_callable("rlang", "rlang_quo_set_expr", (r_fn_ptr) &rlang_quo_set_expr); r_register_c_callable("rlang", "rlang_quo_get_env", (r_fn_ptr) &rlang_quo_get_env); r_register_c_callable("rlang", "rlang_quo_set_env", (r_fn_ptr) &rlang_quo_set_env); // The data mask functions are stable r_register_c_callable("rlang", "rlang_as_data_pronoun", (r_fn_ptr) &rlang_as_data_pronoun); r_register_c_callable("rlang", "rlang_as_data_mask_3.0.0", (r_fn_ptr) &rlang_as_data_mask); r_register_c_callable("rlang", "rlang_new_data_mask_3.0.0", (r_fn_ptr) &rlang_new_data_mask); // eval_tidy() is stable r_register_c_callable("rlang", "rlang_eval_tidy", (r_fn_ptr) &rlang_eval_tidy); // Maturing r_register_c_callable("rlang", "rlang_is_splice_box", (r_fn_ptr) &is_splice_box); r_register_c_callable("rlang", "rlang_unbox", (r_fn_ptr) &rlang_unbox); r_register_c_callable("rlang", "rlang_env_dots_values", (r_fn_ptr) &rlang_env_dots_values); r_register_c_callable("rlang", "rlang_env_dots_list", (r_fn_ptr) &rlang_env_dots_list); // Experimental method for exporting C function pointers as actual R objects rlang_register_pointer("rlang", "rlang_test_is_spliceable", (r_fn_ptr) &rlang_is_clevel_spliceable); // Compatibility r_register_c_callable("rlang", "rlang_as_data_mask", (r_fn_ptr) &rlang_as_data_mask_compat); r_register_c_callable("rlang", "rlang_new_data_mask", (r_fn_ptr) &rlang_new_data_mask_compat); r_register_r_callables(dll, r_callables, externals); } // From "../internal/internal.h" void rlang_init_internal(sexp* ns); sexp* rlang_library_load(sexp* ns) { rlang_init_internal(ns); return r_null; } sexp* rlang_library_unload() { return r_null; } rlang/src/export/exported.c0000644000176200001440000002614413535661371015504 0ustar liggesusers#include // attrs.c sexp* rlang_poke_attributes(sexp* x, sexp* attrs) { SET_ATTRIB(x, attrs); return x; } // cnd.c sexp* rlang_cnd_signal(sexp* cnd) { r_cnd_signal(cnd); return r_null; } sexp* rlang_cnd_type(sexp* cnd) { enum r_condition_type type = r_cnd_type(cnd); switch (type) { case r_cnd_type_condition: return r_chr("condition"); case r_cnd_type_message: return r_chr("message"); case r_cnd_type_warning: return r_chr("warning"); case r_cnd_type_error: return r_chr("error"); case r_cnd_type_interrupt: return r_chr("interrupt"); default: r_abort("Internal error: Unhandled `r_condition_type`"); } } sexp* rlang_interrupt() { r_interrupt(); return r_null; } // env.c sexp* rlang_env_poke_parent(sexp* env, sexp* new_parent) { if (R_IsNamespaceEnv(env)) { r_abort("Can't change the parent of a namespace environment"); } if (R_IsPackageEnv(env)) { r_abort("Can't change the parent of a package environment"); } if (R_EnvironmentIsLocked(env)) { r_abort("Can't change the parent of a locked environment"); } if (env == r_global_env) { r_abort("Can't change the parent of the global environment"); } if (env == r_base_env) { r_abort("Can't change the parent of the base environment"); } if (env == r_empty_env) { r_abort("Can't change the parent of the empty environment"); } SET_ENCLOS(env, new_parent); return env; } sexp* rlang_env_frame(sexp* env) { return FRAME(env); } sexp* rlang_env_hash_table(sexp* env) { return HASHTAB(env); } sexp* rlang_env_inherits(sexp* env, sexp* ancestor) { return r_lgl(r_env_inherits(env, ancestor, r_empty_env)); } sexp* rlang_env_bind_list(sexp* env, sexp* names, sexp* data) { if (r_typeof(env) != r_type_environment) { r_abort("Internal error: `env` must be an environment."); } if (r_typeof(names) != r_type_character) { r_abort("Internal error: `names` must be a character vector."); } if (r_typeof(data) != r_type_list) { r_abort("Internal error: `data` must be a list."); } r_ssize n = r_length(data); if (n != r_length(names)) { r_abort("Internal error: `data` and `names` must have the same length."); } sexp** namesp = r_chr_deref(names); for (r_ssize i = 0; i < n; ++i) { Rf_defineVar(Rf_installChar(namesp[i]), r_list_get(data, i), env); } return r_null; } // eval.c sexp* rlang_eval(sexp* expr, sexp* env) { return Rf_eval(expr, env); } sexp* rlang_eval_top(sexp* expr, sexp* env) { int jumped = 0; sexp* out = R_tryEval(expr, env, &jumped); if (jumped) { r_abort("Top level jump"); } else { return out; } } // formula.c sexp* rlang_is_formulaish(sexp* x, sexp* scoped, sexp* lhs) { int scoped_int = r_as_optional_bool(scoped); int lhs_int = r_as_optional_bool(lhs); bool out = r_is_formulaish(x, scoped_int, lhs_int); return r_lgl(out); } // parse.c sexp* rlang_call_has_precedence(sexp* x, sexp* y, sexp* side) { bool has_predence; if (side == r_null) { has_predence = r_call_has_precedence(x, y); } else if (r_is_string(side, "lhs")) { has_predence = r_lhs_call_has_precedence(x, y); } else if (r_is_string(side, "rhs")) { has_predence = r_rhs_call_has_precedence(x, y); } else { r_abort("`side` must be NULL, \"lhs\" or \"rhs\""); } return r_lgl(has_predence); } sexp* rlang_which_operator(sexp* call) { const char* op = r_op_as_c_string(r_which_operator(call)); return r_chr(op); } // node.c sexp* rlang_node_car(sexp* x) { return CAR(x); } sexp* rlang_node_cdr(sexp* x) { return CDR(x); } sexp* rlang_node_caar(sexp* x) { return CAAR(x); } sexp* rlang_node_cadr(sexp* x) { return CADR(x); } sexp* rlang_node_cdar(sexp* x) { return CDAR(x); } sexp* rlang_node_cddr(sexp* x) { return CDDR(x); } sexp* rlang_node_tail(sexp* x) { while (CDR(x) != r_null) x = CDR(x); return x; } sexp* rlang_node_poke_car(sexp* x, sexp* newcar) { SETCAR(x, newcar); return x; } sexp* rlang_node_poke_cdr(sexp* x, sexp* newcdr) { SETCDR(x, newcdr); return x; } sexp* rlang_node_poke_caar(sexp* x, sexp* newcaar) { SETCAR(CAR(x), newcaar); return x; } sexp* rlang_node_poke_cadr(sexp* x, sexp* newcar) { SETCADR(x, newcar); return x; } sexp* rlang_node_poke_cdar(sexp* x, sexp* newcdar) { SETCDR(CAR(x), newcdar); return x; } sexp* rlang_node_poke_cddr(sexp* x, sexp* newcdr) { SETCDR(CDR(x), newcdr); return x; } sexp* rlang_node_tag(sexp* x) { return TAG(x); } sexp* rlang_node_poke_tag(sexp* x, sexp* tag) { SET_TAG(x, tag); return x; } sexp* rlang_on_exit(sexp* expr, sexp* frame) { r_on_exit(expr, frame); return r_null; } // lang.h sexp* rlang_new_call_node(sexp* car, sexp* cdr) { return Rf_lcons(car, cdr); } // quo.h #include "../internal/quo.h" sexp* rlang_quo_is_missing(sexp* quo) { check_quosure(quo); return r_lgl(quo_is_missing(quo)); } sexp* rlang_quo_is_symbol(sexp* quo) { check_quosure(quo); return r_lgl(quo_is_symbol(quo)); } sexp* rlang_quo_is_call(sexp* quo) { check_quosure(quo); return r_lgl(quo_is_call(quo)); } sexp* rlang_quo_is_symbolic(sexp* quo) { check_quosure(quo); return r_lgl(quo_is_symbolic(quo)); } sexp* rlang_quo_is_null(sexp* quo) { check_quosure(quo); return r_lgl(quo_is_null(quo)); } // sexp.h sexp* rlang_length(sexp* x) { return r_int(r_length(x)); } sexp* rlang_true_length(sexp* x) { return r_int(XTRUELENGTH(x)); } sexp* rlang_is_reference(sexp* x, sexp* y) { return r_lgl(x == y); } sexp* rlang_missing_arg() { return R_MissingArg; } sexp* rlang_duplicate(sexp* x, sexp* shallow) { return r_duplicate(x, r_lgl_get(shallow, 0)); } sexp* rlang_is_null(sexp* x) { return r_lgl(r_is_null(x)); } sexp* rlang_sexp_address(sexp* x) { static char str[1000]; snprintf(str, 1000, "%p", (void*) x); return Rf_mkString(str); } sexp* rlang_poke_type(sexp* x, sexp* type) { SET_TYPEOF(x, Rf_str2type(r_chr_get_c_string(type, 0))); return x; } sexp* rlang_mark_object(sexp* x) { SET_OBJECT(x, 1); return x; } sexp* rlang_unmark_object(sexp* x) { SET_OBJECT(x, 0); return x; } sexp* rlang_get_promise(sexp* x, sexp* env) { switch (r_typeof(x)) { case r_type_promise: return x; case r_type_character: if (r_length(x) == 1) { x = r_sym(r_chr_get_c_string(x, 0)); } else { goto error; } // fallthrough case r_type_symbol: { sexp* prom = r_env_find(env, x); if (r_typeof(prom) == r_type_promise) { return prom; } // fallthrough } error: default: r_abort("`x` must be or refer to a local promise"); } } sexp* rlang_promise_expr(sexp* x, sexp* env) { sexp* prom = rlang_get_promise(x, env); return PREXPR(prom); } sexp* rlang_promise_env(sexp* x, sexp* env) { sexp* prom = rlang_get_promise(x, env); return PRENV(prom); } sexp* rlang_promise_value(sexp* x, sexp* env) { sexp* prom = rlang_get_promise(x, env); sexp* value = PRVALUE(prom); if (value == r_unbound_sym) { return r_sym("R_UnboundValue"); } else { return value; } } sexp* rlang_attrib(sexp* x) { return ATTRIB(x); } // Picks up symbols from parent environment to avoid bumping namedness // during promise resolution sexp* rlang_named(sexp* x, sexp* env) { int n_protect = 0; x = PROTECT(Rf_findVarInFrame3(env, x, FALSE)); ++n_protect; if (TYPEOF(x) == PROMSXP) { x = PROTECT(Rf_eval(x, env)); ++n_protect; } UNPROTECT(n_protect); return Rf_ScalarInteger(NAMED(x)); } sexp* rlang_find_var(sexp* env, sexp* sym) { return Rf_findVar(sym, env); } // vec.h sexp* rlang_vec_alloc(sexp* type, sexp* n) { return Rf_allocVector(Rf_str2type(r_chr_get_c_string(type, 0)), r_int_get(n, 0)); } sexp* rlang_vec_coerce(sexp* x, sexp* type) { return Rf_coerceVector(x, Rf_str2type(r_chr_get_c_string(type, 0))); } // TODO: C-level check for scalar integerish int r_as_int(sexp* x) { switch(r_typeof(x)) { case r_type_integer: return *INTEGER(x); case r_type_double: return (int) *REAL(x); default: r_abort("Internal error: Expected integerish input"); } } sexp* rlang_vec_poke_n(sexp* x, sexp* offset, sexp* y, sexp* from, sexp* n) { r_ssize offset_size = r_as_ssize(offset) - 1; r_ssize from_size = r_as_ssize(from) - 1; r_ssize n_size = r_as_ssize(n); r_vec_poke_n(x, offset_size, y, from_size, n_size); return x; } sexp* rlang_vec_poke_range(sexp* x, sexp* offset, sexp* y, sexp* from, sexp* to) { r_ssize offset_size = r_as_ssize(offset) - 1; r_ssize from_size = r_as_ssize(from) - 1; r_ssize to_size = r_as_ssize(to) - 1; r_vec_poke_range(x, offset_size, y, from_size, to_size); return x; } // vec-list.h static r_ssize validate_n(sexp* n) { if (n == r_null) { return -1; } switch (r_typeof(n)) { case r_type_integer: case r_type_double: if (r_length(n) == 1) { break; } // fallthrough default: r_abort("`n` must be NULL or a scalar integer"); } return r_as_ssize(n); } static int validate_finite(sexp* finite) { switch (r_typeof(finite)) { case r_type_null: return -1; case r_type_integer: case r_type_double: finite = r_vec_coerce(finite, r_type_logical); case r_type_logical: { int value = r_lgl_get(finite, 0); if (value != NA_LOGICAL) { return r_lgl_get(finite, 0); } // else fallthrough } default: r_abort("`finite` must be NULL or a scalar logical"); } } sexp* rlang_is_finite(sexp* x) { return r_shared_lgl(r_is_finite(x)); } sexp* rlang_is_list(sexp* x, sexp* n_) { r_ssize n = validate_n(n_); return r_shared_lgl(r_is_list(x, n)); } sexp* rlang_is_atomic(sexp* x, sexp* n_) { r_ssize n = validate_n(n_); return r_shared_lgl(r_is_atomic(x, n)); } sexp* rlang_is_vector(sexp* x, sexp* n_) { r_ssize n = validate_n(n_); return r_shared_lgl(r_is_vector(x, n)); } sexp* rlang_is_logical(sexp* x, sexp* n_) { r_ssize n = validate_n(n_); return r_shared_lgl(r_is_logical(x, n)); } sexp* rlang_is_integer(sexp* x, sexp* n_) { r_ssize n = validate_n(n_); return r_shared_lgl(r_is_integer(x, n, -1)); } sexp* rlang_is_double(sexp* x, sexp* n_, sexp* finite_) { r_ssize n = validate_n(n_); int finite = validate_finite(finite_); return r_shared_lgl(r_is_double(x, n, finite)); } sexp* rlang_is_integerish(sexp* x, sexp* n_, sexp* finite_) { r_ssize n = validate_n(n_); int finite = validate_finite(finite_); return r_shared_lgl(r_is_integerish(x, n, finite)); } sexp* rlang_is_character(sexp* x, sexp* n_) { r_ssize n = validate_n(n_); return r_shared_lgl(r_is_character(x, n)); } sexp* rlang_is_raw(sexp* x, sexp* n_) { r_ssize n = validate_n(n_); return r_shared_lgl(r_is_raw(x, n)); } sexp* rlang_is_string(sexp* x, sexp* string) { if (r_typeof(x) != r_type_character || r_length(x) != 1) { return r_shared_false; } sexp* value = r_chr_get(x, 0); if (value == NA_STRING) { return r_shared_false; } if (string == r_null) { return r_shared_true; } if (!rlang_is_string(string, r_null)) { r_abort("`string` must be `NULL` or a string"); } bool out = false; r_ssize n = r_length(string); sexp** p = r_chr_deref(string); for (r_ssize i = 0; i < n; ++i, ++p) { if (*p == value) { out = true; break; } } return r_shared_lgl(out); } rlang/src/export/exported-tests.c0000644000176200001440000000342213457603056016635 0ustar liggesusers#include sexp* rlang_r_string(sexp* str) { return STRING_ELT(str, 0); } // chr.c sexp* rlang_test_nms_are_duplicated(sexp* nms, sexp* from_last) { return r_nms_are_duplicated(nms, r_lgl_get(from_last, 0)); } // cnd.c sexp* rlang_test_r_warn(sexp* x) { r_warn(r_chr_get_c_string(x, 0)); return r_null; } sexp* rlang_test_Rf_warningcall(sexp* call, sexp* msg) { Rf_warningcall(call, r_chr_get_c_string(msg, 0)); return r_null; } sexp* rlang_test_Rf_errorcall(sexp* call, sexp* msg) { Rf_errorcall(call, r_chr_get_c_string(msg, 0)); return r_null; } // env.c sexp* rlang_test_base_ns_get(sexp* name) { return r_base_ns_get(r_chr_get_c_string(name, 0)); } // vec-lgl.c sexp* rlang_test_lgl_sum(sexp* x, sexp* na_true) { return r_int(r_lgl_sum(x, r_lgl_get(na_true, 0))); } sexp* rlang_test_lgl_which(sexp* x, sexp* na_true) { return r_lgl_which(x, r_lgl_get(na_true, 0)); } // parse.c sexp* rlang_test_parse(sexp* str) { return r_parse(r_chr_get_c_string(str, 0)); } sexp* rlang_test_parse_eval(sexp* str, sexp* env) { return r_parse_eval(r_chr_get_c_string(str, 0), env); } // node.c sexp* rlang_test_node_list_clone_until(sexp* node, sexp* sentinel) { sexp* sentinel_out; node = KEEP(r_node_list_clone_until(node, sentinel, &sentinel_out)); sexp* out = r_new_vector(r_type_list, 2); r_list_poke(out, 0, node); r_list_poke(out, 1, sentinel_out); FREE(1); return out; } // sym.c sexp* rlang_test_is_special_op_sym(sexp* x) { return r_lgl(r_is_special_op_sym(x)); } // squash.c bool rlang_is_clevel_spliceable(sexp* x) { return Rf_inherits(x, "foo"); } // stack.c sexp* rlang_test_sys_call(sexp* n) { return r_sys_call(r_int_get(n, 0), NULL); } sexp* rlang_test_sys_frame(sexp* n) { return r_sys_frame(r_int_get(n, 0), NULL); } rlang/src/internal.c0000644000176200001440000000060013612022772014122 0ustar liggesusers#include "internal/arg.c" #include "internal/call.c" #include "internal/dots.c" #include "internal/env.c" #include "internal/env-binding.c" #include "internal/eval.c" #include "internal/eval-tidy.c" #include "internal/expr-interp.c" #include "internal/expr-interp-rotate.c" #include "internal/fn.c" #include "internal/internal.c" #include "internal/quo.c" #include "internal/utils.c" rlang/src/lib.c0000644000176200001440000000142013611313357013056 0ustar liggesusers// This is an include point for the implementations of the rlang // library. It should be included in a single and separate compilation // unit. #include "lib/rlang.h" #include "lib/attrs.c" #include "lib/cnd.c" #include "lib/debug.c" #include "lib/env.c" #include "lib/env-binding.c" #include "lib/eval.c" #include "lib/export.c" #include "lib/fn.c" #include "lib/formula.c" #include "lib/lang.c" #include "lib/node.c" #include "lib/parse.c" #include "lib/quo.c" #include "lib/replace-na.c" #include "lib/rlang.c" #include "lib/session.c" #include "lib/sexp.c" #include "lib/squash.c" #include "lib/stack.c" #include "lib/sym.c" #include "lib/sym-unescape.c" #include "lib/vec.c" #include "lib/vec-chr.c" #include "lib/vec-lgl.c" #include "lib/vec-list.c" #include "lib/weakref.c" rlang/src/Makevars0000644000176200001440000000240013500140126013624 0ustar liggesusersPKG_CPPFLAGS = -I./lib/ lib-files = \ lib/rlang.h \ lib/attrs.c \ lib/cnd.c \ lib/debug.c \ lib/env.c \ lib/env-binding.c \ lib/eval.c \ lib/export.c \ lib/fn.c \ lib/formula.c \ lib/lang.c \ lib/node.c \ lib/parse.c \ lib/quo.c \ lib/replace-na.c \ lib/rlang.c \ lib/sexp.c \ lib/squash.c \ lib/stack.c \ lib/sym.c \ lib/sym-unescape.c \ lib/vec.c \ lib/vec-chr.c \ lib/vec-lgl.c \ lib/vec-list.c internal-files = \ internal/arg.c \ internal/dots.c \ internal/call.c \ internal/env.c \ internal/env-binding.c \ internal/eval.c \ internal/eval-tidy.c \ internal/expr-interp.c \ internal/expr-interp-rotate.c \ internal/fn.c \ internal/internal.c \ internal/quo.c \ internal/utils.c export-files = \ export/exported.c \ export/exported-tests.c \ export/init.c all: $(SHLIB) $(SHLIB): lib.o internal.o export.o lib.c: $(lib-files) touch lib.c internal.c: $(internal-files) touch internal.c export.c: $(export-files) touch export.c .PHONY: all rlang/src/lib/0000755000176200001440000000000013614116052012711 5ustar liggesusersrlang/src/lib/parse.h0000644000176200001440000000515413405732277014214 0ustar liggesusers#ifndef RLANG_PARSE_H #define RLANG_PARSE_H sexp* r_parse(const char* str); sexp* r_parse_eval(const char* str, sexp* env); // This only includes operators that actually appear in the AST. // Examples of silent operators are `else` and `in`. enum r_operator { R_OP_NONE = 0, R_OP_FUNCTION, R_OP_WHILE, R_OP_FOR, R_OP_REPEAT, R_OP_IF, R_OP_QUESTION, R_OP_QUESTION_UNARY, R_OP_ASSIGN1, R_OP_ASSIGN2, R_OP_ASSIGN_EQUAL, R_OP_COLON_EQUAL, R_OP_TILDE, R_OP_TILDE_UNARY, R_OP_OR1, R_OP_OR2, R_OP_AND1, R_OP_AND2, R_OP_BANG1, R_OP_BANG3, R_OP_GREATER, R_OP_GREATER_EQUAL, R_OP_LESS, R_OP_LESS_EQUAL, R_OP_EQUAL, R_OP_NOT_EQUAL, R_OP_PLUS, R_OP_MINUS, R_OP_TIMES, R_OP_RATIO, R_OP_MODULO, R_OP_SPECIAL, R_OP_COLON1, R_OP_BANG2, R_OP_PLUS_UNARY, R_OP_MINUS_UNARY, R_OP_HAT, R_OP_DOLLAR, R_OP_AT, R_OP_COLON2, R_OP_COLON3, R_OP_PARENTHESES, R_OP_BRACKETS1, R_OP_BRACKETS2, R_OP_BRACES, R_OP_MAX }; enum r_operator r_which_operator(sexp* call); const char* r_op_as_c_string(enum r_operator op); /** * struct r_op_precedence - Information about operator precedence * * @power: Binding power. Absolute value has no meaning, only the * relative ordering between operators has meaning. * @assoc: -1 if left associative, 0 if non-associative, 1 if right associative. * @unary: `false` if a binary operation. * @delimited: `true` if an operation like `(` or `{`. */ struct r_op_precedence { uint8_t power; int8_t assoc; bool unary; bool delimited; }; extern const struct r_op_precedence r_ops_precedence[R_OP_MAX]; /** * r_op_has_precedence() - Does an operation have precedence over another? * * Relies on information in the table of operation metadata * %r_ops_precedence. * * @x The call that was found lower in the AST (i.e. the call that is * supposed to have precedence). * @parent The call that was found earlier in the AST (i.e. the one * that wraps @x). */ bool r_op_has_precedence(enum r_operator x, enum r_operator parent); bool r_rhs_op_has_precedence(enum r_operator rhs, enum r_operator parent); bool r_lhs_op_has_precedence(enum r_operator lhs, enum r_operator parent); static inline bool r_call_has_precedence(sexp* x, sexp* parent) { return r_op_has_precedence(r_which_operator(x), r_which_operator(parent)); } static inline bool r_lhs_call_has_precedence(sexp* lhs, sexp* parent) { return r_lhs_op_has_precedence(r_which_operator(lhs), r_which_operator(parent)); } static inline bool r_rhs_call_has_precedence(sexp* rhs, sexp* parent) { return r_rhs_op_has_precedence(r_which_operator(rhs), r_which_operator(parent)); } #endif rlang/src/lib/stack.h0000644000176200001440000000041513450422477014200 0ustar liggesusers#ifndef RLANG_STACK_H #define RLANG_STACK_H void r_on_exit(sexp* expr, sexp* frame); sexp* r_current_frame(); sexp* r_sys_frame(int n, sexp* frame); sexp* r_sys_call(int n, sexp* frame); static inline void r_maybe_interrupt() { R_CheckUserInterrupt(); } #endif rlang/src/lib/state.h0000644000176200001440000000023113351410655014202 0ustar liggesusers#ifndef RLANG_STATE_H #define RLANG_STATE_H static inline sexp* r_peek_option(const char* name) { return Rf_GetOption1(Rf_install(name)); } #endif rlang/src/lib/attrs.h0000644000176200001440000000310413405732277014230 0ustar liggesusers#ifndef RLANG_ATTRS_H #define RLANG_ATTRS_H #include "sym.h" static inline sexp* r_get_attributes(sexp* x) { return ATTRIB(x); } inline sexp* r_poke_attributes(sexp* x, sexp* attrs) { SET_ATTRIB(x, attrs); return x; } static inline sexp* r_set_attributes(sexp* x, sexp* attrs) { x = KEEP(r_duplicate(x, true)); SET_ATTRIB(x, attrs); FREE(1); return x; } sexp* r_get_attribute(sexp* x, sexp* tag); sexp* r_push_attribute(sexp* x, sexp* tag, sexp* value); sexp* r_set_attribute(sexp* x, sexp* tag, sexp* value); static inline void r_push_names(sexp* x, sexp* value) { r_push_attribute(x, R_NamesSymbol, value); } sexp* r_node_push_classes(sexp* x, const char** tags); sexp* r_node_push_class(sexp* x, const char* tag); void r_push_classes(sexp* x, const char** tags); void r_push_class(sexp* x, const char* tag); static inline void r_poke_attribute(sexp* x, sexp* sym, sexp* value) { Rf_setAttrib(x, sym, value); } static inline void r_poke_class(sexp* x, sexp* classes) { r_poke_attribute(x, r_class_sym, classes); } static inline sexp* r_set_class(sexp* x, sexp* classes) { x = r_set_attribute(x, r_class_sym, classes); if (classes == r_null) { r_unmark_object(x); } else { r_mark_object(x); } return x; } static inline sexp* r_get_class(sexp* x) { return r_get_attribute(x, r_class_sym); } static inline sexp* r_vec_names(sexp* x) { return r_get_attribute(x, r_names_sym); } static inline void r_poke_names(sexp* x, sexp* nms) { r_poke_attribute(x, r_names_sym, nms); } bool r_has_name_at(sexp* x, r_ssize i); bool r_is_named(sexp* x); #endif rlang/src/lib/env-binding.c0000644000176200001440000000437013405732277015274 0ustar liggesusers#include "rlang.h" bool r_env_binding_is_promise(sexp* env, sexp* sym) { if (r_typeof(sym) != r_type_symbol) { r_abort("Internal error: Expected symbol in promise binding predicate"); } sexp* obj = r_env_find(env, sym); return r_typeof(obj) == r_type_promise && PRVALUE(obj) == r_unbound_sym; } bool r_env_binding_is_active(sexp* env, sexp* sym) { if (r_typeof(sym) != r_type_symbol) { r_abort("Internal error: Expected symbol in active binding predicate"); } return R_BindingIsActive(sym, env); } static sexp* new_binding_types(r_ssize n) { sexp* types = r_new_vector(r_type_integer, n); int* types_ptr = r_int_deref(types); memset(types_ptr, 0, n * sizeof *types_ptr); return types; } static enum r_env_binding_type which_env_binding(sexp* env, sexp* sym) { if (r_env_binding_is_promise(env, sym)) { return R_ENV_BINDING_PROMISE; } if (r_env_binding_is_active(env, sym)) { return R_ENV_BINDING_ACTIVE; } return R_ENV_BINDING_VALUE; } static inline sexp* binding_as_sym(bool list, sexp* bindings, r_ssize i) { if (list) { return r_list_get(bindings, i); } else { return r_str_as_symbol(r_chr_get(bindings, i)); } } static r_ssize detect_special_binding(sexp* env, sexp* bindings, bool symbols) { r_ssize n = r_length(bindings); for (r_ssize i = 0; i < n; ++i) { sexp* sym = binding_as_sym(symbols, bindings, i); if (which_env_binding(env, sym)) { return i; } } return -1; } // Returns NULL if all values to spare an alloc sexp* r_env_binding_types(sexp* env, sexp* bindings) { bool symbols; switch (r_typeof(bindings)) { case r_type_list: symbols = true; break; case r_type_character: symbols = false; break; default: r_abort("Internal error: Unexpected `bindings` type in `r_env_binding_types()`"); } r_ssize i = detect_special_binding(env, bindings, symbols); if (i < 0) { return r_null; } r_ssize n = r_length(bindings); sexp* types = KEEP(new_binding_types(n)); int* types_ptr = r_int_deref(types) + i; while (i < n) { sexp* sym = binding_as_sym(symbols, bindings, i); *types_ptr = which_env_binding(env, sym); ++i; ++types_ptr; } FREE(1); return types; } rlang/src/lib/lang.c0000644000176200001440000000500013404522435013774 0ustar liggesusers#include "rlang.h" bool r_is_call(sexp* x, const char* name) { if (r_typeof(x) != LANGSXP) { return false; } else { return name == NULL || r_is_symbol(r_node_car(x), name); } } bool r_is_call_any(sexp* x, const char** names, int n) { if (r_typeof(x) != LANGSXP) { return false; } else { return r_is_symbol_any(r_node_car(x), names, n); } } #define R_SUBSET_NAMES_N 4 static const char* r_subset_names[R_SUBSET_NAMES_N] = { "$", "@", "::", ":::" }; bool r_is_prefixed_call(sexp* x, const char* name) { if (r_typeof(x) != LANGSXP) { return false; } sexp* head = r_node_car(x); if (!r_is_call_any(head, r_subset_names, R_SUBSET_NAMES_N)) { return false; } if (name) { sexp* rhs = r_node_cadr(r_node_cdr(head)); if (!r_is_symbol(rhs, name)) { return false; } } return true; } bool r_is_prefixed_call_any(sexp* x, const char ** names, int n) { if (r_typeof(x) != LANGSXP) { return false; } sexp* head = r_node_car(x); if (!r_is_call_any(head, r_subset_names, R_SUBSET_NAMES_N)) { return false; } sexp* args = r_node_cdar(x); sexp* sym = r_node_cadr(args); return r_is_symbol_any(sym, names, n); } bool r_is_maybe_prefixed_call_any(sexp* x, const char ** names, int n) { if (r_typeof(x) != LANGSXP) { return false; } if (r_is_symbol_any(r_node_car(x), names, n)) { return true; } return r_is_prefixed_call_any(x, names, n); } bool r_is_namespaced_call(sexp* x, const char* ns, const char* name) { if (r_typeof(x) != LANGSXP) { return false; } sexp* head = r_node_car(x); if (!r_is_call(head, "::")) { return false; } if (ns) { sexp* lhs = r_node_cadr(head); if (!r_is_symbol(lhs, ns)) { return false; } } if (name) { sexp* rhs = r_node_cadr(r_node_cdar(x)); if (!r_is_symbol(rhs, name)) { return false; } } return true; } bool r_is_namespaced_call_any(sexp* x, const char* ns, const char** names, int n) { if (!r_is_namespaced_call(x, ns, NULL)) { return false; } sexp* args = r_node_cdar(x); sexp* sym = r_node_cadr(args); return r_is_symbol_any(sym, names, n); } bool r_is_special_op_call(sexp* x) { return r_typeof(x) == LANGSXP && r_is_special_op_sym(r_node_car(x)); } sexp* r_expr_protect(sexp* x) { static sexp* quote_prim = NULL; if (!quote_prim) quote_prim = r_base_ns_get("quote"); sexp* args = KEEP(r_new_node(x, r_null)); sexp* out = r_new_call(quote_prim, args); FREE(1); return out; } rlang/src/lib/fn.h0000644000176200001440000000112513405732277013477 0ustar liggesusers#ifndef RLANG_FN_H #define RLANG_FN_H static inline sexp* r_fn_body(sexp* fn) { return BODY_EXPR(fn); } static inline void r_fn_poke_body(sexp* fn, sexp* body) { SET_BODY(fn, body); } static inline sexp* r_fn_env(sexp* fn) { return CLOENV(fn); } static inline void r_fn_poke_env(sexp* fn, sexp* env) { SET_CLOENV(fn, env); } sexp* r_new_function(sexp* formals, sexp* body, sexp* env); static inline bool r_is_function(sexp* x) { switch (r_typeof(x)) { case r_type_closure: case r_type_builtin: case r_type_special: return true; default: return false; } } #endif rlang/src/lib/quo.h0000644000176200001440000000036413351410655013675 0ustar liggesusers#ifndef RLANG_QUO_H #define RLANG_QUO_H extern sexp* (*r_quo_get_expr)(sexp* quo); extern sexp* (*r_quo_set_expr)(sexp* quo, sexp* expr); extern sexp* (*r_quo_get_env)(sexp* quo); extern sexp* (*r_quo_set_env)(sexp* quo, sexp* env); #endif rlang/src/lib/cnd.c0000644000176200001440000001433613610070340013623 0ustar liggesusers#include "rlang.h" #define BUFSIZE 8192 #define INTERP(BUF, FMT, DOTS) \ { \ va_list dots; \ va_start(dots, FMT); \ vsnprintf(BUF, BUFSIZE, FMT, dots); \ va_end(dots); \ \ BUF[BUFSIZE - 1] = '\0'; \ } static sexp* msg_call = NULL; void r_inform(const char* fmt, ...) { char buf[BUFSIZE]; INTERP(buf, fmt, ...); r_eval_with_x(msg_call, r_base_env, KEEP(r_chr(buf))); FREE(1); } static sexp* wng_call = NULL; void r_warn(const char* fmt, ...) { char buf[BUFSIZE]; INTERP(buf, fmt, ...); r_eval_with_x(wng_call, r_base_env, KEEP(r_chr(buf))); FREE(1); } static sexp* err_call = NULL; void r_abort(const char* fmt, ...) { char buf[BUFSIZE]; INTERP(buf, fmt, ...); r_eval_with_x(err_call, r_base_env, KEEP(r_chr(buf))); while (1); // No return } sexp* r_interp_str(const char* fmt, ...) { char buf[BUFSIZE]; INTERP(buf, fmt, ...); return r_chr(buf); } static sexp* signal_soft_deprecated_call = NULL; void r_signal_soft_deprecated(const char* msg, const char* id, sexp* env) { id = id ? id : msg; env = env ? env : r_empty_env; if (!msg) { r_abort("Internal error: NULL `msg` in r_signal_soft_deprecated()"); } sexp* msg_ = KEEP(r_chr(msg)); sexp* id_ = KEEP(r_chr(id)); r_eval_with_xyz(signal_soft_deprecated_call, r_base_env, msg_, id_, env); FREE(2); } static void signal_retirement(const char* source, const char* buf); static sexp* warn_deprecated_call = NULL; void r_warn_deprecated(const char* id, const char* fmt, ...) { char buf[BUFSIZE]; INTERP(buf, fmt, ...); sexp* msg_ = KEEP(r_chr(buf)); id = id ? id : buf; sexp* id_ = KEEP(r_chr(id)); r_eval_with_xy(warn_deprecated_call, r_base_env, msg_, id_); FREE(2); } void r_stop_defunct(const char* fmt, ...) { char buf[BUFSIZE]; INTERP(buf, fmt, ...); signal_retirement("stop_defunct(msg = x)", buf); r_abort("Internal error: Unexpected return after `.Defunct()`"); } static void signal_retirement(const char* source, const char* buf) { sexp* call = KEEP(r_parse(source)); sexp* msg = KEEP(r_chr(buf)); r_eval_with_x(call, r_ns_env("rlang"), msg); FREE(2); } static sexp* new_condition_names(sexp* data) { if (!r_is_named(data)) { r_abort("Conditions must have named data fields"); } sexp* data_nms = r_vec_names(data); if (r_chr_has_any(data_nms, (const char* []) { "message", NULL })) { r_abort("Conditions can't have a `message` data field"); } sexp* nms = KEEP(r_new_vector(r_type_character, r_length(data) + 1)); r_chr_poke(nms, 0, r_string("message")); r_vec_poke_n(nms, 1, data_nms, 0, r_length(nms) - 1); FREE(1); return nms; } sexp* r_new_condition(sexp* subclass, sexp* msg, sexp* data) { if (msg == r_null) { msg = r_shared_empty_chr; } else if (!r_is_scalar_character(msg)) { r_abort("Condition message must be a string"); } r_ssize n_data = r_length(data); sexp* cnd = KEEP(r_new_vector(VECSXP, n_data + 1)); r_list_poke(cnd, 0, msg); r_vec_poke_n(cnd, 1, data, 0, r_length(cnd) - 1); r_poke_names(cnd, KEEP(new_condition_names(data))); r_poke_class(cnd, KEEP(chr_append(subclass, KEEP(r_string("condition"))))); FREE(4); return cnd; } static sexp* cnd_signal_call = NULL; static sexp* wng_signal_call = NULL; static sexp* err_signal_call = NULL; void r_cnd_signal(sexp* cnd) { sexp* call = r_null; switch (r_cnd_type(cnd)) { case r_cnd_type_message: call = msg_call; break; case r_cnd_type_warning: call = wng_signal_call; break; case r_cnd_type_error: call = err_signal_call; break; case r_cnd_type_interrupt: r_interrupt(); return; default: call = cnd_signal_call; break; } r_eval_with_x(call, r_base_env, cnd); } #ifdef _WIN32 #include void r_interrupt() { UserBreak = 1; R_CheckUserInterrupt(); r_abort("Internal error: Simulated interrupt not processed"); } #else #include void r_interrupt() { Rf_onintr(); r_abort("Internal error: Simulated interrupt not processed"); } #endif enum r_condition_type r_cnd_type(sexp* cnd) { sexp* classes = r_get_class(cnd); if (r_typeof(cnd) != r_type_list || r_typeof(classes) != r_type_character) { goto error; } r_ssize n_classes = r_length(classes); for (r_ssize i = 0; i < n_classes; ++i) { const char* class_str = r_str_deref(r_chr_get(classes, i)); switch (class_str[0]) { case 'c': if (strcmp(class_str, "condition")) { continue; } else { return r_cnd_type_condition; } case 'm': if (strcmp(class_str, "message")) { continue; } else { return r_cnd_type_message; } case 'w': if (strcmp(class_str, "warning")) { continue; } else { return r_cnd_type_warning; } case 'e': if (strcmp(class_str, "error")) { continue; } else { return r_cnd_type_error; } case 'i': if (strcmp(class_str, "interrupt")) { continue; } else { return r_cnd_type_interrupt; } default: continue; } } error: r_abort("`cnd` is not a condition object"); } sexp* rlang_ns_get(const char* name); void r_init_library_cnd() { msg_call = r_parse("message(x)"); r_mark_precious(msg_call); wng_call = r_parse("warning(x, call. = FALSE)"); r_mark_precious(wng_call); err_call = r_parse("rlang::abort(x)"); r_mark_precious(err_call); wng_signal_call = r_parse("warning(x)"); r_mark_precious(wng_signal_call); err_signal_call = r_parse("rlang:::signal_abort(x)"); r_mark_precious(err_signal_call); const char* cnd_signal_source = "withRestarts(rlang_muffle = function() NULL, signalCondition(x))"; cnd_signal_call = r_parse(cnd_signal_source); r_mark_precious(cnd_signal_call); warn_deprecated_call = r_parse("rlang:::warn_deprecated(x, id = y)"); r_mark_precious(warn_deprecated_call); signal_soft_deprecated_call = r_parse("rlang:::signal_soft_deprecated(x, id = y, env = z)"); r_mark_precious(signal_soft_deprecated_call); } rlang/src/lib/formula.h0000644000176200001440000000032313351410655014531 0ustar liggesusers#ifndef RLANG_FORMULA_H #define RLANG_FORMULA_H bool r_is_formulaish(sexp* x, int scoped, int lhs); sexp* r_f_rhs(sexp* f); sexp* r_f_lhs(sexp* f); sexp* r_f_env(sexp* f); bool r_f_has_env(sexp* f); #endif rlang/src/lib/parse.c0000644000176200001440000003153513361570151014201 0ustar liggesusers#include "rlang.h" #include static void abort_parse(sexp* code, const char* why) { if (r_peek_option("rlang__verbose_errors") != r_null) { r_sexp_print(code); } r_abort("Internal error: %s", why); } sexp* r_parse(const char* str) { sexp* str_ = KEEP(r_chr(str)); ParseStatus status; sexp* out = KEEP(R_ParseVector(str_, -1, &status, r_null)); if (status != PARSE_OK) { abort_parse(str_, "Parsing failed"); } if (r_length(out) != 1) { abort_parse(str_, "Expected a single expression"); } out = r_list_get(out, 0); FREE(2); return out; } sexp* r_parse_eval(const char* str, sexp* env) { sexp* out = r_eval(KEEP(r_parse(str)), env); FREE(1); return out; } const struct r_op_precedence r_ops_precedence[R_OP_MAX] = { [R_OP_NONE] = { .power = 0, .assoc = 0, .unary = false, .delimited = false }, [R_OP_FUNCTION] = { .power = 5, .assoc = 1, .unary = true, .delimited = false }, [R_OP_QUESTION] = { .power = 10, .assoc = -1, .unary = false, .delimited = false }, [R_OP_QUESTION_UNARY] = { .power = 10, .assoc = -1, .unary = true, .delimited = false }, [R_OP_WHILE] = { .power = 20, .assoc = -1, .unary = false, .delimited = true }, [R_OP_FOR] = { .power = 20, .assoc = -1, .unary = false, .delimited = true }, [R_OP_REPEAT] = { .power = 20, .assoc = -1, .unary = false, .delimited = true }, [R_OP_IF] = { .power = 30, .assoc = 1, .unary = false, .delimited = true }, [R_OP_ASSIGN1] = { .power = 40, .assoc = 1, .unary = false, .delimited = false }, [R_OP_ASSIGN2] = { .power = 40, .assoc = 1, .unary = false, .delimited = false }, [R_OP_COLON_EQUAL] = { .power = 40, .assoc = 1, .unary = false, .delimited = false }, [R_OP_ASSIGN_EQUAL] = { .power = 50, .assoc = 1, .unary = false, .delimited = false }, [R_OP_TILDE] = { .power = 60, .assoc = -1, .unary = false, .delimited = false }, [R_OP_TILDE_UNARY] = { .power = 60, .assoc = -1, .unary = true, .delimited = false }, [R_OP_OR1] = { .power = 70, .assoc = -1, .unary = false, .delimited = false }, [R_OP_OR2] = { .power = 70, .assoc = -1, .unary = false, .delimited = false }, [R_OP_AND1] = { .power = 80, .assoc = -1, .unary = false, .delimited = false }, [R_OP_AND2] = { .power = 80, .assoc = -1, .unary = false, .delimited = false }, [R_OP_BANG1] = { .power = 90, .assoc = -1, .unary = true, .delimited = false }, [R_OP_BANG3] = { .power = 90, .assoc = -1, .unary = true, .delimited = false }, [R_OP_GREATER] = { .power = 100, .assoc = 0, .unary = false, .delimited = false }, [R_OP_GREATER_EQUAL] = { .power = 100, .assoc = 0, .unary = false, .delimited = false }, [R_OP_LESS] = { .power = 100, .assoc = 0, .unary = false, .delimited = false }, [R_OP_LESS_EQUAL] = { .power = 100, .assoc = 0, .unary = false, .delimited = false }, [R_OP_EQUAL] = { .power = 100, .assoc = 0, .unary = false, .delimited = false }, [R_OP_NOT_EQUAL] = { .power = 100, .assoc = 0, .unary = false, .delimited = false }, [R_OP_PLUS] = { .power = 110, .assoc = -1, .unary = false, .delimited = false }, [R_OP_MINUS] = { .power = 110, .assoc = -1, .unary = false, .delimited = false }, [R_OP_TIMES] = { .power = 120, .assoc = -1, .unary = false, .delimited = false }, [R_OP_RATIO] = { .power = 120, .assoc = -1, .unary = false, .delimited = false }, [R_OP_MODULO] = { .power = 130, .assoc = -1, .unary = false, .delimited = false }, [R_OP_SPECIAL] = { .power = 130, .assoc = -1, .unary = false, .delimited = false }, [R_OP_COLON1] = { .power = 140, .assoc = -1, .unary = false, .delimited = false }, [R_OP_BANG2] = { .power = 150, .assoc = -1, .unary = true, .delimited = false }, [R_OP_PLUS_UNARY] = { .power = 150, .assoc = -1, .unary = true, .delimited = false }, [R_OP_MINUS_UNARY] = { .power = 150, .assoc = -1, .unary = true, .delimited = false }, [R_OP_HAT] = { .power = 160, .assoc = 1, .unary = false, .delimited = false }, [R_OP_DOLLAR] = { .power = 170, .assoc = -1, .unary = false, .delimited = false }, [R_OP_AT] = { .power = 170, .assoc = -1, .unary = false, .delimited = false }, [R_OP_COLON2] = { .power = 180, .assoc = 0, .unary = false, .delimited = false }, [R_OP_COLON3] = { .power = 180, .assoc = 0, .unary = false, .delimited = false }, [R_OP_PARENTHESES] = { .power = 190, .assoc = 0, .unary = true, .delimited = true }, [R_OP_BRACKETS1] = { .power = 190, .assoc = -1, .unary = false, .delimited = false }, [R_OP_BRACKETS2] = { .power = 190, .assoc = -1, .unary = false, .delimited = false }, [R_OP_BRACES] = { .power = 200, .assoc = 0, .unary = false, .delimited = true } }; enum r_operator r_which_operator(sexp* call) { if (r_typeof(call) != r_type_call) { return R_OP_NONE; } sexp* head = r_node_car(call); if (r_typeof(head) != r_type_symbol) { return R_OP_NONE; } const char* name = r_sym_get_c_string(head); int len = strlen(name); bool is_unary = r_node_cddr(call) == r_null; switch (name[0]) { case 'w': if (strcmp(name, "while") == 0) { return R_OP_WHILE; } else { goto none; } case 'f': if (strcmp(name, "for") == 0) { return R_OP_FOR; } else if (strcmp(name, "function") == 0) { return R_OP_FUNCTION; } else { goto none; } case 'r': if (strcmp(name, "repeat") == 0) { return R_OP_REPEAT; } else { goto none; } case 'i': if (strcmp(name, "if") == 0) { return R_OP_IF; } else { goto none; } case '?': if (len == 1) { if (is_unary) { return R_OP_QUESTION_UNARY; } else { return R_OP_QUESTION; } } else { goto none; } case '<': switch (len) { case 1: return R_OP_LESS; case 2: switch (name[1]) { case '-': return R_OP_ASSIGN1; case '=': return R_OP_LESS_EQUAL; default: goto none; } case 3: if (name[1] == '<' && name[2] == '-') { return R_OP_ASSIGN2; } else { goto none; } default: goto none; } case '>': switch (len) { case 1: return R_OP_GREATER; case 2: if (name[1] == '=') { return R_OP_GREATER_EQUAL; } else { goto none; } default: goto none; } case '=': switch (len) { case 1: return R_OP_ASSIGN_EQUAL; case 2: if (name[1] == '=') { return R_OP_EQUAL; } else { goto none; } default: goto none; } case ':': switch (len) { case 1: return R_OP_COLON1; case 2: switch (name[1]) { case '=': return R_OP_COLON_EQUAL; case ':': return R_OP_COLON2; default: goto none; } case 3: if (name[1] == ':' && name[2] == ':') { return R_OP_COLON3; } else { goto none; } default: goto none; } case '~': if (len == 1) { if (is_unary) { return R_OP_TILDE_UNARY; } else { return R_OP_TILDE; } } else { goto none; } case '|': switch (len) { case 1: return R_OP_OR1; case 2: if (name[1] == '|') { return R_OP_OR2; } else { goto none; } default: goto none; } case '&': switch (len) { case 1: return R_OP_AND1; case 2: if (name[1] == '&') { return R_OP_AND2; } else { goto none; } default: goto none; } case '!': switch (len) { case 1: return R_OP_BANG1; case 2: switch (name[1]) { case '!': return R_OP_BANG2; case '=': return R_OP_NOT_EQUAL; default: goto none; } case 3: if (name[1] == '!' && name[2] == '!') { return R_OP_BANG3; } else { goto none; } default: goto none; } case '+': if (len == 1) { if (is_unary) { return R_OP_PLUS_UNARY; } else { return R_OP_PLUS; } } else { goto none; } case '-': if (len == 1) { if (is_unary) { return R_OP_MINUS_UNARY; } else { return R_OP_MINUS; } } else { goto none; } case '*': if (len == 1) { return R_OP_TIMES; } else { goto none; } case '/': if (len == 1) { return R_OP_RATIO; } else { goto none; } case '%': switch (len) { case 1: goto none; case 2: if (name[1] == '%') { return R_OP_MODULO; } else { goto none; } default: if (name[len - 1] == '%') { return R_OP_SPECIAL; } else { goto none; } } case '^': if (len == 1) { return R_OP_HAT; } else { goto none; } case '$': if (len == 1) { return R_OP_DOLLAR; } else { goto none; } case '@': if (len == 1) { return R_OP_AT; } else { goto none; } case '(': if (len == 1) { return R_OP_PARENTHESES; } else { goto none; } case '[': switch (len) { case 1: return R_OP_BRACKETS1; case 2: if (name[1] == '[') { return R_OP_BRACKETS2; } else { goto none; } default: goto none; } case '{': if (len == 1) { return R_OP_BRACES; } else { goto none; } none: default: return R_OP_NONE; } } const char* r_op_as_c_string(enum r_operator op) { switch (op) { case R_OP_NONE: return ""; case R_OP_WHILE: return "while"; case R_OP_FOR: return "for"; case R_OP_REPEAT: return "repeat"; case R_OP_IF: return "if"; case R_OP_FUNCTION: return "function"; case R_OP_QUESTION: return "?"; case R_OP_QUESTION_UNARY: return "?unary"; case R_OP_ASSIGN1: return "<-"; case R_OP_ASSIGN2: return "<<-"; case R_OP_ASSIGN_EQUAL: return "="; case R_OP_COLON_EQUAL: return ":="; case R_OP_TILDE: return "~"; case R_OP_TILDE_UNARY: return "~unary"; case R_OP_OR1: return "|"; case R_OP_OR2: return "||"; case R_OP_AND1: return "&"; case R_OP_AND2: return "&&"; case R_OP_BANG1: return "!"; case R_OP_BANG3: return "!!!"; case R_OP_GREATER: return ">"; case R_OP_GREATER_EQUAL: return ">="; case R_OP_LESS: return "<"; case R_OP_LESS_EQUAL: return "<="; case R_OP_EQUAL: return "=="; case R_OP_NOT_EQUAL: return "!="; case R_OP_PLUS: return "+"; case R_OP_MINUS: return "-"; case R_OP_TIMES: return "*"; case R_OP_RATIO: return "/"; case R_OP_MODULO: return "%%"; case R_OP_SPECIAL: return "special"; case R_OP_COLON1: return ":"; case R_OP_BANG2: return "!!"; case R_OP_PLUS_UNARY: return "+unary"; case R_OP_MINUS_UNARY: return "-unary"; case R_OP_HAT: return "^"; case R_OP_DOLLAR: return "$"; case R_OP_AT: return "@"; case R_OP_COLON2: return "::"; case R_OP_COLON3: return ":::"; case R_OP_PARENTHESES: return "("; case R_OP_BRACKETS1: return "["; case R_OP_BRACKETS2: return "[["; case R_OP_BRACES: return "{"; case R_OP_MAX: r_abort("Unexpected `enum r_operator` value"); } // Silence mistaken noreturn warning on GCC r_abort("Never reached"); } bool op_has_precedence_impl(enum r_operator x, enum r_operator parent, int side) { if (x > R_OP_MAX || parent > R_OP_MAX) { r_abort("Internal error: `enum r_operator` out of bounds"); } if (x == R_OP_NONE) { return true; } if (parent == R_OP_NONE) { return true; } struct r_op_precedence x_info = r_ops_precedence[x]; struct r_op_precedence y_info = r_ops_precedence[parent]; if (x_info.delimited) { return true; } if (y_info.delimited) { return false; } uint8_t x_power = x_info.power; uint8_t y_power = y_info.power; if (x_power == y_power) { if (side == 0) { r_abort("Internal error: Unspecified direction of associativity"); } return r_ops_precedence[x].assoc == side; } else { return x_power > y_power; } } bool r_op_has_precedence(enum r_operator x, enum r_operator parent) { return op_has_precedence_impl(x, parent, 0); } bool r_lhs_op_has_precedence(enum r_operator lhs, enum r_operator parent) { return op_has_precedence_impl(lhs, parent, -1); } bool r_rhs_op_has_precedence(enum r_operator rhs, enum r_operator parent) { return op_has_precedence_impl(rhs, parent, 1); } rlang/src/lib/vec.c0000644000176200001440000001715113504161362013641 0ustar liggesusers#include "rlang.h" #include #include static bool has_correct_length(sexp* x, r_ssize n) { return n < 0 || r_length(x) == n; } bool r_is_atomic(sexp* x, r_ssize n) { switch(r_typeof(x)) { case LGLSXP: case INTSXP: case REALSXP: case CPLXSXP: case STRSXP: case RAWSXP: return has_correct_length(x, n); default: return false; } } bool r_is_scalar_atomic(sexp* x) { return r_is_atomic(x, 1); } bool r_is_vector(sexp* x, r_ssize n) { switch(r_typeof(x)) { case LGLSXP: case INTSXP: case REALSXP: case CPLXSXP: case STRSXP: case RAWSXP: case VECSXP: return has_correct_length(x, n); default: return false; } } bool r_is_logical(sexp* x, r_ssize n) { return r_typeof(x) == r_type_logical && has_correct_length(x, n); } bool r_is_finite(sexp* x) { r_ssize n = r_length(x); switch(r_typeof(x)) { case r_type_integer: { int* ptr = r_int_deref(x); for (r_ssize i = 0; i < n; ++i, ++ptr) { if (*ptr == NA_INTEGER) { return false; } } break; } case r_type_double: { double* ptr = r_dbl_deref(x); for (r_ssize i = 0; i < n; ++i, ++ptr) { if (!isfinite(*ptr)) { return false; } } break; } case r_type_complex: { r_complex_t* ptr = r_cpl_deref(x); for (r_ssize i = 0; i < n; ++i, ++ptr) { if (!isfinite(ptr->r) || !isfinite(ptr->i)) { return false; } } break; } default: r_abort("Internal error: expected a numeric vector"); } return true; } bool r_is_integer(sexp* x, r_ssize n, int finite) { if (r_typeof(x) != r_type_integer || !has_correct_length(x, n)) { return false; } if (finite >= 0 && (bool) finite != r_is_finite(x)) { return false; } return true; } bool r_is_double(sexp* x, r_ssize n, int finite) { if (r_typeof(x) != r_type_double || !has_correct_length(x, n)) { return false; } if (finite >= 0 && (bool) finite != r_is_finite(x)) { return false; } return true; } // Allow integers up to 2^52, same as R_XLEN_T_MAX when long vector // support is enabled #define RLANG_MAX_DOUBLE_INT 4503599627370496 bool r_is_integerish(sexp* x, r_ssize n, int finite) { if (r_typeof(x) == r_type_integer) { return r_is_integer(x, n, finite); } if (r_typeof(x) != r_type_double || !has_correct_length(x, n)) { return false; } r_ssize actual_n = r_length(x); double* ptr = r_dbl_deref(x); bool actual_finite = true; for (r_ssize i = 0; i < actual_n; ++i, ++ptr) { double elt = *ptr; if (!isfinite(elt)) { actual_finite = false; continue; } if (elt > RLANG_MAX_DOUBLE_INT) { return false; } // C99 guarantees existence of the int_least_N_t types, even on // machines that don't support arithmetic on width N: if (elt != (int_least64_t) elt) { return false; } } if (finite >= 0 && actual_finite != (bool) finite) { return false; } return true; } #undef RLANG_MAX_DOUBLE_INT bool r_is_character(sexp* x, r_ssize n) { return r_typeof(x) == r_type_character && has_correct_length(x, n); } bool r_is_raw(sexp* x, r_ssize n) { return r_typeof(x) == r_type_raw && has_correct_length(x, n); } r_ssize r_vec_length(sexp* x) { switch(r_typeof(x)) { case r_type_null: return 0; case r_type_logical: case r_type_integer: case r_type_double: case r_type_complex: case r_type_character: case r_type_raw: case r_type_list: case r_type_string: return XLENGTH(x); default: r_abort("Internal error: expected a vector"); } } sexp* r_vec_get(sexp* vec, r_ssize i) { switch (r_typeof(vec)) { case r_type_character: return r_chr_get(vec, i); case r_type_list: return r_list_get(vec, i); default: r_abort("Internal error: Unimplemented type in `r_vec_get()`"); } } bool r_vec_find_first_identical_any(sexp* x, sexp* y, r_ssize* index) { if (r_typeof(x) != r_type_list && r_typeof(x) != r_type_character) { r_abort("Internal error: `x` must be a list or character vector in `r_vec_find_first_identical_any()`"); } if (r_typeof(y) != r_type_list && r_typeof(y) != r_type_character) { r_abort("Internal error: `y` must be a list or character vector in `r_vec_find_first_identical_any()`"); } r_ssize n = r_length(x); r_ssize n_comparisons = r_length(y); for (r_ssize i = 0; i < n; ++i) { sexp* elt = r_vec_get(x, i); for (r_ssize j = 0; j < n_comparisons; ++j) { if (r_is_identical(elt, r_vec_get(y, j))) { if (index) { *index = i; } return true; } } } return false; } // Copy -------------------------------------------------------------- void r_vec_poke_n(sexp* x, r_ssize offset, sexp* y, r_ssize from, r_ssize n) { if ((r_length(x) - offset) < n) { r_abort("Can't copy data to `x` because it is too small"); } if ((r_length(y) - from) < n) { r_abort("Can't copy data from `y` because it is too small"); } switch (r_typeof(x)) { case LGLSXP: { int* src_data = LOGICAL(y); int* dest_data = LOGICAL(x); for (r_ssize i = 0; i != n; ++i) dest_data[i + offset] = src_data[i + from]; break; } case INTSXP: { int* src_data = INTEGER(y); int* dest_data = INTEGER(x); for (r_ssize i = 0; i != n; ++i) dest_data[i + offset] = src_data[i + from]; break; } case REALSXP: { double* src_data = REAL(y); double* dest_data = REAL(x); for (r_ssize i = 0; i != n; ++i) dest_data[i + offset] = src_data[i + from]; break; } case CPLXSXP: { r_complex_t* src_data = COMPLEX(y); r_complex_t* dest_data = COMPLEX(x); for (r_ssize i = 0; i != n; ++i) dest_data[i + offset] = src_data[i + from]; break; } case RAWSXP: { r_byte_t* src_data = RAW(y); r_byte_t* dest_data = RAW(x); for (r_ssize i = 0; i != n; ++i) dest_data[i + offset] = src_data[i + from]; break; } case STRSXP: { sexp* elt; for (r_ssize i = 0; i != n; ++i) { elt = STRING_ELT(y, i + from); SET_STRING_ELT(x, i + offset, elt); } break; } case VECSXP: { sexp* elt; for (r_ssize i = 0; i != n; ++i) { elt = VECTOR_ELT(y, i + from); SET_VECTOR_ELT(x, i + offset, elt); } break; } default: r_abort("Copy requires vectors"); } } void r_vec_poke_range(sexp* x, r_ssize offset, sexp* y, r_ssize from, r_ssize to) { r_vec_poke_n(x, offset, y, from, to - from + 1); } // Coercion ---------------------------------------------------------- sexp* rlang_vec_coercer(sexp* dest) { switch(r_typeof(dest)) { case LGLSXP: return rlang_ns_get("as_logical"); case INTSXP: return rlang_ns_get("as_integer"); case REALSXP: return rlang_ns_get("as_double"); case CPLXSXP: return rlang_ns_get("as_complex"); case STRSXP: return rlang_ns_get("as_character"); case RAWSXP: return rlang_ns_get("as_bytes"); default: r_abort("No coercion implemented for `%s`", Rf_type2str(r_typeof(dest))); } } void r_vec_poke_coerce_n(sexp* x, r_ssize offset, sexp* y, r_ssize from, r_ssize n) { if (r_typeof(y) == r_typeof(x)) { r_vec_poke_n(x, offset, y, from, n); return ; } if (r_is_object(y)) { r_abort("Can't splice S3 objects"); } // FIXME: This callbacks to rlang R coercers with an extra copy. sexp* coercer = rlang_vec_coercer(x); sexp* call = KEEP(Rf_lang2(coercer, y)); sexp* coerced = KEEP(r_eval(call, R_BaseEnv)); r_vec_poke_n(x, offset, coerced, from, n); FREE(2); } void r_vec_poke_coerce_range(sexp* x, r_ssize offset, sexp* y, r_ssize from, r_ssize to) { r_vec_poke_coerce_n(x, offset, y, from, to - from + 1); } rlang/src/lib/node.h0000644000176200001440000000370313457603056014024 0ustar liggesusers#ifndef RLANG_NODE_H #define RLANG_NODE_H static inline sexp* r_node_car(sexp* x) { return CAR(x); } static inline sexp* r_node_cdr(sexp* x) { return CDR(x); } static inline sexp* r_node_caar(sexp* x) { return CAAR(x); } static inline sexp* r_node_cadr(sexp* x) { return CADR(x); } static inline sexp* r_node_cdar(sexp* x) { return CDAR(x); } static inline sexp* r_node_cddr(sexp* x) { return CDDR(x); } static inline sexp* r_node_tail(sexp* x) { while (CDR(x) != R_NilValue) x = CDR(x); return x; } static inline sexp* r_node_poke_car(sexp* x, sexp* newcar) { SETCAR(x, newcar); return x; } static inline sexp* r_node_poke_cdr(sexp* x, sexp* newcdr) { SETCDR(x, newcdr); return x; } static inline sexp* r_node_poke_caar(sexp* x, sexp* newcaar) { SETCAR(CAR(x), newcaar); return x; } static inline sexp* r_node_poke_cadr(sexp* x, sexp* newcar) { SETCADR(x, newcar); return x; } static inline sexp* r_node_poke_cdar(sexp* x, sexp* newcdar) { SETCDR(CAR(x), newcdar); return x; } static inline sexp* r_node_poke_cddr(sexp* x, sexp* newcdr) { SETCDR(CDR(x), newcdr); return x; } static inline sexp* r_node_tag(sexp* x) { return TAG(x); } static inline sexp* r_node_poke_tag(sexp* x, sexp* tag) {SET_TAG(x, tag); return x; } static inline bool r_is_pairlist(sexp* x) { return TYPEOF(x) == LISTSXP; } static inline sexp* r_new_node(sexp* car, sexp* cdr) { return Rf_cons(car, cdr); } sexp* r_new_tagged_node(const char* tag, sexp* car, sexp* cdr); static inline sexp* r_pairlist(sexp* car) { return Rf_list1(car); } static inline sexp* r_pairlist2(sexp* car1, sexp* car2) { return Rf_list2(car1, car2); } static inline sexp* r_pairlist3(sexp* car1, sexp* car2, sexp* car3) { return Rf_list3(car1, car2, car3); } sexp* r_node_tree_clone(sexp* x); sexp* r_node_list_clone_until(sexp* node, sexp* sentinel, sexp** sentinel_out); sexp* r_node_list_find_tag(sexp* node, sexp* tag); sexp* r_node_list_reverse(sexp* node); #endif rlang/src/lib/env-binding.h0000644000176200001440000000051413405732277015275 0ustar liggesusers#ifndef RLANG_ENV_BINDING_H #define RLANG_ENV_BINDING_H enum r_env_binding_type { R_ENV_BINDING_VALUE = 0, R_ENV_BINDING_PROMISE, R_ENV_BINDING_ACTIVE, }; bool r_env_binding_is_promise(sexp* env, sexp* sym); bool r_env_binding_is_active(sexp* env, sexp* sym); sexp* r_env_binding_types(sexp* env, sexp* bindings); #endif rlang/src/lib/formula.c0000644000176200001440000000355013457603056014537 0ustar liggesusers#include "rlang.h" sexp* r_f_rhs(sexp* f) { if (r_typeof(f) != LANGSXP) { r_abort("`x` must be a formula"); } switch (r_length(f)) { case 2: return r_node_cadr(f); case 3: return CADDR(f); default: r_abort("Invalid formula"); } } sexp* r_f_lhs(sexp* f) { if (r_typeof(f) != LANGSXP) { r_abort("`x` must be a formula"); } switch (r_length(f)) { case 2: return r_null; case 3: return r_node_cadr(f); default: r_abort("Invalid formula"); } } sexp* r_f_env(sexp* f) { return r_get_attribute(f, r_sym(".Environment")); } bool r_f_has_env(sexp* f) { return r_is_environment(r_f_env(f)); } bool r_is_formulaish(sexp* x, int scoped, int lhs) { static const char* formulaish_names[2] = { "~", ":=" }; if (r_typeof(x) != LANGSXP) { return false; } sexp* head = r_node_car(x); if (!r_is_symbol_any(head, formulaish_names, 2)) { return false; } if (scoped >= 0) { int has_env = r_typeof(r_f_env(x)) == ENVSXP; if (scoped != has_env) { return false; } } if (lhs >= 0) { int has_lhs = r_length(x) > 2; if (lhs != has_lhs) { return false; } } return true; } sexp* new_raw_formula(sexp* lhs, sexp* rhs, sexp* env) { static sexp* tilde_sym = NULL; if (!tilde_sym) { tilde_sym = r_sym("~"); } if (!r_is_environment(env) && env != r_null) { r_abort("`env` must be an environment"); } sexp* f; sexp* args; if (lhs == r_null) { args = KEEP(r_pairlist(rhs)); } else { args = KEEP(r_pairlist2(lhs, rhs)); } f = KEEP(r_new_call(tilde_sym, args)); sexp* attrs = KEEP(r_new_node(env, r_null)); r_node_poke_tag(attrs, r_sym(".Environment")); r_poke_attributes(f, attrs); FREE(3); return f; } sexp* r_new_formula(sexp* lhs, sexp* rhs, sexp* env) { sexp* f = KEEP(new_raw_formula(lhs, rhs, env)); r_push_class(f, "formula"); FREE(1); return f; } rlang/src/lib/vec-lgl.c0000644000176200001440000000316013450627107014414 0ustar liggesusers#include "rlang.h" int r_as_optional_bool(sexp* lgl) { if (lgl == r_null) { return -1; } else { return r_lgl_get(lgl, 0); } } bool r_is_true(sexp* x) { if (!r_is_scalar_logical(x)) { return false; } else { int value = LOGICAL(x)[0]; return value == NA_LOGICAL ? 0 : value; } } r_ssize r_lgl_sum(sexp* x, bool na_true) { if (r_typeof(x) != r_type_logical) { r_abort("Internal error: Excepted logical vector in `r_lgl_sum()`"); } r_ssize n = r_vec_length(x); r_ssize sum = 0; int* ptr = r_lgl_deref(x); for (r_ssize i = 0; i < n; ++i, ++ptr) { // This can't overflow since `sum` is necessarily smaller or equal // to the vector length expressed in `r_ssize`. if (na_true && *ptr) { sum += 1; } else if (*ptr == 1) { sum += 1; } } return sum; } sexp* r_lgl_which(sexp* x, bool na_propagate) { if (r_typeof(x) != r_type_logical) { r_abort("Internal error: Expected logical vector in `r_lgl_which()`"); } r_ssize n = r_length(x); int* data = r_lgl_deref(x); r_ssize which_n = r_lgl_sum(x, na_propagate); if (which_n > INT_MAX) { r_abort("Internal error: Can't fit result of `r_lgl_which()` in an integer vector"); } sexp* which = KEEP(r_new_vector(r_type_integer, which_n)); int* which_data = r_int_deref(which); for (int i = 0; i < n; ++i, ++data) { int elt = *data; if (elt) { if (na_propagate && elt == NA_LOGICAL) { *which_data = NA_INTEGER; ++which_data; } else if (elt != NA_LOGICAL) { *which_data = i + 1; ++which_data; } } } FREE(1); return which; } rlang/src/lib/stack.c0000644000176200001440000000417013457603056014176 0ustar liggesusers#include "rlang.h" sexp* rlang_ns_get(const char* name); void r_on_exit(sexp* expr, sexp* frame) { static sexp* on_exit_prim = NULL; if (!on_exit_prim) { on_exit_prim = r_base_ns_get("on.exit"); } sexp* args = r_pairlist2(expr, r_lgl(1)); sexp* lang = KEEP(r_new_call(on_exit_prim, args)); r_eval(lang, frame); FREE(1); } static sexp* current_frame_call = NULL; sexp* r_current_frame() { return r_eval(current_frame_call, r_empty_env); } static sexp* sys_frame_call = NULL; static sexp* sys_call_call = NULL; static int* sys_frame_n_addr = NULL; static int* sys_call_n_addr = NULL; sexp* r_sys_frame(int n, sexp* frame) { int n_protect = 0; if (!frame) { frame = r_current_frame(); KEEP_N(frame, n_protect); } *sys_frame_n_addr = n; SEXP value = r_eval(sys_frame_call, frame); FREE(n_protect); return value; } sexp* r_sys_call(int n, sexp* frame) { int n_protect = 0; if (!frame) { frame = r_current_frame(); KEEP_N(frame, n_protect); } *sys_call_n_addr = n; SEXP value = r_eval(sys_call_call, frame); FREE(n_protect); return value; } static sexp* generate_sys_call(const char* name, int** n_addr) { sexp* sys_n = KEEP(r_int(0)); *n_addr = r_int_deref(sys_n); sexp* sys_args = KEEP(r_new_node(sys_n, r_null)); sexp* sys_call = KEEP(r_new_call(r_base_ns_get(name), sys_args)); r_mark_precious(sys_call); FREE(3); return sys_call; } void r_init_library_stack() { sexp* current_frame_args; current_frame_args = KEEP(r_int(-1)); current_frame_args = KEEP(r_new_node(current_frame_args, r_null)); sexp* current_frame_body = r_new_call(r_base_ns_get("sys.frame"), current_frame_args); sexp* current_frame_fn = KEEP(r_new_function(r_null, current_frame_body, r_empty_env)); current_frame_call = r_new_call(current_frame_fn, r_null); r_mark_precious(current_frame_call); FREE(3); sys_frame_call = generate_sys_call("sys.frame", &sys_frame_n_addr); sys_call_call = generate_sys_call("sys.call", &sys_call_n_addr); } rlang/src/lib/eval.c0000644000176200001440000000465413405732277014030 0ustar liggesusers#include "rlang.h" sexp* r_eval_with_x(sexp* call, sexp* parent, sexp* x) { sexp* env = KEEP(r_new_environment(parent, 1)); r_env_poke(env, r_x_sym, x); sexp* out = r_eval(call, env); FREE(1); return out; } sexp* r_eval_with_xy(sexp* call, sexp* parent, sexp* x, sexp* y) { sexp* env = KEEP(r_new_environment(parent, 1)); r_env_poke(env, r_x_sym, x); r_env_poke(env, r_y_sym, y); sexp* out = r_eval(call, env); FREE(1); return out; } sexp* r_eval_with_xyz(sexp* call, sexp* parent, sexp* x, sexp* y, sexp* z) { sexp* env = KEEP(r_new_environment(parent, 1)); r_env_poke(env, r_x_sym, x); r_env_poke(env, r_y_sym, y); r_env_poke(env, r_z_sym, z); sexp* out = r_eval(call, env); FREE(1); return out; } sexp* r_eval_with_wxyz(sexp* call, sexp* parent, sexp* w, sexp* x, sexp* y, sexp* z) { sexp* env = KEEP(r_new_environment(parent, 1)); r_env_poke(env, r_w_sym, w); r_env_poke(env, r_x_sym, x); r_env_poke(env, r_y_sym, y); r_env_poke(env, r_z_sym, z); sexp* out = r_eval(call, env); FREE(1); return out; } static sexp* shared_x_env; static sexp* shared_xy_env; static sexp* shared_xyz_env; // Evaluate call with a preallocated environment containing a single // `x` binding and inheriting from base env. // // Since this has side effects, it should not be used when there is a // chance of recursing into the C library. It should only be used to // evaluate pure R calls or functions from other packages, such as the // base package. sexp* eval_with_x(sexp* call, sexp* x) { r_env_poke(shared_x_env, r_x_sym, x); sexp* out = KEEP(r_eval(call, shared_x_env)); // Release for gc r_env_poke(shared_x_env, r_x_sym, r_null); FREE(1); return out; } sexp* eval_with_xy(sexp* call, sexp* x, sexp* y) { r_env_poke(shared_xy_env, r_x_sym, x); r_env_poke(shared_xy_env, r_y_sym, y); sexp* out = KEEP(r_eval(call, shared_xy_env)); // Release for gc r_env_poke(shared_xy_env, r_x_sym, r_null); r_env_poke(shared_xy_env, r_y_sym, r_null); FREE(1); return out; } sexp* eval_with_xyz(sexp* call, sexp* x, sexp* y, sexp* z) { r_env_poke(shared_xyz_env, r_x_sym, x); r_env_poke(shared_xyz_env, r_y_sym, y); r_env_poke(shared_xyz_env, r_z_sym, z); sexp* out = KEEP(r_eval(call, shared_xyz_env)); // Release for gc r_env_poke(shared_xyz_env, r_x_sym, r_null); r_env_poke(shared_xyz_env, r_y_sym, r_null); r_env_poke(shared_xyz_env, r_z_sym, r_null); FREE(1); return out; } rlang/src/lib/vec-list.h0000644000176200001440000000073513405732277014630 0ustar liggesusers#ifndef RLANG_VECTOR_LIST_H #define RLANG_VECTOR_LIST_H static inline sexp* r_list_get(sexp* list, r_ssize i) { return VECTOR_ELT(list, i); } static inline void r_list_poke(sexp* list, r_ssize i, sexp* elt) { SET_VECTOR_ELT(list, i, elt); } sexp* r_new_list(sexp* x, const char* name); static inline bool r_is_list(sexp* x, r_ssize n) { if (r_typeof(x) != r_type_list) { return false; } if (n < 0) { return true; } return r_length(x) == n; } #endif rlang/src/lib/eval.h0000644000176200001440000000064513405732277014031 0ustar liggesusers#ifndef RLANG_EVAL_H #define RLANG_EVAL_H static inline sexp* r_eval(sexp* expr, sexp* env) { return Rf_eval(expr, env); } sexp* r_eval_with_x(sexp* call, sexp* parent, sexp* x); sexp* r_eval_with_xy(sexp* call, sexp* parent, sexp* x, sexp* y); sexp* r_eval_with_xyz(sexp* call, sexp* parent, sexp* x, sexp* y, sexp* z); sexp* r_eval_with_wxyz(sexp* call, sexp* parent, sexp* w, sexp* x, sexp* y, sexp* z); #endif rlang/src/lib/env.h0000644000176200001440000000374213375013205013660 0ustar liggesusers#ifndef RLANG_ENV_H #define RLANG_ENV_H #include #include #define r_global_env R_GlobalEnv #define r_base_env R_BaseEnv #define r_empty_env R_EmptyEnv extern sexp* r_methods_ns_env; #if (!defined(R_VERSION) || R_VERSION < R_Version(3, 2, 0)) static inline sexp* r_env_names(sexp* env) { return R_lsInternal(env, true); } #else static inline sexp* r_env_names(sexp* env) { return R_lsInternal3(env, true, false); } #endif static inline r_ssize r_env_length(sexp* env) { if (r_typeof(env) != r_type_environment) { r_abort("Expected an environment"); } return Rf_xlength(env); } static inline sexp* r_env_parent(sexp* env) { return ENCLOS(env); } static inline void r_env_poke_parent(sexp* env, sexp* new_parent) { SET_ENCLOS(env, new_parent); } static inline bool r_is_environment(sexp* x) { return TYPEOF(x) == ENVSXP; } static inline bool r_is_namespace(sexp* x) { return R_IsNamespaceEnv(x); } static inline sexp* r_env_find(sexp* env, sexp* sym) { return Rf_findVarInFrame3(env, sym, FALSE); } static inline sexp* r_env_find_anywhere(sexp* env, sexp* sym) { return Rf_findVar(sym, env); } static inline bool r_env_has(sexp* env, sexp* sym) { return r_env_find(env, sym) != r_unbound_sym; } static inline bool r_env_has_anywhere(sexp* env, sexp* sym) { return r_env_find_anywhere(env, sym) != r_unbound_sym; } static inline sexp* r_env_poke(sexp* env, sexp* sym, sexp* value) { Rf_defineVar(sym, value, env); return env; } sexp* r_ns_env(const char* pkg); sexp* r_base_ns_get(const char* name); sexp* r_new_environment(sexp* parent, r_ssize size); sexp* r_env_as_list(sexp* x); sexp* r_list_as_environment(sexp* x, sexp* parent); sexp* r_env_clone(sexp* env, sexp* parent); sexp* r_env_unbind_names(sexp* env, sexp* names, bool inherits); sexp* r_env_unbind_all(sexp* env, const char** names, bool inherits); sexp* r_env_unbind(sexp* env, const char* name, bool inherits); bool r_env_inherits(sexp* env, sexp* ancestor, sexp* top); #endif rlang/src/lib/cnd.h0000644000176200001440000000173613403506710013635 0ustar liggesusers#ifndef RLANG_CND_H #define RLANG_CND_H #include void r_inform(const char* fmt, ...); void r_warn(const char* fmt, ...); void r_abort(const char* fmt, ...) __attribute__((noreturn)); void r_interrupt(); void r_signal_soft_deprecated(const char* msg, const char* id, sexp* env); void r_warn_deprecated(const char* id, const char* fmt, ...); void r_stop_defunct(const char* fmt, ...); sexp* r_interp_str(const char* fmt, ...); sexp* r_new_condition(sexp* type, sexp* msg, sexp* data); static inline bool r_is_condition(sexp* x) { return TYPEOF(x) == VECSXP && Rf_inherits(x, "condition"); } void r_cnd_signal(sexp* cnd); void r_cnd_inform(sexp* cnd, bool mufflable); void r_cnd_warn(sexp* cnd, bool mufflable); void r_cnd_abort(sexp* cnd, bool mufflable); enum r_condition_type { r_cnd_type_condition = 0, r_cnd_type_message = 1, r_cnd_type_warning = 2, r_cnd_type_error = 3, r_cnd_type_interrupt = 4 }; enum r_condition_type r_cnd_type(sexp* cnd); #endif rlang/src/lib/quo.c0000644000176200001440000000027113351410655013665 0ustar liggesusers#include "rlang.h" sexp* (*r_quo_get_expr)(sexp* quo); sexp* (*r_quo_set_expr)(sexp* quo, sexp* expr); sexp* (*r_quo_get_env)(sexp* quo); sexp* (*r_quo_set_env)(sexp* quo, sexp* env); rlang/src/lib/debug.c0000644000176200001440000000056213362570620014153 0ustar liggesusers#include "rlang.h" void r_sexp_inspect(sexp* x) { sexp* call = KEEP(r_parse(".Internal(inspect(x))")); r_eval_with_x(call, r_base_env, x); FREE(1); } void r_browse() { r_browse_at(KEEP(r_current_frame())); FREE(1); } void r_browse_at(sexp* env) { // The NULL expression is needed because of a limitation in ESS r_parse_eval("{ browser(); NULL }", env); } rlang/src/lib/sym.h0000644000176200001440000000170013457603056013702 0ustar liggesusers#ifndef RLANG_SYM_H #define RLANG_SYM_H #define r_unbound_sym R_UnboundValue #define r_missing_sym R_MissingArg #define r_names_sym R_NamesSymbol #define r_class_sym R_ClassSymbol #define r_dots_sym R_DotsSymbol #define r_namespace_sym R_DoubleColonSymbol #define r_namespace3_sym R_TripleColonSymbol extern sexp* r_dot_environment_sym; extern sexp* r_function_sym; extern sexp* r_srcref_sym; extern sexp* r_tilde_sym; extern sexp* r_w_sym; extern sexp* r_x_sym; extern sexp* r_y_sym; extern sexp* r_z_sym; sexp* r_new_symbol(sexp* x, int* err); static inline sexp* r_sym(const char* c_string) { return Rf_install(c_string); } static inline sexp* r_sym_get_string(sexp* sym) { return PRINTNAME(sym); } static inline const char* r_sym_get_c_string(sexp* sym) { return CHAR(PRINTNAME(sym)); } bool r_is_symbol(sexp* sym, const char* string); bool r_is_symbol_any(sexp* x, const char** strings, int n); bool r_is_special_op_sym(sexp* x); #endif rlang/src/lib/vec-chr.h0000644000176200001440000000351013457603056014422 0ustar liggesusers#ifndef RLANG_VECTOR_CHR_H #define RLANG_VECTOR_CHR_H #include #define r_missing_str R_NaString extern sexp* r_shared_empty_chr; extern sexp* r_empty_str; static inline sexp* r_chr_get(sexp* chr, r_ssize i) { return STRING_ELT(chr, i); } static inline void r_chr_poke(sexp* chr, r_ssize i, sexp* elt) { SET_STRING_ELT(chr, i, elt); } static inline const char* r_str_deref(sexp* str) { return CHAR(str); } static inline const char* r_chr_get_c_string(sexp* chr, r_ssize i) { return CHAR(r_chr_get(chr, i)); } static inline sexp* r_nms_get(sexp* nms, r_ssize i) { if (nms == r_null) { return r_empty_str; } else { return r_chr_get(nms, i); } } bool r_chr_has(sexp* chr, const char* c_string); bool r_chr_has_any(sexp* chr, const char** c_strings); r_ssize r_chr_detect_index(sexp* chr, const char* c_string); sexp* r_new_character(const char** strings); static inline sexp* r_string(const char* c_string) { return Rf_mkChar(c_string); } static inline sexp* r_chr(const char* c_string) { return Rf_mkString(c_string); } sexp* chr_prepend(sexp* chr, sexp* r_string); sexp* chr_append(sexp* chr, sexp* r_string); sexp* r_nms_are_duplicated(sexp* nms, bool from_last); sexp* r_str_unserialise_unicode(sexp* r_string); static inline bool r_is_string(sexp* x, const char* string) { if (r_typeof(x) != r_type_character || r_length(x) != 1) { return false; } if (string && strcmp(r_chr_get_c_string(x, 0), string) != 0) { return false; } return true; } static inline sexp* r_str_as_symbol(sexp* str) { return r_sym(Rf_translateChar(str)); } static inline sexp* r_str_as_character(sexp* x) { return Rf_ScalarString(x); } static inline bool r_str_is_name(sexp* str) { if (str == r_missing_str) { return false; } if (str == r_empty_str) { return false; } return true; } #endif rlang/src/lib/squash.h0000644000176200001440000000022313457603056014375 0ustar liggesusers#ifndef RLANG_SQUASH_H #define RLANG_SQUASH_H sexp* r_squash_if(sexp* dots, enum r_type kind, bool (*is_spliceable)(sexp*), int depth); #endif rlang/src/lib/vec.h0000644000176200001440000000733713457603056013663 0ustar liggesusers#ifndef RLANG_VECTOR_H #define RLANG_VECTOR_H r_ssize r_vec_length(sexp* x); static inline int* r_lgl_deref(sexp* x) { return LOGICAL(x); } static inline int* r_int_deref(sexp* x) { return INTEGER(x); } static inline double* r_dbl_deref(sexp* x) { return REAL(x); } static inline r_complex_t* r_cpl_deref(sexp* x) { return COMPLEX(x); } static inline r_byte_t* r_raw_deref(sexp* x) { return RAW(x); } static inline sexp** r_chr_deref(sexp* x) { return STRING_PTR(x); } static inline sexp** r_list_deref(sexp* x) { return VECTOR_PTR(x); } static inline void r_vec_get_check(sexp*x, r_ssize i, const char* fn) { if ((r_length(x) - 1) < i) { r_abort("Internal error in `%s()`: Vector is too small", fn); } } static inline int r_lgl_get(sexp* x, r_ssize i) { r_vec_get_check(x, i, "r_lgl_get"); return LOGICAL(x)[i]; } static inline int r_int_get(sexp* x, r_ssize i) { r_vec_get_check(x, i, "r_int_get"); return INTEGER(x)[i]; } static inline double r_dbl_get(sexp* x, r_ssize i) { r_vec_get_check(x, i, "r_dbl_get"); return REAL(x)[i]; } static inline r_complex_t r_cpl_get(sexp* x, r_ssize i) { r_vec_get_check(x, i, "r_cpl_get"); return COMPLEX(x)[i]; } static inline r_byte_t r_raw_get(sexp* x, r_ssize i) { r_vec_get_check(x, i, "r_raw_get"); return RAW(x)[i]; } static inline void r_lgl_poke(sexp* x, r_ssize i, int y) { r_vec_get_check(x, i, "r_lgl_poke"); LOGICAL(x)[i] = y; } static inline void r_int_poke(sexp* x, r_ssize i, int y) { r_vec_get_check(x, i, "r_int_poke"); INTEGER(x)[i] = y; } static inline void r_dbl_poke(sexp* x, r_ssize i, double y) { r_vec_get_check(x, i, "r_dbl_poke"); REAL(x)[i] = y; } static inline void r_cpl_poke(sexp* x, r_ssize i, r_complex_t y) { r_vec_get_check(x, i, "r_cpl_poke"); COMPLEX(x)[i] = y; } static inline void r_raw_poke(sexp* x, r_ssize i, r_byte_t y) { r_vec_get_check(x, i, "r_raw_poke"); RAW(x)[i] = y; } sexp* r_vec_get(sexp* vec, r_ssize i); bool r_is_vector(sexp* x, r_ssize n); bool r_is_scalar_atomic(sexp* x); bool r_is_atomic(sexp* x, r_ssize n); bool r_is_finite(sexp* x); bool r_is_logical(sexp* x, r_ssize n); bool r_is_integerish(sexp* x, r_ssize n, int finite); bool r_is_integer(sexp* x, r_ssize n, int finite); bool r_is_double(sexp* x, r_ssize n, int finite); bool r_is_character(sexp* x, r_ssize n); bool r_is_raw(sexp* x, r_ssize n); static inline bool r_is_scalar_character(sexp* x) { return r_typeof(x) == r_type_character && r_length(x) == 1; } static inline bool r_is_scalar_logical(sexp* x) { return r_typeof(x) == r_type_logical && r_length(x) == 1; } static inline sexp* r_int(int x) { return Rf_ScalarInteger(x); } static inline sexp* r_new_vector(enum r_type type, r_ssize n) { return Rf_allocVector(type, n); } static inline sexp* r_vec_coerce(sexp* x, enum r_type to) { return Rf_coerceVector(x, to); } void r_vec_poke_n(sexp* x, r_ssize offset, sexp* y, r_ssize from, r_ssize n); void r_vec_poke_range(sexp* x, r_ssize offset, sexp* y, r_ssize from, r_ssize to); void r_vec_poke_coerce_n(sexp* x, r_ssize offset, sexp* y, r_ssize from, r_ssize n); void r_vec_poke_coerce_range(sexp* x, r_ssize offset, sexp* y, r_ssize from, r_ssize to); static inline bool r_vec_find_first_duplicate(sexp* x, sexp* except, r_ssize* index) { r_ssize idx; if (except) { idx = Rf_any_duplicated3(x, except, false); } else { idx = Rf_any_duplicated(x, false); } if (idx) { if (index) { *index = idx - 1; } return true; } else { return false; } } static inline sexp* r_vec_are_duplicated(sexp* x) { return Rf_duplicated(x, false); } bool r_vec_find_first_identical_any(sexp* x, sexp* y, r_ssize* index); #endif rlang/src/lib/export.h0000644000176200001440000000212513405732277014416 0ustar liggesusers#ifndef RLANG_EXPORT_H #define RLANG_EXPORT_H #include #include #if (defined(R_VERSION) && R_VERSION < R_Version(3, 4, 0)) typedef union {void* p; DL_FUNC fn;} fn_ptr; sexp* R_MakeExternalPtrFn(DL_FUNC p, sexp* tag, sexp* prot); DL_FUNC R_ExternalPtrAddrFn(sexp* s); #endif typedef DL_FUNC r_fn_ptr; typedef R_CallMethodDef r_callable; typedef R_ExternalMethodDef r_external; typedef DllInfo r_dll_info; void rlang_register_pointer(const char* ns, const char* ptr_name, DL_FUNC fn); static inline void r_register_c_callable(const char* pkg, const char* ptr_name, r_fn_ptr fn) { R_RegisterCCallable(pkg, ptr_name, fn); } static inline void r_register_r_callables(r_dll_info* dll, const r_callable* const callables, const r_external* const externals) { R_registerRoutines(dll, NULL, callables, NULL, externals); R_useDynamicSymbols(dll, FALSE); } static inline r_fn_ptr r_peek_c_callable(const char* pkg, const char* callable) { return R_GetCCallable(pkg, callable); } #endif rlang/src/lib/env.c0000644000176200001440000001265013551606443013661 0ustar liggesusers#include "rlang.h" #include sexp* eval_with_x(sexp* call, sexp* x); sexp* eval_with_xy(sexp* call, sexp* x, sexp* y); sexp* eval_with_xyz(sexp* call, sexp* x, sexp* y, sexp* z); sexp* r_ns_env(const char* pkg) { sexp* ns = r_env_find(R_NamespaceRegistry, r_sym(pkg)); if (ns == r_unbound_sym) { r_abort("Can't find namespace `%s`", pkg); } return ns; } static sexp* ns_env_get(sexp* env, const char* name) { sexp* obj = KEEP(r_env_find(env, r_sym(name))); // Can be a promise to a lazyLoadDBfetch() call if (r_typeof(obj) == PROMSXP) { obj = r_eval(obj, r_empty_env); } if (obj != r_unbound_sym) { FREE(1); return obj; } // Trigger object not found error r_eval(r_sym(name), env); r_abort("Internal error: `ns_env_get()` should have failed earlier"); } sexp* r_base_ns_get(const char* name) { return ns_env_get(r_base_env, name); } static sexp* rlang_ns_env = NULL; sexp* rlang_ns_get(const char* name) { return ns_env_get(rlang_ns_env, name); } static sexp* new_env_call = NULL; static sexp* new_env__parent_node = NULL; static sexp* new_env__size_node = NULL; sexp* r_new_environment(sexp* parent, r_ssize size) { parent = parent ? parent : r_empty_env; r_node_poke_car(new_env__parent_node, parent); size = size ? size : 29; r_node_poke_car(new_env__size_node, r_int(size)); sexp* env = r_eval(new_env_call, r_base_env); // Free for gc r_node_poke_car(new_env__parent_node, r_null); return env; } static sexp* env2list_call = NULL; static sexp* list2env_call = NULL; sexp* r_env_as_list_compat(sexp* env, sexp* out); sexp* r_env_as_list(sexp* env) { sexp* out = KEEP(eval_with_x(env2list_call, env)); #if R_VERSION < R_Version(4, 0, 0) out = r_env_as_list_compat(env, out); #endif FREE(1); return out; } // On R < 4.0, the active binding function is returned instead of // its value. We invoke the active bindings here to get consistent // behaviour in all supported R versions. sexp* r_env_as_list_compat(sexp* env, sexp* out) { sexp* nms = KEEP(r_env_names(env)); sexp* types = KEEP(r_env_binding_types(env, nms)); if (types == R_NilValue) { FREE(2); return out; } r_ssize n = r_length(nms); sexp** nms_ptr = r_chr_deref(nms); int* types_ptr = r_int_deref(types); for (r_ssize i = 0; i < n; ++i, ++nms_ptr, ++types_ptr) { enum r_env_binding_type type = *types_ptr; if (type == R_ENV_BINDING_ACTIVE) { r_ssize fn_idx = r_chr_detect_index(nms, r_str_deref(*nms_ptr)); if (fn_idx < 0) { r_abort("Internal error: Can't find active binding in list"); } sexp* fn = r_list_get(out, fn_idx); sexp* value = r_eval(KEEP(r_call(fn)), r_empty_env); r_list_poke(out, fn_idx, value); FREE(1); } } FREE(2); return out; } sexp* r_list_as_environment(sexp* x, sexp* parent) { parent = parent ? parent : r_empty_env; return eval_with_xy(list2env_call, x, parent); } sexp* r_env_clone(sexp* env, sexp* parent) { if (parent == NULL) { parent = r_env_parent(env); } sexp* out = KEEP(r_env_as_list(env)); out = r_list_as_environment(out, parent); FREE(1); return out; } static sexp* remove_call = NULL; sexp* r_env_unbind_names(sexp* env, sexp* names, bool inherits) { return eval_with_xyz(remove_call, env, names, inherits ? r_shared_true : r_shared_false); } sexp* rlang_env_unbind(sexp* env, sexp* names, sexp* inherits) { if (r_typeof(env) != r_type_environment) { r_abort("`env` must be an environment"); } if (r_typeof(names) != r_type_character) { r_abort("`names` must be a character vector"); } if (!r_is_scalar_logical(inherits)) { r_abort("`inherits` must be a scalar logical vector"); } return r_env_unbind_names(env, names, *r_lgl_deref(inherits)); } sexp* r_env_unbind_all(sexp* env, const char** names, bool inherits) { sexp* nms = KEEP(r_new_character(names)); sexp* out = r_env_unbind_names(env, nms, inherits); FREE(1); return out; } sexp* r_env_unbind(sexp* env, const char* name, bool inherits) { static const char* names[2] = { "", NULL }; names[0] = name; return r_env_unbind_all(env, names, inherits); } bool r_env_inherits(sexp* env, sexp* ancestor, sexp* top) { top = top ? top : r_empty_env; if (r_typeof(env) != r_type_environment) { r_abort("`env` must be an environment"); } if (r_typeof(ancestor) != r_type_environment) { r_abort("`ancestor` must be an environment"); } if (r_typeof(top) != r_type_environment) { r_abort("`top` must be an environment"); } if (env == r_empty_env) { return false; } while (env != top && env != r_empty_env) { if (env == ancestor) { return true; } env = r_env_parent(env);; } return env == ancestor; } void r_init_rlang_ns_env() { rlang_ns_env = r_ns_env("rlang"); } sexp* r_methods_ns_env = NULL; void r_init_library_env() { new_env_call = r_parse_eval("as.call(list(new.env, TRUE, NULL, NULL))", r_base_env); r_mark_precious(new_env_call); new_env__parent_node = r_node_cddr(new_env_call); new_env__size_node = r_node_cdr(new_env__parent_node); env2list_call = r_parse("as.list.environment(x, all.names = TRUE)"); r_mark_precious(env2list_call); list2env_call = r_parse("list2env(x, envir = NULL, parent = y, hash = TRUE)"); r_mark_precious(list2env_call); remove_call = r_parse("remove(list = y, envir = x, inherits = z)"); r_mark_precious(remove_call); r_methods_ns_env = r_parse_eval("asNamespace('methods')", r_base_env); } rlang/src/lib/session.c0000644000176200001440000000126413405732277014556 0ustar liggesusers#include "rlang.h" sexp* eval_with_x(sexp* call, sexp* x); static sexp* is_installed_call = NULL; bool r_is_installed(const char* pkg) { sexp* installed = eval_with_x(is_installed_call, KEEP(r_chr(pkg))); bool out = *r_lgl_deref(installed); FREE(1); return out; } static sexp* has_colour_call = NULL; bool r_has_colour() { if (!r_is_installed("crayon")) { return false; } return *r_lgl_deref(r_eval(has_colour_call, r_base_env)); } void r_init_library_session() { is_installed_call = r_parse("requireNamespace(x, quietly = TRUE)"); r_mark_precious(is_installed_call); has_colour_call = r_parse("crayon::has_color()"); r_mark_precious(has_colour_call); } rlang/src/lib/node.c0000644000176200001440000000420313457603056014013 0ustar liggesusers#include "rlang.h" sexp* r_new_tagged_node(const char* tag, sexp* car, sexp* cdr) { sexp* node = KEEP(r_new_node(car, cdr)); r_node_poke_tag(node, r_sym(tag)); FREE(1); return node; } // Shallow copy of a node tree sexp* r_node_tree_clone(sexp* x) { if (r_typeof(x) != r_type_pairlist) { r_abort("Internal error: Expected node tree for shallow copy"); } x = KEEP(r_duplicate(x, true)); sexp* rest = x; while (rest != r_null) { sexp* head = r_node_car(rest); if (r_typeof(head) == r_type_pairlist) { r_node_poke_car(rest, r_node_tree_clone(head)); } rest = r_node_cdr(rest); } FREE(1); return x; } /** * - If `sentinel` is found in the first node: `parent_out` is `r_null` * - If `sentinel` is not found: both return value and `parent_out` * are `r_null` * - If `sentinel` is `r_null`, this is like a full shallow duplication * but returns tail node */ sexp* r_node_list_clone_until(sexp* node, sexp* sentinel, sexp** parent_out) { sexp* parent = r_null; sexp* cur = node; int n_protect = 0; while (true) { if (cur == sentinel) { FREE(n_protect); *parent_out = parent; return node; } // Return NULL if sentinel is not found if (cur == r_null) { FREE(n_protect); *parent_out = r_null; return r_null; } sexp* tag = r_node_tag(cur); cur = r_new_node(r_node_car(cur), r_node_cdr(cur)); r_node_poke_tag(cur, tag); if (parent == r_null) { KEEP_N(cur, n_protect); node = cur; } else { r_node_poke_cdr(parent, cur); } parent = cur; cur = r_node_cdr(cur); } r_abort("Internal error in r_node_list_clone_until()"); } sexp* r_node_list_find_tag(sexp* node, sexp* tag) { while (node != r_null) { if (r_node_tag(node) == tag) { return node; } node = r_node_cdr(node); } return r_null; } sexp* r_node_list_reverse(sexp* node) { if (node == r_null) { return node; } sexp* prev = r_null; sexp* tail = node; sexp* next; while (tail != r_null) { next = r_node_cdr(tail); r_node_poke_cdr(tail, prev); prev = tail; tail = next; } return prev; } rlang/src/lib/rlang.c0000644000176200001440000000540713457603056014200 0ustar liggesusers#include // Allows long vectors to be indexed with doubles r_ssize r_as_ssize(sexp* n) { switch (r_typeof(n)) { case r_type_double: { if (r_length(n) != 1) { goto invalid; } double out = r_dbl_get(n, 0); if (out > R_SSIZE_MAX) { r_abort("`n` is too large a number"); } return (r_ssize) floor(out); } case r_type_integer: { if (r_length(n) != 1) { goto invalid; } return (r_ssize) r_int_get(n, 0); } invalid: default: r_abort("Expected a scalar integer or double"); } } void r_init_rlang_ns_env(); void r_init_library_cnd(); void r_init_library_env(); void r_init_library_session(); void r_init_library_squash(); void r_init_library_stack(); void r_init_library_sym(); void r_init_library_vec_chr(); sexp* r_shared_true; sexp* r_shared_false; static sexp* shared_x_env; static sexp* shared_xy_env; static sexp* shared_xyz_env; // This *must* be called before making any calls to the functions // provided in the library. Register this function in your init file // and `.Call()` it from your `.onLoad()` hook. SEXP r_init_library() { r_init_library_sym(); // Needs to be first r_init_rlang_ns_env(); r_init_library_cnd(); r_init_library_env(); r_init_library_session(); r_init_library_squash(); r_init_library_stack(); r_init_library_vec_chr(); r_shared_true = r_new_vector(r_type_logical, 1); r_mark_precious(r_shared_true); r_mark_shared(r_shared_true); *r_lgl_deref(r_shared_true) = 1; r_shared_false = r_new_vector(r_type_logical, 1); r_mark_precious(r_shared_false); r_mark_shared(r_shared_false); *r_lgl_deref(r_shared_false) = 0; shared_x_env = r_parse_eval("new.env(hash = FALSE, parent = baseenv(), size = 1L)", r_base_env); r_mark_precious(shared_x_env); shared_xy_env = r_parse_eval("new.env(hash = FALSE, parent = baseenv(), size = 1L)", r_base_env); r_mark_precious(shared_xy_env); shared_xyz_env = r_parse_eval("new.env(hash = FALSE, parent = baseenv(), size = 1L)", r_base_env); r_mark_precious(shared_xyz_env); r_quo_get_expr = (sexp* (*)(sexp*)) r_peek_c_callable("rlang", "rlang_quo_get_expr"); r_quo_set_expr = (sexp* (*)(sexp*, sexp*)) r_peek_c_callable("rlang", "rlang_quo_set_expr"); r_quo_get_env = (sexp* (*)(sexp*)) r_peek_c_callable("rlang", "rlang_quo_get_env"); r_quo_set_env = (sexp* (*)(sexp*, sexp*)) r_peek_c_callable("rlang", "rlang_quo_set_env"); /* parse.c - r_ops_precedence[] */ RLANG_ASSERT((sizeof(r_ops_precedence) / sizeof(struct r_op_precedence)) == R_OP_MAX); for (int i = R_OP_NONE + 1; i < R_OP_MAX; ++i) { if (r_ops_precedence[i].power == 0) { r_abort("Internal error: `r_ops_precedence` is not fully initialised"); } } // Return a SEXP so the init function can be called from R return r_null; } rlang/src/lib/debug.h0000644000176200001440000000023413405732277014162 0ustar liggesusers#ifndef RLANG_DEBUG_H #define RLANG_DEBUG_H #define r_printf Rprintf void r_sexp_inspect(sexp* x); void r_browse(); void r_browse_at(sexp* env); #endif rlang/src/lib/sym-unescape.c0000644000176200001440000001025713607605214015500 0ustar liggesusers#include "rlang.h" #include #include #include // Interface functions --------------------------------------------------------- void copy_character(sexp* tgt, sexp* src, R_xlen_t len); R_xlen_t unescape_character_in_copy(sexp* tgt, sexp* src, R_xlen_t i); sexp* rlang_symbol(sexp* chr) { // Uses installChar(), no translation. Translating causes issues // when converting back to character. return r_vec_coerce(chr, r_type_symbol); } sexp* rlang_symbol_to_character(sexp* chr) { sexp* name = PRINTNAME(chr); return r_str_as_character(r_str_unserialise_unicode(name)); } sexp* rlang_unescape_character(sexp* chr) { R_xlen_t len = Rf_xlength(chr); R_xlen_t i = unescape_character_in_copy(r_null, chr, 0); if (i == len) return chr; sexp* ret = KEEP(r_new_vector(STRSXP, len)); copy_character(ret, chr, i); unescape_character_in_copy(ret, chr, i); FREE(1); return ret; } // Private functions ----------------------------------------------------------- static sexp* unescape_char_to_sexp(char* tmp); static bool has_unicode_escape(const char* chr); static int unescape_char(char* chr); static int unescape_char_found(char* chr); static int process_byte(char* tgt, char* const src, int* len_processed); static bool has_codepoint(const char* src); static bool is_hex(const char chr); void copy_character(sexp* tgt, sexp* src, R_xlen_t len) { for (int i = 0; i < len; ++i) { SET_STRING_ELT(tgt, i, STRING_ELT(src, i)); } } R_xlen_t unescape_character_in_copy(sexp* tgt, sexp* src, R_xlen_t i) { R_xlen_t len = r_length(src); int dry_run = Rf_isNull(tgt); for (; i < len; ++i) { sexp* old_elt = STRING_ELT(src, i); sexp* new_elt = r_str_unserialise_unicode(old_elt); if (dry_run) { if (old_elt != new_elt) return i; } else { SET_STRING_ELT(tgt, i, new_elt); } } return i; } sexp* r_str_unserialise_unicode(sexp* r_string) { int ce = Rf_getCharCE(r_string); const char* src = CHAR(r_string); if (!has_unicode_escape(src)) { return r_string; } const char* re_enc = Rf_reEnc(src, ce, CE_UTF8, 0); if (re_enc == src) { // The string was not copied because we're in a UTF-8 locale. // Need to check first if the string has any UTF-8 escapes. int orig_len = strlen(re_enc); char tmp[orig_len + 1]; memcpy(tmp, re_enc, orig_len + 1); return unescape_char_to_sexp(tmp); } else { // The string has been copied so it's safe to use as buffer char* tmp = (char*)re_enc; return unescape_char_to_sexp(tmp); } } static sexp* unescape_char_to_sexp(char* tmp) { int len = unescape_char(tmp); return Rf_mkCharLenCE(tmp, len, CE_UTF8); } static bool has_unicode_escape(const char* chr) { while (*chr) { if (has_codepoint(chr)) { return true; } ++chr; } return false; } static int unescape_char(char* chr) { int len = 0; while (*chr) { if (has_codepoint(chr)) { return len + unescape_char_found(chr); } else { ++chr; ++len; } } return len; } static int unescape_char_found(char* chr) { char* source = chr; char* target = chr; int len = 0; while (*source) { int len_processed; int len_new = process_byte(target, source, &len_processed); source += len_processed; target += len_new; len += len_new; } *target = 0; return len; } static int process_byte(char* tgt, char* const src, int* len_processed) { if (!has_codepoint(src)) { // Copy only the first character (angle bracket or not), advance *tgt = *src; *len_processed = 1; return 1; } unsigned int codepoint = strtoul(src + strlen(""); // We have 8 bytes space, codepoints occupy less than that: return (int)Rf_ucstoutf8(tgt, codepoint); } static bool has_codepoint(const char* src) { if (src[0] != '<') return false; if (src[1] != 'U') return false; if (src[2] != '+') return false; for (int i = 3; i < 7; ++i) { if (!is_hex(src[i])) return false; } if (src[7] != '>') return false; return true; } static bool is_hex(const char chr) { if (chr >= '0' && chr <= '9') return true; if (chr >= 'A' && chr <= 'F') return true; return false; } rlang/src/lib/attrs.c0000644000176200001440000000615013351410763014220 0ustar liggesusers#include "rlang.h" extern sexp* rlang_get_attributes(sexp* x); extern sexp* r_poke_attributes(sexp* x, sexp* attrs); sexp* r_push_attribute(sexp* x, sexp* tag, sexp* value) { sexp* attrs = r_new_node(value, r_get_attributes(x)); r_node_poke_tag(attrs, tag); r_poke_attributes(x, attrs); return attrs; } // Unlike Rf_getAttrib(), this never allocates sexp* r_get_attribute(sexp* x, sexp* tag) { sexp* attrs = r_get_attributes(x); while (attrs != r_null) { if (r_node_tag(attrs) == tag) { sexp* attr = r_node_car(attrs); r_mark_shared(attr); return attr; } attrs = r_node_cdr(attrs); } return r_null; } sexp* r_attrs_set_at(sexp* attrs, sexp* node, sexp* value) { sexp* sentinel = r_node_cdr(node); sexp* new_node = r_null; attrs = KEEP(r_node_list_clone_until(attrs, sentinel, &new_node)); r_node_poke_car(new_node, value); FREE(1); return attrs; } sexp* r_attrs_zap_at(sexp* attrs, sexp* node, sexp* value) { sexp* sentinel = node; sexp* new_node = r_null; attrs = KEEP(r_node_list_clone_until(attrs, sentinel, &new_node)); if (new_node == r_null) { // `node` is the first node of `attrs` attrs = r_node_cdr(attrs); } else { r_node_poke_cdr(new_node, r_node_cdr(node)); } FREE(1); return attrs; } sexp* r_clone2(sexp* x) { sexp* attrs = r_get_attributes(x); // Prevent attributes from being cloned r_poke_attributes(x, r_null); sexp* out = r_duplicate(x, true); r_poke_attributes(x, attrs); r_poke_attributes(out, attrs); return out; } sexp* r_set_attribute(sexp* x, sexp* tag, sexp* value) { sexp* attrs = r_get_attributes(x); sexp* out = KEEP(r_clone2(x)); sexp* node = attrs; while (node != r_null) { if (r_node_tag(node) == tag) { if (value == r_null) { attrs = r_attrs_zap_at(attrs, node, value); } else { attrs = r_attrs_set_at(attrs, node, value); } r_poke_attributes(out, attrs); FREE(1); return out; } node = r_node_cdr(node); } if (value != r_null) { // Just add to the front if attribute does not exist yet attrs = KEEP(r_new_node(out, attrs)); r_node_poke_tag(attrs, tag); r_node_poke_car(attrs, value); r_poke_attributes(out, attrs); FREE(1); } FREE(1); return out; } /** * With push_ prefix, assumes there is no `class` attribute in the * node list merge. This is for low-level construction of objects. */ // Caller must poke the object bit sexp* r_node_push_classes(sexp* node, const char** tags) { sexp* tags_chr = KEEP(r_new_character(tags)); sexp* attrs = r_new_node(tags_chr, node); r_node_poke_tag(attrs, r_class_sym); FREE(1); return attrs; } sexp* r_node_push_class(sexp* x, const char* tag) { static const char* tags[2] = { "", NULL }; tags[0] = tag; return r_node_push_classes(x, tags); } void r_push_classes(sexp* x, const char** tags) { sexp* attrs = r_get_attributes(x); attrs = r_node_push_classes(attrs, tags); SET_ATTRIB(x, attrs); SET_OBJECT(x, 1); } void r_push_class(sexp* x, const char* tag) { static const char* tags[2] = { "", NULL }; tags[0] = tag; r_push_classes(x, tags); } rlang/src/lib/fn.c0000644000176200001440000000044513351410763013467 0ustar liggesusers#include "rlang.h" sexp* r_new_function(sexp* formals, sexp* body, sexp* env) { sexp* args = KEEP(r_new_node(body, r_null)); args = KEEP(r_new_node(formals, args)); sexp* lang = KEEP(r_new_call(r_function_sym, args)); sexp* fn = r_eval(lang, r_base_env); FREE(3); return fn; } rlang/src/lib/lang.h0000644000176200001440000000126013457603056014014 0ustar liggesusers#ifndef RLANG_LANG_H #define RLANG_LANG_H #include "node.h" #define r_new_call Rf_lcons #define r_call Rf_lang1 #define r_call2 Rf_lang2 #define r_call3 Rf_lang3 bool r_is_call(sexp* x, const char* name); bool r_is_call_any(sexp* x, const char** names, int n); bool r_is_prefixed_call(sexp* x, const char* name); bool r_is_prefixed_call_any(sexp* x, const char ** names, int n); bool r_is_maybe_prefixed_call_any(sexp* x, const char ** names, int n); bool r_is_namespaced_call(sexp* x, const char* ns, const char* name); bool r_is_namespaced_call_any(sexp* x, const char* ns, const char** names, int n); bool r_is_special_op_call(sexp* x); sexp* r_expr_protect(sexp* x); #endif rlang/src/lib/vec-list.c0000644000176200001440000000050613351410655014610 0ustar liggesusers#include "rlang.h" sexp* r_new_list(sexp* x, const char* name) { sexp* out = KEEP(r_new_vector(r_type_list, 1)); r_list_poke(out, 0, x); if (name) { sexp* nms = KEEP(r_new_vector(r_type_character, 1)); r_push_names(x, nms); r_chr_poke(nms, 0, r_string(name)); FREE(1); } FREE(1); return out; } rlang/src/lib/session.h0000644000176200001440000000016613405732277014563 0ustar liggesusers#ifndef RLANG_SESSION_H #define RLANG_SESSION_H bool r_is_installed(const char* pkg); bool r_has_colour(); #endif rlang/src/lib/sexp.c0000644000176200001440000000055413457603056014052 0ustar liggesusers#include "rlang.h" bool r_is_named(sexp* x) { sexp* nms = r_vec_names(x); if (r_typeof(nms) != STRSXP) { return false; } if (r_chr_has(nms, "")) { return false; } return true; } bool r_has_name_at(sexp* x, r_ssize i) { sexp* nms = r_vec_names(x); return r_typeof(nms) == r_type_character && r_chr_get(nms, i) != r_empty_str; } rlang/src/lib/squash.c0000644000176200001440000002060613610366361014373 0ustar liggesusers#include "rlang.h" #include "export.h" // Initialised at load time static bool (*rlang_is_splice_box)(sexp*) = NULL; static sexp* (*rlang_unbox)(sexp*) = NULL; // The vector to splice might be boxed in a sentinel wrapper static sexp* maybe_unbox(sexp* x, bool (*is_spliceable)(sexp*)) { if (is_spliceable(x) && rlang_is_splice_box(x)) { return r_vec_coerce(rlang_unbox(x), r_type_list); } else { return x; } } typedef struct { r_ssize size; bool named; bool warned; bool recursive; } squash_info_t; static squash_info_t squash_info_init(bool recursive) { squash_info_t info; info.size = 0; info.named = false; info.warned = false; info.recursive = recursive; return info; } // Atomic squashing --------------------------------------------------- static r_ssize atom_squash(enum r_type kind, squash_info_t info, sexp* outer, sexp* out, r_ssize count, bool (*is_spliceable)(sexp*), int depth) { if (r_typeof(outer) != VECSXP) { r_abort("Only lists can be spliced"); } sexp* inner; sexp* out_names = KEEP(r_vec_names(out)); r_ssize n_outer = r_length(outer); r_ssize n_inner; for (r_ssize i = 0; i != n_outer; ++i) { inner = VECTOR_ELT(outer, i); n_inner = r_vec_length(maybe_unbox(inner, is_spliceable)); if (depth != 0 && is_spliceable(inner)) { inner = PROTECT(maybe_unbox(inner, is_spliceable)); count = atom_squash(kind, info, inner, out, count, is_spliceable, depth - 1); UNPROTECT(1); } else if (n_inner) { r_vec_poke_coerce_n(out, count, inner, 0, n_inner); if (info.named) { sexp* nms = r_vec_names(inner); if (r_typeof(nms) == r_type_character) { r_vec_poke_n(out_names, count, nms, 0, n_inner); } else if (n_inner == 1 && r_has_name_at(outer, i)) { SET_STRING_ELT(out_names, count, STRING_ELT(r_vec_names(outer), i)); } } count += n_inner; } } FREE(1); return count; } // List squashing ----------------------------------------------------- static r_ssize list_squash(squash_info_t info, sexp* outer, sexp* out, r_ssize count, bool (*is_spliceable)(sexp*), int depth) { if (r_typeof(outer) != VECSXP) { r_abort("Only lists can be spliced"); } sexp* inner; sexp* out_names = KEEP(r_vec_names(out)); r_ssize n_outer = r_length(outer); for (r_ssize i = 0; i != n_outer; ++i) { inner = VECTOR_ELT(outer, i); if (depth != 0 && is_spliceable(inner)) { inner = PROTECT(maybe_unbox(inner, is_spliceable)); count = list_squash(info, inner, out, count, is_spliceable, depth - 1); UNPROTECT(1); } else { SET_VECTOR_ELT(out, count, inner); if (info.named && r_typeof(r_vec_names(outer)) == r_type_character) { sexp* name = STRING_ELT(r_vec_names(outer), i); SET_STRING_ELT(out_names, count, name); } count += 1; } } FREE(1); return count; } // First pass -------------------------------------------------------- static void squash_warn_names(void) { Rf_warningcall(r_null, "Outer names are only allowed for unnamed scalar atomic inputs"); } static void update_info_outer(squash_info_t* info, sexp* outer, r_ssize i) { if (!info->warned && info->recursive && r_has_name_at(outer, i)) { squash_warn_names(); info->warned = true; } } static void update_info_inner(squash_info_t* info, sexp* outer, r_ssize i, sexp* inner) { r_ssize n_inner = info->recursive ? 1 : r_vec_length(inner); info->size += n_inner; // Return early if possible if (info->named && info->warned) { return; } bool named = r_typeof(r_vec_names(inner)) == r_type_character; bool recursive = info->recursive; bool copy_outer = recursive || n_inner == 1; bool copy_inner = !recursive; if (named && copy_inner) { info->named = true; } if (r_has_name_at(outer, i)) { if (!recursive && (n_inner != 1 || named) && !info->warned) { squash_warn_names(); info->warned = true; } if (copy_outer) { info->named = true; } } } static void squash_info(squash_info_t* info, sexp* outer, bool (*is_spliceable)(sexp*), int depth) { if (r_typeof(outer) != r_type_list) { r_abort("Only lists can be spliced"); } sexp* inner; r_ssize n_outer = r_length(outer); for (r_ssize i = 0; i != n_outer; ++i) { inner = VECTOR_ELT(outer, i); if (depth != 0 && is_spliceable(inner)) { update_info_outer(info, outer, i); inner = PROTECT(maybe_unbox(inner, is_spliceable)); squash_info(info, inner, is_spliceable, depth - 1); UNPROTECT(1); } else if (info->recursive || r_vec_length(inner)) { update_info_inner(info, outer, i, inner); } } } static sexp* squash(enum r_type kind, sexp* dots, bool (*is_spliceable)(sexp*), int depth) { bool recursive = kind == VECSXP; squash_info_t info = squash_info_init(recursive); squash_info(&info, dots, is_spliceable, depth); sexp* out = KEEP(r_new_vector(kind, info.size)); if (info.named) { sexp* nms = KEEP(r_new_vector(r_type_character, info.size)); r_poke_names(out, nms); FREE(1); } if (recursive) { list_squash(info, dots, out, 0, is_spliceable, depth); } else { atom_squash(kind, info, dots, out, 0, is_spliceable, depth); } FREE(1); return out; } // Predicates -------------------------------------------------------- typedef bool (*is_spliceable_t)(sexp*); static bool is_spliced_bare(sexp* x) { if (!r_is_object(x)) { return r_typeof(x) == r_type_list; } else { return rlang_is_splice_box(x); } } static is_spliceable_t predicate_pointer(sexp* x) { switch (r_typeof(x)) { case VECSXP: if (Rf_inherits(x, "fn_pointer") && r_length(x) == 1) { sexp* ptr = VECTOR_ELT(x, 0); if (r_typeof(ptr) == EXTPTRSXP) { return (is_spliceable_t) R_ExternalPtrAddrFn(ptr); } } break; case EXTPTRSXP: return (is_spliceable_t) R_ExternalPtrAddrFn(x); default: break; } r_abort("`predicate` must be a closure or function pointer"); return NULL; } static is_spliceable_t predicate_internal(sexp* x) { static sexp* is_spliced_clo = NULL; if (!is_spliced_clo) { is_spliced_clo = rlang_ns_get("is_spliced"); } static sexp* is_spliceable_clo = NULL; if (!is_spliceable_clo) { is_spliceable_clo = rlang_ns_get("is_spliced_bare"); } if (x == is_spliced_clo) { return rlang_is_splice_box; } if (x == is_spliceable_clo) { return &is_spliced_bare; } return NULL; } // Emulate closure behaviour with global variable. static sexp* clo_spliceable = NULL; static bool is_spliceable_closure(sexp* x) { if (!clo_spliceable) { r_abort("Internal error while splicing"); } SETCADR(clo_spliceable, x); sexp* out = r_eval(clo_spliceable, R_GlobalEnv); return r_lgl_get(out, 0); } // Export ------------------------------------------------------------ sexp* r_squash_if(sexp* dots, enum r_type kind, bool (*is_spliceable)(sexp*), int depth) { switch (kind) { case LGLSXP: case INTSXP: case REALSXP: case CPLXSXP: case STRSXP: case RAWSXP: case VECSXP: return squash(kind, dots, is_spliceable, depth); default: r_abort("Splicing is not implemented for this type"); return r_null; } } sexp* rlang_squash_closure(sexp* dots, enum r_type kind, sexp* pred, int depth) { sexp* prev_pred = clo_spliceable; clo_spliceable = KEEP(Rf_lang2(pred, Rf_list2(r_null, r_null))); sexp* out = r_squash_if(dots, kind, &is_spliceable_closure, depth); clo_spliceable = prev_pred; FREE(1); return out; } sexp* rlang_squash(sexp* dots, sexp* type, sexp* pred, sexp* depth_) { enum r_type kind = Rf_str2type(CHAR(STRING_ELT(type, 0))); int depth = Rf_asInteger(depth_); is_spliceable_t is_spliceable; switch (r_typeof(pred)) { case r_type_closure: is_spliceable = predicate_internal(pred); if (is_spliceable) { return r_squash_if(dots, kind, is_spliceable, depth); } // else fallthrough case r_type_builtin: case r_type_special: return rlang_squash_closure(dots, kind, pred, depth); default: is_spliceable = predicate_pointer(pred); return r_squash_if(dots, kind, is_spliceable, depth); } } void r_init_library_squash() { rlang_is_splice_box = (bool (*)(sexp*)) r_peek_c_callable("rlang", "rlang_is_splice_box"); rlang_unbox = (sexp* (*)(sexp*)) r_peek_c_callable("rlang", "rlang_unbox"); } rlang/src/lib/weakref.c0000644000176200001440000000132113500531447014501 0ustar liggesusers#include #include sexp* rlang_new_weakref(sexp* key, sexp* value, sexp* finalizer, sexp* on_quit) { if (r_typeof(key) != ENVSXP && r_typeof(key) != EXTPTRSXP) { r_abort("`key` must be an environment or external pointer"); } return R_MakeWeakRef(key, value, finalizer, LOGICAL(on_quit)[0]); } sexp* rlang_wref_key(sexp* x) { if (r_typeof(x) != WEAKREFSXP) { r_abort("`x` must be a weak reference object"); } return R_WeakRefKey(x); } sexp* rlang_wref_value(sexp* x) { if (r_typeof(x) != WEAKREFSXP) { r_abort("`x` must be a weak reference object"); } return R_WeakRefValue(x); } sexp* rlang_is_weakref(sexp* x) { return Rf_ScalarLogical(r_typeof(x) == WEAKREFSXP); } rlang/src/lib/export.c0000644000176200001440000000202513351410655014401 0ustar liggesusers#include "rlang.h" #include "export.h" #include #if (defined(R_VERSION) && R_VERSION < R_Version(3, 4, 0)) sexp* R_MakeExternalPtrFn(DL_FUNC p, sexp* tag, sexp* prot) { fn_ptr ptr; ptr.fn = p; return R_MakeExternalPtr(ptr.p, tag, prot); } DL_FUNC R_ExternalPtrAddrFn(sexp* s) { fn_ptr ptr; ptr.p = EXTPTR_PTR(s); return ptr.fn; } #endif sexp* rlang_namespace(const char* ns) { sexp* ns_string = KEEP(Rf_mkString(ns)); sexp* call = KEEP(r_sym("getNamespace")); call = KEEP(Rf_lang2(call, ns_string)); sexp* ns_env = r_eval(call, R_BaseEnv); FREE(3); return ns_env; } void rlang_register_pointer(const char* ns, const char* ptr_name, DL_FUNC fn) { sexp* ptr = KEEP(R_MakeExternalPtrFn(fn, r_null, r_null)); sexp* ptr_obj = KEEP(r_new_vector(VECSXP, 1)); SET_VECTOR_ELT(ptr_obj, 0, ptr); sexp* ptr_class = KEEP(Rf_mkString("fn_pointer")); Rf_setAttrib(ptr_obj, R_ClassSymbol, ptr_class); sexp* ns_env = KEEP(rlang_namespace(ns)); Rf_defineVar(r_sym(ptr_name), ptr_obj, ns_env); FREE(4); } rlang/src/lib/sexp.h0000644000176200001440000000400613457603056014053 0ustar liggesusers#ifndef RLANG_SEXP_H #define RLANG_SEXP_H static inline r_ssize r_length(sexp* x) { return Rf_xlength(x); } static inline enum r_type r_typeof(sexp* x) { return TYPEOF(x); } #define r_mark_precious R_PreserveObject #define r_unmark_precious R_ReleaseObject static inline void r_mark_shared(sexp* x) { MARK_NOT_MUTABLE(x); } static inline bool r_is_shared(sexp* x) { return MAYBE_REFERENCED(x); } static inline void r_mark_object(sexp* x) { SET_OBJECT(x, 1); } static inline void r_unmark_object(sexp* x) { SET_OBJECT(x, 0); } static inline bool r_is_object(sexp* x) { return OBJECT(x); } static inline bool r_inherits(sexp* x, const char* tag) { return Rf_inherits(x, tag); } static inline sexp* r_missing_arg() { return R_MissingArg; } static inline bool r_is_missing(sexp* x) { return x == R_MissingArg; } static inline bool r_is_null(sexp* x) { return x == R_NilValue; } static inline sexp* r_duplicate(sexp* x, bool shallow) { if (shallow) { return Rf_shallow_duplicate(x); } else { return Rf_duplicate(x); } } static inline sexp* r_copy(sexp* x) { return Rf_duplicate(x); } static inline sexp* r_clone(sexp* x) { return Rf_shallow_duplicate(x); } static inline sexp* r_maybe_duplicate(sexp* x, bool shallow) { if (r_is_shared(x)) { return r_duplicate(x, shallow); } else { return x; } } static inline sexp* r_poke_type(sexp* x, enum r_type type) { SET_TYPEOF(x, type); return x; } static inline sexp* r_poke_str_type(sexp* x, const char* type) { SET_TYPEOF(x, Rf_str2type(type)); return x; } static inline const char* r_type_as_c_string(enum r_type type) { return CHAR(Rf_type2str(type)); } static inline bool r_is_symbolic(sexp* x) { return r_typeof(x) == LANGSXP || r_typeof(x) == SYMSXP; } static inline void r_sexp_print(sexp* x) { Rf_PrintValue(x); } static inline bool r_is_identical(sexp* x, sexp* y) { // 16 corresponds to base::identical()'s defaults // Do we need less conservative versions? return R_compute_identical(x, y, 16); } #endif rlang/src/lib/rlang.h0000644000176200001440000000346413440165104014173 0ustar liggesusers#ifndef RLANG_RLANG_H #define RLANG_RLANG_H #include #include #define R_NO_REMAP #include typedef struct SEXPREC sexp; typedef Rbyte r_byte_t; typedef Rcomplex r_complex_t; typedef R_xlen_t r_ssize; #define R_SSIZE_MAX R_XLEN_T_MAX r_ssize r_as_ssize(sexp* n); enum r_type { r_type_null = 0, r_type_symbol = 1, r_type_pairlist = 2, r_type_closure = 3, r_type_environment = 4, r_type_promise = 5, r_type_call = 6, r_type_special = 7, r_type_builtin = 8, r_type_string = 9, r_type_logical = 10, r_type_integer = 13, r_type_double = 14, r_type_complex = 15, r_type_character = 16, r_type_dots = 17, r_type_any = 18, r_type_list = 19, r_type_expression = 20, r_type_bytecode = 21, r_type_pointer = 22, r_type_weakref = 23, r_type_raw = 24, r_type_s4 = 25, r_type_new = 30, r_type_free = 31, r_type_function = 99 }; #define r_null R_NilValue extern sexp* r_shared_true; extern sexp* r_shared_false; #define KEEP PROTECT #define FREE UNPROTECT #define KEEP_N(x, n) (++n, KEEP(x)) #define KEEP_WITH_INDEX(x, i) PROTECT_WITH_INDEX(x, &i) #define KEEP_I REPROTECT #define RLANG_ASSERT(condition) ((void)sizeof(char[1 - 2*!(condition)])) #include "sexp.h" #include "attrs.h" #include "debug.h" #include "cnd.h" #include "env.h" #include "env-binding.h" #include "eval.h" #include "export.h" #include "fn.h" #include "formula.h" #include "lang.h" #include "node.h" #include "parse.h" #include "quo.h" #include "session.h" #include "squash.h" #include "stack.h" #include "state.h" #include "sym.h" #include "vec.h" #include "vec-chr.h" #include "vec-lgl.h" #include "vec-list.h" sexp* r_init_library(); #endif rlang/src/lib/vec-lgl.h0000644000176200001440000000063213442432203014412 0ustar liggesusers#ifndef RLANG_VECTOR_LGL_H #define RLANG_VECTOR_LGL_H int r_as_optional_bool(sexp* lgl); static inline sexp* r_lgl(bool x) { return Rf_ScalarLogical(x); } bool r_is_true(sexp* x); static inline sexp* r_shared_lgl(bool x) { if (x) { return r_shared_true; } else { return r_shared_false; } } r_ssize r_lgl_sum(sexp* x, bool na_true); sexp* r_lgl_which(sexp* x, bool na_propagate); #endif rlang/src/lib/vec-chr.c0000644000176200001440000000534713405732277014430 0ustar liggesusers#include #include "rlang.h" r_ssize ptrs_array_length(void** ptrs) { r_ssize n = 0; while (*ptrs) { ++ptrs; ++n; } return n; } sexp* r_new_character(const char** strings) { r_ssize n = ptrs_array_length((void**) strings); sexp* out = KEEP(r_new_vector(STRSXP, n)); for (r_ssize i = 0; i < n; ++i) { r_chr_poke(out, i, r_string(strings[i])); } FREE(1); return out; } r_ssize r_chr_detect_index(sexp* chr, const char* c_string) { r_ssize n = r_length(chr); for (r_ssize i = 0; i != n; ++i) { const char* cur = CHAR(STRING_ELT(chr, i)); if (strcmp(cur, c_string) == 0) { return i; } } return -1; } bool r_chr_has(sexp* chr, const char* c_string) { r_ssize idx = r_chr_detect_index(chr, c_string); return idx >= 0; } bool r_chr_has_any(sexp* chr, const char** c_strings) { r_ssize n = r_length(chr); for (r_ssize i = 0; i != n; ++i) { const char* cur = CHAR(STRING_ELT(chr, i)); while (*c_strings) { if (strcmp(cur, *c_strings) == 0) { return true; } ++c_strings; } } return false; } static void validate_chr_setter(sexp* chr, sexp* r_string) { if (r_typeof(chr) != r_type_character) { r_abort("`chr` must be a character vector"); } if (r_typeof(r_string) != r_type_string) { r_abort("`r_string` must be an internal R string"); } } sexp* chr_prepend(sexp* chr, sexp* r_string) { if (r_is_null(chr)) { return r_str_as_character(r_string); } else { validate_chr_setter(chr, r_string); } int n = r_length(chr); sexp* out = KEEP(r_new_vector(STRSXP, n + 1)); r_vec_poke_n(out, 1, chr, 0, n); r_chr_poke(out, 0, r_string); FREE(1); return out; } sexp* chr_append(sexp* chr, sexp* r_str) { if (r_is_null(chr)) { return r_str_as_character(r_str); } validate_chr_setter(chr, r_str); int n = r_length(chr); sexp* out = KEEP(r_new_vector(STRSXP, n + 1)); r_vec_poke_n(out, 0, chr, 0, n); r_chr_poke(out, n, r_str); FREE(1); return out; } sexp* r_nms_are_duplicated(sexp* nms, bool from_last) { if (r_typeof(nms) != r_type_character) { r_abort("Internal error: Expected a character vector of names for checking duplication"); } sexp* dups = KEEP(Rf_duplicated(nms, from_last)); r_ssize n = r_length(dups); int* dups_ptr = r_lgl_deref(dups); sexp** nms_ptr = r_chr_deref(nms); for (r_ssize i = 0; i < n; ++i, ++dups_ptr, ++nms_ptr) { if (*nms_ptr == r_empty_str || *nms_ptr == r_missing_str) { *dups_ptr = false; } } FREE(1); return dups; } sexp* r_shared_empty_chr = NULL; sexp* r_empty_str = NULL; void r_init_library_vec_chr() { r_shared_empty_chr = r_chr(""); r_mark_precious(r_shared_empty_chr); r_empty_str = r_chr_get(r_shared_empty_chr, 0); } rlang/src/lib/sym.c0000644000176200001440000000332013404523163013665 0ustar liggesusers#include #include "rlang.h" // In old R versions `as.name()` does not translate to native which // loses the encoding. This symbol constructor always translates. sexp* r_new_symbol(sexp* x, int* err) { switch (r_typeof(x)) { case SYMSXP: return x; case STRSXP: if (r_length(x) == 1) { const char* string = Rf_translateChar(r_chr_get(x, 0)); return r_sym(string); } // else fallthrough default: { if (err) { *err = -1; return r_null; } else { const char* type = r_type_as_c_string(r_typeof(x)); r_abort("Can't create a symbol with a %s", type); } }} } bool r_is_symbol(sexp* x, const char* string) { if (r_typeof(x) != SYMSXP) { return false; } else { return strcmp(CHAR(PRINTNAME(x)), string) == 0; } } bool r_is_symbol_any(sexp* x, const char** strings, int n) { if (r_typeof(x) != SYMSXP) { return false; } const char* name = CHAR(PRINTNAME(x)); for (int i = 0; i < n; ++i) { if (strcmp(name, strings[i]) == 0) { return true; } } return false; } bool r_is_special_op_sym(sexp* x) { if (r_typeof(x) != SYMSXP) { return false; } const char* name = CHAR(PRINTNAME(x)); int len = strlen(name); return len > 2 && name[0] == '%' && name[len - 1] == '%'; } sexp* r_dot_environment_sym; sexp* r_function_sym; sexp* r_srcref_sym; sexp* r_tilde_sym; sexp* r_w_sym; sexp* r_x_sym; sexp* r_y_sym; sexp* r_z_sym; void r_init_library_sym() { r_dot_environment_sym = r_sym(".Environment"); r_function_sym = r_sym("function"); r_srcref_sym = r_sym("srcref"); r_tilde_sym = r_sym("~"); r_w_sym = r_sym("w"); r_x_sym = r_sym("x"); r_y_sym = r_sym("y"); r_z_sym = r_sym("z"); } rlang/src/lib/replace-na.c0000644000176200001440000000720713517571557015113 0ustar liggesusers#include "rlang.h" static sexp* replace_na_(sexp* x, sexp* replacement, int start); static sexp* replace_na_vec_(sexp* x, sexp* replacement, int start); sexp* rlang_replace_na(sexp* x, sexp* replacement) { int n = r_length(x); int i = 0; switch(r_typeof(x)) { case LGLSXP: { int* arr = LOGICAL(x); for (; i < n; ++i) { if (arr[i] == NA_LOGICAL) { break; } } break; } case INTSXP: { int* arr = INTEGER(x); for (; i < n; ++i) { if (arr[i] == NA_INTEGER) { break; } } break; } case REALSXP: { double* arr = REAL(x); for (; i < n; ++i) { if (ISNA(arr[i])) { break; } } break; } case STRSXP: { for (; i < n; ++i) { if (STRING_ELT(x, i) == NA_STRING) { break; } } break; } case CPLXSXP: { r_complex_t* arr = COMPLEX(x); for (; i < n; ++i) { if (ISNA(arr[i].r)) { break; } } break; } default: { r_abort("Don't know how to handle object of type", Rf_type2char(r_typeof(x))); } } if (i == n) { return x; } else if (r_length(replacement) == 1) { return replace_na_(x, replacement, i); } else { return replace_na_vec_(x, replacement, i); } } static sexp* replace_na_(sexp* x, sexp* replacement, int i) { KEEP(x = Rf_duplicate(x)); int n = r_length(x); switch(r_typeof(x)) { case LGLSXP: { int* arr = LOGICAL(x); int new_value = LOGICAL(replacement)[0]; for (; i < n; ++i) { if (arr[i] == NA_LOGICAL) { arr[i] = new_value; } } break; } case INTSXP: { int* arr = INTEGER(x); int new_value = INTEGER(replacement)[0]; for (; i < n; ++i) { if (arr[i] == NA_INTEGER) { arr[i] = new_value; } } break; } case REALSXP: { double* arr = REAL(x); double new_value = REAL(replacement)[0]; for (; i < n; ++i) { if (ISNA(arr[i])) { arr[i] = new_value; } } break; } case STRSXP: { sexp* new_value = STRING_ELT(replacement, 0); for (; i < n; ++i) { if (STRING_ELT(x, i) == NA_STRING) { SET_STRING_ELT(x, i, new_value); } } break; } case CPLXSXP: { r_complex_t* arr = COMPLEX(x); r_complex_t new_value = COMPLEX(replacement)[0]; for (; i < n; ++i) { if (ISNA(arr[i].r)) { arr[i] = new_value; } } break; } default: { r_abort("Don't know how to handle object of type", Rf_type2char(r_typeof(x))); } } FREE(1); return x; } static sexp* replace_na_vec_(sexp* x, sexp* replacement, int i) { KEEP(x = Rf_duplicate(x)); int n = r_length(x); switch(r_typeof(x)) { case LGLSXP: { int* arr = LOGICAL(x); for (; i < n; ++i) { if (arr[i] == NA_LOGICAL) { arr[i] = LOGICAL(replacement)[i]; } } break; } case INTSXP: { int* arr = INTEGER(x); for (; i < n; ++i) { if (arr[i] == NA_INTEGER) { arr[i] = INTEGER(replacement)[i]; } } break; } case REALSXP: { double* arr = REAL(x); for (; i < n; ++i) { if (ISNA(arr[i])) { arr[i] = REAL(replacement)[i]; } } break; } case STRSXP: { for (; i < n; ++i) { if (STRING_ELT(x, i) == NA_STRING) { SET_STRING_ELT(x, i, STRING_ELT(replacement, i)); } } break; } case CPLXSXP: { r_complex_t* arr = COMPLEX(x); for (; i < n; ++i) { if (ISNA(arr[i].r)) { arr[i] = COMPLEX(replacement)[i]; } } break; } default: { r_abort("Don't know how to handle object of type", Rf_type2char(r_typeof(x))); } } FREE(1); return x; } rlang/src/export.c0000644000176200001440000000013113611313357013627 0ustar liggesusers#include "export/exported.c" #include "export/exported-tests.c" #include "export/init.c" rlang/src/capture.c0000644000176200001440000000620713457603056013771 0ustar liggesusers#include #define attribute_hidden #define _(string) (string) SEXP attribute_hidden new_captured_arg(SEXP x, SEXP env) { static SEXP nms = NULL; if (!nms) { nms = allocVector(STRSXP, 2); R_PreserveObject(nms); MARK_NOT_MUTABLE(nms); SET_STRING_ELT(nms, 0, mkChar("expr")); SET_STRING_ELT(nms, 1, mkChar("env")); } SEXP info = PROTECT(allocVector(VECSXP, 2)); SET_VECTOR_ELT(info, 0, x); SET_VECTOR_ELT(info, 1, env); setAttrib(info, R_NamesSymbol, nms); UNPROTECT(1); return info; } SEXP attribute_hidden new_captured_literal(SEXP x) { return new_captured_arg(x, R_EmptyEnv); } SEXP attribute_hidden new_captured_promise(SEXP x, SEXP env) { SEXP expr_env = R_NilValue; SEXP expr = x; while (TYPEOF(expr) == PROMSXP) { expr_env = PRENV(expr); expr = PREXPR(expr); } // Evaluated arguments are returned as literals if (expr_env == R_NilValue) { SEXP value = PROTECT(eval(x, env)); expr = new_captured_literal(value); UNPROTECT(1); } else { MARK_NOT_MUTABLE(expr); expr = new_captured_arg(expr, expr_env); } return expr; } SEXP attribute_hidden rlang_capturearginfo(SEXP call, SEXP op, SEXP args, SEXP rho) { int nProt = 0; // Unwrap first layer of promise SEXP sym = findVarInFrame3(rho, install("x"), TRUE); PROTECT(sym); ++nProt; // May be a literal if compiler did not wrap in a promise if (TYPEOF(sym) != PROMSXP) { SEXP value = new_captured_literal(sym); UNPROTECT(nProt); return value; } sym = PREXPR(sym); if (TYPEOF(sym) != SYMSXP) { UNPROTECT(nProt); error(_("\"x\" must be an argument name")); } SEXP frame = CAR(args); SEXP arg = findVar(sym, frame); PROTECT(arg); ++nProt; if (arg == R_UnboundValue) { UNPROTECT(nProt); error(_("object '%s' not found"), CHAR(PRINTNAME(sym))); } SEXP value; if (arg == R_MissingArg) value = new_captured_literal(arg); else if (TYPEOF(arg) == PROMSXP) value = new_captured_promise(arg, frame); else value = new_captured_literal(arg); UNPROTECT(nProt); return value; } SEXP capturedots(SEXP frame) { SEXP dots = PROTECT(findVar(R_DotsSymbol, frame)); if (dots == R_UnboundValue) { error(_("Must capture dots in a function where dots exist")); } if (dots == R_MissingArg) { UNPROTECT(1); return R_NilValue; } SEXP out = PROTECT(cons(R_NilValue, R_NilValue)); SEXP node = out; while (dots != R_NilValue) { SEXP head = CAR(dots); SEXP dot; if (TYPEOF(head) == PROMSXP) dot = new_captured_promise(head, frame); else dot = new_captured_literal(head); SETCDR(node, cons(dot, R_NilValue)); SET_TAG(CDR(node), TAG(dots)); node = CDR(node); dots = CDR(dots); } UNPROTECT(2); return CDR(out); } SEXP attribute_hidden rlang_capturedots(SEXP call, SEXP op, SEXP args, SEXP rho) { SEXP caller_env = CAR(args); return capturedots(caller_env); } rlang/R/0000755000176200001440000000000013614040226011554 5ustar liggesusersrlang/R/expr.R0000644000176200001440000002577613561023554012704 0ustar liggesusers#' Is an object an expression? #' #' @description #' #' `is_expression()` tests for expressions, the set of objects that can be #' obtained from parsing R code. An expression can be one of two #' things: either a symbolic object (for which `is_symbolic()` returns #' `TRUE`), or a syntactic literal (testable with #' `is_syntactic_literal()`). Technically, calls can contain any R #' object, not necessarily symbolic objects or syntactic #' literals. However, this only happens in artificial #' situations. Expressions as we define them only contain numbers, #' strings, `NULL`, symbols, and calls: this is the complete set of R #' objects that can be created when R parses source code (e.g. from #' using [parse_expr()]). #' #' Note that we are using the term expression in its colloquial sense #' and not to refer to [expression()] vectors, a data type that wraps #' expressions in a vector and which isn't used much in modern R code. #' #' @details #' #' `is_symbolic()` returns `TRUE` for symbols and calls (objects with #' type `language`). Symbolic objects are replaced by their value #' during evaluation. Literals are the complement of symbolic #' objects. They are their own value and return themselves during #' evaluation. #' #' `is_syntactic_literal()` is a predicate that returns `TRUE` for the #' subset of literals that are created by R when parsing text (see #' [parse_expr()]): numbers, strings and `NULL`. Along with symbols, #' these literals are the terminating nodes in an AST. #' #' Note that in the most general sense, a literal is any R object that #' evaluates to itself and that can be evaluated in the empty #' environment. For instance, `quote(c(1, 2))` is not a literal, it is #' a call. However, the result of evaluating it in [base_env()] is a #' literal(in this case an atomic vector). #' #' Pairlists are also a kind of language objects. However, since they #' are mostly an internal data structure, `is_expression()` returns `FALSE` #' for pairlists. You can use `is_pairlist()` to explicitly check for #' them. Pairlists are the data structure for function arguments. They #' usually do not arise from R code because subsetting a call is a #' type-preserving operation. However, you can obtain the pairlist of #' arguments by taking the CDR of the call object from C code. The #' rlang function [node_cdr()] will do it from R. Another way in #' which pairlist of arguments arise is by extracting the argument #' list of a closure with [base::formals()] or [fn_fmls()]. #' #' @param x An object to test. #' @seealso [is_call()] for a call predicate. #' @export #' @examples #' q1 <- quote(1) #' is_expression(q1) #' is_syntactic_literal(q1) #' #' q2 <- quote(x) #' is_expression(q2) #' is_symbol(q2) #' #' q3 <- quote(x + 1) #' is_expression(q3) #' is_call(q3) #' #' #' # Atomic expressions are the terminating nodes of a call tree: #' # NULL or a scalar atomic vector: #' is_syntactic_literal("string") #' is_syntactic_literal(NULL) #' #' is_syntactic_literal(letters) #' is_syntactic_literal(quote(call())) #' #' # Parsable literals have the property of being self-quoting: #' identical("foo", quote("foo")) #' identical(1L, quote(1L)) #' identical(NULL, quote(NULL)) #' #' # Like any literals, they can be evaluated within the empty #' # environment: #' eval_bare(quote(1L), empty_env()) #' #' # Whereas it would fail for symbolic expressions: #' # eval_bare(quote(c(1L, 2L)), empty_env()) #' #' #' # Pairlists are also language objects representing argument lists. #' # You will usually encounter them with extracted formals: #' fmls <- formals(is_expression) #' typeof(fmls) #' #' # Since they are mostly an internal data structure, is_expression() #' # returns FALSE for pairlists, so you will have to check explicitly #' # for them: #' is_expression(fmls) #' is_pairlist(fmls) is_expression <- function(x) { is_symbolic(x) || is_syntactic_literal(x) } #' @export #' @rdname is_expression is_syntactic_literal <- function(x) { switch(typeof(x), NULL = { TRUE }, logical = , integer = , double = , character = { length(x) == 1 }, complex = { if (length(x) != 1) { return(FALSE) } is_na(x) || Re(x) == 0 }, FALSE ) } #' @export #' @rdname is_expression is_symbolic <- function(x) { typeof(x) %in% c("language", "symbol") } #' Turn an expression to a label #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} #' #' `expr_text()` turns the expression into a single string, which #' might be multi-line. `expr_name()` is suitable for formatting #' names. It works best with symbols and scalar types, but also #' accepts calls. `expr_label()` formats the expression nicely for use #' in messages. #' #' @param expr An expression to labellise. #' #' @section Life cycle: #' #' These functions are in the questioning stage because they are #' redundant with the `quo_` variants and do not handle quosures. #' #' @examples #' # To labellise a function argument, first capture it with #' # substitute(): #' fn <- function(x) expr_label(substitute(x)) #' fn(x:y) #' #' # Strings are encoded #' expr_label("a\nb") #' #' # Names and expressions are quoted with `` #' expr_label(quote(x)) #' expr_label(quote(a + b + c)) #' #' # Long expressions are collapsed #' expr_label(quote(foo({ #' 1 + 2 #' print(x) #' }))) #' @export expr_label <- function(expr) { if (is.character(expr)) { encodeString(expr, quote = '"') } else if (is.atomic(expr)) { format(expr) } else if (is.name(expr)) { paste0("`", as.character(expr), "`") } else { chr <- deparse_one(expr) paste0("`", chr, "`") } } #' @rdname expr_label #' @export expr_name <- function(expr) { if (is_null(expr)) { return("NULL") } if (is_symbol(expr)) { return(as_string(expr)) } if (is_call(expr)) { if (is_data_pronoun(expr)) { name <- data_pronoun_name(expr) %||% "" } else { name <- deparse_one(expr) name <- gsub("\n.*$", "...", name) } return(name) } # So 1L is translated to "1" and not "1L" if (is_scalar_atomic(expr)) { return(as.character(expr)) } if (length(expr) == 1) { name <- expr_text(expr) name <- gsub("\n.*$", "...", name) return(name) } abort("`expr` must quote a symbol, scalar, or call") } #' @rdname expr_label #' @export #' @param width Width of each line. #' @param nlines Maximum number of lines to extract. expr_text <- function(expr, width = 60L, nlines = Inf) { if (is_symbol(expr)) { return(sym_text(expr)) } str <- deparse(expr, width.cutoff = width, backtick = TRUE) if (length(str) > nlines) { str <- c(str[seq_len(nlines - 1)], "...") } paste0(str, collapse = "\n") } sym_text <- function(sym) { # Use as_string() to translate unicode tags text <- as_string(sym) if (needs_backticks(text)) { text <- sprintf("`%s`", text) } text } deparse_one <- function(expr) { str <- deparse(expr, 60L) if (length(str) > 1) { if (is_call(expr, function_sym)) { expr[[3]] <- quote(...) str <- deparse(expr, 60L) } else if (is_call(expr, brace_sym)) { str <- "{ ... }" } else if (is_call(expr)) { str <- deparse(call2(expr[[1]], quote(...)), 60L) } str <- paste(str, collapse = "\n") } str } #' Set and get an expression #' #' These helpers are useful to make your function work generically #' with quosures and raw expressions. First call `get_expr()` to #' extract an expression. Once you're done processing the expression, #' call `set_expr()` on the original object to update the expression. #' You can return the result of `set_expr()`, either a formula or an #' expression depending on the input type. Note that `set_expr()` does #' not change its input, it creates a new object. #' #' @param x An expression, closure, or one-sided formula. In addition, #' `set_expr()` accept frames. #' @param value An updated expression. #' @param default A default expression to return when `x` is not an #' expression wrapper. Defaults to `x` itself. #' @return The updated original input for `set_expr()`. A raw #' expression for `get_expr()`. #' @seealso [quo_get_expr()] and [quo_set_expr()] for versions of #' [get_expr()] and [set_expr()] that only work on quosures. #' @export #' @examples #' f <- ~foo(bar) #' e <- quote(foo(bar)) #' frame <- identity(identity(ctxt_frame())) #' #' get_expr(f) #' get_expr(e) #' get_expr(frame) #' #' set_expr(f, quote(baz)) #' set_expr(e, quote(baz)) set_expr <- function(x, value) { if (is_quosure(x)) { x <- quo_set_expr(x, value) } else if (is_formula(x)) { f_rhs(x) <- value } else if (is_closure(x)) { body(x) <- value } else { x <- value } x } #' @rdname set_expr #' @export get_expr <- function(x, default = x) { .Call(rlang_get_expression, x, default) } expr_type_of <- function(x) { if (missing(x)) { return("missing") } type <- typeof(x) if (type %in% c("symbol", "language", "pairlist", "NULL")) { type } else { "literal" } } switch_expr <- function(.x, ...) { switch(expr_type_of(.x), ...) } #' Print an expression #' #' @description #' #' `expr_print()`, powered by `expr_deparse()`, is an alternative #' printer for R expressions with a few improvements over the base R #' printer. #' #' * It colourises [quosures][nse-defuse] according to their environment. #' Quosures from the global environment are printed normally while #' quosures from local environments are printed in unique colour (or #' in italic when all colours are taken). #' #' * It wraps inlined objects in angular brackets. For instance, an #' integer vector unquoted in a function call (e.g. #' `expr(foo(!!(1:3)))`) is printed like this: `foo()` while by default R prints the code to create that vector: #' `foo(1:3)` which is ambiguous. #' #' * It respects the width boundary (from the global option `width`) #' in more cases. #' #' @param x An object or expression to print. #' @param width The width of the deparsed or printed expression. #' Defaults to the global option `width`. #' #' @export #' @examples #' # It supports any object. Non-symbolic objects are always printed #' # within angular brackets: #' expr_print(1:3) #' expr_print(function() NULL) #' #' # Contrast this to how the code to create these objects is printed: #' expr_print(quote(1:3)) #' expr_print(quote(function() NULL)) #' #' # The main cause of non-symbolic objects in expressions is #' # quasiquotation: #' expr_print(expr(foo(!!(1:3)))) #' #' #' # Quosures from the global environment are printed normally: #' expr_print(quo(foo)) #' expr_print(quo(foo(!!quo(bar)))) #' #' # Quosures from local environments are colourised according to #' # their environments (if you have crayon installed): #' local_quo <- local(quo(foo)) #' expr_print(local_quo) #' #' wrapper_quo <- local(quo(bar(!!local_quo, baz))) #' expr_print(wrapper_quo) expr_print <- function(x, width = peek_option("width")) { cat_line(expr_deparse(x, width = width)) } #' @rdname expr_print #' @export expr_deparse <- function(x, width = peek_option("width")) { deparser <- new_quo_deparser(width = width) quo_deparse(x, deparser) } rlang/R/nse-force.R0000644000176200001440000003007513610376546013602 0ustar liggesusers#' Force parts of an expression #' #' @description #' #' It is sometimes useful to force early evaluation of part of an #' expression before it gets fully evaluated. The tidy eval framework #' provides several forcing operators for different use cases. #' #' - The bang-bang operator `!!` forces a _single_ object. One #' common case for `!!` is to substitute an environment-variable #' (created with `<-`) with a data-variable (inside a data frame). #' #' ``` #' library(dplyr) #' #' # The environment variable `var` refers to the data-variable #' # `height` #' var <- sym("height") #' #' # We force `var`, which substitutes it with `height` #' starwars %>% #' summarise(avg = mean(!!var, na.rm = TRUE)) #' ``` #' #' - The big-bang operator `!!!` forces-splice a _list_ of objects. #' The elements of the list are spliced in place, meaning that they #' each become one single argument. #' #' ``` #' vars <- syms(c("height", "mass")) #' #' # Force-splicing is equivalent to supplying the elements separately #' starwars %>% select(!!!vars) #' starwars %>% select(height, mass) #' ``` #' #' - The curly-curly operator `{{ }}` for function arguments is a bit #' special because it forces the function argument and immediately #' defuses it. The defused expression is substituted in place, ready #' to be evaluated in another context, such as the data frame. #' #' In practice, this is useful when you have a data-variable in an #' env-variable (such as a function argument). #' #' ``` #' # Force-defuse all function arguments that might contain #' # data-variables by embracing them with {{ }} #' mean_by <- function(data, by, var) { #' data %>% #' group_by({{ by }}) %>% #' summarise(avg = mean({{ var }}, na.rm = TRUE)) #' } #' #' # The env-variables `by` and `var` are forced but defused. #' # The data-variables they contain are evaluated by dplyr later on #' # in data context. #' iris %>% mean_by(by = Species, var = Sepal.Width) #' ``` #' #' Use `qq_show()` to experiment with forcing operators. `qq_show()` #' defuses its input, processes all forcing operators, and prints the #' result with [expr_print()] to reveal objects inlined in the #' expression by the forcing operators. #' #' #' @section Forcing names: #' #' When a function takes multiple named arguments #' (e.g. `dplyr::mutate()`), it is difficult to supply a variable as #' name. Since the LHS of `=` is [defused][nse-defuse], giving the name #' of a variable results in the argument having the name of the #' variable rather than the name stored in that variable. This problem #' of forcing evaluation of names is exactly what the `!!` operator is #' for. #' #' Unfortunately R is very strict about the kind of expressions #' supported on the LHS of `=`. This is why rlang interprets the #' walrus operator `:=` as an alias of `=`. You can use it to supply #' names, e.g. `a := b` is equivalent to `a = b`. Since its syntax is #' more flexible you can also force names on its LHS: #' #' ``` #' name <- "Jane" #' #' list2(!!name := 1 + 2) #' exprs(!!name := 1 + 2) #' ``` #' #' Like `=`, the `:=` operator expects strings or symbols on its LHS. #' #' Since unquoting names is related to interpolating within a string #' with the glue package, we have made the glue syntax available on #' the LHS of `:=`: #' #' ``` #' list2("{name}" := 1) #' tibble("{name}" := 1) #' ``` #' #' You can also interpolate defused function arguments with double #' braces `{{`, similar to the curly-curly syntax: #' #' ``` #' wrapper <- function(data, var) { #' data %>% mutate("{{ var }}_foo" := {{ var }} * 2) #' } #' ``` #' #' Currently, forcing names with `:=` only works in top level #' expressions. These are all valid: #' #' ``` #' exprs("{name}" := x) #' tibble("{name}" := x) #' ``` #' #' But deep-forcing names isn't supported: #' #' ``` #' exprs(this(is(deep("{name}" := x)))) #' ``` #' #' #' @section Theory: #' #' Formally, `quo()` and `expr()` are quasiquotation functions, `!!` #' is the unquote operator, and `!!!` is the unquote-splice operator. #' These terms have a rich history in Lisp languages, and live on in #' modern languages like #' [Julia](https://docs.julialang.org/en/v1/manual/metaprogramming/) #' and #' [Racket](https://docs.racket-lang.org/reference/quasiquote.html). #' #' #' @section Life cycle: #' #' * Calling `UQ()` and `UQS()` with the rlang namespace qualifier is #' deprecated as of rlang 0.3.0. Just use the unqualified forms #' instead: #' #' ``` #' # Bad #' rlang::expr(mean(rlang::UQ(var) * 100)) #' #' # Ok #' rlang::expr(mean(UQ(var) * 100)) #' #' # Good #' rlang::expr(mean(!!var * 100)) #' ``` #' #' Supporting namespace qualifiers complicates the implementation of #' unquotation and is misleading as to the nature of unquoting #' operators (which are syntactic operators that operates at #' quotation-time rather than function calls at evaluation-time). #' #' * `UQ()` and `UQS()` were soft-deprecated in rlang 0.2.0 in order #' to make the syntax of quasiquotation more consistent. The prefix #' forms are now \code{`!!`()} and \code{`!!!`()} which is #' consistent with other R operators (e.g. \code{`+`(a, b)} is the #' prefix form of `a + b`). #' #' Note that the prefix forms are not as relevant as before because #' `!!` now has the right operator precedence, i.e. the same as #' unary `-` or `+`. It is thus safe to mingle it with other #' operators, e.g. `!!a + !!b` does the right thing. In addition the #' parser now strips one level of parentheses around unquoted #' expressions. This way `(!!"foo")(...)` expands to `foo(...)`. #' These changes make the prefix forms less useful. #' #' Finally, the named functional forms `UQ()` and `UQS()` were #' misleading because they suggested that existing knowledge about #' functions is applicable to quasiquotation. This was reinforced by #' the visible definitions of these functions exported by rlang and #' by the tidy eval parser interpreting `rlang::UQ()` as `!!`. In #' reality unquoting is *not* a function call, it is a syntactic #' operation. The operator form makes it clearer that unquoting is #' special. #' #' @name nse-force #' @aliases quasiquotation UQ UQS {{}} \{\{ #' @examples #' # Interpolation with {{ }} is the easiest way to forward #' # arguments to tidy eval functions: #' if (is_attached("package:dplyr")) { #' #' # Forward all arguments involving data frame columns by #' # interpolating them within other data masked arguments. #' # Here we interpolate `arg` in a `summarise()` call: #' my_function <- function(data, arg) { #' summarise(data, avg = mean({{ arg }}, na.rm = TRUE)) #' } #' #' my_function(mtcars, cyl) #' my_function(mtcars, cyl * 10) #' #' # The operator is just a shortcut for `!!enquo()`: #' my_function <- function(data, arg) { #' summarise(data, avg = mean(!!enquo(arg), na.rm = TRUE)) #' } #' #' my_function(mtcars, cyl) #' #' } #' #' # Quasiquotation functions quote expressions like base::quote() #' quote(how_many(this)) #' expr(how_many(this)) #' quo(how_many(this)) #' #' # In addition, they support unquoting. Let's store symbols #' # (i.e. object names) in variables: #' this <- sym("apples") #' that <- sym("oranges") #' #' # With unquotation you can insert the contents of these variables #' # inside the quoted expression: #' expr(how_many(!!this)) #' expr(how_many(!!that)) #' #' # You can also insert values: #' expr(how_many(!!(1 + 2))) #' quo(how_many(!!(1 + 2))) #' #' #' # Note that when you unquote complex objects into an expression, #' # the base R printer may be a bit misleading. For instance compare #' # the output of `expr()` and `quo()` (which uses a custom printer) #' # when we unquote an integer vector: #' expr(how_many(!!(1:10))) #' quo(how_many(!!(1:10))) #' #' # This is why it's often useful to use qq_show() to examine the #' # result of unquotation operators. It uses the same printer as #' # quosures but does not return anything: #' qq_show(how_many(!!(1:10))) #' #' #' # Use `!!!` to add multiple arguments to a function. Its argument #' # should evaluate to a list or vector: #' args <- list(1:3, na.rm = TRUE) #' quo(mean(!!!args)) #' #' # You can combine the two #' var <- quote(xyz) #' extra_args <- list(trim = 0.9, na.rm = TRUE) #' quo(mean(!!var , !!!extra_args)) #' #' #' # The plural versions have support for the `:=` operator. #' # Like `=`, `:=` creates named arguments: #' quos(mouse1 := bernard, mouse2 = bianca) #' #' # The `:=` is mainly useful to unquote names. Unlike `=` it #' # supports `!!` on its LHS: #' var <- "unquote me!" #' quos(!!var := bernard, mouse2 = bianca) #' #' #' # All these features apply to dots captured by enquos(): #' fn <- function(...) enquos(...) #' fn(!!!args, !!var := penny) #' #' #' # Unquoting is especially useful for building an expression by #' # expanding around a variable part (the unquoted part): #' quo1 <- quo(toupper(foo)) #' quo1 #' #' quo2 <- quo(paste(!!quo1, bar)) #' quo2 #' #' quo3 <- quo(list(!!quo2, !!!syms(letters[1:5]))) #' quo3 NULL #' @rdname nse-force #' @usage NULL #' @export UQ <- function(x) { abort("`UQ()` can only be used within a quasiquoted argument") } #' @rdname nse-force #' @usage NULL #' @export UQS <- function(x) { abort("`UQS()` can only be used within a quasiquoted argument") } #' @rdname nse-force #' @usage NULL #' @export `!!` <- function(x) { abort("`!!` can only be used within a quasiquoted argument") } #' @rdname nse-force #' @usage NULL #' @export `!!!` <- function(x) { abort("`!!!` can only be used within a quasiquoted argument") } #' @rdname nse-force #' @usage NULL #' @export `:=` <- function(x, y) { abort("`:=` can only be used within a quasiquoted argument") } #' @rdname nse-force #' @param expr An expression to be quasiquoted. #' @export qq_show <- function(expr) { expr_print(enexpr(expr)) } #' Process unquote operators in a captured expression #' #' While all capturing functions in the tidy evaluation framework #' perform unquote on capture (most notably [quo()]), #' `expr_interp()` manually processes unquoting operators in #' expressions that are already captured. `expr_interp()` should be #' called in all user-facing functions expecting a formula as argument #' to provide the same quasiquotation functionality as NSE functions. #' #' @param x A function, raw expression, or formula to interpolate. #' @param env The environment in which unquoted expressions should be #' evaluated. By default, the formula or closure environment if a #' formula or a function, or the current environment otherwise. #' @export #' @examples #' # All tidy NSE functions like quo() unquote on capture: #' quo(list(!!(1 + 2))) #' #' # expr_interp() is meant to provide the same functionality when you #' # have a formula or expression that might contain unquoting #' # operators: #' f <- ~list(!!(1 + 2)) #' expr_interp(f) #' #' # Note that only the outer formula is unquoted (which is a reason #' # to use expr_interp() as early as possible in all user-facing #' # functions): #' f <- ~list(~!!(1 + 2), !!(1 + 2)) #' expr_interp(f) #' #' #' # Another purpose for expr_interp() is to interpolate a closure's #' # body. This is useful to inline a function within another. The #' # important limitation is that all formal arguments of the inlined #' # function should be defined in the receiving function: #' other_fn <- function(x) toupper(x) #' #' fn <- expr_interp(function(x) { #' x <- paste0(x, "_suffix") #' !!! body(other_fn) #' }) #' fn #' fn("foo") expr_interp <- function(x, env = NULL) { if (is_formula(x)) { f_rhs(x) <- .Call(rlang_interp, f_rhs(x), env %||% f_env(x)) } else if (is_closure(x)) { body(x) <- .Call(rlang_interp, body(x), env %||% fn_env(x)) } else { x <- .Call(rlang_interp, x, env %||% parent.frame()) } x } glue_unquote <- function(text, env = caller_env()) { glue::glue(glue_first_pass(text, env = env), .envir = env) } glue_first_pass <- function(text, env = caller_env()) { glue::glue( text, .open = "{{", .close = "}}", .transformer = glue_first_pass_eval, .envir = env ) } glue_first_pass_eval <- function(text, env) { text_expr <- parse_expr(text) defused_expr <- eval_bare(call2(enexpr, text_expr), env) as_label(defused_expr) } rlang/R/vec-new.R0000644000176200001440000001246513563531312013257 0ustar liggesusers#' Create vectors #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} #' #' The atomic vector constructors are equivalent to [c()] but: #' #' * They allow you to be more explicit about the output #' type. Implicit coercions (e.g. from integer to logical) follow #' the rules described in [vector-coercion]. #' #' * They use [dynamic dots][dyn-dots]. #' #' #' @section Life cycle: #' #' * All the abbreviated constructors such as `lgl()` will probably be #' moved to the vctrs package at some point. This is why they are #' marked as questioning. #' #' * Automatic splicing is soft-deprecated and will trigger a warning #' in a future version. Please splice explicitly with `!!!`. #' #' @param ... Components of the new vector. Bare lists and explicitly #' spliced lists are spliced. #' @name vector-construction #' @examples #' # These constructors are like a typed version of c(): #' c(TRUE, FALSE) #' lgl(TRUE, FALSE) #' #' # They follow a restricted set of coercion rules: #' int(TRUE, FALSE, 20) #' #' # Lists can be spliced: #' dbl(10, !!! list(1, 2L), TRUE) #' #' #' # They splice names a bit differently than c(). The latter #' # automatically composes inner and outer names: #' c(a = c(A = 10), b = c(B = 20, C = 30)) #' #' # On the other hand, rlang's ctors use the inner names and issue a #' # warning to inform the user that the outer names are ignored: #' dbl(a = c(A = 10), b = c(B = 20, C = 30)) #' dbl(a = c(1, 2)) #' #' # As an exception, it is allowed to provide an outer name when the #' # inner vector is an unnamed scalar atomic: #' dbl(a = 1) #' #' # Spliced lists behave the same way: #' dbl(!!! list(a = 1)) #' dbl(!!! list(a = c(A = 1))) NULL #' @rdname vector-construction #' @export lgl <- function(...) { .Call(rlang_squash, dots_values(...), "logical", is_spliced_bare, 1L) } #' @rdname vector-construction #' @export int <- function(...) { .Call(rlang_squash, dots_values(...), "integer", is_spliced_bare, 1L) } #' @rdname vector-construction #' @export dbl <- function(...) { .Call(rlang_squash, dots_values(...), "double", is_spliced_bare, 1L) } #' @rdname vector-construction #' @export cpl <- function(...) { .Call(rlang_squash, dots_values(...), "complex", is_spliced_bare, 1L) } #' @rdname vector-construction #' @export #' @export chr <- function(...) { .Call(rlang_squash, dots_values(...), "character", is_spliced_bare, 1L) } #' @rdname vector-construction #' @export #' @examples #' #' # bytes() accepts integerish inputs #' bytes(1:10) #' bytes(0x01, 0xff, c(0x03, 0x05), list(10, 20, 30L)) bytes <- function(...) { dots <- map(dots_values(...), function(dot) { if (is_bare_list(dot) || is_spliced(dot)) { map(dot, new_bytes) } else { new_bytes(dot) } }) .Call(rlang_squash, dots, "raw", is_spliced_bare, 1L) } #' Create vectors matching a given length #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} #' #' These functions construct vectors of a given length, with attributes #' specified via dots. Except for `new_list()` and `new_raw()`, the #' empty vectors are filled with typed [missing] values. This is in #' contrast to the base function [base::vector()] which creates #' zero-filled vectors. #' #' @param n The vector length. #' @param names Names for the new vector. #' #' @section Lifecycle: #' #' These functions are likely to be replaced by a vctrs equivalent in #' the future. They are in the questioning lifecycle stage. #' #' @keywords internal #' @examples #' new_list(10) #' new_logical(10) #' @name new-vector #' @seealso rep_along NULL #' @rdname new-vector #' @export new_logical <- function(n, names = NULL) { set_names(rep_len(na_lgl, n), names) } #' @rdname new-vector #' @export new_integer <- function(n, names = NULL) { set_names(rep_len(na_int, n), names) } #' @rdname new-vector #' @export new_double <- function(n, names = NULL) { set_names(rep_len(na_dbl, n), names) } #' @rdname new-vector #' @export new_character <- function(n, names = NULL) { set_names(rep_len(na_chr, n), names) } #' @rdname new-vector #' @export new_complex <- function(n, names = NULL) { set_names(rep_len(na_cpl, n), names) } #' @rdname new-vector #' @export new_raw <- function(n, names = NULL) { set_names(vector("raw", n), names) } #' @rdname new-vector #' @export new_list <- function(n, names = NULL) { set_names(vector("list", n), names) } #' Create vectors matching the length of a given vector #' #' These functions take the idea of [seq_along()] and apply it to #' repeating values. #' #' @param x Values to repeat. #' @param along Vector whose length determine how many times `x` #' is repeated. #' @param names Names for the new vector. The length of `names` #' determines how many times `x` is repeated. #' #' @seealso new-vector #' @export #' @examples #' x <- 0:5 #' rep_along(x, 1:2) #' rep_along(x, 1) #' #' # Create fresh vectors by repeating missing values: #' rep_along(x, na_int) #' rep_along(x, na_chr) #' #' # rep_named() repeats a value along a names vectors #' rep_named(c("foo", "bar"), list(letters)) rep_along <- function(along, x) { rep_len(x, length(along)) } #' @export #' @rdname rep_along rep_named <- function(names, x) { names <- names %||% chr() if (!is_character(names)) { abort("`names` must be `NULL` or a character vector") } set_names(rep_len(x, length(names)), names) } rlang/R/nse-defuse.R0000644000176200001440000003215013604137604013744 0ustar liggesusers#' Defuse R expressions #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("stable")} #' #' The defusing operators `expr()` and `enquo()` prevent the #' evaluation of R code. Defusing is also known as _quoting_, and is #' done in base R by [quote()] and [substitute()]. When a function #' argument is defused, R doesn't return its value like it normally #' would but it returns the R expression describing how to make the #' value. These defused expressions are like blueprints for computing #' values. #' #' There are two main ways to defuse expressions, to which correspond #' the two functions `expr()` and `enquo()`. Whereas `expr()` defuses #' your own expression, `enquo()` defuses expressions supplied as #' argument by the user of a function. See section on function #' arguments for more on this distinction. #' #' The main purpose of defusing evaluation of an expression is to #' enable data-masking, where an expression is evaluated in the #' context of a data frame so that you can write `var` instead of #' `data$var`. The expression is defused so it can be resumed later #' on, in a context where the data-variables have been defined. #' #' Defusing prevents the evaluation of R code, but you can still force #' evaluation inside a defused expression with the [forcing #' operators][nse-force] `!!` and `!!!`. #' #' #' @section Types of defused expressions: #' #' * __Calls__, like `f(1, 2, 3)` or `1 + 1` represent the action of #' calling a function to compute a new value, such as a vector. #' #' * __Symbols__, like `x` or `df`, represent named objects. When the #' object pointed to by the symbol was defined in a function or in #' the global environment, we call it an environment-variable. When #' the object is a column in a data frame, we call it a #' data-variable. #' #' You can create new call or symbol objects by using the defusing #' function `expr()`: #' #' ``` #' # Create a symbol representing objects called `foo` #' expr(foo) #' #' # Create a call representing the computation of the mean of `foo` #' expr(mean(foo, na.rm = TRUE)) #' ``` #' #' Defusing is not the only way to create defused expressions. You can #' also assemble them from data: #' #' ``` #' # Assemble a symbol from a string #' var <- "foo" #' sym(var) #' #' # Assemble a call from strings, symbols, and other objects #' call("mean", sym(var), na.rm = TRUE) #' ``` #' #' #' @section Defusing function arguments: #' #' There are two points of view when it comes to defusing an #' expression: #' #' * You can defuse expressions that _you_ supply with `expr()`. This #' is one way of creating symbols and calls (see previous section). #' #' * You can defuse the expressions supplied by _the user_ of your #' function with the operators starting with `en` like `ensym()`, #' `enquo()` and their plural variants. They defuse function #' arguments . #' #' #' @section Defused arguments and quosures: #' #' If you inspect the return values of `expr()` and `enquo()`, you'll #' notice that the latter doesn't return a raw expression like the #' former. Instead it returns a __quosure__, a wrapper containing an #' expression and an environment. R needs information about the #' environment to properly evaluate the argument expression because it #' comes from a different context than the current function. #' #' See the [quosure] help topic about tools to work with quosures. #' #' #' @section Comparison to base R: #' #' * The defusing operator `expr()` is similar to [quote()]. Like #' [bquote()], it allows [forcing][nse-defuse] evaluation of parts #' of an expression. #' #' * The plural variant `exprs()` is similar to [alist()]. #' #' * The argument-defusing operator `enquo()` is similar to #' [substitute()]. #' #' @inheritParams dots_list #' @param expr An expression. #' @param arg A symbol representing an argument. The expression #' supplied to that argument will be captured instead of being #' evaluated. #' @param ... For `enexprs()`, `ensyms()` and `enquos()`, names of #' arguments to capture without evaluation (including `...`). For #' `exprs()` and `quos()`, the expressions to capture unevaluated #' (including expressions contained in `...`). #' @param .named Whether to ensure all dots are named. Unnamed #' elements are processed with [quo_name()] to build a default #' name. See also [quos_auto_name()]. #' @param .ignore_empty Whether to ignore empty arguments. Can be one #' of `"trailing"`, `"none"`, `"all"`. If `"trailing"`, only the #' last argument is ignored if it is empty. Note that `"trailing"` #' applies only to arguments passed in `...`, not to named #' arguments. On the other hand, `"all"` also applies to named #' arguments. #' @param .unquote_names Whether to treat `:=` as `=`. Unlike `=`, the #' `:=` syntax supports `!!` unquoting on the LHS. #' @name nse-defuse #' @aliases quotation #' @examples #' # expr() and exprs() capture expressions that you supply: #' expr(symbol) #' exprs(several, such, symbols) #' #' # enexpr() and enexprs() capture expressions that your user supplied: #' expr_inputs <- function(arg, ...) { #' user_exprs <- enexprs(arg, ...) #' user_exprs #' } #' expr_inputs(hello) #' expr_inputs(hello, bonjour, ciao) #' #' # ensym() and ensyms() provide additional type checking to ensure #' # the user calling your function has supplied bare object names: #' sym_inputs <- function(...) { #' user_symbols <- ensyms(...) #' user_symbols #' } #' sym_inputs(hello, "bonjour") #' ## sym_inputs(say(hello)) # Error: Must supply symbols or strings #' expr_inputs(say(hello)) #' #' #' # All these quoting functions have quasiquotation support. This #' # means that you can unquote (evaluate and inline) part of the #' # captured expression: #' what <- sym("bonjour") #' expr(say(what)) #' expr(say(!!what)) #' #' # This also applies to expressions supplied by the user. This is #' # like an escape hatch that allows control over the captured #' # expression: #' expr_inputs(say(!!what), !!what) #' #' #' # Finally, you can capture expressions as quosures. A quosure is an #' # object that contains both the expression and its environment: #' quo <- quo(letters) #' quo #' #' get_expr(quo) #' get_env(quo) #' #' # Quosures can be evaluated with eval_tidy(): #' eval_tidy(quo) #' #' # They have the nice property that you can pass them around from #' # context to context (that is, from function to function) and they #' # still evaluate in their original environment: #' multiply_expr_by_10 <- function(expr) { #' # We capture the user expression and its environment: #' expr <- enquo(expr) #' #' # Then create an object that only exists in this function: #' local_ten <- 10 #' #' # Now let's create a multiplication expression that (a) inlines #' # the user expression as LHS (still wrapped in its quosure) and #' # (b) refers to the local object in the RHS: #' quo(!!expr * local_ten) #' } #' quo <- multiply_expr_by_10(2 + 3) #' #' # The local parts of the quosure are printed in colour if your #' # terminal is capable of displaying colours: #' quo #' #' # All the quosures in the expression evaluate in their original #' # context. The local objects are looked up properly and we get the #' # expected result: #' eval_tidy(quo) NULL #' @rdname nse-defuse #' @export expr <- function(expr) { enexpr(expr) } #' @rdname nse-defuse #' @export enexpr <- function(arg) { .Call(rlang_enexpr, substitute(arg), parent.frame()) } #' @rdname nse-defuse #' @export exprs <- function(..., .named = FALSE, .ignore_empty = c("trailing", "none", "all"), .unquote_names = TRUE) { .Call(rlang_exprs_interp, frame_env = environment(), named = .named, ignore_empty = .ignore_empty, unquote_names = .unquote_names, homonyms = "keep", check_assign = FALSE ) } #' @rdname nse-defuse #' @export enexprs <- function(..., .named = FALSE, .ignore_empty = c("trailing", "none", "all"), .unquote_names = TRUE, .homonyms = c("keep", "first", "last", "error"), .check_assign = FALSE) { endots( call = sys.call(), frame_env = parent.frame(), capture_arg = rlang_enexpr, capture_dots = rlang_exprs_interp, named = .named, ignore_empty = .ignore_empty, unquote_names = .unquote_names, homonyms = .homonyms, check_assign = .check_assign ) } #' @rdname nse-defuse #' @export ensym <- function(arg) { .Call(rlang_ensym, substitute(arg), parent.frame()) } #' @rdname nse-defuse #' @export ensyms <- function(..., .named = FALSE, .ignore_empty = c("trailing", "none", "all"), .unquote_names = TRUE, .homonyms = c("keep", "first", "last", "error"), .check_assign = FALSE) { exprs <- endots( call = sys.call(), frame_env = parent.frame(), capture_arg = rlang_enexpr, capture_dots = rlang_exprs_interp, named = .named, ignore_empty = .ignore_empty, unquote_names = .unquote_names, homonyms = .homonyms, check_assign = .check_assign ) map(exprs, function(expr) { if (is_quosure(expr)) { expr <- quo_get_expr(expr) } sym(expr) }) } #' @rdname nse-defuse #' @export quo <- function(expr) { enquo(expr) } #' @rdname nse-defuse #' @export enquo <- function(arg) { .Call(rlang_enquo, substitute(arg), parent.frame()) } #' @rdname nse-defuse #' @export quos <- function(..., .named = FALSE, .ignore_empty = c("trailing", "none", "all"), .unquote_names = TRUE) { .Call(rlang_quos_interp, frame_env = environment(), named = .named, ignore_empty = .ignore_empty, unquote_names = .unquote_names, homonyms = "keep", check_assign = FALSE ) } #' @rdname nse-defuse #' @export enquos <- function(..., .named = FALSE, .ignore_empty = c("trailing", "none", "all"), .unquote_names = TRUE, .homonyms = c("keep", "first", "last", "error"), .check_assign = FALSE) { quos <- endots( call = sys.call(), frame_env = parent.frame(), capture_arg = rlang_enquo, capture_dots = rlang_quos_interp, named = .named, ignore_empty = .ignore_empty, unquote_names = .unquote_names, homonyms = .homonyms, check_assign = .check_assign ) structure(quos, class = "quosures") } capture_args <- c( ".named", ".ignore_empty", ".unquote_names", ".homonyms", ".check_assign" ) endots <- function(call, frame_env, capture_arg, capture_dots, named, ignore_empty, unquote_names, homonyms, check_assign) { ignore_empty <- arg_match(ignore_empty, c("trailing", "none", "all")) syms <- as.list(node_cdr(call)) if (!is_null(names(syms))) { is_arg <- names(syms) %in% capture_args syms <- syms[!is_arg] } # Avoid note about registration problems dot_call <- .Call splice_dots <- FALSE dots <- map(syms, function(sym) { if (!is_symbol(sym)) { abort("Inputs to capture must be argument names") } if (identical(sym, dots_sym)) { splice_dots <<- TRUE splice(dot_call(capture_dots, frame_env = frame_env, named = named, ignore_empty = ignore_empty, unquote_names = unquote_names, homonyms = homonyms, check_assign = check_assign )) } else { dot_call(capture_arg, sym, frame_env) } }) if (splice_dots) { dots <- flatten_if(dots, is_spliced) } if (ignore_empty == "all") { if (identical(capture_arg, rlang_enquo)) { dot_is_missing <- quo_is_missing } else { dot_is_missing <- is_missing } dots <- keep(dots, negate(dot_is_missing)) } if (named) { dots <- quos_auto_name(dots) } names(dots) <- names2(dots) dots } #' Ensure that all elements of a list of expressions are named #' #' This gives default names to unnamed elements of a list of #' expressions (or expression wrappers such as formulas or #' quosures). `exprs_auto_name()` deparses the expressions with #' [expr_name()] by default. `quos_auto_name()` deparses with #' [quo_name()]. #' #' @param exprs A list of expressions. #' @param width Deprecated. Maximum width of names. #' @param printer Deprecated. A function that takes an expression #' and converts it to a string. This function must take an #' expression as the first argument and `width` as the second #' argument. #' @export exprs_auto_name <- function(exprs, width = NULL, printer = NULL) { if (!is_null(width)) { warn_deprecated(paste_line( "The `width` argument is deprecated as of rlang 0.3.0." )) } if (!is_null(printer)) { warn_deprecated(paste_line( "The `printer` argument is deprecated as of rlang 0.3.0." )) } have_name <- have_name(exprs) if (any(!have_name)) { nms <- map_chr(exprs[!have_name], as_label) names(exprs)[!have_name] <- nms } exprs } #' @rdname exprs_auto_name #' @param quos A list of quosures. #' @export quos_auto_name <- function(quos, width = NULL) { exprs_auto_name(quos, width = width) } rlang/R/quo.R0000644000176200001440000004671713563530577012542 0ustar liggesusers#' Quosure getters, setters and testers #' #' @description #' #' A quosure is a type of [quoted expression][nse-defuse] that includes #' a reference to the context where it was created. A quosure is thus #' guaranteed to evaluate in its original environment and can refer to #' local objects. #' #' You can access the quosure components (its expression and its #' environment) with: #' #' * [get_expr()] and [get_env()]. These getters also support other #' kinds of objects such as formulas. #' #' * `quo_get_expr()` and `quo_get_env()`. These getters only work #' with quosures and throw an error with other types of input. #' #' Test if an object is a quosure with `is_quosure()`. If you know an #' object is a quosure, use the `quo_` prefixed predicates to check #' its contents, `quo_is_missing()`, `quo_is_symbol()`, etc. #' #' #' @section Quosured constants: #' #' A quosure usually does not carry environments for [constant #' objects][is_syntactic_literal] like strings or numbers. [quo()] and #' [enquo()] only capture an environment for [symbolic #' expressions][is_symbolic]. For instance, all of these return the #' [empty environment][empty_env]: #' #' ``` #' quo_get_env(quo("constant")) #' quo_get_env(quo(100)) #' quo_get_env(quo(NA)) #' ``` #' #' On the other hand, quosures capture the environment of symbolic #' expressions, i.e. expressions whose meaning depends on the #' environment in which they are evaluated and what objects are #' defined there: #' #' ``` #' quo_get_env(quo(some_object)) #' quo_get_env(quo(some_function())) #' ``` #' #' #' @section Empty quosures: #' #' When missing arguments are captured as quosures, either through #' [enquo()] or [quos()], they are returned as an empty quosure. These #' quosures contain the [missing argument][missing_arg] and typically #' have the [empty environment][empty_env] as enclosure. #' #' #' @section Life cycle: #' #' - `is_quosure()` is stable. #' #' - `quo_get_expr()` and `quo_get_env()` are stable. #' #' @name quosure #' @seealso [quo()] for creating quosures by quotation; [as_quosure()] #' and [new_quosure()] for constructing quosures manually. #' @examples #' quo <- quo(my_quosure) #' quo #' #' #' # Access and set the components of a quosure: #' quo_get_expr(quo) #' quo_get_env(quo) #' #' quo <- quo_set_expr(quo, quote(baz)) #' quo <- quo_set_env(quo, empty_env()) #' quo #' #' # Test wether an object is a quosure: #' is_quosure(quo) #' #' # If it is a quosure, you can use the specialised type predicates #' # to check what is inside it: #' quo_is_symbol(quo) #' quo_is_call(quo) #' quo_is_null(quo) #' #' # quo_is_missing() checks for a special kind of quosure, the one #' # that contains the missing argument: #' quo() #' quo_is_missing(quo()) #' #' fn <- function(arg) enquo(arg) #' fn() #' quo_is_missing(fn()) NULL #' @rdname quosure #' @param x An object to test. #' @export is_quosure <- function(x) { inherits(x, "quosure") } #' @rdname quosure #' @param quo A quosure to test. #' @export quo_is_missing <- function(quo) { .Call(rlang_quo_is_missing, quo) } #' @rdname quosure #' @param name The name of the symbol or function call. If `NULL` the #' name is not tested. #' @export quo_is_symbol <- function(quo, name = NULL) { is_symbol(quo_get_expr(quo), name = name) } #' @rdname quosure #' @inheritParams is_call #' @export quo_is_call <- function(quo, name = NULL, n = NULL, ns = NULL) { is_call(quo_get_expr(quo), name = name, n = n, ns = ns) } #' @rdname quosure #' @export quo_is_symbolic <- function(quo) { .Call(rlang_quo_is_symbolic, quo) } #' @rdname quosure #' @export quo_is_null <- function(quo) { .Call(rlang_quo_is_null, quo) } #' @rdname quosure #' @export quo_get_expr <- function(quo) { .Call(rlang_quo_get_expr, quo) } #' @rdname quosure #' @export quo_get_env <- function(quo) { .Call(rlang_quo_get_env, quo) } #' @rdname quosure #' @param expr A new expression for the quosure. #' @export quo_set_expr <- function(quo, expr) { .Call(rlang_quo_set_expr, quo, expr) } #' @rdname quosure #' @param env A new environment for the quosure. #' @export quo_set_env <- function(quo, env) { .Call(rlang_quo_set_env, quo, env) } #' Create a list of quosures #' #' @description #' #' This small S3 class provides methods for `[` and `c()` and ensures #' the following invariants: #' #' * The list only contains quosures. #' * It is always named, possibly with a vector of empty strings. #' #' `new_quosures()` takes a list of quosures and adds the `quosures` #' class and a vector of empty names if needed. `as_quosures()` calls #' [as_quosure()] on all elements before creating the `quosures` #' object. #' #' @param x A list of quosures or objects to coerce to quosures. #' @param env The default environment for the new quosures. #' @param named Whether to name the list with [quos_auto_name()]. #' @export new_quosures <- function(x) { if (!is_list(x) || !every(x, is_quosure)) { abort("Expected a list of quosures") } structure(x, class = "quosures", names = names2(x) ) } #' @rdname new_quosures #' @export as_quosures <- function(x, env, named = FALSE) { x <- map(x, as_quosure, env = env) if (named) { x <- quos_auto_name(x) } new_quosures(x) } #' @rdname new_quosures #' @export is_quosures <- function(x) { inherits(x, "quosures") } #' @export `[.quosures` <- function(x, i) { structure(NextMethod(), class = "quosures") } #' @export c.quosures <- function(..., recursive = FALSE) { out <- NextMethod() if (every(out, is_quosure)) { new_quosures(out) } else { warn_deprecated(paste_line( "Quosure lists can't be concatenated with objects other than quosures as of rlang 0.3.0.", "Please call `as.list()` on the quosure list first." )) out } } #' @export print.quosures <- function(x, ...) { cat_line(">\n") print(unclass(x), ...) } #' @export as.list.quosures <- function(x, ...) { unclass(x) } #' @export `[<-.quosures` <- function(x, i, value) { if (idx <- detect_index(value, negate(is_quosure))) { signal_quosure_assign(value[[idx]]) } NextMethod() } #' @export `[[<-.quosures` <- function(x, i, value) { if (!is_quosure(value) && !is_null(value)) { signal_quosure_assign(value) } NextMethod() } #' @export `$<-.quosures` <- function(x, name, value) { x[[name]] <- value x } signal_quosure_assign <- function(x) { warn_deprecated(paste_line( "Assigning non-quosure objects to quosure lists is deprecated as of rlang 0.3.0.", "Please coerce to a bare list beforehand with `as.list()`" )) } # Dynamically registered pillar_shaft.quosures <- function(x, ...) { labels <- map_chr(unname(x), as_label) structure(labels, width = 10L) } type_sum.quosures <- function(x) { "quos" } #' Coerce object to quosure #' #' @description #' #' While `new_quosure()` wraps any R object (including expressions, #' formulas, or other quosures) into a quosure, `as_quosure()` #' converts formulas and quosures and does not double-wrap. #' #' #' @section Life cycle: #' #' - `as_quosure()` now requires an explicit default environment for #' creating quosures from symbols and calls. #' #' - `as_quosureish()` is deprecated as of rlang 0.2.0. This function #' assumes that quosures are formulas which is currently true but #' might not be in the future. #' #' @param x An object to convert. Either an [expression][is_expression] or a #' formula. #' @param env The environment in which the expression should be #' evaluated. Only used for symbols and calls. This should typically #' be the environment in which the expression was created. #' @seealso [quo()], [is_quosure()] #' @export #' @examples #' # as_quosure() converts expressions or any R object to a validly #' # scoped quosure: #' env <- env(var = "thing") #' as_quosure(quote(var), env) #' #' #' # The environment is ignored for formulas: #' as_quosure(~foo, env) #' as_quosure(~foo) #' #' # However you must supply it for symbols and calls: #' try(as_quosure(quote(var))) as_quosure <- function(x, env = NULL) { if (is_quosure(x)) { return(x) } if (is_bare_formula(x)) { env <- f_env(x) if (is_null(env)) { abort(paste_line( "The formula does not have an environment.", "This is a quoted formula that was never evaluated." )) } return(new_quosure(f_rhs(x), env)) } if (is_symbolic(x)) { if (is_null(env)) { warn_deprecated(paste_line( "`as_quosure()` requires an explicit environment as of rlang 0.3.0.", "Please supply `env`." )) env <- caller_env() } return(new_quosure(x, env)) } new_quosure(x, empty_env()) } #' @rdname as_quosure #' @param expr The expression wrapped by the quosure. #' @export new_quosure <- function(expr, env = caller_env()) { .Call(rlang_new_quosure, expr, env) } #' Squash a quosure #' #' @description #' #' `quo_squash()` flattens all nested quosures within an expression. #' For example it transforms `^foo(^bar(), ^baz)` to the bare #' expression `foo(bar(), baz)`. #' #' This operation is safe if the squashed quosure is used for #' labelling or printing (see [quo_label()] or [quo_name()]). However #' if the squashed quosure is evaluated, all expressions of the #' flattened quosures are resolved in a single environment. This is a #' source of bugs so it is good practice to set `warn` to `TRUE` to #' let the user know about the lossy squashing. #' #' #' @section Life cycle: #' #' This function replaces `quo_expr()` which was deprecated in #' rlang 0.2.0. `quo_expr()` was a misnomer because it implied that it #' was a mere expression acccessor for quosures whereas it was really #' a lossy operation that squashed all nested quosures. #' #' #' @param quo A quosure or expression. #' @param warn Whether to warn if the quosure contains other quosures #' (those will be collapsed). This is useful when you use #' `quo_squash()` in order to make a non-tidyeval API compatible #' with quosures. In that case, getting rid of the nested quosures #' is likely to cause subtle bugs and it is good practice to warn #' the user about it. #' #' @export #' @examples #' # Quosures can contain nested quosures: #' quo <- quo(wrapper(!!quo(wrappee))) #' quo #' #' # quo_squash() flattens all the quosures and returns a simple expression: #' quo_squash(quo) quo_squash <- function(quo, warn = FALSE) { # Never warn when unwrapping outer quosure if (is_quosure(quo)) { quo <- quo_get_expr(quo) } if (is_missing(quo)) { missing_arg() } else { quo_squash_impl(duplicate(quo), warn = warn) } } #' Format quosures for printing or labelling #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} #' #' **Note:** You should now use [as_label()] or [as_name()] instead #' of `quo_name()`. See life cycle section below. #' #' These functions take an arbitrary R object, typically an #' [expression][is_expression], and represent it as a string. #' #' * `quo_name()` returns an abbreviated representation of the object #' as a single line string. It is suitable for default names. #' #' * `quo_text()` returns a multiline string. For instance block #' expressions like `{ foo; bar }` are represented on 4 lines (one #' for each symbol, and the curly braces on their own lines). #' #' These deparsers are only suitable for creating default names or #' printing output at the console. The behaviour of your functions #' should not depend on deparsed objects. If you are looking for a way #' of transforming symbols to strings, use [as_string()] instead of #' `quo_name()`. Unlike deparsing, the transformation between symbols #' and strings is non-lossy and well defined. #' #' @inheritParams quo_squash #' @inheritParams expr_label #' #' @section Life cycle: #' #' These functions are in the questioning life cycle stage. #' #' * [as_label()] and [as_name()] should be used instead of #' `quo_name()`. `as_label()` transforms any R object to a string #' but should only be used to create a default name. Labelisation is #' not a well defined operation and no assumption should be made #' about the label. On the other hand, `as_name()` only works with #' (possibly quosured) symbols, but is a well defined and #' deterministic operation. #' #' * We don't have a good replacement for `quo_text()` yet. See #' to follow discussions #' about a new deparsing API. #' #' @seealso [expr_label()], [f_label()] #' @examples #' # Quosures can contain nested quosures: #' quo <- quo(foo(!! quo(bar))) #' quo #' #' # quo_squash() unwraps all quosures and returns a raw expression: #' quo_squash(quo) #' #' # This is used by quo_text() and quo_label(): #' quo_text(quo) #' #' # Compare to the unwrapped expression: #' expr_text(quo) #' #' # quo_name() is helpful when you need really short labels: #' quo_name(quo(sym)) #' quo_name(quo(!! sym)) #' @export quo_label <- function(quo) { expr_label(quo_squash(quo)) } #' @rdname quo_label #' @export quo_text <- function(quo, width = 60L, nlines = Inf) { expr_text(quo_squash(quo), width = width, nlines = nlines) } #' @rdname quo_label #' @export quo_name <- function(quo) { expr_name(quo_squash(quo)) } quo_squash_impl <- function(x, parent = NULL, warn = FALSE) { switch_expr(x, language = { if (is_quosure(x)) { if (!is_false(warn)) { if (is_string(warn)) { msg <- warn } else { msg <- "Collapsing inner quosure" } warn(msg) warn <- FALSE } while (is_quosure(x)) { x <- quo_get_expr(x) } if (!is_null(parent)) { node_poke_car(parent, x) } quo_squash_impl(x, parent, warn = warn) } else { quo_squash_impl(node_cdr(x), warn = warn) } }, pairlist = { while (!is_null(x)) { quo_squash_impl(node_car(x), x, warn = warn) x <- node_cdr(x) } } ) x } #' @export print.quosure <- function(x, ...) { cat_line(.trailing = FALSE, bold(""), "expr: " ) quo_print(x) cat_line(.trailing = FALSE, "env: " ) env <- quo_get_env(x) quo_env_print(env) invisible(x) } #' @export str.quosure <- function(object, ...) { str(unclass(object), ...) } #' @export as.character.quosure <- function(x, ...) { warn_deprecated(paste_line( "Using `as.character()` on a quosure is deprecated as of rlang 0.3.0.", "Please use `as_label()` or `as_name()` instead." )) NextMethod() } #' @export `[.quosure` <- function(x, i, ...) { signal_soft_deprecated(c( "Subsetting quosures with `[` is deprecated as of rlang 0.4.0", "Please use `quo_get_expr()` instead." )) NextMethod() } #' @export `[[.quosure` <- function(x, i, ...) { signal_soft_deprecated(c( "Subsetting quosures with `[[` is deprecated as of rlang 0.4.0", "Please use `quo_get_expr()` instead." )) NextMethod() } # Create a circular list of colours. This infloops if printed in the REPL! new_quo_palette <- function() { last_node <- new_node(open_cyan, NULL) palette <- new_node(open_blue, new_node(open_green, new_node(open_magenta, last_node))) node_poke_cdr(last_node, palette) # First node has no colour new_node(close_colour, palette) } # Reproduces output of printed calls base_deparse <- function(x) { deparse(x, control = "keepInteger") } quo_deparse <- function(x, lines = new_quo_deparser()) { if (!is_quosure(x)) { return(sexp_deparse(x, lines = lines)) } env <- quo_get_env(x) lines$quo_open_colour(env) lines$push("^") lines$make_next_sticky() sexp_deparse(quo_get_expr(x), lines) lines$quo_reset_colour() lines$get_lines() } new_quo_deparser <- function(width = peek_option("width"), crayon = has_crayon()) { lines <- new_lines(width = width, deparser = quo_deparse) child_r6lite(lines, has_colour = crayon, quo_envs = list(), quo_history = pairlist(), quo_colours = list( open_blue, open_green, open_magenta, open_cyan, open_yellow ), quo_was_too_many = FALSE, quo_push_opener = function(self, opener) { self$quo_history <- new_node(opener, self$quo_history) self$push_sticky(opener()) self }, quo_open_colour = function(self, env) { if (self$has_colour) { if (is_reference(env, global_env()) || is_reference(env, empty_env())) { self$quo_push_opener(close_colour) return(NULL) } n_known_envs <- length(self$quo_envs) idx <- detect_index(self$quo_envs, identical, env) if (idx) { opener <- self$quo_colours[[idx]] } else if (n_known_envs < length(self$quo_colours)) { self$quo_envs <- c(self$quo_envs, list(env)) idx <- n_known_envs + 1L opener <- self$quo_colours[[idx]] } else { opener <- function() paste0(close_colour(), open_blurred_italic()) self$quo_was_too_many <- TRUE } self$quo_push_opener(opener) } }, quo_reset_colour = function(self) { if (self$has_colour) { if (self$quo_was_too_many) { self$push_sticky(close_blurred_italic()) } self$quo_history <- node_cdr(self$quo_history) reset <- node_car(self$quo_history) %||% close_colour self$push_sticky(reset()) } } ) } quo_print <- function(quo) { # Take into account the first 8-character wide columns width <- peek_option("width") - 10L deparser <- new_quo_deparser(width = width) lines <- quo_deparse(quo, deparser) n <- length(lines) lines[seq2(2, n)] <- paste0(" ", lines[seq2(2, n)]) cat(paste0(lines, "\n")) } quo_env_print <- function(env) { nm <- env_label(env) if (!is_reference(env, global_env()) && !is_reference(env, empty_env())) { nm <- blue(nm) } cat_line(nm) } #' @export Ops.quosure <- function(e1, e2) { if (identical(.Generic, "!")) { abort(paste_line( "Quosures can only be unquoted within a quasiquotation context.", "", " # Bad:", " list(!!myquosure)", "", " # Good:", " dplyr::mutate(data, !!myquosure)" )) } if (missing(e2)) { bad <- sprintf(" %s%s", .Generic, "myquosure") good <- sprintf(" %s!!%s", .Generic, "myquosure") } else if (is_quosure(e1) && is_quosure(e2)) { bad <- sprintf(" myquosure1 %s myquosure2", .Generic) good <- sprintf(" !!myquosure1 %s !!myquosure2", .Generic) } else if (is_quosure(e1)) { bad <- sprintf(" myquosure %s rhs", .Generic) good <- sprintf(" !!myquosure %s rhs", .Generic) } else { bad <- sprintf(" lhs %s myquosure", .Generic) good <- sprintf(" lhs %s !!myquosure", .Generic) } abort(paste_line( "Base operators are not defined for quosures.", "Do you need to unquote the quosure?", "", " # Bad:", bad, "", " # Good:", good, )) } abort_quosure_op <- function(group, op) { abort(paste_line( sprintf("%s operations are not defined for quosures.", group), "Do you need to unquote the quosure?", "", " # Bad:", sprintf(" %s(myquosure)", op), "", " # Good:", sprintf(" %s(!!myquosure)", op), )) } #' @export Math.quosure <- function(x, ...) { abort_quosure_op("Math", .Generic) } #' @export Summary.quosure <- function(x, ...) { abort_quosure_op("Summary", .Generic) } #' @export mean.quosure <- function(x, na.rm = TRUE, ...) { abort_quosure_op("Summary", "mean") } #' @importFrom stats median #' @export median.quosure <- function(x, na.rm = TRUE, ...) { abort_quosure_op("Summary", "median") } #' @importFrom stats quantile #' @export quantile.quosure <- function(x, na.rm = TRUE, ...) { abort_quosure_op("Summary", "quantile") } rlang/R/utils.R0000644000176200001440000001400413612344312013037 0ustar liggesusers substitute_ <- function(x, env) { if (identical(env, globalenv())) { env <- as.list(env) } call <- substitute(substitute(x, env), list(x = x)) eval_bare(call) } drop_last <- function(x) { x[-length(x)] } drop_first <- function(x) { x[-1] } set_names2 <- function(x, nms = names2(x)) { empty <- nms == "" nms[empty] <- x[empty] names(x) <- nms x } imap <- function(.x, .f, ...) { idx <- names(.x) %||% seq_along(.x) out <- Map(.f, idx, .x, ...) names(out) <- names(.x) out } imap_chr <- function(.x, .f, ...) { as.vector(imap(.x, .f, ...), "character") } map_around <- function(.x, .neighbour = c("right", "left"), .f, ...) { where <- arg_match(.neighbour) n <- length(.x) out <- vector("list", n) if (n == 0) { return(.x) } if (n == 1) { out[[1]] <- .f(.x[[1]], missing_arg(), ...) return(out) } if (n > 1 && where == "right") { neighbours <- .x[seq(2, n)] idx <- seq_len(n - 1) out[idx] <- Map(.f, .x[idx], neighbours, ...) out[[n]] <- .f(.x[[n]], missing_arg(), ...) return(out) } if (n > 1 && where == "left") { neighbours <- .x[seq(1, n - 1)] idx <- seq(2, n) out[idx] <- Map(.f, .x[idx], neighbours, ...) out[[1]] <- .f(.x[[1]], missing_arg(), ...) return(out) } stop("unimplemented") } discard_unnamed <- function(x) { if (is_environment(x)) { x } else { discard(x, names2(x) == "") } } captureArgInfo <- function(x) { args <- pairlist(parent.frame()) .Call(rlang_capturearginfo, NULL, NULL, args, environment()) } captureDots <- function() { args <- pairlist(parent.frame()) .Call(rlang_capturedots, NULL, NULL, args, environment()) } cat_line <- function(..., .trailing = TRUE, file = "") { cat(paste_line(..., .trailing = .trailing), file = file) } paste_line <- function(..., .trailing = FALSE) { lines <- paste(chr(...), collapse = "\n") if (.trailing) { lines <- paste0(lines, "\n") } lines } has_crayon <- function() { is_installed("crayon") && crayon::has_color() } red <- function(x) if (has_crayon()) crayon::red(x) else x blue <- function(x) if (has_crayon()) crayon::blue(x) else x green <- function(x) if (has_crayon()) crayon::green(x) else x yellow <- function(x) if (has_crayon()) crayon::yellow(x) else x magenta <- function(x) if (has_crayon()) crayon::magenta(x) else x cyan <- function(x) if (has_crayon()) crayon::cyan(x) else x blurred <- function(x) if (has_crayon()) crayon::blurred(x) else x silver <- function(x) if (has_crayon()) crayon::silver(x) else x bold <- function(x) if (has_crayon()) crayon::bold(x) else x italic <- function(x) if (has_crayon()) crayon::italic(x) else x underline <- function(x) if (has_crayon()) crayon::underline(x) else x open_red <- function() if (has_crayon()) open_style("red") open_blue <- function() if (has_crayon()) open_style("blue") open_green <- function() if (has_crayon()) open_style("green") open_yellow <- function() if (has_crayon()) open_style("yellow") open_magenta <- function() if (has_crayon()) open_style("magenta") open_cyan <- function() if (has_crayon()) open_style("cyan") close_colour <- function() if (has_crayon()) "\u001b[39m" close_italic <- function() if (has_crayon()) "\u001b[23m" open_yellow_italic <- function() if (has_crayon()) "\u001b[33m\u001b[3m" open_blurred_italic <- function() if (has_crayon()) "\u001b[2m\u001b[3m" close_blurred_italic <- function() if (has_crayon()) "\u001b[23m\u001b[22m" bullet <- function(x) { paste0(bold(silver("* ")), x) } open_style <- function(style) { paste0("\u001b[", codes[[style]][[1]], "m") } close_style <- function(style) { paste0("\u001b[", codes[[style]][[2]], "m") } ansi_regex <- paste0( "(?:(?:\\x{001b}\\[)|\\x{009b})", "(?:(?:[0-9]{1,3})?(?:(?:;[0-9]{0,3})*)?[A-M|f-m])", "|\\x{001b}[A-M]" ) strip_style <- function(x) { gsub(ansi_regex, "", x, perl = TRUE) } codes <- list( reset = c(0L, 0L), bold = c(1L, 22L), blurred = c(2L, 22L), italic = c(3L, 23L), underline = c(4L, 24L), inverse = c(7L, 27L), hidden = c(8L, 28L), strikethrough = c(9L, 29L), black = c(30L, 39L), red = c(31L, 39L), green = c(32L, 39L), yellow = c(33L, 39L), blue = c(34L, 39L), magenta = c(35L, 39L), cyan = c(36L, 39L), white = c(37L, 39L), silver = c(90L, 39L), bgBlack = c(40L, 49L), bgRed = c(41L, 49L), bgGreen = c(42L, 49L), bgYellow = c(43L, 49L), bgBlue = c(44L, 49L), bgMagenta = c(45L, 49L), bgCyan = c(46L, 49L), bgWhite = c(47L, 49L) ) `$.r6lite` <- function(self, arg) { field <- env_get(self, as_string(substitute(arg)), inherit = TRUE) if (is_function(field)) { expr_interp(function(...) { # Unquote the method so it is printable method <- !!field method(self, ...) }) } else { field } } r6lite <- function(...) { structure(new_environment(list2(...)), class = "r6lite") } child_r6lite <- function(.parent, ...) { structure(child_env(.parent, ...), class = "r6lite") } inc <- function(x) { x + 1L } dec <- function(x) { x - 1L } pluralise <- function(n, singular, plural) { if (n == 1) { singular } else { plural } } pluralise_along <- function(x, singular, plural) { pluralise(length(x), singular, plural) } pluralise_n <- function(n, singular, plural) { pluralise(n, singular, plural) } pad_spaces <- function(x, left = TRUE) { widths <- nchar(x) pads <- max(widths) - widths if (left) { paste0(spaces(pads), x) } else { paste0(x, spaces(pads)) } } info <- function() { i <- if (is_installed("cli")) cli::symbol$info else "i" blue(i) } cross <- function() { x <- if (is_installed("cli")) cli::symbol$cross else "x" red(x) } strip_trailing_newline <- function(x) { n <- nchar(x) if (substr(x, n, n) == "\n") { substr(x, 0, n - 1L) } else { x } } rlang/R/parse.R0000644000176200001440000000670613561023554013030 0ustar liggesusers#' Parse R code #' #' These functions parse and transform text into R expressions. This #' is the first step to interpret or evaluate a piece of R code #' written by a programmer. #' #' `parse_expr()` returns one expression. If the text contains more #' than one expression (separated by semicolons or new lines), an error is #' issued. On the other hand `parse_exprs()` can handle multiple #' expressions. It always returns a list of expressions (compare to #' [base::parse()] which returns a base::expression vector). All #' functions also support R connections. #' #' The versions suffixed with `_quo` and `_quos` return #' [quosures][nse-defuse] rather than raw expressions. #' #' #' @section Life cycle: #' #' - `parse_quosure()` and `parse_quosures()` were soft-deprecated in #' rlang 0.2.0 and renamed to `parse_quo()` and `parse_quos()`. This #' is consistent with the rule that abbreviated suffixes indicate #' the return type of a function. #' #' @param x Text containing expressions to parse_expr for #' `parse_expr()` and `parse_exprs()`. Can also be an R connection, #' for instance to a file. If the supplied connection is not open, #' it will be automatically closed and destroyed. #' @param env The environment for the quosures. Depending on the use #' case, a good default might be the [global #' environment][global_env] but you might also want to evaluate the #' R code in an isolated context (perhaps a child of the global #' environment or of the [base environment][base_env]). #' @return `parse_expr()` returns an [expression][is_expression], #' `parse_exprs()` returns a list of expressions. Note that for the #' plural variants the length of the output may be greater than the #' length of the input. This would happen is one of the strings #' contain several expressions (such as `"foo; bar"`). #' @seealso [base::parse()] #' @export #' @examples #' # parse_expr() can parse any R expression: #' parse_expr("mtcars %>% dplyr::mutate(cyl_prime = cyl / sd(cyl))") #' #' # A string can contain several expressions separated by ; or \n #' parse_exprs("NULL; list()\n foo(bar)") #' #' # You can also parse source files by passing a R connection. Let's #' # create a file containing R code: #' path <- tempfile("my-file.R") #' cat("1; 2; mtcars", file = path) #' #' # We can now parse it by supplying a connection: #' parse_exprs(file(path)) parse_expr <- function(x) { exprs <- parse_exprs(x) n <- length(exprs) if (n == 0) { abort("No expression to parse") } else if (n > 1) { abort("More than one expression parsed") } exprs[[1]] } #' @rdname parse_expr #' @export parse_exprs <- function(x) { if (inherits(x, "connection")) { if (!isOpen(x)) { open(x) on.exit(close(x)) } exprs <- parse(file = x) } else if (is_string(x)) { exprs <- parse(text = x) } else if (is.character(x)) { x <- paste(x, collapse = "; ") exprs <- parse(text = x) } else { abort("`x` must be a character vector or an R connection") } as.list(exprs) } #' @rdname parse_expr #' @export parse_quo <- function(x, env) { if (missing(env)) { abort("The quosure environment should be explicitly supplied as `env`") } new_quosure(parse_expr(x), as_environment(env)) } #' @rdname parse_expr #' @export parse_quos <- function(x, env) { if (missing(env)) { abort("The quosure environment should be explicitly supplied as `env`") } out <- map(parse_exprs(x), new_quosure, env = as_environment(env)) new_quosures(out) } rlang/R/attr.R0000644000176200001440000001551013553605731012665 0ustar liggesusers structure2 <- function(.x, ...) { exec("structure", .Data = .x, ...) } set_class <- function(x, class) { attr(x, "class") <- class x } #' Is object named? #' #' `is_named()` checks that `x` has names attributes, and that none of #' the names are missing or empty (`NA` or `""`). `is_dictionaryish()` #' checks that an object is a dictionary: that it has actual names and #' in addition that there are no duplicated names. `have_name()` #' is a vectorised version of `is_named()`. #' #' @param x An object to test. #' @return `is_named()` and `is_dictionaryish()` are scalar predicates #' and return `TRUE` or `FALSE`. `have_name()` is vectorised and #' returns a logical vector as long as the input. #' @export #' @examples #' # A data frame usually has valid, unique names #' is_named(mtcars) #' have_name(mtcars) #' is_dictionaryish(mtcars) #' #' # But data frames can also have duplicated columns: #' dups <- cbind(mtcars, cyl = seq_len(nrow(mtcars))) #' is_dictionaryish(dups) #' #' # The names are still valid: #' is_named(dups) #' have_name(dups) #' #' #' # For empty objects the semantics are slightly different. #' # is_dictionaryish() returns TRUE for empty objects: #' is_dictionaryish(list()) #' #' # But is_named() will only return TRUE if there is a names #' # attribute (a zero-length character vector in this case): #' x <- set_names(list(), character(0)) #' is_named(x) #' #' #' # Empty and missing names are invalid: #' invalid <- dups #' names(invalid)[2] <- "" #' names(invalid)[5] <- NA #' #' # is_named() performs a global check while have_name() can show you #' # where the problem is: #' is_named(invalid) #' have_name(invalid) #' #' # have_name() will work even with vectors that don't have a names #' # attribute: #' have_name(letters) is_named <- function(x) { nms <- names(x) if (is_null(nms)) { return(FALSE) } if (any(nms_are_invalid(nms))) { return(FALSE) } TRUE } #' @rdname is_named #' @export is_dictionaryish <- function(x) { if (!length(x)) { return(!is.null(x)) } is_named(x) && !any(duplicated(names(x))) } #' @rdname is_named #' @export have_name <- function(x) { nms <- names(x) if (is.null(nms)) { rep(FALSE, length(x)) } else { !nms_are_invalid(nms) } } nms_are_invalid <- function(x) { x == "" | is.na(x) } #' Does an object have an element with this name? #' #' This function returns a logical value that indicates if a data #' frame or another named object contains an element with a specific #' name. Note that `has_name()` only works with vectors. For instance, #' environments need the specialised function [env_has()]. #' #' Unnamed objects are treated as if all names are empty strings. `NA` #' input gives `FALSE` as output. #' #' @param x A data frame or another named object #' @param name Element name(s) to check #' @return A logical vector of the same length as `name` #' @examples #' has_name(iris, "Species") #' has_name(mtcars, "gears") #' @export has_name <- function(x, name) { name %in% names2(x) } #' Set names of a vector #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("stable")} #' #' This is equivalent to [stats::setNames()], with more features and #' stricter argument checking. #' #' #' @section Life cycle: #' #' `set_names()` is stable and exported in purrr. #' #' @param x Vector to name. #' @param nm,... Vector of names, the same length as `x`. #' #' You can specify names in the following ways: #' #' * If you do nothing, `x` will be named with itself. #' #' * If `x` already has names, you can provide a function or formula #' to transform the existing names. In that case, `...` is passed #' to the function. #' #' * If `nm` is `NULL`, the names are removed (if present). #' #' * In all other cases, `nm` and `...` are coerced to character. #' #' @export #' @examples #' set_names(1:4, c("a", "b", "c", "d")) #' set_names(1:4, letters[1:4]) #' set_names(1:4, "a", "b", "c", "d") #' #' # If the second argument is ommitted a vector is named with itself #' set_names(letters[1:5]) #' #' # Alternatively you can supply a function #' set_names(1:10, ~ letters[seq_along(.)]) #' set_names(head(mtcars), toupper) #' #' # If the input vector is unnamed, it is first named after itself #' # before the function is applied: #' set_names(letters, toupper) #' #' # `...` is passed to the function: #' set_names(head(mtcars), paste0, "_foo") set_names <- function(x, nm = x, ...) { set_names_impl(x, x, nm, ...) } # FIXME: This can be simplified once the `_along` ctors are defunct set_names_impl <- function(x, mold, nm, ...) { if (!is_vector(x)) { abort("`x` must be a vector") } if (is_function(nm) || is_formula(nm)) { if (is_null(names(mold))) { mold <- as.character(mold) } else { mold <- names2(mold) } nm <- as_function(nm) nm <- nm(mold, ...) } else if (!is_null(nm)) { if (dots_n(...)) { nm <- as.character(c(nm, ...)) } else { nm <- as.character(nm) } } if (!is_null(nm) && !is_character(nm, length(x))) { abort("`nm` must be `NULL` or a character vector the same length as `x`") } names(x) <- nm x } #' Get names of a vector #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("stable")} #' #' This names getter always returns a character vector, even when an #' object does not have a `names` attribute. In this case, it returns #' a vector of empty names `""`. It also standardises missing names to #' `""`. #' #' #' @section Life cycle: #' #' `names2()` is stable. #' #' @param x A vector. #' @export #' @examples #' names2(letters) #' #' # It also takes care of standardising missing names: #' x <- set_names(1:3, c("a", NA, "b")) #' names2(x) names2 <- function(x) { if (typeof(x) == "environment") { abort("Use `env_names()` for environments.") } nms <- names(x) if (is_null(nms)) { rep("", length(x)) } else { nms %|% "" } } # Avoids `NA` names on subset-assign with unnamed vectors `names2<-` <- function(x, value) { if (is_null(names(x))) { names(x) <- names2(x) } names(x) <- value x } length_ <- function(x) { .Call(rlang_length, x) } #' How long is an object? #' #' This is a function for the common task of testing the length of an #' object. It checks the length of an object in a non-generic way: #' [base::length()] methods are ignored. #' #' @param x A R object. #' @param n A specific length to test `x` with. If `NULL`, #' `has_length()` returns `TRUE` if `x` has length greater than #' zero, and `FALSE` otherwise. #' @export #' @keywords internal #' @examples #' has_length(list()) #' has_length(list(), 0) #' #' has_length(letters) #' has_length(letters, 20) #' has_length(letters, 26) has_length <- function(x, n = NULL) { len <- .Call(rlang_length, x) if (is_null(n)) { as.logical(len) } else { len == n } } poke_attributes <- function(x, attrs) { .Call(rlang_poke_attributes, x, attrs) } rlang/R/utils-encoding.R0000644000176200001440000001245513553606402014640 0ustar liggesusers#' Coerce to a character vector and attempt encoding conversion #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} #' #' Unlike specifying the `encoding` argument in `as_string()` and #' `as_character()`, which is only declarative, these functions #' actually attempt to convert the encoding of their input. There are #' two possible cases: #' #' * The string is tagged as UTF-8 or latin1, the only two encodings #' for which R has specific support. In this case, converting to the #' same encoding is a no-op, and converting to native always works #' as expected, as long as the native encoding, the one specified by #' the `LC_CTYPE` locale has support for all characters occurring in #' the strings. Unrepresentable characters are serialised as unicode #' points: "". #' #' * The string is not tagged. R assumes that it is encoded in the #' native encoding. Conversion to native is a no-op, and conversion #' to UTF-8 should work as long as the string is actually encoded in #' the locale codeset. #' #' When translating to UTF-8, the strings are parsed for serialised #' unicode points (e.g. strings looking like "U+xxxx") with #' [chr_unserialise_unicode()]. This helps to alleviate the effects of #' character-to-symbol-to-character roundtrips on systems with #' non-UTF-8 native encoding. #' #' @param x An object to coerce. #' @export #' @keywords internal #' @examples #' # Let's create a string marked as UTF-8 (which is guaranteed by the #' # Unicode escaping in the string): #' utf8 <- "caf\uE9" #' Encoding(utf8) #' as_bytes(utf8) as_utf8_character <- function(x) { .Call(rlang_unescape_character, as_character(x)) } #' Translate unicode points to UTF-8 #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} #' #' For historical reasons, R translates strings to the native encoding #' when they are converted to symbols. This string-to-symbol #' conversion is not a rare occurrence and happens for instance to the #' names of a list of arguments converted to a call by `do.call()`. #' #' If the string contains unicode characters that cannot be #' represented in the native encoding, R serialises those as an ASCII #' sequence representing the unicode point. This is why Windows users #' with western locales often see strings looking like ``. To #' alleviate some of the pain, rlang parses strings and looks for #' serialised unicode points to translate them back to the proper #' UTF-8 representation. This transformation occurs automatically in #' functions like [env_names()] and can be manually triggered with #' `as_utf8_character()` and `chr_unserialise_unicode()`. #' #' #' @section Life cycle: #' #' This function is experimental. #' #' @param chr A character vector. #' @export #' @keywords internal #' @examples #' ascii <- "" #' chr_unserialise_unicode(ascii) #' #' identical(chr_unserialise_unicode(ascii), "\u5e78") chr_unserialise_unicode <- function(chr) { stopifnot(is_character(chr)) .Call(rlang_unescape_character, chr) } #' Create a string #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} #' #' These base-type constructors allow more control over the creation #' of strings in R. They take character vectors or string-like objects #' (integerish or raw vectors), and optionally set the encoding. The #' string version checks that the input contains a scalar string. #' #' @param x A character vector or a vector or list of string-like #' objects. #' @param encoding If non-null, set an encoding mark. This is only #' declarative, no encoding conversion is performed. #' @keywords internal #' @export #' @examples #' # As everywhere in R, you can specify a string with Unicode #' # escapes. The characters corresponding to Unicode codepoints will #' # be encoded in UTF-8, and the string will be marked as UTF-8 #' # automatically: #' cafe <- string("caf\uE9") #' Encoding(cafe) #' as_bytes(cafe) #' #' # In addition, string() provides useful conversions to let #' # programmers control how the string is represented in memory. For #' # encodings other than UTF-8, you'll need to supply the bytes in #' # hexadecimal form. If it is a latin1 encoding, you can mark the #' # string explicitly: #' cafe_latin1 <- string(c(0x63, 0x61, 0x66, 0xE9), "latin1") #' Encoding(cafe_latin1) #' as_bytes(cafe_latin1) string <- function(x, encoding = NULL) { if (is_integerish(x)) { x <- rawToChar(as.raw(x)) } else if (is_raw(x)) { x <- rawToChar(x) } else if (!is_string(x)) { abort("`x` must be a string or raw vector") } if (!is_null(encoding)) { Encoding(x) <- encoding } x } #' Coerce to a raw vector #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} #' #' This currently only works with strings, and returns its hexadecimal #' representation. #' #' #' @section Life cycle: #' #' Raw vector functions are experimental. #' #' @param x A string. #' @return A raw vector of bytes. #' @keywords internal #' @export as_bytes <- function(x) { switch(typeof(x), raw = return(x), character = if (is_string(x)) return(charToRaw(x)) ) abort("`x` must be a string or raw vector") } new_bytes <- function(x) { if (is_integerish(x)) { as.raw(x) } else if (is_raw(x)) { x } else { abort("input should be integerish") } } rlang/R/deparse.R0000644000176200001440000004726113607323615013344 0ustar liggesusers line_push <- function(line, text, sticky = FALSE, boundary = NULL, width = NULL, indent = 0L, has_colour = FALSE) { if (!length(line)) { return(text) } if (!is_string(line)) { abort("`line` must be a string or empty") } if (!is_string(text)) { abort("`text` must be a string") } width <- width %||% peek_option("width") if (!has_overflown(line, text, width, has_colour)) { return(paste0(line, text)) } if (is_scalar_integer(boundary) && nchar(line) != boundary) { first <- substr(line, 0L, boundary) second <- substr(line, boundary + 1L, nchar(line)) # Trim trailing spaces after boundary second <- trim_leading_spaces(second) second <- paste0(spaces(indent), second) if (sticky || !has_overflown(second, text, width, has_colour)) { line <- trim_trailing_spaces(first) text <- paste0(second, text) } else { text <- paste0(spaces(indent), text) } } else if (sticky) { line <- paste0(line, text) text <- chr() } else { line <- trim_trailing_spaces(line) text <- paste0(spaces(indent), text) } c(line, text) } spaces <- function(ns) { map_chr(ns, function(n) paste(rep(" ", n), collapse = "")) } is_spaces <- function(str) { identical(str, spaces(nchar(str))) } has_overflown <- function(line, text, width, has_colour) { if (has_colour) { line <- strip_style(line) text <- strip_style(text) } text <- trim_trailing_spaces(text) nchar(line) + nchar(text) > width && !is_spaces(line) } trim_trailing_spaces <- function(line) { sub(" *$", "", line) } trim_leading_spaces <- function(line) { sub("^ *", "", line) } new_lines <- function(width = peek_option("width"), deparser = sexp_deparse) { width <- width %||% 60L stopifnot(is_integerish(width, n = 1)) r6lite( deparse = function(self, x) { deparser(x, lines = self) }, width = width, boundary = NULL, next_sticky = FALSE, indent = 0L, indent_status = pairlist(), next_indent_sticky = FALSE, has_colour = FALSE, lines = chr(), last_line = chr(), get_lines = function(self) { c(self$lines, self$last_line) }, get_indent = function(self) { if (self$indent < 0) { warn("Internal error: Negative indent while deparsing") 0L } else { self$indent } }, push = function(self, lines) { stopifnot(is_character(lines)) for (line in lines) { self$push_one(line) } self }, push_one = function(self, line) { line <- line_push(self$last_line, line, sticky = self$next_sticky, boundary = self$boundary, width = self$width, indent = self$get_indent(), has_colour = self$has_colour ) n <- length(line) if (n > 1) { self$lines <- c(self$lines, line[-n]) self$last_line <- line[[n]] self$boundary <- NULL self$next_indent_sticky <- FALSE } else if (n) { self$last_line <- line if (self$next_sticky) { self$boundary <- nchar(line) } } self$next_sticky <- FALSE self }, push_newline = function(self) { self$lines <- c(self$lines, self$last_line) self$last_line <- spaces(self$get_indent()) self$next_sticky <- FALSE self$next_indent_sticky <- FALSE self }, push_sticky = function(self, line) { stopifnot(is_string(line)) self$next_sticky <- TRUE self$push(line) self$set_boundary() self }, make_next_sticky = function(self) { self$next_sticky <- TRUE self }, set_boundary = function(self) { self$boundary <- nchar(self$last_line) self }, increase_indent = function(self) { status <- node_car(self$indent_status) if (self$next_indent_sticky) { node_poke_cadr(status, inc(node_cadr(status))) } else { self$indent <- self$indent + 2L self$indent_status <- new_node(new_node(FALSE, new_node(0L, NULL)), self$indent_status) self$next_indent_sticky <- TRUE } self }, decrease_indent = function(self) { status <- node_car(self$indent_status) if (is_null(status)) { warn("Internal error: Detected NULL `status` while deparsing") return(self) } reset <- node_car(status) n_sticky <- node_cadr(status) # Decrease indent level only once for all the openers that were # on a single line if (!reset) { self$indent <- self$indent - 2L node_poke_car(status, TRUE) self$next_indent_sticky <- FALSE } if (n_sticky >= 1L) { node_poke_cadr(status, dec(n_sticky)) } else { self$indent_status <- node_cdr(self$indent_status) self$next_indent_sticky <- FALSE } self } ) } fmls_deparse <- function(x, lines = new_lines()) { lines$push_sticky("(") lines$increase_indent() while (!is_null(x)) { sym_deparse(node_tag(x), lines) car <- node_car(x) if (!is_missing(car)) { lines$push_sticky(" = ") lines$make_next_sticky() lines$deparse(node_car(x)) } x <- node_cdr(x) if (!is_null(x)) { lines$push_sticky(", ") } } lines$push_sticky(")") lines$decrease_indent() lines$get_lines() } fn_call_deparse <- function(x, lines = new_lines()) { lines$push("function") x <- node_cdr(x) fmls_deparse(node_car(x), lines) lines$push_sticky(" ") lines$increase_indent() x <- node_cdr(x) lines$deparse(node_car(x)) lines$decrease_indent() lines$get_lines() } fn_deparse <- function(x, lines) { lines$push("") lines$decrease_indent() lines$get_lines() } while_deparse <- function(x, lines = new_lines()) { x <- node_cdr(x) lines$push("while (") lines$deparse(node_car(x)) x <- node_cdr(x) lines$push(") ") lines$deparse(node_car(x)) lines$get_lines() } for_deparse <- function(x, lines = new_lines()) { x <- node_cdr(x) lines$push("for (") lines$deparse(node_car(x)) x <- node_cdr(x) lines$push(" in ") lines$deparse(node_car(x)) x <- node_cdr(x) lines$push(") ") lines$deparse(node_car(x)) lines$get_lines() } repeat_deparse <- function(x, lines = new_lines()) { lines$push("repeat ") lines$deparse(node_cadr(x)) lines$get_lines() } if_deparse <- function(x, lines = new_lines()) { x <- node_cdr(x) lines$push("if (") lines$deparse(node_car(x)) x <- node_cdr(x) lines$push(") ") lines$deparse(node_car(x)) x <- node_cdr(x) if (!is_null(x)) { lines$push(" else ") lines$deparse(node_car(x)) } lines$get_lines() } # Wrap if the call lower in the AST is not supposed to have # precedence. This sort of AST cannot arise in parsed code but can # occur in constructed calls. operand_deparse <- function(x, parent, side, lines) { wrap <- !call_has_precedence(x, parent, side) if (wrap) { lines$push("(") lines$make_next_sticky() } lines$deparse(x) if (wrap) { lines$push_sticky(")") } } binary_op_deparse <- function(x, lines = new_lines(), space = " ") { # Constructed call without second argument if (is_null(node_cddr(x))) { return(call_deparse(x, lines)) } outer <- x; op <- as_string(node_car(x)) x <- node_cdr(x) operand_deparse(node_car(x), outer, "lhs", lines) lines$push_sticky(paste0(space, op, space)) x <- node_cdr(x) lines$increase_indent() operand_deparse(node_car(x), outer, "rhs", lines) lines$decrease_indent() lines$get_lines() } spaced_op_deparse <- function(x, lines = new_lines()) { binary_op_deparse(x, lines, space = " ") } unspaced_op_deparse <- function(x, lines = new_lines()) { binary_op_deparse(x, lines, space = "") } unary_op_deparse <- function(x, lines = new_lines()) { op <- as_string(node_car(x)) lines$push(op) lines$deparse(node_cadr(x)) lines$get_lines() } brackets_deparse <- function(x, lines = new_lines()) { x <- node_cdr(x) lines$deparse(node_car(x)) args_deparse(node_cdr(x), lines, delims = c("[", "]")) lines$get_lines() } brackets2_deparse <- function(x, lines = new_lines()) { x <- node_cdr(x) lines$deparse(node_car(x)) args_deparse(node_cdr(x), lines, delims = c("[[", "]]")) lines$get_lines() } parens_deparse <- function(x, lines = new_lines()) { lines$push("(") lines$deparse(node_cadr(x)) lines$push(")") lines$get_lines() } braces_deparse <- function(x, lines = new_lines()) { lines$push("{") lines$increase_indent() x <- node_cdr(x) # No need for a newline if the block is empty if (is_null(x)) { lines$push(" }") return(lines$get_lines()) } while (!is_null(x)) { lines$push_newline() lines$deparse(node_car(x)) x <- node_cdr(x) } lines$decrease_indent() lines$push_newline() lines$push("}") lines$get_lines() } sym_deparse <- function(x, lines = new_lines()) { str <- as_string(x) if (needs_backticks(str)) { str <- sprintf("`%s`", str) } lines$push(str)$get_lines() } args_deparse <- function(x, lines = new_lines(), delims = c("(", ")")) { stopifnot(is_character(delims, n = 2)) lines$push_sticky(delims[[1]]) lines$increase_indent() while (!is_null(x)) { tag <- node_tag(x) if (!is_null(tag)) { lines$push(as_string(tag)) lines$push_sticky(" = ") lines$make_next_sticky() } lines$deparse(node_car(x)) x <- node_cdr(x) if (!is_null(x)) { lines$push_sticky(", ") } } lines$push_sticky(delims[[2]]) lines$decrease_indent() lines$get_lines() } call_deparse <- function(x, lines = new_lines()) { car <- node_car(x) type <- call_delimited_type(car) switch(type, parens = { car <- call("(", car) lines$deparse(car) }, backticks = { lines$deparse(node_car(car)) args_deparse(node_cdr(car), lines) }, lines$deparse(car) ) args_deparse(node_cdr(x), lines) } call_delimited_type <- function(call) { if (!is_call(call)) { return("none") } op <- which_operator(call) if (op == "") { return("none") } switch (op, `function` = "parens", `while` = , `for` = , `repeat` = , `if` = , `?` = , `<-` = , `<<-` = , `=` = , `:=` = , `~` = , `|` = , `||` = , `&` = , `&&` = , `>` = , `>=` = , `<` = , `<=` = , `==` = , `!=` = , `+` = , `-` = , `*` = , `/` = , `%%` = , `special` = , `:` = , `^` = , `?unary` = , `~unary` = , `!` = , `!!!` = , `!!` = , `+unary` = , `-unary` = "backticks", `$` = , `@` = , `::` = , `:::` = , `[` = , `[[` = , `(` = , `{` = "none", abort("Internal error: Unexpected operator while deparsing") ) } op_deparse <- function(op, x, lines) { deparser <- switch (op, `function` = fn_call_deparse, `while` = while_deparse, `for` = for_deparse, `repeat` = repeat_deparse, `if` = if_deparse, `?` = , `<-` = , `<<-` = , `=` = , `:=` = , `~` = , `|` = , `||` = , `&` = , `&&` = , `>` = , `>=` = , `<` = , `<=` = , `==` = , `!=` = , `+` = , `-` = , `*` = , `/` = , `%%` = , `special` = spaced_op_deparse, `:` = , `^` = , `$` = , `@` = , `::` = , `:::` = unspaced_op_deparse, `?unary` = , `~unary` = , `!` = , `!!!` = , `!!` = , `+unary` = , `-unary` = unary_op_deparse, `[` = brackets_deparse, `[[` = brackets2_deparse, `(` = parens_deparse, `{` = braces_deparse, abort("Internal error: Unexpected operator while deparsing") ) deparser(x, lines) lines$get_lines() } call_deparser <- function(x) { op <- which_operator(x) if (op != "") { function(x, lines) op_deparse(op, x, lines) } else { call_deparse } } atom_elements <- function(x) { elts <- as.character(x) na_pos <- are_na(x) & !is.nan(x) elts[na_pos] <- "NA" elts[!na_pos] <- switch (typeof(x), integer = paste0(elts[!na_pos], "L"), character = map_chr(elts[!na_pos], deparse), elts[!na_pos] ) elts } is_scalar_deparsable <- function(x) { typeof(x) != "raw" && length(x) == 1 && !is_named(x) } atom_deparse <- function(x, lines = new_lines()) { if (is_scalar_deparsable(x)) { lines$push(deparse(x)) return(NULL) } truncated <- length(x) > 5L if (truncated) { x <- .subset(x, 1:5) } lines$push(paste0("<", rlang_type_sum(x), ": ")) lines$increase_indent() elts <- atom_elements(x) nms <- names2(x) n <- length(elts) for (i in seq_len(n)) { nm <- nms[[i]] if (nzchar(nm)) { lines$push(paste0(nm, " = ")) lines$make_next_sticky() } lines$push(elts[[i]]) if (i != n) { lines$push_sticky(", ") } } if (truncated) { lines$push_sticky(", ") lines$push("...") } lines$push_sticky(">") lines$decrease_indent() lines$get_lines() } list_deparse <- function(x, lines = new_lines()) { if (!length(x) && !is_null(names(x))) { lines$push("") return(lines$get_lines()) } lines$push(paste0(" 5L if (truncated) { x <- .subset(x, 1:5) } nms <- names2(x) n <- length(x) for (i in seq_len(n)) { nm <- nms[[i]] if (nzchar(nm)) { lines$push(paste0(nm, " = ")) lines$make_next_sticky() } lines$deparse(x[[i]]) if (i != n) { lines$push_sticky(", ") } } if (truncated) { lines$push_sticky(", ") lines$push("...") } lines$push_sticky(">") lines$decrease_indent() lines$get_lines() } s3_deparse <- function(x, lines = new_lines()) { lines$push(paste0("<", rlang_type_sum(x), ">")) lines$get_lines() } literal_deparser <- function(type) { function(x, lines = new_lines()) { lines$push(paste0("<", type, ">")) } } default_deparse <- function(x, lines = new_lines()) { lines$push(deparse(x, control = "keepInteger")) lines$get_lines() } sexp_deparse <- function(x, lines = new_lines()) { if (is.object(x)) { return(s3_deparse(x, lines)) } deparser <- switch (typeof(x), symbol = sym_deparse, language = call_deparser(x), closure = fn_deparse, `...` = literal_deparser("..."), any = literal_deparser("any"), environment = literal_deparser("environment"), externalptr = literal_deparser("pointer"), promise = literal_deparser("promise"), weakref = literal_deparser("weakref"), logical = , integer = , double = , complex = , character = , raw = atom_deparse, list = list_deparse, default_deparse ) deparser(x, lines) lines$get_lines() } needs_backticks <- function(str) { if (!is_string(str)) { str <- as_string(str) } n <- nchar(str) if (!n) { return(FALSE) } if (str %in% reserved_words) { return(TRUE) } start <- substr(str, 1, 1) if (!grepl("[[:alpha:].]", start)) { return(TRUE) } if (n == 1) { return(FALSE) } remaining <- substr(str, 2, n) # .0 double literals if (start == "." && grepl("^[[:digit:]]", remaining)) { return(TRUE) } grepl("[^[:alnum:]_.]", remaining) } # From gram.y reserved_words <- c( "NULL", "NA", "TRUE", "FALSE", "Inf", "NaN", "NA_integer_", "NA_real_", "NA_character_", "NA_complex_", "function", "while", "repeat", "for", "if", "in", "else", "next", "break" ) #' Create a default name for an R object #' #' @description #' #' `as_label()` transforms R objects into a short, human-readable #' description. You can use labels to: #' #' * Display an object in a concise way, for example to labellise axes #' in a graphical plot. #' #' * Give default names to columns in a data frame. In this case, #' labelling is the first step before name repair. #' #' See also [as_name()] for transforming symbols back to a #' string. Unlike `as_label()`, `as_string()` is a well defined #' operation that guarantees the roundtrip symbol -> string -> #' symbol. #' #' In general, if you don't know for sure what kind of object you're #' dealing with (a call, a symbol, an unquoted constant), use #' `as_label()` and make no assumption about the resulting string. If #' you know you have a symbol and need the name of the object it #' refers to, use [as_string()]. For instance, use `as_label()` with #' objects captured with `enquo()` and `as_string()` with symbols #' captured with `ensym()`. #' #' @param x An object. #' #' @section Transformation to string: #' #' * Quosures are [squashed][quo_squash] before being labelled. #' * Symbols are transformed to string with `as_string()`. #' * Calls are abbreviated. #' * Numbers are represented as such. #' * Other constants are represented by their type, such as `` #' or ``. #' #' Note that simple symbols should generally be transformed to strings #' with [as_name()]. Labelling is not a well defined operation and #' no assumption should be made about how the label is created. On the #' other hand, `as_name()` only works with symbols and is a well #' defined, deterministic operation. #' #' @seealso [as_name()] for transforming symbols back to a string #' deterministically. #' @examples #' # as_label() is useful with quoted expressions: #' as_label(expr(foo(bar))) #' as_label(expr(foobar)) #' #' # It works with any R object. This is also useful for quoted #' # arguments because the user might unquote constant objects: #' as_label(1:3) #' as_label(base::list) #' @export as_label <- function(x) { x <- quo_squash(x) if (is_missing(x)) { return("") } switch(typeof(x), NULL = "NULL", symbol = as_string(x), language = { if (is_data_pronoun(x)) { data_pronoun_name(x) %||% "" } else { name <- deparse_one(x) name <- gsub("\n.*$", "...", name) name } }, if (is_bare_atomic(x, n = 1)) { name <- expr_text(x) name <- gsub("\n.*$", "...", name) name } else { paste0("<", rlang_type_sum(x), ">") } ) } #' Extract names from symbols #' #' @description #' #' `as_name()` converts [symbols][sym] to character strings. The #' conversion is deterministic. That is, the roundtrip symbol -> name #' -> symbol always gets the same result. #' #' - Use `as_name()` when you need to transform a symbol to a string #' to _refer_ to an object by its name. #' #' - Use [as_label()] when you need to transform any kind of object to #' a string to _represent_ that object with a short description. #' #' Expect `as_name()` to gain #' [name-repairing](https://principles.tidyverse.org/names-attribute.html#minimal-unique-universal) #' features in the future. #' #' Note that `rlang::as_name()` is the _opposite_ of #' [base::as.name()]. If you're writing base R code, we recommend #' using [base::as.symbol()] which is an alias of `as.name()` that #' follows a more modern terminology (R types instead of S modes). #' #' @param x A string or symbol, possibly wrapped in a [quosure][quosure]. #' If a string, the attributes are removed, if any. #' @return A character vector of length 1. #' #' @seealso [as_label()] for converting any object to a single string #' suitable as a label. [as_string()] for a lower-level version that #' doesn't unwrap quosures. #' @examples #' # Let's create some symbols: #' foo <- quote(foo) #' bar <- sym("bar") #' #' # as_name() converts symbols to strings: #' foo #' as_name(foo) #' #' typeof(bar) #' typeof(as_name(bar)) #' #' # as_name() unwraps quosured symbols automatically: #' as_name(quo(foo)) #' @export as_name <- function(x) { if (is_quosure(x)) { x <- quo_get_expr(x) } as_string(x) } rlang/R/vec-na.R0000644000176200001440000000756613553606216013077 0ustar liggesusers#' Missing values #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} #' #' Missing values are represented in R with the general symbol #' `NA`. They can be inserted in almost all data containers: all #' atomic vectors except raw vectors can contain missing values. To #' achieve this, R automatically converts the general `NA` symbol to a #' typed missing value appropriate for the target vector. The objects #' provided here are aliases for those typed `NA` objects. #' #' #' @details #' #' Typed missing values are necessary because R needs sentinel values #' of the same type (i.e. the same machine representation of the data) #' as the containers into which they are inserted. The official typed #' missing values are `NA_integer_`, `NA_real_`, `NA_character_` and #' `NA_complex_`. The missing value for logical vectors is simply the #' default `NA`. The aliases provided in rlang are consistently named #' and thus simpler to remember. Also, `na_lgl` is provided as an #' alias to `NA` that makes intent clearer. #' #' Since `na_lgl` is the default `NA`, expressions such as `c(NA, NA)` #' yield logical vectors as no data is available to give a clue of the #' target type. In the same way, since lists and environments can #' contain any types, expressions like `list(NA)` store a logical #' `NA`. #' #' #' @section Life cycle: #' #' These shortcuts might be moved to the vctrs package at some #' point. This is why they are marked as questioning. #' #' @keywords internal #' @examples #' typeof(NA) #' typeof(na_lgl) #' typeof(na_int) #' #' # Note that while the base R missing symbols cannot be overwritten, #' # that's not the case for rlang's aliases: #' na_dbl <- NA #' typeof(na_dbl) #' @name missing NULL #' @rdname missing #' @export na_lgl <- NA #' @rdname missing #' @export na_int <- NA_integer_ #' @rdname missing #' @export na_dbl <- NA_real_ #' @rdname missing #' @export na_chr <- NA_character_ #' @rdname missing #' @export na_cpl <- NA_complex_ #' Test for missing values #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} #' #' `are_na()` checks for missing values in a vector and is equivalent #' to [base::is.na()]. It is a vectorised predicate, meaning that its #' output is always the same length as its input. On the other hand, #' `is_na()` is a scalar predicate and always returns a scalar #' boolean, `TRUE` or `FALSE`. If its input is not scalar, it returns #' `FALSE`. Finally, there are typed versions that check for #' particular [missing types][missing]. #' #' #' @details #' #' The scalar predicates accept non-vector inputs. They are equivalent #' to [is_null()] in that respect. In contrast the vectorised #' predicate `are_na()` requires a vector input since it is defined #' over vector values. #' #' @param x An object to test #' #' @section Life cycle: #' #' These functions might be moved to the vctrs package at some #' point. This is why they are marked as questioning. #' #' @keywords internal #' @examples #' # are_na() is vectorised and works regardless of the type #' are_na(c(1, 2, NA)) #' are_na(c(1L, NA, 3L)) #' #' # is_na() checks for scalar input and works for all types #' is_na(NA) #' is_na(na_dbl) #' is_na(character(0)) #' #' # There are typed versions as well: #' is_lgl_na(NA) #' is_lgl_na(na_dbl) #' @export are_na <- function(x) { if (!is_atomic(x)) { abort("`x` must be an atomic vector") } is.na(x) } #' @rdname are_na #' @export is_na <- function(x) { is_scalar_vector(x) && is.na(x) } #' @rdname are_na #' @export is_lgl_na <- function(x) { identical(x, na_lgl) } #' @rdname are_na #' @export is_int_na <- function(x) { identical(x, na_int) } #' @rdname are_na #' @export is_dbl_na <- function(x) { identical(x, na_dbl) } #' @rdname are_na #' @export is_chr_na <- function(x) { identical(x, na_chr) } #' @rdname are_na #' @export is_cpl_na <- function(x) { identical(x, na_cpl) } rlang/R/cnd.R0000644000176200001440000000571713563531624012467 0ustar liggesusers#' Create a condition object #' #' These constructors make it easy to create subclassed conditions. #' Conditions are objects that power the error system in R. They can #' also be used for passing messages to pre-established handlers. #' #' `cnd()` creates objects inheriting from `condition`. Conditions #' created with `error_cnd()`, `warning_cnd()` and `message_cnd()` #' inherit from `error`, `warning` or `message`. #' #' @section Lifecycle: #' #' The `.type` and `.msg` arguments have been renamed to `.subclass` #' and `message`. They are deprecated as of rlang 0.3.0. #' #' @param class The condition subclass. #' @param ... <[dynamic][dyn-dots]> Named data fields stored inside #' the condition object. #' @param message A default message to inform the user about the #' condition when it is signalled. #' @param trace A `trace` object created by [trace_back()]. #' @param parent A parent condition object created by [abort()]. #' @inheritParams abort #' @seealso [cnd_signal()], [with_handlers()]. #' #' @keywords internal #' @export #' @examples #' # Create a condition inheriting from the s3 type "foo": #' cnd <- cnd("foo") #' #' # Signal the condition to potential handlers. Since this is a bare #' # condition the signal has no effect if no handlers are set up: #' cnd_signal(cnd) #' #' # When a relevant handler is set up, the signal causes the handler #' # to be called: #' with_handlers(cnd_signal(cnd), foo = exiting(function(c) "caught!")) #' #' # Handlers can be thrown or executed inplace. See with_handlers() #' # documentation for more on this. #' #' # Signalling an error condition aborts the current computation: #' err <- error_cnd("foo", message = "I am an error") #' try(cnd_signal(err)) cnd <- function(class, ..., message = "", .subclass) { if (!missing(.subclass)) { deprecate_subclass(.subclass) } if (missing(class)) { abort("Bare conditions must be subclassed") } .Call(rlang_new_condition, class, message, dots_list(...)) } #' @rdname cnd #' @export warning_cnd <- function(class = NULL, ..., message = "", .subclass) { if (!missing(.subclass)) { deprecate_subclass(.subclass) } .Call(rlang_new_condition, c(class, "warning"), message, dots_list(...)) } #' @rdname cnd #' @export message_cnd <- function(class = NULL, ..., message = "", .subclass) { if (!missing(.subclass)) { deprecate_subclass(.subclass) } .Call(rlang_new_condition, c(class, "message"), message, dots_list(...)) } #' Is object a condition? #' @param x An object to test. #' @keywords internal #' @export is_condition <- function(x) { inherits(x, "condition") } #' What type is a condition? #' #' Use `cnd_type()` to check what type a condition is. #' #' @param cnd A condition object. #' @return A string, either `"condition"`, `"message"`, `"warning"`, #' `"error"` or `"interrupt"`. #' #' @keywords internal #' @export #' @examples #' cnd_type(catch_cnd(abort("Abort!"))) #' cnd_type(catch_cnd(interrupt())) cnd_type <- function(cnd) { .Call(rlang_cnd_type, cnd) } rlang/R/env-special.R0000644000176200001440000002361013604124153014110 0ustar liggesusers#' Search path environments #' #' @description #' #' The search path is a chain of environments containing exported #' functions of attached packages. #' #' The API includes: #' #' - [base::search()] to get the names of environments attached to the #' search path. #' #' - `search_envs()` returns the environments on the search path as a #' list. #' #' - `pkg_env_name()` takes a bare package name and prefixes it with #' `"package:"`. Attached package environments have search names of #' the form `package:name`. #' #' - `pkg_env()` takes a bare package name and returns the scoped #' environment of packages if they are attached to the search path, #' and throws an error otherwise. It is a shortcut for #' `search_env(pkg_env_name("pkgname"))`. #' #' - `is_attached()` returns `TRUE` when its argument (a search name #' or a package environment) is attached to the search path. #' #' #' @section The search path: #' #' This chain of environments determines what objects are visible from #' the global workspace. It contains the following elements: #' #' - The chain always starts with `global_env()` and finishes with #' `base_env()` (technically, it finishes with the `empty_env()` #' which the base package environment inherits from). #' #' - Each [base::library()] call attaches a new package environment to #' the search path. Attached packages are associated with a [search #' name][env_name]. #' #' - In addition, any list, data frame, or environment can be attached #' to the search path with [base::attach()]. #' #' #' @param name The name of an environment attached to the search #' path. Call [base::search()] to get the names of environments #' currently attached to the search path. Note that the search name #' of a package environment is prefixed with `"package:"`. #' #' @keywords internal #' @export #' @examples #' # List the search names of environments attached to the search path: #' search() #' #' # Get the corresponding environments: #' search_envs() #' #' # The global environment and the base package are always first and #' # last in the chain, respectively: #' envs <- search_envs() #' envs[[1]] #' envs[[length(envs)]] #' #' # These two environments have their own shortcuts: #' global_env() #' base_env() #' #' # Packages appear in the search path with a special name. Use #' # pkg_env_name() to create that name: #' pkg_env_name("rlang") #' search_env(pkg_env_name("rlang")) #' #' # Alternatively, get the scoped environment of a package with #' # pkg_env(): #' pkg_env("utils") search_envs <- function() { env_parents(env(.GlobalEnv), last = base_env()) } #' @rdname search_envs #' @export search_env <- function(name) { if (!is_string(name)) { abort("`name` must be a string") } if (!is_attached(name)) { abort(paste_line( sprintf("`%s` is not attached.", name), "Do you need to prefix it with \"package:\"?" )) } as.environment(name) } #' @rdname search_envs #' @param pkg The name of a package. #' @export pkg_env <- function(pkg) { search_env(pkg_env_name(pkg)) } #' @rdname search_envs #' @export pkg_env_name <- function(pkg) { paste0("package:", pkg) } #' @rdname search_envs #' @param x An environment or a search name. #' @export is_attached <- function(x) { if (is_string(x)) { return(x %in% search()) } if (!is_environment(x)) { abort("`x` must be an environment or a name") } env <- global_env() while (!is_reference(env, empty_env())) { if (is_reference(x, env)) { return(TRUE) } env <- env_parent(env) } FALSE } #' @rdname search_envs #' @export base_env <- baseenv #' @rdname search_envs #' @export global_env <- globalenv #' Get the empty environment #' #' The empty environment is the only one that does not have a parent. #' It is always used as the tail of an environment chain such as the #' search path (see [search_envs()]). #' #' @export #' @examples #' # Create environments with nothing in scope: #' child_env(empty_env()) empty_env <- emptyenv #' Get the current or caller environment #' #' @description #' #' * The current environment is the execution environment of the #' current function (the one currently being evaluated). #' #' * The caller environment is the execution environment of the #' function that called the current function. #' #' @inheritParams caller_frame #' #' @seealso [caller_frame()] and [current_frame()] #' @export #' @examples #' # Let's create a function that returns its current environment and #' # its caller environment: #' fn <- function() list(current = current_env(), caller = caller_env()) #' #' # The current environment is an unique execution environment #' # created when `fn()` was called. The caller environment is the #' # global env because that's where we called `fn()`. #' fn() #' #' # Let's call `fn()` again but this time within a function: #' g <- function() fn() #' #' # Now the caller environment is also an unique execution environment. #' # This is the exec env created by R for our call to g(): #' g() caller_env <- function(n = 1) { parent.frame(n + 1) } #' @rdname caller_env #' @export current_env <- function() { parent.frame() } #' Get the namespace of a package #' #' Namespaces are the environment where all the functions of a package #' live. The parent environments of namespaces are the `imports` #' environments, which contain all the functions imported from other #' packages. #' #' #' @section Life cycle: #' #' These functions are experimental and may not belong to the rlang #' package. Expect API changes. #' #' @param x #' * For `ns_env()`, the name of a package or an environment as a #' string. #' * An environment (the current environment by default). #' * A function. #' #' In the latter two cases, the environment ancestry is searched for #' a namespace with [base::topenv()]. If the environment doesn't #' inherit from a namespace, this is an error. #' #' @seealso [pkg_env()] #' @keywords internal #' @export ns_env <- function(x = caller_env()) { env <- switch(typeof(x), builtin = , special = ns_env("base"), closure = topenv(fn_env(x)), environment = topenv(x), character = if (is_string(x)) asNamespace(x) ) if (!is_namespace(env)) { abort("`x` must be a package name or a function inheriting from a namespace.") } env } #' @rdname ns_env #' @export ns_imports_env <- function(x = caller_env()) { env_parent(ns_env(x)) } #' @rdname ns_env #' @param env A namespace environment. #' @export ns_env_name <- function(x = caller_env()) { env <- switch(typeof(x), environment = , builtin = , special = , closure = ns_env(x), abort("`x` must be an environment or a function inheriting from a namespace.") ) unname(getNamespaceName(env)) } ns_exports <- function(ns) getNamespaceExports(ns) ns_imports <- function(ns) getNamespaceImports(ns) ns_exports_has <- function(ns, name) { if (is_reference(ns, base_ns_env)) { exports <- base_pkg_env } else { exports <- ns$.__NAMESPACE__.$exports } !is_null(exports) && exists(name, envir = exports, inherits = FALSE) } #' Is an object a namespace environment? #' #' @param x An object to test. #' @export is_namespace <- function(x) { isNamespace(x) } #' Is a package installed in the library? #' #' This checks that a package is installed with minimal side effects. #' If installed, the package will be loaded but not attached. #' #' @param pkg The name of a package. #' @return `TRUE` if the package is installed, `FALSE` otherwise. #' @export #' @examples #' is_installed("utils") #' is_installed("ggplot5") is_installed <- function(pkg) { is_true(requireNamespace(pkg, quietly = TRUE)) } env_type <- function(env) { if (is_reference(env, global_env())) { "global" } else if (is_reference(env, empty_env())) { "empty" } else if (is_reference(env, base_env())) { "base" } else if (is_frame_env(env)) { "frame" } else { "local" } } friendly_env_type <- function(type) { switch(type, global = "the global environment", empty = "the empty environment", base = "the base environment", frame = "a frame environment", local = "a local environment", abort("Internal error: unknown environment type") ) } env_format <- function(env) { type <- env_type(env) if (type %in% c("frame", "local")) { addr <- sexp_address(get_env(env)) type <- paste(type, addr) } type } #' Label of an environment #' #' @description #' #' Special environments like the global environment have their own #' names. `env_name()` returns: #' #' * "global" for the global environment. #' #' * "empty" for the empty environment. #' #' * "base" for the base package environment (the last environment on #' the search path). #' #' * "namespace:pkg" if `env` is the namespace of the package "pkg". #' #' * The `name` attribute of `env` if it exists. This is how the #' [package environments][search_envs] and the [imports #' environments][ns_imports_env] store their names. The name of package #' environments is typically "package:pkg". #' #' * The empty string `""` otherwise. #' #' `env_label()` is exactly like `env_name()` but returns the memory #' address of anonymous environments as fallback. #' #' @param env An environment. #' #' @export #' @examples #' # Some environments have specific names: #' env_name(global_env()) #' env_name(ns_env("rlang")) #' #' # Anonymous environments don't have names but are labelled by their #' # address in memory: #' env_name(env()) #' env_label(env()) env_name <- function(env) { if (!is_environment(env)) { abort("`env` must be an environment") } if (is_reference(env, global_env())) { return("global") } if (is_reference(env, base_env())) { return("package:base") } if (is_reference(env, empty_env())) { return("empty") } nm <- environmentName(env) if (is_namespace(env)) { return(paste0("namespace:", nm)) } nm } #' @rdname env_name #' @export env_label <- function(env) { nm <- env_name(env) if (nzchar(nm)) { nm } else { sexp_address(env) } } rlang/R/fn.R0000644000176200001440000004771513563530577012340 0ustar liggesusers#' Create a function #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("stable")} #' #' This constructs a new function given its three components: #' list of arguments, body code and parent environment. #' #' @param args A named list or pairlist of default arguments. Note #' that if you want arguments that don't have defaults, you'll need #' to use the special function [pairlist2()]. If you need quoted #' defaults, use [exprs()]. #' @param body A language object representing the code inside the #' function. Usually this will be most easily generated with #' [base::quote()] #' @param env The parent environment of the function, defaults to the #' calling environment of `new_function()` #' @export #' @examples #' f <- function() letters #' g <- new_function(NULL, quote(letters)) #' identical(f, g) #' #' # Pass a list or pairlist of named arguments to create a function #' # with parameters. The name becomes the parameter name and the #' # argument the default value for this parameter: #' new_function(list(x = 10), quote(x)) #' new_function(pairlist2(x = 10), quote(x)) #' #' # Use `exprs()` to create quoted defaults. Compare: #' new_function(pairlist2(x = 5 + 5), quote(x)) #' new_function(exprs(x = 5 + 5), quote(x)) #' #' # Pass empty arguments to omit defaults. `list()` doesn't allow #' # empty arguments but `pairlist2()` does: #' new_function(pairlist2(x = , y = 5 + 5), quote(x + y)) #' new_function(exprs(x = , y = 5 + 5), quote(x + y)) new_function <- function(args, body, env = caller_env()) { .Call(rlang_new_function, args, body, env) } prim_eval <- eval(quote(sys.function(0))) is_prim_eval <- function(x) identical(x, prim_eval) #' Name of a primitive function #' @param prim A primitive function such as [base::c()]. #' @keywords internal #' @export prim_name <- function(prim) { stopifnot(is_primitive(prim)) # Workaround because R_FunTab is not public name <- format(prim) name <- sub("^.Primitive\\(\"", "", name) name <- sub("\"\\)$", "", name) name } #' Extract arguments from a function #' #' `fn_fmls()` returns a named list of formal arguments. #' `fn_fmls_names()` returns the names of the arguments. #' `fn_fmls_syms()` returns formals as a named list of symbols. This #' is especially useful for forwarding arguments in [constructed #' calls][lang]. #' #' Unlike `formals()`, these helpers throw an error with primitive #' functions instead of returning `NULL`. #' #' @param fn A function. It is lookep up in the calling frame if not #' supplied. #' @seealso [call_args()] and [call_args_names()] #' @export #' @examples #' # Extract from current call: #' fn <- function(a = 1, b = 2) fn_fmls() #' fn() #' #' # fn_fmls_syms() makes it easy to forward arguments: #' call2("apply", !!! fn_fmls_syms(lapply)) #' #' # You can also change the formals: #' fn_fmls(fn) <- list(A = 10, B = 20) #' fn() #' #' fn_fmls_names(fn) <- c("foo", "bar") #' fn() fn_fmls <- function(fn = caller_fn()) { check_closure(fn) formals(fn) } #' @rdname fn_fmls #' @export fn_fmls_names <- function(fn = caller_fn()) { args <- fn_fmls(fn) names(args) } #' @rdname fn_fmls #' @export fn_fmls_syms <- function(fn = caller_fn()) { fmls_nms <- fn_fmls_names(fn) if (is_null(fmls_nms)) { return(list()) } nms <- set_names(fmls_nms) names(nms)[match("...", nms)] <- "" syms(nms) } #' @rdname fn_fmls #' @param value New formals or formals names for `fn`. #' @export `fn_fmls<-` <- function(fn, value) { check_closure(fn) attrs <- attributes(fn) formals(fn) <- value # Work around bug in base R attributes(fn) <- attrs fn } #' @rdname fn_fmls #' @export `fn_fmls_names<-` <- function(fn, value) { check_closure(fn) attrs <- attributes(fn) fmls <- formals(fn) names(fmls) <- value formals(fn) <- fmls # Work around bug in base R attributes(fn) <- attrs fn } check_closure <- function(x) { if (!is_closure(x)) { abort(sprintf("`fn` must be an R function, not %s", friendly_type_of(x))) } } #' Get or set function body #' #' `fn_body()` is a simple wrapper around [base::body()]. It always #' returns a `\{` expression and throws an error when the input is a #' primitive function (whereas `body()` returns `NULL`). The setter #' version preserves attributes, unlike `body<-`. #' #' @inheritParams fn_fmls #' #' @export #' @examples #' # fn_body() is like body() but always returns a block: #' fn <- function() do() #' body(fn) #' fn_body(fn) #' #' # It also throws an error when used on a primitive function: #' try(fn_body(base::list)) fn_body <- function(fn = caller_fn()) { if(!is_closure(fn)) { abort("`fn` is not a closure") } body <- body(fn) if (is_call(body, "{")) { body } else { call("{", body) } } #' @rdname fn_body #' @export `fn_body<-` <- function(fn, value) { attrs <- attributes(fn) body(fn) <- value # Work around bug in base R. First remove source references since # the body has changed attrs$srcref <- NULL attributes(fn) <- attrs fn } fn_body_node <- function(fn) { body <- body(fn) if (is_call(body, "{")) { node_cdr(fn) } else { pairlist(body) } } #' Is object a function? #' #' The R language defines two different types of functions: primitive #' functions, which are low-level, and closures, which are the regular #' kind of functions. #' #' Closures are functions written in R, named after the way their #' arguments are scoped within nested environments (see #' https://en.wikipedia.org/wiki/Closure_(computer_programming)). The #' root environment of the closure is called the closure #' environment. When closures are evaluated, a new environment called #' the evaluation frame is created with the closure environment as #' parent. This is where the body of the closure is evaluated. These #' closure frames appear on the evaluation stack (see [ctxt_stack()]), #' as opposed to primitive functions which do not necessarily have #' their own evaluation frame and never appear on the stack. #' #' Primitive functions are more efficient than closures for two #' reasons. First, they are written entirely in fast low-level #' code. Second, the mechanism by which they are passed arguments is #' more efficient because they often do not need the full procedure of #' argument matching (dealing with positional versus named arguments, #' partial matching, etc). One practical consequence of the special #' way in which primitives are passed arguments is that they #' technically do not have formal arguments, and [formals()] will #' return `NULL` if called on a primitive function. Finally, primitive #' functions can either take arguments lazily, like R closures do, #' or evaluate them eagerly before being passed on to the C code. #' The former kind of primitives are called "special" in R terminology, #' while the latter is referred to as "builtin". `is_primitive_eager()` #' and `is_primitive_lazy()` allow you to check whether a primitive #' function evaluates arguments eagerly or lazily. #' #' You will also encounter the distinction between primitive and #' internal functions in technical documentation. Like primitive #' functions, internal functions are defined at a low level and #' written in C. However, internal functions have no representation in #' the R language. Instead, they are called via a call to #' [base::.Internal()] within a regular closure. This ensures that #' they appear as normal R function objects: they obey all the usual #' rules of argument passing, and they appear on the evaluation stack #' as any other closures. As a result, [fn_fmls()] does not need to #' look in the `.ArgsEnv` environment to obtain a representation of #' their arguments, and there is no way of querying from R whether #' they are lazy ('special' in R terminology) or eager ('builtin'). #' #' You can call primitive functions with [.Primitive()] and internal #' functions with [.Internal()]. However, calling internal functions #' in a package is forbidden by CRAN's policy because they are #' considered part of the private API. They often assume that they #' have been called with correctly formed arguments, and may cause R #' to crash if you call them with unexpected objects. #' #' @inheritParams type-predicates #' @export #' @examples #' # Primitive functions are not closures: #' is_closure(base::c) #' is_primitive(base::c) #' #' # On the other hand, internal functions are wrapped in a closure #' # and appear as such from the R side: #' is_closure(base::eval) #' #' # Both closures and primitives are functions: #' is_function(base::c) #' is_function(base::eval) #' #' # Primitive functions never appear in evaluation stacks: #' is_primitive(base::`[[`) #' is_primitive(base::list) #' list(ctxt_stack())[[1]] #' #' # While closures do: #' identity(identity(ctxt_stack())) is_function <- function(x) { is_closure(x) || is_primitive(x) } #' @export #' @rdname is_function is_closure <- function(x) { typeof(x) == "closure" } #' @export #' @rdname is_function is_primitive <- function(x) { typeof(x) %in% c("builtin", "special") } #' @export #' @rdname is_function #' @examples #' #' # Many primitive functions evaluate arguments eagerly: #' is_primitive_eager(base::c) #' is_primitive_eager(base::list) #' is_primitive_eager(base::`+`) is_primitive_eager <- function(x) { typeof(x) == "builtin" } #' @export #' @rdname is_function #' @examples #' #' # However, primitives that operate on expressions, like quote() or #' # substitute(), are lazy: #' is_primitive_lazy(base::quote) #' is_primitive_lazy(base::substitute) is_primitive_lazy <- function(x) { typeof(x) == "special" } #' Return the closure environment of a function #' #' Closure environments define the scope of functions (see [env()]). #' When a function call is evaluated, R creates an evaluation frame #' (see [ctxt_stack()]) that inherits from the closure environment. #' This makes all objects defined in the closure environment and all #' its parents available to code executed within the function. #' #' `fn_env()` returns the closure environment of `fn`. There is also #' an assignment method to set a new closure environment. #' #' @param fn,x A function. #' @param value A new closure environment for the function. #' @export #' @examples #' env <- child_env("base") #' fn <- with_env(env, function() NULL) #' identical(fn_env(fn), env) #' #' other_env <- child_env("base") #' fn_env(fn) <- other_env #' identical(fn_env(fn), other_env) fn_env <- function(fn) { if (is_primitive(fn)) { return(ns_env("base")) } if(is_closure(fn)) { return(environment(fn)) } abort("`fn` is not a function") } #' @export #' @rdname fn_env `fn_env<-` <- function(x, value) { if(!is_function(x)) { abort("`fn` is not a function") } environment(x) <- value x } #' Convert to function or closure #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("stable")} #' #' * `as_function()` transforms a one-sided formula into a function. #' This powers the lambda syntax in packages like purrr. #' #' * `as_closure()` first passes its argument to `as_function()`. If #' the result is a primitive function, it regularises it to a proper #' [closure] (see [is_function()] about primitive functions). Some #' special control flow primitives like `if`, `for`, or `break` #' can't be coerced to a closure. #' #' @param x A function or formula. #' #' If a **function**, it is used as is. #' #' If a **formula**, e.g. `~ .x + 2`, it is converted to a function #' with up to two arguments: `.x` (single argument) or `.x` and `.y` #' (two arguments). The `.` placeholder can be used instead of `.x`. #' This allows you to create very compact anonymous functions (lambdas) with up #' to two inputs. Functions created from formulas have a special #' class. Use `is_lambda()` to test for it. #' #' Lambdas currently do not support [nse-force], #' due to the way the arguments are handled internally. #' #' @param env Environment in which to fetch the function in case `x` #' is a string. #' @export #' @examples #' f <- as_function(~ .x + 1) #' f(10) #' #' g <- as_function(~ -1 * .) #' g(4) #' #' h <- as_function(~ .x - .y) #' h(6, 3) #' #' # Functions created from a formula have a special class: #' is_lambda(f) #' is_lambda(as_function(function() "foo")) #' #' # Primitive functions are regularised as closures #' as_closure(list) #' as_closure("list") #' #' # Operators have `.x` and `.y` as arguments, just like lambda #' # functions created with the formula syntax: #' as_closure(`+`) #' as_closure(`~`) #' #' # Use a regular function for tidy evaluation, also when calling functions #' # that use tidy evaluation: #' ## Bad: #' e <- as_function(~ as_label(ensym(.x))) #' ## Good: #' e <- as_function(function(x) as_label(ensym(x))) #' #' e(y) as_function <- function(x, env = caller_env()) { if (is_function(x)) { return(x) } if (is_quosure(x)) { return(eval(expr(function(...) eval_tidy(!!x)))) } if (is_formula(x)) { if (length(x) > 2) { abort("Can't convert a two-sided formula to a function") } args <- list(... = missing_arg(), .x = quote(..1), .y = quote(..2), . = quote(..1)) fn <- new_function(args, f_rhs(x), f_env(x)) fn <- structure(fn, class = c("rlang_lambda_function", "function")) return(fn) } if (is_string(x)) { return(get(x, envir = env, mode = "function")) } abort_coercion(x, friendly_type("function")) } #' @export print.rlang_lambda_function <- function(x, ...) { cat_line("") NextMethod() } #' @rdname as_function #' @export is_lambda <- function(x) { inherits(x, "rlang_lambda_function") } #' @rdname as_function #' @export as_closure <- function(x, env = caller_env()) { x <- as_function(x, env = env) if (is_closure(x)) { return(x) } if (!is_primitive(x)) { abort_coercion(x, "a closure") } fn_name <- prim_name(x) fn <- op_as_closure(fn_name) if (!is_null(fn)) { return(fn) } fmls <- formals(args(fn_name)) prim_call <- call2(x, !!!prim_args(fmls)) # The closure wrapper should inherit from the global environment # to ensure proper lexical dispatch with methods defined there new_function(fmls, prim_call, global_env()) } prim_args <- function(fmls) { args <- names(fmls) # Set argument names but only after `...`. Arguments before dots # should be positionally matched. dots_i <- match("...", args) if (!is_na(dots_i)) { idx <- seq2(dots_i + 1L, length(args)) names2(args)[idx] <- args[idx] } syms(args) } utils::globalVariables(c("!<-", "(<-", "enexpr<-")) op_as_closure <- function(prim_nm) { switch(prim_nm, `<-` = , `<<-` = , `=` = function(.x, .y) { op <- sym(prim_nm) expr <- expr((!!op)(!!enexpr(.x), !!enexpr(.y))) eval_bare(expr, caller_env()) }, `@` = , `$` = function(.x, .i) { op <- sym(prim_nm) expr <- expr((!!op)(.x, !!quo_squash(enexpr(.i), warn = TRUE))) eval_bare(expr) }, `[[<-` = function(.x, .i, .value) { expr <- expr((!!enexpr(.x))[[!!enexpr(.i)]] <- !!enexpr(.value)) eval_bare(expr, caller_env()) }, `[<-` = function(.x, ...) { args <- exprs(...) n <- length(args) if (n < 2L) { abort("Must supply operands to `[<-`") } expr <- expr((!!enexpr(.x))[!!!args[-n]] <- !!args[[n]]) eval_bare(expr, caller_env()) }, `@<-` = function(.x, .i, .value) { expr <- expr(`@`(!!enexpr(.x), !!enexpr(.i)) <- !!enexpr(.value)) eval_bare(expr, caller_env()) }, `$<-` = function(.x, .i, .value) { expr <- expr(`$`(!!enexpr(.x), !!enexpr(.i)) <- !!enexpr(.value)) eval_bare(expr, caller_env()) }, `(` = function(.x) .x, `[` = function(.x, ...) .x[...], `[[` = function(.x, ...) .x[[...]], `{` = function(...) { values <- list(...) values[[length(values)]] }, `&` = new_binary_closure(function(.x, .y) .x & .y), `|` = new_binary_closure(function(.x, .y) .x | .y), `&&` = new_binary_closure(function(.x, .y) .x && .y), `||` = new_binary_closure(function(.x, .y) .x || .y, shortcircuiting = TRUE), `!` = function(.x) !.x, `+` = new_binary_closure(function(.x, .y) if (missing(.y)) .x else .x + .y, versatile = TRUE), `-` = new_binary_closure(function(.x, .y) if (missing(.y)) -.x else .x - .y, versatile = TRUE), `*` = new_binary_closure(function(.x, .y) .x * .y), `/` = new_binary_closure(function(.x, .y) .x / .y), `^` = new_binary_closure(function(.x, .y) .x ^ .y), `%%` = new_binary_closure(function(.x, .y) .x %% .y), `<` = new_binary_closure(function(.x, .y) .x < .y), `<=` = new_binary_closure(function(.x, .y) .x <= .y), `>` = new_binary_closure(function(.x, .y) .x > .y), `>=` = new_binary_closure(function(.x, .y) .x >= .y), `==` = new_binary_closure(function(.x, .y) .x == .y), `!=` = new_binary_closure(function(.x, .y) .x != .y), `:` = new_binary_closure(function(.x, .y) .x : .y), `~` = function(.x, .y) { if (is_missing(substitute(.y))) { new_formula(NULL, substitute(.x), caller_env()) } else { new_formula(substitute(.x), substitute(.y), caller_env()) } }, `c` = function(...) c(...), # Unsupported primitives `break` = , `for` = , `function` = , `if` = , `next` = , `repeat` = , `return` = , `while` = { nm <- chr_quoted(prim_nm) abort(paste0("Can't coerce the primitive function ", nm, " to a closure")) } ) } new_binary_closure <- function(fn, versatile = FALSE, shortcircuiting = FALSE) { if (versatile) { nodes <- versatile_check_nodes } else if (shortcircuiting) { nodes <- shortcircuiting_check_nodes } else { nodes <- binary_check_nodes } nodes <- duplicate(nodes, shallow = TRUE) nodes <- node_append(nodes, fn_body_node(fn)) body <- new_call(brace_sym, nodes) formals(fn) <- binary_fmls body(fn) <- body fn } binary_fmls <- as.pairlist(alist( e1 = , e2 = , .x = e1, .y = e2 )) binary_check_nodes <- pairlist( quote( if (missing(.x)) { if (missing(e1)) { abort("Must supply `e1` or `.x` to binary operator") } .x <- e1 } else if (!missing(e1)) { abort("Can't supply both `e1` and `.x` to binary operator") } ), quote( if (missing(.y)) { if (missing(e2)) { abort("Must supply `e2` or `.y` to binary operator") } .y <- e2 } else if (!missing(e2)) { abort("Can't supply both `e2` and `.y` to binary operator") } ) ) versatile_check_nodes <- as.pairlist(c( binary_check_nodes[[1]], quote( if (missing(.y) && !missing(e2)) { .y <- e2 } else if (!missing(e2)) { abort("Can't supply both `e2` and `.y` to binary operator") } ) )) shortcircuiting_check_nodes <- as.pairlist(c( binary_check_nodes[[1]], quote(if (.x) return(TRUE)), binary_check_nodes[[2]] )) #' Make an `fn` object #' #' @noRd #' @description #' #' `new_fn()` takes a function and sets the class to `c("fn", #' function)`. #' #' * Inheriting from `"fn"` enables a print method that strips all #' attributes (except `srcref`) before printing. This is currently #' the only purpose of the `fn` class. #' #' * Inheriting from `"function"` makes sure your function still #' dispatches on type methods. #' #' @param fn A closure. #' @return An object of class `c("fn", "function")`. #' @examples #' fn <- structure(function() "foo", attribute = "foobar") #' print(fn) #' #' # The `fn` object doesn't print with attributes: #' fn <- new_fn(fn) #' print(fn) new_fn <- function(fn) { stopifnot(is_closure(fn)) structure(fn, class = c("fn", "function")) } print.fn <- function(x, ...) { srcref <- attr(x, "srcref") attributes(x) <- NULL x <- structure(x, srcref = srcref) print(x) } as_predicate <- function(.fn, ...) { .fn <- as_function(.fn) function(...) { out <- .fn(...) if (!is_bool(out)) { abort(sprintf( "Predicate functions must return a single `TRUE` or `FALSE`, not %s", as_predicate_friendly_type_of(out) )) } out } } as_predicate_friendly_type_of <- function(x) { if (is_na(x)) { "a missing value" } else { friendly_type_of(x, length = TRUE) } } rlang/R/types.R0000644000176200001440000003246213553606073013064 0ustar liggesusers#' Type predicates #' #' These type predicates aim to make type testing in R more #' consistent. They are wrappers around [base::typeof()], so operate #' at a level beneath S3/S4 etc. #' #' Compared to base R functions: #' #' * The predicates for vectors include the `n` argument for #' pattern-matching on the vector length. #' #' * Unlike `is.atomic()`, `is_atomic()` does not return `TRUE` for #' `NULL`. #' #' * Unlike `is.vector()`, `is_vector()` tests if an object is an #' atomic vector or a list. `is.vector` checks for the presence of #' attributes (other than name). #' #' @param x Object to be tested. #' @param n Expected length of a vector. #' @param finite Whether all values of the vector are finite. The #' non-finite values are `NA`, `Inf`, `-Inf` and `NaN`. Setting this #' to something other than `NULL` can be expensive because the whole #' vector needs to be traversed and checked. #' @param encoding Defunct as of rlang 0.4.0. #' @seealso [bare-type-predicates] [scalar-type-predicates] #' @name type-predicates NULL #' @export #' @rdname type-predicates is_list <- function(x, n = NULL) { .Call(rlang_is_list, x, n) } parsable_atomic_types <- c("logical", "integer", "double", "complex", "character") atomic_types <- c(parsable_atomic_types, "raw") #' @export #' @rdname type-predicates is_atomic <- function(x, n = NULL) { .Call(rlang_is_atomic, x, n) } #' @export #' @rdname type-predicates is_vector <- function(x, n = NULL) { .Call(rlang_is_vector, x, n) } # Mostly for unit testing is_finite <- function(x) { .Call(rlang_is_finite, x) } #' @export #' @rdname type-predicates is_integer <- function(x, n = NULL) { .Call(rlang_is_integer, x, n) } #' @export #' @rdname type-predicates is_double <- function(x, n = NULL, finite = NULL) { .Call(rlang_is_double, x, n, finite) } #' @export #' @rdname type-predicates is_character <- function(x, n = NULL, encoding = NULL) { if (!is_null(encoding)) { stop_defunct("The `encoding` argument is deprecated as of rlang 0.3.0.") } if (!.Call(rlang_is_character, x, n)) { return(FALSE) } if (!is_null(encoding)) { stopifnot(typeof(encoding) == "character") if (!all(Encoding(x) %in% encoding)) { return(FALSE) } } TRUE } #' @export #' @rdname type-predicates is_logical <- function(x, n = NULL) { .Call(rlang_is_logical, x, n) } #' @export #' @rdname type-predicates is_raw <- function(x, n = NULL) { .Call(rlang_is_raw, x, n) } #' @export #' @rdname type-predicates is_bytes <- is_raw #' @export #' @rdname type-predicates is_null <- function(x) { .Call(rlang_is_null, x) } #' Scalar type predicates #' #' @description #' #' These predicates check for a given type and whether the vector is #' "scalar", that is, of length 1. #' #' In addition to the length check, `is_string()` and `is_bool()` #' return `FALSE` if their input is missing. This is useful for #' type-checking arguments, when your function expects a single string #' or a single `TRUE` or `FALSE`. #' #' @inheritParams type-predicates #' @param x object to be tested. #' @seealso [type-predicates], [bare-type-predicates] #' @name scalar-type-predicates NULL #' @export #' @rdname scalar-type-predicates is_scalar_list <- function(x) { .Call(rlang_is_list, x, 1L) } #' @export #' @rdname scalar-type-predicates is_scalar_atomic <- function(x) { .Call(rlang_is_atomic, x, 1L) } #' @export #' @rdname scalar-type-predicates is_scalar_vector <- function(x) { .Call(rlang_is_vector, x, 1L) } #' @export #' @rdname scalar-type-predicates is_scalar_integer <- function(x) { .Call(rlang_is_integer, x, 1L) } #' @export #' @rdname scalar-type-predicates is_scalar_double <- function(x) { .Call(rlang_is_double, x, 1L, NULL) } #' @export #' @rdname scalar-type-predicates is_scalar_character <- function(x, encoding = NULL) { if (!is_null(encoding)) { stop_defunct("The `encoding` argument is deprecated as of rlang 0.3.0.") } is_character(x, encoding = encoding, n = 1L) } #' @export #' @rdname scalar-type-predicates is_scalar_logical <- function(x) { .Call(rlang_is_logical, x, 1L) } #' @export #' @rdname scalar-type-predicates is_scalar_raw <- function(x) { .Call(rlang_is_raw, x, 1L) } #' @export #' @param string A string to compare to `x`. If a character vector, #' returns `TRUE` if at least one element is equal to `x`. #' @rdname scalar-type-predicates is_string <- function(x, string = NULL) { .Call(rlang_is_string, x, string) } #' @export #' @rdname scalar-type-predicates is_scalar_bytes <- is_scalar_raw #' @export #' @rdname scalar-type-predicates is_bool <- function(x) { is_logical(x, n = 1) && !is.na(x) } #' Bare type predicates #' #' These predicates check for a given type but only return `TRUE` for #' bare R objects. Bare objects have no class attributes. For example, #' a data frame is a list, but not a bare list. #' #' * The predicates for vectors include the `n` argument for #' pattern-matching on the vector length. #' #' * Like [is_atomic()] and unlike base R `is.atomic()`, #' `is_bare_atomic()` does not return `TRUE` for `NULL`. #' #' * Unlike base R `is.numeric()`, `is_bare_double()` only returns #' `TRUE` for floating point numbers. #' @inheritParams type-predicates #' @seealso [type-predicates], [scalar-type-predicates] #' @name bare-type-predicates NULL #' @export #' @rdname bare-type-predicates is_bare_list <- function(x, n = NULL) { !is.object(x) && is_list(x, n) } #' @export #' @rdname bare-type-predicates is_bare_atomic <- function(x, n = NULL) { !is.object(x) && is_atomic(x, n) } #' @export #' @rdname bare-type-predicates is_bare_vector <- function(x, n = NULL) { is_bare_atomic(x) || is_bare_list(x, n) } #' @export #' @rdname bare-type-predicates is_bare_double <- function(x, n = NULL) { !is.object(x) && is_double(x, n) } #' @export #' @rdname bare-type-predicates is_bare_integer <- function(x, n = NULL) { !is.object(x) && is_integer(x, n) } #' @export #' @rdname bare-type-predicates is_bare_numeric <- function(x, n = NULL) { if (!is_null(n) && length(x) != n) return(FALSE) !is.object(x) && typeof(x) %in% c("double", "integer") } #' @export #' @rdname bare-type-predicates is_bare_character <- function(x, n = NULL, encoding = NULL) { if (!is_null(encoding)) { stop_defunct("The `encoding` argument is deprecated as of rlang 0.3.0.") } !is.object(x) && is_character(x, n, encoding = encoding) } #' @export #' @rdname bare-type-predicates is_bare_logical <- function(x, n = NULL) { !is.object(x) && is_logical(x, n) } #' @export #' @rdname bare-type-predicates is_bare_raw <- function(x, n = NULL) { !is.object(x) && is_raw(x, n) } #' @export #' @rdname bare-type-predicates is_bare_string <- function(x, n = NULL) { !is.object(x) && is_string(x, n) } #' @export #' @rdname bare-type-predicates is_bare_bytes <- is_bare_raw #' Is object an empty vector or NULL? #' #' @param x object to test #' @export #' @examples #' is_empty(NULL) #' is_empty(list()) #' is_empty(list(NULL)) is_empty <- function(x) length(x) == 0 #' Is object an environment? #' #' `is_bare_environment()` tests whether `x` is an environment without a s3 or #' s4 class. #' #' @inheritParams is_empty #' @export is_environment <- function(x) { typeof(x) == "environment" } #' @rdname is_environment #' @export is_bare_environment <- function(x) { !is.object(x) && typeof(x) == "environment" } #' Is object identical to TRUE or FALSE? #' #' These functions bypass R's automatic conversion rules and check #' that `x` is literally `TRUE` or `FALSE`. #' @inheritParams is_empty #' @export #' @examples #' is_true(TRUE) #' is_true(1) #' #' is_false(FALSE) #' is_false(0) is_true <- function(x) { identical(x, TRUE) } #' @rdname is_true #' @export is_false <- function(x) { identical(x, FALSE) } #' Is a vector integer-like? #' #' @description #' #' These predicates check whether R considers a number vector to be #' integer-like, according to its own tolerance check (which is in #' fact delegated to the C library). This function is not adapted to #' data analysis, see the help for [base::is.integer()] for examples #' of how to check for whole numbers. #' #' Things to consider when checking for integer-like doubles: #' #' * This check can be expensive because the whole double vector has #' to be traversed and checked. #' #' * Large double values may be integerish but may still not be #' coercible to integer. This is because integers in R only support #' values up to `2^31 - 1` while numbers stored as double can be #' much larger. #' #' @seealso [is_bare_numeric()] for testing whether an object is a #' base numeric type (a bare double or integer vector). #' @inheritParams type-predicates #' @export #' @examples #' is_integerish(10L) #' is_integerish(10.0) #' is_integerish(10.0, n = 2) #' is_integerish(10.000001) #' is_integerish(TRUE) is_integerish <- function(x, n = NULL, finite = NULL) { .Call(rlang_is_integerish, x, n, finite) } #' @rdname is_integerish #' @export is_bare_integerish <- function(x, n = NULL, finite = NULL) { !is.object(x) && is_integerish(x, n, finite) } #' @rdname is_integerish #' @export is_scalar_integerish <- function(x, finite = NULL) { .Call(rlang_is_integerish, x, 1L, finite) } type_of_ <- function(x) { type <- typeof(x) if (is_formulaish(x)) { if (identical(node_car(x), colon_equals_sym)) { "definition" } else { "formula" } } else if (type == "character") { if (length(x) == 1) "string" else "character" } else if (type %in% c("builtin", "special")) { "primitive" } else { type } } #' Format a type for error messages #' #' @section Life cycle: #' #' * `friendly_type()` is experimental. #' #' @param type A type as returned by [typeof()]. #' @return A string of the prettified type, qualified with an #' indefinite article. #' @export #' @keywords internal #' @examples #' friendly_type("logical") #' friendly_type("integer") #' friendly_type("string") #' @export friendly_type <- function(type) { as_friendly_type(type) %||% type } #' Is an object copyable? #' #' When an object is modified, R generally copies it (sometimes #' lazily) to enforce [value #' semantics](https://en.wikipedia.org/wiki/Value_semantics). #' However, some internal types are uncopyable. If you try to copy #' them, either with `<-` or by argument passing, you actually create #' references to the original object rather than actual #' copies. Modifying these references can thus have far reaching side #' effects. #' #' @param x An object to test. #' @keywords internal #' @export #' @examples #' # Let's add attributes with structure() to uncopyable types. Since #' # they are not copied, the attributes are changed in place: #' env <- env() #' structure(env, foo = "bar") #' env #' #' # These objects that can only be changed with side effect are not #' # copyable: #' is_copyable(env) #' #' structure(base::list, foo = "bar") #' str(base::list) is_copyable <- function(x) { switch(typeof(x), NULL = , char = , symbol = , special = , builtin = , environment = , externalptr = FALSE, TRUE ) } is_equal <- function(x, y) { identical(x, y) } #' Is an object referencing another? #' #' @description #' #' There are typically two situations where two symbols may refer to #' the same object. #' #' * R objects usually have copy-on-write semantics. This is an #' optimisation that ensures that objects are only copied if #' needed. When you copy a vector, no memory is actually copied #' until you modify either the original object or the copy is #' modified. #' #' Note that the copy-on-write optimisation is an implementation #' detail that is not guaranteed by the specification of the R #' language. #' #' * Assigning an [uncopyable][is_copyable] object (like an #' environment) creates a reference. These objects are never copied #' even if you modify one of the references. #' #' @param x,y R objects. #' @keywords internal #' @export #' @examples #' # Reassigning an uncopyable object such as an environment creates a #' # reference: #' env <- env() #' ref <- env #' is_reference(ref, env) #' #' # Due to copy-on-write optimisation, a copied vector can #' # temporarily reference the original vector: #' vec <- 1:10 #' copy <- vec #' is_reference(copy, vec) #' #' # Once you modify on of them, the copy is triggered in the #' # background and the objects cease to reference each other: #' vec[[1]] <- 100 #' is_reference(copy, vec) is_reference <- function(x, y) { .Call(rlang_is_reference, x, y) } # Use different generic name to avoid import warnings when loading # packages that import all of rlang after it has been load_all'd rlang_type_sum <- function(x) { if (is_installed("pillar")) { pillar::type_sum(x) } else { UseMethod("type_sum") } } type_sum.ordered <- function(x) "ord" type_sum.factor <- function(x) "fct" type_sum.POSIXct <- function(x) "dttm" type_sum.difftime <- function(x) "time" type_sum.Date <- function(x) "date" type_sum.data.frame <- function(x) class(x)[[1]] type_sum.default <- function(x) { if (!is.object(x)) { switch(typeof(x), logical = "lgl", integer = "int", double = "dbl", character = "chr", complex = "cpl", builtin = , special = , closure = "fn", environment = "env", symbol = if (is_missing(x)) { "missing" } else { "sym" }, typeof(x) ) } else if (!isS4(x)) { paste0("S3: ", class(x)[[1]]) } else { paste0("S4: ", methods::is(x)[[1]]) } } rlang/R/lifecycle.R0000644000176200001440000001734513563536243013664 0ustar liggesusers#' Life cycle of the rlang package #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("maturing")} #' #' The rlang package is currently maturing. Unless otherwise stated, #' this applies to all its exported functions. Maturing functions are #' susceptible to API changes. Only use these in packages if you're #' prepared to make changes as the package evolves. See sections below #' for a list of functions marked as stable. #' #' The documentation pages of retired functions contain life cycle #' sections that explain the reasons for their retirements. #' #' #' @section Stable functions: #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("stable")} #' #' * [eval_tidy()] #' * [!!], [!!!] #' * [enquo()], [quo()], [quos()] #' * [enexpr()], [expr()], [exprs()] #' * [sym()], [syms()] #' * [new_quosure()], [is_quosure()] #' * [missing_arg()], [is_missing()] #' #' * [quo_get_expr()], [quo_set_expr()] #' * [quo_get_env()], [quo_set_env()] #' #' * [eval_bare()] #' #' * [set_names()], [names2()] #' * [as_function()], [new_function()] #' #' #' @section Experimental functions: #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} #' #' These functions are not yet part of the rlang API. Expect breaking #' changes. #' #' * [with_env()], [locally()], [env_poke()] #' * [pkg_env()], [pkg_env_name()], [ns_env()], [ns_imports_env()], [ns_env_name()] #' #' * [is_pairlist()], [as_pairlist()], [is_node()], [is_node_list()] #' #' * [is_definition()], [new_definition()], [is_formulaish()], #' [dots_definitions()] #' #' * [local_options()], [with_options()], [push_options()], #' [peek_options()], [peek_option()] #' #' * [as_bytes()], [chr_unserialise_unicode()] #' #' * [caller_fn()], [current_fn()] #' #' #' @section Questioning stage: #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} #' #' #' **In the questioning stage as of rlang 0.4.0** #' #' These functions are likely to be moved to the vctrs package: #' #' * [lgl()], [int()], etc. #' * [new_logical()], [new_integer()], etc. #' * [na_lgl], [na_int], [is_lgl_na()], [is_int_na()], etc. #' #' #' **In the questioning stage as of rlang 0.3.0** #' #' * [child_env()] #' * [flatten()], [squash()], and their atomic vector variants #' * [modify()] and [prepend()] #' * [with_restarts()], [rst_list()], [rst_exists()], [rst_jump()], #' [rst_maybe_jump()], [rst_abort()]. It is not clear yet whether we #' want to recommend restarts as a style of programming in R. #' * [return_from()] and [return_to()]. #' * [expr_label()], [expr_name()], and [expr_text()]. #' #' #' **In the questioning stage as of rlang 0.2.0** #' #' * [UQ()], [UQS()] #' * [dots_splice()], [splice()] #' #' #' @section Soft-deprecated functions and arguments: #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("soft-deprecated")} #' #' #' **Soft-deprecated in rlang 0.4.0** #' #' * [exiting()]: Handlers are now treated as exiting by default. #' * [invoke()]: Use the simpler [exec()] instead. #' * [as_logical()], [as_integer()], etc. => `vctrs::vec_cast()`. #' * [type_of()], [switch_type()], [coerce_type()], [switch_class()], #' [coerce_class()] #' #' #' @section Deprecated functions and arguments: #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' #' **Bumped to deprecated in rlang 0.4.0** #' #' * [modify()] and [prepend()]. #' * `new_logical_along()`, `new_integer_along()`, #' `new_double_along()`, `new_complex_along()`, #' `new_character_along()`, `new_raw_along()`, `new_list_along()`. #' #' * [lang_modify()] => [call_modify()] #' * [lang_standardise()] => [call_standardise()] #' * [lang_fn()] => [call_fn()] #' * [lang_name()] => [call_name()] #' * [lang_args()] => [call_args()] #' * [lang_args_names()] => [call_args_names()] #' * [lang_head()], [lang_tail()] #' * [lang()] => [call2()] #' * [new_language()] => [new_call()] #' * [is_lang()] => [is_call()] #' * [is_unary_lang()] => Use the `n` argument of [is_call()] #' * [is_binary_lang()] => Use the `n` argument of [is_call()] #' * [quo_is_lang()] => [quo_is_call()] #' #' * [call_modify()]: `.standardise` and `.env` arguments. #' #' * [is_expr()] => [is_expression()] #' * `quo_expr()` => [quo_squash()] #' * [parse_quosure()] => [parse_quo()] #' * [parse_quosures()] => [parse_quos()] #' * Assigning non-quosure objects to quosure lists. #' * `as.character()` on quosures. #' #' * [cnd_signal()]: `.cnd` => `cnd` #' * [cnd_signal()]: The `.mufflable` argument no longer has any effect #' #' * `scoped_names()` => [base::search()] #' * `is_scoped()` => [is_attached()] #' * `scoped_env()` => [search_env()] #' * `scoped_envs()` => [search_envs()] #' #' * `env_bind_exprs()` => [env_bind_lazy()] #' * `env_bind_fns()` => [env_bind_active()] #' * Passing a function or formula to `env_depth()`, #' `env_poke_parent()`, `env_parent<-`, `env_tail()`, `set_env()`, #' `env_clone()`, `env_inherits()`, `env_bind()`, #' `local_bindings()`, `with_bindings()`, `env_poke()`, #' `env_has()`, `env_get()`, `env_names()`, `env_bind_exprs()` and #' `env_bind_fns()`. This internal genericity was causing confusion #' (see issue #427). You should now extract the environment #' separately before calling these functions. #' * [get_env()]: The `env` argument no longer has a default and must be supplied #' #' * [is_frame()], [global_frame()], [current_frame()], #' [ctxt_frame()], [call_frame()], [frame_position()], #' [caller_frame()] #' #' * [ctxt_depth()], [call_depth()], [ctxt_stack()], [call_stack()], #' [stack_trim()] #' #' * [set_attrs()], [mut_attrs()] #' #' * The `width` and `printer` arguments of [exprs_auto_name()] and #' [quos_auto_name()] no longer have any effect. For the same #' reason, passing a width as `.named` argument of dots collectors #' like `quos()` is deprecated. #' #' * `as_overscope()` => [as_data_mask()] #' * `new_overscope()` => [new_data_mask()] #' * `overscope_eval_next()` => [eval_tidy()] #' * `overscope_clean()` #' #' #' @section Defunct functions and arguments: #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("defunct")} #' #' **Defunct as of rlang 0.4.0** #' #' * `length()` and `names()` on tidy eval `.data` pronouns. #' * Supplying a named `!!!` call. #' #' * [as_data_mask()]: `parent` argument #' * [new_data_mask()]: `parent` argument #' * [env_tail()]: `sentinel` => `last` #' * [abort()], [warn()], [inform()]: `msg`, `type` => `.msg`, `.type` #' * [abort()], [warn()], [inform()], [cnd()], [error_cnd()], #' [warning_cnd()], [message_cnd()]: `call` argument. #' * [is_character()], [is_string()], and variants: The `encoding` #' argument. #' #' #' @section Archived: #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("archived")} #' #' These functions were entirely removed from the package. You will #' find them in the commit history and previous releases. #' #' #' **Archived as of rlang 0.4.0** #' #' * `UQE()` #' * `as_dictionary()`, `is_dictionary()` #' * `as_quosureish()`, `is_quosureish()` #' * `eval_tidy_()` #' * `mut_utf8_locale()`, `mut_latin1_locale()`, `mut_mbcs_locale()` #' * `set_chr_encoding()`, `chr_encoding()`, `set_str_encoding()`, `str_encoding()` #' * `as_native_character()`, `as_utf8_string()`, `as_native_string()` #' * `lang_type_of()`, `switch_lang()`, `coerce_lang()` #' #' #' **Archived as of rlang 0.3.0:** #' #' * `cnd_inform()`, `cnd_warn()` and `cnd_abort()` #' #' * `new_cnd()` => [cnd()] #' * `cnd_message()` => [message_cnd()] #' * `cnd_warning()` => [warning_cnd()] #' * `cnd_error()` => [error_cnd()] #' * `rst_muffle()` => [cnd_muffle()] #' * `inplace()` => [calling()]. The `muffle` argument of `inplace()` #' has not been implemented in `calling()` and is now defunct. #' #' * [cnd_signal()]: `.msg` and `.call`. #' * [cnd()], [error_cnd()], [warning_cnd()] and [message_cnd()]: #' `.msg` => `message`. #' #' #' @keywords internal #' @name lifecycle NULL rlang/R/weakref.R0000644000176200001440000000573513500531447013341 0ustar liggesusers#' Create a weak reference #' #' @description #' #' A weak reference is a special R object which makes it possible to keep a #' reference to an object without preventing garbage collection of that object. #' It can also be used to keep data about an object without preventing GC of the #' object, similar to WeakMaps in JavaScript. #' #' Objects in R are considered _reachable_ if they can be accessed by following #' a chain of references, starting from a _root node_; root nodes are #' specially-designated R objects, and include the global environment and base #' environment. As long as the key is reachable, the value will not be garbage #' collected. This is true even if the weak reference object becomes #' unreachable. The key effectively prevents the weak reference and its value #' from being collected, according to the following chain of ownership: #' `weakref <- key -> value`. #' #' When the key becomes unreachable, the key and value in the weak reference #' object are replaced by `NULL`, and the finalizer is scheduled to execute. #' #' @param key The key for the weak reference. Must be a reference object -- that #' is, an environment or external pointer. #' @param value The value for the weak reference. This can be `NULL`, if you #' want to use the weak reference like a weak pointer. #' @param finalizer A function that is run after the key becomes unreachable. #' @param on_quit Should the finalizer be run when R exits? #' #' @keywords experimental #' @seealso [is_weakref()], [wref_key()] and [wref_value()]. #' @export #' @examples #' e <- env() #' #' # Create a weak reference to e #' w <- new_weakref(e, finalizer = function(e) message("finalized")) #' #' # Get the key object from the weak reference #' identical(wref_key(w), e) #' #' # When the regular reference (the `e` binding) is removed and a GC occurs, #' # the weak reference will not keep the object alive. #' rm(e) #' gc() #' identical(wref_key(w), NULL) #' #' #' # A weak reference with a key and value. The value contains data about the #' # key. #' k <- env() #' v <- list(1, 2, 3) #' w <- new_weakref(k, v) #' #' identical(wref_key(w), k) #' identical(wref_value(w), v) #' #' # When v is removed, the weak ref keeps it alive because k is still reachable. #' rm(v) #' gc() #' identical(wref_value(w), list(1, 2, 3)) #' #' # When k is removed, the weak ref does not keep k or v alive. #' rm(k) #' gc() #' identical(wref_key(w), NULL) #' identical(wref_value(w), NULL) new_weakref <- function(key, value = NULL, finalizer = NULL, on_quit = FALSE) { .Call(rlang_new_weakref, key, value, finalizer, on_quit) } #' Get key/value from a weak reference object #' #' @param x A weak reference object. #' #' @seealso [is_weakref()] and [new_weakref()]. #' #' @export wref_key <- function(x) { .Call(rlang_wref_key, x) } #' @rdname wref_key #' @export wref_value <- function(x) { .Call(rlang_wref_value, x) } #' Is object a weak reference? #' @param x An object to test. #' @export is_weakref <- function(x) { .Call(rlang_is_weakref, x) } rlang/R/compat-friendly-type.R0000644000176200001440000000253113535420473015764 0ustar liggesusers# nocov start --- r-lib/rlang compat-friendly-type --- 2019-09-09 Mon 11:50 friendly_type_of <- function(x, length = FALSE) { if (is.object(x)) { return(sprintf("a `%s` object", paste(class(x), collapse = "/"))) } friendly <- as_friendly_type(typeof(x)) if (length && rlang::is_vector(x)) { friendly <- paste0(friendly, sprintf(" of length %s", length(x))) } friendly } as_friendly_type <- function(type) { switch(type, logical = "a logical vector", integer = "an integer vector", numeric = , double = "a double vector", complex = "a complex vector", character = "a character vector", raw = "a raw vector", string = "a string", list = "a list", NULL = "NULL", environment = "an environment", externalptr = "a pointer", weakref = "a weak reference", S4 = "an S4 object", name = , symbol = "a symbol", language = "a call", pairlist = "a pairlist node", expression = "an expression vector", quosure = "a quosure", formula = "a formula", char = "an internal string", promise = "an internal promise", ... = "an internal dots object", any = "an internal `any` object", bytecode = "an internal bytecode object", primitive = , builtin = , special = "a primitive function", closure = "a function", type ) } # nocov end rlang/R/cnd-handlers.R0000644000176200001440000002433313607306553014260 0ustar liggesusers#' Establish handlers on the stack #' #' @description #' #' Condition handlers are functions established on the evaluation #' stack (see [ctxt_stack()]) that are called by R when a condition is #' signalled (see [cnd_signal()] and [abort()] for two common signal #' functions). They come in two types: #' #' * Exiting handlers aborts all code currently run between #' `with_handlers()` and the point where the condition has been #' raised. `with_handlers()` passes the return value of the handler #' to its caller. #' #' * Calling handlers, which are executed from inside the signalling #' functions. Their return values are ignored, only their side #' effects matters. Valid side effects are writing a log message, or #' jumping out of the signalling context by [invoking a #' restart][with_restarts] or using [return_from()]. If the raised #' condition was an error, this interrupts the aborting process. #' #' If a calling handler returns normally, it effectively declines to #' handle the condition and other handlers on the stack (calling or #' exiting) are given a chance to handle the condition. #' #' Handlers are exiting by default, use [calling()] to create a #' calling handler. #' #' @param .expr An expression to execute in a context where new #' handlers are established. The underscored version takes a quoted #' expression or a quoted formula. #' @param ... <[dynamic][dyn-dots]> Named handlers. These should be #' functions of one argument, or [formula functions][as_function]. #' The handlers are considered exiting by default, use [calling()] #' to specify a calling handler. #' #' @section Life cycle: `exiting()` is soft-deprecated as of rlang #' 0.4.0 because [with_handlers()] now treats handlers as exiting by #' default. #' #' @examples #' # Signal a condition with signal(): #' fn <- function() { #' g() #' cat("called?\n") #' "fn() return value" #' } #' g <- function() { #' h() #' cat("called?\n") #' } #' h <- function() { #' signal("A foobar condition occurred", "foo") #' cat("called?\n") #' } #' #' # Exiting handlers jump to with_handlers() before being #' # executed. Their return value is handed over: #' handler <- function(c) "handler return value" #' with_handlers(fn(), foo = handler) #' #' # Calling handlers are called in turn and their return value is #' # ignored. Returning just means they are declining to take charge of #' # the condition. However, they can produce side-effects such as #' # displaying a message: #' some_handler <- function(c) cat("some handler!\n") #' other_handler <- function(c) cat("other handler!\n") #' with_handlers(fn(), foo = calling(some_handler), foo = calling(other_handler)) #' #' # If a calling handler jumps to an earlier context, it takes #' # charge of the condition and no other handler gets a chance to #' # deal with it. The canonical way of transferring control is by #' # jumping to a restart. See with_restarts() and restarting() #' # documentation for more on this: #' exiting_handler <- function(c) rst_jump("rst_foo") #' fn2 <- function() { #' with_restarts(g(), rst_foo = function() "restart value") #' } #' with_handlers(fn2(), foo = calling(exiting_handler), foo = calling(other_handler)) #' @export with_handlers <- function(.expr, ...) { handlers <- list2(...) is_calling <- map_lgl(handlers, inherits, "rlang_box_calling_handler") handlers <- map_if(handlers, is_calling, unbox) handlers <- map(handlers, as_function) calling <- handlers[is_calling] exiting <- handlers[!is_calling] expr <- quote(.expr) if (length(calling)) { expr <- expr(withCallingHandlers(!!expr, !!!calling)) } if (length(exiting)) { expr <- expr(tryCatch(!!expr, !!!exiting)) } .Call(rlang_eval, expr, environment()) } #' @rdname with_handlers #' @param handler A handler function that takes a condition as #' argument. This is passed to [as_function()] and can thus be a #' formula describing a lambda function. #' @export calling <- function(handler) { handler <- as_function(handler) new_box(handler, "rlang_box_calling_handler") } #' Create a restarting handler #' #' This constructor automates the common task of creating an #' [calling()] handler that invokes a restart. #' #' Jumping to a restart point from a calling handler has two #' effects. First, the control flow jumps to wherever the restart was #' established, and the restart function is called (with `...`, or #' `.fields` as arguments). Execution resumes from the #' [with_restarts()] call. Secondly, the transfer of the control flow #' out of the function that signalled the condition means that the #' handler has dealt with the condition. Thus the condition will not #' be passed on to other potential handlers established on the stack. #' #' @param .restart The name of a restart. #' @param .fields A character vector specifying the fields of the #' condition that should be passed as arguments to the restart. If #' named, the names (except empty names `""`) are used as #' argument names for calling the restart function. Otherwise the #' the fields themselves are used as argument names. #' @param ... <[dynamic][dyn-dots]> Additional arguments passed on #' the restart function. These arguments are evaluated only once #' and immediately, when creating the restarting handler. #' @keywords internal #' @export #' @seealso [calling()] and [exiting()]. #' @examples #' # This is a restart that takes a data frame and names as arguments #' rst_bar <- function(df, nms) { #' stats::setNames(df, nms) #' } #' #' # This restart is simpler and does not take arguments #' rst_baz <- function() "baz" #' #' # Signalling a condition parameterised with a data frame #' fn <- function() { #' with_restarts(signal("A foobar condition occurred", "foo", foo_field = mtcars), #' rst_bar = rst_bar, #' rst_baz = rst_baz #' ) #' } #' #' # Creating a restarting handler that passes arguments `nms` and #' # `df`, the latter taken from a data field of the condition object #' restart_bar <- restarting("rst_bar", #' nms = LETTERS[1:11], .fields = c(df = "foo_field") #' ) #' #' # The restarting handlers jumps to `rst_bar` when `foo` is signalled: #' with_handlers(fn(), foo = restart_bar) #' #' # The restarting() constructor is especially nice to use with #' # restarts that do not need arguments: #' with_handlers(fn(), foo = restarting("rst_baz")) restarting <- function(.restart, ..., .fields = NULL) { stopifnot(is_scalar_character(.restart)) if (!is_null(.fields)) { .fields <- set_names2(.fields) stopifnot(is_character(.fields) && is_dictionaryish(.fields)) } args <- list2(...) handler <- function(c) { fields <- set_names(c[.fields], names(.fields)) rst_args <- c(fields, args) do.call("rst_jump", c(list(.restart = .restart), rst_args)) } calling(handler) } #' Catch a condition #' #' This is a small wrapper around `tryCatch()` that captures any #' condition signalled while evaluating its argument. It is useful for #' situations where you expect a specific condition to be signalled, #' for debugging, and for unit testing. #' #' @param expr Expression to be evaluated with a catching condition #' handler. #' @param classes A character vector of condition classes to catch. By #' default, catches all conditions. #' @return A condition if any was signalled, `NULL` otherwise. #' @export #' @examples #' catch_cnd(10) #' catch_cnd(abort("an error")) #' catch_cnd(signal("my_condition", message = "a condition")) catch_cnd <- function(expr, classes = "condition") { stopifnot(is_character(classes)) handlers <- rep_named(classes, list(identity)) eval_bare(rlang::expr( tryCatch(!!!handlers, { force(expr) return(NULL) }) )) } #' Muffle a condition #' #' Unlike [exiting()] handlers, [calling()] handlers must be explicit #' that they have handled a condition to stop it from propagating to #' other handlers. Use `cnd_muffle()` within a calling handler (or as #' a calling handler, see examples) to prevent any other handlers from #' being called for that condition. #' #' #' @section Mufflable conditions: #' #' Most conditions signalled by base R are muffable, although the name #' of the restart varies. cnd_muffle() will automatically call the #' correct restart for you. It is compatible with the following #' conditions: #' #' * `warning` and `message` conditions. In this case `cnd_muffle()` #' is equivalent to [base::suppressMessages()] and #' [base::suppressWarnings()]. #' #' * Bare conditions signalled with `signal()` or [cnd_signal()]. Note #' that conditions signalled with [base::signalCondition()] are not #' mufflable. #' #' * Interrupts are sometimes signalled with a `resume` restart on #' recent R versions. When this is the case, you can muffle the #' interrupt with `cnd_muffle()`. Check if a restart is available #' with `base::findRestart("resume")`. #' #' If you call `cnd_muffle()` with a condition that is not mufflable #' you will cause a new error to be signalled. #' #' * Errors are not mufflable since they are signalled in critical #' situations where execution cannot continue safely. #' #' * Conditions captured with [base::tryCatch()], [with_handlers()] or #' [catch_cnd()] are no longer mufflable. Muffling restarts _must_ #' be called from a [calling] handler. #' #' @param cnd A condition to muffle. #' #' @keywords internal #' @export #' @examples #' fn <- function() { #' inform("Beware!", "my_particular_msg") #' inform("On your guard!") #' "foobar" #' } #' #' # Let's install a muffling handler for the condition thrown by `fn()`. #' # This will suppress all `my_particular_wng` warnings but let other #' # types of warnings go through: #' with_handlers(fn(), #' my_particular_msg = calling(function(cnd) { #' inform("Dealt with this particular message") #' cnd_muffle(cnd) #' }) #' ) #' #' # Note how execution of `fn()` continued normally after dealing #' # with that particular message. #' #' # cnd_muffle() can also be passed to with_handlers() as a calling #' # handler: #' with_handlers(fn(), #' my_particular_msg = calling(cnd_muffle) #' ) cnd_muffle <- function(cnd) { restart <- switch(cnd_type(cnd), message = "muffleMessage", warning = "muffleWarning", interrupt = "resume", "rlang_muffle" ) if (!is_null(findRestart(restart))) { invokeRestart(restart) } abort("Can't find a muffling restart") } rlang/R/node.R0000644000176200001440000001213013457603056012634 0ustar liggesusers#' Helpers for pairlist and language nodes #' #' @description #' #' **Important**: These functions are for expert R programmers only. #' You should only use them if you feel comfortable manipulating low #' level R data structures at the C level. We export them at the R level #' in order to make it easy to prototype C code. They don't perform #' any type checking and can crash R very easily (try to take the CAR #' of an integer vector --- save any important objects beforehand!). #' #' @param x A language or pairlist node. Note that these functions are #' barebones and do not perform any type checking. #' @param car,newcar,cdr,newcdr The new CAR or CDR for the node. These #' can be any R objects. #' @param newtag The new tag for the node. This should be a symbol. #' @return Setters like `node_poke_car()` invisibly return `x` modified #' in place. Getters return the requested node component. #' @seealso [duplicate()] for creating copy-safe objects and #' [base::pairlist()] for an easier way of creating a linked list of #' nodes. #' @keywords internal #' @export new_node <- function(car, cdr = NULL) { .Call(rlang_new_node, car, cdr) } #' @rdname new_node #' @export node_car <- function(x) { .Call(rlang_node_car, x) } #' @rdname new_node #' @export node_cdr <- function(x) { .Call(rlang_node_cdr, x) } #' @rdname new_node #' @export node_caar <- function(x) { .Call(rlang_node_caar, x) } #' @rdname new_node #' @export node_cadr <- function(x) { .Call(rlang_node_cadr, x) } #' @rdname new_node #' @export node_cdar <- function(x) { .Call(rlang_node_cdar, x) } #' @rdname new_node #' @export node_cddr <- function(x) { .Call(rlang_node_cddr, x) } #' @rdname new_node #' @export node_poke_car <- function(x, newcar) { invisible(.Call(rlang_node_poke_car, x, newcar)) } #' @rdname new_node #' @export node_poke_cdr <- function(x, newcdr) { invisible(.Call(rlang_node_poke_cdr, x, newcdr)) } #' @rdname new_node #' @export node_poke_caar <- function(x, newcar) { invisible(.Call(rlang_node_poke_caar, x, newcar)) } #' @rdname new_node #' @export node_poke_cadr <- function(x, newcar) { invisible(.Call(rlang_node_poke_cadr, x, newcar)) } #' @rdname new_node #' @export node_poke_cdar <- function(x, newcdr) { invisible(.Call(rlang_node_poke_cdar, x, newcdr)) } #' @rdname new_node #' @export node_poke_cddr <- function(x, newcdr) { invisible(.Call(rlang_node_poke_cddr, x, newcdr)) } #' @rdname new_node #' @export node_tag <- function(x) { .Call(rlang_node_tag, x) } #' @rdname new_node #' @export node_poke_tag <- function(x, newtag) { invisible(.Call(rlang_node_poke_tag, x, newtag)) } #' Coerce to pairlist #' #' This transforms vector objects to a linked pairlist of nodes. See #' the [pairlist][node] type help page. #' #' #' @keywords internal #' @section Life cycle: #' #' `as_pairlist()` is experimental because we are still figuring out #' the naming scheme for pairlists and node-like objects. #' #' @param x An object to coerce. #' @export as_pairlist <- function(x) { if (! typeof(x) %in% c(atomic_types, "list", "pairlist", "NULL")) { abort_coercion(x, "pairlist") } as.vector(x, "pairlist") } #' Is object a node or pairlist? #' #' @description #' #' * `is_pairlist()` checks that `x` has type `pairlist`. #' #' * `is_node()` checks that `x` has type `pairlist` or `language`. #' It tests whether `x` is a node that has a CAR and a CDR, #' including callable nodes (language objects). #' #' * `is_node_list()` checks that `x` has type `pairlist` or `NULL`. #' `NULL` is the empty node list. #' #' #' @section Life cycle: #' #' These functions are experimental. We are still figuring out a good #' naming convention to refer to the different lisp-like lists in R. #' #' @param x Object to test. #' @seealso [is_call()] tests for language nodes. #' @keywords internal #' @export is_pairlist <- function(x) { typeof(x) == "pairlist" } #' @rdname is_pairlist #' @export is_node <- function(x) { typeof(x) %in% c("pairlist", "language") } #' @rdname is_pairlist #' @export is_node_list <- function(x) { typeof(x) %in% c("pairlist", "NULL") } # Shallow copy of node trees node_tree_clone <- function(x) { .Call(rlang_node_tree_clone, x); } node_walk <- function(.x, .f, ...) { cur <- .x while (!is.null(cur)) { .f(cur, ...) cur <- node_cdr(cur) } NULL } node_walk_nonnull <- function(.x, .f, ...) { cur <- .x out <- NULL while (!is.null(cur) && is.null(out)) { out <- .f(cur, ...) cur <- node_cdr(cur) } out } node_walk_last <- function(.x, .f, ...) { cur <- .x while (!is.null(node_cdr(cur))) { cur <- node_cdr(cur) } .f(cur, ...) } node_append <- function(.x, .y) { node_walk_last(.x, function(l) node_poke_cdr(l, .y)) .x } node_list_reverse <- function(x) { .Call(rlang_node_list_reverse, x) } #' Create a new call from components #' #' @param car The head of the call. It should be a #' [callable][is_callable] object: a symbol, call, or literal #' function. #' @param cdr The tail of the call, i.e. a [node list][node] of #' arguments. #' #' @keywords internal #' @export new_call <- function(car, cdr = NULL) { .Call(rlang_new_call, car, cdr) } rlang/R/utils-cli-tree.R0000644000176200001440000000437613406265312014557 0ustar liggesusers# Extract from cli::tree # Modifications: # * Remove assertions (requires assertthat) # * Remove width triming (requires ansistrings or similar) # * Use map_chr() instead of vcapply() # Additional functions inlined: # * is_utf8_output() # * is_latex_output() cli_tree <- function(data, root = data[[1]][[1]], style = NULL, indices = NULL) { style <- style %||% cli_box_chars() labels <- if (ncol(data) >= 3) data[[3]] else data[[1]] res <- character() pt <- function(root, n = integer(), mx = integer()) { num_root <- match(root, data[[1]]) level <- length(n) - 1 prefix <- map_chr(seq_along(n), function(i) { if (n[i] < mx[i]) { if (i == length(n)) { paste0(style$j, style$h) } else { paste0(style$v, " ") } } else if (n[i] == mx[i] && i == length(n)) { paste0(style$l, style$h) } else { " " } }) res <<- c(res, paste0(paste(prefix, collapse = ""), labels[[num_root]])) children <- data[[2]][[num_root]] for (d in seq_along(children)) { pt(children[[d]], c(n, d), c(mx, length(children))) } } if (nrow(data)) { pt(root) } if (length(indices)) { indices <- pad_spaces(as.character(indices)) indices <- paste0(" ", indices, ". ") # The root isn't numbered root_padding <- spaces(nchar(indices[[1]])) indices <- c(root_padding, indices) res <- paste0(silver(indices), res) } res } cli_box_chars <- function() { if (cli_is_utf8_output()) { list( "h" = "\u2500", # horizontal "v" = "\u2502", # vertical "l" = "\u2514", # leaf "j" = "\u251C" # junction ) } else { list( "h" = "-", # horizontal "v" = "|", # vertical "l" = "\\", # leaf "j" = "+" # junction ) } } cli_is_utf8_output <- function() { opt <- getOption("cli.unicode", NULL) if (!is.null(opt)) { isTRUE(opt) } else { l10n_info()$`UTF-8` && !cli_is_latex_output() } } cli_is_latex_output <- function() { if (!("knitr" %in% loadedNamespaces())) return(FALSE) get("is_latex_output", asNamespace("knitr"))() } rlang/R/cnd-restarts.R0000644000176200001440000001650113563532006014320 0ustar liggesusers#' Establish a restart point on the stack #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} #' #' Restart points are named functions that are established with #' `with_restarts()`. Once established, you can interrupt the normal #' execution of R code, jump to the restart, and resume execution from #' there. Each restart is established along with a restart function #' that is executed after the jump and that provides a return value #' from the establishing point (i.e., a return value for #' `with_restarts()`). #' #' @param .expr An expression to execute with new restarts established #' on the stack. This argument is passed by expression and supports #' [unquoting][nse-force]. It is evaluated in a context where #' restarts are established. #' @param ... <[dynamic][dyn-dots]> Named restart functions. The #' name is taken as the restart name and the function is executed #' after the jump. #' @seealso [return_from()] and [return_to()] for a more flexible way #' of performing a non-local jump to an arbitrary call frame. #' #' @details #' #' Restarts are not the only way of jumping to a previous call frame #' (see [return_from()] or [return_to()]). However, they have the #' advantage of being callable by name once established. #' #' @section Life cycle: #' #' All the restart functions are in the questioning stage. It is not #' clear yet whether we want to recommend restarts as a style of #' programming in R. #' #' @keywords internal #' @export #' @examples #' # Restarts are not the only way to jump to a previous frame, but #' # they have the advantage of being callable by name: #' fn <- function() with_restarts(g(), my_restart = function() "returned") #' g <- function() h() #' h <- function() { rst_jump("my_restart"); "not returned" } #' fn() #' #' # Whereas a non-local return requires to manually pass the calling #' # frame to the return function: #' fn <- function() g(current_env()) #' g <- function(env) h(env) #' h <- function(env) { return_from(env, "returned"); "not returned" } #' fn() #' #' #' # rst_maybe_jump() checks that a restart exists before trying to jump: #' fn <- function() { #' g() #' cat("will this be called?\n") #' } #' g <- function() { #' rst_maybe_jump("my_restart") #' cat("will this be called?\n") #' } #' #' # Here no restart are on the stack: #' fn() #' #' # If a restart point called `my_restart` was established on the #' # stack before calling fn(), the control flow will jump there: #' rst <- function() { #' cat("restarting...\n") #' "return value" #' } #' with_restarts(fn(), my_restart = rst) #' #' #' # Restarts are particularly useful to provide alternative default #' # values when the normal output cannot be computed: #' #' fn <- function(valid_input) { #' if (valid_input) { #' return("normal value") #' } #' #' # We decide to return the empty string "" as default value. An #' # altenative strategy would be to signal an error. In any case, #' # we want to provide a way for the caller to get a different #' # output. For this purpose, we provide two restart functions that #' # returns alternative defaults: #' restarts <- list( #' rst_empty_chr = function() character(0), #' rst_null = function() NULL #' ) #' #' with_restarts(splice(restarts), .expr = { #' #' # Signal a typed condition to let the caller know that we are #' # about to return an empty string as default value: #' cnd_signal("default_empty_string") #' #' # If no jump to with_restarts, return default value: #' "" #' }) #' } #' #' # Normal value for valid input: #' fn(TRUE) #' #' # Default value for bad input: #' fn(FALSE) #' #' # Change the default value if you need an empty character vector by #' # defining a calling handler that jumps to the restart. It has to #' # be calling because exiting handlers jump to the place where they #' # are established before being executed, and the restart is not #' # defined anymore at that point: #' rst_handler <- calling(function(c) rst_jump("rst_empty_chr")) #' with_handlers(fn(FALSE), default_empty_string = rst_handler) #' #' # You can use restarting() to create restarting handlers easily: #' with_handlers(fn(FALSE), default_empty_string = restarting("rst_null")) with_restarts <- function(.expr, ...) { restarts <- map(list2(...), as_function) value(withRestarts(.expr, !!!restarts)) } #' Restarts utilities #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} #' #' Restarts are named jumping points established by [with_restarts()]. #' `rst_list()` returns the names of all restarts currently #' established. `rst_exists()` checks if a given restart is #' established. `rst_jump()` stops execution of the current function #' and jumps to a restart point. If the restart does not exist, an #' error is thrown. `rst_maybe_jump()` first checks that a restart #' exists before jumping. #' #' @param .restart The name of a restart. #' @param ... <[dynamic][dyn-dots]> Arguments passed on to the #' restart function. #' @seealso [with_restarts()] #' #' @section Life cycle: #' #' All the restart functions are in the questioning stage. It is not #' clear yet whether we want to recommend restarts as a style of #' programming in R. #' #' @keywords internal #' @export rst_list <- function() { computeRestarts() } #' @rdname rst_list #' @export rst_exists <- function(.restart) { !is.null(findRestart(.restart)) } #' @rdname rst_list #' @export rst_jump <- function(.restart, ...) { args <- c(list(r = .restart), dots_list(...)) do.call("invokeRestart", args) } #' @rdname rst_list #' @export rst_maybe_jump <- function(.restart, ...) { if (rst_exists(.restart)) { args <- list2(r = .restart, ...) do.call("invokeRestart", args) } } #' Jump to the abort restart #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} #' #' The abort restart is the only restart that is established at top #' level. It is used by R as a top-level target, most notably when an #' error is issued (see [abort()]) that no handler is able #' to deal with (see [with_handlers()]). #' #' @section Life cycle: #' #' All the restart functions are in the questioning stage. It is not #' clear yet whether we want to recommend restarts as a style of #' programming in R. #' #' @seealso [rst_jump()], [abort()] #' @keywords internal #' @export #' @examples #' # The `abort` restart is a bit special in that it is always #' # registered in a R session. You will always find it on the restart #' # stack because it is established at top level: #' rst_list() #' #' # You can use the `above` restart to jump to top level without #' # signalling an error: #' \dontrun{ #' fn <- function() { #' cat("aborting...\n") #' rst_abort() #' cat("This is never called\n") #' } #' { #' fn() #' cat("This is never called\n") #' } #' } #' #' # The `above` restart is the target that R uses to jump to top #' # level when critical errors are signalled: #' \dontrun{ #' { #' abort("error") #' cat("This is never called\n") #' } #' } #' #' # If another `abort` restart is specified, errors are signalled as #' # usual but then control flow resumes with from the new restart: #' \dontrun{ #' out <- NULL #' { #' out <- with_restarts(abort("error"), abort = function() "restart!") #' cat("This is called\n") #' } #' cat("`out` has now become:", out, "\n") #' } rst_abort <- function() { rst_jump("abort") } rlang/R/formula.R0000644000176200001440000001164313612027777013367 0ustar liggesusers#' Create a formula #' #' @param lhs,rhs A call, name, or atomic vector. #' @param env An environment. #' @return A formula object. #' @seealso [new_quosure()] #' @export #' @examples #' new_formula(quote(a), quote(b)) #' new_formula(NULL, quote(b)) new_formula <- function(lhs, rhs, env = caller_env()) { .Call(rlang_new_formula, lhs, rhs, env) } #' Is object a formula? #' #' `is_formula()` tests if `x` is a call to `~`. `is_bare_formula()` #' tests in addition that `x` does not inherit from anything else than #' `"formula"`. #' #' The `scoped` argument patterns-match on whether the scoped bundled #' with the quosure is valid or not. Invalid scopes may happen in #' nested quotations like `~~expr`, where the outer quosure is validly #' scoped but not the inner one. This is because `~` saves the #' environment when it is evaluated, and quoted formulas are by #' definition not evaluated. #' #' @param x An object to test. #' @param scoped A boolean indicating whether the quosure is scoped, #' that is, has a valid environment attribute. If `NULL`, the scope #' is not inspected. #' @param lhs A boolean indicating whether the [formula][is_formula] #' or [definition][is_definition] has a left-hand side. If `NULL`, #' the LHS is not inspected. #' @export #' @examples #' x <- disp ~ am #' is_formula(x) #' #' is_formula(~10) #' is_formula(10) #' #' is_formula(quo(foo)) #' is_bare_formula(quo(foo)) #' #' # Note that unevaluated formulas are treated as bare formulas even #' # though they don't inherit from "formula": #' f <- quote(~foo) #' is_bare_formula(f) #' #' # However you can specify `scoped` if you need the predicate to #' # return FALSE for these unevaluated formulas: #' is_bare_formula(f, scoped = TRUE) #' is_bare_formula(eval(f), scoped = TRUE) is_formula <- function(x, scoped = NULL, lhs = NULL) { if (!is_formulaish(x, scoped = scoped, lhs = lhs)) { return(FALSE) } identical(node_car(x), tilde_sym) } #' @rdname is_formula #' @export is_bare_formula <- function(x, scoped = NULL, lhs = NULL) { if (!is_formula(x, scoped = scoped, lhs = lhs)) { return(FALSE) } class <- class(x) is_null(class) || identical(class, "formula") } #' Get or set formula components #' #' `f_rhs` extracts the righthand side, `f_lhs` extracts the lefthand #' side, and `f_env` extracts the environment. All functions throw an #' error if `f` is not a formula. #' #' @param f,x A formula #' @param value The value to replace with. #' @export #' @return `f_rhs` and `f_lhs` return language objects (i.e. atomic #' vectors of length 1, a name, or a call). `f_env` returns an #' environment. #' @examples #' f_rhs(~ 1 + 2 + 3) #' f_rhs(~ x) #' f_rhs(~ "A") #' f_rhs(1 ~ 2) #' #' f_lhs(~ y) #' f_lhs(x ~ y) #' #' f_env(~ x) f_rhs <- function(f) { if (is_quosure(f)) { signal_formula_access() return(quo_get_expr(f)) } .Call(r_f_rhs, f) } #' @export #' @rdname f_rhs `f_rhs<-` <- function(x, value) { if (is_quosure(x)) { signal_formula_access() return(quo_set_expr(x, value)) } if (!is_formula(x)) { abort("`f` must be a formula") } x[[length(x)]] <- value x } #' @export #' @rdname f_rhs f_lhs <- function(f) { if (is_quosure(f)) { signal_formula_access() abort("Can't retrieve the LHS of a quosure") } .Call(r_f_lhs, f) } #' @export #' @rdname f_rhs `f_lhs<-` <- function(x, value) { if (is_quosure(x)) { signal_formula_access() abort("Can't set the LHS of a quosure") } if (!is_formula(x)) { abort("`f` must be a formula") } if (length(x) < 3) { x <- duplicate(x) node_poke_cdr(x, pairlist(value, x[[2]])) } else { x[[2]] <- value } x } #' @export #' @rdname f_rhs f_env <- function(f) { if (is_quosure(f)) { signal_formula_access() return(quo_get_env(f)) } if (!is_formula(f)) { abort("`f` must be a formula") } attr(f, ".Environment") } #' @export #' @rdname f_rhs `f_env<-` <- function(x, value) { if (is_quosure(x)) { signal_formula_access() return(quo_set_env(x, value)) } if (!is_formula(x)) { abort("`f` must be a formula") } structure(x, .Environment = value) } #' Turn RHS of formula into a string or label #' #' Equivalent of [expr_text()] and [expr_label()] for formulas. #' #' @param x A formula. #' @inheritParams expr_text #' @export #' @examples #' f <- ~ a + b + bc #' f_text(f) #' f_label(f) #' #' # Names a quoted with `` #' f_label(~ x) #' # Strings are encoded #' f_label(~ "a\nb") #' # Long expressions are collapsed #' f_label(~ foo({ #' 1 + 2 #' print(x) #' })) f_text <- function(x, width = 60L, nlines = Inf) { expr_text(f_rhs(x), width = width, nlines = nlines) } #' @rdname f_text #' @export f_name <- function(x) { expr_name(f_rhs(x)) } #' @rdname f_text #' @export f_label <- function(x) { expr_label(f_rhs(x)) } signal_formula_access <- function() { if (is_true(peek_option("rlang:::warn_quosure_access"))) { warn( "Using formula accessors with quosures is soft-deprecated" ) } } rlang/R/rlang.R0000644000176200001440000000371113610376546013021 0ustar liggesusers#' @useDynLib rlang, .registration = TRUE NULL # For cnd.R is_same_body <- NULL on_package_load <- function(pkg, expr) { if (isNamespaceLoaded(pkg)) { expr } else { thunk <- function(...) expr setHook(packageEvent(pkg, "onLoad"), thunk) } } downstream_deps <- list( dplyr = c(min = "0.8.0", from = "0.4.0") ) check_downstream_dep <- function(dep, pkg) { min <- dep[["min"]] from <- dep[["from"]] stopifnot( !is_null(min), !is_null(from) ) ver <- utils::packageVersion(pkg) if (ver >= min) { return() } rlang_ver <- utils::packageVersion("rlang") msg <- c( sprintf("As of rlang %s, %s must be at least version %s.", from, pkg, min), x = sprintf("%s %s is too old for rlang %s.", pkg, ver, rlang_ver) ) os <- tolower(Sys.info()[["sysname"]]) if (os == "windows") { url <- "https://github.com/jennybc/what-they-forgot/issues/62" howto <- c( i = sprintf("Please update %s to the latest version.", pkg), i = sprintf("Updating packages on Windows requires precautions:\n <%s>", url) ) } else { howto <- c( i = sprintf("Please update %s with `install.packages(\"%s\")` and restart R.", pkg, pkg) ) } msg <- c(msg, howto) warn(msg) } base_ns_env <- NULL base_pkg_env <- NULL .onLoad <- function(lib, pkg) { if (getRversion() < "3.5") { is_same_body <<- function(x, y) identical(x, y) } else { is_same_body <<- is_reference } on_package_load("glue", .Call(rlang_glue_is_there)) .Call(r_init_library) .Call(rlang_library_load, ns_env("rlang")) s3_register("pillar::pillar_shaft", "quosures", pillar_shaft.quosures) s3_register("pillar::type_sum", "quosures", type_sum.quosures) map2(downstream_deps, names(downstream_deps), function(dep, pkg) { force(dep) on_package_load(pkg, check_downstream_dep(dep, pkg)) }) base_ns_env <<- ns_env("base") base_pkg_env <<- baseenv() } .onUnload <- function(lib) { .Call(rlang_library_unload) } rlang/R/env-binding.R0000644000176200001440000005373613563536376014140 0ustar liggesusers#' Bind symbols to objects in an environment #' #' @description #' #' These functions create bindings in an environment. The bindings are #' supplied through `...` as pairs of names and values or expressions. #' `env_bind()` is equivalent to evaluating a `<-` expression within #' the given environment. This function should take care of the #' majority of use cases but the other variants can be useful for #' specific problems. #' #' - `env_bind()` takes named _values_ which are bound in `.env`. #' `env_bind()` is equivalent to [base::assign()]. #' #' - `env_bind_active()` takes named _functions_ and creates active #' bindings in `.env`. This is equivalent to #' [base::makeActiveBinding()]. An active binding executes a #' function each time it is evaluated. The arguments are passed to #' [as_function()] so you can supply formulas instead of functions. #' #' Remember that functions are scoped in their own environment. #' These functions can thus refer to symbols from this enclosure #' that are not actually in scope in the dynamic environment where #' the active bindings are invoked. This allows creative solutions #' to difficult problems (see the implementations of `dplyr::do()` #' methods for an example). #' #' - `env_bind_lazy()` takes named _expressions_. This is equivalent #' to [base::delayedAssign()]. The arguments are captured with #' [exprs()] (and thus support call-splicing and unquoting) and #' assigned to symbols in `.env`. These expressions are not #' evaluated immediately but lazily. Once a symbol is evaluated, the #' corresponding expression is evaluated in turn and its value is #' bound to the symbol (the expressions are thus evaluated only #' once, if at all). #' #' #' @section Side effects: #' #' Since environments have reference semantics (see relevant section #' in [env()] documentation), modifying the bindings of an environment #' produces effects in all other references to that environment. In #' other words, `env_bind()` and its variants have side effects. #' #' Like other side-effecty functions like `par()` and `options()`, #' `env_bind()` and variants return the old values invisibly. #' #' #' @section Life cycle: #' #' Passing an environment wrapper like a formula or a function instead #' of an environment is soft-deprecated as of rlang 0.3.0. This #' internal genericity was causing confusion (see issue #427). You #' should now extract the environment separately before calling these #' functions. #' #' @param .env An environment. #' @param ... <[dynamic][dyn-dots]> Named objects (`env_bind()`), #' expressions `env_bind_lazy()`, or functions (`env_bind_active()`). #' Use [zap()] to remove bindings. #' @return The input object `.env`, with its associated environment #' modified in place, invisibly. #' @export #' @examples #' # env_bind() is a programmatic way of assigning values to symbols #' # with `<-`. We can add bindings in the current environment: #' env_bind(current_env(), foo = "bar") #' foo #' #' # Or modify those bindings: #' bar <- "bar" #' env_bind(current_env(), bar = "BAR") #' bar #' #' # You can remove bindings by supplying zap sentinels: #' env_bind(current_env(), foo = zap()) #' try(foo) #' #' # Unquote-splice a named list of zaps #' zaps <- rep_named(c("foo", "bar"), list(zap())) #' env_bind(current_env(), !!!zaps) #' try(bar) #' #' # It is most useful to change other environments: #' my_env <- env() #' env_bind(my_env, foo = "foo") #' my_env$foo #' #' # A useful feature is to splice lists of named values: #' vals <- list(a = 10, b = 20) #' env_bind(my_env, !!!vals, c = 30) #' my_env$b #' my_env$c #' #' # You can also unquote a variable referring to a symbol or a string #' # as binding name: #' var <- "baz" #' env_bind(my_env, !!var := "BAZ") #' my_env$baz #' #' #' # The old values of the bindings are returned invisibly: #' old <- env_bind(my_env, a = 1, b = 2, baz = "baz") #' old #' #' # You can restore the original environment state by supplying the #' # old values back: #' env_bind(my_env, !!!old) env_bind <- function(.env, ...) { env_bind_impl(.env, list3(...), "env_bind()", bind = TRUE) } env_bind_impl <- function(env, data, fn, bind = FALSE, binder = NULL) { if (!is_vector(data)) { type <- friendly_type_of(data) abort(sprintf("`data` must be a vector not a %s", type)) } if (length(data)) { nms <- names(data) if (is_null(nms) || any(nms_are_invalid(nms))) { abort("Can't bind data because all arguments must be named") } if (any(duplicated(nms))) { abort("Can't bind data because some arguments have the same name") } } env <- get_env_retired(env, fn) data <- vec_coerce(data, "list") nms <- names2(data) if (bind) { old <- new_list(length(nms), nms) overwritten <- env_has(env, nms) old[overwritten] <- env_get_list(env, nms[overwritten]) old[!overwritten] <- list(zap()) # We don't allow duplicates so we can remove bindings separately zapped <- map_lgl(data, is_zap) & overwritten rm(list = nms[zapped], envir = env) data <- data[!zapped] nms <- names(data) %||% chr() } if (is_null(binder)) { .Call(rlang_env_bind_list, env, nms, data); } else { for (i in seq_along(data)) { binder(env, nms[[i]], data[[i]]) } } if (bind) { invisible(old) } else { invisible(env) } } #' @rdname env_bind #' @param .eval_env The environment where the expressions will be #' evaluated when the symbols are forced. #' @export #' @examples #' #' # env_bind_lazy() assigns expressions lazily: #' env <- env() #' env_bind_lazy(env, name = { cat("forced!\n"); "value" }) #' #' # Referring to the binding will cause evaluation: #' env$name #' #' # But only once, subsequent references yield the final value: #' env$name #' #' # You can unquote expressions: #' expr <- quote(message("forced!")) #' env_bind_lazy(env, name = !!expr) #' env$name #' #' #' # By default the expressions are evaluated in the current #' # environment. For instance we can create a local binding and refer #' # to it, even though the variable is bound in a different #' # environment: #' who <- "mickey" #' env_bind_lazy(env, name = paste(who, "mouse")) #' env$name #' #' # You can specify another evaluation environment with `.eval_env`: #' eval_env <- env(who = "minnie") #' env_bind_lazy(env, name = paste(who, "mouse"), .eval_env = eval_env) #' env$name #' #' # Or by unquoting a quosure: #' quo <- local({ #' who <- "fievel" #' quo(paste(who, "mouse")) #' }) #' env_bind_lazy(env, name = !!quo) #' env$name env_bind_lazy <- function(.env, ..., .eval_env = caller_env()) { exprs <- exprs(...) exprs <- map_if(exprs, is_quosure, function(quo) call2(as_function(quo))) binder <- function(env, nm, value) { do.call("delayedAssign", list( x = nm, value = value, eval.env = .eval_env, assign.env = env )) } env_bind_impl(.env, exprs, "env_bind_lazy()", TRUE, binder) } #' @rdname env_bind #' @export #' @examples #' #' # You can create active bindings with env_bind_active(). Active #' # bindings execute a function each time they are evaluated: #' fn <- function() { #' cat("I have been called\n") #' rnorm(1) #' } #' #' env <- env() #' env_bind_active(env, symbol = fn) #' #' # `fn` is executed each time `symbol` is evaluated or retrieved: #' env$symbol #' env$symbol #' eval_bare(quote(symbol), env) #' eval_bare(quote(symbol), env) #' #' # All arguments are passed to as_function() so you can use the #' # formula shortcut: #' env_bind_active(env, foo = ~ runif(1)) #' env$foo #' env$foo env_bind_active <- function(.env, ...) { fns <- map_if(list3(...), negate(is_zap), as_function) existing <- env_names(.env) binder <- function(env, nm, value) { # makeActiveBinding() fails if there is already a regular binding if (nm %in% existing) { env_unbind(env, nm) } makeActiveBinding(nm, value, env) } env_bind_impl(.env, fns, "env_bind_active()", TRUE, binder) } #' Temporarily change bindings of an environment #' #' @description #' #' * `local_bindings()` temporarily changes bindings in `.env` (which #' is by default the caller environment). The bindings are reset to #' their original values when the current frame (or an arbitrary one #' if you specify `.frame`) goes out of scope. #' #' * `with_bindings()` evaluates `expr` with temporary bindings. When #' `with_bindings()` returns, bindings are reset to their original #' values. It is a simple wrapper around `local_bindings()`. #' #' @inheritParams env_bind #' @param ... Pairs of names and values. These dots support splicing #' (with value semantics) and name unquoting. #' @param .frame The frame environment that determines the scope of #' the temporary bindings. When that frame is popped from the call #' stack, bindings are switched back to their original values. #' @return `local_bindings()` returns the values of old bindings #' invisibly; `with_bindings()` returns the value of `expr`. #' @export #' @examples #' foo <- "foo" #' bar <- "bar" #' #' # `foo` will be temporarily rebinded while executing `expr` #' with_bindings(paste(foo, bar), foo = "rebinded") #' paste(foo, bar) local_bindings <- function(..., .env = .frame, .frame = caller_env()) { env <- get_env_retired(.env, "local_bindings()") bindings <- list2(...) if (!length(bindings)) { return(list()) } old <- env_bind_impl(env, bindings, "local_bindings()", bind = TRUE) local_exit(frame = .frame, !!call2(env_bind_impl, env, old, bind = TRUE)) invisible(old) } #' @rdname local_bindings #' @param .expr An expression to evaluate with temporary bindings. #' @export with_bindings <- function(.expr, ..., .env = caller_env()) { env <- get_env_retired(.env, "with_bindings()") local_bindings(..., .env = .env) .expr } #' Mask bindings by defining symbols deeper in a scope #' #' `env_bury()` is like [env_bind()] but it creates the bindings in a #' new child environment. This makes sure the new bindings have #' precedence over old ones, without altering existing environments. #' Unlike `env_bind()`, this function does not have side effects and #' returns a new environment (or object wrapping that environment). #' #' @inheritParams env_bind #' @return A copy of `.env` enclosing the new environment containing #' bindings to `...` arguments. #' @seealso [env_bind()], [env_unbind()] #' #' @keywords internal #' @export #' @examples #' orig_env <- env(a = 10) #' fn <- set_env(function() a, orig_env) #' #' # fn() currently sees `a` as the value `10`: #' fn() #' #' # env_bury() will bury the current scope of fn() behind a new #' # environment: #' fn <- env_bury(fn, a = 1000) #' fn() #' #' # Even though the symbol `a` is still defined deeper in the scope: #' orig_env$a env_bury <- function(.env, ...) { env_ <- get_env(.env) env_ <- child_env(env_, ...) set_env(.env, env_) } #' Remove bindings from an environment #' #' `env_unbind()` is the complement of [env_bind()]. Like `env_has()`, #' it ignores the parent environments of `env` by default. Set #' `inherit` to `TRUE` to track down bindings in parent environments. #' #' @inheritParams get_env #' @param nms A character vector containing the names of the bindings #' to remove. #' @param inherit Whether to look for bindings in the parent #' environments. #' @return The input object `env` with its associated environment #' modified in place, invisibly. #' @export #' @examples #' data <- set_names(as.list(letters), letters) #' env_bind(environment(), !!! data) #' env_has(environment(), letters) #' #' # env_unbind() removes bindings: #' env_unbind(environment(), letters) #' env_has(environment(), letters) #' #' # With inherit = TRUE, it removes bindings in parent environments #' # as well: #' parent <- child_env(NULL, foo = "a") #' env <- child_env(parent, foo = "b") #' env_unbind(env, "foo", inherit = TRUE) #' env_has(env, "foo", inherit = TRUE) env_unbind <- function(env = caller_env(), nms, inherit = FALSE) { if (inherit) { while (any(exist <- env_has(env, nms, inherit = TRUE))) { rm(list = nms[exist], envir = env, inherits = TRUE) } } else { exist <- env_has(env, nms, inherit = FALSE) rm(list = nms[exist], envir = env) } invisible(env) } #' Does an environment have or see bindings? #' #' `env_has()` is a vectorised predicate that queries whether an #' environment owns bindings personally (with `inherit` set to #' `FALSE`, the default), or sees them in its own environment or in #' any of its parents (with `inherit = TRUE`). #' #' @inheritParams env_unbind #' @return A named logical vector as long as `nms`. #' @export #' @examples #' parent <- child_env(NULL, foo = "foo") #' env <- child_env(parent, bar = "bar") #' #' # env does not own `foo` but sees it in its parent environment: #' env_has(env, "foo") #' env_has(env, "foo", inherit = TRUE) env_has <- function(env = caller_env(), nms, inherit = FALSE) { env <- get_env_retired(env, "env_has()") nms <- set_names(nms) map_lgl(nms, exists, envir = env, inherits = inherit) } #' Get an object in an environment #' #' `env_get()` extracts an object from an enviroment `env`. By #' default, it does not look in the parent environments. #' `env_get_list()` extracts multiple objects from an environment into #' a named list. #' #' @inheritParams get_env #' @inheritParams env_has #' @param nm,nms Names of bindings. `nm` must be a single string. #' @param default A default value in case there is no binding for `nm` #' in `env`. #' @return An object if it exists. Otherwise, throws an error. #' @export #' @examples #' parent <- child_env(NULL, foo = "foo") #' env <- child_env(parent, bar = "bar") #' #' # This throws an error because `foo` is not directly defined in env: #' # env_get(env, "foo") #' #' # However `foo` can be fetched in the parent environment: #' env_get(env, "foo", inherit = TRUE) #' #' # You can also avoid an error by supplying a default value: #' env_get(env, "foo", default = "FOO") env_get <- function(env = caller_env(), nm, default, inherit = FALSE) { env <- get_env_retired(env, "env_get()") if (!missing(default)) { exists <- env_has(env, nm, inherit = inherit) if (!exists) { return(default) } } # FIXME: The `inherit` case fails with missing arguments if (inherit) { return(get(nm, envir = env, inherits = TRUE)) } .Call(rlang_env_get, env, nm) } #' @rdname env_get #' @export env_get_list <- function(env = caller_env(), nms, default, inherit = FALSE) { env <- get_env_retired(env, "env_get_list()") nms <- set_names(nms) # FIXME R 3.1: missingness of `default` is not passed through dots on 3.1 if (missing(default)) { map(nms, env_get, env = env, inherit = inherit) } else { map(nms, env_get, env = env, inherit = inherit, default = default) } } #' Poke an object in an environment #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} #' #' `env_poke()` will assign or reassign a binding in `env` if `create` #' is `TRUE`. If `create` is `FALSE` and a binding does not already #' exists, an error is issued. #' #' #' @details #' #' If `inherit` is `TRUE`, the parents environments are checked for #' an existing binding to reassign. If not found and `create` is #' `TRUE`, a new binding is created in `env`. The default value for #' `create` is a function of `inherit`: `FALSE` when inheriting, #' `TRUE` otherwise. #' #' This default makes sense because the inheriting case is mostly #' for overriding an existing binding. If not found, something #' probably went wrong and it is safer to issue an error. Note that #' this is different to the base R operator `<<-` which will create #' a binding in the global environment instead of the current #' environment when no existing binding is found in the parents. #' #' #' @section Life cycle: #' #' `env_poke()` is experimental. We are still experimenting with #' reducing the number of redundant functions by using quasiquotation. #' It is possible `env_poke()` will be deprecated in favour of #' `env_bind()` and name-unquoting with `:=`. #' #' @inheritParams env_get #' @param value The value for a new binding. #' @param create Whether to create a binding if it does not already #' exist in the environment. #' @return The old value of `nm` or a [zap sentinel][zap] if the #' binding did not exist yet. #' #' @keywords internal #' @export env_poke <- function(env = caller_env(), nm, value, inherit = FALSE, create = !inherit) { stopifnot(is_string(nm)) env_ <- get_env_retired(env, "env_poke()") old <- env_get(env_, nm, inherit = inherit, default = zap()) if (inherit) { scope_poke(env_, nm, value, create) } else if (create || env_has(env_, nm)) { assign(nm, value, envir = env_) } else { abort(paste0("Can't find existing binding in `env` for \"", nm, "\"")) } invisible(maybe_missing(old)) } scope_poke <- function(env, nm, value, create) { cur <- env while (!env_has(cur, nm) && !is_empty_env(cur)) { cur <- env_parent(cur) } if (is_empty_env(cur)) { if (!create) { abort(paste0("Can't find existing binding in `env` for \"", nm, "\"")) } cur <- env } assign(nm, value, envir = cur) env } #' Names and numbers of symbols bound in an environment #' #' `env_names()` returns object names from an enviroment `env` as a #' character vector. All names are returned, even those starting with #' a dot. `env_length()` returns the number of bindings. #' #' @section Names of symbols and objects: #' #' Technically, objects are bound to symbols rather than strings, #' since the R interpreter evaluates symbols (see [is_expression()] for a #' discussion of symbolic objects versus literal objects). However it #' is often more convenient to work with strings. In rlang #' terminology, the string corresponding to a symbol is called the #' _name_ of the symbol (or by extension the name of an object bound #' to a symbol). #' #' @section Encoding: #' #' There are deep encoding issues when you convert a string to symbol #' and vice versa. Symbols are _always_ in the native encoding. If #' that encoding (let's say latin1) cannot support some characters, #' these characters are serialised to ASCII. That's why you sometimes #' see strings looking like ``, especially if you're running #' Windows (as R doesn't support UTF-8 as native encoding on that #' platform). #' #' To alleviate some of the encoding pain, `env_names()` always #' returns a UTF-8 character vector (which is fine even on Windows) #' with ASCII unicode points translated back to UTF-8. #' #' @inheritParams get_env #' @return A character vector of object names. #' @export #' @examples #' env <- env(a = 1, b = 2) #' env_names(env) env_names <- function(env) { env <- get_env_retired(env, "env_names()") nms <- names(env) .Call(rlang_unescape_character, nms) } #' @rdname env_names #' @export env_length <- function(env) { if (!is_environment(env)) { abort("`env` must be an environment") } length(env) } #' Lock or unlock environment bindings #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} #' #' Locked environment bindings trigger an error when an attempt is #' made to redefine the binding. #' #' @param env An environment. #' @param nms Names of bindings. Defaults to all bindings in `env`. #' #' @return `env_binding_are_unlocked()` returns a logical vector as #' long as `nms` and named after it. `env_binding_lock()` and #' `env_binding_unlock()` return the old value of #' `env_binding_are_unlocked()` invisibly. #' #' @seealso [env_lock()] for locking an environment. #' #' @keywords internal #' @export #' @examples #' # Bindings are unlocked by default: #' env <- env(a = "A", b = "B") #' env_binding_are_locked(env) #' #' # But can optionally be locked: #' env_binding_lock(env, "a") #' env_binding_are_locked(env) #' #' # If run, the following would now return an error because `a` is locked: #' # env_bind(env, a = "foo") #' # with_env(env, a <- "bar") #' #' # Let's unlock it. Note that the return value indicate which #' # bindings were locked: #' were_locked <- env_binding_unlock(env) #' were_locked #' #' # Now that it is unlocked we can modify it again: #' env_bind(env, a = "foo") #' with_env(env, a <- "bar") #' env$a env_binding_lock <- function(env, nms = NULL) { nms <- env_binding_validate_names(env, nms) old <- env_binding_are_locked(env, nms) map(nms, lockBinding, env = env) invisible(old) } #' @rdname env_binding_lock #' @export env_binding_unlock <- function(env, nms = NULL) { nms <- env_binding_validate_names(env, nms) old <- env_binding_are_locked(env, nms) map(nms, unlockBinding, env = env) invisible(old) } #' @rdname env_binding_lock #' @export env_binding_are_locked <- function(env, nms = NULL) { nms <- env_binding_validate_names(env, nms) set_names(map_lgl(nms, bindingIsLocked, env = env), nms) } #' What kind of environment binding? #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} #' #' @inheritParams env_binding_lock #' #' @keywords internal #' @return A logical vector as long as `nms` and named after it. #' @export env_binding_are_active <- function(env, nms = NULL) { env_binding_are_type(env, nms, 2L) } #' @rdname env_binding_are_active #' @export env_binding_are_lazy <- function(env, nms = NULL) { env_binding_are_type(env, nms, 1L) } env_binding_are_type <- function(env, nms, type) { nms <- env_binding_validate_names(env, nms) promise <- env_binding_types(env, nms) if (is_null(promise)) { promise <- rep(FALSE, length(nms)) } else { promise <- promise == type } set_names(promise, nms) } env_binding_validate_names <- function(env, nms) { if (is_null(nms)) { nms <- env_names(env) } else { if (!is_character(nms)) { abort("`nms` must be a character vector of names") } } nms } env_binding_types <- function(env, nms = env_names(env)) { .Call(rlang_env_binding_types, env, nms) } env_binding_type_sum <- function(env, nms = NULL) { nms <- env_binding_validate_names(env, nms) active <- env_binding_are_active(env, nms) promise <- env_binding_are_lazy(env, nms) other <- !active & !promise types <- new_character(length(nms), nms) types[active] <- "active" types[promise] <- "lazy" types[other] <- map_chr(env_get_list(env, nms[other]), rlang_type_sum) types } rlang/R/cnd-error.R0000644000176200001440000000550513612344503013602 0ustar liggesusers #' @rdname cnd #' @export error_cnd <- function(.subclass = NULL, ..., message = "", trace = NULL, parent = NULL) { if (!is_null(trace) && !inherits(trace, "rlang_trace")) { abort("`trace` must be NULL or an rlang backtrace") } if (!is_null(parent) && !inherits(parent, "condition")) { abort("`parent` must be NULL or a condition object") } fields <- dots_list(trace = trace, parent = parent, ...) .Call(rlang_new_condition, c(.subclass, "rlang_error", "error"), message, fields) } #' @export conditionMessage.rlang_error <- function(c) { cnd_message(c) } #' @export print.rlang_error <- function(x, ..., simplify = c("branch", "collapse", "none"), fields = FALSE) { cat_line(format(x, simplify = simplify, fields = fields)) invisible(x) } #' @export format.rlang_error <- function(x, ..., child = NULL, simplify = c("branch", "collapse", "none"), fields = FALSE) { # Allow overwriting default display via condition field simplify <- x$rlang$internal$print_simplify %||% simplify header <- rlang_error_header(x, child) message <- strip_trailing_newline(conditionMessage(x)) if (!nzchar(message)) { message <- NULL } out <- paste_line( header, message ) trace <- x$trace simplify <- arg_match(simplify, c("collapse", "branch", "none")) if (!is_null(trace) && trace_length(trace)) { out <- paste_line(out, bold("Backtrace:")) if (!is_null(child)) { trace <- trace_trim_common(trace, child$trace) } trace_lines <- format(trace, ..., simplify = simplify) out <- paste_line(out, trace_lines) } if (simplify != "branch" && !is_null(x$parent)) { parent_lines <- format.rlang_error(x$parent, ..., child = x, simplify = simplify, fields = fields) out <- paste_line(out, parent_lines) } # Recommend printing the full backtrace. Only do it after having # printed all parent errors first. from_last_error <- is_true(x$rlang$internal$from_last_error) && identical(x, last_error()) if (from_last_error && simplify == "branch" && is_null(child) && !is_null(trace)) { reminder <- silver("Run `rlang::last_trace()` to see the full context.") out <- paste_line(out, reminder) } out } #' @export summary.rlang_error <- function(object, ...) { print(object, simplify = "none", fields = TRUE) } rlang_error_header <- function(cnd, child = NULL) { class <- class(cnd)[[1]] if (class != "error") { class <- paste0("error/", class) } if (is_null(child)) { bold(sprintf("<%s>", class)) } else { bold(sprintf("", class)) } } rlang/R/cnd-abort.R0000644000176200001440000002730013612347420013556 0ustar liggesusers#' Signal an error, warning, or message #' #' @description #' #' These functions are equivalent to base functions [base::stop()], #' [base::warning()] and [base::message()], but make it easy to supply #' condition metadata: #' #' * Supply `.subclass` to create a classed condition. Typed #' conditions can be captured or handled selectively, allowing for #' finer-grained error handling. #' #' * Supply metadata with named `...` arguments. This data will be #' stored in the condition object and can be examined by handlers. #' #' `interrupt()` allows R code to simulate a user interrupt of the #' kind that is signalled with `Ctrl-C`. It is currently not possible #' to create custom interrupt condition objects. #' #' #' @section Backtrace: #' #' Unlike `stop()` and `warning()`, these functions don't include call #' information by default. This saves you from typing `call. = FALSE` #' and produces cleaner error messages. #' #' A backtrace is always saved into error objects. You can print a #' simplified backtrace of the last error by calling [last_error()] #' and a full backtrace with `summary(last_error())`. #' #' You can also display a backtrace with the error message by setting #' the option [`rlang_backtrace_on_error`]. It supports the following #' values: #' #' * `"reminder"`: Invite users to call `rlang::last_error()` to see a #' backtrace. #' * `"branch"`: Display a simplified backtrace. #' * `"collapse"`: Display a collapsed backtrace tree. #' * `"full"`: Display a full backtrace tree. #' * `"none"`: Display nothing. #' #' @section Mufflable conditions: #' #' Signalling a condition with `inform()` or `warn()` causes a message #' to be displayed in the console. These messages can be muffled with #' [base::suppressMessages()] or [base::suppressWarnings()]. #' #' On recent R versions (>= R 3.5.0), interrupts are typically #' signalled with a `"resume"` restart. This is however not #' guaranteed. #' #' #' @section Lifecycle: #' #' These functions were changed in rlang 0.3.0 to take condition #' metadata with `...`. Consequently: #' #' * All arguments were renamed to be prefixed with a dot, except for #' `type` which was renamed to `.subclass`. #' * `.call` (previously `call`) can no longer be passed positionally. #' #' @inheritParams cnd #' @param message The message to display. #' #' If not supplied, it is expected that the message is generated #' lazily through [conditionMessage()][cnd_message]. In that case, #' `class` must be supplied. Only `inform()` allows empty messages #' as it is occasionally useful to build user output incrementally. #' @param class Subclass of the condition. This allows your users #' to selectively handle the conditions signalled by your functions. #' @param ... Additional data to be stored in the condition object. #' @param call Defunct as of rlang 0.4.0. Storing the full #' backtrace is now preferred to storing a simple call. #' @param msg,type These arguments were renamed to `message` and #' `.subclass` and are defunct as of rlang 0.4.0. #' @param .subclass This argument was renamed to `class` in rlang #' 0.4.2. It will be deprecated in the next major version. This is #' for consistency with our conventions for class constructors #' documented in . #' #' @seealso [with_abort()] to convert all errors to rlang errors. #' @examples #' # These examples are guarded to avoid throwing errors #' if (FALSE) { #' #' # Signal an error with a message just like stop(): #' abort("Something bad happened") #' #' # Give a class to the error: #' abort("Something bad happened", "somepkg_bad_error") #' #' # This will allow your users to handle the error selectively #' tryCatch( #' somepkg_function(), #' somepkg_bad_error = function(err) { #' warn(conditionMessage(err)) # Demote the error to a warning #' NA # Return an alternative value #' } #' ) #' #' # You can also specify metadata that will be stored in the condition: #' abort("Something bad happened", "somepkg_bad_error", data = 1:10) #' #' # This data can then be consulted by user handlers: #' tryCatch( #' somepkg_function(), #' somepkg_bad_error = function(err) { #' # Compute an alternative return value with the data: #' recover_error(err$data) #' } #' ) #' #' # If you call low-level APIs it is good practice to catch technical #' # errors and rethrow them with a more meaningful message. Pass on #' # the caught error as `parent` to get a nice decomposition of #' # errors and backtraces: #' file <- "http://foo.bar/baz" #' tryCatch( #' download(file), #' error = function(err) { #' msg <- sprintf("Can't download `%s`", file) #' abort(msg, parent = err) #' }) #' #' # Unhandled errors are saved automatically by `abort()` and can be #' # retrieved with `last_error()`. The error prints with a simplified #' # backtrace: #' abort("Saved error?") #' last_error() #' #' # Use `summary()` to print the full backtrace and the condition fields: #' summary(last_error()) #' #' } #' @export abort <- function(message = NULL, class = NULL, ..., trace = NULL, call, parent = NULL, msg, type, .subclass) { validate_signal_args(msg, type, call, .subclass) if (is_null(trace) && is_null(peek_option("rlang:::disable_trace_capture"))) { # Prevents infloops when rlang throws during trace capture local_options("rlang:::disable_trace_capture" = TRUE) trace <- trace_back() if (is_null(parent)) { context <- trace_length(trace) } else { context <- find_capture_context(3L) } trace <- trace_trim_context(trace, context) } message <- validate_signal_message(message, class) message <- collapse_cnd_message(message) cnd <- error_cnd(class, ..., message = message, parent = parent, trace = trace ) signal_abort(cnd) } signal_abort <- function(cnd) { if (is_true(peek_option("rlang:::force_unhandled_error"))) { # Fall back with the full rlang error fallback <- cnd } else { # Let exiting and calling handlers handle the fully typed # condition. The error message hasn't been altered yet and won't # affect handling functions like `try()`. signalCondition(cnd) # If we're still here, the error is unhandled. Fall back with a # bare condition to avoid calling handlers logging the same error # twice fallback <- cnd("rlang_error") } # Save the unhandled error for `rlang::last_error()`. last_error_env$cnd <- cnd # Generate the error message, possibly with a backtrace or reminder fallback$message <- paste_line( conditionMessage(cnd), format_onerror_backtrace(cnd) ) stop(fallback) } trace_trim_context <- function(trace, frame = caller_env()) { if (is_environment(frame)) { idx <- detect_index(trace$ids, identical, env_label(frame)) } else if (is_scalar_integerish(frame)) { idx <- frame } else { abort("`frame` must be a frame environment or index") } to_trim <- seq2(idx, trace_length(trace)) if (length(to_trim)) { trace <- trace_subset(trace, -to_trim) } trace } # Assumes we're called from an exiting handler. Need to find_capture_context <- function(n = 3L) { parent <- orig <- sys.parent(n) call <- sys.call(parent) try_catch_n <- detect_index(sys.calls(), is_call, "tryCatch", .right = TRUE) if (try_catch_n == 0L) { sys.frame(sys.parent(n)) } else { sys.frame(try_catch_n) } } #' Display backtrace on error #' #' @description #' #' Errors thrown with [abort()] automatically save a backtrace that #' can be inspected by calling [last_error()]. Optionally, you can #' also display the backtrace alongside the error message by setting #' the option `rlang_backtrace_on_error` to one of the following #' values: #' #' * `"reminder"`: Display a reminder that the backtrace can be #' inspected by calling [rlang::last_error()]. #' * `"branch"`: Display a simplified backtrace. #' * `"collapse"`: Display a collapsed backtrace tree. #' * `"full"`: Display the full backtrace tree. #' #' #' @section Promote base errors to rlang errors: #' #' Call `options(error = rlang::entrace)` to instrument base #' errors with rlang features. This handler does two things: #' #' * It saves the base error as an rlang object. This allows you to #' call [last_error()] to print the backtrace or inspect its data. #' #' * It prints the backtrace for the current error according to the #' `rlang_backtrace_on_error` option. #' #' @name rlang_backtrace_on_error #' @aliases add_backtrace #' #' @examples #' # Display a simplified backtrace on error for both base and rlang #' # errors: #' #' # options( #' # rlang_backtrace_on_error = "branch", #' # error = rlang::entrace #' # ) #' # stop("foo") NULL # Whenever the backtrace-on-error format is changed, the version in # `inst/backtrace-ver` and in `tests/testthat/helper-rlang.R` must be # bumped. This way `devtools::test()` will skip the tests that require # the dev version to be installed locally. format_onerror_backtrace <- function(cnd) { trace <- cnd$trace if (is_null(trace) || !trace_length(trace)) { return(NULL) } show_trace <- show_trace_p() opts <- c("none", "reminder", "branch", "collapse", "full") if (!is_string(show_trace) || !show_trace %in% opts) { options(rlang_backtrace_on_error = NULL) warn("Invalid `rlang_backtrace_on_error` option (resetting to `NULL`)") return(NULL) } if (show_trace == "none") { return(NULL) } if (show_trace == "reminder") { if (is_interactive()) { reminder <- silver("Run `rlang::last_error()` to see where the error occurred.") } else { reminder <- NULL } return(reminder) } if (show_trace == "branch") { max_frames <- 10L } else { max_frames <- NULL } simplify <- switch(show_trace, full = "none", reminder = "branch", # Check size of backtrace branch show_trace ) out <- paste_line( "Backtrace:", format(trace, simplify = simplify, max_frames = max_frames) ) if (simplify == "none") { # Show parent backtraces while (!is_null(cnd <- cnd$parent)) { trace <- trace_trim_common(cnd$trace, trace) out <- paste_line( out, rlang_error_header(cnd, child = TRUE), "Backtrace:", format(trace, simplify = simplify, max_frames = max_frames) ) } } out } show_trace_p <- function() { old_opt <- peek_option("rlang__backtrace_on_error") if (!is_null(old_opt)) { warn_deprecated(paste_line( "`rlang__backtrace_on_error` is no longer experimental.", "It has been renamed to `rlang_backtrace_on_error`. Please update your RProfile." )) return(old_opt) } opt <- peek_option("rlang_backtrace_on_error") if (!is_null(opt)) { return(opt) } # FIXME: parameterise `is_interactive()`? interactive <- with_options( knitr.in.progress = NULL, rstudio.notebook.executing = NULL, is_interactive() ) if (interactive) { "reminder" } else { "full" } } #' Last `abort()` error #' #' @description #' #' * `last_error()` returns the last error thrown with [abort()]. The #' error is printed with a backtrace in simplified form. #' #' * `last_trace()` is a shortcut to return the backtrace stored in #' the last error. This backtrace is printed in full form. #' #' @export last_error <- function() { if (is_null(last_error_env$cnd)) { abort("Can't show last error because no error was recorded yet") } cnd <- last_error_env$cnd cnd$rlang$internal$from_last_error <- TRUE cnd } #' @rdname last_error #' @export last_trace <- function() { err <- last_error() err$rlang$internal$print_simplify <- "none" err } # This is where we save errors for `last_error()` last_error_env <- new.env(parent = emptyenv()) last_error_env$cnd <- NULL rlang/R/compat-lazyeval.R0000644000176200001440000000424713405732277015032 0ustar liggesusers# nocov start - compat-lazyeval (last updated: rlang 0.3.0) # This file serves as a reference for compatibility functions for lazyeval. # Please find the most recent version in rlang's repository. warn_underscored <- function() { return(NULL) warn(paste( "The underscored versions are deprecated in favour of", "tidy evaluation idioms. Please see the documentation", "for `quo()` in rlang" )) } warn_text_se <- function() { return(NULL) warn("Text parsing is deprecated, please supply an expression or formula") } compat_lazy <- function(lazy, env = caller_env(), warn = TRUE) { if (warn) warn_underscored() if (missing(lazy)) { return(quo()) } if (is_quosure(lazy)) { return(lazy) } if (is_formula(lazy)) { return(as_quosure(lazy, env)) } out <- switch(typeof(lazy), symbol = , language = new_quosure(lazy, env), character = { if (warn) warn_text_se() parse_quo(lazy[[1]], env) }, logical = , integer = , double = { if (length(lazy) > 1) { warn("Truncating vector to length 1") lazy <- lazy[[1]] } new_quosure(lazy, env) }, list = if (inherits(lazy, "lazy")) { lazy = new_quosure(lazy$expr, lazy$env) } ) if (is_null(out)) { abort(sprintf("Can't convert a %s to a quosure", typeof(lazy))) } else { out } } compat_lazy_dots <- function(dots, env, ..., .named = FALSE) { if (missing(dots)) { dots <- list() } if (inherits(dots, c("lazy", "formula"))) { dots <- list(dots) } else { dots <- unclass(dots) } dots <- c(dots, list(...)) warn <- TRUE for (i in seq_along(dots)) { dots[[i]] <- compat_lazy(dots[[i]], env, warn) warn <- FALSE } named <- have_name(dots) if (.named && any(!named)) { nms <- vapply(dots[!named], function(x) expr_text(get_expr(x)), character(1)) names(dots)[!named] <- nms } names(dots) <- names2(dots) dots } compat_as_lazy <- function(quo) { structure(class = "lazy", list( expr = get_expr(quo), env = get_env(quo) )) } compat_as_lazy_dots <- function(...) { structure(class = "lazy_dots", lapply(quos(...), compat_as_lazy)) } # nocov end rlang/R/cnd-entrace.R0000644000176200001440000002007113563530577014102 0ustar liggesusers#' Add backtrace from error handler #' #' @description #' #' `entrace()` interrupts an error throw to add an [rlang #' backtrace][trace_back()] to the error. The error throw is #' immediately resumed. `cnd_entrace()` adds a backtrace to a #' condition object, without any other effect. Both functions should #' be called directly from an error handler. #' #' Set the `error` global option to `quote(rlang::entrace())` to #' transform base errors to rlang errors. These enriched errors #' include a backtrace. The RProfile is a good place to set the #' handler. See [`rlang_backtrace_on_error`] for details. #' #' `entrace()` also works as a [calling][calling] handler, though it #' is often more practical to use the higher-level function #' [with_abort()]. #' #' @inheritParams trace_back #' @param cnd When `entrace()` is used as a calling handler, `cnd` is #' the condition to handle. #' @param ... Unused. These dots are for future extensions. #' #' @seealso [with_abort()] to promote conditions to rlang errors. #' [cnd_entrace()] to manually add a backtrace to a condition. #' @examples #' if (FALSE) { # Not run #' #' # Set the error handler in your RProfile like this: #' if (requireNamespace("rlang", quietly = TRUE)) { #' options(error = rlang::entrace) #' } #' #' } #' @export entrace <- function(cnd, ..., top = NULL, bottom = NULL) { check_dots_empty(...) if (!missing(cnd) && inherits(cnd, "rlang_error")) { return() } if (is_null(bottom)) { nframe <- sys.nframe() - 1 info <- signal_context_info(nframe) bottom <- sys.frame(info[[2]]) } trace <- trace_back(top = top, bottom = bottom) if (missing(cnd)) { entrace_handle_top(trace) } else { abort(conditionMessage(cnd) %||% "", error = cnd, trace = trace) } } #' @rdname entrace #' @export cnd_entrace <- function(cnd, ..., top = NULL, bottom = NULL) { check_dots_empty(...) if (!is_null(cnd$trace)) { return(cnd) } if (is_null(bottom)) { nframe <- sys.parent() - 1 info <- signal_context_info(nframe) bottom <- sys.frame(info[[2]]) } cnd$trace <- trace_back(top = top, bottom = bottom) cnd } #' Return information about signalling context #' #' @param nframe The depth of the frame to inspect. In a condition #' handler, this would typically be `sys.nframe() - 1L`. #' #' @return A named list of two elements `type` and `depth`. The depth #' is the call frame number of the signalling context. The type is #' one of: #' #' * `"unknown"` #' * `"stop_message"` for errors thrown with `base::stop("message")" #' * `"stop_condition"` for errors thrown with `base::stop(cnd_object)` #' * `"stop_native"` for errors thrown from C #' * `"stop_rlang"` for errors thrown with `rlang::abort()` #' * `"warning_message"` for warnings signalled with `base::warning("message")" #' * `"warning_condition"` for warnings signalled with `base::warning(cnd_object)` #' * `"warning_native"` for warnings signalled from C #' * `"warning_promoted"` for warnings promoted to errors with `getOption("warn")` #' * `"warning_rlang"` for warnings signalled with `rlang::warn()` #' * `"message"` for messages signalled with `base::message()` #' * `"message_rlang"` for messages signalled with `rlang::inform()` #' * `"condition"` for conditions signalled with `base::signalCondition()` #' #' @keywords internal #' @noRd signal_context_info <- function(nframe) { first <- sys_body(nframe) if (is_same_body(first, body(.handleSimpleError))) { if (is_same_body(sys_body(nframe - 1), body(stop))) { return(list(type = "stop_message", depth = nframe - 2)) } else if (is_same_body(sys_body(nframe - 4), body(.signalSimpleWarning))) { return(list(type = "warning_promoted", depth = nframe - 6)) } else { return(list(type = "stop_native", depth = nframe - 1)) } } if (is_same_body(first, body(stop))) { if (is_same_body(sys_body(nframe - 1), body(abort))) { return(list(type = "stop_rlang", depth = nframe - 2)) } else { return(list(type = "stop_condition", depth = nframe - 1)) } } if (is_same_body(first, body(signalCondition))) { from_restarts <- from_withrestarts(nframe - 1) signal_body <- sys_body(nframe - 4) if (from_restarts && is_same_body(signal_body, body(message))) { return(list(type = "message", depth = nframe - 5)) } else if (from_restarts && is_same_body(signal_body, body(inform))) { return(list(type = "message_rlang", depth = nframe - 5)) } else { return(list(type = "condition", depth = nframe - 1)) } } if (from_withrestarts(nframe)) { withrestarts_caller <- sys_body(nframe - 3) if (is_same_body(withrestarts_caller, body(.signalSimpleWarning))) { if (is_same_body(sys_body(nframe - 4), body(warning))) { return(list(type = "warning_message", depth = nframe - 5)) } else { return(list(type = "warning_native", depth = nframe - 4)) } } else if (is_same_body(withrestarts_caller, body(warning))) { if (is_same_body(sys_body(nframe - 4), body(warn))) { return(list(type = "warning_rlang", depth = nframe - 5)) } else { return(list(type = "warning_condition", depth = nframe - 4)) } } } list(type = "unknown", depth = nframe) } from_withrestarts <- function(nframe) { is_call(sys.call(nframe), "doWithOneRestart") && is_same_body(sys_body(nframe - 2), body(withRestarts)) } sys_body <- function(n) { body(sys.function(n)) } entrace_handle_top <- function(trace) { # Happens with ctrl-c at top-level if (!trace_length(trace)) { return() } stop_call <- sys.call(-2) stop_frame <- sys.frame(-2) cnd <- stop_frame$cond # False for errors thrown from the C side from_stop <- is_call(stop_call, "stop", ns = c("", "base")) # No need to do anything for rlang errors if (from_stop && inherits(cnd, "rlang_error")) { return(NULL) } if (from_stop) { if (is_null(cnd)) { msg_call <- quote(.makeMessage(..., domain = domain)) msg <- eval_bare(msg_call, stop_frame) } else { msg <- cnd$message } } else { msg <- geterrmessage() } # Save a fake rlang error containing the backtrace err <- error_cnd(message = msg, error = cnd, trace = trace, parent = cnd) last_error_env$cnd <- err # Print backtrace for current error backtrace_lines <- format_onerror_backtrace(err) if (length(backtrace_lines)) { cat_line(backtrace_lines) } NULL } add_backtrace <- function() { # Warnings don't go through when error is being handled msg <- "Warning: `add_backtrace()` is now exported as `entrace()` as of rlang 0.3.1" cat_line(msg, file = stderr()) entrace(bottom = sys.frame(-1)) } #' Promote all errors to rlang errors #' #' @description #' #' `with_abort()` promotes conditions as if they were thrown with #' [abort()]. These errors embed a [backtrace][trace_back]. They are #' particularly suitable to be set as *parent errors* (see `parent` #' argument of [abort()]). #' #' @param expr An expression run in a context where errors are #' promoted to rlang errors. #' @param classes Character vector of condition classes that should be #' promoted to rlang errors. #' #' @details #' #' `with_abort()` installs a [calling handler][calling] for errors and #' rethrows non-rlang errors with [abort()]. However, error handlers #' installed *within* `with_abort()` have priority. For this reason, #' you should use [tryCatch()] and [exiting] handlers outside #' `with_abort()` rather than inside. #' #' @examples #' # with_abort() automatically casts simple errors thrown by stop() #' # to rlang errors. It is is handy for rethrowing low level #' # errors. The backtraces are then segmented between the low level #' # and high level contexts. #' f <- function() g() #' g <- function() stop("Low level error") #' #' high_level <- function() { #' with_handlers( #' with_abort(f()), #' error = ~ abort("High level error", parent = .) #' ) #' } #' @export with_abort <- function(expr, classes = "error") { handlers <- rep_named(classes, list(entrace)) handle_call <- rlang::expr(withCallingHandlers(expr, !!!handlers)) .Call(rlang_eval, handle_call, current_env()) } rlang/R/call.R0000644000176200001440000005606413604123766012637 0ustar liggesusers#' Create a call #' #' @description #' #' Quoted function calls are one of the two types of #' [symbolic][is_symbolic] objects in R. They represent the action of #' calling a function, possibly with arguments. There are two ways of #' creating a quoted call: #' #' * By [quoting][nse-defuse] it. Quoting prevents functions from being #' called. Instead, you get the description of the function call as #' an R object. That is, a quoted function call. #' #' * By constructing it with [base::call()], [base::as.call()], or #' `call2()`. In this case, you pass the call elements (the function #' to call and the arguments to call it with) separately. #' #' See section below for the difference between `call2()` and the base #' constructors. #' #' #' @param .fn Function to call. Must be a callable object: a string, #' symbol, call, or a function. #' @param ... <[dynamic][dyn-dots]> Arguments for the function #' call. Empty arguments are preserved. #' @param .ns Namespace with which to prefix `.fn`. Must be a string #' or symbol. #' #' #' @section Difference with base constructors: #' #' `call2()` is more flexible and convenient than `base::call()`: #' #' * The function to call can be a string or a [callable][is_callable] #' object: a symbol, another call (e.g. a `$` or `[[` call), or a #' function to inline. `base::call()` only supports strings and you #' need to use `base::as.call()` to construct a call with a callable #' object. #' #' ``` #' call2(list, 1, 2) #' #' as.call(list(list, 1, 2)) #' ``` #' #' * The `.ns` argument is convenient for creating namespaced calls. #' #' ``` #' call2("list", 1, 2, .ns = "base") #' #' ns_call <- as.call(list(as.name("::"), as.name("list"), as.name("base"))) #' as.call(list(ns_call, 1, 2)) #' ``` #' #' * `call2()` has [tidy dots][list2] support and you can splice lists #' of arguments with `!!!`. With base R, you need to use `as.call()` #' instead of `call()` if the arguments are in a list. #' #' ``` #' args <- list(na.rm = TRUE, trim = 0) #' #' call2("mean", 1:10, !!!args) #' #' as.call(c(list(as.name("mean"), 1:10), args)) #' ``` #' #' #' @section Life cycle: #' #' In rlang 0.2.0 `lang()` was soft-deprecated and renamed to #' `call2()`. #' #' In early versions of rlang calls were called "language" objects in #' order to follow the R type nomenclature as returned by #' [base::typeof()]. The goal was to avoid adding to the confusion #' between S modes and R types. With hindsight we find it is better to #' use more meaningful type names. #' #' #' @seealso call_modify #' @examples #' # fn can either be a string, a symbol or a call #' call2("f", a = 1) #' call2(quote(f), a = 1) #' call2(quote(f()), a = 1) #' #' #' Can supply arguments individually or in a list #' call2(quote(f), a = 1, b = 2) #' call2(quote(f), !!!list(a = 1, b = 2)) #' #' # Creating namespaced calls is easy: #' call2("fun", arg = quote(baz), .ns = "mypkg") #' #' # Empty arguments are preserved: #' call2("[", quote(x), , drop = ) #' @export call2 <- function(.fn, ..., .ns = NULL) { .External2(rlang_call2_external, .fn, .ns) } #' Create pairlists with splicing support #' #' This pairlist constructor uses [dynamic dots][dyn-dots]. Use #' it to manually create argument lists for calls or parameter lists #' for functions. #' #' @param ... <[dynamic][dyn-dots]> Arguments stored in the #' pairlist. Empty arguments are preserved. #' #' @export #' @examples #' # Unlike `exprs()`, `pairlist2()` evaluates its arguments. #' new_function(pairlist2(x = 1, y = 3 * 6), quote(x * y)) #' new_function(exprs(x = 1, y = 3 * 6), quote(x * y)) #' #' # It preserves missing arguments, which is useful for creating #' # parameters without defaults: #' new_function(pairlist2(x = , y = 3 * 6), quote(x * y)) pairlist2 <- function(...) { .Call(rlang_dots_pairlist, frame_env = environment(), named = FALSE, ignore_empty = "trailing", preserve_empty = TRUE, unquote_names = TRUE, homonyms = "keep", check_assign = FALSE ) } #' Is an object callable? #' #' A callable object is an object that can appear in the function #' position of a call (as opposed to argument position). This includes #' [symbolic objects][is_symbolic] that evaluate to a function or #' literal functions embedded in the call. #' #' Note that strings may look like callable objects because #' expressions of the form `"list"()` are valid R code. However, #' that's only because the R parser transforms strings to symbols. It #' is not legal to manually set language heads to strings. #' #' @param x An object to test. #' @keywords internal #' @export #' @examples #' # Symbolic objects and functions are callable: #' is_callable(quote(foo)) #' is_callable(base::identity) #' #' # node_poke_car() lets you modify calls without any checking: #' lang <- quote(foo(10)) #' node_poke_car(lang, current_env()) #' #' # Use is_callable() to check an input object is safe to put as CAR: #' obj <- base::identity #' #' if (is_callable(obj)) { #' lang <- node_poke_car(lang, obj) #' } else { #' abort("`obj` must be callable") #' } #' #' eval_bare(lang) is_callable <- function(x) { is_symbolic(x) || is_function(x) } #' Is object a call? #' #' This function tests if `x` is a [call][call2]. This is a #' pattern-matching predicate that returns `FALSE` if `name` and `n` #' are supplied and the call does not match these properties. #' #' #' @section Life cycle: #' #' `is_lang()` has been soft-deprecated and renamed to `is_call()` in #' rlang 0.2.0 and similarly for `is_unary_lang()` and #' `is_binary_lang()`. This renaming follows the general switch from #' "language" to "call" in the rlang type nomenclature. See lifecycle #' section in [call2()]. #' #' @param x An object to test. If a formula, the right-hand side is #' extracted. #' @param name An optional name that the call should match. It is #' passed to [sym()] before matching. This argument is vectorised #' and you can supply a vector of names to match. In this case, #' `is_call()` returns `TRUE` if at least one name matches. #' @param n An optional number of arguments that the call should #' match. #' @param ns The namespace of the call. If `NULL`, the namespace #' doesn't participate in the pattern-matching. If an empty string #' `""` and `x` is a namespaced call, `is_call()` returns #' `FALSE`. If any other string, `is_call()` checks that `x` is #' namespaced within `ns`. #' #' Can be a character vector of namespaces, in which case the call #' has to match at least one of them, otherwise `is_call()` returns #' `FALSE`. #' @seealso [is_expression()] #' @export #' @examples #' is_call(quote(foo(bar))) #' #' # You can pattern-match the call with additional arguments: #' is_call(quote(foo(bar)), "foo") #' is_call(quote(foo(bar)), "bar") #' is_call(quote(foo(bar)), quote(foo)) #' #' # Match the number of arguments with is_call(): #' is_call(quote(foo(bar)), "foo", 1) #' is_call(quote(foo(bar)), "foo", 2) #' #' #' # By default, namespaced calls are tested unqualified: #' ns_expr <- quote(base::list()) #' is_call(ns_expr, "list") #' #' # You can also specify whether the call shouldn't be namespaced by #' # supplying an empty string: #' is_call(ns_expr, "list", ns = "") #' #' # Or if it should have a namespace: #' is_call(ns_expr, "list", ns = "utils") #' is_call(ns_expr, "list", ns = "base") #' #' # You can supply multiple namespaces: #' is_call(ns_expr, "list", ns = c("utils", "base")) #' is_call(ns_expr, "list", ns = c("utils", "stats")) #' #' # If one of them is "", unnamespaced calls will match as well: #' is_call(quote(list()), "list", ns = "base") #' is_call(quote(list()), "list", ns = c("base", "")) #' is_call(quote(base::list()), "list", ns = c("base", "")) #' #' #' # The name argument is vectorised so you can supply a list of names #' # to match with: #' is_call(quote(foo(bar)), c("bar", "baz")) #' is_call(quote(foo(bar)), c("bar", "foo")) #' is_call(quote(base::list), c("::", ":::", "$", "@")) is_call <- function(x, name = NULL, n = NULL, ns = NULL) { if (typeof(x) != "language") { return(FALSE) } if (!is_null(ns)) { good_ns <- FALSE for (elt in ns) { if (identical(elt, "") && !is_namespaced_call(x, private = FALSE)) { good_ns <- TRUE break } else if (is_namespaced_call(x, elt, private = FALSE)) { good_ns <- TRUE break } } if (!good_ns) { return(FALSE) } } x <- call_unnamespace(x) if (!is_null(name)) { # Wrap language objects in a list if (!is_vector(name)) { name <- list(name) } unmatched <- TRUE for (elt in name) { if (identical(x[[1]], sym(elt))) { unmatched <- FALSE break } } if (unmatched) { return(FALSE) } } if (!is_null(n) && !has_length(x, n + 1L)) { return(FALSE) } TRUE } # Until `is_call()` is fixed is_call2 <- function(x, ...) { if (is_quosure(x)) { FALSE } else { rlang::is_call(x, ...) } } #' How does a call print at the console? #' #' @description #' #' `call_print_type()` returns the way a call is deparsed and printed #' at the console. This is useful when generating documents based on R #' code. The types of calls are: #' #' * `"prefix"` for calls like `foo()`, unary operators, `-1`, and #' operators with more than 2 arguments like \code{`+`(1, 2, 3)} #' (the latter can be obtained by building calls manually). #' #' * `"infix"` for operators like `1 + 2` or `foo$bar`. #' #' * `"special"` for function definitions, control-flow calls like #' `if` or `for`, and subscripting calls like `foo[]` and `foo[[]]`. #' #' #' @param call A quoted function call. An error is raised if not a call. #' @examples #' call_print_type(quote(foo(bar))) #' call_print_type(quote(foo[[bar]])) #' call_print_type(quote(+foo)) #' call_print_type(quote(function() foo)) #' #' # When an operator call has an artificial number of arguments, R #' # often prints it in prefix form: #' call <- call("+", 1, 2, 3) #' call #' call_print_type(call) #' #' # But not always: #' call <- call("$", 1, 2, 3) #' call #' call_print_type(call) #' @noRd call_print_type <- function(call) { type <- call_print_fine_type(call) switch(type, call = "prefix", control = , delim = , subset = "special", type ) } call_print_fine_type <- function(call) { if (!is_call(call)) { abort("`call` must be a call") } op <- which_operator(call) if (op == "") { return("call") } switch(op, `+unary` = , `-unary` = , `~unary` = , `?unary` = , `!` = , `!!` = , `!!!` = "prefix", `function` = , `while` = , `for` = , `repeat` = , `if` = "control", `(` = , `{` = "delim", `[` = , `[[` = "subset", # These operators always print in infix form even if they have # more arguments `<-` = , `<<-` = , `=` = , `::` = , `:::` = , `$` = , `@` = "infix", `+` = , `-` = , `?` = , `~` = , `:=` = , `|` = , `||` = , `&` = , `&&` = , `>` = , `>=` = , `<` = , `<=` = , `==` = , `!=` = , `*` = , `/` = , `%%` = , `special` = , `:` = , `^` = if (length(node_cdr(call)) == 2) { "infix" } else { "call" } ) } #' Modify the arguments of a call #' #' If you are working with a user-supplied call, make sure the #' arguments are standardised with [call_standardise()] before #' modifying the call. #' #' @inheritParams dots_list #' @param .call Can be a call, a formula quoting a call in the #' right-hand side, or a frame object from which to extract the call #' expression. #' @param ... <[dynamic][dyn-dots]> Named or unnamed expressions #' (constants, names or calls) used to modify the call. Use [zap()] #' to remove arguments. Empty arguments are preserved. #' @param .standardise,.env Soft-deprecated as of rlang 0.3.0. Please #' call [call_standardise()] manually. #' #' @section Life cycle: #' #' * The `.standardise` argument is deprecated as of rlang 0.3.0. #' #' * In rlang 0.2.0, `lang_modify()` was deprecated and renamed to #' `call_modify()`. See lifecycle section in [call2()] for more about #' this change. #' #' @return A quosure if `.call` is a quosure, a call otherwise. #' @export #' @examples #' call <- quote(mean(x, na.rm = TRUE)) #' #' # Modify an existing argument #' call_modify(call, na.rm = FALSE) #' call_modify(call, x = quote(y)) #' #' # Remove an argument #' call_modify(call, na.rm = zap()) #' #' # Add a new argument #' call_modify(call, trim = 0.1) #' #' # Add an explicit missing argument: #' call_modify(call, na.rm = ) #' #' # Supply a list of new arguments with `!!!` #' newargs <- list(na.rm = NULL, trim = 0.1) #' call <- call_modify(call, !!!newargs) #' call #' #' # Remove multiple arguments by splicing zaps: #' newargs <- rep_named(c("na.rm", "trim"), list(zap())) #' call <- call_modify(call, !!!newargs) #' call #' #' #' # Modify the `...` arguments as if it were a named argument: #' call <- call_modify(call, ... = ) #' call #' #' call <- call_modify(call, ... = zap()) #' call #' #' #' # When you're working with a user-supplied call, standardise it #' # beforehand because it might contain unmatched arguments: #' user_call <- quote(matrix(x, nc = 3)) #' call_modify(user_call, ncol = 1) #' #' # Standardising applies the usual argument matching rules: #' user_call <- call_standardise(user_call) #' user_call #' call_modify(user_call, ncol = 1) #' #' #' # You can also modify quosures inplace: #' f <- quo(matrix(bar)) #' call_modify(f, quote(foo)) #' #' #' # By default, arguments with the same name are kept. This has #' # subtle implications, for instance you can move an argument to #' # last position by removing it and remapping it: #' call <- quote(foo(bar = , baz)) #' call_modify(call, bar = NULL, bar = missing_arg()) #' #' # You can also choose to keep only the first or last homonym #' # arguments: #' args <- list(bar = NULL, bar = missing_arg()) #' call_modify(call, !!!args, .homonyms = "first") #' call_modify(call, !!!args, .homonyms = "last") call_modify <- function(.call, ..., .homonyms = c("keep", "first", "last", "error"), .standardise = NULL, .env = caller_env()) { args <- dots_list(..., .preserve_empty = TRUE, .homonyms = .homonyms) expr <- get_expr(.call) if (!is_null(.standardise)) { warn_deprecated(paste_line( "`.standardise` is deprecated as of rlang 0.3.0.", "Please use `call_standardise()` prior to calling `call_modify()`." )) if (.standardise) { expr <- get_expr(call_standardise(.call, env = .env)) } } if (!is_call(expr)) { abort_call_input_type(".call") } expr <- duplicate(expr, shallow = TRUE) # Discard "" names nms <- names2(args) named <- have_name(args) named_args <- args[named] for (i in seq_along(args)) { tag <- sym(nms[[i]]) arg <- args[[i]] if (is_missing(tag)) { if (is_zap(arg)) { abort("Zap sentinels can't be unnamed") } node_append(expr, new_node(arg)) next } if (identical(tag, dots_sym)) { # Unwrap empty quosures. Useful for passing captured arguments # to `call_modify()`. if (identical(maybe_missing(arg), quo())) { arg <- missing_arg() } if (!is_missing(arg) && !is_zap(arg)) { abort("`...` arguments must be `zap()` or empty") } node_accessor <- node_car } else { node_accessor <- node_tag } prev <- expr node <- node_cdr(expr) while (!is_null(node)) { if (identical(node_accessor(node), tag)) { # Remove argument from the list if a zap sentinel if (is_zap(maybe_missing(arg))) { node <- node_cdr(node) node_poke_cdr(prev, node) next } # If `...` it can only be missing at this point, which means # we keep it in the argument list as is if (!identical(tag, dots_sym)) { node_poke_car(node, maybe_missing(arg)) } break } prev <- node node <- node_cdr(node) } if (is_null(node) && !is_zap(maybe_missing(arg))) { if (identical(tag, dots_sym)) { node <- new_node(dots_sym, NULL) node_poke_cdr(prev, node) } else { node <- new_node(maybe_missing(arg), NULL) node_poke_tag(node, tag) node_poke_cdr(prev, node) } } } set_expr(.call, expr) } abort_call_input_type <- function(arg) { abort(sprintf("`%s` must be a quoted call", arg)) } #' Standardise a call #' #' This is essentially equivalent to [base::match.call()], but with #' experimental handling of primitive functions. #' #' #' @section Life cycle: #' #' In rlang 0.2.0, `lang_standardise()` was deprecated and renamed to #' `call_standardise()`. See lifecycle section in [call2()] for more #' about this change. #' #' @param call Can be a call or a quosure that wraps a call. #' @param env The environment where to find the definition of the #' function quoted in `call` in case `call` is not wrapped in a #' quosure. #' #' @return A quosure if `call` is a quosure, a raw call otherwise. #' @export call_standardise <- function(call, env = caller_env()) { expr <- get_expr(call) if (!is_call(expr)) { abort_call_input_type("call") } if (is_frame(call)) { fn <- call$fn } else { # The call name might be a literal, not necessarily a symbol env <- get_env(call, env) fn <- eval_bare(node_car(expr), env) } if (is_primitive(fn)) { call } else { matched <- match.call(fn, expr) set_expr(call, matched) } } #' Extract function from a call #' #' If a frame or formula, the function will be retrieved from the #' associated environment. Otherwise, it is looked up in the calling #' frame. #' #' #' @section Life cycle: #' #' In rlang 0.2.0, `lang_fn()` was deprecated and renamed to #' `call_fn()`. See lifecycle section in [call2()] for more about this #' change. #' #' @inheritParams call_standardise #' @export #' @seealso [call_name()] #' @examples #' # Extract from a quoted call: #' call_fn(quote(matrix())) #' call_fn(quo(matrix())) #' #' # Extract the calling function #' test <- function() call_fn(call_frame()) #' test() call_fn <- function(call, env = caller_env()) { if (is_frame(call)) { return(call$fn) } expr <- get_expr(call) env <- get_env(call, env) if (!is_call(expr)) { abort_call_input_type("call") } switch(call_type(expr), recursive = abort("`call` does not call a named or inlined function"), inlined = node_car(expr), named = , namespaced = , eval_bare(node_car(expr), env) ) } #' Extract function name or namespaced of a call #' #' @section Life cycle: #' #' In rlang 0.2.0, `lang_name()` was deprecated and renamed to #' `call_name()`. See lifecycle section in [call2()] for more about #' this change. #' #' @inheritParams call_standardise #' @return A string with the function name, or `NULL` if the function #' is anonymous. #' @seealso [call_fn()] #' @export #' @examples #' # Extract the function name from quoted calls: #' call_name(quote(foo(bar))) #' call_name(quo(foo(bar))) #' #' # Namespaced calls are correctly handled: #' call_name(~base::matrix(baz)) #' #' # Anonymous and subsetted functions return NULL: #' call_name(quote(foo$bar())) #' call_name(quote(foo[[bar]]())) #' call_name(quote(foo()())) #' #' # Extract namespace of a call with call_ns(): #' call_ns(quote(base::bar())) #' #' # If not namespaced, call_ns() returns NULL: #' call_ns(quote(bar())) call_name <- function(call) { if (is_quosure(call) || is_formula(call)) { call <- get_expr(call) } # FIXME: Disabled for the 0.3.1 release # if (!is_call(call) || is_call(call, c("::", ":::"))) { if (!is_call(call)) { abort_call_input_type("call") } switch(call_type(call), named = as_string(node_car(call)), namespaced = as_string(node_cadr(node_cdar(call))), NULL ) } #' @rdname call_name #' @export call_ns <- function(call) { if (is_quosure(call) || is_formula(call)) { call <- get_expr(call) } if (!is_call(call)) { abort_call_input_type("call") } head <- node_car(call) if (is_call(head, c("::", ":::"))) { as_string(node_cadr(head)) } else { NULL } } #' Extract arguments from a call #' #' @section Life cycle: #' #' In rlang 0.2.0, `lang_args()` and `lang_args_names()` were #' deprecated and renamed to `call_args()` and `call_args_names()`. #' See lifecycle section in [call2()] for more about this change. #' #' @inheritParams call_standardise #' @return A named list of arguments. #' @seealso [fn_fmls()] and [fn_fmls_names()] #' @export #' @examples #' call <- quote(f(a, b)) #' #' # Subsetting a call returns the arguments converted to a language #' # object: #' call[-1] #' #' # On the other hand, call_args() returns a regular list that is #' # often easier to work with: #' str(call_args(call)) #' #' # When the arguments are unnamed, a vector of empty strings is #' # supplied (rather than NULL): #' call_args_names(call) call_args <- function(call) { call <- get_expr(call) if (!is_call(call)) { abort_call_input_type("call") } args <- as.list(call[-1]) set_names((args), names2(args)) } #' @rdname call_args #' @export call_args_names <- function(call) { call <- get_expr(call) if (!is_call(call)) { abort_call_input_type("call") } names2(call[-1]) } is_qualified_call <- function(x) { if (typeof(x) != "language") return(FALSE) is_qualified_symbol(node_car(x)) } is_namespaced_call <- function(x, ns = NULL, private = NULL) { if (typeof(x) != "language") return(FALSE) if (!is_namespaced_symbol(node_car(x), ns, private)) return(FALSE) TRUE } # Returns a new call whose CAR has been unqualified call_unnamespace <- function(x) { if (is_namespaced_call(x)) { call <- call2(node_cadr(node_cdar(x))) node_poke_cdr(call, node_cdr(x)) } else { x } } # Qualified and namespaced symbols are actually calls is_qualified_symbol <- function(x) { if (typeof(x) != "language") return(FALSE) head <- node_cadr(node_cdr(x)) if (typeof(head) != "symbol") return(FALSE) qualifier <- node_car(x) identical(qualifier, namespace_sym) || identical(qualifier, namespace2_sym) || identical(qualifier, dollar_sym) || identical(qualifier, at_sym) } is_namespaced_symbol <- function(x, ns = NULL, private = NULL) { if (typeof(x) != "language") return(FALSE) if (!is_null(ns) && !identical(node_cadr(x), sym(ns))) return(FALSE) head <- node_car(x) if (is_null(private)) { identical(head, namespace_sym) || identical(head, namespace2_sym) } else if (private) { identical(head, namespace2_sym) } else { identical(head, namespace_sym) } } which_operator <- function(call) { .Call(rlang_which_operator, call) } call_has_precedence <- function(call, parent_call, side = NULL) { .Call(rlang_call_has_precedence, call, parent_call, side) } call_type <- function(x) { x <- get_expr(x) stopifnot(typeof(x) == "language") type <- typeof(node_car(x)) if (type == "symbol") { "named" } else if (is_namespaced_symbol(node_car(x))) { "namespaced" } else if (type == "language") { "recursive" } else if (type %in% c("closure", "builtin", "special")) { "inlined" } else { abort("corrupt language object") } } rlang/R/operators.R0000644000176200001440000000773513561023554013737 0ustar liggesusers#' Default value for `NULL` #' #' This infix function makes it easy to replace `NULL`s with a default #' value. It's inspired by the way that Ruby's or operation (`||`) #' works. #' #' @param x,y If `x` is NULL, will return `y`; otherwise returns `x`. #' @export #' @name op-null-default #' @examples #' 1 %||% 2 #' NULL %||% 2 `%||%` <- function(x, y) { if (is_null(x)) y else x } #' Replace missing values #' #' This infix function is similar to \code{\%||\%} but is vectorised #' and provides a default value for missing elements. It is faster #' than using [base::ifelse()] and does not perform type conversions. #' #' @param x The original values. #' @param y The replacement values. Must be of length 1 or the same length as `x`. #' @export #' @name op-na-default #' @seealso [op-null-default] #' @examples #' c("a", "b", NA, "c") %|% "default" #' c(1L, NA, 3L, NA, NA) %|% (6L:10L) `%|%` <- function(x, y) { stopifnot(is_atomic(x) && is_atomic(y)) stopifnot(length(y) == 1 || length(y) == length(x)) stopifnot(typeof(x) == typeof(y)) .Call(rlang_replace_na, x, y) } #' Infix attribute accessor and setter #' #' This operator extracts or sets attributes for regular objects and #' S4 fields for S4 objects. #' #' @param x Object #' @param name Attribute name #' @export #' @name op-get-attr #' @examples #' # Unlike `@`, this operator extracts attributes for any kind of #' # objects: #' factor(1:3) %@% "levels" #' mtcars %@% class #' #' mtcars %@% class <- NULL #' mtcars #' #' # It also works on S4 objects: #' .Person <- setClass("Person", slots = c(name = "character", species = "character")) #' fievel <- .Person(name = "Fievel", species = "mouse") #' fievel %@% name `%@%` <- function(x, name) { name <- as_string(ensym(name)) if (isS4(x)) { eval_bare(expr(`@`(x, !!name))) } else { attr(x, name, exact = TRUE) } } #' @rdname op-get-attr #' @param value New value for attribute `name`. #' @usage x \%@\% name <- value #' @export `%@%<-` <- function(x, name, value) { name <- as_string(ensym(name)) if (isS4(x)) { eval_bare(expr(`@`(x, !!name) <- value)) } else { eval_bare(expr(attr(x, !!name) <- value)) } x } #' Definition operator #' #' @description #' #' The definition operator is typically used in DSL packages like #' `ggvis` and `data.table`. It is also used in the tidyverse as a way #' of unquoting names (see [nse-force]). #' #' * `is_definition()` returns `TRUE` for calls to `:=`. #' #' * `is_formulaish()` returns `TRUE` for both formulas and #' colon-equals operators. #' #' #' @details #' #' The recommended way to use it is to capture arguments as #' expressions or quosures. You can then give a special function #' definition for the `:=` symbol in an overscope. Note that if you #' capture dots with [exprs()] or [quos()], you need to disable #' interpretation of `:=` by setting `.unquote_names` to `FALSE`. #' #' From rlang and data.table perspectives, this operator is not meant #' to be evaluated directly at top-level which is why the exported #' definitions issue an error. #' #' #' @section Life cycle: #' #' These functions are experimental. #' #' @name op-definition #' @param x An object to test. #' @keywords internal #' @export #' @examples #' #' # A predicate is provided to distinguish formulas from the #' # colon-equals operator: #' is_definition(quote(a := b)) #' is_definition(a ~ b) #' #' #' # is_formulaish() tests for both definitions and formulas: #' is_formulaish(a ~ b) #' is_formulaish(quote(a := b)) is_definition <- function(x) { is_formulaish(x) && identical(node_car(x), colon_equals_sym) } #' @rdname op-definition #' @export #' @param lhs,rhs Expressions for the LHS and RHS of the definition. #' @param env The evaluation environment bundled with the definition. new_definition <- function(lhs, rhs, env = caller_env()) { def <- new_formula(lhs, rhs, env) node_poke_car(def, colon_equals_sym) def } #' @rdname op-definition #' @export is_formulaish <- function(x, scoped = NULL, lhs = NULL) { .Call(rlang_is_formulaish, x, scoped, lhs) } rlang/R/trace.R0000644000176200001440000005162613612353621013013 0ustar liggesusers#' Capture a backtrace #' #' A backtrace captures the sequence of calls that lead to the current #' function, sometimes called the call stack. Because of lazy #' evaluation, the call stack in R is actually a tree, which the #' `summary()` method of this object will reveal. #' #' `trace_length()` returns the number of frames in a backtrace. #' #' @param top The first frame environment to be included in the #' backtrace. This becomes the top of the backtrace tree and #' represents the oldest call in the backtrace. #' #' This is needed in particular when you call `trace_back()` #' indirectly or from a larger context, for example in tests or #' inside an RMarkdown document where you don't want all of the #' knitr evaluation mechanisms to appear in the backtrace. #' @param bottom The last frame environment to be included in the #' backtrace. This becomes the rightmost leaf of the backtrace tree #' and represents the youngest call in the backtrace. #' #' Set this when you would like to capture a backtrace without the #' capture context. #' #' Can also be an integer that will be passed to [caller_env()]. #' @examples #' # Trim backtraces automatically (this improves the generated #' # documentation for the rlang website and the same trick can be #' # useful within knitr documents): #' options(rlang_trace_top_env = current_env()) #' #' f <- function() g() #' g <- function() h() #' h <- function() trace_back() #' #' # When no lazy evaluation is involved the backtrace is linear #' # (i.e. every call has only one child) #' f() #' #' # Lazy evaluation introduces a tree like structure #' identity(identity(f())) #' identity(try(f())) #' try(identity(f())) #' #' # When printing, you can request to simplify this tree to only show #' # the direct sequence of calls that lead to `trace_back()` #' x <- try(identity(f())) #' x #' print(x, simplify = "branch") #' #' # With a little cunning you can also use it to capture the #' # tree from within a base NSE function #' x <- NULL #' with(mtcars, {x <<- f(); 10}) #' x #' #' #' # Restore default top env for next example #' options(rlang_trace_top_env = NULL) #' #' # When code is executed indirectly, i.e. via source or within an #' # RMarkdown document, you'll tend to get a lot of guff at the beginning #' # related to the execution environment: #' conn <- textConnection("summary(f())") #' source(conn, echo = TRUE, local = TRUE) #' close(conn) #' #' # To automatically strip this off, specify which frame should be #' # the top of the backtrace. This will automatically trim off calls #' # prior to that frame: #' top <- current_env() #' h <- function() trace_back(top) #' #' conn <- textConnection("summary(f())") #' source(conn, echo = TRUE, local = TRUE) #' close(conn) #' @export trace_back <- function(top = NULL, bottom = NULL) { frames <- sys.frames() idx <- trace_find_bottom(bottom, frames) frames <- frames[idx] parents <- sys.parents()[idx] calls <- as.list(sys.calls()[idx]) calls <- map(calls, call_fix_car) calls <- add_pipe_pointer(calls, frames) calls <- map2(calls, seq_along(calls), maybe_add_namespace) parents <- normalise_parents(parents) ids <- map_chr(frames, env_label) trace <- new_trace(calls, parents, ids) trace <- trace_trim_env(trace, top) trace } trace_find_bottom <- function(bottom, frames) { if (is_null(bottom)) { return(seq_len(sys.parent(2L))) } if (is_environment(bottom)) { top <- detect_index(frames, is_reference, bottom) if (!top) { if (is_reference(bottom, global_env())) { return(int()) } abort("Can't find `bottom` on the call tree") } return(seq_len(top)) } if (is_integerish(bottom, n = 1)) { return(seq_len(sys.parent(bottom + 1L))) } abort("`bottom` must be `NULL`, a frame environment, or an integer") } # Work around R bug causing promises to leak in frame calls call_fix_car <- function(call) { if (typeof(node_car(call)) == "promise") { node_poke_car(call, eval_bare(node_car(call))) } call } # Assumes magrittr 1.5 add_pipe_pointer <- function(calls, frames) { pipe_begs <- which(map_lgl(calls, is_call2, "%>%")) pipe_kinds <- map_int(pipe_begs, pipe_call_kind, calls) pipe_calls <- map2(pipe_begs, pipe_kinds, function(beg, kind) { call <- calls[[beg]] if (kind == 0L) { return(call) } if (kind == 1L) { v <- "i" } else if (kind == 2L) { v <- "k" } frame <- frames[[beg + 5L]] pointer <- frame[[v]] fn <- frame[["function_list"]][[1]] info <- pipe_collect_calls(call, fn_env(fn)) structure(call, pipe_pointer = pointer, pipe_info = info) }) calls[pipe_begs] <- pipe_calls calls } pipe_call_kind <- function(beg, calls) { end1 <- beg + 6L end2 <- beg + 7L if (end2 > length(calls)) { return(0L) } # Uncomplete pipe call magrittr_call1 <- quote(function_list[[i]](value)) # Last call of the pipe magrittr_call2 <- quote(function_list[[k]](value)) if (identical(calls[[end1]], magrittr_call1)) { return(1L) } if (identical(calls[[end2]], magrittr_call2)) { return(2L) } 0L } maybe_add_namespace <- function(call, fn) { if (is_quosure(call)) { call <- quo_get_expr(call) if (!is_call(call)) { return(call) } } if (call_print_fine_type(call) != "call") { return(call) } # Checking for bare symbols covers the `::` and `:::` cases sym <- node_car(call) if (!is_symbol(sym)) { return(call) } nm <- as_string(sym) if (is_environment(fn)) { fn <- get(nm, envir = fn, mode = "function") } else if (is_function(fn)) { fn <- fn } else { fn <- sys.function(fn) } env <- fn_env(fn) top <- topenv(env) if (is_reference(env, global_env())) { prefix <- "global" op <- "::" } else if (is_namespace(top)) { prefix <- ns_env_name(top) if (ns_exports_has(top, nm)) { op <- "::" } else { op <- ":::" } } else { return(call) } namespaced_sym <- call(op, sym(prefix), sym) call[[1]] <- namespaced_sym call } # Remove recursive frames which occur with quosures normalise_parents <- function(parents) { recursive <- parents == seq_along(parents) parents[recursive] <- 0L parents } new_trace <- function(calls, parents, ids, indices = NULL) { indices <- indices %||% seq_along(calls) n <- length(calls) stopifnot( is_list(calls), is_integer(parents, n), is_integer(indices, n) ) structure( list( calls = calls, parents = parents, ids = ids, indices = indices ), class = "rlang_trace" ) } trace_reset_indices <- function(trace) { trace$indices <- seq_len(trace_length(trace)) trace } # Methods ----------------------------------------------------------------- # For internal use only c.rlang_trace <- function(...) { traces <- list(...) calls <- flatten(map(traces, `[[`, "calls")) parents <- flatten_int(map(traces, `[[`, "parents")) ids <- flatten_chr(map(traces, `[[`, "ids")) indices <- flatten_int(map(traces, `[[`, "indices")) new_trace(calls, parents, ids, indices) } #' @export format.rlang_trace <- function(x, ..., simplify = c("none", "collapse", "branch"), max_frames = NULL, dir = getwd(), srcrefs = NULL) { x <- trace_reset_indices(x) switch(arg_match(simplify), none = trace_format(x, max_frames, dir, srcrefs), collapse = trace_format_collapse(x, max_frames, dir, srcrefs), branch = trace_format_branch(x, max_frames, dir, srcrefs) ) } trace_format <- function(trace, max_frames, dir, srcrefs) { if (!is_null(max_frames)) { msg <- "`max_frames` is currently only supported with `simplify = \"branch\"`" stop(msg, call. = FALSE) } if (!trace_length(trace)) { return(trace_root()) } tree <- trace_as_tree(trace, dir = dir, srcrefs = srcrefs) cli_tree(tree, indices = trace$indices) } trace_format_collapse <- function(trace, max_frames, dir, srcrefs) { trace <- trace_simplify_collapse(trace) trace_format(trace, max_frames, dir, srcrefs) } trace_format_branch <- function(trace, max_frames, dir, srcrefs) { trace <- trace_simplify_branch(trace) trace <- branch_uncollapse_pipe(trace) tree <- trace_as_tree(trace, dir = dir, srcrefs = srcrefs) branch <- tree[-1, ][["call"]] cli_branch(branch, max = max_frames, indices = trace$indices) } format_collapsed <- function(what, n) { if (n > 0L) { call_text <- pluralise_n(n, "call", "calls") n_text <- sprintf(" with %d more %s", n, call_text) n_text <- silver(n_text) } else { n_text <- "" } paste0(what, n_text) } format_collapsed_branch <- function(what, n, style = NULL) { style <- style %||% cli_box_chars() what <- sprintf(" %s %s", style$h, what) format_collapsed(what, n) } cli_branch <- function(lines, max = NULL, style = NULL, indices = NULL) { if (!length(lines)) { return(chr()) } numbered <- length(indices) if (numbered) { indices <- pad_spaces(as.character(indices)) indices <- paste0(" ", indices, ". ") padding <- nchar(indices[[1]]) lines <- paste0(silver(indices), lines) } else { style <- style %||% cli_box_chars() lines <- paste0(" ", style$h, lines) } if (is_null(max)) { return(lines) } stopifnot( is_scalar_integerish(max, finite = TRUE), max > 0L ) n <- length(lines) if (n <= max) { return(lines) } style <- style %||% cli_box_chars() n_collapsed <- n - max if (numbered) { collapsed_line <- paste0(spaces(padding), "...") } else { collapsed_line <- format_collapsed_branch("...", n_collapsed, style = style) } if (max == 1L) { lines <- chr( lines[1L], collapsed_line ) return(lines) } half <- max / 2L n_top <- ceiling(half) n_bottom <- floor(half) chr( lines[seq(1L, n_top)], collapsed_line, lines[seq(n - n_bottom + 1L, n)] ) } #' @export print.rlang_trace <- function(x, ..., simplify = c("none", "branch", "collapse"), max_frames = NULL, dir = getwd(), srcrefs = NULL) { cat_line(format(x, ..., simplify = simplify, max_frames = max_frames, dir = dir, srcrefs = srcrefs )) invisible(x) } #' @export summary.rlang_trace <- function(object, ..., max_frames = NULL, dir = getwd(), srcrefs = NULL) { cat_line(format(object, ..., simplify = "none", max_frames = max_frames, dir = dir, srcrefs = srcrefs )) invisible(object) } #' @rdname trace_back #' @param trace A backtrace created by `trace_back()`. #' @export trace_length <- function(trace) { length(trace$calls) } trace_subset <- function(x, i) { if (!length(i)) { return(new_trace(list(), int(), list())) } stopifnot(is_integerish(i)) n <- trace_length(x) if (all(i < 0L)) { i <- setdiff(seq_len(n), abs(i)) } parents <- match(as.character(x$parents[i]), as.character(i), nomatch = 0) new_trace( calls = x$calls[i], parents = parents, ids = x$ids[i], indices = x$indices[i] ) } # Subsets sibling nodes, at the level of the rightmost leaf by # default. Supports full vector subsetting semantics (negative values, # missing index, etc). trace_subset_across <- function(trace, i, n = NULL) { level <- trace_level(trace, n) level_n <- length(level) i <- validate_index(i, level_n) indices <- unlist(map(level[i], chain_indices, trace$parents)) trace_subset(trace, indices) } trace_level <- function(trace, n = NULL) { n <- n %||% trace_length(trace) parents <- trace$parents which(parents == parents[[n]]) } chain_indices <- function(i, parents) { c( parents_indices(i, parents), children_indices(i, parents) ) } children_indices <- function(i, parents) { n <- length(parents) age <- parents[[i]] ages <- parents[1:n] non_children <- parents <= age non_children[seq(1, i)] <- FALSE non_children <- which(non_children) if (length(non_children)) { end <- non_children[[1]] - 1 } else { end <- n } seq2(i + 1L, end) } parents_indices <- function(i, parents) { path <- int() while (i != 0) { path <- c(path, i) i <- parents[i] } rev(path) } # Trimming ---------------------------------------------------------------- trace_trim_env <- function(x, to = NULL) { to <- to %||% peek_option("rlang_trace_top_env") if (is.null(to)) { return(x) } is_top <- x$ids == env_label(to) if (!any(is_top)) { return(x) } start <- last(which(is_top)) + 1 end <- length(x$ids) trace_subset(x, seq2(start, end)) } set_trace_skipped <- function(trace, id, n) { attr(trace$calls[[id]], "collapsed") <- n trace } set_trace_collapsed <- function(trace, id, n) { attr(trace$calls[[id - n]], "collapsed") <- n trace } n_collapsed <- function(trace, id) { call <- trace$calls[[id]] if (is_eval_call(call)) { # When error occurs inside eval()'s frame at top level, there # might be only one frame and nothing to collapse if (id > 1L && is_eval_call(trace$calls[[id - 1L]])) { n <- 1L } else { n <- 0L } return(n) } if (identical(call, quote(function_list[[i]](value)))) { return(6L) } if (identical(call, quote(function_list[[k]](value)))) { return(7L) } 0L } is_eval_call <- function(call) { is_call2(call, c("eval", "evalq"), ns = c("", "base")) } pipe_collect_calls <- function(pipe, env) { node <- node_cdr(pipe) last_call <- pipe_add_dot(node_cadr(node)) last_call <- maybe_add_namespace(last_call, env) calls <- new_node(last_call, NULL) while (is_call2(node_car(node), "%>%")) { node <- node_cdar(node) call <- pipe_add_dot(node_cadr(node)) call <- maybe_add_namespace(call, env) calls <- new_node(call, calls) } first_call <- node_car(node) if (is_call2(first_call)) { # The first call doesn't need a dot first_call <- maybe_add_namespace(first_call, env) calls <- new_node(first_call, calls) leading <- TRUE } else { leading <- FALSE } list(calls = as.list(calls), leading = leading) } pipe_add_dot <- function(call) { if (!is_call2(call)) { return(call2(call, dot_sym)) } node <- node_cdr(call) while (!is_null(node)) { if (identical(node_car(node), dot_sym)) { return(call) } node <- node_cdr(node) } args <- new_node(dot_sym, node_cdr(call)) new_call(node_car(call), args) } has_pipe_pointer <- function(x) { !is_null(attr(x, "pipe_pointer")) } # Assumes a backtrace branch with collapsed pipe branch_uncollapse_pipe <- function(trace) { while (idx <- detect_index(trace$calls, has_pipe_pointer)) { trace_before <- trace_subset(trace, seq2(1L, idx - 1L)) trace_after <- trace_subset(trace, seq2(idx + 2L, trace_length(trace))) pipe <- trace$calls[[idx]] pointer <- attr(pipe, "pipe_pointer") if (!is_scalar_integer(pointer)) { stop("Internal error: Invalid pipe pointer") } pipe_info <- attr(pipe, "pipe_info") pipe_calls <- pipe_info$calls if (pipe_info$leading) { pointer <- inc(pointer) } incomplete <- seq2(pointer + 1L, length(pipe_calls)) if (length(incomplete)) { pipe_calls <- pipe_calls[-incomplete] } parent <- trace$parents[[idx]] pipe_parents <- seq(parent, parent + pointer - 1L) # Assign the pipe frame as dummy ids for uncollapsed frames pipe_ids <- rep(trace$ids[idx], pointer) # This assigns the same frame number to all pipe calls that have # already returned n_collapsed <- attr(pipe, "collapsed") pipe_indices <- rep(idx, length(pipe_calls) - 1L) pipe_indices <- c(pipe_indices, idx + n_collapsed + 1L) # Add the number of uncollapsed frames to children's # ancestry. This assumes a backtrace branch. trace_after$parents <- trace_after$parents + pointer trace$calls <- c(trace_before$calls, pipe_calls, trace_after$calls) trace$parents <- c(trace_before$parents, pipe_parents, trace_after$parents) trace$ids <- c(trace_before$ids, pipe_ids, trace_after$ids) trace$indices <- c(trace_before$indices, pipe_indices, trace_after$indices) } if (length(unique(lengths(trace))) != 1L) { abort("Internal error: Trace data is not square.") } trace } trace_simplify_branch <- function(trace) { parents <- trace$parents path <- int() id <- length(parents) while (id != 0L) { n_collapsed <- n_collapsed(trace, id) if (n_collapsed) { trace <- set_trace_collapsed(trace, id, n_collapsed) next_id <- id - n_collapsed # Rechain child of collapsed parent to correct parent parents[[id + 1L]] <- next_id id <- next_id } if (!is_uninformative_call(trace$calls[[id]])) { path <- c(path, id) } id <- parents[id] } # Always include very first call path <- rev(path) if (length(path) && path[[1]] != 1L) { path <- c(1L, path) } trace$parents <- parents trace_subset(trace, path) } # Bypass calls with inlined functions is_uninformative_call <- function(call) { if (!is_call2(call)) { return(FALSE) } fn <- call[[1]] # Inlined functions occur with active bindings if (is_function(fn)) { return(TRUE) } # If a call, might be wrapped in parentheses while (is_call2(fn, "(")) { fn <- fn[[2]] if (is_call2(fn, "function")) { return(TRUE) } } FALSE } trace_simplify_collapse <- function(trace) { parents <- trace$parents path <- int() id <- length(parents) while (id > 0L) { n_collapsed <- n_collapsed(trace, id) if (n_collapsed) { trace <- set_trace_collapsed(trace, id, n_collapsed) next_id <- id - n_collapsed # Rechain child of collapsed parent to correct parent parents[[id + 1L]] <- next_id id <- next_id } path <- c(path, id) parent_id <- parents[[id]] id <- dec(id) # Collapse intervening call branches n_skipped <- 0L while (id != parent_id) { sibling_parent_id <- parents[[id]] if (sibling_parent_id == parent_id) { trace <- set_trace_skipped(trace, id, n_skipped) path <- c(path, id) n_skipped <- 0L } else { n_skipped <- inc(n_skipped) } id <- dec(id) } } trace$parents <- parents trace_subset(trace, rev(path)) } # Typically the full trace is held by the child error and the partial # trace by the parent trace_trim_common <- function(full, partial) { common <- map_lgl(full$ids, `%in%`, partial$ids) out <- trace_subset(full, which(!common)) # Trim catching context if any calls <- out$calls if (length(calls) && is_call(calls[[1]], c("tryCatch", "with_handlers", "catch_cnd"))) { out <- trace_subset_across(out, -1, 1) } out } # Printing ---------------------------------------------------------------- trace_as_tree <- function(x, dir = getwd(), srcrefs = NULL) { nodes <- c(0, seq_along(x$calls)) children <- map(nodes, function(id) seq_along(x$parents)[x$parents == id]) calls <- as.list(x$calls) is_collapsed <- map(calls, attr, "collapsed") call_text <- map2_chr(calls, is_collapsed, trace_call_text) srcrefs <- srcrefs %||% peek_option("rlang_trace_format_srcrefs") srcrefs <- srcrefs %||% TRUE stopifnot(is_scalar_logical(srcrefs)) if (srcrefs) { refs <- map(x$calls, attr, "srcref") src_locs <- map_chr(refs, src_loc, dir = dir) have_src_loc <- nzchar(src_locs) src_locs <- silver(src_locs[have_src_loc]) call_text[have_src_loc] <- paste0(call_text[have_src_loc], " ", src_locs) } tree <- data.frame(id = as.character(nodes), stringsAsFactors = FALSE) tree$children <- map(children, as.character) tree$call <- c(trace_root(), call_text) tree } # FIXME: Add something like call_deparse_line() trace_call_text <- function(call, collapse) { if (is_null(collapse)) { return(as_label(call)) } if (is_call2(call, "%>%")) { call <- call } else if (length(call) > 1L) { call <- call2(node_car(call), quote(...)) } text <- as_label(call) if (collapse > 0L) { n_collapsed_text <- sprintf(" ... +%d", collapse) } else { n_collapsed_text <- "" } format_collapsed(paste0("[ ", text, " ]"), collapse) } src_loc <- function(srcref, dir = getwd()) { if (is.null(srcref)) { return("") } srcfile <- attr(srcref, "srcfile") if (is.null(srcfile)) { return("") } file <- srcfile$filename if (identical(file, "") || identical(file, "")) { return("") } if (!file.exists(file) && is_null(peek_option("rlang:::trace_force_dangling_srcrefs"))) { return("") } line <- srcref[[1]] column <- srcref[[5]] - 1L paste0(relish(file, dir = dir), ":", line, ":", column) } relish <- function(x, dir = getwd()) { if (substr(dir, nchar(dir), nchar(dir)) != "/") { dir <- paste0(dir, "/") } gsub(dir, "", x, fixed = TRUE) } trace_root <- function() { if (cli_is_utf8_output()) { "\u2588" } else { "x" } } rlang/R/compat-register.R0000644000176200001440000000223413500156763015015 0ustar liggesusers# nocov start --- compat-register --- 2019-06-12 Wed 13:11 s3_register <- function(generic, class, method = NULL) { stopifnot(is.character(generic), length(generic) == 1) stopifnot(is.character(class), length(class) == 1) pieces <- strsplit(generic, "::")[[1]] stopifnot(length(pieces) == 2) package <- pieces[[1]] generic <- pieces[[2]] if (is.null(method)) { method <- get(paste0(generic, ".", class), envir = parent.frame()) } stopifnot(is.function(method)) if (can_s3_register_now(generic, class, method, package)) { registerS3method(generic, class, method, envir = asNamespace(package)) } # Always register hook in case package is later unloaded & reloaded setHook( packageEvent(package, "onLoad"), function(...) { registerS3method(generic, class, method, envir = asNamespace(package)) } ) } can_s3_register_now <- function(generic, class, method, package) { if (!(package %in% loadedNamespaces())) { return(FALSE) } envir <- asNamespace(package) # Avoid registration failures during loading (pkgload or regular), # only register if generic can be accessed exists(generic, envir) } # nocov end rlang/R/compat-oldrel.R0000644000176200001440000000205313351410554014444 0ustar liggesusers# nocov start - compat-oldrel (last updated: rlang 0.1.2) # This file serves as a reference for compatibility functions for old # versions of R. Please find the most recent version in rlang's # repository. # R 3.2.0 ------------------------------------------------------------ if (getRversion() < "3.2.0") { dir_exists <- function(path) { !identical(path, "") && file.exists(paste0(path, .Platform$file.sep)) } dir.exists <- function(paths) { vapply(paths, dir_exists, logical(1)) } names <- function(x) { if (is.environment(x)) { return(ls(x, all.names = TRUE)) } else { return(base::names(x)) } # So R CMD check on old versions of R sees a generic, since we # declare a names() method for dictionary objects UseMethod("names") } trimws <- function(x, which = c("both", "left", "right")) { switch(match.arg(which), left = sub("^[ \t\r\n]+", "", x, perl = TRUE), right = sub("[ \t\r\n]+$", "", x, perl = TRUE), both = trimws(trimws(x, "left"), "right") ) } } # nocov end rlang/R/sexp.R0000644000176200001440000000506313517571611012673 0ustar liggesusers#' Duplicate an R object #' #' In R semantics, objects are copied by value. This means that #' modifying the copy leaves the original object intact. Since #' copying data in memory is an expensive operation, copies in R are #' as lazy as possible. They only happen when the new object is #' actually modified. However, some operations (like [node_poke_car()] #' or [node_poke_cdr()]) do not support copy-on-write. In those cases, #' it is necessary to duplicate the object manually in order to #' preserve copy-by-value semantics. #' #' Some objects are not duplicable, like symbols and environments. #' `duplicate()` returns its input for these unique objects. #' #' @param x Any R object. However, uncopyable types like symbols and #' environments are returned as is (just like with `<-`). #' @param shallow This is relevant for recursive data structures like #' lists, calls and pairlists. A shallow copy only duplicates the #' top-level data structure. The objects contained in the list are #' still the same. #' @seealso pairlist #' @keywords internal #' @export duplicate <- function(x, shallow = FALSE) { .Call(rlang_duplicate, x, shallow) } # nocov start - These functions are mostly for interactive experimentation poke_type <- function(x, type) { invisible(.Call(rlang_poke_type, x, type)) } sexp_address <- function(x) { .Call(rlang_sexp_address, x) } sexp_named <- function(x) { # Don't use `substitute()` because dots might be forwarded arg <- match.call(expand.dots = FALSE)$x .Call(rlang_named, arg, parent.frame()) } mark_object <- function(x) { invisible(.Call(rlang_mark_object, x)) } unmark_object <- function(x) { invisible(.Call(rlang_unmark_object, x)) } true_length <- function(x) { .Call(rlang_true_length, x) } env_frame <- function(x) { .Call(rlang_env_frame, x) } env_hash_table <- function(x) { .Call(rlang_env_hash_table, x) } promise_expr <- function(name, env = caller_env()) { .Call(rlang_promise_expr, name, env) } promise_env <- function(name, env = caller_env()) { .Call(rlang_promise_env, name, env) } promise_value <- function(name, env = caller_env()) { .Call(rlang_promise_value, name, env) } warningcall <- function(call, msg) { .Call(rlang_test_Rf_warningcall, call, msg) } errorcall <- function(call, msg) { .Call(rlang_test_Rf_errorcall, call, msg) } sexp_attrib <- function(x) { .Call(rlang_attrib, x) } vec_alloc <- function(type, n) { stopifnot( is_string(type), is_integer(n, 1) ) .Call(rlang_vec_alloc, type, n) } find_var <- function(env, sym) { .Call(rlang_find_var, env, sym); } # nocov end rlang/R/state.R0000644000176200001440000001047413563536376013050 0ustar liggesusers#' Change global options #' #' @description #' #' * `local_options()` changes options for the duration of a stack #' frame (by default the current one). Options are set back to their #' old values when the frame returns. #' #' * `with_options()` changes options while an expression is #' evaluated. Options are restored when the expression returns. #' #' * `push_options()` adds or changes options permanently. #' #' * `peek_option()` and `peek_options()` return option values. The #' former returns the option directly while the latter returns a #' list. #' #' #' @section Life cycle: #' #' These functions are experimental. #' #' @param ... For `local_options()` and `push_options()`, named #' values defining new option values. For `peek_options()`, strings #' or character vectors of option names. #' @param .frame The environment of a stack frame which defines the #' scope of the temporary options. When the frame returns, the #' options are set back to their original values. #' @return For `local_options()` and `push_options()`, the old option #' values. `peek_option()` returns the current value of an option #' while the plural `peek_options()` returns a list of current #' option values. #' #' @keywords experimental #' @export #' @examples #' # Store and retrieve a global option: #' push_options(my_option = 10) #' peek_option("my_option") #' #' # Change the option temporarily: #' with_options(my_option = 100, peek_option("my_option")) #' peek_option("my_option") #' #' # The scoped variant is useful within functions: #' fn <- function() { #' local_options(my_option = 100) #' peek_option("my_option") #' } #' fn() #' peek_option("my_option") #' #' # The plural peek returns a named list: #' peek_options("my_option") #' peek_options("my_option", "digits") local_options <- function(..., .frame = caller_env()) { options <- list2(...) stopifnot(is_named(options)) old <- options(options) options_lang <- call2(base::options, !!! old) local_exit(!! options_lang, frame = .frame) invisible(old) } #' @rdname local_options #' @param .expr An expression to evaluate with temporary options. #' @export with_options <- function(.expr, ...) { local_options(...) .expr } #' @rdname local_options #' @export push_options <- function(...) { options(list2(...)) } #' @rdname local_options #' @export peek_options <- function(...) { names <- set_names(chr(...)) map(names, getOption) } #' @rdname local_options #' @param name An option name as string. #' @export peek_option <- function(name) { getOption(name) } #' Is R running interactively? #' #' @description #' #' Like [base::interactive()], `is_interactive()` returns `TRUE` when #' the function runs interactively and `FALSE` when it runs in batch #' mode. It also checks, in this order: #' #' * The `rlang_interactive` global option. If set to a single `TRUE` #' or `FALSE`, `is_interactive()` returns that value immediately. This #' escape hatch is useful in unit tests or to manually turn on #' interactive features in RMarkdown outputs. #' #' * Whether knitr, an RStudio notebook, or testthat is in progress. #' #' `with_interactive()` and `local_interactive()` set the global #' option conveniently. #' #' @export is_interactive <- function() { opt <- peek_option("rlang_interactive") if (!is_null(opt)) { if (!is_bool(opt)) { options(rlang_interactive = NULL) abort("`rlang_interactive` must be a single `TRUE` of `FALSE`") } return(opt) } if (is_true(peek_option("knitr.in.progress"))) { return(FALSE) } if (is_true(peek_option("rstudio.notebook.executing"))) { return(FALSE) } if (identical(Sys.getenv("TESTTHAT"), "true")) { return(FALSE) } interactive() } #' @rdname is_interactive #' @param frame The environment of a running function which defines #' the scope of the temporary options. When the function returns, #' the options are reset to their original values. #' @param value A single `TRUE` or `FALSE`. This overrides the return #' value of `is_interactive()`. #' @export local_interactive <- function(value = TRUE, frame = caller_env()) { local_options(rlang_interactive = value, .frame = frame) } #' @rdname is_interactive #' @param expr An expression to evaluate with interactivity set to #' `value`. #' @export with_interactive <- function(expr, value = TRUE) { local_interactive(value) expr } rlang/R/events.R0000644000176200001440000000075713563536376013237 0ustar liggesusers local_exit <- function(expr, frame = caller_env()) { expr <- enexpr(expr) # We are at top-level when only one frame refers to the global environment if (is_reference(frame, global_env())) { is_global_frame <- sys.parents() == 0 if (sum(is_global_frame) == 1) { abort("Can't add an exit event at top-level") } } # Inline everything so the call will succeed in any environment expr <- call2(on.exit, expr, add = TRUE) eval_bare(expr, frame) invisible(expr) } rlang/R/s3.R0000644000176200001440000001427213500156673012242 0ustar liggesusers#' Does an object inherit from a set of classes? #' #' @description #' #' * `inherits_any()` is like [base::inherits()] but is more explicit #' about its behaviour with multiple classes. If `classes` contains #' several elements and the object inherits from at least one of #' them, `inherits_any()` returns `TRUE`. #' #' * `inherits_all()` tests that an object inherits from all of the #' classes in the supplied order. This is usually the best way to #' test for inheritance of multiple classes. #' #' * `inherits_only()` tests that the class vectors are identical. It #' is a shortcut for `identical(class(x), class)`. #' #' @param x An object to test for inheritance. #' @param class A character vector of classes. #' #' @export #' @examples #' obj <- structure(list(), class = c("foo", "bar", "baz")) #' #' # With the _any variant only one class must match: #' inherits_any(obj, c("foobar", "bazbaz")) #' inherits_any(obj, c("foo", "bazbaz")) #' #' # With the _all variant all classes must match: #' inherits_all(obj, c("foo", "bazbaz")) #' inherits_all(obj, c("foo", "baz")) #' #' # The order of classes must match as well: #' inherits_all(obj, c("baz", "foo")) #' #' # inherits_only() checks that the class vectors are identical: #' inherits_only(obj, c("foo", "baz")) #' inherits_only(obj, c("foo", "bar", "baz")) inherits_any <- function(x, class) { if (is_empty(class)) { abort("`class` can't be empty") } inherits(x, class) } #' @rdname inherits_any #' @export inherits_all <- function(x, class) { if (is_empty(class)) { abort("`class` can't be empty") } idx <- inherits(x, class, which = TRUE) cummax <- cummax(idx) cummax[[1]] != 0L && all(idx == cummax) } #' @rdname inherits_any #' @export inherits_only <- function(x, class) { identical(class(x), class) } #' Box a value #' #' `new_box()` is similar to [base::I()] but it protects a value by #' wrapping it in a scalar list rather than by adding an attribute. #' `unbox()` retrieves the boxed value. `is_box()` tests whether an #' object is boxed with optional class. `as_box()` ensures that a #' value is wrapped in a box. `as_box_if()` does the same but only if #' the value matches a predicate. #' #' @name box #' @param x,.x An R object. #' @param class For `new_box()`, an additional class for the #' boxed value (in addition to `rlang_box`). For `is_box()`, a class #' or vector of classes passed to [inherits_all()]. #' @param ... Additional attributes passed to [base::structure()]. #' @export #' @examples #' boxed <- new_box(letters, "mybox") #' is_box(boxed) #' is_box(boxed, "mybox") #' is_box(boxed, "otherbox") #' #' unbox(boxed) #' #' # as_box() avoids double-boxing: #' boxed2 <- as_box(boxed, "mybox") #' boxed2 #' unbox(boxed2) #' #' # Compare to: #' boxed_boxed <- new_box(boxed, "mybox") #' boxed_boxed #' unbox(unbox(boxed_boxed)) #' #' # Use `as_box_if()` with a predicate if you need to ensure a box #' # only for a subset of values: #' as_box_if(NULL, is_null, "null_box") #' as_box_if("foo", is_null, "null_box") new_box <- function(.x, class = NULL, ...) { structure( list(.x), class = c(class, "rlang_box"), ... ) } #' @rdname box #' @export is_box <- function(x, class = NULL) { inherits_all(x, c(class, "rlang_box")) } #' @rdname box #' @param box A boxed value to unbox. #' @export unbox <- function(box) { if (!inherits(box, "rlang_box")) { abort("`box` must be a box") } box[[1]] } print.box <- function(x, ...) { cat_line("") print(unbox(x)) } #' Convert object to a box #' #' @description #' #' * `as_box()` boxes its input only if it is not already a box. The #' class is also checked if supplied. #' #' * `as_box_if()` boxes its input only if it not already a box, or if #' the predicate `.p` returns `TRUE`. #' #' @inheritParams box #' @param class,.class A box class. If the input is already a box of #' that class, it is returned as is. If the input needs to be boxed, #' `class` is passed to [new_box()]. #' #' @export as_box <- function(x, class = NULL) { if (is_box(x, class)) { x } else { new_box(x, class) } } #' @rdname as_box #' @param .p A predicate function. #' @param ... Arguments passed to `.p`. #' @export as_box_if <- function(.x, .p, .class = NULL, ...) { .p <- as_predicate(.p) if (is_box(.x, .class) || !.p(.x, ...)) { .x } else { new_box(.x, .class) } } #' Box a final value for early termination #' #' @description #' #' A value boxed with `done()` signals to its caller that it #' should stop iterating. Use it to shortcircuit a loop. #' #' @param x For `done()`, a value to box. For `is_done_box()`, a #' value to test. #' @return A [boxed][rlang::new_box] value. #' #' @examples #' done(3) #' #' x <- done(3) #' is_done_box(x) #' @export done <- function(x) { new_box( maybe_missing(x), class = "rlang_box_done", empty = missing(x) ) } #' @rdname done #' @param empty Whether the box is empty. If `NULL`, `is_done_box()` #' returns `TRUE` for all done boxes. If `TRUE`, it returns `TRUE` #' only for empty boxes. Otherwise it returns `TRUE` only for #' non-empty boxes. #' @export is_done_box <- function(x, empty = NULL) { if (!inherits(x, "rlang_box_done")) { return(FALSE) } if (is_null(empty)) { return(TRUE) } attr(x, "empty") == empty } #' @export print.rlang_box_done <- function(x, ...) { cat_line("") print(unbox(x)) } #' Create zap objects #' #' @description #' #' `zap()` creates a sentinel object that indicates that an object #' should be removed. For instance, named zaps instruct [env_bind()] #' and [call_modify()] to remove those objects from the environment or #' the call. #' #' The advantage of zap objects is that they unambiguously signal the #' intent of removing an object. Sentinels like `NULL` or #' [missing_arg()] are ambiguous because they represent valid R #' objects. #' #' @param x An object to test. #' #' @export #' @examples #' # Create one zap object: #' zap() #' #' # Create a list of zaps: #' rep(list(zap()), 3) #' rep_named(c("foo", "bar"), list(zap())) zap <- function() { `zap!` } #' @rdname zap #' @export is_zap <- function(x) { inherits(x, "rlang_zap") } `zap!` <- structure(list(), class = "rlang_zap") #' @export print.rlang_zap <- function(x, ...) { cat_line("") } rlang/R/cnd-message.R0000644000176200001440000001060413610102012014052 0ustar liggesusers#' Build an error message from parts #' #' @description #' #' `cnd_message()` assembles an error message from three generics: #' #' - `cnd_header()` #' - `cnd_body()` #' - `cnd_footer()` #' #' The default method for the error header returns the `message` field #' of the condition object. The default methods for the body and #' footer return empty character vectors. In general, methods for #' these generics should return a character vector. The elements are #' combined into a single string with a newline separator. #' #' `cnd_message()` is automatically called by the `conditionMessage()` #' for rlang errors. Error classes created with [abort()] only need to #' implement header, body or footer methods. This provides a lot of #' flexibility for hierarchies of error classes, for instance you #' could inherit the body of an error message from a parent class #' while overriding the header and footer. #' #' #' @section Overriding `cnd_body()`: #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} #' #' Sometimes the contents of an error message depends on the state of #' your checking routine. In that case, it can be tricky to lazily #' generate error messages with `cnd_body()`: you have the choice #' between overspecifying your error class hierarchies with one class #' per state, or replicating the type-checking control flow within the #' `cnd_body()` method. None of these options are ideal. #' #' A better option is to define a `body` field in your error object #' containing a static string, a [lambda-formula][as_function], or a #' function with the same signature as `cnd_body()`. This field #' overrides the `cnd_body()` generic and makes it easy to generate an #' error message tailored to the state in which the error was #' constructed. #' #' @param cnd A condition object. #' @param ... Arguments passed to methods. #' #' @export cnd_message <- function(cnd) { paste_line( cnd_header(cnd), cnd_body(cnd), cnd_footer(cnd) ) } #' @rdname cnd_message #' @export cnd_header <- function(cnd, ...) { UseMethod("cnd_header") } #' @export cnd_header.default <- function(cnd, ...) { cnd$message } #' @rdname cnd_message #' @export cnd_body <- function(cnd, ...) { if (is_null(cnd$body)) { UseMethod("cnd_body") } else { override_cnd_body(cnd, ...) } } #' @export cnd_body.default <- function(cnd, ...) { chr() } override_cnd_body <- function(cnd, ...) { body <- cnd$body if (is_function(body)) { body(cnd, ...) } else if (is_bare_formula(body)) { body <- as_function(body) body(cnd, ...) } else if (is_character(body)) { body } else { abort("`body` must be `TRUE` or a function.") } } #' @rdname cnd_message #' @export cnd_footer <- function(cnd, ...) { UseMethod("cnd_footer") } #' @export cnd_footer.default <- function(cnd, ...) { chr() } #' Format bullets for error messages #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} #' #' `format_error_bullets()` takes a character vector and returns a single #' string (or an empty vector if the input is empty). The elements of #' the input vector are assembled as a list of bullets, depending on #' their names: #' #' - Elements named `"i"` are bulleted with a blue "info" symbol. #' - Elements named `"x"` are bulleted with a red "cross" symbol. #' - Unnamed elements are bulleted with a "*" symbol. #' #' This experimental infrastructure is based on the idea that #' sentences in error messages are best kept short and simple. From #' this point of view, the best way to present the information is in #' the [cnd_body()] method of an error conditon, as a bullet list of #' simple sentences containing a single clause. The info and cross #' symbols of the bullets provide hints on how to interpret the bullet #' relative to the general error issue, which should be supplied as #' [cnd_header()]. #' #' @param x A named character vector of messages. Elements named as #' `x` or `i` are prefixed with the corresponding bullet. #' @export format_error_bullets <- function(x) { if (!length(x)) { return(x) } nms <- names2(x) stopifnot(nms %in% c("i", "x", "")) bullets <- ifelse(nms == "i", info(), ifelse(nms == "x", cross(), "*")) bullets <- paste(bullets, x, collapse = "\n") bullets } collapse_cnd_message <- function(x) { if (length(x) > 1L) { paste( x[[1]], format_error_bullets(x[-1]), sep = "\n" ) } else { x } } rlang/R/vec-squash.R0000644000176200001440000001022513405732277013772 0ustar liggesusers#' Flatten or squash a list of lists into a simpler vector #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} #' #' `flatten()` removes one level hierarchy from a list, while #' `squash()` removes all levels. These functions are similar to #' [unlist()] but they are type-stable so you always know what the #' type of the output is. #' #' #' @section Life cycle: #' #' These functions are in the questioning stage. They have slightly #' different semantics than the flattening functions in purrr and we #' are currently rethinking our approach to flattening with the new #' typing facilities of the vctrs package. #' #' @param x A list to flatten or squash. The contents of the list can #' be anything for unsuffixed functions `flatten()` and `squash()` #' (as a list is returned), but the contents must match the type for #' the other functions. #' @return `flatten()` returns a list, `flatten_lgl()` a logical #' vector, `flatten_int()` an integer vector, `flatten_dbl()` a #' double vector, and `flatten_chr()` a character vector. Similarly #' for `squash()` and the typed variants (`squash_lgl()` etc). #' @export #' @keywords internal #' @examples #' x <- replicate(2, sample(4), simplify = FALSE) #' x #' #' flatten(x) #' flatten_int(x) #' #' # With flatten(), only one level gets removed at a time: #' deep <- list(1, list(2, list(3))) #' flatten(deep) #' flatten(flatten(deep)) #' #' # But squash() removes all levels: #' squash(deep) #' squash_dbl(deep) #' #' # The typed flatten functions remove one level and coerce to an atomic #' # vector at the same time: #' flatten_dbl(list(1, list(2))) #' #' # Only bare lists are flattened, but you can splice S3 lists #' # explicitly: #' foo <- set_attrs(list("bar"), class = "foo") #' str(flatten(list(1, foo, list(100)))) #' str(flatten(list(1, splice(foo), list(100)))) #' #' # Instead of splicing manually, flatten_if() and squash_if() let #' # you specify a predicate function: #' is_foo <- function(x) inherits(x, "foo") || is_bare_list(x) #' str(flatten_if(list(1, foo, list(100)), is_foo)) #' #' # squash_if() does the same with deep lists: #' deep_foo <- list(1, list(foo, list(foo, 100))) #' str(deep_foo) #' #' str(squash(deep_foo)) #' str(squash_if(deep_foo, is_foo)) flatten <- function(x) { .Call(rlang_squash, x, "list", is_spliced_bare, 1L) } #' @rdname flatten #' @export flatten_lgl <- function(x) { .Call(rlang_squash, x, "logical", is_spliced_bare, 1L) } #' @rdname flatten #' @export flatten_int <- function(x) { .Call(rlang_squash, x, "integer", is_spliced_bare, 1L) } #' @rdname flatten #' @export flatten_dbl <- function(x) { .Call(rlang_squash, x, "double", is_spliced_bare, 1L) } #' @rdname flatten #' @export flatten_cpl <- function(x) { .Call(rlang_squash, x, "complex", is_spliced_bare, 1L) } #' @rdname flatten #' @export flatten_chr <- function(x) { .Call(rlang_squash, x, "character", is_spliced_bare, 1L) } #' @rdname flatten #' @export flatten_raw <- function(x) { .Call(rlang_squash, x, "raw", is_spliced_bare, 1L) } #' @rdname flatten #' @export squash <- function(x) { .Call(rlang_squash, x, "list", is_spliced_bare, -1L) } #' @rdname flatten #' @export squash_lgl <- function(x) { .Call(rlang_squash, x, "logical", is_spliced_bare, -1L) } #' @rdname flatten #' @export squash_int <- function(x) { .Call(rlang_squash, x, "integer", is_spliced_bare, -1L) } #' @rdname flatten #' @export squash_dbl <- function(x) { .Call(rlang_squash, x, "double", is_spliced_bare, -1L) } #' @rdname flatten #' @export squash_cpl <- function(x) { .Call(rlang_squash, x, "complex", is_spliced_bare, -1L) } #' @rdname flatten #' @export squash_chr <- function(x) { .Call(rlang_squash, x, "character", is_spliced_bare, -1L) } #' @rdname flatten #' @export squash_raw <- function(x) { .Call(rlang_squash, x, "raw", is_spliced_bare, -1L) } #' @rdname flatten #' @param predicate A function of one argument returning whether it #' should be spliced. #' @export flatten_if <- function(x, predicate = is_spliced) { .Call(rlang_squash, x, "list", predicate, 1L) } #' @rdname flatten #' @export squash_if <- function(x, predicate = is_spliced) { .Call(rlang_squash, x, "list", predicate, -1L) } rlang/R/sym.R0000644000176200001440000000640213500516354012515 0ustar liggesusers#' Create a symbol or list of symbols #' #' These functions take strings as input and turn them into symbols. #' #' @param x A string or list of strings. #' @return A symbol for `sym()` and a list of symbols for `syms()`. #' @export #' @examples #' # The empty string returns the missing argument: #' sym("") #' #' # This way sym() and as_string() are inverse of each other: #' as_string(missing_arg()) #' sym(as_string(missing_arg())) sym <- function(x) { if (is_symbol(x)) { return(x) } if (identical(x, "")) { return(missing_arg()) } if (!is_string(x)) { abort("Only strings can be converted to symbols") } .Call(rlang_symbol, x) } #' @rdname sym #' @export syms <- function(x) { map(x, sym) } #' Is object a symbol? #' @param x An object to test. #' @param name An optional name or vector of names that the symbol #' should match. #' @export is_symbol <- function(x, name = NULL) { if (typeof(x) != "symbol") { return(FALSE) } if (is_null(name)) { return(TRUE) } as_string(x) %in% name } #' Cast symbol to string #' #' `as_string()` converts [symbols][sym] to character strings. #' #' @param x A string or symbol. If a string, the attributes are #' removed, if any. #' @return A character vector of length 1. #' #' @section Unicode tags: #' #' Unlike [base::as.symbol()] and [base::as.name()], `as_string()` #' automatically transforms unicode tags such as `""` to the #' proper UTF-8 character. This is important on Windows because: #' #' * R on Windows has no UTF-8 support, and uses native encoding instead. #' #' * The native encodings do not cover all Unicode characters. For #' example, Western encodings do not support CKJ characters. #' #' * When a lossy UTF-8 -> native transformation occurs, uncovered #' characters are transformed to an ASCII unicode tag like `""`. #' #' * Symbols are always encoded in native. This means that #' transforming the column names of a data frame to symbols might be #' a lossy operation. #' #' * This operation is very common in the tidyverse because of data #' masking APIs like dplyr where data frames are transformed to #' environments. While the names of a data frame are stored as a #' character vector, the bindings of environments are stored as #' symbols. #' #' Because it reencodes the ASCII unicode tags to their UTF-8 #' representation, the string -> symbol -> string roundtrip is #' more stable with `as_string()`. #' #' @seealso [as_name()] for a higher-level variant of `as_string()` #' that automatically unwraps quosures. #' @examples #' # Let's create some symbols: #' foo <- quote(foo) #' bar <- sym("bar") #' #' # as_string() converts symbols to strings: #' foo #' as_string(foo) #' #' typeof(bar) #' typeof(as_string(bar)) #' @export as_string <- function(x) { if (is_string(x)) { attributes(x) <- NULL return(x) } if (is_symbol(x)) { return(.Call(rlang_symbol_to_character, x)) } abort_coercion(x, "a string") } namespace_sym <- quote(`::`) namespace2_sym <- quote(`:::`) dollar_sym <- quote(`$`) dot_data_sym <- quote(.data) dots_sym <- quote(...) at_sym <- quote(`@`) tilde_sym <- quote(`~`) colon_equals_sym <- quote(`:=`) brace_sym <- quote(`{`) dots_sym <- quote(...) function_sym <- quote(`function`) dot_sym <- quote(.) pipe_sym <- quote(`%>%`) rlang/R/dots.R0000644000176200001440000003435513604132570012665 0ustar liggesusers#' Dynamic dots #' #' @description #' #' The `...` syntax of base R allows you to: #' #' - __Forward__ arguments from function to function, matching them #' along the way to function parameters. #' #' - __Collect__ arguments inside data structures, e.g. with [c()] or #' [list()]. #' #' Dynamic dots offer a few additional features: #' #' 1. You can __splice__ arguments saved in a list with the [big #' bang][quasiquotation] operator `!!!`. #' #' 2. You can __unquote__ names by using the [bang bang][quasiquotation] #' operator `!!` on the left-hand side of `:=`. #' #' 3. Trailing commas are ignored, making it easier to copy and paste #' lines of arguments. #' #' #' @section Add dynamic dots support in your functions: #' #' If your function takes dots, adding support for dynamic features is #' as easy as collecting the dots with [list2()] instead of [list()]. #' #' Other dynamic dots collectors are [dots_list()], which is more #' configurable than [list2()], `vars()` which doesn't force its #' arguments, and [call2()] for creating calls. #' #' @name dyn-dots #' @aliases tidy-dots NULL #' Collect dots in a list #' #' `list2(...)` is equivalent to `list(...)` with a few additional #' features, collectively called [dynamic dots][dyn-dots]. While #' `list2()` hard-code these features, `dots_list()` is a lower-level #' version that offers more control. #' #' @param ... Arguments to collect in a list. These dots are #' [dynamic][dyn-dots]. #' @return A list containing the `...` inputs. #' #' @export list2 <- function(...) { .Call(rlang_dots_list, frame_env = environment(), named = FALSE, ignore_empty = "trailing", preserve_empty = FALSE, unquote_names = TRUE, homonyms = "keep", check_assign = FALSE ) } #' @rdname list2 #' @usage NULL #' @export ll <- list2 # Preserves empty arguments list3 <- function(...) { .Call(rlang_dots_list, frame_env = environment(), named = FALSE, ignore_empty = "trailing", preserve_empty = TRUE, unquote_names = TRUE, homonyms = "keep", check_assign = FALSE ) } #' @rdname list2 #' @param .ignore_empty Whether to ignore empty arguments. Can be one #' of `"trailing"`, `"none"`, `"all"`. If `"trailing"`, only the #' last argument is ignored if it is empty. #' @param .preserve_empty Whether to preserve the empty arguments that #' were not ignored. If `TRUE`, empty arguments are stored with #' [missing_arg()] values. If `FALSE` (the default) an error is #' thrown when an empty argument is detected. #' @param .homonyms How to treat arguments with the same name. The #' default, `"keep"`, preserves these arguments. Set `.homonyms` to #' `"first"` to only keep the first occurrences, to `"last"` to keep #' the last occurrences, and to `"error"` to raise an informative #' error and indicate what arguments have duplicated names. #' @param .check_assign Whether to check for `<-` calls passed in #' dots. When `TRUE` and a `<-` call is detected, a warning is #' issued to advise users to use `=` if they meant to match a #' function parameter, or wrap the `<-` call in braces otherwise. #' This ensures assignments are explicit. #' @export #' @examples #' # Let's create a function that takes a variable number of arguments: #' numeric <- function(...) { #' dots <- list2(...) #' num <- as.numeric(dots) #' set_names(num, names(dots)) #' } #' numeric(1, 2, 3) #' #' # The main difference with list(...) is that list2(...) enables #' # the `!!!` syntax to splice lists: #' x <- list(2, 3) #' numeric(1, !!! x, 4) #' #' # As well as unquoting of names: #' nm <- "yup!" #' numeric(!!nm := 1) #' #' #' # One useful application of splicing is to work around exact and #' # partial matching of arguments. Let's create a function taking #' # named arguments and dots: #' fn <- function(data, ...) { #' list2(...) #' } #' #' # You normally cannot pass an argument named `data` through the dots #' # as it will match `fn`'s `data` argument. The splicing syntax #' # provides a workaround: #' fn("wrong!", data = letters) # exact matching of `data` #' fn("wrong!", dat = letters) # partial matching of `data` #' fn(some_data, !!!list(data = letters)) # no matching #' #' #' # Empty arguments trigger an error by default: #' try(fn(, )) #' #' # You can choose to preserve empty arguments instead: #' list3 <- function(...) dots_list(..., .preserve_empty = TRUE) #' #' # Note how the last empty argument is still ignored because #' # `.ignore_empty` defaults to "trailing": #' list3(, ) #' #' # The list with preserved empty arguments is equivalent to: #' list(missing_arg()) #' #' #' # Arguments with duplicated names are kept by default: #' list2(a = 1, a = 2, b = 3, b = 4, 5, 6) #' #' # Use the `.homonyms` argument to keep only the first of these: #' dots_list(a = 1, a = 2, b = 3, b = 4, 5, 6, .homonyms = "first") #' #' # Or the last: #' dots_list(a = 1, a = 2, b = 3, b = 4, 5, 6, .homonyms = "last") #' #' # Or raise an informative error: #' try(dots_list(a = 1, a = 2, b = 3, b = 4, 5, 6, .homonyms = "error")) #' #' #' # dots_list() can be configured to warn when a `<-` call is #' # detected: #' my_list <- function(...) dots_list(..., .check_assign = TRUE) #' my_list(a <- 1) #' #' # There is no warning if the assignment is wrapped in braces. #' # This requires users to be explicit about their intent: #' my_list({ a <- 1 }) dots_list <- function(..., .ignore_empty = c("trailing", "none", "all"), .preserve_empty = FALSE, .homonyms = c("keep", "first", "last", "error"), .check_assign = FALSE) { dots <- .Call(rlang_dots_list, frame_env = environment(), named = FALSE, ignore_empty = .ignore_empty, preserve_empty = .preserve_empty, unquote_names = TRUE, homonyms = .homonyms, check_assign = .check_assign ) names(dots) <- names2(dots) dots } dots_split <- function(..., .n_unnamed = NULL, .ignore_empty = c("trailing", "none", "all"), .preserve_empty = FALSE, .homonyms = c("keep", "first", "last", "error"), .check_assign = FALSE) { dots <- .Call(rlang_dots_list, frame_env = environment(), named = FALSE, ignore_empty = .ignore_empty, preserve_empty = .preserve_empty, unquote_names = TRUE, homonyms = .homonyms, check_assign = .check_assign ) if (is_null(names(dots))) { if (length(dots)) { unnamed_idx <- TRUE } else { unnamed_idx <- lgl() } n <- length(dots) } else { unnamed_idx <- names(dots) == "" n <- sum(unnamed_idx) } if (!is_null(.n_unnamed) && all(n != .n_unnamed)) { ns <- chr_enumerate(.n_unnamed) abort(sprintf("Expected %s unnamed arguments in `...`", ns)) } unnamed <- dots[unnamed_idx] named <- dots[!unnamed_idx] # Remove empty names vector names(unnamed) <- NULL list(named = named, unnamed = unnamed) } #' Splice lists #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} #' #' - `splice` marks an object to be spliced. It is equivalent to using #' `!!!` in a function taking [dynamic dots][dyn-dots]. #' #' - `dots_splice()` is like [dots_list()] but automatically splices #' list inputs. #' #' #' @section Standard splicing versus quoting splicing: #' #' The `!!!` operator works differently in _standard_ functions taking #' dots with `dots_list()` than in _quoting_ functions taking dots #' with [enexprs()] or [enquos()]. #' #' * In quoting functions `!!!` disaggregates its argument (let's call #' it `x`) into as many objects as there are elements in #' `x`. E.g. `quo(foo(!!! c(1, 2)))` is completely equivalent to #' `quo(foo(1, 2))`. The creation of those separate objects has an #' overhead but is typically not important when manipulating calls #' because function calls typically take a small number of #' arguments. #' #' * In standard functions, disaggregating the spliced collection #' would have a negative performance impact in cases where #' `dots_list()` is used to build up data structures from user #' inputs. To avoid this spliced inputs are marked with [splice()] #' and the final list is built with (the equivalent of) #' `flatten_if(dots, is_spliced)`. #' #' Most of the time you should not care about the difference. However #' if you use a standard function taking tidy dots within a quoting #' function, the `!!!` operator will disaggregate its argument because #' the behaviour of the quasiquoting function has priority. You might #' then observe some performance cost in edge cases. Here is one #' example where this would happen: #' #' ``` #' purrr::rerun(10, dplyr::bind_rows(!!! x)) #' ``` #' #' `purrr::rerun()` is a quoting function and `dplyr::bind_rows()` is #' a standard function. Because `bind_rows()` is called _inside_ #' `rerun()`, the list `x` will be disaggregated into a pairlist of #' arguments. To avoid this you can use `splice()` instead: #' #' ``` #' purrr::rerun(10, dplyr::bind_rows(splice(x))) #' ``` #' #' #' @section Life cycle: #' #' * `dots_splice()` is in the questioning stage. It is part of our #' experiments with dots semantics. Compared to `dots_list()`, #' `dots_splice()` automatically splices lists. We now lean towards #' adopting a single type of dots semantics (those of `dots_list()`) #' where splicing is explicit. #' #' * `splice()` is in the questioning stage. It is not clear whether it is #' really needed as there are other ways to avoid the performance #' issue discussed above. #' #' #' @param x A list to splice. #' #' @keywords internal #' @export splice <- function(x) { .Call(rlang_new_splice_box, x) } #' @rdname splice #' @export is_spliced <- function(x) { .Call(rlang_is_splice_box, x) } #' @rdname splice #' @export is_spliced_bare <- function(x) { is_bare_list(x) || is_spliced(x) } #' @export print.rlang_box_splice <- function(x, ...) { cat_line("") print(unbox(x)) } #' @rdname splice #' @inheritParams dots_list #' @export dots_splice <- function(..., .ignore_empty = c("trailing", "none", "all"), .preserve_empty = FALSE, .homonyms = c("keep", "first", "last", "error"), .check_assign = FALSE) { dots <- .Call(rlang_dots_flat_list, frame_env = environment(), named = FALSE, ignore_empty = .ignore_empty, preserve_empty = .preserve_empty, unquote_names = TRUE, homonyms = .homonyms, check_assign = .check_assign ) names(dots) <- names2(dots) dots } #' Evaluate dots with preliminary splicing #' #' This is a tool for advanced users. It captures dots, processes #' unquoting and splicing operators, and evaluates them. Unlike #' [dots_list()], it does not flatten spliced objects, instead they #' are attributed a `spliced` class (see [splice()]). You can process #' spliced objects manually, perhaps with a custom predicate (see #' [flatten_if()]). #' #' @inheritParams dots_list #' @param ... Arguments to evaluate and process splicing operators. #' #' @keywords internal #' @export #' @examples #' dots <- dots_values(!!! list(1, 2), 3) #' dots #' #' # Flatten the objects marked as spliced: #' flatten_if(dots, is_spliced) dots_values <- function(..., .ignore_empty = c("trailing", "none", "all"), .preserve_empty = FALSE, .homonyms = c("keep", "first", "last", "error"), .check_assign = FALSE) { .External2(rlang_ext2_dots_values, named = FALSE, ignore_empty = .ignore_empty, preserve_empty = .preserve_empty, unquote_names = TRUE, homonyms = .homonyms, check_assign = .check_assign ) } # Micro optimisation: Inline character vectors in formals list formals(dots_values) <- pairlist( ... = quote(expr = ), .ignore_empty = c("trailing", "none", "all"), .preserve_empty = FALSE, .homonyms = c("keep", "first", "last", "error"), .check_assign = FALSE ) #' Capture definition objects #' #' @section Life cycle: #' #' `dots_definitions()` is experimental. Expect API changes. #' #' @inheritParams nse-defuse #' #' @keywords internal #' @export dots_definitions <- function(..., .named = FALSE, .ignore_empty = c("trailing", "none", "all")) { dots <- .Call(rlang_quos_interp, frame_env = environment(), named = .named, ignore_empty = .ignore_empty, unquote_names = FALSE, homonyms = "keep", check_assign = FALSE ) is_def <- map_lgl(dots, function(dot) is_definition(quo_get_expr(dot))) defs <- map(dots[is_def], as_definition) list(dots = dots[!is_def], defs = defs) } as_definition <- function(def) { # The definition comes wrapped in a quosure env <- quo_get_env(def) def <- quo_get_expr(def) list( lhs = new_quosure(f_lhs(def), env), rhs = new_quosure(f_rhs(def), env) ) } dots_node <- function(...) { node_cdr(sys.call()) } #' How many arguments are currently forwarded in dots? #' #' This returns the number of arguments currently forwarded in `...` #' as an integer. #' #' @param ... Forwarded arguments. #' @keywords internal #' @export #' @examples #' fn <- function(...) dots_n(..., baz) #' fn(foo, bar) dots_n <- function(...) { nargs() } abort_dots_homonyms <- function(dots, dups) { nms <- names(dots) # This includes the first occurrence as well dups_all <- nms %in% nms[dups] dups_nms <- unique(nms[dups_all]) dups_n <- length(dups_nms) if (!dups_n) { abort("Internal error: Expected dots duplicates") } if (dups_n == 1L) { nm <- dups_nms enum <- homonym_enum(nm, dups_all, nms) pos_msg <- sprintf( "We found multiple arguments named `%s` at positions %s", nm, enum ) abort(paste_line( "Arguments can't have the same name.", pos_msg )) } enums <- map(dups_nms, homonym_enum, dups_all, nms) line <- "* Multiple arguments named `%s` at positions %s" enums_lines <- map2(dups_nms, enums, sprintf, fmt = line) abort(paste_line( "Arguments can't have the same name. We found these problems:", !!!enums_lines )) } homonym_enum <- function(nm, dups, nms) { dups[nms != nm] <- FALSE chr_enumerate(as.character(which(dups)), final = "and") } check_dots_empty <- function(...) { if (nargs()) { abort("These `...` must be empty") } } rlang/R/cnd-signal.R0000644000176200001440000001276113610367047013736 0ustar liggesusers#' Signal a condition object #' #' @description #' #' The type of signal depends on the class of the condition: #' #' * A message is signalled if the condition inherits from #' `"message"`. This is equivalent to signalling with [inform()] or #' [base::message()]. #' #' * A warning is signalled if the condition inherits from #' `"warning"`. This is equivalent to signalling with [warn()] or #' [base::warning()]. #' #' * An error is signalled if the condition inherits from #' `"error"`. This is equivalent to signalling with [abort()] or #' [base::stop()]. #' #' * An interrupt is signalled if the condition inherits from #' `"interrupt"`. This is equivalent to signalling with #' [interrupt()]. #' #' Use [cnd_type()] to determine the type of a condition. #' #' #' @section Lifecycle: #' #' * `.cnd` has been renamed to `cnd` and is deprecated as of rlang 0.3.0. #' #' * The `.mufflable` argument is deprecated as of rlang 0.3.0 and no #' longer has any effect. Non-critical conditions are always #' signalled with a muffle restart. #' #' * Creating a condition object with [cnd_signal()] is deprecated as #' of rlang 0.3.0. Please use [signal()] instead. #' #' @param cnd A condition object (see [cnd()]). #' @param .cnd,.mufflable These arguments are deprecated. #' @seealso [abort()], [warn()] and [inform()] for creating and #' signalling structured R conditions. See [with_handlers()] for #' establishing condition handlers. #' @export #' @examples #' # The type of signal depends on the class. If the condition #' # inherits from "warning", a warning is issued: #' cnd <- warning_cnd("my_warning_class", message = "This is a warning") #' cnd_signal(cnd) #' #' # If it inherits from "error", an error is raised: #' cnd <- error_cnd("my_error_class", message = "This is an error") #' try(cnd_signal(cnd)) cnd_signal <- function(cnd, .cnd, .mufflable) { validate_cnd_signal_args(cnd, .cnd, .mufflable) if (inherits(cnd, "rlang_error") && is_null(cnd$trace)) { trace <- trace_back() cnd$trace <- trace_trim_context(trace, trace_length(trace)) signal_abort(cnd) } else { invisible(.Call(rlang_cnd_signal, cnd)) } } validate_cnd_signal_args <- function(cnd, .cnd, .mufflable, env = parent.frame()) { if (is_character(cnd)) { warn_deprecated(paste_line( "Creating a condition with `cnd_signal()` is deprecated as of rlang 0.3.0.", "Please use `signal()` instead." )) env$cnd <- cnd(cnd) } if (!missing(.cnd)) { warn_deprecated(paste_line( "The `.cnd` argument is deprecated as of rlang 0.3.0.", "Please use `cnd` instead." )) if (is_character(.cnd)) { warn_deprecated(paste_line( "Creating a condition with `cnd_signal()` is deprecated as of rlang 0.3.0.", "Please use `signal()` instead." )) .cnd <- cnd(.cnd) } env$cnd <- .cnd } if (!missing(.mufflable)) { warn_deprecated( "`.mufflable` is deprecated as of rlang 0.3.0 and no longer has any effect" ) } } #' @rdname abort #' @export warn <- function(message = NULL, class = NULL, ..., call, msg, type, .subclass) { validate_signal_args(msg, type, call, .subclass) message <- validate_signal_message(message, class) message <- collapse_cnd_message(message) cnd <- warning_cnd(class, ..., message = message) warning(cnd) } #' @rdname abort #' @param file Where the message is printed. This should be a #' connection or character string which will be passed to [cat()]. #' #' By default, `inform()` prints to standard output in interactive #' sessions and standard error otherwise. This way IDEs can treat #' messages distinctly from warnings and errors, and R scripts can #' still filter out the messages easily by redirecting `stderr`. #' @export inform <- function(message = NULL, class = NULL, ..., file = NULL, call, msg, type, .subclass) { validate_signal_args(msg, type, call, .subclass) message <- message %||% "" message <- collapse_cnd_message(message) message <- paste0(message, "\n") cnd <- message_cnd(class, ..., message = message) withRestarts(muffleMessage = function() NULL, { signalCondition(cnd) file <- file %||% if (is_interactive()) stdout() else stderr() cat(message, file = file) }) invisible() } #' @rdname abort #' @export signal <- function(message, class, ..., .subclass) { if (!missing(.subclass)) { deprecate_subclass(.subclass) } message <- collapse_cnd_message(message) cnd <- cnd(class, ..., message = message) cnd_signal(cnd) } validate_signal_args <- function(msg, type, call, subclass, env = caller_env()) { if (!missing(msg)) { stop_defunct("`msg` has been renamed to `message` and is deprecated as of rlang 0.3.0") } if (!missing(type)) { stop_defunct("`type` has been renamed to `.subclass` and is deprecated as of rlang 0.3.0") } if (!missing(call)) { stop_defunct("`call` is deprecated as of rlang 0.3.0") } if (!missing(subclass)) { deprecate_subclass(subclass, env = env) } } # Allow until next major version deprecate_subclass <- function(subclass, env = caller_env()) { env_bind(env, class = subclass) } #' @rdname abort #' @export interrupt <- function() { .Call(rlang_interrupt) } validate_signal_message <- function(msg, class) { if (is_null(msg)) { if (is_null(class)) { abort("Either `message` or `class` must be supplied.") } msg <- "" } msg } rlang/R/lifecycle-retired.R0000644000176200001440000015532013563536540015314 0ustar liggesusers # Soft-deprecated in rlang 0.4.0 ## Types #' Base type of an object #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("soft-deprecated")} #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} #' #' This is equivalent to [base::typeof()] with a few differences that #' make dispatching easier: #' * The type of one-sided formulas is "quote". #' * The type of character vectors of length 1 is "string". #' * The type of special and builtin functions is "primitive". #' #' #' @section Life cycle: #' #' `type_of()` is an experimental function. Expect API changes. #' #' @param x An R object. #' @export #' @keywords internal #' @examples #' type_of(10L) #' #' # Quosures are treated as a new base type but not formulas: #' type_of(quo(10L)) #' type_of(~10L) #' #' # Compare to base::typeof(): #' typeof(quo(10L)) #' #' # Strings are treated as a new base type: #' type_of(letters) #' type_of(letters[[1]]) #' #' # This is a bit inconsistent with the core language tenet that data #' # types are vectors. However, treating strings as a different #' # scalar type is quite helpful for switching on function inputs #' # since so many arguments expect strings: #' switch_type("foo", character = abort("vector!"), string = "result") #' #' # Special and builtin primitives are both treated as primitives. #' # That's because it is often irrelevant which type of primitive an #' # input is: #' typeof(list) #' typeof(`$`) #' type_of(list) #' type_of(`$`) type_of <- function(x) { signal_soft_deprecated(c( "`type_of()` is deprecated as of rlang 0.4.0.", "Please use `typeof()` or your own version instead." )) type_of_(x) } #' Dispatch on base types #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("soft-deprecated")} #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} #' #' `switch_type()` is equivalent to #' \code{\link[base]{switch}(\link{type_of}(x, ...))}, while #' `switch_class()` switchpatches based on `class(x)`. The `coerce_` #' versions are intended for type conversion and provide a standard #' error message when conversion fails. #' #' #' @param .x An object from which to dispatch. #' @param ... Named clauses. The names should be types as returned by #' [type_of()]. #' @param .to This is useful when you switchpatch within a coercing #' function. If supplied, this should be a string indicating the #' target type. A catch-all clause is then added to signal an error #' stating the conversion failure. This type is prettified unless #' `.to` inherits from the S3 class `"AsIs"` (see [base::I()]). #' @export #' @keywords internal #' @examples #' switch_type(3L, #' double = "foo", #' integer = "bar", #' "default" #' ) #' #' # Use the coerce_ version to get standardised error handling when no #' # type matches: #' to_chr <- function(x) { #' coerce_type(x, "a chr", #' integer = as.character(x), #' double = as.character(x) #' ) #' } #' to_chr(3L) #' #' # Strings have their own type: #' switch_type("str", #' character = "foo", #' string = "bar", #' "default" #' ) #' #' # Use a fallthrough clause if you need to dispatch on all character #' # vectors, including strings: #' switch_type("str", #' string = , #' character = "foo", #' "default" #' ) #' #' # special and builtin functions are treated as primitive, since #' # there is usually no reason to treat them differently: #' switch_type(base::list, #' primitive = "foo", #' "default" #' ) #' switch_type(base::`$`, #' primitive = "foo", #' "default" #' ) #' #' # closures are not primitives: #' switch_type(rlang::switch_type, #' primitive = "foo", #' "default" #' ) switch_type <- function(.x, ...) { signal_soft_deprecated(c( "`switch_type()` is soft-deprecated as of rlang 0.4.0.", "Please use `switch(typeof())` or `switch(my_typeof())` instead." )) switch(type_of_(.x), ...) } #' @rdname switch_type #' @export coerce_type <- function(.x, .to, ...) { signal_soft_deprecated("`coerce_type()` is soft-deprecated as of rlang 0.4.0.") switch(type_of_(.x), ..., abort_coercion(.x, .to)) } #' @rdname switch_type #' @export switch_class <- function(.x, ...) { signal_soft_deprecated("`switch_class()` is soft-deprecated as of rlang 0.4.0.") switch(class(.x), ...) } #' @rdname switch_type #' @export coerce_class <- function(.x, .to, ...) { signal_soft_deprecated("`coerce_class()` is soft-deprecated as of rlang 0.4.0.") switch(class(.x), ..., abort_coercion(.x, .to)) } ## Casting #' Coerce an object to a base type #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("soft-deprecated")} #' #' These are equivalent to the base functions (e.g. [as.logical()], #' [as.list()], etc), but perform coercion rather than conversion. #' This means they are not generic and will not call S3 conversion #' methods. They only attempt to coerce the base type of their #' input. In addition, they have stricter implicit coercion rules and #' will never attempt any kind of parsing. E.g. they will not try to #' figure out if a character vector represents integers or booleans. #' Finally, they treat attributes consistently, unlike the base R #' functions: all attributes except names are removed. #' #' #' @section Lifecycle: #' #' These functions are deprecated in favour of `vctrs::vec_cast()`. #' #' #' @section Coercion to logical and numeric atomic vectors: #' #' * To logical vectors: Integer and integerish double vectors. See #' [is_integerish()]. #' * To integer vectors: Logical and integerish double vectors. #' * To double vectors: Logical and integer vectors. #' * To complex vectors: Logical, integer and double vectors. #' #' #' @section Coercion to character vectors: #' #' `as_character()` and `as_string()` have an optional `encoding` #' argument to specify the encoding. R uses this information for #' internal handling of strings and character vectors. Note that this #' is only declarative, no encoding conversion is attempted. #' #' Note that only `as_string()` can coerce symbols to a scalar #' character vector. This makes the code more explicit and adds an #' extra type check. #' #' #' @section Coercion to lists: #' #' `as_list()` only coerces vector and dictionary types (environments #' are an example of dictionary type). Unlike [base::as.list()], #' `as_list()` removes all attributes except names. #' #' #' @section Effects of removing attributes: #' #' A technical side-effect of removing the attributes of the input is #' that the underlying objects has to be copied. This has no #' performance implications in the case of lists because this is a #' shallow copy: only the list structure is copied, not the contents #' (see [duplicate()]). However, be aware that atomic vectors #' containing large amounts of data will have to be copied. #' #' In general, any attribute modification creates a copy, which is why #' it is better to avoid using attributes with heavy atomic vectors. #' Uncopyable objects like environments and symbols are an exception #' to this rule: in this case, attributes modification happens in #' place and has side-effects. #' #' @inheritParams string #' @param x An object to coerce to a base type. #' #' @keywords internal #' @examples #' # Coercing atomic vectors removes attributes with both base R and rlang: #' x <- structure(TRUE, class = "foo", bar = "baz") #' as.logical(x) #' #' # But coercing lists preserves attributes in base R but not rlang: #' l <- structure(list(TRUE), class = "foo", bar = "baz") #' as.list(l) #' as_list(l) #' #' # Implicit conversions are performed in base R but not rlang: #' as.logical(l) #' \dontrun{ #' as_logical(l) #' } #' #' # Conversion methods are bypassed, making the result of the #' # coercion more predictable: #' as.list.foo <- function(x) "wrong" #' as.list(l) #' as_list(l) #' #' # The input is never parsed. E.g. character vectors of numbers are #' # not converted to numeric types: #' as.integer("33") #' \dontrun{ #' as_integer("33") #' } #' #' #' # With base R tools there is no way to convert an environment to a #' # list without either triggering method dispatch, or changing the #' # original environment. as_list() makes it easy: #' x <- structure(as_environment(mtcars[1:2]), class = "foobar") #' as.list.foobar <- function(x) abort("dont call me") #' as_list(x) #' @name vector-coercion NULL signal_deprecated_cast <- function(fn, env = caller_env(2)) { signal_soft_deprecated(env = env, c( sprintf("`%s()` is deprecated as of rlang 0.4.0", fn), "Please use `vctrs::vec_cast()` instead." )) } #' @rdname vector-coercion #' @export as_logical <- function(x) { signal_deprecated_cast("as_logical") coerce_type_vec(x, friendly_type("logical"), logical = { attributes(x) <- NULL; x }, integer = as_base_type(x, as.logical), double = as_integerish_type(x, as.logical, "logical") ) } #' @rdname vector-coercion #' @export as_integer <- function(x) { signal_deprecated_cast("as_integer") coerce_type_vec(x, friendly_type("integer"), logical = as_base_type(x, as.integer), integer = { attributes(x) <- NULL; x }, double = as_integerish_type(x, as.integer, "integer") ) } #' @rdname vector-coercion #' @export as_double <- function(x) { signal_deprecated_cast("as_double") coerce_type_vec(x, friendly_type("double"), logical = , integer = as_base_type(x, as.double), double = { attributes(x) <- NULL; x } ) } #' @rdname vector-coercion #' @export as_complex <- function(x) { signal_deprecated_cast("as_complex") coerce_type_vec(x, friendly_type("complex"), logical = , integer = , double = as_base_type(x, as.complex), complex = { attributes(x) <- NULL; x } ) } #' @rdname vector-coercion #' @export as_character <- function(x, encoding = NULL) { signal_deprecated_cast("as_character") if (is_unspecified(x)) { return(rep_along(x, na_chr)) } coerce_type_vec(x, friendly_type("character"), string = , character = { attributes(x) <- NULL if (!is_null(encoding)) { Encoding(x) <- encoding } x } ) } #' @rdname vector-coercion #' @export as_list <- function(x) { signal_deprecated_cast("as_list") switch_type(x, environment = env_as_list(x), vec_as_list(x) ) } env_as_list <- function(x) { names_x <- names(x) x <- as_base_type(x, as.list) set_names(x, .Call(rlang_unescape_character, names_x)) } vec_as_list <- function(x) { coerce_type_vec(x, friendly_type("list"), logical = , integer = , double = , string = , character = , complex = , raw = as_base_type(x, as.list), list = { attributes(x) <- NULL; x } ) } is_unspecified <- function(x) { is_logical(x) && all(map_lgl(x, identical, NA)) } as_base_type <- function(x, as_type) { # Zap attributes temporarily instead of unclassing. We want to avoid # method dispatch, but we also want to avoid an extra copy of atomic # vectors: the first when unclassing, the second when coercing. This # is also useful for uncopyable types like environments. attrs <- .Call(rlang_get_attributes, x) .Call(rlang_poke_attributes, x, NULL) # This function assumes that the target type is different than the # input type, otherwise no duplication is done and the output will # be modified by side effect when we restore the input attributes. on.exit(.Call(rlang_poke_attributes, x, attrs)) as_type(x) } as_integerish_type <- function(x, as_type, to) { if (is_integerish(x)) { as_base_type(x, as_type) } else { abort(paste0( "Can't convert a fractional double vector to ", friendly_type(to), "" )) } } coerce_type_vec <- function(.x, .to, ...) { # Cannot reuse coerce_type() because switch() has a bug with # fallthrough and multiple levels of dots forwarding. out <- switch(type_of_(.x), ..., abort_coercion(.x, .to)) if (!is_null(names(.x))) { # Avoid a copy of `out` when we restore the names, since it could be # a heavy atomic vector. We own `out`, so it is ok to change its # attributes inplace. .Call(rlang_poke_attributes, out, pairlist(names = names(.x))) } out } vec_coerce <- function(x, type) { .Call(rlang_vec_coerce, x, type) } # Stack and frames ------------------------------------------------- #' Get caller frame #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' #' @param n Number of frames to go back. #' @keywords internal #' @export caller_frame <- function(n = 1) { warn_deprecated("`caller_frame()` is deprecated as of rlang 0.3.0.") call_frame(n + 2) } #' Call stack information #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' #' The `eval_` and `call_` families of functions provide a replacement #' for the base R functions prefixed with `sys.` (which are all about #' the context stack), as well as for [parent.frame()] (which is the #' only base R function for querying the call stack). The context #' stack includes all R-level evaluation contexts. It is linear in #' terms of execution history but due to lazy evaluation it is #' potentially nonlinear in terms of call history. The call stack #' history, on the other hand, is homogenous. #' #' @details #' #' `ctxt_frame()` and `call_frame()` return a `frame` object #' containing the following fields: `expr` and `env` (call expression #' and evaluation environment), `pos` and `caller_pos` (position of #' current frame in the context stack and position of the caller), and #' `fun` (function of the current frame). `ctxt_stack()` and #' `call_stack()` return a list of all context or call frames on the #' stack. Finally, `ctxt_depth()` and `call_depth()` report the #' current context position or the number of calling frames on the #' stack. #' #' The base R functions take two sorts of arguments to indicate which #' frame to query: `which` and `n`. The `n` argument is #' straightforward: it's the number of frames to go down the stack, #' with `n = 1` referring to the current context. The `which` argument #' is more complicated and changes meaning for values lower than 1. #' For the sake of consistency, the rlang functions all take the #' same kind of argument `n`. This argument has a single meaning (the #' number of frames to go down the stack) and cannot be lower than 1. #' #' Note finally that `parent.frame(1)` corresponds to #' `call_frame(2)$env`, as `n = 1` always refers to the current #' frame. This makes the `_frame()` and `_stack()` functions #' consistent: `ctxt_frame(2)` is the same as `ctxt_stack()[[2]]`. #' Also, `ctxt_depth()` returns one more frame than #' [base::sys.nframe()] because it counts the global frame. That is #' consistent with the `_stack()` functions which return the global #' frame as well. This way, `call_stack(call_depth())` is the same as #' `global_frame()`. #' #' #' @section Life cycle: #' #' These functions are soft-deprecated and replaced by [trace_back()]. #' #' @param n The number of frames to go back in the stack. #' @param clean Whether to post-process the call stack to clean #' non-standard frames. If `TRUE`, suboptimal call-stack entries by #' [base::eval()] will be cleaned up: the duplicate frame created by #' `eval()` is eliminated. #' @param trim The number of layers of intervening frames to trim off #' the stack. See [stack_trim()] and examples. #' @name stack #' @keywords internal #' @examples #' # Expressions within arguments count as contexts #' identity(identity(ctxt_depth())) # returns 2 #' #' # But they are not part of the call stack because arguments are #' # evaluated within the calling function (or the global environment #' # if called at top level) #' identity(identity(call_depth())) # returns 0 #' #' # The context stacks includes all intervening execution frames. The #' # call stack doesn't: #' f <- function(x) identity(x) #' f(f(ctxt_stack())) #' f(f(call_stack())) #' #' g <- function(cmd) cmd() #' f(g(ctxt_stack)) #' f(g(call_stack)) #' #' # The rlang _stack() functions return a list of frame #' # objects. Use purrr::transpose() or index a field with #' # purrr::map()'s to extract a particular field from a stack: #' #' # stack <- f(f(call_stack())) #' # purrr::map(stack, "env") #' # purrr::transpose(stack)$expr #' #' # current_frame() is an alias for ctxt_frame(1) #' fn <- function() list(current = current_frame(), first = ctxt_frame(1)) #' fn() #' #' # While current_frame() is the top of the stack, global_frame() is #' # the bottom: #' fn <- function() { #' n <- ctxt_depth() #' ctxt_frame(n) #' } #' identical(fn(), global_frame()) #' #' #' # ctxt_stack() returns a stack with all intervening frames. You can #' # trim layers of intervening frames with the trim argument: #' identity(identity(ctxt_stack())) #' identity(identity(ctxt_stack(trim = 1))) #' #' # ctxt_stack() is called within fn() with intervening frames: #' fn <- function(trim) identity(identity(ctxt_stack(trim = trim))) #' fn(0) #' #' # We can trim the first layer of those: #' fn(1) #' #' # The outside intervening frames (at the fn() call site) are still #' # returned, but can be trimmed as well: #' identity(identity(fn(1))) #' identity(identity(fn(2))) #' #' g <- function(trim) identity(identity(fn(trim))) #' g(2) #' g(3) NULL new_frame <- function(x) { structure(x, class = "frame") } #' @export print.frame <- function(x, ...) { cat("", sep = "") if (!x$pos) { cat(" [global]\n") } else { cat(" (", x$caller_pos, ")\n", sep = "") } expr <- deparse(x$expr) if (length(expr) > 1) { expr <- paste(expr[[1]], "<...>") } cat("expr: ", expr, "\n", sep = "") cat("env: [", env_format(x$env), "]\n", sep = "") } #' Is object a frame? #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' #' @param x Object to test #' @keywords internal #' @export is_frame <- function(x) { inherits(x, "frame") } #' @rdname stack #' @export global_frame <- function() { warn_deprecated("`global_frame()` is deprecated as of rlang 0.3.0.") new_frame(list( pos = 0L, caller_pos = NA_integer_, expr = NULL, env = globalenv(), fn = NULL, fn_name = NULL )) } #' @rdname stack #' @export current_frame <- function() { warn_deprecated("`current_frame()` is deprecated as of rlang 0.3.0.") ctxt_frame(2) } #' @rdname stack #' @export ctxt_frame <- function(n = 1) { warn_deprecated("`ctxt_frame()` is deprecated as of rlang 0.3.0.") stopifnot(n > 0) pos <- sys.nframe() - n if (pos < 0L) { stop("not that many frames on the stack", call. = FALSE) } else if (pos == 0L) { global_frame() } else { new_frame(list( pos = pos, caller_pos = sys.parent(n + 1), expr = sys.call(-n), env = sys.frame(-n), fn = sys.function(-n), fn_name = call_name(sys.call(-n)) )) } } # Positions of frames in the call stack up to `n` trail_make <- function(callers, n = NULL, clean = TRUE) { n_ctxt <- length(callers) if (is.null(n)) { n_max <- n_ctxt } else { if (n > n_ctxt) { stop("not that many frames on the evaluation stack", call. = FALSE) } n_max <- n + 1 } state <- trail_next(callers, 1, clean) if (!length(state$i) || state$i == 0) { return(0L) } j <- 1 # Preallocate a sufficiently large vector out <- integer(n_max) out[j] <- state$i while (state$i != 0 && j < n_max) { j <- j + 1 n_ctxt <- length(state$callers) next_pos <- n_ctxt - state$i + 1 state <- trail_next(state$callers, next_pos, clean) out[j] <- state$i } # Return relevant subset if (!is.null(n) && n > j) { stop("not that many frames on the call stack", call. = FALSE) } out[seq_len(j)] } trail_next <- function(callers, i, clean) { if (i == 0L) { return(list(callers = callers, i = 0L)) } i <- callers[i] if (clean) { # base::Recall() creates a custom context with the wrong sys.parent() if (identical(sys.function(i - 1L), base::Recall)) { i_pos <- trail_index(callers, i) callers[i_pos] <- i - 1L } # The R-level eval() creates two contexts. We skip the second one if (length(i) && is_prim_eval(sys.function(i))) { n_ctxt <- length(callers) special_eval_pos <- trail_index(callers, i) callers <- callers[-special_eval_pos] i <- i - 1L } } list(callers = callers, i = i) } trail_index <- function(callers, i) { n_ctxt <- length(callers) n_ctxt - i + 1L } #' @rdname stack #' @export call_frame <- function(n = 1, clean = TRUE) { stopifnot(n > 0) eval_callers <- ctxt_stack_callers() trail <- trail_make(eval_callers, n, clean = clean) pos <- trail[n] if (identical(pos, 0L)) { return(global_frame()) } frame <- new_frame(list( pos = pos, caller_pos = trail[n + 1], expr = sys.call(pos), env = sys.frame(pos), fn = sys.function(pos), fn_name = call_name(sys.call(pos)) )) if (clean) { frame <- frame_clean_eval(frame) } frame } # The _depth() functions count the global frame as well #' @rdname stack #' @export ctxt_depth <- function() { warn_deprecated("`ctxt_depth()` is deprecated as of rlang 0.3.0.") sys.nframe() } #' @rdname stack #' @export call_depth <- function() { warn_deprecated("`call_depth()` is deprecated as of rlang 0.3.0.") eval_callers <- ctxt_stack_callers() trail <- trail_make(eval_callers) length(trail) } # Summaries ---------------------------------------------------------- #' @rdname stack #' @export ctxt_stack <- function(n = NULL, trim = 0) { warn_deprecated("`ctxt_stack()` is deprecated as of rlang 0.3.0.") stack_data <- list( pos = ctxt_stack_trail(), caller_pos = ctxt_stack_callers(), expr = ctxt_stack_exprs(), env = ctxt_stack_envs(), fn = ctxt_stack_fns() ) # Remove ctxt_stack() from stack stack_data <- map(stack_data, drop_first) stack_data <- stack_subset(stack_data, n) stack_data$fn_name <- map(stack_data$expr, call_name) stack <- transpose(stack_data) stack <- map(stack, new_frame) if (is.null(n) || (length(n) && n > length(stack))) { stack <- c(stack, list(global_frame())) } if (trim > 0) { stack <- stack_trim(stack, n = trim + 1) } structure(stack, class = c("ctxt_stack", "stack")) } ctxt_stack_trail <- function() { pos <- sys.nframe() - 1 seq(pos, 1) } ctxt_stack_exprs <- function() { exprs <- sys.calls() rev(drop_last(exprs)) } ctxt_stack_envs <- function(n = 1) { envs <- sys.frames() rev(drop_last(envs)) } ctxt_stack_callers <- function() { callers <- sys.parents() rev(drop_last(callers)) } ctxt_stack_fns <- function() { pos <- sys.nframe() - 1 map(seq(pos, 1), sys.function) } stack_subset <- function(stack_data, n) { if (length(n)) { stopifnot(n > 0) n_stack <- length(stack_data[[1]]) if (n == n_stack + 1) { # We'll add the global frame later n <- n <- n - 1 } else if (n > n_stack + 1) { stop("not that many frames on the stack", call. = FALSE) } stack_data <- map(stack_data, `[`, seq_len(n)) } stack_data } #' @rdname stack #' @export call_stack <- function(n = NULL, clean = TRUE) { warn_deprecated("`call_stack()` is deprecated as of rlang 0.3.0.") eval_callers <- ctxt_stack_callers() trail <- trail_make(eval_callers, n, clean = clean) stack_data <- list( pos = drop_last(trail), caller_pos = drop_first(trail), expr = map(trail, sys.call), env = map(trail, sys.frame), fn = map(trail, sys.function) ) stack_data$fn_name <- map(stack_data$expr, call_name) stack <- transpose(stack_data) stack <- map(stack, new_frame) if (clean) { stack <- map(stack, frame_clean_eval) } if (trail[length(trail)] == 0L) { stack <- c(stack, list(global_frame())) } structure(stack, class = c("call_stack", "stack")) } frame_clean_eval <- function(frame) { if (identical(frame$fn, base::eval)) { # Use the environment from the context created in do_eval() # (the context with the fake primitive call) stopifnot(is_prim_eval(sys.function(frame$pos + 1))) frame$env <- sys.frame(frame$pos + 1) } frame } #' Is object a stack? #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("soft-deprecated")} #' #' @param x An object to test #' @keywords internal #' @export is_stack <- function(x) { warn_deprecated("`is_stack()` is deprecated as of rlang 0.3.0.") inherits(x, "stack") } #' @rdname is_stack #' @export is_eval_stack <- function(x) { warn_deprecated("`is_eval_stack()` is deprecated as of rlang 0.3.0.") inherits(x, "ctxt_stack") } #' @rdname is_stack #' @export is_call_stack <- function(x) { warn_deprecated("`is_call_stack()` is deprecated as of rlang 0.3.0.") inherits(x, "call_stack") } #' @export `[.stack` <- function(x, i) { structure(NextMethod(), class = class(x)) } # Handles global_frame() whose `caller_pos` is NA sys_frame <- function(n) { if (is.na(n)) { NULL } else { sys.frame(n) } } #' Find the position or distance of a frame on the evaluation stack #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' #' The frame position on the stack can be computed by counting frames #' from the global frame (the bottom of the stack, the default) or #' from the current frame (the top of the stack). #' #' @details #' #' While this function returns the position of the frame on the #' evaluation stack, it can safely be called with intervening frames #' as those will be discarded. #' #' #' @section Life cycle: #' #' These functions are deprecated and replaced by [trace_back()]. #' #' @param frame The environment of a frame. Can be any object with a #' [get_env()] method. Note that for frame objects, the position from #' the global frame is simply `frame$pos`. Alternatively, `frame` #' can be an integer that represents the position on the stack (and #' is thus returned as is if `from` is "global". #' @param from Whether to compute distance from the global frame (the #' bottom of the evaluation stack), or from the current frame (the #' top of the evaluation stack). #' #' @keywords internal #' @export #' @examples #' fn <- function() g(environment()) #' g <- function(env) frame_position(env) #' #' # frame_position() returns the position of the frame on the evaluation stack: #' fn() #' identity(identity(fn())) #' #' # Note that it trims off intervening calls before counting so you #' # can safely nest it within other calls: #' g <- function(env) identity(identity(frame_position(env))) #' fn() #' #' # You can also ask for the position from the current frame rather #' # than the global frame: #' fn <- function() g(environment()) #' g <- function(env) h(env) #' h <- function(env) frame_position(env, from = "current") #' fn() frame_position <- function(frame, from = c("global", "current")) { warn_deprecated("`frame_position()` is deprecated as of rlang 0.3.0.") stack <- stack_trim(ctxt_stack(), n = 2) if (arg_match(from) == "global") { frame_position_global(frame, stack) } else { caller_pos <- call_frame(2)$pos frame_position_current(frame, stack, caller_pos) } } frame_position_global <- function(frame, stack = NULL) { if (is_frame(frame)) { return(frame$pos) } else if (is_integerish(frame)) { return(frame) } frame <- get_env(frame) stack <- stack %||% stack_trim(ctxt_stack(), n = 2) envs <- pluck(stack, "env") i <- 1 for (env in envs) { if (identical(env, frame)) { return(length(envs) - i) } i <- i + 1 } abort("`frame` not found on evaluation stack") } frame_position_current <- function(frame, stack = NULL, caller_pos = NULL) { if (is_integerish(frame)) { pos <- frame } else { stack <- stack %||% stack_trim(ctxt_stack(), n = 2) pos <- frame_position_global(frame, stack) } caller_pos <- caller_pos %||% call_frame(2)$pos caller_pos - pos + 1 } #' Trim top call layers from the evaluation stack #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' #' [ctxt_stack()] can be tricky to use in real code because all #' intervening frames are returned with the stack, including those at #' `ctxt_stack()` own call site. `stack_trim()` makes it easy to #' remove layers of intervening calls. #' #' #' @section Life cycle: #' #' These functions are deprecated and replaced by [trace_back()]. #' #' @param stack An evaluation stack. #' @param n The number of call frames (not eval frames) to trim off #' the top of the stack. In other words, the number of layers of #' intervening frames to trim. #' @export #' @keywords internal #' @examples #' # Intervening frames appear on the evaluation stack: #' identity(identity(ctxt_stack())) #' #' # stack_trim() will trim the first n layers of calls: #' stack_trim(identity(identity(ctxt_stack()))) #' #' # Note that it also takes care of calls intervening at its own call #' # site: #' identity(identity( #' stack_trim(identity(identity(ctxt_stack()))) #' )) #' #' # It is especially useful when used within a function that needs to #' # inspect the evaluation stack but should nonetheless be callable #' # within nested calls without side effects: #' stack_util <- function() { #' # n = 2 means that two layers of intervening calls should be #' # removed: The layer at ctxt_stack()'s call site (including the #' # stack_trim() call), and the layer at stack_util()'s call. #' stack <- stack_trim(ctxt_stack(), n = 2) #' stack #' } #' user_fn <- function() { #' # A user calls your stack utility with intervening frames: #' identity(identity(stack_util())) #' } #' # These intervening frames won't appear in the evaluation stack #' identity(user_fn()) stack_trim <- function(stack, n = 1) { warn_deprecated("`stack_trim()` is deprecated as of rlang 0.3.0.") if (n < 1) { return(stack) } # Add 1 to discard stack_trim()'s own intervening frames caller_pos <- call_frame(n + 1, clean = FALSE)$pos n_frames <- length(stack) n_skip <- n_frames - caller_pos stack[seq(n_skip, n_frames)] } # Tidy eval -------------------------------------------------------- #' Parse text into a quosure #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' #' These functions were deprecated and renamed to [parse_quo()] #' and [parse_quos()] in rlang 0.2.0. This is for consistency with the #' convention that suffixes indicating return types are not #' abbreviated. #' #' @inheritParams parse_expr #' @keywords internal #' @export parse_quosure <- function(x, env = caller_env()) { warn_deprecated(paste_line( "`parse_quosure()` is deprecated as of rlang 0.2.0.", "Please use `parse_quo()` instead." )) parse_quo(x, env = env) } #' @rdname parse_quosure #' @export parse_quosures <- function(x, env = caller_env()) { warn_deprecated(paste_line( "`parse_quosures()` is deprecated as of rlang 0.2.0.", "Please use `parse_quos()` instead." )) parse_quos(x, env = env) } #' Squash a quosure #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' #' This function is deprecated, please use [quo_squash()] instead. #' #' @inheritParams quo_squash #' @keywords internal #' @export quo_expr <- function(quo, warn = FALSE) { warn_deprecated(paste_line( "`quo_expr()` is deprecated as of rlang 0.2.0.", "Please use `quo_squash()` instead." )) quo_squash(quo, warn = warn) } #' Create an overscope #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' #' These functions have been deprecated in rlang 0.2.0. Please use #' [as_data_mask()] and [new_data_mask()] instead. We no longer #' require the mask to be cleaned up so `overscope_clean()` does not #' have a replacement. #' #' @inheritParams as_data_mask #' @param quo A [quosure][nse-defuse]. #' #' @keywords internal #' @export as_overscope <- function(quo, data = NULL) { warn_deprecated(paste_line( "`as_overscope()` is deprecated as of rlang 0.2.0.", "Please use `as_data_mask()` instead." )) as_data_mask(data) } #' @rdname as_overscope #' @param enclosure The `parent` argument of [new_data_mask()]. #' @export new_overscope <- function(bottom, top = NULL, enclosure = NULL) { warn_deprecated(paste_line( "`new_overscope()` is deprecated as of rlang 0.2.0.", "Please use `new_data_mask()` instead." )) new_data_mask(bottom, top, enclosure) } #' @rdname as_overscope #' @param overscope A data mask. #' @export overscope_clean <- function(overscope) { warn_deprecated("`overscope_clean()` is deprecated as of rlang 0.2.0.") invisible(.Call(rlang_data_mask_clean, overscope)) } #' Evaluate next quosure in a data mask #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' #' `overscope_eval_next()` is deprecated as of rlang 0.2.0. Please use #' `eval_tidy()` to which you can now supply an overscope. #' #' @param quo A quosure. #' @param overscope A valid overscope containing bindings for `~`, #' `.top_env` and `_F` and whose parents contain overscoped bindings #' for tidy evaluation. #' @param env The lexical enclosure in case `quo` is not a validly #' scoped quosure. This is the [base environment][base_env] by #' default. #' #' @keywords internal #' @export overscope_eval_next <- function(overscope, quo, env = base_env()) { warn_deprecated(paste_line( "`overscope_eval_next()` is deprecated as of rlang 0.2.0.", "Please use `eval_tidy()` with a data mask instead." )) .Call(rlang_eval_tidy, quo, overscope, env) } # Expressions ------------------------------------------------------ #' Create a call #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' #' These functions are deprecated, please use [call2()] and #' [new_call()] instead. #' #' @inheritParams call2 #' @keywords internal #' @export lang <- function(.fn, ..., .ns = NULL) { warn_deprecated(paste_line( "`lang()` is deprecated as of rlang 0.2.0.", "Please use `call2()` instead." )) call2(.fn, ..., .ns = .ns) } #' @rdname lang #' @inheritParams new_call #' @export new_language <- function(head, tail = NULL) { warn_deprecated(paste_line( "`new_language()` is deprecated as of rlang 0.2.0.", "Please use `new_call()` instead." )) new_call(head, tail) } #' Is object a call? #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' #' These functions are deprecated, please use [is_call()] and its `n` #' argument instead. #' #' @inheritParams is_call #' @keywords internal #' @export is_lang <- function(x, name = NULL, n = NULL, ns = NULL) { warn_deprecated(paste_line( "`is_lang()` is deprecated as of rlang 0.2.0.", "Please use `is_call()` instead." )) is_call(x, name, n, ns) } #' @rdname is_lang #' @export is_unary_lang <- function(x, name = NULL, ns = NULL) { warn_deprecated(paste_line( "`is_unary_lang()` is deprecated as of rlang 0.2.0.", "Please use `is_call()` instead." )) is_call(x, name, n = 1L, ns = ns) } #' @rdname is_lang #' @export is_binary_lang <- function(x, name = NULL, ns = NULL) { warn_deprecated(paste_line( "`is_binary_lang()` is deprecated as of rlang 0.2.0.", "Please use `is_call()` instead." )) is_call(x, name, n = 2L, ns = ns) } #' @rdname is_lang #' @param quo A quosure to test. #' @export quo_is_lang <- function(quo) { warn_deprecated(paste_line( "`quo_is_lang()` is deprecated as of rlang 0.2.0.", "Please use `quo_is_call()` instead." )) .Call(rlang_quo_is_call, quo) } #' Manipulate or access a call #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' #' These functions are deprecated, please use [call_modify()], #' [call_standardise()], or [call_fn()] instead. #' #' @inheritParams call_modify #' @param lang,.lang The `call` or `.call` argument of the renamed #' functions. #' @keywords internal #' @export lang_modify <- function(.lang, ..., .standardise = FALSE) { warn_deprecated(paste_line( "`lang_modify()` is deprecated as of rlang 0.2.0.", "Please use `call_modify()` instead." )) if (.standardise) { .lang <- call_standardise(.lang, caller_env()) } call_modify(.lang, ...) } #' @rdname lang_modify #' @export lang_standardise <- function(lang) { warn_deprecated(paste_line( "`lang_standardise()` is deprecated as of rlang 0.2.0.", "Please use `call_standardise()` instead." )) call_standardise(lang, env = caller_env()) } #' @rdname lang_modify #' @export lang_fn <- function(lang) { warn_deprecated(paste_line( "`lang_fn()` is deprecated as of rlang 0.2.0.", "Please use `call_fn()` instead." )) call_fn(lang, caller_env()) } #' @rdname lang_modify #' @export lang_name <- function(lang) { warn_deprecated(paste_line( "`lang_name()` is deprecated as of rlang 0.2.0.", "Please use `call_name()` instead." )) call_name(lang) } #' @rdname lang_modify #' @export lang_args <- function(lang) { warn_deprecated(paste_line( "`lang_args()` is deprecated as of rlang 0.2.0.", "Please use `call_args()` instead." )) call_args(lang) } #' @rdname lang_modify #' @export lang_args_names <- function(lang) { warn_deprecated(paste_line( "`lang_args_names()` is deprecated as of rlang 0.2.0.", "Please use `call_args_names()` instead." )) call_args_names(lang) } #' Return the head or tail of a call #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' #' As of rlang 0.2.0 these functions are retired (deprecated for now) #' because they are low level accessors that are rarely needed for end #' users. #' #' @param lang A call. #' @keywords internal #' @export lang_head <- function(lang) { warn_deprecated("`lang_head()` is deprecated as of rlang 0.2.0.") call <- get_expr(lang) stopifnot(is_call(call)) node_car(call) } #' @rdname lang_head #' @export lang_tail <- function(lang) { warn_deprecated("`lang_tail()` is deprecated as of rlang 0.2.0.") call <- get_expr(lang) stopifnot(is_call(call)) node_cdr(call) } #' Is an object an expression? #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' #' This function was deprecated and renamed to [is_expression()] in #' rlang 0.2.0. This is for consistency with other type predicates #' which are not abbreviated. #' #' @inheritParams is_expression #' @keywords internal #' @export is_expr <- function(x) { warn_deprecated(paste_line( "`is_expr()` is deprecated as of rlang 0.2.0.", "Please use `is_expression()` instead." )) is_expression(x) } # Nodes ------------------------------------------------------------ #' Mutate node components #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' #' These functions were deprecated and renamed with `node_poke_` #' prefix in rlang 0.2.0. This change follows a new naming convention #' where mutation is referred to as "poking". #' #' @inheritParams new_node #' #' @keywords internal #' @export mut_node_car <- function(x, newcar) { warn_deprecated("`mut_node_car()` is deprecated as of rlang 0.2.0.") invisible(.Call(rlang_node_poke_car, x, newcar)) } #' @rdname mut_node_car #' @export mut_node_cdr <- function(x, newcdr) { warn_deprecated("`mut_node_cdr()` is deprecated as of rlang 0.2.0.") invisible(.Call(rlang_node_poke_cdr, x, newcdr)) } #' @rdname mut_node_car #' @export mut_node_caar <- function(x, newcar) { warn_deprecated("`mut_node_caar()` is deprecated as of rlang 0.2.0.") invisible(.Call(rlang_node_poke_caar, x, newcar)) } #' @rdname mut_node_car #' @export mut_node_cadr <- function(x, newcar) { warn_deprecated("`mut_node_cadr()` is deprecated as of rlang 0.2.0.") invisible(.Call(rlang_node_poke_cadr, x, newcar)) } #' @rdname mut_node_car #' @export mut_node_cdar <- function(x, newcdr) { warn_deprecated("`mut_node_cdar()` is deprecated as of rlang 0.2.0.") invisible(.Call(rlang_node_poke_cdar, x, newcdr)) } #' @rdname mut_node_car #' @export mut_node_cddr <- function(x, newcdr) { warn_deprecated("`mut_node_cddr()` is deprecated as of rlang 0.2.0.") invisible(.Call(rlang_node_poke_cddr, x, newcdr)) } #' @rdname mut_node_car #' @export mut_node_tag <- function(x, newtag) { warn_deprecated("`mut_node_tag()` is deprecated as of rlang 0.2.0.") invisible(.Call(rlang_node_poke_tag, x, newtag)) } #' @rdname vector-old-ctors #' @export node <- function(car, cdr = NULL) { warn_deprecated(paste_line( "`node()` is deprecated as of rlang 0.2.0.", "Please use `new_node()` instead." )) new_node(car, cdr) } # Environments ----------------------------------------------------- #' Coerce to an environment #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' #' This function is deprecated as it was renamed to [as_environment()] #' in rlang 0.2.0. #' #' @keywords internal #' @export as_env <- function(x, parent = NULL) { warn_deprecated("`as_env()` is deprecated as of rlang 0.2.0.") as_environment(x, parent) } #' Is an object an environment? #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' #' These functions were deprecated and renamed to [is_environment()] #' and [is_bare_environment()] in rlang 0.2.0. This is for consistency #' with other type predicates which are not abbreviated. #' #' @inheritParams is_environment #' @keywords internal #' @export is_env <- function(x) { warn_deprecated(paste_line( "`is_env()` is deprecated as of rlang 0.2.0.", "Please use `is_environment()` instead." )) is_environment(x) } #' @rdname is_env #' @export is_bare_env <- function(x) { warn_deprecated(paste_line( "`is_bare_env()` is deprecated as of rlang 0.2.0.", "Please use `is_bare_environment()` instead." )) is_bare_environment(x) } #' Bind a promise or active binding #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' #' As of rlang 0.3.0, `env_bind_exprs()` and `env_bind_fns()` have #' been renamed to [env_bind_lazy()] and [env_bind_active()] for #' consistency. #' #' @inheritParams env_bind #' #' @keywords internal #' @export env_bind_exprs <- function(.env, ..., .eval_env = caller_env()) { warn_deprecated(paste_line( "`env_bind_exprs()` is deprecated as of rlang 0.3.0.", "Please use `env_bind_lazy()` instead." )) env_bind_lazy(.env = .env, ..., .eval_env = .eval_env) } #' @rdname env_bind_exprs #' @export env_bind_fns <- function(.env, ...) { warn_deprecated(paste_line( "`env_bind_fns()` is deprecated as of rlang 0.3.0.", "Please use `env_bind_active()` instead." )) env_bind_active(.env = .env, ...) } #' Retired `scoped` functions #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' #' These functions are deprecated as of rlang 0.3.0. They are replaced #' by [is_attached()], ... #' #' @param nm The name of an environment attached to the search #' path. Call [base::search()] to see what is currently on the path. #' #' @keywords internal #' @export scoped_env <- function(nm) { warn_deprecated(paste_line( "`scoped_env()` is deprecated as of rlang 0.3.0.", "Please use `search_env()` instead." )) local_options(lifecycle_disable_warnings = TRUE) if (identical(nm, "NULL")) { return(empty_env()) } if (!is_scoped(nm)) { stop(paste0(nm, " is not in scope"), call. = FALSE) } as.environment(nm) } #' @rdname scoped_env #' @export is_scoped <- function(nm) { warn_deprecated(paste_line( "`is_scoped()` is deprecated as of rlang 0.3.0.", "Please use `is_attached()` instead." )) local_options(lifecycle_disable_warnings = TRUE) if (!is_scalar_character(nm)) { stop("`nm` must be a string", call. = FALSE) } nm %in% scoped_names() } #' @rdname scoped_env #' @export scoped_envs <- function() { warn_deprecated(paste_line( "`scoped_envs()` is deprecated as of rlang 0.3.0.", "Please use `search_envs()` instead." )) local_options(lifecycle_disable_warnings = TRUE) envs <- c(list(.GlobalEnv), env_parents(.GlobalEnv)) set_names(envs, scoped_names()) } #' @rdname scoped_env #' @export scoped_names <- function() { warn_deprecated(paste_line( "`scoped_names()` is deprecated as of rlang 0.3.0.", "Please use `base::search()` instead." )) c(search(), "NULL") } # Vectors ---------------------------------------------------------- #' Retired vector construction by length #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' #' These functions were deprecated and renamed with `new_` prefix in #' rlang 0.2.0. This is for consistency with other non-variadic object #' constructors. #' #' @param .x A vector. #' @inheritParams new-vector #' @inheritParams new-vector-along-retired #' @name vector-old-ctors #' @keywords internal NULL #' @rdname vector-old-ctors #' @export lgl_len <- function(.n) { warn_deprecated(paste_line( "`lgl_len()` is deprecated as of rlang 0.2.0.", "Please use `new_logical()` instead." )) new_logical(.n) } #' @rdname vector-old-ctors #' @export int_len <- function(.n) { warn_deprecated(paste_line( "`int_len()` is deprecated as of rlang 0.2.0.", "Please use `new_integer()` instead." )) new_integer(.n) } #' @rdname vector-old-ctors #' @export dbl_len <- function(.n) { warn_deprecated(paste_line( "`dbl_len()` is deprecated as of rlang 0.2.0.", "Please use `new_double()` instead." )) new_double(.n) } #' @rdname vector-old-ctors #' @export chr_len <- function(.n) { warn_deprecated(paste_line( "`chr_len()` is deprecated as of rlang 0.2.0.", "Please use `new_character()` instead." )) new_character(.n) } #' @rdname vector-old-ctors #' @export cpl_len <- function(.n) { warn_deprecated(paste_line( "`cpl_len()` is deprecated as of rlang 0.2.0.", "Please use `new_complex()` instead." )) new_complex(.n) } #' @rdname vector-old-ctors #' @export raw_len <- function(.n) { warn_deprecated(paste_line( "`raw_len()` is deprecated as of rlang 0.2.0.", "Please use `new_raw()` instead." )) new_raw(.n) } #' @rdname vector-old-ctors #' @export bytes_len <- function(.n) { warn_deprecated(paste_line( "`bytes_len()` is deprecated as of rlang 0.2.0.", "Please use `new_raw()` instead." )) new_raw(.n) } #' @rdname vector-old-ctors #' @export list_len <- function(.n) { warn_deprecated(paste_line( "`list_len()` is deprecated as of rlang 0.2.0.", "Please use `new_list()` instead." )) new_list(.n) } #' @rdname vector-old-ctors #' @export lgl_along <- function(.x) { warn_deprecated("`lgl_along()` is deprecated as of rlang 0.2.0.") local_options(lifecycle_disable_warnings = TRUE) new_logical_along(.x, NULL) } #' @rdname vector-old-ctors #' @export int_along <- function(.x) { warn_deprecated("`int_along()` is deprecated as of rlang 0.2.0.") local_options(lifecycle_disable_warnings = TRUE) new_integer_along(.x, NULL) } #' @rdname vector-old-ctors #' @export dbl_along <- function(.x) { warn_deprecated("`dbl_along()` is deprecated as of rlang 0.2.0.") local_options(lifecycle_disable_warnings = TRUE) new_double_along(.x, NULL) } #' @rdname vector-old-ctors #' @export chr_along <- function(.x) { warn_deprecated("`chr_along()` is deprecated as of rlang 0.2.0.") local_options(lifecycle_disable_warnings = TRUE) new_character_along(.x, NULL) } #' @rdname vector-old-ctors #' @export cpl_along <- function(.x) { warn_deprecated("`cpl_along()` is deprecated as of rlang 0.2.0.") local_options(lifecycle_disable_warnings = TRUE) new_complex_along(.x, NULL) } #' @rdname vector-old-ctors #' @export raw_along <- function(.x) { warn_deprecated("`raw_along()` is deprecated as of rlang 0.2.0.") local_options(lifecycle_disable_warnings = TRUE) new_raw_along(.x, NULL) } #' @rdname vector-old-ctors #' @export bytes_along <- function(.x) { warn_deprecated("`bytes_along()` is deprecated as of rlang 0.2.0.") local_options(lifecycle_disable_warnings = TRUE) new_raw_along(.x, NULL) } #' @rdname vector-old-ctors #' @export list_along <- function(.x) { warn_deprecated("`list_along()` is deprecated as of rlang 0.2.0.") local_options(lifecycle_disable_warnings = TRUE) new_list_along(.x, NULL) } #' Create vectors matching the length of a given vector #' #' These functions are deprecated as of rlang 0.3.0 because they #' are longer to type than the equivalent [rep_along()] or #' [rep_named()] calls without added clarity. #' #' @param x A vector. #' @param names Names for the new vector. #' @name new-vector-along-retired #' @keywords internal #' @export #' @rdname new-vector-along-retired new_logical_along <- function(x, names = base::names(x)) { warn_deprecated_along("logical", "NA") set_names_impl(rep_len(na_lgl, length(x)), x, names) } #' @export #' @rdname new-vector-along-retired new_integer_along <- function(x, names = base::names(x)) { warn_deprecated_along("integer", "na_int") set_names_impl(rep_len(na_int, length(x)), x, names) } #' @export #' @rdname new-vector-along-retired new_double_along <- function(x, names = base::names(x)) { warn_deprecated_along("double", "na_dbl") set_names_impl(rep_len(na_dbl, length(x)), x, names) } #' @export #' @rdname new-vector-along-retired new_character_along <- function(x, names = base::names(x)) { warn_deprecated_along("character", "na_chr") set_names_impl(rep_len(na_chr, length(x)), x, names) } #' @export #' @rdname new-vector-along-retired new_complex_along <- function(x, names = base::names(x)) { warn_deprecated_along("complex", "na_cpl") set_names_impl(rep_len(na_cpl, length(x)), x, names) } #' @export #' @rdname new-vector-along-retired new_raw_along <- function(x, names = base::names(x)) { warn_deprecated_along("raw", "new_raw(1)") set_names_impl(vector("raw", length(x)), x, names) } #' @export #' @rdname new-vector-along-retired new_list_along <- function(x, names = base::names(x)) { warn_deprecated_along("list", "list(NULL)") set_names_impl(vector("list", length(x)), x, names) } warn_deprecated_along <- function(type, na) { warn_deprecated(paste_line( sprintf("`new_%s_along()` is deprecated as of rlang 0.3.0.", type), sprintf("Please use `rep_along(x, %s)` or `rep_named(nms, %s)` instead.", na, na) )) } #' Prepend a vector #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' #' Vector functions are now out of scope for rlang. They might be #' revived in the vctrs or funs packages. #' #' #' @keywords internal #' #' @param x the vector to be modified. #' @param values to be included in the modified vector. #' @param before a subscript, before which the values are to be appended. #' @export prepend <- function(x, values, before = 1) { warn_deprecated_vector("prepend") n <- length(x) stopifnot(before > 0 && before <= n) if (before == 1) { c(values, x) } else { c(x[1:(before - 1)], values, x[before:n]) } } #' @rdname prepend #' @param .x A vector to modify. #' @param ... <[dynamic][dyn-dots]> List of elements to merge into #' `.x`. Named elements already existing in `.x` are used as #' replacements. Elements that have new or no names are inserted at #' the end. #' @export modify <- function(.x, ...) { warn_deprecated_vector("modify") out <- as.list(.x) args <- list2(...) args_nms <- names(args) exists <- have_name(args) & args_nms %in% names(out) for (nm in args_nms[exists]) { out[[nm]] <- args[[nm]] } c(out, args[!exists]) } warn_deprecated_vector <- function(fn) { warn_deprecated(paste_line( sprintf("`%s()` is deprecated as of rlang 0.4.0.", fn), "", "Vector tools are now out of scope for rlang to make it a more", "focused package." )) } # Attributes ------------------------------------------------------- #' Add attributes to an object #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("deprecated")} #' #' `set_attrs()` adds, changes, or zaps attributes of objects. Pass a #' single unnamed `NULL` argument to zap all attributes. For #' [uncopyable][is_copyable] types, use `mut_attrs()`. #' #' @details #' #' Unlike [structure()], these setters have no special handling of #' internal attributes names like `.Dim`, `.Dimnames` or `.Names`. #' #' #' @section Life cycle: #' #' These functions are deprecated since rlang 0.3.0. #' #' @param .x An object to decorate with attributes. #' @param ... <[dynamic][dyn-dots]> A list of named attributes. Pass #' a single unnamed `NULL` argument to zap all attributes from `.x`. #' @return `set_attrs()` returns a modified [shallow copy][duplicate] #' of `.x`. `mut_attrs()` invisibly returns the original `.x` #' modified in place. #' #' @keywords internal #' @export #' @examples #' set_attrs(letters, names = 1:26, class = "my_chr") #' #' # Splice a list of attributes: #' attrs <- list(attr = "attr", names = 1:26, class = "my_chr") #' obj <- set_attrs(letters, splice(attrs)) #' obj #' #' # Zap attributes by passing a single unnamed NULL argument: #' set_attrs(obj, NULL) #' set_attrs(obj, !!! list(NULL)) #' #' # Note that set_attrs() never modifies objects in place: #' obj #' #' # For uncopyable types, mut_attrs() lets you modify in place: #' env <- env() #' mut_attrs(env, foo = "bar") #' env set_attrs <- function(.x, ...) { warn_deprecated("`set_attrs()` is deprecated as of rlang 0.3.0") if (!is_copyable(.x)) { abort("`.x` is uncopyable: use `mut_attrs()` to change attributes in place") } set_attrs_impl(.x, ...) } #' @rdname set_attrs #' @export mut_attrs <- function(.x, ...) { warn_deprecated("`set_attrs()` is deprecated as of rlang 0.3.0") if (is_copyable(.x)) { abort("`.x` is copyable: use `set_attrs()` to change attributes without side effect") } invisible(set_attrs_impl(.x, ...)) } set_attrs_impl <- function(.x, ...) { attrs <- dots_list(...) # If passed a single unnamed NULL, zap attributes if (identical(attrs, set_attrs_null)) { attributes(.x) <- NULL } else { attributes(.x) <- c(attributes(.x), attrs) } .x } set_attrs_null <- list(NULL) names(set_attrs_null) <- "" # Conditions -------------------------------------------------------- #' Exiting handler #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("soft-deprecated")} #' #' `exiting()` is no longer necessary as handlers are exiting by default. #' #' @keywords internal #' @export exiting <- function(handler) { signal_soft_deprecated(c( "`exiting()` is soft-deprecated as of rlang 0.4.0.", "Handlers are now treated as exiting by default." )) handler <- as_function(handler) structure(handler, class = c("rlang_handler_exiting", "rlang_handler", "function")) } # Scoped_ #' Questioning `scoped_` functions #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} #' #' These functions have been renamed to use the conventional `local_` #' prefix. They will be deprecated in the next minor version of rlang. #' #' @inheritParams local_interactive #' @inheritParams local_options #' @inheritParams local_bindings #' #' @export scoped_interactive <- function(value = TRUE, frame = caller_env()) { local_interactive(value = value, frame = frame) } #' @rdname scoped_interactive #' @export scoped_options <- function(..., .frame = caller_env()) { local_options(..., .frame = .frame) } #' @rdname scoped_interactive #' @export scoped_bindings <- function(..., .env = .frame, .frame = caller_env()) { local_bindings(..., .env = .env, .frame = .frame) } rlang/R/eval.R0000644000176200001440000002552413563532021012640 0ustar liggesusers#' Evaluate an expression in an environment #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("stable")} #' #' `eval_bare()` is a lower-level version of function [base::eval()]. #' Technically, it is a simple wrapper around the C function #' `Rf_eval()`. You generally don't need to use `eval_bare()` instead #' of `eval()`. Its main advantage is that it handles stack-sensitive #' (calls such as `return()`, `on.exit()` or `parent.frame()`) more #' consistently when you pass an enviroment of a frame on the call #' stack. #' #' @details #' #' These semantics are possible because `eval_bare()` creates only one #' frame on the call stack whereas `eval()` creates two frames, the #' second of which has the user-supplied environment as frame #' environment. When you supply an existing frame environment to #' `base::eval()` there will be two frames on the stack with the same #' frame environment. Stack-sensitive functions only detect the #' topmost of these frames. We call these evaluation semantics #' "stack inconsistent". #' #' Evaluating expressions in the actual frame environment has useful #' practical implications for `eval_bare()`: #' #' * `return()` calls are evaluated in frame environments that might #' be burried deep in the call stack. This causes a long return that #' unwinds multiple frames (triggering the `on.exit()` event for #' each frame). By contrast `eval()` only returns from the `eval()` #' call, one level up. #' #' * `on.exit()`, `parent.frame()`, `sys.call()`, and generally all #' the stack inspection functions `sys.xxx()` are evaluated in the #' correct frame environment. This is similar to how this type of #' calls can be evaluated deep in the call stack because of lazy #' evaluation, when you force an argument that has been passed #' around several times. #' #' The flip side of the semantics of `eval_bare()` is that it can't #' evaluate `break` or `next` expressions even if called within a #' loop. #' #' #' @param expr An expression to evaluate. #' @param env The environment in which to evaluate the expression. #' #' @seealso [eval_tidy()] for evaluation with data mask and quosure #' support. #' @export #' @examples #' # eval_bare() works just like base::eval() but you have to create #' # the evaluation environment yourself: #' eval_bare(quote(foo), env(foo = "bar")) #' #' # eval() has different evaluation semantics than eval_bare(). It #' # can return from the supplied environment even if its an #' # environment that is not on the call stack (i.e. because you've #' # created it yourself). The following would trigger an error with #' # eval_bare(): #' ret <- quote(return("foo")) #' eval(ret, env()) #' # eval_bare(ret, env()) # "no function to return from" error #' #' # Another feature of eval() is that you can control surround loops: #' bail <- quote(break) #' while (TRUE) { #' eval(bail) #' # eval_bare(bail) # "no loop for break/next" error #' } #' #' # To explore the consequences of stack inconsistent semantics, let's #' # create a function that evaluates `parent.frame()` deep in the call #' # stack, in an environment corresponding to a frame in the middle of #' # the stack. For consistency with R's lazy evaluation semantics, we'd #' # expect to get the caller of that frame as result: #' fn <- function(eval_fn) { #' list( #' returned_env = middle(eval_fn), #' actual_env = current_env() #' ) #' } #' middle <- function(eval_fn) { #' deep(eval_fn, current_env()) #' } #' deep <- function(eval_fn, eval_env) { #' expr <- quote(parent.frame()) #' eval_fn(expr, eval_env) #' } #' #' # With eval_bare(), we do get the expected environment: #' fn(rlang::eval_bare) #' #' # But that's not the case with base::eval(): #' fn(base::eval) eval_bare <- function(expr, env = parent.frame()) { .Call(rlang_eval, expr, env) } #' Evaluate an expression within a given environment #' #' These functions evaluate `expr` within a given environment (`env` #' for `with_env()`, or the child of the current environment for #' `locally`). They rely on [eval_bare()] which features a lighter #' evaluation mechanism than base R [base::eval()], and which also has #' some subtle implications when evaluting stack sensitive functions #' (see help for [eval_bare()]). #' #' `locally()` is equivalent to the base function #' [base::local()] but it produces a much cleaner #' evaluation stack, and has stack-consistent semantics. It is thus #' more suited for experimenting with the R language. #' #' #' @section Life cycle: #' #' These functions are experimental. Expect API changes. #' #' #' @inheritParams eval_bare #' @param env An environment within which to evaluate `expr`. Can be #' an object with a [get_env()] method. #' @keywords internal #' @export #' @examples #' # with_env() is handy to create formulas with a given environment: #' env <- child_env("rlang") #' f <- with_env(env, ~new_formula()) #' identical(f_env(f), env) #' #' # Or functions with a given enclosure: #' fn <- with_env(env, function() NULL) #' identical(get_env(fn), env) #' #' #' # Unlike eval() it doesn't create duplicates on the evaluation #' # stack. You can thus use it e.g. to create non-local returns: #' fn <- function() { #' g(current_env()) #' "normal return" #' } #' g <- function(env) { #' with_env(env, return("early return")) #' } #' fn() #' #' #' # Since env is passed to as_environment(), it can be any object with an #' # as_environment() method. For strings, the pkg_env() is returned: #' with_env("base", ~mtcars) #' #' # This can be handy to put dictionaries in scope: #' with_env(mtcars, cyl) with_env <- function(env, expr) { .Call(rlang_eval, substitute(expr), as_environment(env, caller_env())) } #' @rdname with_env #' @export locally <- function(expr) { .Call(rlang_eval, substitute(expr), child_env(caller_env())) } #' Invoke a function with a list of arguments #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("soft-deprecated")} #' #' Normally, you invoke a R function by typing arguments manually. A #' powerful alternative is to call a function with a list of arguments #' assembled programmatically. This is the purpose of `invoke()`. #' #' @details #' #' Technically, `invoke()` is basically a version of [base::do.call()] #' that creates cleaner call traces because it does not inline the #' function and the arguments in the call (see examples). To achieve #' this, `invoke()` creates a child environment of `.env` with `.fn` #' and all arguments bound to new symbols (see [env_bury()]). It then #' uses the same strategy as [eval_bare()] to evaluate with minimal #' noise. #' #' #' @section Life cycle: #' #' `invoke()` is soft-deprecated in favour of [exec()]. Now that we #' understand better the interaction between unquoting and dots #' capture, we can take a simpler approach in `exec()`. #' #' If you need finer control over the generated call, you should construct #' an environment and call yourself, manually burying large objects #' or complex expressions. #' #' @param .fn A function to invoke. Can be a function object or the #' name of a function in scope of `.env`. #' @param .args,... List of arguments (possibly named) to be passed to #' `.fn`. #' @param .env The environment in which to call `.fn`. #' @param .bury A character vector of length 2. The first string #' specifies which name should the function have in the call #' recorded in the evaluation stack. The second string specifies a #' prefix for the argument names. Set `.bury` to `NULL` if you #' prefer to inline the function and its arguments in the call. #' @export #' @keywords internal #' @examples #' # invoke() has the same purpose as do.call(): #' invoke(paste, letters) #' #' # But it creates much cleaner calls: #' invoke(call_inspect, mtcars) #' #' # and stacktraces: #' fn <- function(...) sys.calls() #' invoke(fn, list(mtcars)) #' #' # Compare to do.call(): #' do.call(call_inspect, mtcars) #' do.call(fn, list(mtcars)) #' #' #' # Specify the function name either by supplying a string #' # identifying the function (it should be visible in .env): #' invoke("call_inspect", letters) #' #' # Or by changing the .bury argument, with which you can also change #' # the argument prefix: #' invoke(call_inspect, mtcars, .bury = c("inspect!", "col")) invoke <- function(.fn, .args = list(), ..., .env = caller_env(), .bury = c(".fn", "")) { signal_soft_deprecated(c( "`invoke()` is deprecated as of rlang 0.4.0.", "Please use `exec()` or `eval(expr())`instead." )) args <- c(.args, list(...)) if (is_null(.bury) || !length(args)) { if (is_scalar_character(.fn)) { .fn <- env_get(.env, .fn, inherit = TRUE) } call <- call2(.fn, !!! args) return(.Call(rlang_eval, call, .env)) } if (!is_character(.bury, 2L)) { abort("`.bury` must be a character vector of length 2") } arg_prefix <- .bury[[2]] fn_nm <- .bury[[1]] buried_nms <- paste0(arg_prefix, seq_along(args)) buried_args <- set_names(args, buried_nms) .env <- env_bury(.env, !!! buried_args) args <- set_names(buried_nms, names(args)) args <- syms(args) if (is_function(.fn)) { env_bind(.env, !! fn_nm := .fn) .fn <- fn_nm } call <- call2(.fn, !!! args) .Call(rlang_eval, call, .env) } value <- function(expr) { eval_bare(enexpr(expr), caller_env()) } eval_top <- function(expr, env = caller_env()) { .Call(rlang_eval_top, expr, env) } #' Execute a function #' #' @description #' #' This function constructs and evaluates a call to `.fn`. #' It has two primary uses: #' #' * To call a function with arguments stored in a list (if the #' function doesn't support [dynamic dots][dyn-dots]). Splice the #' list of arguments with `!!!`. #' #' * To call every function stored in a list (in conjunction with `map()`/ #' [lapply()]) #' #' @param .fn A function, or function name as a string. #' @param ... <[dynamic][dyn-dots]> Arguments for `.fn`. #' @param .env Environment in which to evaluate the call. This will be #' most useful if `f` is a string, or the function has side-effects. #' @export #' @examples #' args <- list(x = c(1:10, 100, NA), na.rm = TRUE) #' exec("mean", !!!args) #' exec("mean", !!!args, trim = 0.2) #' #' fs <- list(a = function() "a", b = function() "b") #' lapply(fs, exec) #' #' # Compare to do.call it will not automatically inline expressions #' # into the evaluated call. #' x <- 10 #' args <- exprs(x1 = x + 1, x2 = x * 2) #' exec(list, !!!args) #' do.call(list, args) #' #' # exec() is not designed to generate pretty function calls. This is #' # most easily seen if you call a function that captures the call: #' f <- disp ~ cyl #' exec("lm", f, data = mtcars) #' #' # If you need finer control over the generated call, you'll need to #' # construct it yourself. This may require creating a new environment #' # with carefully constructed bindings #' data_env <- env(data = mtcars) #' eval(expr(lm(!!f, data)), data_env) exec <- function(.fn, ..., .env = caller_env()) { .External2(rlang_exec, .fn, .env) } rlang/R/arg.R0000644000176200001440000001440713461060535012463 0ustar liggesusers#' Match an argument to a character vector #' #' @description #' #' This is equivalent to [base::match.arg()] with a few differences: #' #' * Partial matches trigger an error. #' #' * Error messages are a bit more informative and obey the tidyverse #' standards. #' #' @param arg A symbol referring to an argument accepting strings. #' @param values The possible values that `arg` can take. If `NULL`, #' the values are taken from the function definition of the [caller #' frame][caller_frame]. #' @return The string supplied to `arg`. #' @export #' @examples #' fn <- function(x = c("foo", "bar")) arg_match(x) #' fn("bar") #' #' # This would throw an informative error if run: #' # fn("b") #' # fn("baz") arg_match <- function(arg, values = NULL) { arg_expr <- enexpr(arg) if (!is_symbol(arg_expr)) { abort("Internal error: `arg_match()` expects a symbol") } arg_nm <- as_string(arg_expr) if (is_null(values)) { fn <- caller_fn() values <- fn_fmls(fn)[[arg_nm]] values <- eval_bare(values, get_env(fn)) } if (!is_character(values)) { abort("Internal error: `values` must be a character vector") } if (!is_character(arg)) { abort(paste0(chr_quoted(arg_nm), " must be a character vector")) } arg <- arg[[1]] i <- match(arg, values) if (is_na(i)) { msg <- paste0(chr_quoted(arg_nm), " must be one of ") msg <- paste0(msg, chr_enumerate(chr_quoted(values, "\""))) i_partial <- pmatch(arg, values) if (!is_na(i_partial)) { candidate <- values[[i_partial]] candidate <- chr_quoted(candidate, "\"") msg <- paste0(msg, "\n", "Did you mean ", candidate, "?") } abort(msg) } values[[i]] } chr_quoted <- function(chr, type = "`") { paste0(type, chr, type) } chr_enumerate <- function(chr, sep = ", ", final = "or") { n <- length(chr) if (n < 2) { return(chr) } n <- length(chr) head <- chr[seq_len(n - 1)] last <- chr[length(chr)] head <- paste(head, collapse = sep) # Write a or b. But a, b, or c. if (n > 2) { paste0(head, sep, final, " ", last) } else { paste0(head, " ", final, " ", last) } } #' Generate or handle a missing argument #' #' @description #' #' These functions help using the missing argument as a regular R #' object. #' #' * `missing_arg()` generates a missing argument. #' #' * `is_missing()` is like [base::missing()] but also supports #' testing for missing arguments contained in other objects like #' lists. #' #' * `maybe_missing()` is useful to pass down an input that might be #' missing to another function, potentially substituting by a #' default value. It avoids triggering an "argument is missing" error. #' #' #' @section Other ways to reify the missing argument: #' #' * `base::quote(expr = )` is the canonical way to create a missing #' argument object. #' #' * `expr()` called without argument creates a missing argument. #' #' * `quo()` called without argument creates an empty quosure, i.e. a #' quosure containing the missing argument object. #' #' #' @section Fragility of the missing argument object: #' #' The missing argument is an object that triggers an error if and #' only if it is the result of evaluating a symbol. No error is #' produced when a function call evaluates to the missing argument #' object. This means that expressions like `x[[1]] <- missing_arg()` #' are perfectly safe. Likewise, `x[[1]]` is safe even if the result #' is the missing object. #' #' However, as soon as the missing argument is passed down between #' functions through an argument, you're at risk of triggering a #' missing error. This is because arguments are passed through #' symbols. To work around this, `is_missing()` and `maybe_missing(x)` #' use a bit of magic to determine if the input is the missing #' argument without triggering a missing error. #' #' `maybe_missing()` is particularly useful for prototyping #' meta-programming algorithms in R. The missing argument is a likely #' input when computing on the language because it is a standard #' object in formals lists. While C functions are always allowed to #' return the missing argument and pass it to other C functions, this #' is not the case on the R side. If you're implementing your #' meta-programming algorithm in R, use `maybe_missing()` when an #' input might be the missing argument object. #' #' #' @section Life cycle: #' #' * `missing_arg()` and `is_missing()` are stable. #' * Like the rest of rlang, `maybe_missing()` is maturing. #' #' @param x An object that might be the missing argument. #' @export #' @examples #' # The missing argument usually arises inside a function when the #' # user omits an argument that does not have a default: #' fn <- function(x) is_missing(x) #' fn() #' #' # Creating a missing argument can also be useful to generate calls #' args <- list(1, missing_arg(), 3, missing_arg()) #' quo(fn(!!! args)) #' #' # Other ways to create that object include: #' quote(expr = ) #' expr() #' #' # It is perfectly valid to generate and assign the missing #' # argument in a list. #' x <- missing_arg() #' l <- list(missing_arg()) #' #' # Just don't evaluate a symbol that contains the empty argument. #' # Evaluating the object `x` that we created above would trigger an #' # error. #' # x # Not run #' #' # On the other hand accessing a missing argument contained in a #' # list does not trigger an error because subsetting is a function #' # call: #' l[[1]] #' is.null(l[[1]]) #' #' # In case you really need to access a symbol that might contain the #' # empty argument object, use maybe_missing(): #' maybe_missing(x) #' is.null(maybe_missing(x)) #' is_missing(maybe_missing(x)) #' #' #' # Note that base::missing() only works on symbols and does not #' # support complex expressions. For this reason the following lines #' # would throw an error: #' #' #> missing(missing_arg()) #' #> missing(l[[1]]) #' #' # while is_missing() will work as expected: #' is_missing(missing_arg()) #' is_missing(l[[1]]) missing_arg <- function() { .Call(rlang_missing_arg) } #' @rdname missing_arg #' @export is_missing <- function(x) { .External2(rlang_is_missing, missing(x)) } #' @rdname missing_arg #' @param default The object to return if the input is missing, #' defaults to `missing_arg()`. #' @export maybe_missing <- function(x, default = missing_arg()) { if (is_missing(x)) { default } else { x } } rlang/R/env.R0000644000176200001440000005366713563531636012525 0ustar liggesusers#' Create a new environment #' #' @description #' #' These functions create new environments. #' #' * `env()` creates a child of the current environment by default #' and takes a variable number of named objects to populate it. #' #' * `new_environment()` creates a child of the empty environment by #' default and takes a named list of objects to populate it. #' #' #' @section Environments as objects: #' #' Environments are containers of uniquely named objects. Their most #' common use is to provide a scope for the evaluation of R #' expressions. Not all languages have first class environments, #' i.e. can manipulate scope as regular objects. Reification of scope #' is one of the most powerful features of R as it allows you to change #' what objects a function or expression sees when it is evaluated. #' #' Environments also constitute a data structure in their own #' right. They are a collection of uniquely named objects, subsettable #' by name and modifiable by reference. This latter property (see #' section on reference semantics) is especially useful for creating #' mutable OO systems (cf the [R6 package](https://github.com/wch/R6) #' and the [ggproto #' system](http://ggplot2.tidyverse.org/articles/extending-ggplot2.html) #' for extending ggplot2). #' #' #' @section Inheritance: #' #' All R environments (except the [empty environment][empty_env]) are #' defined with a parent environment. An environment and its #' grandparents thus form a linear hierarchy that is the basis for #' [lexical #' scoping](https://en.wikipedia.org/wiki/Scope_(computer_science)) in #' R. When R evaluates an expression, it looks up symbols in a given #' environment. If it cannot find these symbols there, it keeps #' looking them up in parent environments. This way, objects defined #' in child environments have precedence over objects defined in #' parent environments. #' #' The ability of overriding specific definitions is used in the #' tidyeval framework to create powerful domain-specific grammars. A #' common use of masking is to put data frame columns in scope. See #' for example [as_data_mask()]. #' #' #' @section Reference semantics: #' #' Unlike regular objects such as vectors, environments are an #' [uncopyable][is_copyable()] object type. This means that if you #' have multiple references to a given environment (by assigning the #' environment to another symbol with `<-` or passing the environment #' as argument to a function), modifying the bindings of one of those #' references changes all other references as well. #' #' #' @section Life cycle: #' #' - `child_env()` is in the questioning stage. It is redundant now #' that `env()` accepts parent environments. #' #' @param ...,data <[dynamic][dyn-dots]> Named values. You can #' supply one unnamed to specify a custom parent, otherwise it #' defaults to the current environment. #' @param .parent,parent A parent environment. Can be an object #' supported by [as_environment()]. #' @seealso [env_has()], [env_bind()]. #' @export #' @examples #' # env() creates a new environment which has the current environment #' # as parent #' env <- env(a = 1, b = "foo") #' env$b #' identical(env_parent(env), current_env()) #' #' # Supply one unnamed argument to override the default: #' env <- env(base_env(), a = 1, b = "foo") #' identical(env_parent(env), base_env()) #' #' #' # child_env() lets you specify a parent: #' child <- child_env(env, c = "bar") #' identical(env_parent(child), env) #' #' # This child environment owns `c` but inherits `a` and `b` from `env`: #' env_has(child, c("a", "b", "c", "d")) #' env_has(child, c("a", "b", "c", "d"), inherit = TRUE) #' #' # `parent` is passed to as_environment() to provide handy #' # shortcuts. Pass a string to create a child of a package #' # environment: #' child_env("rlang") #' env_parent(child_env("rlang")) #' #' # Or `NULL` to create a child of the empty environment: #' child_env(NULL) #' env_parent(child_env(NULL)) #' #' # The base package environment is often a good default choice for a #' # parent environment because it contains all standard base #' # functions. Also note that it will never inherit from other loaded #' # package environments since R keeps the base package at the tail #' # of the search path: #' base_child <- child_env("base") #' env_has(base_child, c("lapply", "("), inherit = TRUE) #' #' # On the other hand, a child of the empty environment doesn't even #' # see a definition for `(` #' empty_child <- child_env(NULL) #' env_has(empty_child, c("lapply", "("), inherit = TRUE) #' #' # Note that all other package environments inherit from base_env() #' # as well: #' rlang_child <- child_env("rlang") #' env_has(rlang_child, "env", inherit = TRUE) # rlang function #' env_has(rlang_child, "lapply", inherit = TRUE) # base function #' #' #' # Both env() and child_env() support tidy dots features: #' objs <- list(b = "foo", c = "bar") #' env <- env(a = 1, !!! objs) #' env$c #' #' # You can also unquote names with the definition operator `:=` #' var <- "a" #' env <- env(!!var := "A") #' env$a #' #' #' # Use new_environment() to create containers with the empty #' # environment as parent: #' env <- new_environment() #' env_parent(env) #' #' # Like other new_ constructors, it takes an object rather than dots: #' new_environment(list(a = "foo", b = "bar")) env <- function(...) { dots <- dots_split(..., .n_unnamed = 0:1) if (length(dots$unnamed)) { parent <- dots$unnamed[[1]] } else { parent = caller_env() } env <- new.env(parent = parent) env_bind_impl(env, dots$named) env } #' @rdname env #' @export child_env <- function(.parent, ...) { env <- new.env(parent = as_environment(.parent)) env_bind_impl(env, list2(...)) env } #' @rdname env #' @export new_environment <- function(data = list(), parent = empty_env()) { env <- new.env(parent = parent) env_bind_impl(env, data) env } #' Coerce to an environment #' #' `as_environment()` coerces named vectors (including lists) to an #' environment. The names must be unique. If supplied an unnamed #' string, it returns the corresponding package environment (see #' [pkg_env()]). #' #' If `x` is an environment and `parent` is not `NULL`, the #' environment is duplicated before being set a new parent. The return #' value is therefore a different environment than `x`. #' #' #' @section Life cycle: #' #' `as_env()` was soft-deprecated and renamed to `as_environment()` in #' rlang 0.2.0. This is for consistency as type predicates should not #' be abbreviated. #' #' @param x An object to coerce. #' @param parent A parent environment, [empty_env()] by default. This #' argument is only used when `x` is data actually coerced to an #' environment (as opposed to data representing an environment, like #' `NULL` representing the empty environment). #' @export #' @examples #' # Coerce a named vector to an environment: #' env <- as_environment(mtcars) #' #' # By default it gets the empty environment as parent: #' identical(env_parent(env), empty_env()) #' #' #' # With strings it is a handy shortcut for pkg_env(): #' as_environment("base") #' as_environment("rlang") #' #' # With NULL it returns the empty environment: #' as_environment(NULL) as_environment <- function(x, parent = NULL) { if (is_string(x) && !is_named(x)) { return(pkg_env(x)) } switch(typeof(x), NULL = empty_env(), environment = x, logical = , integer = , double = , character = , complex = , raw = , list = vec_as_environment(x, parent), abort_coercion(x, "an environment") ) } vec_as_environment <- function(x, parent = NULL) { stopifnot(is_dictionaryish(x)) if (is_atomic(x)) { x <- vec_coerce(x, "list") } list2env(x, parent = parent %||% empty_env()) } #' Get parent environments #' #' @description #' #' - `env_parent()` returns the parent environment of `env` if called #' with `n = 1`, the grandparent with `n = 2`, etc. #' #' - `env_tail()` searches through the parents and returns the one #' which has [empty_env()] as parent. #' #' - `env_parents()` returns the list of all parents, including the #' empty environment. This list is named using [env_name()]. #' #' See the section on _inheritance_ in [env()]'s documentation. #' #' #' @section Life cycle: #' #' The `sentinel` argument of `env_tail()` has been deprecated in #' rlang 0.2.0 and renamed to `last`. It is defunct as of rlang 0.4.0. #' #' @inheritParams get_env #' @param n The number of generations to go up. #' @param last The environment at which to stop. Defaults to the #' global environment. The empty environment is always a stopping #' condition so it is safe to leave the default even when taking the #' tail or the parents of an environment on the search path. #' #' `env_tail()` returns the environment which has `last` as parent #' and `env_parents()` returns the list of environments up to `last`. #' @param sentinel This argument is defunct, please use `last` instead. #' @return An environment for `env_parent()` and `env_tail()`, a list #' of environments for `env_parents()`. #' @export #' @examples #' # Get the parent environment with env_parent(): #' env_parent(global_env()) #' #' # Or the tail environment with env_tail(): #' env_tail(global_env()) #' #' # By default, env_parent() returns the parent environment of the #' # current evaluation frame. If called at top-level (the global #' # frame), the following two expressions are equivalent: #' env_parent() #' env_parent(base_env()) #' #' # This default is more handy when called within a function. In this #' # case, the enclosure environment of the function is returned #' # (since it is the parent of the evaluation frame): #' enclos_env <- env() #' fn <- set_env(function() env_parent(), enclos_env) #' identical(enclos_env, fn()) env_parent <- function(env = caller_env(), n = 1) { env_ <- get_env_retired(env, "env_parent()") while (n > 0) { if (is_empty_env(env_)) { abort("The empty environment has no parent") } n <- n - 1 env_ <- parent.env(env_) } env_ } #' @rdname env_parent #' @export env_tail <- function(env = caller_env(), last = global_env(), sentinel = NULL) { if (!is_null(sentinel)) { stop_defunct(paste_line( "`sentinel` is deprecated as of version 0.3.0.", "Please use `last` instead." )) last <- sentinel } env_ <- get_env_retired(env, "env_tail()") parent <- env_parent(env_) while (!is_reference(parent, last) && !is_empty_env(parent)) { env_ <- parent parent <- env_parent(parent) } env_ } #' @rdname env_parent #' @export env_parents <- function(env = caller_env(), last = global_env()) { if (is_empty_env(env)) { return(new_environments(list())) } n <- env_depth(env) out <- new_list(n) if (!typeof(last) %in% c("environment", "NULL")) { abort("`last` must be `NULL` or an environment") } i <- 1L parent <- env_parent(env) while (TRUE) { out[[i]] <- parent if (is_reference(parent, last) || is_empty_env(parent)) { break } i <- i + 1L env <- parent parent <- env_parent(env) } if (i < n) { out <- out[seq_len(i)] } new_environments(out) } #' Depth of an environment chain #' #' This function returns the number of environments between `env` and #' the [empty environment][empty_env()], including `env`. The depth of #' `env` is also the number of parents of `env` (since the empty #' environment counts as a parent). #' #' @inheritParams get_env #' @return An integer. #' @seealso The section on inheritance in [env()] documentation. #' @export #' @examples #' env_depth(empty_env()) #' env_depth(pkg_env("rlang")) env_depth <- function(env) { env_ <- get_env_retired(env, "env_depth()") n <- 0L while (!is_empty_env(env_)) { env_ <- env_parent(env_) n <- n + 1L } n } `_empty_env` <- emptyenv() is_empty_env <- function(env) { is_reference(env, `_empty_env`) } #' Get or set the environment of an object #' #' These functions dispatch internally with methods for functions, #' formulas and frames. If called with a missing argument, the #' environment of the current evaluation frame (see [ctxt_stack()]) is #' returned. If you call `get_env()` with an environment, it acts as #' the identity function and the environment is simply returned (this #' helps simplifying code when writing generic functions for #' environments). #' #' While `set_env()` returns a modified copy and does not have side #' effects, `env_poke_parent()` operates changes the environment by #' side effect. This is because environments are #' [uncopyable][is_copyable]. Be careful not to change environments #' that you don't own, e.g. a parent environment of a function from a #' package. #' #' #' @section Life cycle: #' #' - Using `get_env()` without supplying `env` is deprecated as #' of rlang 0.3.0. Please use [current_env()] to retrieve the #' current environment. #' #' - Passing environment wrappers like formulas or functions instead #' of bare environments is deprecated as of rlang 0.3.0. This #' internal genericity was causing confusion (see issue #427). You #' should now extract the environment separately before calling #' these functions. #' #' @param env An environment. #' @param default The default environment in case `env` does not wrap #' an environment. If `NULL` and no environment could be extracted, #' an error is issued. #' #' @seealso [quo_get_env()] and [quo_set_env()] for versions of #' [get_env()] and [set_env()] that only work on quosures. #' @export #' @examples #' # Environment of closure functions: #' fn <- function() "foo" #' get_env(fn) #' #' # Or of quosures or formulas: #' get_env(~foo) #' get_env(quo(foo)) #' #' #' # Provide a default in case the object doesn't bundle an environment. #' # Let's create an unevaluated formula: #' f <- quote(~foo) #' #' # The following line would fail if run because unevaluated formulas #' # don't bundle an environment (they didn't have the chance to #' # record one yet): #' # get_env(f) #' #' # It is often useful to provide a default when you're writing #' # functions accepting formulas as input: #' default <- env() #' identical(get_env(f, default), default) get_env <- function(env, default = NULL) { if (missing(env)) { warn_deprecated("The `env` argument of `get_env()` must now be supplied") env <- caller_env() } out <- switch(typeof(env), environment = env, definition = , language = if (is_formula(env)) attr(env, ".Environment"), builtin = , special = , primitive = base_env(), closure = environment(env) ) out <- out %||% default if (is_null(out)) { type <- friendly_type_of(env) abort(paste0("Can't extract an environment from ", type)) } else { out } } get_env_retired <- function(x, fn) { if (is_environment(x)) { return(x) } type <- friendly_type_of(x) warn_deprecated(paste_line( sprintf("Passing an environment wrapper like %s is deprecated.", type), sprintf("Please retrieve the environment before calling `%s`", fn) )) get_env(x) } #' @rdname get_env #' @param new_env An environment to replace `env` with. #' @export #' @examples #' #' # set_env() can be used to set the enclosure of functions and #' # formulas. Let's create a function with a particular environment: #' env <- child_env("base") #' fn <- set_env(function() NULL, env) #' #' # That function now has `env` as enclosure: #' identical(get_env(fn), env) #' identical(get_env(fn), current_env()) #' #' # set_env() does not work by side effect. Setting a new environment #' # for fn has no effect on the original function: #' other_env <- child_env(NULL) #' set_env(fn, other_env) #' identical(get_env(fn), other_env) #' #' # Since set_env() returns a new function with a different #' # environment, you'll need to reassign the result: #' fn <- set_env(fn, other_env) #' identical(get_env(fn), other_env) set_env <- function(env, new_env = caller_env()) { new_env <- get_env_retired(new_env, "set_env()") if (is_formulaish(env) || is_closure(env)) { environment(env) <- new_env return(env) } if (is_environment(env)) { return(new_env) } abort(paste0( "Can't set environment for ", friendly_type_of(env) )) } #' @rdname get_env #' @export env_poke_parent <- function(env, new_env) { env <- get_env_retired(env, "env_poke_parent()") new_env <- get_env_retired(new_env, "env_poke_parent()") .Call(rlang_env_poke_parent, env, new_env) } `env_parent<-` <- function(x, value) { env <- get_env_retired(x, "env_poke_parent<-") .Call(rlang_env_poke_parent, env, value) } #' Clone an environment #' #' This creates a new environment containing exactly the same objects, #' optionally with a new parent. #' #' @inheritParams get_env #' @param parent The parent of the cloned environment. #' @export #' @examples #' env <- env(!!! mtcars) #' clone <- env_clone(env) #' identical(env, clone) #' identical(env$cyl, clone$cyl) env_clone <- function(env, parent = env_parent(env)) { env <- get_env_retired(env, "env_clone()") .Call(rlang_env_clone, env, parent) } #' Does environment inherit from another environment? #' #' This returns `TRUE` if `x` has `ancestor` among its parents. #' #' @inheritParams get_env #' @param ancestor Another environment from which `x` might inherit. #' @export env_inherits <- function(env, ancestor) { env <- get_env_retired(env, "env_inherits()") .Call(rlang_env_inherits, env, ancestor) } #' Lock an environment #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} #' #' Locked environments cannot be modified. An important example is #' namespace environments which are locked by R when loaded in a #' session. Once an environment is locked it normally cannot be #' unlocked. #' #' Note that only the environment as a container is locked, not the #' individual bindings. You can't remove or add a binding but you can #' still modify the values of existing bindings. See #' [env_binding_lock()] for locking individual bindings. #' #' @param env An environment. #' @return The old value of `env_is_locked()` invisibly. #' #' @seealso [env_binding_lock()] #' @keywords internal #' @export #' @examples #' # New environments are unlocked by default: #' env <- env(a = 1) #' env_is_locked(env) #' #' # Use env_lock() to lock them: #' env_lock(env) #' env_is_locked(env) #' #' # Now that `env` is locked, it is no longer possible to remove or #' # add bindings. If run, the following would fail: #' # env_unbind(env, "a") #' # env_bind(env, b = 2) #' #' # Note that even though the environment as a container is locked, #' # the individual bindings are still unlocked and can be modified: #' env$a <- 10 env_lock <- function(env) { old <- env_is_locked(env) lockEnvironment(env) invisible(old) } #' @rdname env_lock #' @export env_is_locked <- function(env) { environmentIsLocked(env) } #' Unlock an environment #' #' This function should only be used in development tools or #' interactively. #' #' @inheritParams env_lock #' @return Whether the environment has been unlocked. #' #' @keywords internal #' @export env_unlock <- function(env) { invisible(.Call(rlang_env_unlock, env)) } #' Pretty-print an environment #' #' @description #' #' This prints: #' #' * The [label][env_label] and the parent label. #' #' * Whether the environment is [locked][env_lock]. #' #' * The bindings in the environment (up to 20 bindings). They are #' printed succintly using `pillar::type_sum()` (if available, #' otherwise uses an internal version of that generic). In addition #' [fancy bindings][env_bind_lazy] (actives and promises) are #' indicated as such. #' #' * Locked bindings get a `[L]` tag #' #' @param env An environment, or object that can be converted to an #' environment by [get_env()]. #' #' @export env_print <- function(env = caller_env()) { env <- get_env(env) if (is_empty_env(env)) { parent <- "NULL" } else { parent <- sprintf("", env_label(env_parent(env))) } if (env_is_locked(env)) { locked <- " [L]" } else { locked <- "" } cat_line( bold(sprintf("%s", env_label(env), locked)), sprintf("parent: %s", parent) ) class <- attr(env, "class") if (is_character(class)) { class <- paste(class, collapse = ", ") cat_line(sprintf("class: %s", class)) } nms <- env_names(env) n <- length(nms) if (n) { cat_line("bindings:") if (n > 20) { other <- nms[seq(21L, n)] nms <- nms[1:20] } else { other <- chr() } escaped_nms <- map_chr(syms(nms), deparse, backtick = TRUE) types <- env_binding_type_sum(env, nms) types <- paste0(" ", bullet(paste0(escaped_nms, ": <", types, ">"))) locked <- env_binding_are_locked(env, nms) locked <- ifelse(locked, " [L]", "") types <- paste0(types, locked) cat_line(types) n_other <- length(other) if (n_other) { cat_line(sprintf(" * ... with %s more bindings", n_other)) } } invisible(env) } new_environments <- function(envs, names) { stopifnot(is_list(envs)) structure( envs, names = map_chr(unname(envs), env_name), class = "rlang_envs" ) } #' @export print.rlang_envs <- function(x, ...) { n <- length(x) if (!n) { print(list()) return(invisible(x)) } if (n > 20L) { footer <- sprintf("... and %s more environments", n - 20L) x <- x[seq_len(20L)] } else { footer <- chr() } digits <- n_digits(seq_along(x)) pads <- digits[[length(x)]] - digits pads <- map_chr(pads, spaces) labels <- map_chr(x, env_label) nms_tags <- names_tags(names(x)) cat_line( paste0(pads, "[[", seq_along(x), "]]", nms_tags, " "), footer ) invisible(x) } n_digits <- function(x) { floor(log10(x) + 1) } names_tags <- function(nms) { if (is_null(nms)) { return("") } invalid <- nms_are_invalid(nms) if (all(invalid)) { return("") } ifelse(invalid, " ", " $") } #' @export c.rlang_envs <- function(...) { new_environments(NextMethod()) } #' @export `[.rlang_envs` <- function(x, i) { new_environments(NextMethod()) } #' @export str.rlang_envs <- function(object, ...) { i <- 0 for (env in object) { i <- inc(i) cat(sprintf("[[%s]]\n", i)) env_print(env) cat("\n") } invisible(object) } rlang/R/compat-lifecycle.R0000644000176200001440000001634013563536133015135 0ustar liggesusers# nocov start --- compat-lifecycle --- 2019-11-15 Fri 15:55 # 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 = 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(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() silver <- 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", silver("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 <- cnd( c("defunctError", "error", "condition"), old = NULL, new = NULL, package = NULL, message = msg ) stop(err) } local_lifecycle_silence <- function(frame = rlang::caller_env()) { rlang::local_options(.frame = frame, lifecycle_disable_warnings = TRUE ) } with_lifecycle_silence <- function(expr) { local_lifecycle_silence() expr } local_lifecycle_warnings <- function(frame = rlang::caller_env()) { rlang::local_options(.frame = frame, lifecycle_disable_warnings = FALSE, lifecycle_verbose_soft_deprecation = TRUE, lifecycle_repeat_warnings = TRUE ) } with_lifecycle_warnings <- function(expr) { local_lifecycle_warnings() expr } local_lifecycle_errors <- function(frame = rlang::caller_env()) { local_lifecycle_warnings(frame = frame) rlang::local_options(.frame = frame, lifecycle_warnings_as_errors = TRUE ) } with_lifecycle_errors <- function(expr) { local_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"`. #' #' @keywords internal #' @noRd NULL 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) ) } 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)) ) } upcase1 <- function(x) { substr(x, 1, 1) <- toupper(substr(x, 1, 1)) x } lifecycle_validate_message <- function(msg) { stopifnot(is_character(msg)) paste0(msg, collapse = "\n") } # nocov end rlang/R/eval-tidy.R0000644000176200001440000004503713612030703013603 0ustar liggesusers#' Evaluate an expression with quosures and pronoun support #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("stable")} #' #' `eval_tidy()` is a variant of [base::eval()] that powers the tidy #' evaluation framework. Like `eval()` it accepts user data as #' argument. Whereas `eval()` simply transforms the data to an #' environment, `eval_tidy()` transforms it to a **data mask** with #' [as_data_mask()]. Evaluating in a data mask enables the following #' features: #' #' - [Quosures][nse-defuse]. Quosures are expressions bundled with an #' environment. If `data` is supplied, objects in the data mask #' always have precedence over the quosure environment, i.e. the #' data masks the environment. #' #' - [Pronouns][.data]. If `data` is supplied, the `.env` and `.data` #' pronouns are installed in the data mask. `.env` is a reference to #' the calling environment and `.data` refers to the `data` argument. #' These pronouns lets you be explicit about where to find #' values and throw errors if you try to access non-existent values. #' #' #' @param expr An expression or quosure to evaluate. #' @param data A data frame, or named list or vector. Alternatively, a #' data mask created with [as_data_mask()] or #' [new_data_mask()]. Objects in `data` have priority over those in #' `env`. See the section about data masking. #' #' @param env The environment in which to evaluate `expr`. This #' environment is not applicable for quosures because they have #' their own environments. #' @seealso [nse-force] for the second leg of the tidy evaluation #' framework. #' #' #' @section Data masking: #' #' Data masking refers to how columns or objects inside `data` have #' priority over objects defined in `env` (or in the quosure #' environment, if applicable). If there is a column `var` in `data` #' and an object `var` in `env`, and `expr` refers to `var`, the #' column has priority: #' #' ``` #' var <- "this one?" #' data <- data.frame(var = rep("Or that one?", 3)) #' #' within <- function(data, expr) { #' eval_tidy(enquo(expr), data) #' } #' #' within(data, toupper(var)) #' #> [1] "OR THAT ONE?" "OR THAT ONE?" "OR THAT ONE?" #' ``` #' #' Because the columns or objects in `data` are always found first, #' before objects from `env`, we say that the data "masks" the #' environment. #' #' #' @section When should eval_tidy() be used instead of eval()?: #' #' `base::eval()` is sufficient for simple evaluation. Use #' `eval_tidy()` when you'd like to support expressions referring to #' the `.data` pronoun, or when you need to support quosures. #' #' If you're evaluating an expression captured with quasiquotation #' support, it is recommended to use `eval_tidy()` because users will #' likely unquote quosures. #' #' Note that unwrapping a quosure with [quo_get_expr()] does not #' guarantee that there is no quosures inside the expression. Quosures #' might be unquoted anywhere. For instance, the following does not #' work reliably in the presence of nested quosures: #' #' ``` #' my_quoting_fn <- function(x) { #' x <- enquo(x) #' expr <- quo_get_expr(x) #' env <- quo_get_env(x) #' eval(expr, env) #' } #' #' # Works: #' my_quoting_fn(toupper(letters)) #' #' # Fails because of a nested quosure: #' my_quoting_fn(toupper(!!quo(letters))) #' ``` #' #' #' @section Life cycle: #' #' **rlang 0.3.0** #' #' Passing an environment to `data` is deprecated. Please construct an #' rlang data mask with [new_data_mask()]. #' #' #' @examples #' #' # With simple quoted expressions eval_tidy() works the same way as #' # eval(): #' apple <- "apple" #' kiwi <- "kiwi" #' expr <- quote(paste(apple, kiwi)) #' expr #' #' eval(expr) #' eval_tidy(expr) #' #' # Both accept a data mask as argument: #' data <- list(apple = "CARROT", kiwi = "TOMATO") #' eval(expr, data) #' eval_tidy(expr, data) #' #' #' # In addition eval_tidy() has support for quosures: #' with_data <- function(data, expr) { #' quo <- enquo(expr) #' eval_tidy(quo, data) #' } #' with_data(NULL, apple) #' with_data(data, apple) #' with_data(data, list(apple, kiwi)) #' #' # Secondly eval_tidy() installs handy pronouns that allow users to #' # be explicit about where to find symbols: #' with_data(data, .data$apple) #' with_data(data, .env$apple) #' #' #' # Note that instead of using `.env` it is often equivalent and may #' # be preferred to unquote a value. There are two differences. First #' # unquoting happens earlier, when the quosure is created. Secondly, #' # subsetting `.env` with the `$` operator may be brittle because #' # `$` does not look through the parents of the environment. #' # #' # For instance using `.env$name` in a magrittr pipeline is an #' # instance where this poses problem, because the magrittr pipe #' # currently (as of v1.5.0) evaluates its operands in a *child* of #' # the current environment (this child environment is where it #' # defines the pronoun `.`). #' \dontrun{ #' data %>% with_data(!!kiwi) # "kiwi" #' data %>% with_data(.env$kiwi) # NULL #' } #' @export eval_tidy <- function(expr, data = NULL, env = caller_env()) { .Call(rlang_eval_tidy, expr, data, env) } # Helps work around roxygen loading issues #' @export length.rlang_fake_data_pronoun <- function(...) NULL #' @export names.rlang_fake_data_pronoun <- function(...) NULL #' @export `$.rlang_fake_data_pronoun` <- function(...) NULL #' @export `[[.rlang_fake_data_pronoun` <- function(...) NULL #' @export print.rlang_fake_data_pronoun <- function(...) cat_line("") #' Data pronouns for tidy evaluation #' #' @description #' #' These pronouns allow you to be explicit about where to find objects #' when programming with data masked functions. #' #' ``` #' m <- 10 #' mtcars %>% mutate(disp = .data$disp * .env$m) #' ``` #' #' * `.data` retrieves data-variables from the data frame. #' * `.env` retrieves env-variables from the environment. #' #' Because the lookup is explicit, there is no ambiguity between both #' kinds of variables. Compare: #' #' ``` #' disp <- 10 #' mtcars %>% mutate(disp = .data$disp * .env$disp) #' mtcars %>% mutate(disp = disp * disp) #' ``` #' #' The `.data` object exported from rlang is also useful to import in #' your package namespace to avoid a `R CMD check` note when referring #' to objects from the data mask. #' #' Note that `.data` is only a pronoun, it is not a real data #' frame. This means that you can't take its names or map a function #' over the contents of `.data`. Similarly, `.env` is not an actual R #' environment. For instance, it doesn't have a parent and the #' subsetting operators behave differently. #' #' @name tidyeval-data #' @format NULL #' @export .data <- structure(list(), class = "rlang_fake_data_pronoun") #' @rdname tidyeval-data #' @export .env <- .data #' Create a data mask #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("stable")} #' #' A data mask is an environment (or possibly multiple environments #' forming an ancestry) containing user-supplied objects. Objects in #' the mask have precedence over objects in the environment (i.e. they #' mask those objects). Many R functions evaluate quoted expressions #' in a data mask so these expressions can refer to objects within the #' user data. #' #' These functions let you construct a tidy eval data mask manually. #' They are meant for developers of tidy eval interfaces rather than #' for end users. #' #' #' @section Why build a data mask?: #' #' Most of the time you can just call [eval_tidy()] with a list or a #' data frame and the data mask will be constructed automatically. #' There are three main use cases for manual creation of data masks: #' #' * When [eval_tidy()] is called with the same data in a tight loop. #' Because there is some overhead to creating tidy eval data masks, #' constructing the mask once and reusing it for subsequent #' evaluations may improve performance. #' #' * When several expressions should be evaluated in the exact same #' environment because a quoted expression might create new objects #' that can be referred in other quoted expressions evaluated at a #' later time. One example of this is `tibble::lst()` where new #' columns can refer to previous ones. #' #' * When your data mask requires special features. For instance the #' data frame columns in dplyr data masks are implemented with #' [active bindings][base::delayedAssign]. #' #' #' @section Building your own data mask: #' #' Unlike [base::eval()] which takes any kind of environments as data #' mask, [eval_tidy()] has specific requirements in order to support #' [quosures][nse-defuse]. For this reason you can't supply bare #' environments. #' #' There are two ways of constructing an rlang data mask manually: #' #' * `as_data_mask()` transforms a list or data frame to a data mask. #' It automatically installs the data pronoun [`.data`][.data]. #' #' * `new_data_mask()` is a bare bones data mask constructor for #' environments. You can supply a bottom and a top environment in #' case your data mask comprises multiple environments (see section #' below). #' #' Unlike `as_data_mask()` it does not install the `.data` pronoun #' so you need to provide one yourself. You can provide a pronoun #' constructed with `as_data_pronoun()` or your own pronoun class. #' #' `as_data_pronoun()` will create a pronoun from a list, an #' environment, or an rlang data mask. In the latter case, the whole #' ancestry is looked up from the bottom to the top of the mask. #' Functions stored in the mask are bypassed by the pronoun. #' #' Once you have built a data mask, simply pass it to [eval_tidy()] as #' the `data` argument. You can repeat this as many times as #' needed. Note that any objects created there (perhaps because of a #' call to `<-`) will persist in subsequent evaluations. #' #' #' @section Top and bottom of data mask: #' #' In some cases you'll need several levels in your data mask. One #' good reason is when you include functions in the mask. It's a good #' idea to keep data objects one level lower than function objects, so #' that the former cannot override the definitions of the latter (see #' examples). #' #' In that case, set up all your environments and keep track of the #' bottom child and the top parent. You'll need to pass both to #' `new_data_mask()`. #' #' Note that the parent of the top environment is completely #' undetermined, you shouldn't expect it to remain the same at all #' times. This parent is replaced during evaluation by [eval_tidy()] #' to one of the following environments: #' #' * The default environment passed as the `env` argument of `eval_tidy()`. #' * The environment of the current quosure being evaluated, if applicable. #' #' Consequently, all masking data should be contained between the #' bottom and top environment of the data mask. #' #' @section Life cycle: #' #' The `parent` argument no longer has any effect and is defunct as of #' rlang 0.4.0. The parent of the data mask is determined from either: #' #' * The `env` argument of `eval_tidy()` #' * Quosure environments when applicable #' #' Passing environments to `as_data_mask()` is deprecated as of rlang #' 0.3.0. Please use `new_data_mask()` instead. #' #' **rlang 0.2.0** #' #' In early versions of rlang data masks were called overscopes. We #' think data mask is a more natural name in R. It makes reference to #' masking in the search path which occurs through the same mechanism #' (in technical terms, lexical scoping with hierarchically nested #' environments). We say that objects from user data mask objects #' in the current environment. #' #' Following this change in terminology, `as_overscope()` and #' `new_overscope()` were deprecated in rlang 0.2.0 in favour of #' `as_data_mask()` and `new_data_mask()`. #' #' @param data A data frame or named vector of masking data. #' @param parent Deprecated. This argument no longer has any effect. #' The parent of the data mask is determined from either: #' * The `env` argument of `eval_tidy()` #' * Quosure environments when applicable #' @return A data mask that you can supply to [eval_tidy()]. #' #' @export #' @examples #' # Evaluating in a tidy evaluation environment enables all tidy #' # features: #' mask <- as_data_mask(mtcars) #' eval_tidy(quo(letters), mask) #' #' # You can install new pronouns in the mask: #' mask$.pronoun <- as_data_pronoun(list(foo = "bar", baz = "bam")) #' eval_tidy(quo(.pronoun$foo), mask) #' #' # In some cases the data mask can leak to the user, for example if #' # a function or formula is created in the data mask environment: #' cyl <- "user variable from the context" #' fn <- eval_tidy(quote(function() cyl), mask) #' fn() #' #' # If new objects are created in the mask, they persist in the #' # subsequent calls: #' eval_tidy(quote(new <- cyl + am), mask) #' eval_tidy(quote(new * 2), mask) #' #' #' # In some cases your data mask is a whole chain of environments #' # rather than a single environment. You'll have to use #' # `new_data_mask()` and let it know about the bottom of the mask #' # (the last child of the environment chain) and the topmost parent. #' #' # A common situation where you'll want a multiple-environment mask #' # is when you include functions in your mask. In that case you'll #' # put functions in the top environment and data in the bottom. This #' # will prevent the data from overwriting the functions. #' top <- new_environment(list(`+` = base::paste, c = base::paste)) #' #' # Let's add a middle environment just for sport: #' middle <- env(top) #' #' # And finally the bottom environment containing data: #' bottom <- env(middle, a = "a", b = "b", c = "c") #' #' # We can now create a mask by supplying the top and bottom #' # environments: #' mask <- new_data_mask(bottom, top = top) #' #' # This data mask can be passed to eval_tidy() instead of a list or #' # data frame: #' eval_tidy(quote(a + b + c), data = mask) #' #' # Note how the function `c()` and the object `c` are looked up #' # properly because of the multi-level structure: #' eval_tidy(quote(c(a, b, c)), data = mask) #' #' # new_data_mask() does not create data pronouns, but #' # data pronouns can be added manually: #' mask$.fns <- as_data_pronoun(top) #' #' # The `.data` pronoun should generally be created from the #' # mask. This will ensure data is looked up throughout the whole #' # ancestry. Only non-function objects are looked up from this #' # pronoun: #' mask$.data <- as_data_pronoun(mask) #' mask$.data$c #' #' # Now we can reference the values with the pronouns: #' eval_tidy(quote(c(.data$a, .data$b, .data$c)), data = mask) as_data_mask <- function(data, parent = NULL) { if (!is_null(parent)) { stop_defunct(paste_line( "The `parent` argument of `as_data_mask()` is deprecated.", "The parent of the data mask is determined from either:", "", " * The `env` argument of `eval_tidy()`", " * Quosure environments when applicable" )) } .Call(rlang_as_data_mask, data) } #' @rdname as_data_mask #' @export as_data_pronoun <- function(data) { .Call(rlang_as_data_pronoun, data) } #' @rdname as_data_mask #' @param bottom The environment containing masking objects if the #' data mask is one environment deep. The bottom environment if the #' data mask comprises multiple environment. #' #' If you haven't supplied `top`, this __must__ be an environment #' that you own, i.e. that you have created yourself. #' @param top The last environment of the data mask. If the data mask #' is only one environment deep, `top` should be the same as #' `bottom`. #' #' This __must__ be an environment that you own, i.e. that you have #' created yourself. The parent of `top` will be changed by the tidy #' eval engine and should be considered undetermined. Never make #' assumption about the parent of `top`. #' @export new_data_mask <- function(bottom, top = bottom, parent = NULL) { if (!is_null(parent)) { stop_defunct(paste_line( "The `parent` argument of `new_data_mask()` is deprecated.", "The parent of the data mask is determined from either:", "", " * The `env` argument of `eval_tidy()`", " * Quosure environments when applicable" )) } .Call(rlang_new_data_mask, bottom, top) } #' @export `$.rlang_data_pronoun` <- function(x, nm) { data_pronoun_get(x, nm) } #' @export `[[.rlang_data_pronoun` <- function(x, i, ...) { data_pronoun_get(x, i) } data_pronoun_get <- function(x, nm) { if (!is_string(nm)) { abort("Must subset the data pronoun with a string") } mask <- .subset2(x, 1) .Call(rlang_data_pronoun_get, mask, sym(nm)) } abort_data_pronoun <- function(nm) { msg <- sprintf("Column `%s` not found in `.data`", as_string(nm)) abort(msg, "rlang_error_data_pronoun_not_found") } #' @export `$.rlang_ctxt_pronoun` <- function(x, nm) { ctxt_pronoun_get(x, nm) } #' @export `[[.rlang_ctxt_pronoun` <- function(x, i, ...) { ctxt_pronoun_get(x, i) } ctxt_pronoun_get <- function(x, nm) { if (!is_string(nm)) { abort("Must subset the context pronoun with a string") } eval_bare(sym(nm), x) } #' @export `$<-.rlang_data_pronoun` <- function(x, i, value) { abort("Can't modify the data pronoun") } #' @export `[[<-.rlang_data_pronoun` <- function(x, i, value) { abort("Can't modify the data pronoun") } #' @export `$<-.rlang_ctxt_pronoun` <- function(x, i, value) { abort("Can't modify the context pronoun") } #' @export `[[<-.rlang_ctxt_pronoun` <- function(x, i, value) { abort("Can't modify the context pronoun") } #' @export `[.rlang_data_pronoun` <- function(x, i, ...) { abort("`[` is not supported by .data pronoun, use `[[` or $ instead.") } #' @export names.rlang_data_pronoun <- function(x) { abort("Can't take the `names()` of the `.data` pronoun") } #' @export length.rlang_data_pronoun <- function(x) { abort("Can't take the `length()` of the `.data` pronoun") } #' @export names.rlang_ctxt_pronoun <- function(x) { abort("Can't take the `names()` of the context pronoun") } #' @export length.rlang_ctxt_pronoun <- function(x) { abort("Can't take the `length()` of the context pronoun") } #' @export print.rlang_data_pronoun <- function(x, ...) { cat_line("") invisible(x) } #' @importFrom utils str #' @export str.rlang_data_pronoun <- function(object, ...) { cat_line("") } # Used for deparsing is_data_pronoun <- function(x) { is_call(x, c("[[", "$"), n = 2L) && identical(node_cadr(x), dot_data_sym) } data_pronoun_name <- function(x) { if (is_call(x, "$")) { arg <- node_cadr(node_cdr(x)) if (is_symbol(arg)) { return(as_string(arg)) } else { return(NULL) } } if (is_call(x, "[[")) { arg <- node_cadr(node_cdr(x)) if (is_string(arg)) { return(arg) } else { return(NULL) } } } is_data_mask <- function(x) { is_environment(x) && env_has(x, ".__rlang_data_mask__.") } rlang/R/compat-purrr.R0000644000176200001440000001067113457603056014352 0ustar liggesusers# nocov start - compat-purrr (last updated: rlang 0.3.2.9000) # This file serves as a reference for compatibility functions for # purrr. They are not drop-in replacements but allow a similar style # of programming. This is useful in cases where purrr is too heavy a # package to depend on. Please find the most recent version in rlang's # repository. map <- function(.x, .f, ...) { lapply(.x, .f, ...) } map_mold <- function(.x, .f, .mold, ...) { out <- vapply(.x, .f, .mold, ..., USE.NAMES = FALSE) names(out) <- names(.x) out } map_lgl <- function(.x, .f, ...) { map_mold(.x, .f, logical(1), ...) } map_int <- function(.x, .f, ...) { map_mold(.x, .f, integer(1), ...) } map_dbl <- function(.x, .f, ...) { map_mold(.x, .f, double(1), ...) } map_chr <- function(.x, .f, ...) { map_mold(.x, .f, character(1), ...) } map_cpl <- function(.x, .f, ...) { map_mold(.x, .f, complex(1), ...) } walk <- function(.x, .f, ...) { map(.x, .f, ...) invisible(.x) } pluck <- function(.x, .f) { map(.x, `[[`, .f) } pluck_lgl <- function(.x, .f) { map_lgl(.x, `[[`, .f) } pluck_int <- function(.x, .f) { map_int(.x, `[[`, .f) } pluck_dbl <- function(.x, .f) { map_dbl(.x, `[[`, .f) } pluck_chr <- function(.x, .f) { map_chr(.x, `[[`, .f) } pluck_cpl <- function(.x, .f) { map_cpl(.x, `[[`, .f) } map2 <- function(.x, .y, .f, ...) { out <- mapply(.f, .x, .y, MoreArgs = list(...), SIMPLIFY = FALSE) if (length(out) == length(.x)) { set_names(out, names(.x)) } else { set_names(out, NULL) } } map2_lgl <- function(.x, .y, .f, ...) { as.vector(map2(.x, .y, .f, ...), "logical") } map2_int <- function(.x, .y, .f, ...) { as.vector(map2(.x, .y, .f, ...), "integer") } map2_dbl <- function(.x, .y, .f, ...) { as.vector(map2(.x, .y, .f, ...), "double") } map2_chr <- function(.x, .y, .f, ...) { as.vector(map2(.x, .y, .f, ...), "character") } map2_cpl <- function(.x, .y, .f, ...) { as.vector(map2(.x, .y, .f, ...), "complex") } args_recycle <- function(args) { lengths <- map_int(args, length) n <- max(lengths) stopifnot(all(lengths == 1L | lengths == n)) to_recycle <- lengths == 1L args[to_recycle] <- map(args[to_recycle], function(x) rep.int(x, n)) args } pmap <- function(.l, .f, ...) { args <- args_recycle(.l) do.call("mapply", c( FUN = list(quote(.f)), args, MoreArgs = quote(list(...)), SIMPLIFY = FALSE, USE.NAMES = FALSE )) } probe <- function(.x, .p, ...) { if (is_logical(.p)) { stopifnot(length(.p) == length(.x)) .p } else { map_lgl(.x, .p, ...) } } keep <- function(.x, .f, ...) { .x[probe(.x, .f, ...)] } discard <- function(.x, .p, ...) { sel <- probe(.x, .p, ...) .x[is.na(sel) | !sel] } map_if <- function(.x, .p, .f, ...) { matches <- probe(.x, .p) .x[matches] <- map(.x[matches], .f, ...) .x } compact <- function(.x) { Filter(length, .x) } transpose <- function(.l) { inner_names <- names(.l[[1]]) if (is.null(inner_names)) { fields <- seq_along(.l[[1]]) } else { fields <- set_names(inner_names) } map(fields, function(i) { map(.l, .subset2, i) }) } every <- function(.x, .p, ...) { for (i in seq_along(.x)) { if (!rlang::is_true(.p(.x[[i]], ...))) return(FALSE) } TRUE } some <- function(.x, .p, ...) { for (i in seq_along(.x)) { if (rlang::is_true(.p(.x[[i]], ...))) return(TRUE) } FALSE } negate <- function(.p) { function(...) !.p(...) } reduce <- function(.x, .f, ..., .init) { f <- function(x, y) .f(x, y, ...) Reduce(f, .x, init = .init) } reduce_right <- function(.x, .f, ..., .init) { f <- function(x, y) .f(y, x, ...) Reduce(f, .x, init = .init, right = TRUE) } accumulate <- function(.x, .f, ..., .init) { f <- function(x, y) .f(x, y, ...) Reduce(f, .x, init = .init, accumulate = TRUE) } accumulate_right <- function(.x, .f, ..., .init) { f <- function(x, y) .f(y, x, ...) Reduce(f, .x, init = .init, right = TRUE, accumulate = TRUE) } detect <- function(.x, .f, ..., .right = FALSE, .p = is_true) { for (i in index(.x, .right)) { if (.p(.f(.x[[i]], ...))) { return(.x[[i]]) } } NULL } detect_index <- function(.x, .f, ..., .right = FALSE, .p = is_true) { for (i in index(.x, .right)) { if (.p(.f(.x[[i]], ...))) { return(i) } } 0L } index <- function(x, right = FALSE) { idx <- seq_along(x) if (right) { idx <- rev(idx) } idx } imap <- function(.x, .f, ...) { map2(.x, vec_index(.x), .f, ...) } vec_index <- function(x) { names(x) %||% seq_along(x) } # nocov end rlang/R/vec.R0000644000176200001440000000472613500441315012463 0ustar liggesusers#' Increasing sequence of integers in an interval #' #' These helpers take two endpoints and return the sequence of all #' integers within that interval. For `seq2_along()`, the upper #' endpoint is taken from the length of a vector. Unlike #' `base::seq()`, they return an empty vector if the starting point is #' a larger integer than the end point. #' #' @param from The starting point of the sequence. #' @param to The end point. #' @param x A vector whose length is the end point. #' @return An integer vector containing a strictly increasing #' sequence. #' @export #' @examples #' seq2(2, 10) #' seq2(10, 2) #' seq(10, 2) #' #' seq2_along(10, letters) seq2 <- function(from, to) { if (length(from) != 1) { abort("`from` must be length one") } if (length(to) != 1) { abort("`to` must be length one") } if (from > to) { int() } else { seq.int(from, to) } } #' @rdname seq2 #' @export seq2_along <- function(from, x) { seq2(from, length(x)) } first <- function(x) { .subset2(x, 1L) } last <- function(x) { .subset2(x, length_(x)) } validate_index <- function(i, n) { seq_len(n)[i] } #' Poke values into a vector #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} #' #' These tools are for R experts only. They copy elements from `y` #' into `x` by mutation. You should only do this if you own `x`, #' i.e. if you have created it or if you are certain that it doesn't #' exist in any other context. Otherwise you might create unintended #' side effects that have undefined consequences. #' #' @param x The destination vector. #' @param start The index indicating where to start modifying `x`. #' @param y The source vector. #' @param from The index indicating where to start copying from `y`. #' @param n How many elements should be copied from `y` to `x`. #' @param to The index indicating the end of the range to copy from `y`. #' #' @keywords internal #' @export vec_poke_n <- function(x, start, y, from = 1L, n = length(y)) { stopifnot( is_integerish(start), is_integerish(from), is_integerish(n) ) .Call(rlang_vec_poke_n, x, start, y, from, n) } #' @rdname vec_poke_n #' @export vec_poke_range <- function(x, start, y, from = 1L, to = length(y) - from + 1L) { stopifnot( is_integerish(start), is_integerish(from), is_integerish(to) ) .Call(rlang_vec_poke_range, x, start, y, from, to) } rlang/R/stack.R0000644000176200001440000001003313553606356013017 0ustar liggesusers#' Get properties of the current or caller frame #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")} #' #' * The current frame is the execution context of the function that #' is currently being evaluated. #' #' * The caller frame is the execution context of the function that #' called the function currently being evaluated. #' #' See the [call stack][stack] topic for more information. #' #' #' @section Life cycle: #' #' These functions are experimental. #' #' @param n The number of generations to go back. #' #' @seealso [caller_env()] and [current_env()] #' @keywords internal #' @export caller_fn <- function(n = 1) { with_options(lifecycle_disable_warnings = TRUE, call_frame(n + 2)$fn ) } #' @rdname caller_fn #' @export current_fn <- function() { with_options(lifecycle_disable_warnings = TRUE, call_frame(2)$fn ) } #' Jump to or from a frame #' #' @description #' #' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} #' #' While [base::return()] can only return from the current local #' frame, these two functions will return from any frame on the #' current evaluation stack, between the global and the currently #' active context. They provide a way of performing arbitrary #' non-local jumps out of the function currently under evaluation. #' #' @section Life cycle: #' #' The support for `frame` object is soft-deprecated. Please pass #' simple environments to `return_from()` and `return_to()`. #' #' These functions are in the questioning lifecycle because we are #' considering simpler alternatives. #' #' @param frame An environment, a frame object, or any object with an #' [get_env()] method. The environment should be an evaluation #' environment currently on the stack. #' @param value The return value. #' #' @details #' #' `return_from()` will jump out of `frame`. `return_to()` is a bit #' trickier. It will jump out of the frame located just before `frame` #' in the evaluation stack, so that control flow ends up in `frame`, #' at the location where the previous frame was called from. #' #' These functions should only be used rarely. These sort of non-local #' gotos can be hard to reason about in casual code, though they can #' sometimes be useful. Also, consider to use the condition system to #' perform non-local jumps. #' #' #' @keywords internal #' @export #' @examples #' # Passing fn() evaluation frame to g(): #' fn <- function() { #' val <- g(current_env()) #' cat("g returned:", val, "\n") #' "normal return" #' } #' g <- function(env) h(env) #' #' # Here we return from fn() with a new return value: #' h <- function(env) return_from(env, "early return") #' fn() #' #' # Here we return to fn(). The call stack unwinds until the last frame #' # called by fn(), which is g() in that case. #' h <- function(env) return_to(env, "early return") #' fn() return_from <- function(frame, value = NULL) { if (is_integerish(frame)) { frame <- ctxt_frame(frame)$env } exit_env <- get_env(frame) expr <- expr(return(!!value)) eval_bare(expr, exit_env) } #' @rdname return_from #' @export return_to <- function(frame, value = NULL) { with_options(lifecycle_disable_warnings = TRUE, { if (is_integerish(frame)) { prev_pos <- frame - 1 } else { env <- get_env(frame) distance <- frame_position_current(env) prev_pos <- distance - 1 } prev_frame <- ctxt_frame(prev_pos)$env }) return_from(prev_frame, value) } is_frame_env <- function(env) { for (frame in sys.frames()) { if (identical(env, frame)) { return(TRUE) } } FALSE } #' Inspect a call #' #' This function is useful for quick testing and debugging when you #' manipulate expressions and calls. It lets you check that a function #' is called with the right arguments. This can be useful in unit #' tests for instance. Note that this is just a simple wrapper around #' [base::match.call()]. #' #' @param ... Arguments to display in the returned call. #' @export #' @examples #' call_inspect(foo(bar), "" %>% identity()) call_inspect <- function(...) match.call() rlang/R/utils-conditions.R0000644000176200001440000000033013500516300015175 0ustar liggesusers abort_coercion <- function(x, to_type) { x_type <- friendly_type_of(x) if (!inherits(to_type, "AsIs")) { to_type <- as_friendly_type(to_type) } abort(paste0("Can't convert ", x_type, " to ", to_type)) } rlang/NEWS.md0000644000176200001440000016622413614037745012500 0ustar liggesusers # rlang 0.4.4 * Maintenance release for CRAN. # rlang 0.4.3 * You can now use glue syntax to unquote on the LHS of `:=`. This syntax is automatically available in all functions taking dots with `list2()` and `enquos()`, and thus most of the tidyverse. Note that if you use the glue syntax in an R package, you need to import glue. A single pair of braces triggers normal glue interpolation: ```r df <- data.frame(x = 1:3) suffix <- "foo" df %>% dplyr::mutate("var_{suffix}" := x * 2) #> x var_foo #> 1 1 2 #> 2 2 4 #> 3 3 6 ``` Using a pair of double braces is for labelling a function argument. Technically, this is shortcut for `"{as_label(enquo(arg))}"`. The syntax is similar to the curly-curly syntax for interpolating function arguments: ```r my_wrapper <- function(data, var, suffix = "foo") { data %>% dplyr::mutate("{{ var }}_{suffix}" := {{ var }} * 2) } df %>% my_wrapper(x) #> x x_foo #> 1 1 2 #> 2 2 4 #> 3 3 6 df %>% my_wrapper(sqrt(x)) #> x sqrt(x)_foo #> 1 1 2.000000 #> 2 2 2.828427 #> 3 3 3.464102 ``` * Fixed a bug in magrittr backtraces that caused duplicate calls to appear in the trace. * Fixed a bug in magrittr backtraces that caused wrong call indices. * Empty backtraces are no longer shown when `rlang_backtrace_on_error` is set. * The tidy eval `.env` pronoun is now exported for documentation purposes. * `warn()` and `abort()` now check that either `class` or `message` was supplied. `inform()` allows sending empty message as it is occasionally useful for building user output incrementally. * `flatten()` fails with a proper error when input can't be flattened (#868, #885). * `inform()` now consistently appends a final newline to the message (#880). * `cnd_body.default()` is now properly registered. * `cnd_signal()` now uses the same approach as `abort()` to save unhandled errors to `last_error()`. * Parsable constants like `NaN` and `NA_integer_` are now deparsed by `expr_deparse()` in their parsable form (#890). * Infix operators now stick to their LHS when deparsed by `expr_deparse()` (#890). # rlang 0.4.2 * New `cnd_header()`, `cnd_body()` and `cnd_footer()` generics. These are automatically called by `conditionMessage.rlang_error()`, the default method for all rlang errors. Concretely, this is a way of breaking up lazy generation of error messages with `conditionMessage()` into three independent parts. This provides a lot of flexibility for hierarchies of error classes, for instance you could inherit the body of an error message from a parent class while overriding the header and footer. * The reminder to call `last_error()` is now less confusing thanks to a suggestion by @markhwhiteii. * The functions prefixed in `scoped_` have been renamed to use the more conventional `local_` prefix. For instance, `scoped_bindings()` is now `local_bindings()`. The `scoped_` functions will be deprecated in the next significant version of rlang (0.5.0). * The `.subclass` argument of `abort()`, `warn()` and `inform()` has been renamed to `class`. This is for consistency with our conventions for class constructors documented in https://adv-r.hadley.nz/s3.html#s3-subclassing. * `inform()` now prints messages to the standard output by default in interactive sessions. This makes them appear more like normal output in IDEs such as RStudio. In non-interactive sessions, messages are still printed to standard error to make it easy to redirect messages when running R scripts (#852). * Fixed an error in `trace_back()` when the call stack contains a quosured symbol. * Backtrace is now displayed in full when an error occurs in non-interactive sessions. Previously the backtraces of parent errors were left out. # rlang 0.4.1 * New experimental framework for creating bulleted error messages. See `?cnd_message` for the motivation and an overwiew of the tools we have created to support this approach. In particular, `abort()` now takes character vectors to assemble a bullet list. Elements named `x` are prefixed with a red cross, elements named `i` are prefixed with a blue info symbol, and unnamed elements are prefixed with a bullet. * Capture of backtrace in the context of rethrowing an error from an exiting handler has been improved. The `tryCatch()` context no longer leaks in the high-level backtrace. * Printing an error no longer recommends calling `last_trace()`, unless called from `last_error()`. * `env_clone()` no longer recreates active bindings and is now just an alias for `env2list(as.list(env))`. Unlike `as.list()` which returns the active binding function on R < 4.0, the value of active bindings is consistently used in all versions. * The display of rlang errors derived from parent errors has been improved. The simplified backtrace (as printed by `rlang::last_error()`) no longer includes the parent errors. On the other hand, the full backtrace (as printed by `rlang::last_trace()`) now includes the backtraces of the parent errors. * `cnd_signal()` has improved support for rlang errors created with `error_cnd()`. It now records a backtrace if there isn't one already, and saves the error so it can be inspected with `rlang::last_error()`. * rlang errors are no longer formatted and saved through `conditionMessage()`. This makes it easier to use a `conditionMessage()` method in subclasses created with `abort()`, which is useful to delay expensive generation of error messages until display time. * `abort()` can now be called without error message. This is useful when `conditionMessage()` is used to generate the message at print-time. * Fixed an infinite loop in `eval_tidy()`. It occurred when evaluating a quosure that inherits from the mask itself. * `env_bind()`'s performance has been significantly improved by fixing a bug that caused values to be repeatedly looked up by name. * `cnd_muffle()` now checks that a restart exists before invoking it. The restart might not exist if the condition is signalled with a different function (such as `stop(warning_cnd)`). * `trace_length()` returns the number of frames in a backtrace. * Added internal utility `cnd_entrace()` to add a backtrace to a condition. * `rlang::last_error()` backtraces are no longer displayed in red. * `x %|% y` now also works when `y` is of same length as `x` (@rcannood, #806). * Empty named lists are now deparsed more explicitly as `""`. * Fixed `chr()` bug causing it to return invisibly. # rlang 0.4.0 ## Tidy evaluation ### Interpolate function inputs with the curly-curly operator The main change of this release is the new tidy evaluation operator `{{`. This operator abstracts the quote-and-unquote idiom into a single interpolation step: ``` my_wrapper <- function(data, var, by) { data %>% group_by({{ by }}) %>% summarise(average = mean({{ var }}, na.rm = TRUE)) } ``` `{{ var }}` is a shortcut for `!!enquo(var)` that should be easier on the eyes, and easier to learn and teach. Note that for multiple inputs, the existing documentation doesn't stress enough that you can just pass dots straight to other tidy eval functions. There is no need for quote-and-unquote unless you need to modify the inputs or their names in some way: ``` my_wrapper <- function(data, var, ...) { data %>% group_by(...) %>% summarise(average = mean({{ var }}, na.rm = TRUE)) } ``` ### More robust `.env` pronoun Another improvement to tidy evaluation should make it easier to use the `.env` pronoun. Starting from this release, subsetting an object from the `.env` pronoun now evaluates the corresponding symbol. This makes `.env` more robust, in particular in magrittr pipelines. The following example would previously fail: ``` foo <- 10 mtcars %>% mutate(cyl = cyl * .env$foo) ``` This way, using the `.env` pronoun is now equivalent to unquoting a constant objects, but with an easier syntax: ``` mtcars %>% mutate(cyl = cyl * !!foo) ``` Note that following this change, and despite its name, `.env` is no longer referring to a bare environment. Instead, it is a special shortcut with its own rules. Similarly, the `.data` pronoun is not really a data frame. ## New functions and features * New `pairlist2()` function with splicing support. It preserves missing arguments, which makes it useful for lists of formal parameters for functions. * `is_bool()` is a scalar type predicate that checks whether its input is a single `TRUE` or `FALSE`. Like `is_string()`, it returns `FALSE` when the input is missing. This is useful for type-checking function arguments (#695). * `is_string()` gains a `string` argument. `is_string(x, "foo")` is a shortcut for `is_character(x) && length(x) == 1 && identical(x, "foo")`. * Lists of quosures now have pillar methods for display in tibbles. * `set_names()` now names unnamed input vectors before applying a function. The following expressions are now equivalent: ``` letters %>% set_names() %>% set_names(toupper) letters %>% set_names(toupper) ``` * You can now pass a character vector as message argument for `abort()`, `warn()`, `inform()`, and `signal()`. The vector is collapsed to a single string with a `"\n"` newline separating each element of the input vector (#744). * `maybe_missing()` gains a `default` argument. * New functions for weak references: `new_weakref()`, `weakref_key()`, `weakref_value()`, and `is_weakref()` (@wch, #787). ## Performance * The performance of `exec()` has been improved. It is now on the same order of performance as `do.call()`, though slightly slower. * `call2()` now uses the new `pairlist2()` function internally. This considerably improves its performance. This also means it now preserves empty arguments: ``` call2("fn", 1, , foo = ) #> fn(1, , foo = ) ``` ## Bugfixes and small improvements * `with_handlers()` now installs calling handlers first on the stack, no matter their location in the argument list. This way they always take precedence over exiting handlers, which ensures their side effects (such as logging) take place (#718). * In rlang backtraces, the `global::` prefix is now only added when the function directly inherits from the global environment. Functions inheriting indirectly no longer have a namespace qualifier (#733). * `options(error = rlang::entrace)` now has better support for errors thrown from C (#779). It also saves structured errors in the `error` field of `rlang::last_error()`. * `ns_env()` and `ns_env_name()` (experimental functions) now support functions and environments consisently. They also require an argument from now on. * `is_interactive()` is aware of the `TESTTHAT` environment variable and returns `FALSE` when it is `"true"` (@jennybc, #738). * `fn_fmls()` and variants no longer coerce their input to a closure. Instead, they throw an error. * Fixed an issue in knitr that caused backtraces to print even when `error = TRUE`. * The return object from `as_function()` now inherits from `"function"` (@richierocks, #735). ## Lifecycle We commit to support 5 versions of R. As R 3.6 is about to be released, rlang now requires R 3.2 or greater. We're also continuing our efforts to streamline and narrow the rlang API. * `modify()` and `prepend()` (two experimental functions marked as in the questioning stage since rlang 0.3.0) are now deprecated. Vector functions are now out of scope for rlang. They might be revived in the vctrs or funs packages. * `exiting()` is soft-deprecated because `with_handlers()` treats handlers as exiting by default. * The vector constructors like `lgl()` or `new_logical()` are now in the questioning stage. They are likely to be moved to the vctrs package at some point. Same for the missing values shortcuts like `na_lgl`. * `as_logical()`, `as_integer()`, etc have been soft-deprecated in favour of `vctrs::vec_cast()`. * `type_of()`, `switch_type()`, `coerce_type()`, and friends are soft-deprecated. * The encoding and locale API was summarily archived. This API didn't bring any value and wasn't used on CRAN. * `lang_type_of()`, `switch_lang()`, and `coerce_lang()` were archived. These functions were not used on CRAN or internally. * Subsetting quosures with `[` or `[[` is soft-deprecated. * All functions that were soft-deprecated, deprecated, or defunct in previous releases have been bumped to the next lifecycle stage. # rlang 0.3.2 * Fixed protection issue reported by rchk. * The experimental option `rlang__backtrace_on_error` is no longer experimental and has been renamed to `rlang_backtrace_on_error`. * New "none" option for `rlang_backtrace_on_error`. * Unary operators applied to quosures now give better error messages. * Fixed issue with backtraces of warnings promoted to error, and entraced via `withCallingHandlers()`. The issue didn't affect entracing via top level `options(error = rlang::entrace)` handling. # rlang 0.3.1 This patch release polishes the new backtrace feature introduced in rlang 0.3.0 and solves bugs for the upcoming release of purrr 0.3.0. It also features `as_label()` and `as_name()` which are meant to replace `quo_name()` in the future. Finally, a bunch of deparsing issues have been fixed. ## Backtrace fixes * New `entrace()` condition handler. Add this to your RProfile to enable rlang backtraces for all errors, including warnings promoted to errors: ```r if (requireNamespace("rlang", quietly = TRUE)) { options(error = rlang::entrace) } ``` This handler also works as a calling handler: ```r with_handlers( error = calling(entrace), foo(bar) ) ``` However it's often more practical to use `with_abort()` in that case: ```r with_abort(foo(bar)) ``` * `with_abort()` gains a `classes` argument to promote any kind of condition to an rlang error. * New `last_trace()` shortcut to print the backtrace stored in the `last_error()`. * Backtrace objects now print in full by default. * Calls in backtraces are now numbered according to their position in the call tree. The numbering is non-contiguous for simplified backtraces because of omitted call frames. * `catch_cnd()` gains a `classes` argument to specify which classes of condition to catch. It returns `NULL` if the expected condition could not be caught (#696). ## `as_label()` and `as_name()` The new `as_label()` and `as_name()` functions should be used instead of `quo_name()` to transform objects and quoted expressions to a string. We have noticed that tidy eval users often use `quo_name()` to extract names from quosured symbols. This is not a good use for that function because the way `quo_name()` creates a string is not a well defined operation. For this reason, we are replacing `quo_name()` with two new functions that have more clearly defined purposes, and hopefully better names reflecting those purposes. Use `as_label()` to transform any object to a short human-readable description, and `as_name()` to extract names from (possibly quosured) symbols. Create labels with `as_label()` to: * Display an object in a concise way, for example to labellise axes in a graphical plot. * Give default names to columns in a data frame. In this case, labelling is the first step before name repair. We expect `as_label()` to gain additional parameters in the future, for example to control the maximum width of a label. The way an object is labelled is thus subject to change. On the other hand, `as_name()` transforms symbols back to a string in a well defined manner. Unlike `as_label()`, `as_name()` guarantees the roundtrip symbol -> string -> symbol. In general, if you don't know for sure what kind of object you're dealing with (a call, a symbol, an unquoted constant), use `as_label()` and make no assumption about the resulting string. If you know you have a symbol and need the name of the object it refers to, use `as_name()`. For instance, use `as_label()` with objects captured with `enquo()` and `as_name()` with symbols captured with `ensym()`. Note that `quo_name()` will only be soft-deprecated at the next major version of rlang (0.4.0). At this point, it will start issuing once-per-session warnings in scripts, but not in packages. It will then be deprecated in yet another major version, at which point it will issue once-per-session warnings in packages as well. You thus have plenty of time to change your code. ## Minor fixes and features * New `is_interactive()` function. It serves the same purpose as `base::interactive()` but also checks if knitr is in progress and provides an escape hatch. Use `with_interactive()` and `scoped_interactive()` to override the return value of `is_interactive()`. This is useful in unit tests or to manually turn on interactive features in RMarkdown outputs * `calling()` now boxes its argument. * New `done()` function to box a value. Done boxes are sentinels to indicate early termination of a loop or computation. For instance, it will be used in the purrr package to allow users to shortcircuit a reduction or accumulation. * `new_box()` now accepts additional attributes passed to `structure()`. * Fixed a quotation bug with binary operators of zero or one argument such as `` `/`(1) `` (#652). They are now deparsed and printed properly as well. * New `call_ns()` function to retrieve the namespace of a call. Returns `NULL` if the call is not namespaced. * Top-level S3 objects are now deparsed properly. * Empty `{` blocks are now deparsed on the same line. * Fixed a deparsing issue with symbols containing non-ASCII characters (#691). * `expr_print()` now handles `[` and `[[` operators correctly, and deparses non-syntactic symbols with backticks. * `call_modify()` now respects ordering of unnamed inputs. Before this fix, it would move all unnamed inputs after named ones. * `as_closure()` wrappers now call primitives with positional arguments to avoid edge case issues of argument matching. * `as_closure()` wrappers now dispatch properly on methods defined in the global environment (tidyverse/purrr#459). * `as_closure()` now supports both base-style (`e1` and `e2`) and purrr-style (`.x` and `.y`) arguments with binary primitives. * `exec()` takes `.fn` as first argument instead of `f`, for consistency with other rlang functions. * Fixed infinite loop with quosures created inside a data mask. * Base errors set as `parent` of rlang errors are now printed correctly. # rlang 0.3.0 ## Breaking changes The rlang API is still maturing. In this section, you'll find hard breaking changes. See the life cycle section below for an exhaustive list of API changes. * `quo_text()` now deparses non-syntactic symbols with backticks: ``` quo_text(sym("foo+")) #> [1] "`foo+`" ``` This caused a number of issues in reverse dependencies as `quo_text()` tends to be used for converting symbols to strings. `quo_text()` and `quo_name()` should not be used for this purpose because they are general purpose deparsers. These functions should generally only be used for printing outputs or creating default labels. If you need to convert symbols to strings, please use `as_string()` rather than `quo_text()`. We have extended the documentation of `?quo_text` and `?quo_name` to make these points clearer. * `exprs()` no longer flattens quosures. `exprs(!!!quos(x, y))` is now equivalent to `quos(x, y)`. * The sentinel for removing arguments in `call_modify()` has been changed from `NULL` to `zap()`. This breaking change is motivated by the ambiguity of `NULL` with valid argument values. ```r call_modify(call, arg = NULL) # Add `arg = NULL` to the call call_modify(call, arg = zap()) # Remove the `arg` argument from the call ``` * The `%@%` operator now quotes its input and supports S4 objects. This makes it directly equivalent to `@` except that it extracts attributes for non-S4 objects (#207). * Taking the `env_parent()` of the empty environment is now an error. ## Summary The changes for this version are organised around three main themes: error reporting, tidy eval, and tidy dots. * `abort()` now records backtraces automatically in the error object. Errors thrown with `abort()` invite users to call `rlang::last_error()` to see a backtrace and help identifying where and why the error occurred. The backtraces created by rlang (you can create one manually with `trace_back()`) are printed in a simplified form by default that removes implementation details from the backtrace. To see the full backtrace, call `summary(rlang::last_error())`. `abort()` also gains a `parent` argument. This is meant for situations where you're calling a low level API (to download a file, parse a JSON file, etc) and would like to intercept errors with `base::tryCatch()` or `rlang::with_handlers()` and rethrow them with a high-level message. Call `abort()` with the intercepted error as the `parent` argument. When the user prints `rlang::last_error()`, the backtrace will be shown in two sections corresponding to the high-level and low-level contexts. In order to get segmented backtraces, the low-level error has to be thrown with `abort()`. When that's not the case, you can call the low-level function within `with_abort()` to automatically promote all errors to rlang errors. * The tidy eval changes are mostly for developers of data masking APIs. The main user-facing change is that `.data[[` is now an unquote operator so that `var` in `.data[[var]]` is never masked by data frame columns and always picked from the environment. This makes the pronoun safe for programming in functions. * The `!!!` operator now supports all classed objects like factors. It calls `as.list()` on S3 objects and `as(x, "list")` on S4 objects. * `dots_list()` gains several arguments to control how dots are collected. You can control the selection of arguments with the same name with `.homonyms` (keep first, last, all, or abort). You can also elect to preserve empty arguments with `.preserve_empty`. ## Conditions and errors * New `trace_back()` captures a backtrace. Compared to the base R traceback, it contains additional structure about the relationship between frames. It comes with tools for automatically restricting to frames after a certain environment on the stack, and to simplify when printing. These backtraces are now recorded in errors thrown by `abort()` (see below). * `abort()` gains a `parent` argument to specify a parent error. This is meant for situations where a low-level error is expected (e.g. download or parsing failed) and you'd like to throw an error with higher level information. Specifying the low-level error as parent makes it possible to partition the backtraces based on ancestry. * Errors thrown with `abort()` now embed a backtrace in the condition object. It is no longer necessary to record a trace with a calling handler for such errors. * `with_abort()` runs expressions in a context where all errors are promoted to rlang errors and gain a backtrace. * Unhandled errors thrown by `abort()` are now automatically saved and can be retrieved with `rlang::last_error()`. The error prints with a simplified backtrace. Call `summary(last_error())` to see the full backtrace. * New experimental option `rlang__backtrace_on_error` to display backtraces alongside error messages. See `?rlang::abort` for supported options. * The new `signal()` function completes the `abort()`, `warn()` and `inform()` family. It creates and signals a bare condition. * New `interrupt()` function to simulate an user interrupt from R code. * `cnd_signal()` now dispatches messages, warnings, errors and interrupts to the relevant signalling functions (`message()`, `warning()`, `stop()` and the C function `Rf_onintr()`). This makes it a good choice to resignal a captured condition. * New `cnd_type()` helper to determine the type of a condition (`"condition"`, `"message"`, `"warning"`, `"error"` or `"interrupt"`). * `abort()`, `warn()` and `inform()` now accepts metadata with `...`. The data are stored in the condition and can be examined by user handlers. Consequently all arguments have been renamed and prefixed with a dot (to limit naming conflicts between arguments and metadata names). * `with_handlers()` treats bare functions as exiting handlers (equivalent to handlers supplied to `tryCatch()`). It also supports the formula shortcut for lambda functions (as in purrr). * `with_handlers()` now produces a cleaner stack trace. ## Tidy dots * The input types of `!!!` have been standardised. `!!!` is generally defined on vectors: it takes a vector (typically, a list) and unquotes each element as a separate argument. The standardisation makes `!!!` behave the same in functions taking dots with `list2()` and in quoting functions. `!!!` accepts these types: - Lists, pairlists, and atomic vectors. If they have a class, they are converted with `base::as.list()` to allow S3 dispatch. Following this change, objects like factors can now be spliced without data loss. - S4 objects. These are converted with `as(obj, "list")` before splicing. - Quoted blocks of expressions, i.e. `{ }` calls `!!!` disallows: - Any other objects like functions or environments, but also language objects like formula, symbols, or quosures. Quoting functions used to automatically wrap language objects in lists to make them spliceable. This behaviour is now soft-deprecated and it is no longer valid to write `!!!enquo(x)`. Please unquote scalar objects with `!!` instead. * `dots_list()`, `enexprs()` and `enquos()` gain a `.homonyms` argument to control how to treat arguments with the same name. The default is to keep them. Set it to `"first"` or `"last"` to keep only the first or last occurrences. Set it to `"error"` to raise an informative error about the arguments with duplicated names. * `enexprs()` and `enquos()` now support `.ignore_empty = "all"` with named arguments as well (#414). * `dots_list()` gains a `.preserve_empty` argument. When `TRUE`, empty arguments are stored as missing arguments (see `?missing_arg`). * `dots_list()`, `enexprs()` and `enquos()` gain a `.check_assign` argument. When `TRUE`, a warning is issued when a `<-` call is detected in `...`. No warning is issued if the assignment is wrapped in brackets like `{ a <- 1 }`. The warning lets users know about a possible typo in their code (assigning instead of matching a function parameter) and requires them to be explicit that they really want to assign to a variable by wrapping in parentheses. * `lapply(list(quote(foo)), list2)` no longer evaluates `foo` (#580). ## Tidy eval * You can now unquote quosured symbols as LHS of `:=`. The symbol is automatically unwrapped from the quosure. * Quosure methods have been defined for common operations like `==`. These methods fail with an informative error message suggesting to unquote the quosure (#478, #tidyverse/dplyr#3476). * `as_data_pronoun()` now accepts data masks. If the mask has multiple environments, all of these are looked up when subsetting the pronoun. Function objects stored in the mask are bypassed. * It is now possible to unquote strings in function position. This is consistent with how the R parser coerces strings to symbols. These two expressions are now equivalent: `expr("foo"())` and `expr((!!"foo")())`. * Quosures converted to functions with `as_function()` now support nested quosures. * `expr_deparse()` (used to print quosures at the console) now escapes special characters. For instance, newlines now print as `"\n"` (#484). This ensures that the roundtrip `parse_expr(expr_deparse(x))` is not lossy. * `new_data_mask()` now throws an error when `bottom` is not a child of `top` (#551). * Formulas are now evaluated in the correct environment within `eval_tidy()`. This fixes issues in dplyr and other tidy-evaluation interfaces. * New functions `new_quosures()` and `as_quosures()` to create or coerce to a list of quosures. This is a small S3 class that ensures two invariants on subsetting and concatenation: that each element is a quosure and that the list is always named even if only with a vector of empty strings. ## Environments * `env()` now treats a single unnamed argument as the parent of the new environment. Consequently, `child_env()` is now superfluous and is now in questioning life cycle. * New `current_env()` and `current_fn()` functions to retrieve the current environment or the function being evaluated. They are equivalent to `base::environment()` and `base::sys.function()` called without argument. * `env_get()` and `env_get_list()` gain a `default` argument to provide a default value for non-existing bindings. * `env_poke()` now returns the old value invisibly rather than the input environment. * The new function `env_name()` returns the name of an environment. It always adds the "namespace:" prefix to namespace names. It returns "global" instead of ".GlobalEnv" or "R_GlobalEnv", "empty" instead of "R_EmptyEnv". The companion `env_label()` is like `env_name()` but returns the memory address for anonymous environments. * `env_parents()` now returns a named list. The names are taken with `env_name()`. * `env_parents()` and `env_tail()` now stop at the global environment by default. This can be changed with the `last` argument. The empty environment is always a stopping condition so you can take the parents or the tail of an environment on the search path without changing the default. * New predicates `env_binding_are_active()` and `env_binding_are_lazy()` detect the kind of bindings in an environment. * `env_binding_lock()` and `env_binding_unlock()` allows to lock and unlock multiple bindings. The predicate `env_binding_are_locked()` tests if bindings are locked. * `env_lock()` and `env_is_locked()` lock an environment or test if an environment is locked. * `env_print()` pretty-prints environments. It shows the contents (up to 20 elements) and the properties of the environment. * `is_scoped()` has been soft-deprecated and renamed to `is_attached()`. It now supports environments in addition to search names. * `env_bind_lazy()` and `env_bind_active()` now support quosures. * `env_bind_exprs()` and `env_bind_fns()` are soft-deprecated and renamed to `env_bind_lazy()` and `env_bind_active()` for clarity and consistency. * `env_bind()`, `env_bind_exprs()`, and `env_bind_fns()` now return the list of old binding values (or missing arguments when there is no old value). This makes it easy to restore the original environment state: ``` old <- env_bind(env, foo = "foo", bar = "bar") env_bind(env, !!!old) ``` * `env_bind()` now supports binding missing arguments and removing bindings with zap sentinels. `env_bind(env, foo = )` binds a missing argument and `env_bind(env, foo = zap())` removes the `foo` binding. * The `inherit` argument of `env_get()` and `env_get_list()` has changed position. It now comes after `default`. * `scoped_bindings()` and `with_bindings()` can now be called without bindings. * `env_clone()` now recreates active bindings correctly. * `env_get()` now evaluates promises and active bindings since these are internal objects which should not be exposed at the R level (#554) * `env_print()` calls `get_env()` on its argument, making it easier to see the environment of closures and quosures (#567). * `env_get()` now supports retrieving missing arguments when `inherit` is `FALSE`. ## Calls * `is_call()` now accepts multiple namespaces. For instance `is_call(x, "list", ns = c("", "base"))` will match if `x` is `list()` or if it's `base::list()`: * `call_modify()` has better support for `...` and now treats it like a named argument. `call_modify(call, ... = )` adds `...` to the call and `call_modify(call, ... = NULL)` removes it. * `call_modify()` now preserves empty arguments. It is no longer necessary to use `missing_arg()` to add a missing argument to a call. This is possible thanks to the new `.preserve_empty` option of `dots_list()`. * `call_modify()` now supports removing unexisting arguments (#393) and passing multiple arguments with the same name (#398). The new `.homonyms` argument controls how to treat these arguments. * `call_standardise()` now handles primitive functions like `~` properly (#473). * `call_print_type()` indicates how a call is deparsed and printed at the console by R: prefix, infix, and special form. * The `call_` functions such as `call_modify()` now correctly check that their input is the right type (#187). ## Other improvements and fixes * New function `zap()` returns a sentinel that instructs functions like `env_bind()` or `call_modify()` that objects are to be removed. * New function `rep_named()` repeats value along a character vector of names. * New function `exec()` is a simpler replacement to `invoke()` (#536). `invoke()` has been soft-deprecated. * Lambda functions created from formulas with `as_function()` are now classed. Use `is_lambda()` to check a function was created with the formula shorthand. * `is_integerish()` now supports large double values (#578). * `are_na()` now requires atomic vectors (#558). * The operator `%@%` has now a replacement version to update attributes of an object (#207). * `fn_body()` always returns a `{` block, even if the function has a single expression. For instance `fn_body(function(x) do()) ` returns `quote({ do() })`. * `is_string()` now returns `FALSE` for `NA_character_`. * The vector predicates have been rewritten in C for performance. * The `finite` argument of `is_integerish()` is now `NULL` by default. Missing values are now considered as non-finite for consistency with `base::is.finite()`. * `is_bare_integerish()` and `is_scalar_integerish()` gain a `finite` argument for consistency with `is_integerish()`. * `flatten_if()` and `squash_if()` now handle primitive functions like `base::is.list()` as predicates. * `is_symbol()` now accepts a character vector of names to mach the symbol against. * `parse_exprs()` and `parse_quos()` now support character vectors. Note that the output may be longer than the input as each string may yield multiple expressions (such as `"foo; bar"`). * `parse_quos()` now adds the `quosures` class to its output. ## Lifecycle ### Soft-deprecated functions and arguments rlang 0.3.0 introduces a new warning mechanism for soft-deprecated functions and arguments. A warning is issued, but only under one of these circumstances: * rlang has been attached with a `library()` call. * The deprecated function has been called from the global environment. In addition, deprecation warnings appear only once per session in order to not be disruptive. Deprecation warnings shouldn't make R CMD check fail for packages using testthat. However, `expect_silent()` can transform the warning to a hard failure. #### tidyeval * `.data[[foo]]` is now an unquote operator. This guarantees that `foo` is evaluated in the context rather than the data mask and makes it easier to treat `.data[["bar"]]` the same way as a symbol. For instance, this will help ensuring that `group_by(df, .data[["name"]])` and `group_by(df, name)` produce the same column name. * Automatic naming of expressions now uses a new deparser (still unexported) instead of `quo_text()`. Following this change, automatic naming is now compatible with all object types (via `pillar::type_sum()` if available), prevents multi-line names, and ensures `name` and `.data[["name"]]` are given the same default name. * Supplying a name with `!!!` calls is soft-deprecated. This name is ignored because only the names of the spliced vector are applied. * Quosure lists returned by `quos()` and `enquos()` now have "list-of" behaviour: the types of new elements are checked when adding objects to the list. Consequently, assigning non-quosure objects to quosure lists is now soft-deprecated. Please coerce to a bare list with `as.list()` beforehand. * `as_quosure()` now requires an explicit environment for symbols and calls. This should typically be the environment in which the expression was created. * `names()` and `length()` methods for data pronouns are deprecated. It is no longer valid to write `names(.data)` or `length(.data)`. * Using `as.character()` on quosures is soft-deprecated (#523). #### Miscellaneous * Using `get_env()` without supplying an environment is now soft-deprecated. Please use `current_env()` to retrieve the current environment. * The frame and stack API is soft-deprecated. Some of the functionality has been replaced by `trace_back()`. * The `new_vector_along()` family is soft-deprecated because these functions are longer to type than the equivalent `rep_along()` or `rep_named()` calls without added clarity. * Passing environment wrappers like formulas or functions to `env_` functions is now soft-deprecated. This internal genericity was causing confusion (see issue #427). You should now extract the environment separately before calling these functions. This change concerns `env_depth()`, `env_poke_parent()`, `env_parent<-`, `env_tail()`, `set_env()`, `env_clone()`, `env_inherits()`, `env_bind()`, `scoped_bindings()`, `with_bindings()`, `env_poke()`, `env_has()`, `env_get()`, `env_names()`, `env_bind_exprs()` and `env_bind_fns()`. * `cnd_signal()` now always installs a muffling restart for non-critical conditions. Consequently the `.mufflable` argument has been soft-deprecated and no longer has any effect. ### Deprecated functions and arguments Deprecated functions and arguments issue a warning inconditionally, but only once per session. * Calling `UQ()` and `UQS()` with the rlang namespace qualifier is deprecated as of rlang 0.3.0. Just use the unqualified forms instead: ``` # Bad rlang::expr(mean(rlang::UQ(var) * 100)) # Ok rlang::expr(mean(UQ(var) * 100)) # Good rlang::expr(mean(!!var * 100)) ``` Although soft-deprecated since rlang 0.2.0, `UQ()` and `UQS()` can still be used for now. * The `call` argument of `abort()` and condition constructors is now deprecated in favour of storing full backtraces. * The `.standardise` argument of `call_modify()` is deprecated. Please use `call_standardise()` beforehand. * The `sentinel` argument of `env_tail()` has been deprecated and renamed to `last`. ### Defunct functions and arguments Defunct functions and arguments throw an error when used. * `as_dictionary()` is now defunct. * The experimental function `rst_muffle()` is now defunct. Please use `cnd_muffle()` instead. Unlike its predecessor, `cnd_muffle()` is not generic. It is marked as a calling handler and thus can be passed directly to `with_handlers()` to muffle specific conditions (such as specific subclasses of warnings). * `cnd_inform()`, `cnd_warn()` and `cnd_abort()` are retired and defunct. The old `cnd_message()`, `cnd_warning()`, `cnd_error()` and `new_cnd()` constructors deprecated in rlang 0.2.0 are now defunct. * Modifying a condition with `cnd_signal()` is defunct. In addition, creating a condition with `cnd_signal()` is soft-deprecated, please use the new function [signal()] instead. * `inplace()` has been renamed to `calling()` to follow base R terminology more closely. ### Functions and arguments in the questioning stage We are no longer convinced these functions are the right approach but we do not have a precise alternative yet. * The functions from the restart API are now in the questioning lifecycle stage. It is not clear yet whether we want to recommend restarts as a style of programming in R. * `prepend()` and `modify()` are in the questioning stage, as well as `as_logical()`, `as_character()`, etc. We are still figuring out what vector tools belong in rlang. * `flatten()`, `squash()` and their atomic variants are now in the questioning lifecycle stage. They have slightly different semantics than the flattening functions in purrr and we are currently rethinking our approach to flattening with the new typing facilities of the vctrs package. # rlang 0.2.2 This is a maintenance release that fixes several garbage collection protection issues. # rlang 0.2.1 This is a maintenance release that fixes several tidy evaluation issues. * Functions with tidy dots support now allow splicing atomic vectors. * Quosures no longer capture the current `srcref`. * Formulas are now evaluated in the correct environment by `eval_tidy()`. This fixes issues in dplyr and other tidy-evaluation interfaces. # rlang 0.2.0 This release of rlang is mostly an effort at polishing the tidy evaluation framework. All tidy eval functions and operators have been rewritten in C in order to improve performance. Capture of expression, quasiquotation, and evaluation of quosures are now vastly faster. On the UI side, many of the inconveniences that affected the first release of rlang have been solved: * The `!!` operator now has the precedence of unary `+` and `-` which allows a much more natural syntax: `!!a > b` only unquotes `a` rather than the whole `a > b` expression. * `enquo()` works in magrittr pipes: `mtcars %>% select(!!enquo(var))`. * `enquos()` is a variant of `quos()` that has a more natural interface for capturing multiple arguments and `...`. See the first section below for a complete list of changes to the tidy evaluation framework. This release also polishes the rlang API. Many functions have been renamed as we get a better feel for the consistency and clarity of the API. Note that rlang as a whole is still maturing and some functions are even experimental. In order to make things clearer for users of rlang, we have started to develop a set of conventions to document the current stability of each function. You will now find "lifecycle" sections in documentation topics. In addition we have gathered all lifecycle information in the `?rlang::lifecycle` help page. Please only use functions marked as stable in your projects unless you are prepared to deal with occasional backward incompatible updates. ## Tidy evaluation * The backend for `quos()`, `exprs()`, `list2()`, `dots_list()`, etc is now written in C. This greatly improve the performance of dots capture, especially with the splicing operator `!!!` which now scales much better (you'll see a 1000x performance gain in some cases). The unquoting algorithm has also been improved which makes `enexpr()` and `enquo()` more efficient as well. * The tidy eval `!!` operator now binds tightly. You no longer have to wrap it in parentheses, i.e. `!!x > y` will only unquote `x`. Technically the `!!` operator has the same precedence as unary `-` and `+`. This means that `!!a:b` and `!!a + b` are equivalent to `(!!a):b` and `(!!a) + b`. On the other hand `!!a^b` and `!!a$b` are equivalent to`!!(a^b)` and `!!(a$b)`. * The print method for quosures has been greatly improved. Quosures no longer appear as formulas but as expressions prefixed with `^`; quosures are colourised according to their environment; unquoted objects are displayed between angular brackets instead of code (i.e. an unquoted integer vector is shown as `` rather than `1:2`); unquoted S3 objects are displayed using `pillar::type_sum()` if available. * New `enquos()` function to capture arguments. It treats `...` the same way as `quos()` but can also capture named arguments just like `enquo()`, i.e. one level up. By comparison `quos(arg)` only captures the name `arg` rather than the expression supplied to the `arg` argument. In addition, `enexprs()` is like `enquos()` but like `exprs()` it returns bare expressions. And `ensyms()` expects strings or symbols. * It is now possible to use `enquo()` within a magrittr pipe: ``` select_one <- function(df, var) { df %>% dplyr::select(!!enquo(var)) } ``` Technically, this is because `enquo()` now also captures arguments in parents of the current environment rather than just in the current environment. The flip side of this increased flexibility is that if you made a typo in the name of the variable you want to capture, and if an object of that name exists anywhere in the parent contexts, you will capture that object rather than getting an error. * `quo_expr()` has been renamed to `quo_squash()` in order to better reflect that it is a lossy operation that flattens all nested quosures. * `!!!` now accepts any kind of objects for consistency. Scalar types are treated as vectors of length 1. Previously only symbolic objects like symbols and calls were treated as such. * `ensym()` is a new variant of `enexpr()` that expects a symbol or a string and always returns a symbol. If a complex expression is supplied it fails with an error. * `exprs()` and `quos()` gain a `.unquote_names` arguments to switch off interpretation of `:=` as a name operator. This should be useful for programming on the language targetting APIs such as data.table. * `exprs()` gains a `.named` option to auto-label its arguments (#267). * Functions taking dots by value rather than by expression (e.g. regular functions, not quoting functions) have a more restricted set of unquoting operations. They only support `:=` and `!!!`, and only at top-level. I.e. `dots_list(!!! x)` is valid but not `dots_list(nested_call(!!! x))` (#217). * Functions taking dots with `list2()` or `dots_list()` now support splicing of `NULL` values. `!!! NULL` is equivalent to `!!! list()` (#242). * Capture operators now support evaluated arguments. Capturing a forced or evaluated argument is exactly the same as unquoting that argument: the actual object (even if a vector) is inlined in the expression. Capturing a forced argument occurs when you use `enquo()`, `enexpr()`, etc too late. It also happens when your quoting function is supplied to `lapply()` or when you try to quote the first argument of an S3 method (which is necessarily evaluated in order to detect which class to dispatch to). (#295, #300). * Parentheses around `!!` are automatically removed. This makes the generated expression call cleaner: `(!! sym("name"))(arg)`. Note that removing the parentheses will never affect the actual precedence within the expression as the parentheses are only useful when parsing code as text. The parentheses will also be added by R when printing code if needed (#296). * Quasiquotation now supports `!!` and `!!!` as functional forms: ``` expr(`!!`(var)) quo(call(`!!!`(var))) ``` This is consistent with the way native R operators parses to function calls. These new functional forms are to be preferred to `UQ()` and `UQS()`. We are now questioning the latter and might deprecate them in a future release. * The quasiquotation parser now gives meaningful errors in corner cases to help you figure out what is wrong. * New getters and setters for quosures: `quo_get_expr()`, `quo_get_env()`, `quo_set_expr()`, and `quo_set_env()`. Compared to `get_expr()` etc, these accessors only work on quosures and are slightly more efficient. * `quo_is_symbol()` and `quo_is_call()` now take the same set of arguments as `is_symbol()` and `is_call()`. * `enquo()` and `enexpr()` now deal with default values correctly (#201). * Splicing a list no longer mutates it (#280). ## Conditions * The new functions `cnd_warn()` and `cnd_inform()` transform conditions to warnings or messages before signalling them. * `cnd_signal()` now returns invisibly. * `cnd_signal()` and `cnd_abort()` now accept character vectors to create typed conditions with several S3 subclasses. * `is_condition()` is now properly exported. * Condition signallers such as `cnd_signal()` and `abort()` now accept a call depth as `call` arguments. This allows plucking a call from further up the call stack (#30). * New helper `catch_cnd()`. This is a small wrapper around `tryCatch()` that captures and returns any signalled condition. It returns `NULL` if none was signalled. * `cnd_abort()` now adds the correct S3 classes for error conditions. This fixes error catching, for instance by `testthat::expect_error()`. ## Environments * `env_get_list()` retrieves muliple bindings from an environment into a named list. * `with_bindings()` and `scoped_bindings()` establish temporary bindings in an environment. * `is_namespace()` is a snake case wrapper around `isNamespace()`. ## Various features * New functions `inherits_any()`, `inherits_all()`, and `inherits_only()`. They allow testing for inheritance from multiple classes. The `_any` variant is equivalent to `base::inherits()` but is more explicit about its behaviour. `inherits_all()` checks that all classes are present in order and `inherits_only()` checks that the class vectors are identical. * New `fn_fmls<-` and `fn_fmls_names<-` setters. * New function experimental function `chr_unserialise_unicode()` for turning characters serialised to unicode point form (e.g. ``) to UTF-8. In addition, `as_utf8_character()` now translates those as well. (@krlmlr) * `expr_label()` now supports quoted function definition calls (#275). * `call_modify()` and `call_standardise()` gain an argument to specify an environment. The call definition is looked up in that environment when the call to modify or standardise is not wrapped in a quosure. * `is_symbol()` gains a `name` argument to check that that the symbol name matches a string (#287). * New `rlang_box` class. Its purpose is similar to the `AsIs` class from `base::I()`, i.e. it protects a value temporarily. However it does so by wrapping the value in a scalar list. Use `new_box()` to create a boxed value, `is_box()` to test for a boxed value, and `unbox()` to unbox it. `new_box()` and `is_box()` accept optional subclass. * The vector constructors such as `new_integer()`, `new_double_along()` etc gain a `names` argument. In the case of the `_along` family it defaults to the names of the input vector. ## Bugfixes * When nested quosures are evaluated with `eval_tidy()`, the `.env` pronoun now correctly refers to the current quosure under evaluation (#174). Previously it would always refer to the environment of the outermost quosure. * `as_pairlist()` (part of the experimental API) now supports `NULL` and objects of type pairlist (#397). * Fixed a performance bug in `set_names()` that caused a full copy of the vector names (@jimhester, #366). ## API changes The rlang API is maturing and still in flux. However we have made an effort to better communicate what parts are stable. We will not introduce breaking changes for stable functions unless the payoff for the change is worth the trouble. See `?rlang::lifecycle` for the lifecycle status of exported functions. * The particle "lang" has been renamed to "call": - `lang()` has been renamed to `call2()`. - `new_language()` has ben renamed to `new_call()`. - `is_lang()` has been renamed to `is_call()`. We haven't replaced the `is_unary_lang()` and `is_binary_lang()` because they are redundant with the `n` argument of `is_call()`. - All call accessors such as `lang_fn()`, `lang_name()`, `lang_args()` etc are soft-deprecated and renamed with `call_` prefix. In rlang 0.1 calls were called "language" objects in order to follow the R type nomenclature as returned by `base::typeof()`. We wanted to avoid adding to the confusion between S modes and R types. With hindsight we find it is better to use more meaningful type names. * We now use the term "data mask" instead of "overscope". We think data mask is a more natural name in the context of R. We say that that objects from user data mask objects in the current environment. This makes reference to object masking in the search path which is due to the same mechanism (in technical terms, lexical scoping with hierarchically nested environments). Following this new terminology, the new functions `as_data_mask()` and `new_data_mask()` replace `as_overscope()` and `new_overscope()`. `as_data_mask()` has also a more consistent interface. These functions are only meant for developers of tidy evaluation interfaces. * We no longer require a data mask (previously called overscope) to be cleaned up after evaluation. `overscope_clean()` is thus soft-deprecated without replacement. ### Breaking changes * `!!` now binds tightly in order to match intuitive parsing of tidy eval code, e.g. `!! x > y` is now equivalent to `(!! x) > y`. A corollary of this new syntax is that you now have to be explicit when you want to unquote the whole expression on the right of `!!`. For instance you have to explicitly write `!! (x > y)` to unquote `x > y` rather than just `x`. * `UQ()`, `UQS()` and `:=` now issue an error when called directly. The previous definitions caused surprising results when the operators were invoked in wrong places (i.e. not in quasiquoted arguments). * The prefix form `` `!!`() `` is now an alias to `!!` rather than `UQE()`. This makes it more in line with regular R syntax where operators are parsed as regular calls, e.g. `a + b` is parsed as `` `+`(a, b) `` and both forms are completely equivalent. Also the prefix form `` `!!!`() `` is now equivalent to `!!!`. * `UQE()` is now deprecated in order to simplify the syntax of quasiquotation. Please use `!! get_expr(x)` instead. * `expr_interp()` now returns a formula instead of a quosure when supplied a formula. * `is_quosureish()` and `as_quosureish()` are deprecated. These functions assumed that quosures are formulas but that is only an implementation detail. * `new_cnd()` is now `cnd()` for consistency with other constructors. Also, `cnd_error()`, `cnd_warning()` and `cnd_message()` are now `error_cnd()`, `warning_cnd()` and `message_cnd()` to follow our naming scheme according to which the type of output is a suffix rather than a prefix. * `is_node()` now returns `TRUE` for calls as well and `is_pairlist()` does not return `TRUE` for `NULL` objects. Use `is_node_list()` to determine whether an object either of type `pairlist` or `NULL`. Note that all these functions are still experimental. * `set_names()` no longer automatically splices lists of character vectors as we are moving away from automatic splicing semantics. ### Upcoming breaking changes * Calling the functional forms of unquote operators with the rlang namespace qualifier is soft-deprecated. `UQ()` and `UQS()` are not function calls so it does not make sense to namespace them. Supporting namespace qualifiers complicates the implementation of unquotation and is misleading as to the nature of unquoting (which are syntactic operators at quotation-time rather than function calls at evaluation-time). * We are now questioning `UQ()` and `UQS()` as functional forms of `!!`. If `!!` and `!!!` were native R operators, they would parse to the functional calls `` `!!`() `` and `` `!!!`() ``. This is now the preferred way to unquote with a function call rather than with the operators. We haven't decided yet whether we will deprecate `UQ()` and `UQS()` in the future. In any case we recommend using the new functional forms. * `parse_quosure()` and `parse_quosures()` are soft-deprecated in favour of `parse_quo()` and `parse_quos()`. These new names are consistent with the rule that abbreviated suffixes indicate the return type of a function. In addition the new functions require their callers to explicitly supply an environment for the quosures. * Using `f_rhs()` and `f_env()` on quosures is soft-deprecated. The fact that quosures are formulas is an implementation detail that might change in the future. Please use `quo_get_expr()` and `quo_get_env()` instead. * `quo_expr()` is soft-deprecated in favour of `quo_squash()`. `quo_expr()` was a misnomer because it implied that it was a mere expression acccessor for quosures whereas it was really a lossy operation that squashed all nested quosures. * With the renaming of the `lang` particle to `call`, all these functions are soft-deprecated: `lang()`, `is_lang()`, `lang_fn()`, `lang_name()`, `lang_args()`. In addition, `lang_head()` and `lang_tail()` are soft-deprecated without replacement because these are low level accessors that are rarely needed. * `as_overscope()` is soft-deprecated in favour of `as_data_mask()`. * The node setters were renamed from `mut_node_` prefix to `node_poke_`. This change follows a new naming convention in rlang where mutation is referred to as "poking". * `splice()` is now in questioning stage as it is not needed given the `!!!` operator works in functions taking dots with `dots_list()`. * `lgl_len()`, `int_len()` etc have been soft-deprecated and renamed with `new_` prefix, e.g. `new_logical()` and `new_integer()`. This is for consistency with other non-variadic object constructors. * `ll()` is now an alias to `list2()`. This is consistent with the new `call2()` constructor for calls. `list2()` and `call2()` are versions of `list()` and `call()` that support splicing of lists with `!!!`. `ll()` remains around as a shorthand for users who like its conciseness. * Automatic splicing of lists in vector constructors (e.g. `lgl()`, `chr()`, etc) is now soft-deprecated. Please be explicit with the splicing operator `!!!`. # rlang 0.1.6 * This is a maintenance release in anticipation of a forthcoming change to R's C API (use `MARK_NOT_MUTABLE()` instead of `SET_NAMED()`). * New function `is_reference()` to check whether two objects are one and the same. # rlang 0.1.4 * `eval_tidy()` no longer maps over lists but returns them literally. This behaviour is an overlook from past refactorings and was never documented. # rlang 0.1.2 This hotfix release makes rlang compatible with the R 3.1 branch. # rlang 0.1.1 This release includes two important fixes for tidy evaluation: * Bare formulas are now evaluated in the correct environment in tidyeval functions. * `enquo()` now works properly within compiled functions. Before this release, constants optimised by the bytecode compiler couldn't be enquoted. ## New functions: * The `new_environment()` constructor creates a child of the empty environment and takes an optional named list of data to populate it. Compared to `env()` and `child_env()`, it is meant to create environments as data structures rather than as part of a scope hierarchy. * The `new_call()` constructor creates calls out of a callable object (a function or an expression) and a pairlist of arguments. It is useful to avoid costly internal coercions between lists and pairlists of arguments. ## UI improvements: * `env_child()`'s first argument is now `.parent` instead of `parent`. * `mut_` setters like `mut_attrs()` and environment helpers like `env_bind()` and `env_unbind()` now return their (modified) input invisibly. This follows the tidyverse convention that functions called primarily for their side effects should return their input invisibly. * `is_pairlist()` now returns `TRUE` for `NULL`. We added `is_node()` to test for actual pairlist nodes. In other words, `is_pairlist()` tests for the data structure while `is_node()` tests for the type. ## Bugfixes: * `env()` and `env_child()` can now get arguments whose names start with `.`. Prior to this fix, these arguments were partial-matching on `env_bind()`'s `.env` argument. * The internal `replace_na()` symbol was renamed to avoid a collision with an exported function in tidyverse. This solves an issue occurring in old versions of R prior to 3.3.2 (#133). # rlang 0.1.0 Initial release. rlang/MD50000644000176200001440000006275713614116052011705 0ustar liggesusersc516aa9a18ed37a248f60d0177987273 *DESCRIPTION 26d4053b540b9e641ae2f5155a52722a *NAMESPACE f8a284f1b67fe17940374e513c6b4999 *NEWS.md 5af4924cec25d6004eaea90286452f11 *R/arg.R 1c165414df71d30e95d1ab364ec57700 *R/attr.R 5fab52d11771fd139f56d0a99feeb47c *R/call.R 6ebc7b6e67357e15e3659890d81fb800 *R/cnd-abort.R 2a6567e9489e66bd6dc84afbe19c31d5 *R/cnd-entrace.R 165768e009fde718a2e72c886ea6fd29 *R/cnd-error.R 929128b96a70853705474d043b0ec2dd *R/cnd-handlers.R faafdd832ccfcd734cafca6f61fd665f *R/cnd-message.R 5076c1dd518a74b797ab6d714482e662 *R/cnd-restarts.R 92ba4ba6dc1d3fbfe1fe975e65873f99 *R/cnd-signal.R ca31ea99129ea5a2f3c2fbe50cc7baab *R/cnd.R e5a9676fa2b27c9a20ed34b04731c271 *R/compat-friendly-type.R fe2b083cb49e6a80aedf7695b7b0ba07 *R/compat-lazyeval.R bf3266e842b5b0d6684b38f7ba65a8a4 *R/compat-lifecycle.R 552b6c37e0f78fa99b9233101a2c59f7 *R/compat-oldrel.R 6ff61ce96b8a0aca5f241ef7aaab4a68 *R/compat-purrr.R 4de02456d59484fb66db37255e5b1b4f *R/compat-register.R 6bf20ae75a526fd067b4656b22540ebd *R/deparse.R 242aaf55932a9915668173a2b0aa3984 *R/dots.R 8c1a2c4a2ac73781365ef285304f385c *R/env-binding.R b3b0c2050ae6947464d14514bf3295b1 *R/env-special.R 46f13081ed0377d60cd9e87e123ecc1b *R/env.R 380f9343c0a5731cd3114e4842c8a6ac *R/eval-tidy.R 01ea3d1fb018d218fb64596038f789d9 *R/eval.R 72bd835d21b98507402f640446e8f4ea *R/events.R c661ba6708a5366d94d986d9c7ec9afc *R/expr.R 2520edfb3ff5511f1837a66d624b2f3f *R/fn.R e275f9bb770963827d43f477f677a11a *R/formula.R 06a13aa37b82b2dd1c51caffedf1510f *R/lifecycle-retired.R 96f8b19e5c960f200e96e4223759ecbd *R/lifecycle.R 53b825c5101deb8bd90defafbd16cb87 *R/node.R 722427282bc96755fad869ef36f77862 *R/nse-defuse.R 25084c76251b1252428d9df991a87582 *R/nse-force.R 132a0138e9f71cb23b58f470502e08e5 *R/operators.R dca98ef6cc78e9281442c96a7fe7d35e *R/parse.R 7ed678cf3c0125579637d15454e0421e *R/quo.R 9dfbc6be257d326e5d15d30f1aac679a *R/rlang.R 5f6b9b92d0c166f1e2a2acadef364bbe *R/s3.R 4fc9517643e8358fc34188ec624cdada *R/sexp.R 72f397950f0f33bf1421c1caf7bfb714 *R/stack.R 0bc7f8968458ebd3a47f583def062bc8 *R/state.R 728889badca449f1a272477d777d7914 *R/sym.R 222e512210dc7ce93ac4fe127a7b515e *R/trace.R e95ee75b973990e9faad18594f89dbde *R/types.R 1b35c98262b47382e00066635ea67e16 *R/utils-cli-tree.R a4eb7beca392f730c331d203124ef20e *R/utils-conditions.R 520e5f54bc830142895d5f7f30d7af82 *R/utils-encoding.R 1675bf7f7c51557e19b8ff486889ee71 *R/utils.R ccc317028acdcef6c838e80a69f5c17b *R/vec-na.R ee59231a415a456645cce45c958f98a5 *R/vec-new.R c385c983f67b71461d7b0951db6a9c5d *R/vec-squash.R 7abd99704c8a9dec7e55651158cc2853 *R/vec.R 5835c34bf4379eb86b6257fd9dce56d7 *R/weakref.R 292e379abe2774db729d8879e2f4283a *README.md f109462257dcc47cdf36acc73db95860 *build/rlang.pdf c9e47dbb0e1927076ed7b2e1ec157be7 *inst/backtrace-ver 45c5d0d5c255447ab7f9f6feb8d1b89f *man/abort.Rd 80bd3cb98f7beaafd3a5760a7deb8647 *man/are_na.Rd c0222d277eed7d8f3eee103050a27c02 *man/arg_match.Rd 4b77a5dcfe61ef4fb2dfd345efc5179e *man/as_box.Rd af6d2e6c53f4b5975b0cc12e4b6beee6 *man/as_bytes.Rd 9b0b85a6f43d85821fa8cf0e16d42273 *man/as_data_mask.Rd df5d488b6e0736e2587c384302fd2b18 *man/as_env.Rd c1f68c6b5e8ed038b2d7e5d06d210c87 *man/as_environment.Rd 01ab0f0d84f37867ca6961dbd335dfa9 *man/as_function.Rd 9fdb70fad5ae4354884e4794a139d76a *man/as_label.Rd 575d97131ccb8062aed4435eab97f83a *man/as_name.Rd 23696ab1ca81af5a6a27a0322dba7bb5 *man/as_overscope.Rd 865c093d4787c7b6b4606e1edeef8380 *man/as_pairlist.Rd 3c1a051be39ec68211ab31b0b96d45f7 *man/as_quosure.Rd e49fc83ae3d468fda56ff882fea28ce1 *man/as_string.Rd 25ccdb462a218193121a0700d20c0ea5 *man/as_utf8_character.Rd efd21709654799e23eea58ff9b5cc7b7 *man/bare-type-predicates.Rd fb15f234fc440e2465266347c66955b7 *man/box.Rd 7b6d66d1361c9f2c1d15b5ba74a2789d *man/call2.Rd ac2d36604312134191c74e134ccae3cb *man/call_args.Rd 6bf3b26abfd88bbecc5715afc376ee8f *man/call_fn.Rd 2d443ee93e189ed684e9d7d40ef66e9d *man/call_inspect.Rd 0dd6834ec3aecc42710a1c526b2680ee *man/call_modify.Rd 5fbeb53f45cb69a49691185d4db8ca85 *man/call_name.Rd 1fc2c135723e034860164fce0e97c254 *man/call_standardise.Rd e44ce9514dac75c51c716bc5a8ecc716 *man/caller_env.Rd 7278cee1831a1973aab715678a475201 *man/caller_fn.Rd 296ed78ac6c8afe2f4b7135b423f730b *man/caller_frame.Rd fbb49d5cbc765200fef6ff0dfb754a5e *man/catch_cnd.Rd f0357139f4ff3aa04f404cec96bf28b3 *man/chr_unserialise_unicode.Rd c358c2cab5adaaeab1d048b8eb6585a2 *man/cnd.Rd 639f0f7f6c43dcb5f583fa6983454ce3 *man/cnd_message.Rd 48704a674969062908b413a82cb4db38 *man/cnd_muffle.Rd caa0076108771b239c58a450cae0dbd6 *man/cnd_signal.Rd ff04cda4427d58d29adffe62584a893c *man/cnd_type.Rd 6c2067d64d1478c522148882c6126eae *man/done.Rd a92a7a883787ef9787f7081de275f485 *man/dots_definitions.Rd eeb1597b3c596c220fc4d98aff8c387b *man/dots_n.Rd da1f1192db1ed365d6bec9970feb8b80 *man/dots_values.Rd ed4c24f851aeae3ba1c17434e3171742 *man/duplicate.Rd 00665622e577f6afa5e71ab00de8b295 *man/dyn-dots.Rd 16d5c0a4d87193d62a935037549cb822 *man/empty_env.Rd b5153c919b659bae705838251e9cac2f *man/entrace.Rd 085c005b35b90d969c55cd7d2abbd314 *man/env.Rd 764e7c76128489eb4d5f45255174596d *man/env_bind.Rd 67fd1c9b0b2130527fdb469b33f6a402 *man/env_bind_exprs.Rd 4765a839bd99a74d99b86dfbb3d45e0d *man/env_binding_are_active.Rd 449b54ab5b12a6bef4d2812cd2094547 *man/env_binding_lock.Rd b059d5eb28204fa598df27767b2f2571 *man/env_bury.Rd 99fc970e815450263d94f5a781dd1dbe *man/env_clone.Rd f330df1e53699e936dabc4617079c438 *man/env_depth.Rd 89e5527fc2edf344b2ce98c16c1b8430 *man/env_get.Rd e550d9e9d0461ea5dd7104b8e5bfb58c *man/env_has.Rd 2e4b15ff1b9f7d608dbaff7e1efc6399 *man/env_inherits.Rd ccade1888c23c36a05de52a40b3b4e54 *man/env_lock.Rd 5bee84cd96d0aa2d27af6ac6346ce9f0 *man/env_name.Rd 874a7a42f2f3714957ba6e2d743420a7 *man/env_names.Rd ae4667e25cec1be49e6e470ca42147a5 *man/env_parent.Rd 5ac20678463853402612e4ee31d7ab35 *man/env_poke.Rd 7d30ffcdbe51324da7ed5970cd5bb79c *man/env_print.Rd dd096f3fadf7cf90a8e04f0e3b17f734 *man/env_unbind.Rd 51cae32ed1f181fee83f694d37a8baf6 *man/env_unlock.Rd a78184e9d096bdffd0263dd117e96294 *man/eval_bare.Rd 27b8ff498d242088603bbc6c3aa6494a *man/eval_tidy.Rd cd22ab89004120aec8e2dad3b65a4b02 *man/exec.Rd 22dc0fba69f406cb106a2d026a87d744 *man/exiting.Rd 90df05f7445387c6d0a0a5f2a99c7678 *man/expr_interp.Rd 56710ca87969efee9a4aebacffad22c5 *man/expr_label.Rd cabf5acb64b83da0c166dbf9f518bbc7 *man/expr_print.Rd f8b086c885b70eb02f71449c18f23537 *man/exprs_auto_name.Rd f9fe2913a3200a2db8c3695e21b73dff *man/f_rhs.Rd 04ddff4dc1e88d33f18c8c4592ba4707 *man/f_text.Rd cb1e46f469cfbbbde29c8b5113e1d789 *man/figures/lifecycle-archived.svg c0d2e5a54f1fa4ff02bf9533079dd1f7 *man/figures/lifecycle-defunct.svg a1b8c987c676c16af790f563f96cbb1f *man/figures/lifecycle-deprecated.svg c3978703d8f40f2679795335715e98f4 *man/figures/lifecycle-experimental.svg 952b59dc07b171b97d5d982924244f61 *man/figures/lifecycle-maturing.svg 27b879bf3677ea76e3991d56ab324081 *man/figures/lifecycle-questioning.svg 46de21252239c5a23d400eae83ec6b2d *man/figures/lifecycle-retired.svg 6902bbfaf963fbc4ed98b86bda80caa2 *man/figures/lifecycle-soft-deprecated.svg 53b3f893324260b737b3c46ed2a0e643 *man/figures/lifecycle-stable.svg 42e90e0813fee26f77866a2f8025b3ba *man/figures/rlang.png d49584b139ea00cd3a3c275b64d31a4d *man/flatten.Rd da6985c05634ac13d265f277265f6dc1 *man/fn_body.Rd fb6a9867bff132541ea3830d5707ad29 *man/fn_env.Rd 6ed6c420ba258116d089292e292196fb *man/fn_fmls.Rd b74e0e52be647dbc34557875d517a605 *man/format_error_bullets.Rd bebd7f75a2c8bbf9aa62187604f507e0 *man/frame_position.Rd 173e5384356e2384b1785e2e3892f0b1 *man/friendly_type.Rd a8ae08d2e73e467d60b7ab71255ad1e2 *man/get_env.Rd 36a034671a550aae53290d36e926ddc7 *man/has_length.Rd 9314263b645e88284694fffcb74117c8 *man/has_name.Rd 37557bfdbf3f7a1800a6de3e451a0df4 *man/inherits_any.Rd 6de3c9de434c72fd5e2bbd28183d9018 *man/invoke.Rd a6fd832b4a4f7de63547ed811e8563b4 *man/is_call.Rd 7a153c5c18079918623d0b5a9ed89284 *man/is_callable.Rd 19fe249aab67dab503763ca5071c9138 *man/is_condition.Rd 66808a49eb27f386625c38a66f1dae84 *man/is_copyable.Rd ab65d6e0c9ab4b2914627ef58f4995ee *man/is_empty.Rd 45e51f0e8bf5c9d68b94a934ae594eea *man/is_env.Rd 2731bdb87a563f5a2e5903b34d9ca50b *man/is_environment.Rd 3058162050e224dae24208f0a117f066 *man/is_expr.Rd 12e4d884da00e38e64ce795847e60522 *man/is_expression.Rd f1151d26fb8190d83e147f1cd9e1cc66 *man/is_formula.Rd 593cb5564a4df84f56583d2826f7bc72 *man/is_frame.Rd 314e00bf2367739e2f376535070678d1 *man/is_function.Rd bcb58c5e8037d81718b33f3c4b4ab4c8 *man/is_installed.Rd e96c0512f0421fb5f74ea6f3784c4a1b *man/is_integerish.Rd b85b334f13f2763a8fcb2aa7b318547e *man/is_interactive.Rd 5170a8d21b9d587a244c5c80217a9610 *man/is_lang.Rd b4888543fa7d4d715edd043863b447c5 *man/is_named.Rd 468eb2b598b28efdbd4d5d9f8c12a226 *man/is_namespace.Rd a811ebb034918a018971346506163c43 *man/is_pairlist.Rd b4a02a7600060f95965d6838ec04e1ca *man/is_reference.Rd 9e9c71aa513980ea1c5aff3088122cce *man/is_stack.Rd 41556c0aaeeab103f071615edaa12d43 *man/is_symbol.Rd c524dae3c587048154fff2fbded9f7b9 *man/is_true.Rd c69137d6645b654033e89868911e03b4 *man/is_weakref.Rd d2b8a9b63a8aa343471b51aefc7252de *man/lang.Rd 2505b17b0d99468f3970aa15c8120663 *man/lang_head.Rd d618f8f97f21676595a8ddbac628b309 *man/lang_modify.Rd 9310d5aec286c1e3e366b0187dba2148 *man/last_error.Rd 8f77a901db3f3f6329e45741fe4f5dec *man/lifecycle.Rd aaf3b51d76f97ee7c5ea6d9337ae87da *man/list2.Rd 59742d6634d0813c130e892db08a4dc5 *man/local_bindings.Rd fbe16d7c265aa1a09bfc3341469b5490 *man/local_options.Rd bf35e01efbb319ab4c12f64eb2c64a35 *man/missing.Rd 53413faae7c02d7cead6824f46f58324 *man/missing_arg.Rd 868d19e1bfe7e058b0d42c06ac49e329 *man/mut_node_car.Rd d3c95e9eb63e64a80319826aa6fd5a65 *man/names2.Rd 1f5c221bd8a3f917d970e8eabfd9a1a7 *man/new-vector-along-retired.Rd 4b5913f7036e333a43eb7e36cfcc3452 *man/new-vector.Rd f5df9b04102726b56a6e208a9d3467ae *man/new_call.Rd 2ad8783d26be37103f821e5ae535c56b *man/new_formula.Rd 61727c7a4202509209db865ef2c94c30 *man/new_function.Rd 9463d5488f644d7e834c761b76032358 *man/new_node.Rd 73f43de162110988a7b3839b2f2bcffc *man/new_quosures.Rd 124c3a599323e8c3eeb8eedaa5c49594 *man/new_weakref.Rd 847356638b38152e3246f1e1e708714d *man/ns_env.Rd ea4e89281f7772e3e4540c10a939175e *man/nse-defuse.Rd 9f7bc81793a5329fea5c955fba7cbe90 *man/nse-force.Rd e1462d9d9630b4d9512d18d12b36b496 *man/op-definition.Rd 84259297bc000baf9e9d182954fd6653 *man/op-get-attr.Rd abee158657464add262d5fdeb2b38d07 *man/op-na-default.Rd 104a6a1976e8c95b00c7f5f3457ba6d7 *man/op-null-default.Rd 107df637d90fda4f84a41437b504610d *man/overscope_eval_next.Rd efff9235671da7b9fe38b1f992b9018f *man/pairlist2.Rd fe714a3ab196ab4038fba2fbd91fac0c *man/parse_expr.Rd b10abb1a029228aa69ff3f8abb4284f4 *man/parse_quosure.Rd 658cfff90cff0be2d3276618e0afb786 *man/prepend.Rd afc9cc159795e4415c38a5987075910d *man/prim_name.Rd 1b5abc0211ff2b8e9187b65f8fc072de *man/quo_expr.Rd fe71c6ee45b141c0dad2545b2cc11926 *man/quo_label.Rd fa7331ec24c5d4a80a148f1360bdad94 *man/quo_squash.Rd a7fedef4b0cfd24438a37823d5cc55d7 *man/quosure.Rd 9951ed59df6c313b031098c947e06413 *man/rep_along.Rd 1717c39bd80e5287c2700a02d923da06 *man/restarting.Rd 236fa85d10090ba90fae121e3e3091b5 *man/return_from.Rd 1c94d5adc2a60c73a8503b480e315141 *man/rlang_backtrace_on_error.Rd b968917f82d6ca0aa2077cb995cf1ffd *man/rst_abort.Rd cf0f7abafe93e3d4f46416925f2fea78 *man/rst_list.Rd 9273bb2be0b7ed15ad9ffd4c92566fcd *man/scalar-type-predicates.Rd 04fd2d4a4cd6700b476ba24c07e21d30 *man/scoped_env.Rd cccf9ad2f317740ee8e1448fcbacf35c *man/scoped_interactive.Rd 244a592b475da54c4fa3a3037da673d7 *man/search_envs.Rd 231f1a6e76b2d308aa1eb9c6430e3bcb *man/seq2.Rd 62f12ec1e10346ae91840aad410731f0 *man/set_attrs.Rd 34595dfb7e8fefad12dd8d6a0ae4ec62 *man/set_expr.Rd 2fdfd64be7fe1f498c4b68b70df24abf *man/set_names.Rd 6c018f27cb77afd6ea1ee7af3b6ca9a1 *man/splice.Rd 40d79e87370769dff43edf40d263b939 *man/stack.Rd ba0a2bcd414ca53f3b25b1520fa842d8 *man/stack_trim.Rd b69de2a056ee5d0160066f8189a32546 *man/string.Rd b0f2d89c60b78ea0e7fb80f0647fd2cb *man/switch_type.Rd cedb35b0b50689b6a9710aeafbaa6e31 *man/sym.Rd e352508a28727e8b4891a1cc023458fb *man/tidyeval-data.Rd 093365b5b5a08f8ebd77adc9d31d509b *man/trace_back.Rd a94a851fcc00b26aa7632e0bb7f94648 *man/type-predicates.Rd cc36b3b4ffbd397b87f20075ad4d6ad5 *man/type_of.Rd 8d33d8d85390bdd875c59482bb1bb965 *man/vec_poke_n.Rd 978701861b71e101c5e62f5293d5e20a *man/vector-coercion.Rd fb4c2393458b91ab9715aada09576adc *man/vector-construction.Rd d3b13364edb4f1f68a9da79cdc699f0d *man/vector-old-ctors.Rd dd034e6f314b4267a998d7a55877c872 *man/with_abort.Rd dc0c826278a037cf7046016a3fb29156 *man/with_env.Rd 1e9af579a78c1bf17768b5ab357d094d *man/with_handlers.Rd b1204f0748c1c2665bc9870d228aec4d *man/with_restarts.Rd 6dadd42c4837cfdd7bd7c647a875f065 *man/wref_key.Rd b1488158ec99011b492963e9bcae0a8b *man/zap.Rd 66ac975961c99405838507cd011d82b4 *src/Makevars 10ee83abd769da3bb96ec811de18c886 *src/capture.c 4ef367588c5e607b1a99842eba7d6a5f *src/config.h 372738f63854b1faa1e7dc2c3768a7b0 *src/export.c 8a2dfae28875c90bfc9de70ba046a87c *src/export/exported-tests.c b97588ab389197682ac808ce4afb705d *src/export/exported.c cb4fadb3a24df37bc6d7b4c5a2855965 *src/export/init.c 2cc558eb80d6c9e64efad82e9978f263 *src/internal.c 9e6d3d6b8492df1769ec6ff9ca7cdc81 *src/internal/arg.c fd538226905ccf738d831d00fa8bac31 *src/internal/call.c 0961111252ed34530fcf35f6b8b5e311 *src/internal/dots.c 3f13fd0791f56ee38ecdd013b0312ddb *src/internal/dots.h 2bb7535872e5586ea45cf9cd9dc5cc9b *src/internal/env-binding.c 89d1c417dfdf35daf96afd2f105bfa9e *src/internal/env.c 85c31160da5af13b2bc3727912fe0211 *src/internal/eval-tidy.c 5dc577fa185b900fd7a6d3042b5a7af5 *src/internal/eval.c 8a6b0be53d8af9798bb55690616b2f81 *src/internal/expr-interp-rotate.c d94334212a74d3d56e347d85675e5ea5 *src/internal/expr-interp-rotate.h 7d78291cf4a9b5122660f4987c3f60e9 *src/internal/expr-interp.c 5987fd35349209dcf117087ef83833a2 *src/internal/expr-interp.h 8637d965924f4c9e8a55298733efb534 *src/internal/fn.c 0c530fa000490ccccf60d51a0cf0210f *src/internal/internal.c 45ca29661f3ba2faab693101f4710a2f *src/internal/internal.h c64b24338b05ab8e00fe42e0f86842e0 *src/internal/quo.c eede28d66f0412d290e3b00fe17745b1 *src/internal/quo.h 4ee2e4830a1ac533bd007b669c8c8e01 *src/internal/utils.c ff395f8e6ad740dd5f7b60d864f49a32 *src/internal/utils.h a76b4649b52f32c495a82071da3e8adc *src/lib.c 067612a1029725345471ebb0501d8692 *src/lib/attrs.c 9f4b1d0c468eba805e8e6a16aecce92b *src/lib/attrs.h 80c75cece0efe637effc4e406d66c846 *src/lib/cnd.c cc9d3d4ab89f4e455f337b2dac7031e6 *src/lib/cnd.h 0b39ced2716f810e1d3077c815f08db2 *src/lib/debug.c d21e1a1aed030124e43757342a367e5e *src/lib/debug.h 8c3bc03bba67055dd0199dcd81b8dd63 *src/lib/env-binding.c fd4229cdd98d28ed142faf962c43f318 *src/lib/env-binding.h 57d25886518b6fbb23b876fcfa9f9005 *src/lib/env.c 9ceee44531756416a079f669420674bf *src/lib/env.h e162a686d720ce4c1216d45f3e0048c7 *src/lib/eval.c f1b759055e4573973c15f331f317a845 *src/lib/eval.h 4f93b1c72a2b68597b5f1728c9504cc9 *src/lib/export.c 20d5446627a2287db5d4be5008c04ecd *src/lib/export.h 9c98c87f176cc2b25f655134afb944ff *src/lib/fn.c c19bdf6375b063337a66a13f4bc46797 *src/lib/fn.h d479b97e907b4b4df4a791e231951248 *src/lib/formula.c 65f6bd0f962f7a05322e1964c3d545b2 *src/lib/formula.h 02f85c1ea80c8a6cc641129cfb57a1d3 *src/lib/lang.c 6beb48b277b89161d9783861df1f768e *src/lib/lang.h 9a3a8a9fbb823d961bb86b8ba0213fa7 *src/lib/node.c bd612ef855dfc112236d498e8431188b *src/lib/node.h ab930f0279639637a7903ae84fe15d81 *src/lib/parse.c 07ff98ca6ec48ddd488d31b4108a7aa0 *src/lib/parse.h bfd369311f1b014af975e8d169090b42 *src/lib/quo.c b1395da0d9a1a6e1a0e8b96f8d122af4 *src/lib/quo.h 67ace3674598f218fb283b395875160d *src/lib/replace-na.c 99f8dbe7f3e10bf87317782072511c09 *src/lib/rlang.c 93a3ee8739e396952ef7f9ec12cada8f *src/lib/rlang.h 634a6c9ebb0ed74ab8e0ee8efe1f0caf *src/lib/session.c ec7812f53895289341237370654f38f3 *src/lib/session.h 230426f242dc3d7c0cf03e19d9fba2d7 *src/lib/sexp.c ca07bf136cb3f36615eb1ab44f27a5bc *src/lib/sexp.h 67ed1a2e2d3156ba9579b9cb514b0b23 *src/lib/squash.c 59ef3095ac2c292a8c77852243bfd89c *src/lib/squash.h 933e232e1b6b49093cca95074884ccb7 *src/lib/stack.c ca5ec968a58e31753b06ac34eaa04132 *src/lib/stack.h 0b96cb0ff95091cf208b92a1a0b0f095 *src/lib/state.h d7867bdffe192abf2025196d16a12d11 *src/lib/sym-unescape.c 351b725d260ad8c5ef67d4a50ef17877 *src/lib/sym.c af276e7ffb667dc4ade79ad031fbc72c *src/lib/sym.h cdce8bee71636b800f4734a062d98401 *src/lib/vec-chr.c e7bd651d1cd8d5b48cae2a9aa185010c *src/lib/vec-chr.h 33b95efaea45265a1db5ae2fddcecb9b *src/lib/vec-lgl.c c686c77faeb522d5425eebae89ae024d *src/lib/vec-lgl.h 2e4169e36a519cb5365fcaa5d8d517d4 *src/lib/vec-list.c 4ac26e74a0437d8fcd605e23c2735f20 *src/lib/vec-list.h 34d002f2db38814a4d86a22725e58532 *src/lib/vec.c a5620e19282921953300f25c6b9ce7cd *src/lib/vec.h f62bfc377df0fd1681959ba55ea4d5a6 *src/lib/weakref.c 69397c1a0491ea4760de06ef3fb71424 *tests/sink.R 689f0fa1b25df0719206586844edb2d0 *tests/testthat.R ba141ebe66e9cbf68456c4894d8f811d *tests/testthat/fixtures/Makefile 2759ff4c56f377e704ba0b25c325b13c *tests/testthat/fixtures/error-backtrace-conditionMessage.R ac9346885a36276a5ecc31dd63ea2dfe *tests/testthat/fixtures/error-backtrace-empty.R 7530c4b7eb71435b132a22841c60b75b *tests/testthat/fixtures/error-backtrace-parent.R 3ab920cb77c0ea75ce7d624a53fb0188 *tests/testthat/fixtures/error-backtrace-rethrown.R 8b28713c7d4d4582fa2d322b802a7280 *tests/testthat/fixtures/error-backtrace.R 8c22bc013d19c89ee1d781719df9ec69 *tests/testthat/fixtures/lib.zip 2f019c1aa291d53dec4131b8ebabcb87 *tests/testthat/fixtures/rlanglibtest/DESCRIPTION 7aab50abe7351ed88ab8802f5f80ce0e *tests/testthat/fixtures/rlanglibtest/NAMESPACE d6b263e1ae07adbe16fb5f2f275898c9 *tests/testthat/fixtures/rlanglibtest/R/rlanglibtest.R de5d6e28846d582858e06161de676531 *tests/testthat/fixtures/rlanglibtest/src/Makevars b2a1450e0cec785c0feed66d31219788 *tests/testthat/fixtures/rlanglibtest/src/init.c 7295d46696a4d41f92a5f967c65edf5a *tests/testthat/fixtures/rlanglibtest/src/test-quo-accessors.c d18d1bdcf3564ccaa3a32da5977d5787 *tests/testthat/fixtures/rlanglibtest/tests/testthat.R cf4af2dc60c747068c60d6504d34e8a8 *tests/testthat/fixtures/rlanglibtest/tests/testthat/test-quo-accessors.R 14b5a0404c1240c2cab8fe47085c7edb *tests/testthat/fixtures/trace-srcref.R 09184e8ef439a4ad6f39110792a05e27 *tests/testthat/helper-c-api.R 963a2a85c67e4beba72a7f364a1998a0 *tests/testthat/helper-capture.R 3b482bee49095e2920cddd0b1d03672f *tests/testthat/helper-cli.R 71a741f89e168366b2cae6b75a2149e8 *tests/testthat/helper-cnd.R 2d7ee799c99c893d163355e80c164ed0 *tests/testthat/helper-locale.R 71d70b5fc2aa426a2918ec167f657855 *tests/testthat/helper-print.R c16b053e407d860a1d1f1d6c9a2b8fa1 *tests/testthat/helper-rlang.R a20ff5a7133d7e0407ccd1ea4ff6034e *tests/testthat/helper-stack.R 6098121d6f5bf36b8d9385369a2e4a02 *tests/testthat/helper-trace.R 38018381bb16505ca34473b12644ba15 *tests/testthat/output-cnd-abort-parent-trace.txt e0649b85d5979841b91488152e75c534 *tests/testthat/output-cnd-abort-trace-reminder.txt 174be906c15a7e0857eeb05b32a1bcb0 *tests/testthat/setup-tests.R 512dd39b4a02489cc9cbc68c76480b3d *tests/testthat/teardown-tests.R 34c0701d8baf6df15db848ab65ae4c63 *tests/testthat/test-arg.R 77a34f02f9d73b44f97f5cea98c41959 *tests/testthat/test-attr.R bfa85e8fe84a22bf5aca74d2cf48674a *tests/testthat/test-c-api.R 556347b51ae8ecd6d88052400ec22e55 *tests/testthat/test-call.R 4c8f4352fc47bb17199ab2da4cf37d49 *tests/testthat/test-cnd-abort.R 8c44fa885a060f0ac2077078d309adf3 *tests/testthat/test-cnd-entrace.R a7350bc25732b7fa01be5a41a0e19f2f *tests/testthat/test-cnd-error-conditionMessage.txt 75c1d42edcf7cdba67406e078bd3b5d3 *tests/testthat/test-cnd-error-empty.txt e7d6d0a51d32ccf89e0a69d62397f4cf *tests/testthat/test-cnd-error-parent-default.txt 9793b529b3df3bff5f86996c236b197d *tests/testthat/test-cnd-error-parent-full.txt 5d64ed023c338131b489408ff037cb4b *tests/testthat/test-cnd-error-parent-trace.txt 31457c5739ea9baba7158a68f7db4e15 *tests/testthat/test-cnd-error-parent.txt d79369627b1fe56c6160502102ab471b *tests/testthat/test-cnd-error-print-base-parent.txt 814aa456670852335d566a02711a76c9 *tests/testthat/test-cnd-error-print-no-message.txt cb8a78a12b204b3f27ad4a8e5a4d1583 *tests/testthat/test-cnd-error-str.txt de041b5c3c7caadac312a1f67fd7a66b *tests/testthat/test-cnd-error.R b55ba265a7111cde4ab78aa4b6cd2a34 *tests/testthat/test-cnd-error.txt 75fb7b084e5546d20989d1d8756e7987 *tests/testthat/test-cnd-handlers.R eabdd1c5fc2c3aee314ce3130b502491 *tests/testthat/test-cnd-message.R 157803aa1cb3e646b56e3a7a93f9db7f *tests/testthat/test-cnd-signal-trace.txt bb98a7205ffbb4d7ce2de38e8cea69b0 *tests/testthat/test-cnd-signal.R e28f232aeaa0e9f129cc42f243208708 *tests/testthat/test-cnd.R 7df45679d1c8565b82a09b385506d148 *tests/testthat/test-compat.R 450f3ed8a58eac4d34294e41791fbc33 *tests/testthat/test-deparse.R 058cfb36cb8329b88fb5d6bd62baa17d *tests/testthat/test-dots.R 441d927b3b0e857c429652c3840e4e8d *tests/testthat/test-encoding.R d603df0226f00192fe1d10389cf7ef1d *tests/testthat/test-env-binding.R 56b58a9469574bca355efea7896ff6d8 *tests/testthat/test-env-special.R 2245de12eed13ec2195a5394292edce1 *tests/testthat/test-env.R a969f70060db560530fa0eacfda9f791 *tests/testthat/test-error-print-conditionMessage.txt 3d299f309c1f8b95a8df464c6a5114e3 *tests/testthat/test-eval-tidy.R 62f8245d0d706ac8452f629ee555e919 *tests/testthat/test-events.R f4c54250bdd6f738a8345062898beeaf *tests/testthat/test-exec.R fc481fb91e65da643e012883f3c2cddf *tests/testthat/test-expr.R 8dc952677d76e5e5e9aab88db8a831c0 *tests/testthat/test-fn.R 1bc98da29fef967ac23d58c02a076bec *tests/testthat/test-formula.R 0f500a3580cb25bf07d70c6ece67ed5b *tests/testthat/test-lifecycle.R 1a2bb3f4b4774212c1a99adbc56e30cd *tests/testthat/test-node.R a3515d2e5e7c75e93c7094eb168968ca *tests/testthat/test-nse-defuse.R 25d8de95ab77468e0198587e9041eed8 *tests/testthat/test-nse-force.R 00eff5cd966092193dbd8e4abaa2c4ad *tests/testthat/test-operators.R 43106a9fc423e928a2e11c829ddfc6d5 *tests/testthat/test-parse.R 649b0a3c3f37a6f9c39d13bfeea8fd80 *tests/testthat/test-quo.R cc02f78c1cfe04fa2b1acd2d18c05d55 *tests/testthat/test-retired.R 12c61b61febb98ecca2b4d80316c813a *tests/testthat/test-s3.R cde921e0059c385b8022c9b31a257a59 *tests/testthat/test-sexp.R 6ee94643e23e5c19dd96e2da620467c8 *tests/testthat/test-stack.R 36ef4351ffd718f258824f6f24165aa0 *tests/testthat/test-state.R fe0d60f8c170f6579a036e4d2edf18b8 *tests/testthat/test-sym.R 9df2edf93f43b86ef67748f218ac906c *tests/testthat/test-trace-backtrace-anonymous.txt 16160422020d641a7ed2aab5ce557950 *tests/testthat/test-trace-backtrace-branch-first-frame.txt 60493aadab991fc90663d6122cb3f4b5 *tests/testthat/test-trace-call-car-promise.txt cc5c0935bd172edd785a52250385caa8 *tests/testthat/test-trace-collapse-children.txt e4d446e136aecdf87164cc91e5472096 *tests/testthat/test-trace-collapse-eval.txt 2515ae22f00d1e062f5dd1922270d8fb *tests/testthat/test-trace-collapse-evalq.txt 6a54221f8f437f8bc9e37c2454b0905d *tests/testthat/test-trace-collapse-magrittr-before-after1.txt 959b5eb717a6bf0be3e8c01060242e8b *tests/testthat/test-trace-collapse-magrittr-before-after2.txt e38c8777b46a1e0262690d589d85a970 *tests/testthat/test-trace-collapse-magrittr-before-after3.txt 43b4b159e28951e3bad1733423a333c6 *tests/testthat/test-trace-collapse-magrittr-children.txt bc03dd31e9296989e66a2508f16ff11f *tests/testthat/test-trace-collapse-magrittr-complete-leading1.txt 32ec47a5f04c8479d47ea9fcaccfd720 *tests/testthat/test-trace-collapse-magrittr-complete-leading2.txt a8c5f99cc9ed77eef542fb3d7db18714 *tests/testthat/test-trace-collapse-magrittr-complete1.txt ef04645194b8470aeb1ec6ea1b37b4a6 *tests/testthat/test-trace-collapse-magrittr-complete2.txt c73edfe049ad0373aa7b98bfcbdaa2e2 *tests/testthat/test-trace-collapse-magrittr-incomplete-leading1.txt 3406f1904fa1f147b858028d7f73818d *tests/testthat/test-trace-collapse-magrittr-incomplete-leading2.txt 1dc34422e488198e015b1f47e9189fbd *tests/testthat/test-trace-collapse-magrittr-incomplete.txt 8192dcaf43128ecbbcb9527cf97b581e *tests/testthat/test-trace-collapse-magrittr.txt de2921b8bdaf391c26ad1c9de84e0365 *tests/testthat/test-trace-collapse-magrittr2.txt 8a0cdca8d17e153b0a16a86030bce906 *tests/testthat/test-trace-collapse-magrittr3.txt 021e3942fe38e1b1f2602022c08767e4 *tests/testthat/test-trace-collapsed1.txt 40ce587ac30cdb7e5176a24c464494d8 *tests/testthat/test-trace-collapsed2.txt 737305c359e5a2dc156a06d13e598895 *tests/testthat/test-trace-dangling-srcref.txt d75f1a8c5a7f6fec60e5128f0d986c95 *tests/testthat/test-trace-degenerate-null.txt ee101590748d8a60d132c87c33f51051 *tests/testthat/test-trace-degenerate-scalar.txt 1d004ad36b020b70fa5da2697f6508b3 *tests/testthat/test-trace-degenerate-sym.txt 0f8f920358b91fea42a830936639df9a *tests/testthat/test-trace-global-prefix.txt b7171d84dcf0e1c9b0578b67f13795f9 *tests/testthat/test-trace-local-prefix.txt 7c68acccbcfc50fa04ec8337704111a3 *tests/testthat/test-trace-non-collapsed-eval 239c90d2c7851b6ccd4ffee10c9c9639 *tests/testthat/test-trace-print.txt 2149b6f3d4f118c8c2c99e9929a02107 *tests/testthat/test-trace-recursive.txt ffc6a7a756e17da1c97b153a623ada0d *tests/testthat/test-trace-summary.txt 14d26652d1ea3ece060ff1e2629459c8 *tests/testthat/test-trace-trim.txt 29b9bccd977f39167ee060b79363d70d *tests/testthat/test-trace-truncate-backtrace-branch.txt d10f376dad7ac53cbd2442a1cc5d8b6f *tests/testthat/test-trace-unexported-prefix.txt 91b441316f05e1728ea63069296cd555 *tests/testthat/test-trace.R 6b1b3510ea7e63829803b8c61fa82162 *tests/testthat/test-trace.Rmd 9c774a68f57dfb29ab48970f226d0ff8 *tests/testthat/test-types.R 398137d343f4a18ad98464064f5364fa *tests/testthat/test-utils.R 572399f89b628bac2ad57a31c23ae7a6 *tests/testthat/test-vec-new.R a9c6c389d7adce09814ffa9b097eb3d8 *tests/testthat/test-vec-squash.R b69c4a48b28aa8c81649819a4915bd51 *tests/testthat/test-vec-utils.R fd2507820f81ffc5549ff8be3e1ce1ac *tests/testthat/test-vec.R fdef13a19485fd841541309b570cb824 *tests/testthat/test-weakref.R 4697fee148db94b20fbdd9c223fd094c *tests/testthat/test-with-abort.txt 1e63674e3da62f7388a9ab97c359e549 *tools/hasmacros.sh rlang/inst/0000755000176200001440000000000013612350433012332 5ustar liggesusersrlang/inst/backtrace-ver0000644000176200001440000000000613612347057014772 0ustar liggesusers1.0.0