xml2/0000755000176200001440000000000014533377212011143 5ustar liggesusersxml2/NAMESPACE0000644000176200001440000001252314532115535012362 0ustar liggesusers# Generated by roxygen2: do not edit by hand S3method("[",xml_missing) S3method("[",xml_nodeset) S3method("[[",xml_missing) S3method("xml_attr<-",xml_missing) S3method("xml_attr<-",xml_node) S3method("xml_attr<-",xml_nodeset) S3method("xml_attrs<-",xml_missing) S3method("xml_attrs<-",xml_node) S3method("xml_attrs<-",xml_nodeset) S3method("xml_name<-",xml_missing) S3method("xml_name<-",xml_node) S3method("xml_name<-",xml_nodeset) S3method("xml_text<-",xml_missing) S3method("xml_text<-",xml_node) S3method("xml_text<-",xml_nodeset) S3method(as.character,xml_document) S3method(as.character,xml_missing) S3method(as.character,xml_node) S3method(as.character,xml_nodeset) S3method(as_list,xml_document) S3method(as_list,xml_missing) S3method(as_list,xml_node) S3method(as_list,xml_nodeset) S3method(as_xml_document,character) S3method(as_xml_document,connection) S3method(as_xml_document,list) S3method(as_xml_document,raw) S3method(as_xml_document,response) S3method(as_xml_document,xml_document) S3method(as_xml_document,xml_node) S3method(as_xml_document,xml_nodeset) S3method(format,xml_node) S3method(is.na,xml_missing) S3method(is.na,xml_node) S3method(is.na,xml_nodeset) S3method(nodeset_apply,xml_document) S3method(nodeset_apply,xml_missing) S3method(nodeset_apply,xml_node) S3method(nodeset_apply,xml_nodeset) S3method(print,xml_document) S3method(print,xml_missing) S3method(print,xml_namespace) S3method(print,xml_node) S3method(print,xml_nodeset) S3method(read_html,default) S3method(read_html,response) S3method(read_xml,character) S3method(read_xml,connection) S3method(read_xml,raw) S3method(read_xml,response) S3method(tree_structure,xml_missing) S3method(tree_structure,xml_node) S3method(tree_structure,xml_nodeset) S3method(write_html,xml_document) S3method(write_html,xml_missing) S3method(write_html,xml_node) S3method(write_html,xml_nodeset) S3method(write_xml,xml_document) S3method(write_xml,xml_missing) S3method(write_xml,xml_node) S3method(write_xml,xml_nodeset) S3method(xml_add_child,xml_document) S3method(xml_add_child,xml_missing) S3method(xml_add_child,xml_node) S3method(xml_add_child,xml_nodeset) S3method(xml_add_parent,xml_missing) S3method(xml_add_parent,xml_node) S3method(xml_add_parent,xml_nodeset) S3method(xml_add_sibling,xml_missing) S3method(xml_add_sibling,xml_node) S3method(xml_add_sibling,xml_nodeset) S3method(xml_find_all,xml_missing) S3method(xml_find_all,xml_node) S3method(xml_find_all,xml_nodeset) S3method(xml_find_chr,xml_missing) S3method(xml_find_chr,xml_node) S3method(xml_find_chr,xml_nodeset) S3method(xml_find_first,xml_missing) S3method(xml_find_first,xml_node) S3method(xml_find_first,xml_nodeset) S3method(xml_find_int,xml_missing) S3method(xml_find_int,xml_node) S3method(xml_find_int,xml_nodeset) S3method(xml_find_lgl,xml_missing) S3method(xml_find_lgl,xml_node) S3method(xml_find_lgl,xml_nodeset) S3method(xml_find_num,xml_missing) S3method(xml_find_num,xml_node) S3method(xml_find_num,xml_nodeset) S3method(xml_ns,xml_document) S3method(xml_ns,xml_missing) S3method(xml_ns,xml_node) S3method(xml_ns,xml_nodeset) S3method(xml_parent,xml_missing) S3method(xml_parent,xml_node) S3method(xml_parent,xml_nodeset) S3method(xml_remove,xml_missing) S3method(xml_remove,xml_node) S3method(xml_remove,xml_nodeset) S3method(xml_replace,xml_missing) S3method(xml_replace,xml_node) S3method(xml_replace,xml_nodeset) S3method(xml_serialize,xml_document) S3method(xml_serialize,xml_node) S3method(xml_serialize,xml_nodeset) S3method(xml_set_attr,xml_missing) S3method(xml_set_attr,xml_node) S3method(xml_set_attr,xml_nodeset) S3method(xml_set_attrs,xml_missing) S3method(xml_set_attrs,xml_node) S3method(xml_set_attrs,xml_nodeset) S3method(xml_set_name,xml_missing) S3method(xml_set_name,xml_node) S3method(xml_set_name,xml_nodeset) S3method(xml_url,xml_missing) S3method(xml_url,xml_node) S3method(xml_url,xml_nodeset) S3method(xml_validate,xml_document) export("xml_attr<-") export("xml_attrs<-") export("xml_name<-") export("xml_text<-") export(as_list) export(as_xml_document) export(download_html) export(download_xml) export(html_structure) export(read_html) export(read_xml) export(url_absolute) export(url_escape) export(url_parse) export(url_relative) export(url_unescape) export(write_html) export(write_xml) export(xml2_example) export(xml_add_child) export(xml_add_parent) export(xml_add_sibling) export(xml_attr) export(xml_attrs) export(xml_cdata) export(xml_child) export(xml_children) export(xml_comment) export(xml_contents) export(xml_double) export(xml_dtd) export(xml_find_all) export(xml_find_chr) export(xml_find_first) export(xml_find_int) export(xml_find_lgl) export(xml_find_num) export(xml_find_one) export(xml_has_attr) export(xml_integer) export(xml_length) export(xml_missing) export(xml_name) export(xml_new_document) export(xml_new_root) export(xml_ns) export(xml_ns_rename) export(xml_ns_strip) export(xml_parent) export(xml_parents) export(xml_path) export(xml_remove) export(xml_replace) export(xml_root) export(xml_serialize) export(xml_set_attr) export(xml_set_attrs) export(xml_set_name) export(xml_set_namespace) export(xml_set_text) export(xml_siblings) export(xml_structure) export(xml_text) export(xml_type) export(xml_unserialize) export(xml_url) export(xml_validate) exportClasses(xml_document) exportClasses(xml_missing) exportClasses(xml_node) exportClasses(xml_nodeset) import(rlang) importFrom(methods,setOldClass) useDynLib(xml2, .registration = TRUE) xml2/LICENSE0000644000176200001440000000005214517773421012151 0ustar liggesusersYEAR: 2023 COPYRIGHT HOLDER: xml2 authors xml2/tools/0000755000176200001440000000000013633161317012300 5ustar liggesusersxml2/tools/winlibs.R0000644000176200001440000000066613633161317014102 0ustar liggesusers# Build against static libraries from rwinlib VERSION <- commandArgs(TRUE) if(!file.exists(sprintf("../windows/libxml2-%s/include/libxml2/libxml/parser.h", VERSION))){ if(getRversion() < "3.3.0") setInternet2() download.file(sprintf("https://github.com/rwinlib/libxml2/archive/v%s.zip", VERSION), "lib.zip", quiet = TRUE) dir.create("../windows", showWarnings = FALSE) unzip("lib.zip", exdir = "../windows") unlink("lib.zip") } xml2/README.md0000644000176200001440000000451414517773421012432 0ustar liggesusers # xml2 [![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/xml2)](https://cran.r-project.org/package=xml2) [![Codecov test coverage](https://codecov.io/gh/r-lib/xml2/branch/master/graph/badge.svg)](https://app.codecov.io/gh/r-lib/xml2?branch=main) [![R build status](https://github.com/r-lib/xml2/workflows/R-CMD-check/badge.svg)](https://github.com/r-lib/xml2/actions) [![R-CMD-check](https://github.com/r-lib/xml2/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/r-lib/xml2/actions/workflows/R-CMD-check.yaml) The xml2 package is a binding to [libxml2](http://xmlsoft.org), making it easy to work with HTML and XML from R. The API is somewhat inspired by [jQuery](https://jquery.com). ## Installation You can install xml2 from CRAN, ``` r install.packages("xml2") ``` or you can install the development version from github, using `devtools`: ``` r # install.packages("pak") pak::pak("r-lib/xml2") ``` ## Usage ``` r library("xml2") x <- read_xml(" text ") x xml_name(x) xml_children(x) xml_text(x) xml_find_all(x, ".//baz") h <- read_html("

Hi !") h xml_name(h) xml_text(h) ``` There are three key classes: - `xml_node`: a single node in a document. - `xml_doc`: the complete document. Acting on a document is usually the same as acting on the root node of the document. - `xml_nodeset`: a **set** of nodes within the document. Operations on `xml_nodeset`s are vectorised, apply the operation over each node in the set. ## Compared to the XML package xml2 has similar goals to the XML package. The main differences are: - xml2 takes care of memory management for you. It will automatically free the memory used by an XML document as soon as the last reference to it goes away. - xml2 has a very simple class hierarchy so you don’t need to think about exactly what type of object you have, xml2 will just do the right thing. - More convenient handling of namespaces in Xpath expressions - see `xml_ns()` and `xml_ns_strip()` to get started. ## Code of Conduct Please note that the xml2 project is released with a [Contributor Code of Conduct](https://xml2.r-lib.org/CODE_OF_CONDUCT.html). By contributing to this project, you agree to abide by its terms. xml2/man/0000755000176200001440000000000014532115535011713 5ustar liggesusersxml2/man/xml_validate.Rd0000644000176200001440000000123013026552053014644 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_schema.R \name{xml_validate} \alias{xml_validate} \title{Validate XML schema} \usage{ xml_validate(x, schema) } \arguments{ \item{x}{A document, node, or node set.} \item{schema}{an XML document containing the schema} } \value{ TRUE or FALSE } \description{ Validate an XML document against an XML 1.0 schema. } \examples{ # Example from https://msdn.microsoft.com/en-us/library/ms256129(v=vs.110).aspx doc <- read_xml(system.file("extdata/order-doc.xml", package = "xml2")) schema <- read_xml(system.file("extdata/order-schema.xml", package = "xml2")) xml_validate(doc, schema) } xml2/man/xml_type.Rd0000644000176200001440000000060513026552053014041 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_type.R \name{xml_type} \alias{xml_type} \title{Determine the type of a node.} \usage{ xml_type(x) } \arguments{ \item{x}{A document, node, or node set.} } \description{ Determine the type of a node. } \examples{ x <- read_xml(" a ") xml_type(x) xml_type(xml_contents(x)) } xml2/man/xml_missing.Rd0000644000176200001440000000040614517773421014542 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_missing.R \name{xml_missing} \alias{xml_missing} \title{Construct an missing xml object} \usage{ xml_missing() } \description{ Construct an missing xml object } \keyword{internal} xml2/man/xml_attr.Rd0000644000176200001440000000612413633161317014037 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_attr.R \name{xml_attr} \alias{xml_attr} \alias{xml_has_attr} \alias{xml_attrs} \alias{xml_attr<-} \alias{xml_set_attr} \alias{xml_attrs<-} \alias{xml_set_attrs} \title{Retrieve an attribute.} \usage{ xml_attr(x, attr, ns = character(), default = NA_character_) xml_has_attr(x, attr, ns = character()) xml_attrs(x, ns = character()) xml_attr(x, attr, ns = character()) <- value xml_set_attr(x, attr, value, ns = character()) xml_attrs(x, ns = character()) <- value xml_set_attrs(x, value, ns = character()) } \arguments{ \item{x}{A document, node, or node set.} \item{attr}{Name of attribute to extract.} \item{ns}{Optionally, a named vector giving prefix-url pairs, as produced by \code{\link[=xml_ns]{xml_ns()}}. If provided, all names will be explicitly qualified with the ns prefix, i.e. if the element \code{bar} is defined in namespace \code{foo}, it will be called \code{foo:bar}. (And similarly for attributes). Default namespaces must be given an explicit name. The ns is ignored when using \code{\link[=xml_name<-]{xml_name<-()}} and \code{\link[=xml_set_name]{xml_set_name()}}.} \item{default}{Default value to use when attribute is not present.} \item{value}{character vector of new value.} } \value{ \code{xml_attr()} returns a character vector. \code{NA} is used to represent of attributes that aren't defined. \code{xml_has_attr()} returns a logical vector. \code{xml_attrs()} returns a named character vector if \code{x} x is single node, or a list of character vectors if given a nodeset } \description{ \code{xml_attrs()} retrieves all attributes values as a named character vector, \verb{xml_attrs() <-} or \code{xml_set_attrs()} sets all attribute values. \code{xml_attr()} retrieves the value of single attribute and \verb{xml_attr() <-} or \code{xml_set_attr()} modifies its value. If the attribute doesn't exist, it will return \code{default}, which defaults to \code{NA}. \code{xml_has_attr()} tests if an attribute is present. } \examples{ x <- read_xml("") xml_attr(x, "id") xml_attr(x, "apple") xml_attrs(x) kids <- xml_children(x) kids xml_attr(kids, "id") xml_has_attr(kids, "id") xml_attrs(kids) # Missing attributes give missing values xml_attr(xml_children(x), "d") xml_has_attr(xml_children(x), "d") # If the document has a namespace, use the ns argument and # qualified attribute names x <- read_xml(' ') doc <- xml_children(x)[[1]] ns <- xml_ns(x) xml_attrs(doc) xml_attrs(doc, ns) # If you don't supply a ns spec, you get the first matching attribute xml_attr(doc, "id") xml_attr(doc, "b:id", ns) xml_attr(doc, "id", ns) # Can set a single attribute with `xml_attr() <-` or `xml_set_attr()` xml_attr(doc, "id") <- "one" xml_set_attr(doc, "id", "two") # Or set multiple attributes with `xml_attrs()` or `xml_set_attrs()` xml_attrs(doc) <- c("b:id" = "one", "f:id" = "two", "id" = "three") xml_set_attrs(doc, c("b:id" = "one", "f:id" = "two", "id" = "three")) } xml2/man/xml_children.Rd0000644000176200001440000000450713633161317014660 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_children.R \name{xml_children} \alias{xml_children} \alias{xml_child} \alias{xml_contents} \alias{xml_parents} \alias{xml_siblings} \alias{xml_parent} \alias{xml_length} \alias{xml_root} \title{Navigate around the family tree.} \usage{ xml_children(x) xml_child(x, search = 1, ns = xml_ns(x)) xml_contents(x) xml_parents(x) xml_siblings(x) xml_parent(x) xml_length(x, only_elements = TRUE) xml_root(x) } \arguments{ \item{x}{A document, node, or node set.} \item{search}{For \code{xml_child}, either the child number to return (by position), or the name of the child node to return. If there are multiple child nodes with the same name, the first will be returned} \item{ns}{Optionally, a named vector giving prefix-url pairs, as produced by \code{\link[=xml_ns]{xml_ns()}}. If provided, all names will be explicitly qualified with the ns prefix, i.e. if the element \code{bar} is defined in namespace \code{foo}, it will be called \code{foo:bar}. (And similarly for attributes). Default namespaces must be given an explicit name. The ns is ignored when using \code{\link[=xml_name<-]{xml_name<-()}} and \code{\link[=xml_set_name]{xml_set_name()}}.} \item{only_elements}{For \code{xml_length}, should it count all children, or just children that are elements (the default)?} } \value{ A node or nodeset (possibly empty). Results are always de-duplicated. } \description{ \code{xml_children} returns only elements, \code{xml_contents} returns all nodes. \code{xml_length} returns the number of children. \code{xml_parent} returns the parent node, \code{xml_parents} returns all parents up to the root. \code{xml_siblings} returns all nodes at the same level. \code{xml_child} makes it easy to specify a specific child to return. } \examples{ x <- read_xml(" ") xml_children(x) xml_children(xml_children(x)) xml_siblings(xml_children(x)[[1]]) # Note the each unique node only appears once in the output xml_parent(xml_children(x)) # Mixed content x <- read_xml(" a c e f") # Childen gets the elements, contents gets all node types xml_children(x) xml_contents(x) xml_length(x) xml_length(x, only_elements = FALSE) # xml_child makes it easier to select specific children xml_child(x) xml_child(x, 2) xml_child(x, "baz") } xml2/man/xml_new_document.Rd0000644000176200001440000000257613633161317015563 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_modify.R \name{xml_new_document} \alias{xml_new_document} \alias{xml_new_root} \title{Create a new document, possibly with a root node} \usage{ xml_new_document(version = "1.0", encoding = "UTF-8") xml_new_root( .value, ..., .copy = inherits(.value, "xml_node"), .version = "1.0", .encoding = "UTF-8" ) } \arguments{ \item{version}{The version number of the document.} \item{encoding}{The character encoding to use in the document. The default encoding is \sQuote{UTF-8}. Available encodings are specified at \url{http://xmlsoft.org/html/libxml-encoding.html#xmlCharEncoding}.} \item{.value}{node to insert.} \item{...}{If named attributes or namespaces to set on the node, if unnamed text to assign to the node.} \item{.copy}{whether to copy the \code{.value} before replacing. If this is \code{FALSE} then the node will be moved from it's current location.} \item{.version}{The version number of the document, passed to \code{xml_new_document(version)}.} \item{.encoding}{The encoding of the document, passed to \code{xml_new_document(encoding)}.} } \value{ A \code{xml_document} object. } \description{ \code{xml_new_document} creates only a new document without a root node. In most cases you should instead use \code{xml_new_root}, which creates a new document and assigns the root node in one step. } xml2/man/url_escape.Rd0000644000176200001440000000101013664746162014327 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_url.R \name{url_escape} \alias{url_escape} \alias{url_unescape} \title{Escape and unescape urls.} \usage{ url_escape(x, reserved = "") url_unescape(x) } \arguments{ \item{x}{A character vector of urls.} \item{reserved}{A string containing additional characters to avoid escaping.} } \description{ Escape and unescape urls. } \examples{ url_escape("a b c") url_escape("a b c", "") url_unescape("a\%20b\%2fc") url_unescape("\%C2\%B5") } xml2/man/xml2-package.Rd0000644000176200001440000000145514517773421014471 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml2-package.R \docType{package} \name{xml2-package} \alias{xml2} \alias{xml2-package} \title{xml2: Parse XML} \description{ Work with XML files using a simple, consistent interface. Built on top of the 'libxml2' C library. } \seealso{ Useful links: \itemize{ \item \url{https://xml2.r-lib.org/} \item \url{https://github.com/r-lib/xml2} \item Report bugs at \url{https://github.com/r-lib/xml2/issues} } } \author{ \strong{Maintainer}: Hadley Wickham \email{hadley@posit.co} Authors: \itemize{ \item Jim Hester \item Jeroen Ooms } Other contributors: \itemize{ \item Posit Software, PBC [copyright holder, funder] \item R Foundation (Copy of R-project homepage cached as example) [contributor] } } \keyword{internal} xml2/man/xml_set_namespace.Rd0000644000176200001440000000072713026552053015674 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_modify.R \name{xml_set_namespace} \alias{xml_set_namespace} \title{Set the node's namespace} \usage{ xml_set_namespace(.x, prefix = "", uri = "") } \arguments{ \item{.x}{a node} \item{prefix}{The namespace prefix to use} \item{uri}{The namespace URI to use} } \value{ the node (invisibly) } \description{ The namespace to be set must be already defined in one of the node's ancestors. } xml2/man/xml_find_all.Rd0000644000176200001440000001043014532115535014630 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_find.R \name{xml_find_all} \alias{xml_find_all} \alias{xml_find_all.xml_nodeset} \alias{xml_find_first} \alias{xml_find_num} \alias{xml_find_int} \alias{xml_find_chr} \alias{xml_find_lgl} \alias{xml_find_one} \title{Find nodes that match an xpath expression.} \usage{ xml_find_all(x, xpath, ns = xml_ns(x), ...) \method{xml_find_all}{xml_nodeset}(x, xpath, ns = xml_ns(x), flatten = TRUE, ...) xml_find_first(x, xpath, ns = xml_ns(x)) xml_find_num(x, xpath, ns = xml_ns(x)) xml_find_int(x, xpath, ns = xml_ns(x)) xml_find_chr(x, xpath, ns = xml_ns(x)) xml_find_lgl(x, xpath, ns = xml_ns(x)) } \arguments{ \item{x}{A document, node, or node set.} \item{xpath}{A string containing an xpath (1.0) expression.} \item{ns}{Optionally, a named vector giving prefix-url pairs, as produced by \code{\link[=xml_ns]{xml_ns()}}. If provided, all names will be explicitly qualified with the ns prefix, i.e. if the element \code{bar} is defined in namespace \code{foo}, it will be called \code{foo:bar}. (And similarly for attributes). Default namespaces must be given an explicit name. The ns is ignored when using \code{\link[=xml_name<-]{xml_name<-()}} and \code{\link[=xml_set_name]{xml_set_name()}}.} \item{...}{Further arguments passed to or from other methods.} \item{flatten}{A logical indicating whether to return a single, flattened nodeset or a list of nodesets.} } \value{ \code{xml_find_all} returns a nodeset if applied to a node, and a nodeset or a list of nodesets if applied to a nodeset. If there are no matches, the nodeset(s) will be empty. Within each nodeset, the result will always be unique; repeated nodes are automatically de-duplicated. \code{xml_find_first} returns a node if applied to a node, and a nodeset if applied to a nodeset. The output is \emph{always} the same size as the input. If there are no matches, \code{xml_find_first} will return a missing node; if there are multiple matches, it will return the first only. \code{xml_find_num}, \code{xml_find_chr}, \code{xml_find_lgl} return numeric, character and logical results respectively. } \description{ Xpath is like regular expressions for trees - it's worth learning if you're trying to extract nodes from arbitrary locations in a document. Use \code{xml_find_all} to find all matches - if there's no match you'll get an empty result. Use \code{xml_find_first} to find a specific match - if there's no match you'll get an \code{xml_missing} node. } \section{Deprecated functions}{ \code{xml_find_one()} has been deprecated. Instead use \code{xml_find_first()}. } \examples{ x <- read_xml("") xml_find_all(x, ".//baz") xml_path(xml_find_all(x, ".//baz")) # Note the difference between .// and // # // finds anywhere in the document (ignoring the current node) # .// finds anywhere beneath the current node (bar <- xml_find_all(x, ".//bar")) xml_find_all(bar, ".//baz") xml_find_all(bar, "//baz") # Find all vs find one ----------------------------------------------------- x <- read_xml("

Some text.

Some other text.

No bold here!

") para <- xml_find_all(x, ".//p") # By default, if you apply xml_find_all to a nodeset, it finds all matches, # de-duplicates them, and returns as a single nodeset. This means you # never know how many results you'll get xml_find_all(para, ".//b") # If you set flatten to FALSE, though, xml_find_all will return a list of # nodesets, where each nodeset contains the matches for the corresponding # node in the original nodeset. xml_find_all(para, ".//b", flatten = FALSE) # xml_find_first only returns the first match per input node. If there are 0 # matches it will return a missing node xml_find_first(para, ".//b") xml_text(xml_find_first(para, ".//b")) # Namespaces --------------------------------------------------------------- # If the document uses namespaces, you'll need use xml_ns to form # a unique mapping between full namespace url and a short prefix x <- read_xml(' ') xml_find_all(x, ".//f:doc") xml_find_all(x, ".//f:doc", xml_ns(x)) } \seealso{ \code{\link[=xml_ns_strip]{xml_ns_strip()}} to remove the default namespaces } xml2/man/read_xml.Rd0000644000176200001440000000742513633161317014005 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_parse.R \name{read_xml} \alias{read_xml} \alias{read_html} \alias{read_xml.character} \alias{read_xml.raw} \alias{read_xml.connection} \title{Read HTML or XML.} \usage{ read_xml(x, encoding = "", ..., as_html = FALSE, options = "NOBLANKS") read_html(x, encoding = "", ..., options = c("RECOVER", "NOERROR", "NOBLANKS")) \method{read_xml}{character}(x, encoding = "", ..., as_html = FALSE, options = "NOBLANKS") \method{read_xml}{raw}( x, encoding = "", base_url = "", ..., as_html = FALSE, options = "NOBLANKS" ) \method{read_xml}{connection}( x, encoding = "", n = 64 * 1024, verbose = FALSE, ..., base_url = "", as_html = FALSE, options = "NOBLANKS" ) } \arguments{ \item{x}{A string, a connection, or a raw vector. A string can be either a path, a url or literal xml. Urls will be converted into connections either using \code{base::url} or, if installed, \code{curl::curl}. Local paths ending in \code{.gz}, \code{.bz2}, \code{.xz}, \code{.zip} will be automatically uncompressed. If a connection, the complete connection is read into a raw vector before being parsed.} \item{encoding}{Specify a default encoding for the document. Unless otherwise specified XML documents are assumed to be in UTF-8 or UTF-16. If the document is not UTF-8/16, and lacks an explicit encoding directive, this allows you to supply a default.} \item{...}{Additional arguments passed on to methods.} \item{as_html}{Optionally parse an xml file as if it's html.} \item{options}{Set parsing options for the libxml2 parser. Zero or more of \Sexpr[results=rd]{xml2:::describe_options(xml2:::xml_parse_options())}} \item{base_url}{When loading from a connection, raw vector or literal html/xml, this allows you to specify a base url for the document. Base urls are used to turn relative urls into absolute urls.} \item{n}{If \code{file} is a connection, the number of bytes to read per iteration. Defaults to 64kb.} \item{verbose}{When reading from a slow connection, this prints some output on every iteration so you know its working.} } \value{ An XML document. HTML is normalised to valid XML - this may not be exactly the same transformation performed by the browser, but it's a reasonable approximation. } \description{ Read HTML or XML. } \section{Setting the "user agent" header}{ When performing web scraping tasks it is both good practice --- and often required --- to set the \href{https://en.wikipedia.org/wiki/User_agent}{user agent} request header to a specific value. Sometimes this value is assigned to emulate a browser in order to have content render in a certain way (e.g. \verb{Mozilla/5.0 (Windows NT 5.1; rv:52.0) Gecko/20100101 Firefox/52.0} to emulate more recent Windows browsers). Most often, this value should be set to provide the web resource owner information on who you are and the intent of your actions like this Google scraping bot user agent identifier: \verb{Googlebot/2.1 (+http://www.google.com/bot.html)}. You can set the HTTP user agent for URL-based requests using \code{\link[httr:set_config]{httr::set_config()}} and \code{\link[httr:user_agent]{httr::user_agent()}}: \code{httr::set_config(httr::user_agent("me@example.com; +https://example.com/info.html"))} \code{\link[httr:set_config]{httr::set_config()}} changes the configuration globally, \code{\link[httr:with_config]{httr::with_config()}} can be used to change configuration temporarily. } \examples{ # Literal xml/html is useful for small examples read_xml("") read_html("Hi<title></html>") read_html("<html><title>Hi") # From a local path read_html(system.file("extdata", "r-project.html", package = "xml2")) \dontrun{ # From a url cd <- read_xml(xml2_example("cd_catalog.xml")) me <- read_html("http://had.co.nz") } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xml2/man/xml_text.Rd��������������������������������������������������������������������������������0000644�0001762�0000144�00000002306�14517773421�014056� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_text.R \name{xml_text} \alias{xml_text} \alias{xml_text<-} \alias{xml_set_text} \alias{xml_double} \alias{xml_integer} \title{Extract or modify the text} \usage{ xml_text(x, trim = FALSE) xml_text(x) <- value xml_set_text(x, value) xml_double(x) xml_integer(x) } \arguments{ \item{x}{A document, node, or node set.} \item{trim}{If \code{TRUE} will trim leading and trailing spaces.} \item{value}{character vector with replacement text.} } \value{ A character vector, the same length as x. } \description{ \code{xml_text} returns a character vector, \code{xml_double} returns a numeric vector, \code{xml_integer} returns an integer vector. } \examples{ x <- read_xml("<p>This is some text. This is <b>bold!</b></p>") xml_text(x) xml_text(xml_children(x)) x <- read_xml("<x>This is some text. <x>This is some nested text.</x></x>") xml_text(x) xml_text(xml_find_all(x, "//x")) x <- read_xml("<p> Some text </p>") xml_text(x, trim = TRUE) # xml_double() and xml_integer() are useful for extracting numeric attributes x <- read_xml("<plot><point x='1' y='2' /><point x='2' y='1' /></plot>") xml_integer(xml_find_all(x, "//@x")) } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xml2/man/oldclass.Rd��������������������������������������������������������������������������������0000644�0001762�0000144�00000001215�14421526304�014002� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/S4.R \name{xml_document-class} \alias{xml_document-class} \alias{xml_missing-class} \alias{xml_node-class} \alias{xml_nodeset-class} \title{Register S4 classes} \description{ Classes are exported so they can be re-used within S4 classes, see \code{\link[methods:setOldClass]{methods::setOldClass()}}. \itemize{ \item \code{xml_document}: a complete document. \item \code{xml_nodeset}: a \emph{set} of nodes within a document. \item \code{xml_missing}: a missing object, e.g. for an empty result set. \item \code{xml_node}: a single node in a document. } } \keyword{internal} �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xml2/man/url_absolute.Rd����������������������������������������������������������������������������0000644�0001762�0000144�00000001544�13664746162�014721� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_url.R \name{url_absolute} \alias{url_absolute} \alias{url_relative} \title{Convert between relative and absolute urls.} \usage{ url_absolute(x, base) url_relative(x, base) } \arguments{ \item{x}{A character vector of urls relative to that base} \item{base}{A string giving a base url.} } \value{ A character vector of urls } \description{ Convert between relative and absolute urls. } \examples{ url_absolute(c(".", "..", "/", "/x"), "http://hadley.nz/a/b/c/d") url_relative("http://hadley.nz/a/c", "http://hadley.nz") url_relative("http://hadley.nz/a/c", "http://hadley.nz/") url_relative("http://hadley.nz/a/c", "http://hadley.nz/a/b") url_relative("http://hadley.nz/a/c", "http://hadley.nz/a/b/") } \seealso{ \code{\link{xml_url}} to retrieve the URL associated with a document } ������������������������������������������������������������������������������������������������������������������������������������������������������������xml2/man/xml_comment.Rd�����������������������������������������������������������������������������0000644�0001762�0000144�00000000625�13026552053�014524� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/classes.R \name{xml_comment} \alias{xml_comment} \title{Construct a comment node} \usage{ xml_comment(content) } \arguments{ \item{content}{The comment content} } \description{ Construct a comment node } \examples{ x <- xml_new_document() r <- xml_add_child(x, "root") xml_add_child(r, xml_comment("Hello!")) as.character(x) } �����������������������������������������������������������������������������������������������������������xml2/man/xml_url.Rd���������������������������������������������������������������������������������0000644�0001762�0000144�00000001025�13633161317�013662� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_url.R \name{xml_url} \alias{xml_url} \title{The URL of an XML document} \usage{ xml_url(x) } \arguments{ \item{x}{A node or document.} } \value{ A character vector of length 1. Returns \code{NA} if the name is not set. } \description{ This is useful for interpreting relative urls with \code{\link[=url_relative]{url_relative()}}. } \examples{ catalog <- read_xml(xml2_example("cd_catalog.xml")) xml_url(catalog) x <- read_xml("<foo/>") xml_url(x) } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xml2/man/figures/�����������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14517773421�013366� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xml2/man/figures/lifecycle-defunct.svg��������������������������������������������������������������0000644�0001762�0000144�00000002424�14517773421�017476� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="106" height="20" role="img" aria-label="lifecycle: defunct"> <title>lifecycle: defunct lifecycle defunct xml2/man/figures/lifecycle-maturing.svg0000644000176200001440000000243014517773421017671 0ustar liggesusers lifecycle: maturing lifecycle maturing xml2/man/figures/lifecycle-archived.svg0000644000176200001440000000243014517773421017630 0ustar liggesusers lifecycle: archived lifecycle archived xml2/man/figures/lifecycle-soft-deprecated.svg0000644000176200001440000000246614517773421021125 0ustar liggesusers lifecycle: soft-deprecated lifecycle soft-deprecated xml2/man/figures/lifecycle-questioning.svg0000644000176200001440000000244414517773421020415 0ustar liggesusers lifecycle: questioning lifecycle questioning xml2/man/figures/lifecycle-superseded.svg0000644000176200001440000000244014517773421020207 0ustar liggesusers lifecycle: superseded lifecycle superseded xml2/man/figures/lifecycle-stable.svg0000644000176200001440000000247214517773421017323 0ustar liggesusers lifecycle: stable lifecycle stable xml2/man/figures/lifecycle-experimental.svg0000644000176200001440000000245014517773421020542 0ustar liggesusers lifecycle: experimental lifecycle experimental xml2/man/figures/lifecycle-deprecated.svg0000644000176200001440000000244014517773421020144 0ustar liggesusers lifecycle: deprecated lifecycle deprecated xml2/man/url_parse.Rd0000644000176200001440000000113013664746162014204 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_url.R \name{url_parse} \alias{url_parse} \title{Parse a url into its component pieces.} \usage{ url_parse(x) } \arguments{ \item{x}{A character vector of urls.} } \value{ A dataframe with one row for each element of \code{x} and columns: scheme, server, port, user, path, query, fragment. } \description{ Parse a url into its component pieces. } \examples{ url_parse("http://had.co.nz/") url_parse("http://had.co.nz:1234/") url_parse("http://had.co.nz:1234/?a=1&b=2") url_parse("http://had.co.nz:1234/?a=1&b=2#def") } xml2/man/download_xml.Rd0000644000176200001440000000357314517773421014710 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_parse.R \name{download_xml} \alias{download_xml} \alias{download_html} \title{Download a HTML or XML file} \usage{ download_xml( url, file = basename(url), quiet = TRUE, mode = "wb", handle = curl::new_handle() ) download_html( url, file = basename(url), quiet = TRUE, mode = "wb", handle = curl::new_handle() ) } \arguments{ \item{url}{A character string naming the URL of a resource to be downloaded.} \item{file}{A character string with the name where the downloaded file is saved.} \item{quiet}{If \code{TRUE}, suppress status messages (if any), and the progress bar.} \item{mode}{A character string specifying the mode with which to write the file. Useful values are \code{"w"}, \code{"wb"} (binary), \code{"a"} (append) and \code{"ab"}.} \item{handle}{a curl handle object} } \value{ Path of downloaded file (invisibly). } \description{ Libcurl implementation of \code{C_download} (the "internal" download method) with added support for https, ftps, gzip, etc. Default behavior is identical to \code{\link[=download.file]{download.file()}}, but request can be fully configured by passing a custom \code{\link[curl:handle]{curl::handle()}}. } \details{ The main difference between \code{curl_download} and \code{curl_fetch_disk} is that \code{curl_download} checks the http status code before starting the download, and raises an error when status is non-successful. The behavior of \code{curl_fetch_disk} on the other hand is to proceed as normal and write the error page to disk in case of a non success response. For a more advanced download interface which supports concurrent requests and resuming large files, have a look at the \link[curl]{multi_download} function. } \examples{ \dontrun{ download_html("http://tidyverse.org/index.html") } } \seealso{ \link[curl:curl_download]{curl_download} } xml2/man/xml_dtd.Rd0000644000176200001440000000167514517773421013655 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/classes.R \name{xml_dtd} \alias{xml_dtd} \title{Construct a document type definition} \usage{ xml_dtd(name = "", external_id = "", system_id = "") } \arguments{ \item{name}{The name of the declaration} \item{external_id}{The external ID of the declaration} \item{system_id}{The system ID of the declaration} } \description{ This is used to create simple document type definitions. If you need to create a more complicated definition with internal subsets it is recommended to parse a string directly with \code{read_xml()}. } \examples{ r <- xml_new_root( xml_dtd( "html", "-//W3C//DTD XHTML 1.0 Transitional//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" ) ) # Use read_xml directly for more complicated DTD d <- read_xml( ' ]> This is a valid document &foo; !' ) } xml2/man/as_xml_document.Rd0000644000176200001440000000167114517773421015377 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/as_xml_document.R \name{as_xml_document} \alias{as_xml_document} \title{Coerce a R list to xml nodes.} \usage{ as_xml_document(x, ...) } \arguments{ \item{x}{A document, node, or node set.} \item{...}{Needed for compatibility with generic. Unused.} } \description{ This turns an R list into the equivalent XML document. Not all R lists will produce valid XML, in particular there can only be one root node and all child nodes need to be named (or empty) lists. R attributes become XML attributes and R names become XML node names. } \examples{ as_xml_document(list(x = list())) # Nesting multiple nodes as_xml_document(list(foo = list(bar = list(baz = list())))) # attributes are stored as R attributes as_xml_document(list(foo = structure(list(), id = "a"))) as_xml_document(list(foo = list( bar = structure(list(), id = "a"), bar = structure(list(), id = "b") ))) } xml2/man/xml_ns_strip.Rd0000644000176200001440000000130214517773421014726 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_modify.R \name{xml_ns_strip} \alias{xml_ns_strip} \title{Strip the default namespaces from a document} \usage{ xml_ns_strip(x) } \arguments{ \item{x}{A document, node, or node set.} } \description{ Strip the default namespaces from a document } \examples{ x <- read_xml( " " ) # Need to specify the default namespaces to find the baz nodes xml_find_all(x, "//d1:baz") xml_find_all(x, "//d2:baz") # After stripping the default namespaces you can find both baz nodes directly xml_ns_strip(x) xml_find_all(x, "//baz") } xml2/man/as_list.Rd0000644000176200001440000000345513633161317013647 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/as_list.R \name{as_list} \alias{as_list} \title{Coerce xml nodes to a list.} \usage{ as_list(x, ns = character(), ...) } \arguments{ \item{x}{A document, node, or node set.} \item{ns}{Optionally, a named vector giving prefix-url pairs, as produced by \code{\link[=xml_ns]{xml_ns()}}. If provided, all names will be explicitly qualified with the ns prefix, i.e. if the element \code{bar} is defined in namespace \code{foo}, it will be called \code{foo:bar}. (And similarly for attributes). Default namespaces must be given an explicit name. The ns is ignored when using \code{\link[=xml_name<-]{xml_name<-()}} and \code{\link[=xml_set_name]{xml_set_name()}}.} \item{...}{Needed for compatibility with generic. Unused.} } \description{ This turns an XML document (or node or nodeset) into the equivalent R list. Note that this is \code{as_list()}, not \code{as.list()}: \code{lapply()} automatically calls \code{as.list()} on its inputs, so we can't override the default. } \details{ \code{as_list} currently only handles the four most common types of children that an element might have: \itemize{ \item Other elements, converted to lists. \item Attributes, stored as R attributes. Attributes that have special meanings in R (\code{\link[=class]{class()}}, \code{\link[=comment]{comment()}}, \code{\link[=dim]{dim()}}, \code{\link[=dimnames]{dimnames()}}, \code{\link[=names]{names()}}, \code{\link[=row.names]{row.names()}} and \code{\link[=tsp]{tsp()}}) are escaped with '.' \item Text, stored as a character vector. } } \examples{ as_list(read_xml(" a ]]>")) as_list(read_xml(" ")) as_list(read_xml("")) as_list(read_xml("")) } xml2/man/xml_replace.Rd0000644000176200001440000000336113633161317014500 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_modify.R \name{xml_replace} \alias{xml_replace} \alias{xml_add_sibling} \alias{xml_add_child} \alias{xml_add_parent} \alias{xml_remove} \title{Modify a tree by inserting, replacing or removing nodes} \usage{ xml_replace(.x, .value, ..., .copy = TRUE) xml_add_sibling(.x, .value, ..., .where = c("after", "before"), .copy = TRUE) xml_add_child(.x, .value, ..., .where = length(xml_children(.x)), .copy = TRUE) xml_add_parent(.x, .value, ...) xml_remove(.x, free = FALSE) } \arguments{ \item{.x}{a document, node or nodeset.} \item{.value}{node to insert.} \item{...}{If named attributes or namespaces to set on the node, if unnamed text to assign to the node.} \item{.copy}{whether to copy the \code{.value} before replacing. If this is \code{FALSE} then the node will be moved from it's current location.} \item{.where}{to add the new node, for \code{xml_add_child} the position after which to add, use \code{0} for the first child. For \code{xml_add_sibling} either \sQuote{"before"} or \sQuote{"after"} indicating if the new node should be before or after \code{.x}.} \item{free}{When removing the node also free the memory used for that node. Note if you use this option you cannot use any existing objects pointing to the node or its children, it is likely to crash R or return garbage.} } \description{ \code{xml_add_sibling()} and \code{xml_add_child()} are used to insert a node as a sibling or a child. \code{xml_add_parent()} adds a new parent in between the input node and the current parent. \code{xml_replace()} replaces an existing node with a new node. \code{xml_remove()} removes a node from the tree. } \details{ Care needs to be taken when using \code{xml_remove()}, } xml2/man/xml_path.Rd0000644000176200001440000000075113026552053014016 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_path.R \name{xml_path} \alias{xml_path} \title{Retrieve the xpath to a node} \usage{ xml_path(x) } \arguments{ \item{x}{A document, node, or node set.} } \value{ A character vector. } \description{ This is useful when you want to figure out where nodes matching an xpath expression live in a document. } \examples{ x <- read_xml("") xml_path(xml_find_all(x, ".//baz")) } xml2/man/write_xml.Rd0000644000176200001440000000273013633161317014216 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_write.R \name{write_xml} \alias{write_xml} \alias{write_xml.xml_document} \alias{write_html} \alias{write_html.xml_document} \title{Write XML or HTML to disk.} \usage{ write_xml(x, file, ...) \method{write_xml}{xml_document}(x, file, ..., options = "format", encoding = "UTF-8") write_html(x, file, ...) \method{write_html}{xml_document}(x, file, ..., options = "format", encoding = "UTF-8") } \arguments{ \item{x}{A document or node to write to disk. It's not possible to save nodesets containing more than one node.} \item{file}{Path to file or connection to write to.} \item{...}{additional arguments passed to methods.} \item{options}{default: \sQuote{format}. Zero or more of \Sexpr[results=rd]{xml2:::describe_options(xml2:::xml_save_options())}} \item{encoding}{The character encoding to use in the document. The default encoding is \sQuote{UTF-8}. Available encodings are specified at \url{http://xmlsoft.org/html/libxml-encoding.html#xmlCharEncoding}.} } \description{ This writes out both XML and normalised HTML. The default behavior will output the same format which was read. If you want to force output pass \code{option = "as_xml"} or \code{option = "as_html"} respectively. } \examples{ h <- read_html("

Hi!

") tmp <- tempfile(fileext = ".xml") write_xml(h, tmp, options = "format") readLines(tmp) # write formatted HTML output write_html(h, tmp, options = "format") readLines(tmp) } xml2/man/xml_name.Rd0000644000176200001440000000225513633161317014006 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_name.R \name{xml_name} \alias{xml_name} \alias{xml_name<-} \alias{xml_set_name} \title{The (tag) name of an xml element.} \usage{ xml_name(x, ns = character()) xml_name(x, ns = character()) <- value xml_set_name(x, value, ns = character()) } \arguments{ \item{x}{A document, node, or node set.} \item{ns}{Optionally, a named vector giving prefix-url pairs, as produced by \code{\link[=xml_ns]{xml_ns()}}. If provided, all names will be explicitly qualified with the ns prefix, i.e. if the element \code{bar} is defined in namespace \code{foo}, it will be called \code{foo:bar}. (And similarly for attributes). Default namespaces must be given an explicit name. The ns is ignored when using \code{\link[=xml_name<-]{xml_name<-()}} and \code{\link[=xml_set_name]{xml_set_name()}}.} \item{value}{a character vector with replacement name.} } \value{ A character vector. } \description{ The (tag) name of an xml element. Modify the (tag) name of an element } \examples{ x <- read_xml("123") xml_name(x) y <- read_xml("1abc") z <- xml_children(y) xml_name(xml_children(y)) } xml2/man/xml_cdata.Rd0000644000176200001440000000061413633161317014137 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/classes.R \name{xml_cdata} \alias{xml_cdata} \title{Construct a cdata node} \usage{ xml_cdata(content) } \arguments{ \item{content}{The CDATA content, does not include \verb{")) as.character(x) } xml2/man/xml_serialize.Rd0000644000176200001440000000172613633161317015057 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_serialize.R \name{xml_serialize} \alias{xml_serialize} \alias{xml_unserialize} \title{Serializing XML objects to connections.} \usage{ xml_serialize(object, connection, ...) xml_unserialize(connection, ...) } \arguments{ \item{object}{\R object to serialize.} \item{connection}{an open \link[base]{connection} or (for \code{serialize}) \code{NULL} or (for \code{unserialize}) a raw vector (see \sQuote{Details}).} \item{...}{Additional arguments passed to \code{\link[=read_xml]{read_xml()}}.} } \value{ For \code{serialize}, \code{NULL} unless \code{connection = NULL}, when the result is returned in a raw vector. For \code{unserialize} an \R object. } \description{ Serializing XML objects to connections. } \examples{ library(xml2) x <- read_xml(" 123 456 ") b <- xml_find_all(x, "//b") out <- xml_serialize(b, NULL) xml_unserialize(out) } xml2/man/xml2_example.Rd0000644000176200001440000000066313633161317014604 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{xml2_example} \alias{xml2_example} \title{Get path to a xml2 example} \usage{ xml2_example(path = NULL) } \arguments{ \item{path}{Name of file. If \code{NULL}, the example files will be listed.} } \description{ xml2 comes bundled with a number of sample files in its \sQuote{inst/extdata} directory. This function makes them easy to access. } xml2/man/xml_structure.Rd0000644000176200001440000000250514517773421015133 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_structure.R \name{xml_structure} \alias{xml_structure} \alias{html_structure} \title{Show the structure of an html/xml document.} \usage{ xml_structure(x, indent = 2, file = "") html_structure(x, indent = 2, file = "") } \arguments{ \item{x}{HTML/XML document (or part there of)} \item{indent}{Number of spaces to ident} \item{file}{A \link[base]{connection}, or a character string naming the file to print to. If \code{""} (the default), \code{cat} prints to the standard output connection, the console unless redirected by \code{\link[base]{sink}}. If it is \code{"|cmd"}, the output is piped to the command given by \file{cmd}, by opening a pipe connection. } } \description{ Show the structure of an html/xml document without displaying any of the values. This is useful if you want to get a high level view of the way a document is organised. Compared to \code{xml_structure}, \code{html_structure} prints the id and class attributes. } \examples{ xml_structure(read_xml("")) rproj <- read_html(system.file("extdata", "r-project.html", package = "xml2")) xml_structure(rproj) xml_structure(xml_find_all(rproj, ".//p")) h <- read_html("

") html_structure(h) } xml2/man/xml_ns.Rd0000644000176200001440000000262113633161317013503 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xml_namespaces.R \name{xml_ns} \alias{xml_ns} \alias{xml_ns_rename} \title{XML namespaces.} \usage{ xml_ns(x) xml_ns_rename(old, ...) } \arguments{ \item{x}{A document, node, or node set.} \item{old, ...}{An existing xml_namespace object followed by name-value (old prefix-new prefix) pairs to replace.} } \value{ A character vector with class \code{xml_namespace} so the default display is a little nicer. } \description{ \code{xml_ns} extracts all namespaces from a document, matching each unique namespace url with the prefix it was first associated with. Default namespaces are named \code{d1}, \code{d2} etc. Use \code{xml_ns_rename} to change the prefixes. Once you have a namespace object, you can pass it to other functions to work with fully qualified names instead of local names. } \examples{ x <- read_xml(' ') xml_ns(x) # When there are default namespaces, it's a good idea to rename # them to give informative names: ns <- xml_ns_rename(xml_ns(x), d1 = "foo", d2 = "bar") ns # Now we can pass ns to other xml function to use fully qualified names baz <- xml_children(xml_children(x)) xml_name(baz) xml_name(baz, ns) xml_find_all(x, "//baz") xml_find_all(x, "//foo:baz", ns) str(as_list(x)) str(as_list(x, ns)) } xml2/DESCRIPTION0000644000176200001440000000362314533377212012655 0ustar liggesusersPackage: xml2 Title: Parse XML Version: 1.3.6 Authors@R: c( person("Hadley", "Wickham", , "hadley@posit.co", role = c("aut", "cre")), person("Jim", "Hester", role = "aut"), person("Jeroen", "Ooms", role = "aut"), person("Posit Software, PBC", role = c("cph", "fnd")), person("R Foundation", role = "ctb", comment = "Copy of R-project homepage cached as example") ) Description: Work with XML files using a simple, consistent interface. Built on top of the 'libxml2' C library. License: MIT + file LICENSE URL: https://xml2.r-lib.org/, https://github.com/r-lib/xml2 BugReports: https://github.com/r-lib/xml2/issues Depends: R (>= 3.6.0) Imports: cli, methods, rlang (>= 1.1.0) Suggests: covr, curl, httr, knitr, magrittr, mockery, rmarkdown, testthat (>= 3.0.0) VignetteBuilder: knitr Config/Needs/website: tidyverse/tidytemplate Encoding: UTF-8 RoxygenNote: 7.2.3 SystemRequirements: libxml2: libxml2-dev (deb), libxml2-devel (rpm) Collate: 'S4.R' 'as_list.R' 'xml_parse.R' 'as_xml_document.R' 'classes.R' 'format.R' 'import-standalone-obj-type.R' 'import-standalone-purrr.R' 'import-standalone-types-check.R' 'init.R' 'nodeset_apply.R' 'paths.R' 'utils.R' 'xml2-package.R' 'xml_attr.R' 'xml_children.R' 'xml_document.R' 'xml_find.R' 'xml_missing.R' 'xml_modify.R' 'xml_name.R' 'xml_namespaces.R' 'xml_node.R' 'xml_nodeset.R' 'xml_path.R' 'xml_schema.R' 'xml_serialize.R' 'xml_structure.R' 'xml_text.R' 'xml_type.R' 'xml_url.R' 'xml_write.R' 'zzz.R' Config/testthat/edition: 3 NeedsCompilation: yes Packaged: 2023-12-04 14:50:27 UTC; hadleywickham Author: Hadley Wickham [aut, cre], Jim Hester [aut], Jeroen Ooms [aut], Posit Software, PBC [cph, fnd], R Foundation [ctb] (Copy of R-project homepage cached as example) Maintainer: Hadley Wickham Repository: CRAN Date/Publication: 2023-12-04 16:30:02 UTC xml2/build/0000755000176200001440000000000014533363463012245 5ustar liggesusersxml2/build/vignette.rds0000644000176200001440000000031614533363463014604 0ustar liggesusersb```b`afb`b2 1# 'X&/藟]%9h Pm:I, Q,LHYsSь`wI-HK î?"5lP5,n90{C2K7(1 棸(\^P4@btr$$ eQExml2/build/xml2.pdf0000644000176200001440000043757114533363462013642 0ustar liggesusers%PDF-1.5 % 124 0 obj << /Length 1033 /Filter /FlateDecode >> stream xڕVs6~_[a$i.te:sיsŠ`j~$99`88yBjӷ Z.+Ϗ RLţYȬ?$]'9s\L?9,~)1!1, "Z2n!M %1T{rE |pPddG[V<ġӣ'vEϷa." qEmESُb}b"F E}ڇDn񹐫a Eeb6%26(d4E-4`@R,J&Bަހ-n>e>-=4Ck Ͻ!EQؾ%"3sMA|u(w^(m.I"oBlxQ)nX) z@^AY&5ԹE^Rt,xPLZ:QbrdX?^&}C8ĎzSExs&;Kݦx hTdnyy?c]mttU _g\-:R^yJ3"LwL vC h4Ɉ(WMa1 -E!';kL@HvO:jp2OIL12&3kJN bzX\tiQycə`ˆY3{(.Ջ@avSpi)f /UXwjWs}[p}bL!Dc01MӾ2L\62)|SCq$MS /zK?Mg4RGwi3K[fM\0{L`bcpE;P\!:Kʦfnϕ {͖su={FL銥3[U[ P T KX&+V endstream endobj 159 0 obj << /Length 806 /Filter /FlateDecode >> stream xMs0ADHi3cƷQA5H$I rMҋ.0첒V`zy`#0 V0"1 #Jpʃ%a:Gbc$|$KQT0˼v?f xΫy48Cw$uK%Zm2nekEғz a'NzcUbЊIZh݅tgVm2d=Bi|"9)(F/2HHcꐓ^uvQJZuY((B!t6840JΞo-@#p#G[E:v"7!ˇlDn'ԣv#gҘd2~ kS5 C}^L|(;Z)i#k22~>}nc&5yȎSŷ=?yꯏ_W@Z$I endstream endobj 197 0 obj << /Length 1837 /Filter /FlateDecode >> stream xYYoF~ׯ` 0W{ Tn"Ap`M,Tlw MʴCr9{s`oM;18C0FN`3R<9  4!S$3l; "cx4TmsW8v1~ZFw._"Rf\~E ڀ`#,Ez'^Lܸ_s/ؓ |Sy %OѸ; (# Q  0j ^f_gDӓ@#bNa'#RnN)gϝgR{&'I0N@9b̿3{;∴v,e5g*3ͦ(SYmSUEI0!0@cF(dTٮ %HlYm2BoW?0i췲hg2$!RyUZʯLv9t?Ɨ^c}ohZ6UV= r@ ?RZ429qnp:3ޔ";RQ~11D-A.v>~4N)נ6]sJ#(!ڕCYYSM7u^VDI0(9YUYjLڤr='PZ!R,fr4o/ʡ,WGnUQW$QUM y@t=)R#ζY.B0w+$h*;S򐨁0a@Pv~v_76MRVXvgHVˠM#>̉(+}ؽ(jUN Mޔ _]DNK EOýpaE 6@j'o'ӑiuIppYsmc`,d%*!g>Z6 lDw̛SXDG}U&`0 1 fͺWf-uE\ʵdyZɖ Nqv#UuJҔҋ`羪j(j&?Ӄ;1,6Ŝv{ QNQw<ʑp֍\L UG8 Br]9$yJQ$ĩj^E.rQO>.r#&f=ɇɒyƚf)Z'ӽey0;LqXhHjcz{CDewY'b׵y^ b8X\jBkP$]co}w0R[Iv.~{ІLC.' \x ?vľ|$K 8R=AS| 7Z]G FX ak֚7jXd4D2<c޾U4W0> endstream endobj 2 0 obj << /Type /ObjStm /N 100 /First 824 /Length 1994 /Filter /FlateDecode >> stream xڽYMoHW19l{a Av' n-1$3~_QTSm9bKTWUJ8a"6Ah%@B[a:`: k -l p r¥ O(ƈ0X]@O^ ^X [M,(VaN{X Z8Ɲ) Y .bFvFM< [f :8 zX"/7/1m1)XJ4S ?K&pRf Dp xO<\O4|@ ~9 ^\9{+ 5OoM50FK|+ t צeX #ze34b! ΢ Ax9FaB_v#bY4 "Hi!- ip4nv,QqNiʹG3tɶÓ mu{L¶'Y*dJqߡNA9VX VV>n[ogӔ8y{ gg<.oդel7̜UӪ麴?ټyu+>+nߓ5Z-c }Lo[.W@,9dnGƋnyUϪ3._X 9il;e$B$-h;mdqsj*1_xwv|,>:7WmnZ]We1[^ƋVg^&h6o6\١hm9V6'W̛fS5{,W$NFrX\<6W+;C1=-8+;~lvݹ**~Wӏ(>a+ٻҽA}cDG׏C?~ܮl>lg{<xdz=\z<x΍$y5щaNNyO Ϣ8T]]sHm42?>I!Du|].`ﱥCtH? endstream endobj 225 0 obj << /Length 1255 /Filter /FlateDecode >> stream xڵWmo6_!d_d fIPR}tC"%& KDIHʖl5ɖu;>ڡW8up;(%~Sȝn0xI=hz/*Pz12a@R5x"ɶJbgYN{AX F Fg1mвڭ(W">8$fwo+QOtM27K!e(UEC ? Ka239 Ę|%;%racgbqf/6襁.-f ,Ƚ_Z%[Cti ә$M<-δX{ٽUfVU!,tܝA 04Zɬ-sɵ0d=*C- ;@ar %(i#XRi*(LݫO4Mlw6yԱA-|KrQUF)Yk> stream xڭXo6_!/6P3`taKa@[DZeҥw,x"ϫMyb?V`0(U}KFji;c>H3fa'&$=ey$IBy%Wq+𖄠,-c#f oʊ-찦5tϴ0)\ݾd݋bxq}1ɹ铃WWK+e/',m/o~l$~2?|3(ZPD:ώ6q,Bj#0jG%V[K;Z%߾ؑAZ42w\Jq MV\$hڱTa:I6Z`>bWn!tDӦ mck 8CďZ}&;$Mcztockqfխ.smꃽn $wM"}Cp8$2MCX^nop%Cܑ:͔,m9$ki8dDu)l".Nj@( S 'nBt.9d I'N*I ]|+: Q'ٓ|*Fi C''9],ՖY>/LѲCx_$#\GZrKp!6X$,IG^On̮W/3bJ/Fg>aE,up3Pף{7Qb F}]ăm>t[F]z۾s執o8#? H#?&mR<=ʓ, 52_ endstream endobj 257 0 obj << /Length 1414 /Filter /FlateDecode >> stream xXo6_a)+5e 8Űu(hNɒ!Mڿ~w$%K";Cx}R&oOЛ$$ Y8-'Iz$dNr߳_10'rY*)ҏO9<+2q3.hN^=7^rڅO\0# <ϑŢLެ~4%ؙ?>(e\H(LBbəa|~.zL!7fョ>j^rgA1(oK{ =RϹ߬d^8voG!DX[jϧ. z60 b[O0Vf;kӖ^~]}xJE6Ie0 <ÍXʪ?NVD!e9{p.p’pcQb'D?8dUU=#Jz7=½PoFKCB$qVDOٛk|sc(4鎿LXLQ}@Pgh6;C@?J2I92hj] }O)z;n>Z/}B(,c9?濘 ֐ endstream endobj 268 0 obj << /Length 2408 /Filter /FlateDecode >> stream xڕX[sJ~ϯP{t8/a!)xd%*Ž_=";Tzz{mzVśч`қIźg[p]{,gO=+a4"śk"N49<VMKy/6ǕndYoRBU呤6 5}aQ `Xl~& 8~$߼ $H.2~|]tj&0;Gy~DթvvjIc%b`i?2/b>H\ xl %[myUWRVGi܉hẛ/^N;m4ݨgRɼf*cFR˲JȻME2L5.xFI>Z&1FV} ŖV+t.,'n8Feg ~b8Y"m3>[ۋdNG+9F2Y8rF*B/#:H_ &: L=o&p;8 JraIemtq,`@]A}#s *&08(~ t~Z|f O_~7 yUd`c2KPBzkȊ8nYJkޭH 8~Q*Z&T*4'Xlo=&<튲L(TTn93UlĽ~> F '؝Ǣ;K6_TH{II y̾!m,z& XJzCl7e$Td7XJqT_`\P cMd杨qkhSSqȜ0`zy[# @%Qi*8Bhxא|(n󲨶DEL xu*cW+['J="LԈ9VOmyys殹;v`=eGXR }ֵ͋p`򺅼P%#,76#86EReVԣO>tH '}oacG"E0^ ̛-$>hz0 q]OS?c nq fԏ3-=Fi•\=#Dz-Ǵ9i'jCq\@Q[.VԣĹo|CS%Kޥ[O~?-GcmQ1Kd }WIb栴 W,j#υqqK\rقۂT`6Y\X$7VOO}ѯF ӯb25' G9p KRrBLt(9Ƿȃh(6El|[a3}yvGpッl,5SġmCtqB+MSכ!vұ]JuXI^q9XfZ]3valPA'>dT1Ž@8FǻkDO`` @(.z|4;<3%8Fv)EhOϋw677ݾIcSs MZ,<0mǤPaӨX@Kk9w?JyNrtw4gBE*Kmt4 endstream endobj 280 0 obj << /Length 902 /Filter /FlateDecode >> stream xڵVo6_A/60SU-Y1ں{ h[dzݸwX$ZAww"huz1rnCnkD ($8\HѧI< .&^b?AM}%[2?hQk¹ bFnFա9b#9vn}b11&IbtB&o3- s,rg eyJ>سT( 3Bg$%Xk)+fU8Ws:GNZ#]QWs\\,1?SGGʥ8q'8JbKjQR\QLOFXJ~\J93üW!nwԆP>CAm] |<~u~^ƥ{>H=2 endstream endobj 293 0 obj << /Length 806 /Filter /FlateDecode >> stream xV]o0}ϯ@2T+USui^jrIG~,Yۗ{}ϽƧd0ȅ!A0F1rjLB\dx-98x&p9LA6-6Bxe'il0B//mݱ6FJ>; \6u), q Tʅ0}X~"2J NoG?N6E]$c}-LgNFusڴ;vIJ]\*Pa:L>ԁd610(k8-2VIYj^&xޓ\2(U^/,*(fNwD"v& ^CzfUy̚ ӤQҮeFwreYTた4j(VuKv_.W28_>mq65!P C@rRC9nD츌х ` #od^#זԨ[V$Jb8K2T {H^"{wU#uaNSI=DYrTtHa e)U|9tBIuz1ꉒAc*F{vEuAV=|nWoeZ̄Ys8_Űlfi^6e"I%j69t'~wTdADyXN Qx8?wJÞNwgE tn7S endstream endobj 209 0 obj << /Type /ObjStm /N 100 /First 881 /Length 1838 /Filter /FlateDecode >> stream xY]O[9}ϯcgP%ڊJVؐ!AIg.!]Ⱦs3cC3PhIdk$B[LrPq&s@K$S!<%N]2:x"bXFcXI#$|;%{cd| mghqVX$ӑ?;.s l)!$KI7R\v*[%)jג Kr.[ 6X݊BJQ%Z˪?:ubZh]hsx!0δ$I </e["KI{3 N7K&IȤciŽ6ҘN.:[5.rW6*4dgMRl@O7#GuX*8!,ڍDRh UZfR z+ %Nv5vh_EC(.v|@yE-VW0]bdn}fo: {kssx3b{;pBP+k &`֖Яӆ9&8 !w4 PKx3|\K_zJ+HZrIdL.ƣѱ:u45!fR<=H>mmG/\}7W<[F}=E_ v1PEMs, QJpWOD ƪFP"%O;35'V#BR#<4X3&ߞ,Z0QX/OGa[^E!vg/BMRzX.7F^a> ]Y!,{#ϐQ>\ pvf?NAi^gLm'o>5fpNkt~3Ӆ{-p8'FAP)ɿ4;Kٷڌӭduv{kRHI-QݒZ,3y"8o8w+ҫX0cAj] 'PS^HW5u1:0tJTvLL*JxCq _ȅbK lQX^TWz1e`ŕ:0}Rb~p|Czu`Zc-@wZ<+*ݵ2w{}@R`J06;y_7䕜ghXf".+^ו J׵Z: $> stream xW[o6~ВDH tk :`k]X[DdQ\/Mq`{(; pzl44"g6w"'0 }ϙΗ1owp2:I 8m[ zu6 .f#$vKq7?ĹUWN@8GJlO0`'D^ƑuCiB:uw&kz}3vkQB߯0 $IRw}"cP74 7iu?1V2XEIO<[нQu"&A:~!yL_VԐ!C:W{>#G_+*02$WJq﮳=+xU|(Ch.S{#78ruΊ^g>.ddžd[7cVucyhp^ ڛUluz9qI 3/|ݚTS.V7Cyυ7~+&a8@̈́>0juWPPNsVIKqފ)ef!͖BaB$.7RLuŭcԲv5;{,{?fEQJJ В>ԖlmoI?ݔ]-| Z-uz!mmMe2\6~xH8.p'<]`=5*(6#HegeMAa@[8q%AWE)4I{t+P0F]$ l(ȝ,ÇdBYog]}'ta@e.54Q%ȷ9V1$J߿RS dY̒'D Q4%&G`H+spt-*].eЯ/Ua]ss͏jAZ;w9kəjf8v#Uff3k;|P(6ףX=m[0!?N0!$BwfZ > stream xWo6~_Z@7E{ȰXQ>EHt,L3IN~G%[qݞx}qpԁFZR1.%1,ܗ2!}R&z hvKjr8Rr326O:e 8 "sx`p2A00@T1akX2LIiÈ Mڍڭ7X2!#KV9;b.QRhwbo|[MNF ")lnK8BUYa27q[ڕצvvqٟ0E./yմ,in>kk($z~zW=L_ZL ژg'i%0MM W~#KHH~h3)Za/OX`WVOnx;@emJS{(9ꢘ^I( ww}RǠM]!O mb(9X 䌎@H~!:hT(u?yӚ =|yNJW^%m[?C0mw<#8mJbGu8U>Qt^OHc¡'U!$]j>,f~ ?I*̙&6#CA5)6dO[fpIkWb[x"7}I0;U쨂oL<:FcrGrgt7wtW7; PTuR"ՃFB ٴD,s>n_z[û_gͪ<8O'W; i2O7Dp}oE I^ChH7u5Xf_<<{"]lvg͌7 S>6OBi3Ͽg=g?FY,k4dK endstream endobj 342 0 obj << /Length 1617 /Filter /FlateDecode >> stream xڵXَ6}0܇@!)Q` mӢŠ/Im%Wg^.EckA ˹.63<"z.> @2c&`F #/ӏ2\/y|V|gF,(Eѿk cBK3Q7^e٫l. LY-'q(D1!Cfs)JX~TpRƴ ދ?KnsK}!V:?Rkzn^,ӥ6:_mKSO- Tp_E HCeG zYmJ*#OBBJvD)D3V/ZW_0ddBn-Q RN}E1JH=l :4w'_B~֟҂E4St$BI 6U'9NQ rn(> Zer4/i͊ׯmձ JJo.gYk0!hDV 0V۬V- ޫetH>6<4Ԡ($ ?)Np=#$(N#($F.4f|y1lf( {~l,Nxn@M6mNbTj^Z3z>pvIQdm5eizS0Hs.1 "@h$IKdT[7H˓,tB4^<ژ\Q(̥(#c Fe #l/xl?g;&`, vӞwgͳ dWu~[Wr~}(@p$EB&A'@6,ޮ;PwTAVjՠ(* ,`ZVy7)8h9ӣAޥ%slqQE ǡ.[[ROЁRUL o8_և(uNLwoQ7J1}zLfI4zO0ȫA}nmf"g闝B1q,\ Xt2pvt%jK%&v2`lno۶\_ZUu+|_*zؖj8_CkrnڔﲥG#l_$yn&$rhvǏgWJ(g]I^ CןOj' ͞w{ގ:j->F:UzHSc!KtsA@q`8ӕ_/9hޕi3(XN=W ]"x'˪r9~zF/aUV7Fgۇj~>ԣVO|7g Sv!̳H=,  endstream endobj 349 0 obj << /Length 1013 /Filter /FlateDecode >> stream xڽV]6}ϯy)3R٧NJ 3{MH>a\gfWd(TzG0FK/ FU=/1IUϫpLPA602.;Nb%7K1YJ?a2 czif ϟ~ҹ>e 7^?7zĀvI0E|UflCtf?3GȘH/>c/8Н sϣV{=0 aF τ=YC9XGQnˢnCK*fiE [ŀ [l"XwNlde1i[&Ш$B2zΠ,M*&X04g訍iȤ,]4]|ko`s"\ٳcՖۻc& f0ڌ ugE:GJ]p{wy"qX=PE_Ą@ w =̈UǪ,@4}LY)Quz4%[UU治p"pJo?ԗlJ C뱵eW7Y, pd0FRuW{C&[͡*0A00A}/&+.A[mTb k4Q G_)ŦN 1"&M Fd{goa+/ٱ7)(dq^UƘL0A-q0Ix B|\roԴ|kֶa$KSFq)R 8UgOyVl&["1Vʤo0;uP:bΧ`NQ(j5;ȝyAЪjgv$[I'uY caݦOo.PLKUl}2z >!c'y kº.{-u> 1;lz t͞KwοՐ] endstream endobj 371 0 obj << /Length 1524 /Filter /FlateDecode >> stream xڥXs6_\_L,K|II.v1KmKܿ`Ĺ~vWZkZ?~-j$^YRzc]g֍ͼ8]#,1qN ΨѰ ^sFusy屡 E$Ccāga@콜/Y*g(3ne' 9P0fa4,X@z$Ots]Wsnﱳ}o3D#KDp)lX"E+]_7m]h'ӻW( 1#y()WhqH8}ā툍di×tm7ʧeJM}@J9Jck>S)C(ujzug<{5P y:H~0I息vA_K'źL^h]L@)[5XKDlFtBX`f*VCΎAӛMICaBP'.ffC763k;`v'okmvyx^(ݜ)3m|Vԭ VzSG9zEbO)'͕̕c{( Rʺ[§>_g͓3`|sC8Ϋ^K.Hu nx2Ѡ!7Ў䓇onP@dF7ڛʆB%.x7fj q **_ˎx#eTmT*Oќ ~اqEc@tBvϗ!^-zM,ּq6ld!o,MF6qT)I}ٗOJ$VC'WqNgzv?cjqCB#J[je GփbZ9[g< Y @q9+s(x[LD?:94&xʙ脱0",2}eZ 5=9̘S&k~)8bE{B endstream endobj 380 0 obj << /Length 1032 /Filter /FlateDecode >> stream xڵVmo6_fE]]V 5CvHC[^<_RGɒ-5}0x3֖~7Yy.FejaOvyHx2}긣nc<_`zđ*#Ѝ +e\US'MN zևqc#b:\flStͦ9t?ks>wQ"k7@D,OuɥLzA|?"p:(piul%"^Y"v/ø*K>>rdV,eEs +b(^EUsZ4y8wD>HK7wG\-GXKG׶jDǶiGr>Uc8qa+8t':[׆1 gpowoA$VQe1;|0-ZFDwАp}\^/@Lxp|ThQKuRv@ff ڤ\ csۘj6^^__>̕e =XvwB:*Y{= o/MbJaqu0h0)şo#6 endstream endobj 393 0 obj << /Length 1999 /Filter /FlateDecode >> stream xڵێ}B@bk$RaKd-FmegݯPdk4cx>_{#TFq()E)P2tFbC8?JYY"\=>||P0бH ?`  Sτz "BX]j02I^$ }ޚa-D _G 7:޺!xu̺|ՁYſOYAnq߬Crm[ԕ McR#k CӅk4 Ĭɟ]7ũ3/vBlT"W'TMUY{P;6ˬaAkָenp8aOz+OItYSޣ\pF"oOeq(2+%dq1SodSM*k=}>|:{1O$Aw7jjn^tO}I0I<dPBF6z AHTSu['1[s1[+3>YI5c|8., ap!S.tYEHX(Z 6x~+(;QS$*^kLf8eR{ ?l %fP碱}D}51oX`CHny ݲraY:sEQZ0`zFlp 'w({MSP9tBbPFX])҈@?u!mׁ{爥q1w𖭥i L.@rLID"-[6}Ͱe֔XqId`4!Jxay`pG-ʌas>'O'ph@<#X{8gdܾ: qYbv}U|yӸ:wLƚjC+=tn1[IP$jl{ B!季n*ַ"U[,~NM >G!#r./uߝzS|z ՘/gKCr+ ?k8HEާŧ%Ũ%R;]cįy _4Ґ]tѻ)rTcGTˣNrE9"|8&|&7j`5 endstream endobj 319 0 obj << /Type /ObjStm /N 100 /First 876 /Length 1464 /Filter /FlateDecode >> stream xXMo7W%9KCN!p-m[:R @feي?Rʶ^rq8U %.#t5lSr6O$+5 R̮bSK8 b("^Xac%O[BL'Q@ F@``@@oJ ܉0N"(nT2Lء(R5*( 'XRo&h'HL334$*XU0Q8,Wr`NM"$LF$ƤȀ Z/#k#bbsH0 ٬&*1{1 v(zj 9EFc ٓsbZ cPMKJ  t%8W3)n6C`n9*#)'GD28H1U*5?v<ټK&Z fJqbWN" ,)d ' /)bĉw0 %K _Ǯ{u~<^L'd1Gh<>dz/㣓OMp4{8}4͠ޖd oi{=[ch}x;=y ٷdޛH^̾?>яq O&?M w~é.%yMNOo`wÃ)#^cu ؆$ފg]]IvPv'VKj "x!M{5/w]ziq5h 5S޹t8ʼj#8Z5g F0W9zC60WoF큼EuS 5v.{|Zq/ws)dUJ@@W V\ag[tu?L_O.ģ٩̟[\dh d xGGcp'QV*6R)SslO؋\Sof듮FUB NX9כeިYNV=ޠ'[- lU/ϩ 7RWKlFbx-EkS??6*䄏O"ǩA|xY1cǮ.jf#/US:ۄAr8 MYFpT D5m5x ɗ6 >knwM 5\K ޳(&~7ɣAl*^c8mp@. _Gk>N=/.9{֠dnHO ۨA)dU`/-T )lKǭ@+R JKH=c/RիƯເ= endstream endobj 410 0 obj << /Length 1223 /Filter /FlateDecode >> stream xڝW[o8~ȦH1TH3v4+)7RBMr(ɿ԰1},&FɈMg*>LvB:ќ4(&_ E4 Ca@znJ3 D[ەW Ɛ9 p}nA.>~,e?Nux)ÄwNy]?KǨ\S)M= |ӕz%7 ",/z`W?ל0yr(R|nGL;"+>LB4A,{-;}6Nv'X}pTȀ`Y^+NON%JIOI? {$lK)ѨT7 fex'nfmLuu.$>QUCQITF[ . 5J)iDH~_HeڜfP7E*vRZ0 b%CdEUۥΈ+rCZ؀|ڝbŚ@K `Tɛʪ&R>-4 V|r1b%Zj6vDLVX k7<\*I:O|~\ĐxZ [)V*3$ UFSGfYcڙتc$t:š2g1AҩwL㫌-z[#7ZE\z:B`-C%L~q܁v:+&H[bZҘ:p^芊Zڢ* }w(μS.GF(L֕X/U̵}N8Z8˪hmQQa.*<8\Ň٢'lkqrƢf8D~$69|+9hݱ= n|S;o{Fl)C2[j>鱍y{%R.Yuu|o endstream endobj 421 0 obj << /Length 1329 /Filter /FlateDecode >> stream xڵW[o6~$1CR$Ynkm^"% K$q~/RD[nC;Wboa{bQ^cB-rO#Peb)4e.FV5Vֻˌ{Y 6OǏ|⩷פ/"%QcxնDdl  $ v>UJz2S1Ýװ%P3ӻzeVQD,i8";~TRazN[m vT⑩ீSDsQt5eGwb-e{8JAΘH߁˕@V\͛|2g|b@q[D=݊ev*&=#e2od.{s8P1#$t›wɏM&qlT'GmݶŲ<'0[u7^$ b8o,$'1ѣ,N)JPHFaj?R$T5?BW:ɒ7>UTRCe6uk3|mYi5tfQXv(F7Nt0| W}c+2.npѓ_fV51ڣ]ƕU?wr&15# endstream endobj 434 0 obj << /Length 1514 /Filter /FlateDecode >> stream xڭXo6_!t&{ȶfaڢe&KD#%GONǻ>(ltj~NJ҈Gb0JDNQY\O_H(RrEm8fNJ[޷Fv=lh'b yUNT# hڢf^H>^1B_]ZTy*͘K^~IXOSZQV`#i"N\[OLz0)dYh6^ m紴3b? 2]KVaM3cȴg}>LcG$MEb+f{7ck=U[r[M#8pmdF1 MZ]Tn6{~bWbu\[z kS̀nC7+lY|׬1v/#\N!1N1?=m;z-Il[+eAV,j7p "D Mp * k|U+jV sv*ZOG%.PcyfHd.V(|*42QP]Bnfh9{l=7lXQ}&?jz;G!A_WVS)WzBH5+>YHtlaB۩~C G[ &d #FG &!P Vو>nfj4@M| BqwUFI*ڊn"*Wib8"Փ endstream endobj 446 0 obj << /Length 1022 /Filter /FlateDecode >> stream xڭVK6WΡ6Iz-\[4)C"NzHh[$g7,zI9pfulVBzvo<0rjmcӂ $7D>N#󔥻Uu kwn_nlMqOP0c , Ҧ.^DG^$BDuS^U #}}DuQx> e> ~IZo$)OR/W4T+I\wS=D)f'RQwM&:2} Ѱbmo)x*ŮNi{ےKEvDN0 K#.Hi%98(9WtZEE6߬hY2[Fr(UFpW;6C,`GJLLkD[2yOW"oTEVPK. ;Ufʟ.˫;#`PkӽR}Ek{u昌@a&~t@2S|Ӏ|_X&wߦ\*ZdMJL̔G<4giQ-5K<ɚU&ZyT'EnJ+wziODcm,=YIo-iƿ$`JAB.$wf$:c@ \f:g8?lAt`kP dg endstream endobj 455 0 obj << /Length 1173 /Filter /FlateDecode >> stream xڵWKo6W4e)(ewm %UcC)Y~%NsHΌ MC_?9˝aN) <י%Ηn=Y~~SF)(ӌ.S,jO|LwM=,J{7I~8eJG.#[42^7UZibD, ۩ڴq=s+Eڭ7~6{@:9w7$p  ^4uu 0{@gΧ-Wf@L'܍c4A5=ADSfqQB'ȇ(bUYEߌ)8yڿTLcHYy^lJl6 uS&Cz9RshZR.7T;>,6M+gE"עWj'LdC++Y+}#n܈PjA~%EY˼!za(GϵXʓ;fp`Z >*ѥh ?x/!|wXw YT{T-O2^8EPd<╨Dۤb삄ׄ~'e&ק\ڦllhuZI|j8 L endstream endobj 473 0 obj << /Length 1528 /Filter /FlateDecode >> stream xڥX[o6~RYR%aKm@[Ldٯ!%\ uDw. ~4bv1JI^S]z v!=߶g%"+>VȫK><.DfΨoe*2bC0$6$As6_:7r/𵪗Wus(ْgGe``VYW(YTH&bY$l+zmnPJ;ަvYэ@ٍڍ.$~W4 Z{FjT1rk]`#'Iy U,4r-u#1U႒rA1$QNF"F,/5/Bc@x)(Ԅ\F9ai뫛7r!.0[:ei"N8rrgñuDLb}p]3s ;?Dxog`by׻tNMv0Gp$H("Xꎱvq7߽5ځ:3:.S5"I% dq{ޢP@Vn j)iۀ^jϸ=z4rVy FIcH;;v7@ise'3gZ`h7vM?)\C&xd==gbU4lhR*5 0Mm5'D$0PvTt4}#վc8]u(#e}{H9[>IPe8"nIJL Ɖ endstream endobj 487 0 obj << /Length 1021 /Filter /FlateDecode >> stream xڵVێ6}W~D4I8&[ % Mdewxcye7$Oɹ3Caoag^2N7_{cK8F,|}C!vދ >E|c iv~&wIC3 v\=k.&^ <6Q-"ck+WJT0;h2 B? ZIzy6QNt1.gFr6,fCPxO(27y$rQWbՃMW|<,`mJ-+%rf_M(EO wңw%X x-wK,΋ P!;>ZqCU(U!:',!Uht !OaJQ+Scva,C1DBF9bVJU=rѐ'2ĬB-puf+U] T2֥RKY7eU#;LBOSf|ȯ ײŨk}%̈́׮E Moڝ,fp^Dŗ_(N+$8. _fȡO~yD:_ FrY,W Vz_r.0TUF)KI9둦jM[hzn˧Q_ƶpJ4}n3^)T9Nte; :2iN,||~oeT5OR>GUlNvc&c?h4caM-Tme5׭֧~=u,0f5zF6ZVm PQI -5t_<g&@Y8?:r}_@ ,T-WfKۋJ?HZ4ݣ{iϘ~Qc%aD'N"uvCsԪkEݽMSE@a5r~ A;RS7F ?w7ݡ}g`Sc.` endstream endobj 406 0 obj << /Type /ObjStm /N 100 /First 874 /Length 1574 /Filter /FlateDecode >> stream xXnG}߯h)/𐞮[_" @DJ$d X1hHsjl^p*zzgkN]z4IHA5\,Q Z(I,W\%d4dM5SNRMWwŰCj@-dh`&#l dY'Xdؚaӹ$Cw`PvAP Z* j(O$ Nl(U%v@RJ"x®W7K6QMBU*Rĭw  WxWp,PFBkP܂U+f%P+J2C4+/vIB=~L%C ¥_5\4(F`Kkg` %h.Q, z_L7|QR9ԟg V|)NGT'cxY5+Rš  A4"R/TXKv ỳƊ&]ydxrddx<_O/CT" Abr펾|/xz?;Nl-'>G eUX)+O-P kH>║U_*U ;hs0ݠ &&y: jLޡFFE}E/Rrf3[X4 M&z'[M9|7݉LJgo% ۥMh+t6]^v=8'*2X"6jdt-Q0juSRZҩX$B eiMLuz)YU:ިwNkQ*, d9iHBqO渋1֍awgga=Zg_ra@_/|fx|w:h~|2{]$O.~>Bͺ|j HrN/;+E*aCoL}`$ 8Ķ.73I/7ua RIѨj|k|P~KXy{~Bbo%:0]`uc6gN3 ]`@XT܍f{a ƙl8~ƭb?qIN3>AsZ7x' RZN0q^(m)Gc]`;VG"7Іc>Ͽず฀ƌYS%˗Gl:dxve?"F'!4/ZVLxϬkZ;tu`ÈTE-D'o_fH̀ &\^7SS~[jJcNLt-7Rچ-~zbo:U6RIkK B I"()6+*jH endstream endobj 501 0 obj << /Length 1359 /Filter /FlateDecode >> stream xWo6B@DSȰېXڢc$Ѫ$q;>$ y:;;g?f; JB:c:Q ʜ.O_39 09gW{% [vy$D]lKQx\Rox~I #ݖq9ɀ՛oaTi׫󆷆?ViH3]\7;7u lгCZ]q>a /HkUK`sұp=GwVS }/e%39=_hyI$w d(_FgX| ON(e- kyQhliq/8a~y_gOWga* "v"1y,a ᔄ1!--,?E>lpMډ(MRq># v`>MjW(%G/ yTCGTV8f?RB/:vM$= ٨&_ ~ g1/ STFY͢b$wF*H`[9&yf>c֏ygh ? q;[IrfuR 6!ܼ~wh\Ks- endstream endobj 517 0 obj << /Length 944 /Filter /FlateDecode >> stream xW[o0~W@*$N"Qnm'MZ*M*BBqC널O[ !6>%=8 %G'6讹DT{OJxP츠,2[BPo\efSG.dYո(r0r:Vն ivjM<_&ǝi7gΒPR&V&(8nǘvA#T쁙+G&y ȃq߼šAbtc,Lza> stream xڭU[o0~ϯ@ H؀LLK'Mݤi5*-@Nc4Y ccf`d؈Q1cQ5&qku7G>;&_ܯ-lLp1ڏsNwUVvCy,X ګ꣉nL"6ݑeɜU,RǵEQs9U31W{,#ؼbUJ'h@2`tqOV$~ĜMrj}S @`"E1@ *"1H#E,F ?݈O }Y…q5ڋj2]~@L0Bp 8"-sn,Bȶ||H:yΞI4QD:"Nl)xEȋ{ey,%YQqpĤs]?yz٭nC^JhZg$|K:kԅF)vTʫ lBQ+7 z IYBV꣟}c_[y`&qs+r~Mô*s :N^ʳ*r*PR/U,@qcٺF0${C#?ZM3^aNYAy6t,YS6cs8SP>9Ͼ+ AOG0[ endstream endobj 629 0 obj << /Length 1567 /Filter /FlateDecode >> stream x[Ko6W ԌHTY"ma(c eC7F}IKV$^7 FV~37Cu֎|s[y$A.0uOOoiďzzQ"rq,2E^n9O(ɔ_ DOiE!m!`VK2ڭ[ RW46B(-B* %slp{1 eH kU1&"CÐa 64<ޥ:P 3ͅP Uc ɛQ(ZaQ R: ?B'5Mva%_!\Xd[d*c I ^JTifhDn #-hg3){L|L/jHg*G@"A? fi)зV&JX&JqPBLeȳ*?d\c) |ecS>72t<ϗkCX PƅoȰ$[T x }!ߌ3_Fi7䱱Y)d,M7D} JUimˉJM Z]Gϫ_3\~Ґ^A]9tDGDK~Y\ !IYCm`6]H!b,.gJ>[w|Ɠ0iVC.wt :D~ЭջZDƶ !mtsK! I3fqλ ;As^WfhYRf]O:@΋P\-1+)Xca-W8JbI OBge[ʼneo)B@;"i?'qAz?!.+T{5 fx,JmjsFGa& +Pu;ǠCa˨jo* J=lq+6ݣ4к9E / LJgx4AK i_pku$FYgQG<ꘇR6ܤլ2L@:)NV̚7ui~g#6m[T`NlyN>a1ߥ) Eş;j+k9vgz^=|Ctoѵ>JnݣFB+Ö`ҰE-oq[` IN񖫺he<-l[.j^eBw=Bw[ŎX lxsܜԟz˝}!bp%]|t,\6'_N>jZ_O\t("⽍3Cw ^j kTз9?eTcfh1XƷoƗkd߀9o^k^A˰:?wgq/:v6_,i0?+-0 Z<ruN[Lj{p`e@!@^_  hMrWL}WH<5Owͥ endstream endobj 498 0 obj << /Type /ObjStm /N 100 /First 885 /Length 2269 /Filter /FlateDecode >> stream xZˎWplؼO`( A EBc4 Ϲշ@jRY Ȫa^':{iEb2ƣjQn3>&Ň9KY;b`BxeR<2 τiZ љTPDo=aV.a/N ,@PcX1cd,1 QX4śY0 Npa_MvNR0Qt,KȮ3 !>Lϣ3&Otl;×6:=ºMYbf*ϰ~Љ{ѮԎ*[Xrːax 7|'& "1A(i3 mxjTb{ʡ?\̡@38T'6$Ŀ:*(݂C -w1 6RtNPA#Y Ъ1xYS >6ɱ qJ,1usC G&0d/@Qh5@5%=zW+kI׿wUadt͛Z?/cg!a&2PX80}p_=.gyganߖ?>޾{uxX/_!¢Iq+a +yzӲۂmݓW77CF0U$tk !T&$%YQ\w0ؓRuڧu¾ y`N{BW"v>B .$O?'i?ß T='(G\#!}\r:.ﻻ7ɻ72LH *ckU%rpʱT#j0Ӿ`s\7g+C>N(N˸HF3мnp,bZg땃v6`nQ_Y 85y>H?Ŋ9ȑRaǖl%[ֲl{#ijijijijijijijijijijKGul'^Ox=z'^Ox#Fe)`Y Deulo$Hx3fě7o&Lx3R<)?;h9[Vl=۞6((((2eqJ NGGljljljljljǶf*D2+C$6+a}4 VYeb`&ei "mĀr`Ͱ0.sJBj7ކ)`9p4.!0 q PW6+8 ]r~}6 yX/apgI؊ u/#-D߷UGx8LĎ7NbDPhFXP8VqO{rlEf":l^Wm4k邬9j#(oXS&R*0OTN@qr?:8D"TBPyօʗH즵ml$3oR8 ǡ,8(&Ail! X5F pH_O!NTlhPpX!N$hF 9 2qqd;х $OesЖy)Cp>Sج@QT4"Z%c}]~I["饊f_Mp8ds5bU;m!NO[$mAqo %8nJxEm0v$FͶه7s:oEYw}B!F>E8&t$A ͂-Γiۥ> stream xڽUMK@W챂xۢRjk Iz7&v-C͛yofQpȀT q E >y,4LcPX/඄&9iu@HUyY^2yʫ$J6$*:=9 `JȘ-HԲ^cNkARWu.(oM=0B4D'i/&z,^xe/+vTT.E{jܚE|;k3 7? }0yuwڍvn'2ΒI|JȾNqj}ݸ]7v׭R_vS-ix*r28{mw7ۄ$RtJ=Ou endstream endobj 644 0 obj << /Length 113 /Filter /FlateDecode >> stream x332V0PP06S02U01SH1*24 (Bes< ͸=\ %E\N \. ц \.  33qzrrJi` endstream endobj 658 0 obj << /Length1 2932 /Length2 21315 /Length3 0 /Length 22783 /Filter /FlateDecode >> stream xڜzP]k&׃;ww;ݝ$4;ݝ`sntϼ7SST-*j"f& I{WFV&>-m p::VNDJJu+W[gH rvr^tKā`7u7@`rqXXyeP2lj@gG"+G)-ؑP:ZAV s1rvqځl|Z2:2oYY߳zق-+׿[sǃ̍LA. 3&#0 r1@ dr `$t@ffgX:13gŜL n`fe 0YX#2J ̑`2'V:[yXXXX,dnosEpsbbm,* a0rs8Yx< /R,e"o9x -C):{}j,,X14=9kt{zG_69=0/.{fI7[L!ϟ3?Bhge]R O] ?Uf%boaEdljj 0ں)[+{_/JJpN/?HٛY[8@gg" x89>+p$Optsw-0%'0Ff߈,%F,f߈,#vo.F 8oή7gWT#p>߈kF욿8oήx;h~)G/)x@V.6[&ti7bekMoοচ8Mm@{7\`#NptS[͉/o,F)A# \w`2a\(` s+?vpslb; Xo'O0wߕdXfn"]k~"-;'8=xW7䯋Jv9& ++PjpG3~` 0)7X߅@.x/G`;,'4տ'Y70ibG0EfWKgnn'wLEz387 =l >|_V".9Zׇv׊x0q_I_w`-%N:I6j&>m J楁2퐖zK.mHxYezx0[c}W!0_A.;"(@d|aV"{ ^ S$[1/TR Ɋ@QJ;=h^:I6lǏ |pe>egar KOKˆˤZUtti ->j9j3ͷpUF@aղ(p_|ލe/d>%qRLqGݠl>piDTa/}k&.CD@dn{ QMu=6Qj'۶dLn*1U+-*eij]]afr^f9C_FޫZTx:F^4a=h0af>oV 6z ;:%:n~ VDb~j>$4^s\/R-%YI۲J0;Qw E[@DZ{7 : ld\䠵M)J=`]pˡa\[G]&u.JgV"U99pR\}όӌf%QK1Fc_5$Pkbofp0u=/jҔÓ=}3fItg: R|3fnqv[G"%i۝N#O.]CMc%锒ܼwEep $+YuøTEr+~  P!ש3hLY-{gs {~SgGc@AnF}5p*} ub-Sf+s[:ߝ>luWPms6p igCНWR 9I4qkau6` =hA:y\wEH[Dc&X$k>sdf/e S_wޜP[ߠகBu_)U ,/}QA x NT#tW<| #5C p-e{cX+\\ {?V]Fb~]ycwuA&L d3yv"/oS\yuI[tB@UHa\%*g,)*KjߋF;"u]&3kq bG\.k9Z W6ǔXv/W1~9=a1.գwP;UVXиD4᠁MёSB .h%xrC03)&S/oLZADu5V1u/52%-+vU믏K\d0J ZILRBh<u!l'o'EnXj{;;5,X,_T2A^)X#bZ@l5̿3+glʻ 3~[x)mEYc=,^Nk,ORmKuwaG'n^"Xm x|mIKdC-77_{>z'B8=}vJgcw>JO aB,AƑ-ڴ/UOrM¦㚰"S,ja(cEDWȔ~Y.UoZay D k soqWK9ߜ\y uAMN-^m0UG{VpPșSbmK"sCLq-p5G"Nz=&gCRx~>o/1cC;|d=05Xp%@[Cf_*;j 'O4^wa=e# UIf}ȖjNR؎dP,B9ٗ^XAC>$)"rLf6ƅ̔br Wcl@qhGY!^s_aFk2&i/7k ~m>kxq/פopsvm| H:~Fj tt2$LI ('ȫ`fSsK!+C_5dXn|0Ӗh$3&|#W_nHu%6=YUGPgEybD_-0JQȰ͜j`٤8:Vb'Xy=MH̤87':vLlJ'iǕ_վOU6QV?뙜 XAVRMʍc׼{{†I4ПaBrH =ia2ђmCb%o^,js\d-jxNJ-bGmAKuCdEN&E%u]-9|l,sW1ѕ#7+xJVq(ߐȚ} 5kM^cG5եT83 T!o(⡬׹h ?$u8:u/vݷ(n(p}-`m48]bc@[Dn$ߴޯ1y=jS&o*΄qY*6~DXE9(le?UiKGaK|V;O_>UlqxB_`] c$t bP4GJɾHF0;ݯ*>~xs|W`,5i: l70XfTxjvX'wŗ>їDC/ 2 ؂|i&C-F^ݖi(+y^=핰J3zqEMo%071HTFD<$ZXȠp/Lmb|P88n?"Ќ3CJ>X>HF'| eW̆ܥt*y>(@E</z3%פc4aD H;FysY$ZmwoJlp,,woOXy\B=$S%4GЯ |%H3UTuQgɒY&L03޺6)]6N/z<[ ԛsY歲>]yZY|oefx1aSL 9q{ }兙*]piJ5~*?a^[-SqG8C  (mI=֮ע,AbQai(x(]k2ErM.r'P:MMyaYL++SwM4'\v+a%O/#gó.Zhw Vu.Ya4 Hjz$y!,i 3Vo^T0heP-Ɉbd$<W4Й kNd&Ƽ\[yg vZvݏtX@Y&y!CDܼ`)̥͹Ŀ:w Trqg zQfݦOʌml g0.r.oU 1Q !@@R2xNzpR-t$ƝwGޢǴc8vaӠV.1U`;{ᬚ`T%6˲ҲDӗ S޺3zBĞϴp͊qDج4V70 o?vW|{L紨g11G(gyU-5T:U"JFC>|qaw9Fzy0}2NH߄|k^J !pd%:qo/Lj9o1g0g|tBoGH3TgR~A,%OP.EIp/"x3xAЉ#5~8]5LZ*+rE_E~0ۉ?BU.4z~z= ,%~F©t]g J+ώ4Vޘ⫚gQq̳p] mѾEZN#di6/~!=AI=oLى1j[-lz)}Bu]T<Ǡ_gGp E`@ R[ֶgL5@^apR Vu/'rC&t_oX9r8 R^jTUD]DQ/V5VgBi5N31lr %tp>LK~8zt"Fu#8'ᑚk긞|F ~N7 Z?V3+ȆZ=4W.}?MH@M@:3 d(l[rA8$Y3|5o;E5#?b<<4%%\6H{؊9(5PURҸf*OCH Vv:۫[wCà>0aE=d,Tv_@P۔ %I^+vaLxU,jQ1Ul[TPn}شIx#qtNK`rel~.CHaP[#rGJAC^s^o"39hpZ)sS&w =AiD˼[A_ؑmK00>ΊiZ"qZ44&eL1 pMAnOz\| Ma:ݷWCOFn%VEqC iG?XS&TN_n1F !P4@hS K==7sZ|<[U8NɎ?U#PfA5#E m[e"ypk^A(~6{r= bcF]h - Ҋ3FO":ܸlb[R'tχb+n3DNVA??>Bynߨ{D Otșf)ޓuSiWRנ' XlPL{h.o]3]ryhu֨.x\TM+V\?o2q.]"=`U&|.pOf8ɘ;LtTAE<6r*E0<@ օZXf])rNsüΚ+: ' EӲApW}=" 3 ܢѠ) 6S~,Q,'oQTc3ر 96^gī4_$thTŻocevsЬ\IVpOR  ;agŅi K5$yf>n++QތؓKoF계p1hVѻ<:j Z?SN4|&t: 4'0o3 Ѿ{e.W.hTAɵIKJ]KG' `ݩ㳅p>@Vv e; %`msI6K r:Mi?ȘCįMSVfC}%e' ].8txهV((#"hek⯉:QO[*0 цiQ\gA|S?%Ͼ)ב]!Q\ҧWp#v3̽e6; `*fȁmo 5 _&6z;V4%X'Պ)^"M\ ^=Ϟ0KpfPcu22c+:x j kہgjE"0mKc=[^RbW캆^'n\|;oouơ"".[ڌ;?!nOo1ɢcC+5T',$+h> AϡJ&kdz( B0noȍk7W+!GY|?Ś =F,ݴ<; R/ )X'>BhL΁f]WZ'rH/<N2?.SÝLOvָ)f])Ga~kD;hsq/B)Ϣ)}^,q08;mS$QLJatX0?!ly [U|jtN,ބD E#X}NYv, H6Eyyդ$E(qqS%!\Msd7r|c|U ׌|`PosAVuް_VłD;$h! mdWa5QJ.}Q{~&~lĺ~æ YX)*! QjaBk{1k7IN}QY}3<;i9r(2֩(Ps=c?$Z xjr4vvCD5E˳o<%Y]?~JTW״s-A^!Y[c.nOU@J{(Ғp\M,_ɜ:[;mS f\`z? O ./)#[X5℞DQr{\YMZN~E9g;dʧ/@"=IL#[]5.īujT$wvG$'(Ĉ Z懭wARr0dvaC kΫW^uRՅp*I @!^[C2Lh<Jk qOeLP,>qEjVva9e4`PkwyCi]\>%0o\i5uJ* By&I&r]bQCr΄/6qp-~|JqIҲ\P[ЍX}&MΨZ8!๑ݤB]8Zja=ЅmQY^]C/4|C/J؉sVNLN6 |6.{5בf{/aᬘ:~-^jw@mrb*\J ) C=]ٙ"O,ǰ?vM~J֜a'h#:M+׎G$ө򄦲4Õ LM~#C6FHwK{  b`{遹zjScb8Y pM'0Y0cϻ/Uh<@Wm*T.~g`gs"hѺGczsS+QVG f&雴}8ٔﭴ$#-$94uWIvZrg柼P5S3]L$֓egaD!,뉗@Gk5K8#֞G[Qj&M@* Tk0䕇_ Do\EʻO:s Pl{Ѹ%rׂ4ҵdpCDOgn喽Mk|yqhTA0h%,gyO1+;}[/{!$7RTVh\8/[Lzͽc螩5?%.,;81)44a"+?"$Z{ט[o|BP?姒ԯWzS=~[֖n grEko\"jQHuy;&o 2v(زNdݖ'ϙe&[ˏY Imrɿh6P!r*0ʋloʂsȨ;~Ҋ?AÆ#M16%MfH2p?<~fEiǕ%q8@lřRU ^{]?G2Q JZ/LSfm 7A|lryW8v{5kbY8Zxx;-,bǎ"9!: .nw'6[s>/)k!.4{D9] >%1ȂFOO~ 8nJq!C|Iտ:@x4^<LQ#Jb+(^S >.b%ty=K=ce`Du{LN>G}TsxtbR*~#̹.xJ=I.l_7qnW9]k?ѼٱMO*ߣ'o?f7:5G VdJzW]{˞.IGs.}ݨ3kV7zOHoזSuˀw"b&eEj)&w]O'B w?qU8O)Y%."F-¬Zˍ,@V4+I] -  ׻k\]wI>wHG5 51轉a0>c/_E~_(0mk0Lڌ  'S̓.bB73FsSבN ,XvH+QjHgJ"mQlg( ELn;4f{~%o&? UN5^Gn»nI-XL&.cqX`7/B}{aճ>tNgZG{‘[kn޲r/!iIhAh?T8G؛Ybg&Qc}u(r1砿0Gp_|9&0(v=[ ">_`P@ K1 } C /*6*x2~QlϹs2J#­O6sp/#]V!:vVj˭e~b$EG|b]**dN^Clwؽם`r)6_9ˊzơX%~-dK-=B+HqEQ/?JIӮ|b ~㍯ok)u{rOU+/2 U(He6 ;[K֏1@px#]Q;QdR`.ÞNNe[樢% On%xu'-*ݟhV@P!@o 2 av3j28 2'|a?ѽI52_19,62tyxK>ƝnvٺEytWЙ,2}?8UrF@:uD⧔.] Gr7${<[_+uWjB"Gdd#m8&3!35:#h6֍_ i3{C{X*K%g}XѮF7OV{pemu&*TlX; EP7cTƞ!)/Z(]9D`Z8 '[5 a )jyYl)7~"pϡ;Agoqy ta5g$)g6+ u7370VX̽wSL6>YB;H=qpOy@iHɼ;"In%;*NGzTIMx ;cYuHHC1l< k!T 6*M PfN4롩~?j },`jiX2H;8fu#ZGG [Ls3_|:*t"9 :/Y͋ifnv0I;AГi'F[U/8{`xx崃F"mƋ0dYZ[Cu^+:𺐎е\6W7lMp$Nf Q]tE{+Az&G [#2ҐM#ݠfu2_϶< 3zo}- J+\H}a1@)KnI~X{=ZbYa,-U%I[k+iBrIq3$ah Jhhm |%x!OOb%^$iamɬu+uKìX~S)o787.iNe;xOMT121-ȨFtѺy!B)SϿۏe5"".T IT*Q*#xվ0T}R䲔 mh.#LI5!h?^:| 9atH4g•ЏZ=ֆee2fl(rv2o\Ѿ_:L+:m~.d4I3 -8i4!8XKqܕ k_@(TYgo=~;VUb~Nei50f : dh5&M&.CقtypDdDz@C %(*ޖk4h)U: l$Kt"LD_[t7L5b*}x/OUjq 4N#6=P=.bL°J2V?٦voĨ5X QaDW0̍52;Ŷ4_ O9|)NlAOjκhX;pI_Jw\1Nl(It*8H7`Ijh9Q3=#2}mnw]k·?%?YGP3I,J<\}m9Z C887&Ŋg35rtNvDJ(cuvٓh@[aE­օ a y+q q:Lsk6[EYb@_?[I;WlUk/GT ա:>D3[_=@`t޵.` DLvgٴ 1[NbԨY?쩃82C-p>=cCHϤk)2U_yeM`r󃑘0Z=cFjE2߃*k`Ka_ eF>o:̽Y.,!AGq0aM].研&g=Y +[Z܆Z b6=mM6h~'MiϯT[,.^|'r;de &,*ǒU_fW2$ɂ|p ׅ}A(6`+fjyLf)Y6wEږ'y1|cn՟>(8i@^ZPDҔNJQve6^.N::P4ͤ iU=9g֪NԆZa@_lZkfKN84IX;25sܽ RD sWo+ЁzPdㅁL gWFK#ɣ$(!3G<> OOu2UUFlQQZY񓸏/=8lAu\s%ikP3Xn~PNkB71;v\L汞 oAUJ`fv+g&or4w T lo:{\.[N; [lZ)I<]2|d`ϥ)97@QvprQ.&yռSAf1mn/j0ЩVD=?Gc~SsBzG.O4ѿۈ㱹!O"*K|>ҔPM,#wR#h.u78Dթ4tEZ[ێ; C u)W $z/}o;"-۶Sy5'k!M{ST^8Q_ưkw݈WzVC*q`3ՌhSm_Lz|`T\k6VsHirV&)*J;}ҩ%!; r ߼j<~qߐ_l )CZ] G{ūJ,&:PSmD @$(Й~Q UIoEb)?iKN4^+ЍQ|]lQi9_E)s,L2v|?5rЕ%|^#]6"9(7f9#~B3WfCb{(l . o!xU!wb@48r+#ALhU& R&kL6k8J+_jh ژ! (KUej1Jc" θabL}{bpU$ Otޛ #gCR܄FX1AˆXj vͅ8FdN \ 9&&CGjw2\'ۏ֟j^)WJVZ VV:ͧXu_1H W] z-\lAՔ>SoVTYT*("CX*xJ5azU\~ЍOs?~"p>[ĉ,]x[!GV<ڟ7T !qYvŚ_?Y?fi*7wBy`589PQtɠ,l`3 ֫M?; JyS/ad ֮KswsЃ!0!䠄_ggvFa'*'9܍s ~ 8/Am0s(Z;aU^ Ʃ*~]sXh? Nt< uhBL(8.AP8Lo濣8ݓSa|WJrc}7yG!y7tWOG3 f(<vCT>McOS(`ƘwL/ʔ.I?r!\pf"#ZKl p)`&!R%? Me.ج͋Y.>n5T8C>o=[ШD1pFr6%V8&sJ1mͫ8{WJ#s&q-i26Sm YNY3af!i\/4DIqh"|͗U:#K`:ʴBxMce+赤\O˸}o 2 `"ģqhc7q&aJAn ?jlH:},]?lCX2Ѽ{pӘg=:hu=B>vتkϸ}c=P$,2e`(ZZJl=Qg~{ =W f٭y%O5F|^4@U{[=$=`2e3jc%YR;)ԡUo./liḨ$3Kíe*䙘N]l];&4;l/8IHy;@ iWQt,zD9!͊ F/CfsCŕfVЄ×,}#mmݦK(%܆d&A*H{REuܩ@0Gޟ,B'(fD1]$Ǡ: !=P` ! yEQ fos+gR4y`R nX'=O{w}qIl)ֹP*mEt<"JnhUvoaM=4Oqh6'*s3Iw&8uw _i7do≛ J_|4fm\H>ڨe{C4Q|EËx:"͎j{`{6)]D%뻃mF9Iɑ(.T18m9V9U Jx}r)D%ᄙ-65=J/}|Cpr8曓|xv0k$Ihrx :Y?8pU;9h'fKnHz)$+苡byiXlY$U1u+G+ 홗nApނ(sVןO&B,Ep08`7) ߤKV8fi0_e,l_5f(܌8u 7^Єi i%n}`zxBZP~ ecCR4nv_Sc1F$Aؒ=xryl%5? ans-sh<yjBNS9{i${q|ĂB?SwwۄbSw֢5v Y15bUwK݌y@XAEiH(p+F*/6Q q궇?F ')@g wKFb/ 4(q;.XPId1_:-_QKhpȷŖx*& G@kܦFnI" tT+ 4RRlrM *iKݓcޢ5s =E)BcjFbg.Cİ9}]X6^C*X ;H:5QON:mZYhYsۖl~~0Y|QuyT7 =i(cH_-3פA>\>4d{ ݡ2TS{gӟea8M4QPm Sj75ِ=<ǡ&_3tCs=/k_k{ =kn7Eq,b|N$3`5kl% .˺Hl|BHYm]g33*Y!i3  mc%iҙdf7~EJh#<zLuQl:cbPdCaR#dlQ\0 ҒjHII= qXW_h+ԣ>iωY3Tːf$s5ͫo$=ɹLvqjvCO3$xoz.ۻ^}ܪ6Ivz y W&H"xl.`DE:耱=zDpU d}̳k)5S0O"UЧb@viD+F}0vS!~]|B_aA\ha+VV*]&T2­ȶU*yf68]M5:oqnVx MU9_D]3aArJv'TwmҠwҋઐXyYX"K?M䧯+FnFھxt]vl4l䩷6 鸹2D_qB^ . A<{y찆C endstream endobj 660 0 obj << /Length1 1144 /Length2 1528 /Length3 0 /Length 2250 /Filter /FlateDecode >> stream xuSyQa"AXHx\dDg"B+1+|&WY#]AĆ#t rt&TA>Z4s:¢gBvP#X4L,SB ]3i̜!>@͝[q?,fδ6Ptw'alPXp+c62@gH4Lx`Ѹp;џb B;E`B !@5|SGa5 V ku^(o>H0fn_T06x)"o1WB;Blľ  îWALd3Ep?5wO-47˝dq\xӽsiiWsYw! 10uL 2)5,fμ87 `px.1"`P @7C0sN0aB0 Q̯4xf.=eςAp+P/AIg'ϐc0nYXm,Zn+t^fD6r)m`9o9L{c" j湥i0=gCT~Ф5EkcϝWFWO;T&#񺓛Qz|%1͏(u#%[҅S.x^Ѡ[ꨂJvU}E*&6޼d(۴dzt̬]ӣ뫻5S^ّX}Dkm60dx0t~zli^Kɚv󶞆{k'֩#%ILf=?x$6wjVurhu(237k<]iu4Mтָ'" ^&?S^PZo#fn=q-ޞ'IS 6Ɖg'v5+:+E-%F#/7삯O$1w_H\W8PAݓҨ@BT9>2hZJ?U7[qf*L&\꺪#oXl-Aih\Fѹw)}ʭDءx5{b 2+: M%w:~uxe[ؤ=j*/ާ z:V]q[e"Y)sa@&YDtd[~Lwp[:eMY1uX|ƹڪ~9qluL,a$+o[{$mr>[4|x~p7>Qi\XZT< 0\8e@<2}llDUޭ\Q=D-)p#1ve9k|U\3)J)}AؾގWuЉ<گ4kli3[}!FW7=81&A[%E R9etI犓%?Hd)g֍{}:drވ>~s@ҞhReQ? {#nq69WxKKԇn7r겜p=*VmI.xu$ #c|?M>ՙe:Y`{Yt2C eͺiۍ{6i8U捞5 K֭^]%+ ڍ#VE\~E"Pk~%lLs+ęyoj UVHF`iͶ8QO 6kKZ$M sSC] ąhv~B1Ja:`:>LcKRa-4&w([nR(UK}5*a㧬'R4>o R:`4V̷(2語rnxjo \s͓T҅ اPPhy`#qRãvEjA fR[SiNuC%eNy՝թsG9޷h{cdE>!Gm,)hi|-M7Q21dՈDZêhEm 쩒\h endstream endobj 662 0 obj << /Length1 1626 /Length2 13626 /Length3 0 /Length 14470 /Filter /FlateDecode >> stream xڭveT.wwk!KN-Cp;$CpA/{9Νgk}oSTjJRe5FsGShmoh+Ϩ4|9))\& kGq4llV^^^xJ@EKOO_&S|xZ[:>>܁vN@GYv@FJQ tLf@W -`\>bLN@37/ bo vX8>zrX;ٹCn7 ' G0eGWUY\8AV&rZfn#̇db =A2̭]L>rsr?0\&.v@W׏0?Mv0X\vLl9@- G+?nNs fhϬH ߱#@ +Gm_CK) ?n Ș8> @סq\L_NjZQG;ɀL>Z"`A ?֮֞@sek_5́.v^n)_tVf_P7xf)u5 y m1 u/lQ= #* ad0s~ ^.!߁XV0X{>fae/a$5Ǥ//G{@OʢMFv&'Ǹ^/+ďPF€Ǟ/ۼU/LM|om^ 'N{týv=iB?rھB n f2Sy-H].qUhvrL{'dxN&0S䣇{?zs(MpSOHS@^.wfoPON`#nN+bLY 6d3fYWH 2/Wq=rl\ kL"zH}mAOsp2AɲW׵DZbD1@yr$x qN֛s*fGDx!uQLWK+?^J4u,NP ]6-|ǟD;m۔g䞬e3fh gzu3s3Mβq]})i8|Ɍ<9ɛ$-7˳Q#'@=Yzg`;|ǚgzFyz1F^nBWQ)5 GniϪ- pֿYAl w%`* jNYԋ?RNty{}L(l ,^A%xl'*6}ؘ׮M&*|&̀9m{ (uOR5@9Z˽YMc4W ]X-ƳV7 $Zi^DL~Akh<P&~z^8L[C 9Mu*#m\)?3.Si& okP2h@~LʧԽixA\oGԁAw8c-9( B˜.W$vkuF2>GQv.z9x`wS,hn,Jf&Ec%`~' 0]AA-ZPF.氟:w{V}cPT;0t^t~jMn==*zoA'rg)H@:=uE}|UB;)<242v ꩬ6v 3H$L 6}7WvQ|s/-6aq^Źs9I; *+Gi N#D8>4fzF )—͛^Kܸw7|x;7+JxC4[=XH[JbY{w@lmĬ0$猼ԉ'd;W#MG>&&J#κ'#IsN9~/bpS+, ^WA ٥tf sg`UpZR8,<\wfAz[~Þezi9LBZ&!H7:vVs s`P;&p1OԨ*|EA:.vxf`7ie7gA&n}h dT}P 3jP .ϝQOzQO+V_Nt'  vx"3ld1ih,zY#ryw٧kcIDd&R7%MFɩ PSRICyȋf 'D eD̸O~pt~z.5m{K#[. O$J\!(_n0d')ceۺ>W|H!_v DaWX5.ZKuſȏhF~N)ҁ&5"u?s=(.O`ԧλ!E2m,)Q>ZJ UD+4Ƃtssbܑ0Tc bTG€?lȇU~S; #]4wks \ϻq0e]} ݆u||xK[{7 5*ё-D5f_mj  =it E^ԁ0M։ٌgkLrBM ƜAlV+!=YIuVL ͈Kk_~hΆIV.Q>=)X|sKU#]\xA9[7=Ygs.-rT>M[T8kΏ G؆1#؅cw n"N jČ:ep9H~-CS-k8b-ISRJVB 'h>WA0ӑd hJф (ʢr ' e䋽Rxt v}VƯOBjaܡ9L"ΌywV+ksLL4$a nb$a}A#dhuZL7 p>hŞ7]x90@aUYA,_LK4r94`A䖣S8) l\{jyXЃHGfI( (Eݬ@cn ׾iẹm!<6Лno7,bbL\NIU_b18j^K"Q; gIp3kpW /y9n9-|`|")~GN{z%ۉcl;_1~N4څT!g[x/]+tU9Ybw m!bCz}N u)|Or$ٽ rrP :}59M #UY\’2^@f q# < aQi2W.sBk^e!KK`' # J44,s GMQ~*]f)ne<#{Zi@P:Mzh$r 6rz 4!x kyMoVeC3 B۳P.PI4sgwU-x¸ψ9Q\_CZN:syPf[Ovt^`vwOT0/%S@ TT#gƣ12K@TdJ1~[x P]&كR~L j5ܷ)aݱoV:hBړqQ3K2d*{q`|ޅs43AѢkB_W%G"< !ahAk?{ &3D]QZT<I#{7UT#`J_.2|Vܞꦷ Jiʙ!B)]@a ? -RB(.H9C=fI_jJAPR&%U$>APꮄ(ϏBpj;ên(= ܛiPhC(t&4X^g#V+4JEmEqYqhwl盧!3j抵 ҂u[^vZk- qhDL&NBr[8YZOD Z@zR6N'ejalbSAoip.=,Td9]xhRwљà˹7:Hg] 3|M`jsxenX! [g Ho{OU!NX<Ou vk6|{ç4k@Y'Z9BQRD;"dk\|}r?p-]MxM[{<>P =L-W-SKVW5ߵ-+xXe| bo4DDVGڨWty( 2Yύ<- aapQx?uD\>3tBh|["78iP,0<ůF$C|]([<| Drn[?'_iR?3"iQlP=._ŎHb~(,jțBj;–Cip81KpwYweO+ɝMcH"鱨<*.m?GRgE򼫆GO"%ؔF,hB.?0}U2%T(*9&gjsKj«" _CrRl{gNJ4bm ;[7ߌI`|`ҝ!4 P3g6[ a `KsIBc}NDtf(PUb}o@L&.RyI; Ϥ[Wi_[UK6BNH=CCھ> &3ܬ&DYϫ}|oG"9Ec'g۾$ CQEg Ӡa Փ"%,w}{4(+~U5{6:[ p4}j&/S/KJ=`Ӿ% g0r`ӜQmfJg ϊXS9| TV8g\Bĝm矾y=sUCok3>tq/VZsfUaEw뢰} xiktb(mKǪd@@\ɐ`4\;ҿI=[BqT5nR~Tb+"qƞZ+pa$͓«rį` vz,K,Ц-2ct#PiI|[QCTYqQ pMj*sk,{AyS3:jʡj;^PƦ4Y<~gyM0~&h %+.HI%ҜXpeAb%Q%ƠArC_z2} [U?"G}11­ /ǟƠobP$)&K `(R:SыBnN5ǑU(&9K/Ê^䡞':4Pƞjƿ_pP_DjO4.zvc#B]86.J~f8Z{ܢXkL[+o#NK(qM2ՉFȄ?>r3PZMd0&VB>dIbsh8,& Kەlg9!kXVTCwIkԛX2YEAz_jV] n[:TXLQH#rՋ{'< Ag>s7ŁekMyA(k!|N32*&4&A"GZDZx_So 69zӋœ"/ k$ e05tpSbQq5w"6JAjV_Ff18HGKg讒m#ZEU pW;c(L% Z?a#bfX4Ġ'Mm2=3NR3zhOOl-\2HX\|lEpaE<ly//v! eM7ڟ,߱S?3#$L> eePxcj,eZSJ|V)n&Eʡ/MӯAs!ݴS KzԖ$嬀+V|O'̀F0jOeM}H`s3~DT3_D2_=!%/;1P%R/;]F@1xOτ\9`y3b 6ЬүLMMgc×k3e~6~[`ޕeJ%Q:OF_ ~J 5^7Jc6_Mat~]>/ðZ"CU( F[2o/.:vWA%8z:Dx͜%5iM(XQ$n!TҐ`dgRڱ ҽ} VZEY# A.O٨/вE _X}@Ҋ th+ϚNRkv( OvEP"^]@?-1Shq7I$-󖂛"p~ *(" .9}D8?4XT)L\҆PBnOL~F9##j,xBrE5xH^GQgU A[Kq4F^Co85-Û&&f04A%UM^)R+aنoҭM<ѣn]8}Q!~((h% elj1[z#yo" ly!!E=L.`Vq錘 +%Fwwd;wlfjqTb[{R%%&!-w$cHŲ2z7Sܙl .\4w;r&=tL)Q9y&qeʫmi; Pc:T+)ŽP(GC7ݳx>f5ƽZ?Vd:nZngewY_ƟWp7|(?L8K]nZ쑯pVSxZw*VT#!{}'M'C;:[ q#hɠ&'G+'a)f=6܄̪(r=SD +AF^~s7^BMחHySϥ1|ܾ>83Z tR?ծUD̕Ǥm5"Mz(t8Emt>tbFJ!|]\2I q c0YխCBIx>Y; |8&-$afw@!; MZ᫳a,saTlbj\ +~_Ja˲"C=;},d/-]O>>D0/NeC9r`$o55%EQt>9fvi_K\ۊ!Y1xe\Br*SU]AoQ®v{[>W1V7 &}Rݑ~6 aiT+j>B w srvyTDNj* bRa%^7SBT[w [KNR:ʾ-,1=q:c/ׄ rLiLf4iHvgՀ;7j9Ɨ`,n?'nXrV6׵]rmB^!NE@WtT-&>YV#/r3doՍM$( #fa;"S^{ő:xM;r=eiX;c)Dg[ ''"r1 5ew[Gn]Lhfkes} sxo[Ex)e#((e?_&t}4o/JQôxtўR:^$fy_ro֦8͸+1CŪXfZl63ȑy`脔Ipbf=mL+dkYUnƜ0o9X&A?DzvO3a9;=oysi^S (u- twrk+{%+7$58$!MWܱDFwi[X\98o{>拋p̯!_e.Hg#I? jQj4gqP9xrGF:4j%=>tFʥ?ɇacgۥbe[aZ[]hk['fH9UA-)З'dD .jaBJknCZf&>{9yYwM،]&Ua|y#nWuJ)k5P8>~ ?l7s[(kt W*1@oxHT?#qїmH]\_C\WdPtyyN+m\!Ec5(`d%2XGN:\4K/Ӗu}g@ ª6ΫrT*_ƾ+2b5]r.@;]/a_H'c敃VyT X[TI yy%D| 铫ۢD=:\jr`sSYR 14cAؽ)T] (h?)]zq& ܟ${NĐJZH<R.^oAsNKUHtGCN[3*FIꌪJܩ)}ny2*)تo5a ,[P˓daSC@Aݴ?RG~RI36:3~hZ#-|Nf*skGl&f.r0H\U&+!/qKԽ;YD&j~mRR -#$c(̼K#$aÝ]"Ŗn8ɠ'Wa}%]رL_'Lu!8Phwniز:ꠄۚeъؒRV/LtZy721U£/N:Y<;ȈIcgOw /b*Q:_*:uB+P*g&n5MoC<߯񗹫yg30Ge)Rd ̜qg={)g1C%5w6 q  .ΜkQv('jBK+F9$Q(!y+ڱ0mC Hy!ltE[=BmπڈJ+%N4x `"?Fέ+Y:"5h34~k׺Rӂ^j"zԯ[W4ЪH5[{a @KKӉ~SO˚ϡZ0?nN|7rPR$[_F&,4o.y;}-CM*nM^.:}C@1n(_"wjJӦn+~T<+\ CG_i@9D<S{,uٳXebƋ5 &DIu)Q5i. ﷕ ޽ Wٚd`TӜ鳞J :x1=uHUS/x3n\$3uToFYTU0`Sޛ BG ,'w'kM8gwYXemADt]zJ@!GI2%;g(a'.{;~7_EČ'Dum1xx=&0mMjֶ8srAFh)ps8m#Q[hֶ@Y_)C>H$#wCE\ ?nyJ=}S@iG2!\% ̠ͱP.\}((Yܘ[iUV6")><'e9sd0o6M~sWF>4_vlc+ugNvVw'ޣUג1]zֱNsۦ81- 'NvDIfzom D)q0i[5Ip%oE8tOiG]/|? %-F"6DOW;Sg" BAnhRݎ{Fj v Q;J8 W˖vxxKa7wGEvg\@-hu]ɐHG*/H~ 4bOKg:qo a\:/yA_R܂,٤oo1Dgz[keGi.zWsnsZ<>[PueXݩ2RJ.T\ݷ:7rV0gbHOoTåko g7B[i ~AzWCӵ&c*jxokzkybq9dpmVm0Wj&Wngғ:> ňiMURjJ^ԴOrݥٽF6_{4*(7UI\B^tN71O6&(%F2;V;%RDc;gX=V^WxS)<"hd"暑n 7F2sE i{O\^–W KqI$ͣ1G%nW07ڐ/[Tmhe:5q)gR*Z<ֳdWKX7^p5% ]d+. Ho3dQ,"f??X7y4&4{[3ACV*EporL~ bcR?1UF^=D;]aw<ޣZosuvƊ=#ۂmt̲}7 {RjMOw1ߟ5>O>zΟ_B{s-unKYn{rjf!ዷr'hL\AHjЧt ⧉_*쎟P0C.-Q zv,<,Nς1LvfI`8 ˄p5EMc2\oЏwt>\7)Ѣ> stream xڬctem&vvTl6+m۶QTlWl6z޷O}~1=qM\{Ȉ Mlr6.NJv6rv2tJ&f.rV22aGg ;[g.1@`!{8Z;(UԩhhhS ?4=,l_\MmLlB_;*M&ayMI9q*@bhma02u29}[S_,A'⯛?*ZwoF.$WnjZSsrv2rw "< dW 3kilgOIu6u8;`ldom7_0{GdakM M;Y'_v9X8;X02i7-̏fEo\M fovcSrvC(X#[#r\_\ lw 13?c`ca&N&l-fagIX`j`g8Z[ؚ_m120?$[ebk_+K׿*-@Y2T;*s?0BBv/:F67!N&M1YnU?<Q[#;FGO?j#Gǿ$k?{w#%;#` :̼I^F_*Ņ5v=~;??jC蛦=?G{1)zRM |H 7;i8W^bcP;ܝTT+dv~'q-G#}G5JkCBjB+:;'O:y~;ɍ&6M9#JvhTݪ^BHʘqL`- d'v TGK8.<"Wߵ$y¶vǕnk{$NR̺F) 1`,;RO&ʇ%P?V+PC T>Ps@7kJx iJ}T˿ǃل!T1eY57 ɟMj ; YbӦ+Z2>EGww(k <ϙ&](aMK2ihX|_Oڡ&ZJԬHdn,5 +jA8|{|P3S wViKA Hʮ;HrF~}9>kb|~^5:o`f`L?%:3ņVF5`*S|p\Ud'LdԣizōI*5$JdrDYmlBCԐ\݃ -H"/ĨJX{ rk`mOtկ"W,N,тwqf|}4|H ߻ }|cr2!:m"Gaw{y+Z rTzR:tܜvƌ~[+f[A"ugSϽ9jZ(U DX Y _:|95j0K>~##V<{:%PcyNSUYngرNU&U32qlt| Žg5OS:13o4dEXbD1ֱҰZ'fh덇`Ȕd?y{H ʬaadAI7G2dϼ^~۸!̓$}* s!Xn;$3f.;[%^@qB2_ȡG9/s, - FW*f;q8WM"zדkDP3L >W\ת2ű{dzyYi\b2>|Ľ0xP@B !( `xӡ1AWQ,ش$ T!~?ΎHr;?}WW-]DU/\쒋0Ɂ'}k$}%e[44æWuGVA0<[Go*m ljb^W9lU9Vj=@16?QK}Gmqgވj9?1<80AH扳 ydө'z#R``Xo}~ʴa/ w" _-tTf>&q}| TI ^FY40ghy|( y:ܮUcl~1bN"F! y0E6V >n5_ y QD3326?מđJ&(>1).qjT'l: ,ʔ$JZ̗w!u N %I tg0D8N-Xs`&/eȆ7_5I_zPY{ .JH_C5Lg; IFb/,f="_w[fw0>/幕s&Dʿ4kBf[,$[ėY]3 >:t{9B g_s灤֨Q۠;&L+oJMb6mhRg˜[>I75uoT4"+sIg ?'fÅhQ*n'l %"(e]sB?%)h6\n\:*t4Ik.^D\3;,?_1nABޝ#[ kDmɀP},%_. 7KU@i~QgEa[-O"4Q0K&*S;2>Dc,?3$6 rE f4rWjY!˰ȜLnipqB Q5 ZX\q=#%v3@Meۘ +Tg (Im|"2j?!čGKm?%Gc=0tOWx댝69s2b`~H5^N"֗>".V,U4c8uBe,h2l VZȒ/̡}zWJ?b=(@MϪ2Z͚/3`xK<xpv7 /f,R ӻg;OYu#2G6HOY~,֑Szͫ뀥 =9$ݘ{xiJB;kd̤+\oVS|k!qAK}|xO]Lоd>!ϝro$up6p5fhȧw}ka 7/#X4wg׹(Op+/˛uJԾhPR?uED9 mUM+R$7ɵ{Fq>SᛢŰѩub^Df i{@7瘱: T0\u4I FRSo K'U8` ?sv$엸Y|A㿋^7}/r8O,cLdⷭ=BR_nu$&WyCސ"XMZ,rȳDcc0 ƇCWLozD}A&( gų_4X{ y"H5Pb#ǃɣg'To1$:A(.JzCвEzA BUAfsD CAe~Yb^Y +[cCtcm0YVlӄӳ@ˏTlőɻ52MK4™͌IDMrD= ?=3X^jے *uhц#†s`sR{sǔ-Z'S 58KW[M&ٖ!*-j;%Eɂ$m.]dD|zxRp48HRI~ ܧ4Ž>dLIo|8xPEw<ﳗauy ӾL&KG⮂90H6nr(&t(g#.uho{ byʾ N2o =ro,* %r@wl,>`b2@3$+sAmQmkd-(1MA[k%smxxMB5?ve8 \h 5C甇{ҮmU"_^wiukE`$hn=Q'!-vKSC)JؙTFm`1 톹C\|MӸ37@-<1\yveZYFx$I> 鸶RHvnb{E>K&{t큨F$mH2İ 8]]v&gvs\%˃@X=%d[l ݬ`dl5E*·K.`V/S$eO*8f.;d#`yT*~(h+ޛ(\KF8NgiȘnW aრ[0c zڲ-ml"WS~_qUv 3#rRo" P͙}qiϬ%zJT?)e`| Qc(=G/'/C;^+h}p Rad$@ʈ).#ZO)*pkT'5nSCVwB;⢝vo0 gsCl%^xh}o(UՆ9Z::(ۣfAr] )uqQΔ; 020if7wF+&$?}HTp2ѻ:zM-L9̡.e035ZPCz%]Ɇ/XJ5b%"«N$hIdbh;d] mNM3*ދ(nimBT`;y֯)~fxV6 hJ)Z 0*Ax2(K)P&JA{?joG#;Pr#J~[6F~~h"دn̿4zW5/{Y #!끶npK.UY|"C*2']6)%Ё K xYl-xqd={=St7Cj0SW>\ ya./2'Bzw i$/ݲKc/JAzx!j%.'Oa` L_/oQMoX t.x6Lw=15,BAzl_3jP0ށy⮘UPĘ'ͻa9 pD$dr azqa2⧂T1dG,ҩj\n݉ BTЗ Zo n+w_hSy˶͊1g 6wb|6~%h) A=^u3-9wV`?W.; 8N*+UrԱ1ireezo\0!3O*،;C@GS$9om/\ zQcΐOX`uyO0ez}lز< K#S/bC9S_ Ux转 .|sitc&46~N3K% iN0ΰ4OΔințbg{R̨oLg&#s뻒aZM蒧.r ~eQ{=K]L.h!0BUy]h[`CĴ]λ 9R_za`UP.uTѲQӳ-<8Lr[h}ݞ_LL&Aqcܳ?DدOi m~P,LǮ:T:8YzHùt OVƧ^{<li, N l-FYCYCs4UZtFfę@st= 0>S'aeC<%jG M ]ъܕ3 Smܬ`fMB<?]lB,fm,,@4y΢fy^tT'Ja#6m_Co$<>Ns y: Twl{כΛMFBXMEo@:M|;l9,J U8 \Q򻏷Zlgl8 `(Vc8LQzO8LݸZc Z f'1~j[XJZ`2 u`((7$;T&/O| 0=mY et4U=qpD/eҼC: sL3O#.xsoSC:L?!t;w⯽xg^B%m_:v/T%w«>@ݓT XRi"{pӀd>yXr-aЏ.q}Tj36.lͬ1i.6x[菌*+5JQ$|z^M<ٟ9V8Xan׺NӹAC<*:[Gr.5brC[ɟ L]𡖫Sr}Z ,MpyQ:#kM9=☊q{Ɍ:4)#TKUd78X$w l/ܔ]B'a5 9eb] h 5bP5}}R]H49>35}-TD$e[n8 >,23:ϲsvfX{'d uzPHa?L33v3~LóQՁqݐ$N ! 7mƑ_2۩-1@ScV^?(+{%rbұj{%p\*n]-kCf3 z*afwRt5m"j_/4м*2B3Q,8.$6wd3!w.'CR~Ɓ$1XYh`@X2Y0V-'-2BS&}e Eh+Uwjۑvu)2;vB]7 UE=Y^.7&<6VaL%5ܤ~XCq)ьq0H}Vhu=>ެ7[֔:9o_.v$'Tb#nj~(%RkFPPp~Kd~ԺU n$*t qЃq=xhFhdv-Z,P؝hܵff辺 lZ;znK,i}ud֋v@*MHCq }ZH V@ń7L8|qX'}! gRB:85V%JHk;7Ow[&LPlDu/n'JvخJkwq5 o+ASkg~CXIsuPID 9BV,u-*'o7R>Jz2!x{+|vM  l"S^1bf:>7.XaFׅP\ /bĝ^ Ⱥp{Y4VxN(:z3 #I)HN<#YT#0RU 7Wf8>XcCzױ/xd 7zG*R0 $҆g Cgj ZJLW-;ȯA=%WKEެ3B8D}nSA}\[!i 'Tr|s"޹?si -EJDv.l&1= .<%oeh8)> vlHG+N4Q|/kQW ۂwaƪ [Ƌro{:('4Su^˔y)*K.wnFl<oǁ\s KZc'GHn0le"coSHޟÙDY}U"A^6#!=ļdppwd"vSW|mR9v ]5si]9ۙ20J=qnMEU* EZƋF2 zgQm,{w8$مp+cr4Ґq(ALEhZ]U'+4׎yohxu 6 v #JTbބTnuO-a#SO$udx@'iy(Ԏ]Aaie$R,Ώ]hnp+5$ &MrAH4S+ZLaPRY ,,b0Y0 2>_ l;u> )k&RIa Lz_WWMo)HLH U =C.0+e@cCy$.Q?+u?kf%A^RVbwřuVf4/;CՌp5b6%t!}e @Ffw:W* )yUޱFӥA|m]R5Ģ/(Pc{ !Z"$*BڅhnfJ1="FnQy~D/[9ό&fA}+^-2j /p @a ײ/Ph0L"y%Y - Fy͢UtG/UAmM'oZbB)VQG;ˌ{0#bߥOO7%M5,צ%xK %/yR"MUp/5Ҟq-LT9}_R1|Er$/e(/f` xaÆAմ\6 :[T^FS ,ƓDѸ i ]1jb:#*tLUq|r{V]D;[$Lc__HN@ z(^5;xQ/2nh kަFoJ;7Rn+y }8< ;[4H;^ssd?l8LJisQ0"e/-tvM;-˃%z4kV-vˠ>PcTi#ʃBa/[x '6+BϡIMtؗ/eL- ojtKk D P 0̪HPHlEuӈ,:&8Lu㉑ l%=i*$]fx `'z1~ż~?p:R{+G8p1wY( ~7{rܷ Pg_ȎeYorxu>^辱K/jtEG\Jq)%QCiU9ؠΆRfr!yu[@bckG|vQvϤX$k+n: NyްQֽ84%{SD`e慃?<k6\CN}^Dtan&/wr`X@OϲM.nt+YmJ/l:UΤ Fpϥ} Fz2 [ /c %Z7SMb3Fڎ ߉gb+_ _8yfPr+pT7_EhMRyhd@j${ܨA+824荒B~+`% $pV+RmJ- >TN"G7>Q, jޢT(;4uO3PyL &ISZRgY,ZeR*mfS%+ CS3zA a/%UfWP& #gX_n%]IS+.P^?~|+, X(^J.BUo ?L,$<=Ϻ8O9}ڷ9$T_h+P0HÁ:{(WJJϐKi_o8(cl9&qr›5tA? {h}mgퟔ{A{y\g8?bLBji/O> S#:X7pZ=U";su h/nٽۨy^wFg L }MQSmm"SC թy>s9ъdĄLCi bLY ŝŽ _EO|j]F8yGhNvM;8ȫ[:E9U۔$ZW#uFX6b7 V>N6LdJ|=#T 0Y3y@LØ56;Ab +^޺EZzyҎKjhfăj5d̙A @e6 )%iDz0\ho3ͺ/:k`Z<~xE0A)FHzZY׶T%).~%#Di/t?ZknX2(ظg 6?c3^! 52#ӕfArC:=WdC߰ܗ`cdPm14U@K ] -Fx6~i= /<Ɲ!5lLn'nd`dbTj|g(c8]Raw,:|1nn3X7J^1.Ec-Q5?upJsbbŴ73 ]"rfa,WjɮcKx2hְ@2=4wB&]}C[)fm͑r8܀ι6BWzhf(|x,n&qqTq4wZL(|, J]5ǼbdO| ӌ{=Wfߐ~9UJ7&X6NCc4yCڒ(v0!44_z$SgA4O B*k1ۥqSD~sZQrjcf8M=(6n7B~~ۇΓ<(\8:0Twle(~"mCA t[pϯD:Q+?]FK_uf sQH[B'F ܜu0K@')$TVhȺ Om=x-l;/&-sxzZ+ZǵMI.{_'"f ?x[NϪlpN$]4<[5siqVpX)SHqx"A\ hWzy Qc,&>w& 6۬W[X($`ɽX֫Qֲӆw ibyR0Z'0t$N,~.{ޫl z'&o%b;3|oZ2I hF|gԄa;-Dz. [ FPSEQ;C\T)@q \z;ꌇR?(^հR*H:A1hNˬg茝 oR:XBJYx˪`9iRډ% bE6ꢔmVlÓq}K @v7}\Is -^z,"<3R\$Sh MYnMo?wT|=tְz8qšH.8w" 2"E{rjl9wQ5Ys}TAo/Ev{]ҫhZl1f/?Z](W2M{sPrκ7N^V^m07FuH=?& cVdUH2 'THP ʹJ+GCF4BY䒸^L|\R LΛGkC0@Ӑfxw|vN0,߬ Z)WW5.}m7r JTTl o]k^:'#JSjZ$r)W0!jf ؁ h07e1JPiݚxQnHĘ $ Qu䛼Ɍނ}x`hrklnqd-_WxAxϯkO !xW/w=ɫK+1N)e/as 0.A"{6"z[ȭFx$g%Pd=:b؛HMӔ'.l>1 `J,"^9mQg-c7OKR+c8r{znJ-@ZW:/MSGXgۣ?r'H"<#q6њi?Jȑ%g-v^Q啶cXvcC\]Dk#GA,,/)%J,DC LQF:/!][b\Cn}ڰ*mp;D\vט-g;NynBX'Y&H[gaCOGRfDT:Tэ0Wh80f bQZq yWhYN%+Ӽe̤'_Lpdl+AB_R\.e/Ⱦuύ6͗L%5`)an7LT3Mr5r1%wQtݾh$-ȣ#i@ɤZQ\Z erL OܼEg}.$l̛&)fW~ƚԕ:ioqEᶥ4QU|Aā;:foS@ )ĖS*Xv  %Wt3/eT8645q GywKdC|6Ua-5I6 X+%:N_+aZ$kɟ).A-o8ñL|ٷ.cOypP+@h9o Zff:K:HaUû[9d8cN F@#hTr)lNX."OW$Ê nMe3aٚV|X+n+ Qiew x챺7受!Knbij)\bp=d tK]c ѻYgɃ 1zRp70^mˮ-T%> ,J&V#E9 endstream endobj 666 0 obj << /Length1 1644 /Length2 10356 /Length3 0 /Length 11194 /Filter /FlateDecode >> stream xڭweX\ۖ-] wwV;Twww@pHNp#t?kʘ2暻6-&,!B,]5Nʬ`kwVlqr6w t 4DH99{@m ,1Xxb{};9;^!ώ`0 ؃Rj @9P v-!e%rr}X:9 Jse{Œp\W7% vq> ksG9 ? ʭJU jqvFU;O7s?]!jի%OI^a^nGWO, 0qu7~ + wW?3`]@`WWW?gR_NY#+ފ 5klk# YQprpr-;W k 'G{oltr{ `#@ +Gu;;d{ h]Wk]/` nmp~UGCoUA,mV}KCZ+'ǿl v[vkUPZ/YVMa3Eu,ܴO%z_Sϳ ` O#h3Hn掠ky^`KE'K0۬lii~Np&:-jpOB O{L}"RjƁbot]!&oOt|Ͽ*oqoOk="}vA:DQKs`٘׍ . H sA"29A@1eU3kB^nVâ;ug)7.EYdjWI( ŤԬEeBYv˂ ͱrY%X: _s "A::"<heDc&ҶKMɑDzj>柨@`Y9{\{!.otwxQɓ &[3dՌm͗xDzO]Z{H,oBq ~f3=lV*Fn՗=PBMI78yBjQ?b{hUM)÷&L 9ߡ.ʘ|c>0Ҁ8}mnaX2%4j-qIXT~YGz I\KG뼋ᑻz|)̽7@ssSBZFMݸen4֌hz"IWƍrXV7NXɏVD]7(X/]QaU+X[J *x)KD > 4 +QGןޤ;qv5ulIx_&Y2#P/1x:P$(Z O=4.8R7EҾ/=rp9+Q }>?DH qHXITczsFuVC2'͒<'ޙZ.mN~>Or'-d3Ќ$xk90Ѷ,sD˱s ̼Y+Yݏђ|W8Ƞ0CNR)~>OIhQ*^S[搥bk΍T;im7Zd5g(? VBPtRQ+qBͥ(DŽ91gfXBy*2Ή0_6BnAǣyzrdo?.z ? 6Y_%_]`v7aFT`e~Ȭ,c6_ n NZ*tIE :SCJɢ /xNԚ !e2[sG nU\]|xcA#L]DX?~( RSQ]Mc>=YTR%ܣ pOXoX `4ɯuC8|^LM֎&L;i\j:_?o)13b;(H Eʹp3UYGmyw;' g k)/k1M#!'"m=wI} 72}cQ)1D_x ^XZfom#g榙9$=D!+|&sAƣOpG*!ԁ1= h|h߉CTJ (^;{c͹ilG~xsttKױU[oB)w!Vͫ&s4.=52bV!?zȩ~4Z <1UHmG,.65e8 2I,&@vxp8n}ILÔL/WV?cL̅܀/L?:^mXf#њtڰ",e~6WP;/<1XȩaR>AMāٕ6ƀr̉VN>Z}!ӒP֦(Y,lw@Z4fo+{7KxqC⽍>L\9$( >A|mHXuPqֻ6Gܢ8}׉Z $ TmMfxs{#0¬KWvr<|eh&&J M^']VR^!}Uc٣Mf-FAim~koܰt3ͥe}:TSM.5jD%gd fؙfRba3f6ߥp{v[8U!Qn|' -q6k0xx] vP[pүV*+@y4-[.c8$ =ʼUMw"?t|x&2v.sk@__HQΧ^ێE̯L KA05u‹kOGgeeSK`'^邏2 ycA'[LZ"-}"^{X$x7gQJO4(wj\p-ub]dƘ*/?Yڏ~P,w\ Vݶ h/xXol}|UUߩkT[Q""z6CV= t=։a;rR8a|GHmKYGʤn*k&6v!lg *DkP'-u~,ՆPYi&PT`J`m@'J< ,GRI ξ՛M (_j܃ vX>#O}ghE] ѭN"ߺ8Z2uZ[ւ0[hޢ=9WAc5_ 2㓃>A gt+;yN=sbZgr2]j"+)C oKA#]-ԸN}t$5 ɜHNJ±6gݟ8=XmKfR6'E뵝- (J._/2lVc,.c 1' Y MӸ~k}G?~ :m(Ÿ+W=ƀћ)e}5aO⠣ @m"[ "UũDAX/NN;B# tZش>b֥|!AJBz6gv6K{=̪6(őZ|D6wM & uc8Y8ԵP5v΂_">ުڤ Xxd7ޟp0/Q02~uUtTAnqF$u1X(sǧB@N2X |> e ?ئ}Smi]Nv3ҊLFf,bm *qGUAb"bȮx#1J]DӼ*]#)wfeD+(RI,3ZQPR(Ѧ53 ;s O Lrkèe+dKo@ J$>{8%cH9H5E+ey'G$G3T4((˦p4dppIQ'|d1B,Lk"?)H`Ĥl Uej+IA`J:ˋ.hV")ꕬMFx/~ڥv~_ڎV8 Kl*"ʝ=xx\mU;\qjiĒo1}k^_$݊rWp4o` %t|z녋`l˄axl(+8'ɺL&ퟯexCHy%[aRr β46rU$g|Pځ-ZkpZѱ[.ySKߚ#h*@ _&~ oKeӃ'ާΉ4m`:)P;&A?]eѢj=v'VJu)ֺR58ƔX ioe@m uwJ;r(Lxdh%ĺgIƵzu'cfZޗ$K֘@OA|,TK9Rrr7>I!C 5qOF ~&i m*ec"dI Y ʾc_vW"CO`l0٦%}C>Yڙ+0JcxnߐSex;f&#mCb92[mmlnҧN!:mr 0Zmwd朸Mi0XcTz7ߛ㗸 8v^nF2xa|x٫vOWSؼs6\Bg2͌}z?YV 0%y'K] ZnZoT =UЄ8(`irڹ̺NcÂƝ F* %4b}Q|+=33NSUK,P7+)PUfG[$Z!>oY#(!$7zZg+XfC2j }^N2[ڡ.<x,AaQ .ޗSx:ڏ/BR"<]҇U%;$7*q߸%w4;CsOF;]VŢQԉSZ&cCּGESSp`XuU8=@i a:J\P('ɍ)9d# Pq۶k7CܿjN(f8=7h{>O;HƱ9FT0?KÜCUnk1=SvBcb|;A0V}jV=ctl:pba/>eoX4[Z>rn YK2(aأK4sKLro^!@ SgroNN!܋a,M.܌K^y3#%fTt!?i܏6J /E .lD0g+fhsdD''ݴ+R;iMA',/~&íLnɷ rRE2,F(Ai#vfN{k{χO%3S㡋@kS.3*'.#,[w*A?h@P!f$Mb˜BHNDbeCt|oץ߭PU"Y\2}WºaOBZ>i4UDh4j+Ba#UL?2x]!3"yT9.ct+ 'ue0U}h,)+vDSUZQz_]1IZ6c~WBfxDhO[ V1H2eI[x޹N䤏1+[aZ"+!xb?. {(*}.Fy\e5jm@x22fQPDUcRbJgO1dC'pga|ՎŞu.酮Jۉ4KE= Q1lB-0q?2t℻i1(q`kA^9mQ3\ip:-NN5F}-ɥK5}UF}s:XkW'!!(BxgzF((1/ss_FtPښ4+7Y˲ ~5<#jM \Eb$V%OQkћg~l?ΔE8hC0-p6مjqHZKL| aY!:TA#q-S5-mSKLG-5#T; 2Dob *QJxDN3f/FA7VF+Oۘ'13ZSPYA^OTvwʶhsAhA7ۯ><$ i0AБlTY"}^ ^o2ʝn%;RL<- F Iۃm$?foHԟ7;yP,k~TuVbBtRUPąxnZ4oBtڷ] cSP?j S4{Td&.^eu}۠)b)Ң6|WѲ+ype64?Yv%dwB@0tDyX^~uKEAGnH={#(Ŏ2/#kfj=mZ b7BEYL?/oǠִjݵxxdME7';7g z%F*&ʢOa]]j5ґ) )00M#~'ĴZI+Jz.+lZ;*܉s_]U[>yjoBȡ)m0w=n" w`YA~8pHO Oi [,]C ik1o R[AI=ߋ\magW& sa}I2ӔMf|tϼσkFBn']Kn.>U|ZaXog&`#/99"sZV[&' 0<+YUEqԕl v0Bxcw""e W&u.>^ϳ~/^;@ei>G`ʎh6ɳW}Xt9%΍-ZSؼ4MLʩYPTqAYChgJsQ:,Ek%'A sPhaWsKׇH/K%eY$h1>Y{np](]M ypٺ-S#f.VyD?(*@}U+F}ԝx*n|{( ťtoQ#UI'GOr)u}O4m,\($=؛I?wq4 U:P&d0[zqt)UO "InxFuPSyWB 3Xݤ#' -f"."(` (cBנb bdZ{eƪrB$3mNU^ :dLKQ'pT .${NRP5WoH 楛CO\R6!tS>_1CvD)d; _I[y5d;ς.nP6X$n~G˙Yo);tl(SwgQe{fui c0tO+sĴlQ)nT1ЍgXLp'3VL%`–|U8~hĪe;1Ll"߀;b[rmG5XY.~jđ0?buϊ,$(9#hxK( ҝC=sxJHR]-a904NQfN?ݧYԦ<-B-ۢ+ ը?QyAUG(*xڃ"|n)筊rzq7P  %& d{ ' '@YIZ p)s:E2YTO{ YLm"o$L:ɗa}#h0TXi:,(kmgN;Iv/0jm b4"i>G *na2!x)T<!¸@cp9.␂ZVe;Ax$ hŷՈâΨ؈P$G]fE/KX9."Ys~Eb 5XI ?;=a 3Lԥ$Dyg Q|yÔ}> stream xڭcx_&c{wl۶ѱc۶ձmvұ3g\}[uWUZE]QN(ngLD 1rqR㒥SH9Zblpdd"@Cg ;[QCg 7@hL\\\pd;{G 3sg: Zqy7@hmgouḰS k @DAQSJ^@)!6bdma 0:vv&DK `p[ h@G ' ';pX[S_ݿ waKhdha UQTu::/ 3ibgOKE -l@wr&Nֆs%wW.NfY-hfhb trK>[ hmJ7fp ̋v\ fo&v)ߔ;DoEyo=WjqkkyC=h mw @ϲ6tp,?6wN!dkW!:&6z--܁&SC뿗/ W F[[ۿ!nA^JYQYmw*U=쁀I]sx1s9>ƿϑ',ghfgddt ?slhkw;4[[3 LLw>b_ڨZT_cUi^B4tfq M}8 Ӛ7xCBWEAsȠW~u(poRIY`ʟĵ8! @~{wxIq A?##minW oqJ );zRU# ϭL-5F"9!`WI9Ԃ~*=BԔ"/tfd+KD*gVUCad+MRq#| F;%,AqFѣ0[1Xw4^E?a {}σyյ7@#sj‰RW;(R3au jiσ,5w?QFFMیy_=)FsC[|P濞AmVY}ԈJ$Vy4dOOɭpFKZ#QĜT7Չ5cʑ&,rG?tsq3ZZ; I#+j=2x.ʵt`>izD7MYB6PLr=̛U ̈jo8I.wyZ(3#*]͹g{'RBSpH4 gIo}q)88(DBiQAg'-ɐ2q S Y"Dhd%nsC2U<5Oʟeh _ â1`ؠ( Z?E4v-"7;Cy疧235 {߾3wo¯{M$b~?ҝn_Ȩ٣z*^%jپa'$Z:LjhDq: ֎ϮOLI{V l[3 - QnM}z- gNQ66$n_f;2]C=v0@e'+ 7*#S;Vr7dCgӑ+@n+ǢuEϩiEu!aSh>P9mL 1ξh‹W3^,g+jf1}ʌ9kc ׁW3zٜlvxيPoGB]rL@=NÇ^c/F>l*'rqF-(k b $}y 5pWwC;f/j#a+BHLeHOr誻/ӥzwנ3e_ƽq.Me,|R9)-EQ| jt[<60dn)ELC@j Vh:>f1! @"0Qhτ*b\p Tt&pIXWPmik7bY<<[7ZZTmO%τY[P,\2"I@ɱUl5[Rm~M}25,R{ɢ7Khp} FoRs)]U@xr'NKw5qߞO%s9 jqMD* {2rkHP[@ @s,?!ک|=KV{y-@^q!փ`O3_h2=flZb&%->J"70Ce.z?3EKBxC POޕ+?Y#Utv`i$Ìt取[iND2z= {X@fh ;F"sF<=SHɏYh@|OeBgRVIɓP: [˽+~| Pk˾zx }iEFf;ĕ'QPdaFcT[DA 2IXgX>1Y_J`5j}&"~zݟ s;%*qm2S~'RX~cH?:D I=>hTjj,kឹs=Vꛪ{<MQ }jtBY+g槟m*xʳx`;g쑊EJH.ҘgbL غ 20>%_$:2~=$d w (E]`x@ F׎¼ +sxM)OA 768. nZI?C,$ Ǿ go(uG2BWC('uY۞7_1Z(sJ=T-uNw3IHwа"aNQ;}EN4tfO9I,F9L;7 KA7fOxKGh+ABzțўTݠj6l7y7NY}֛Wٖ꺸lq|*]Mk[E飝8"aMl]d&O;t=~)$6.x9D{/>;j]RXY<Bkǟ?5)~TSXP!gŽTadw,}D 5; Z a򜭤!a. [gU1~Pi[{vHzr{:ʒE)6 F +d!Cj#GxEqމ{# }E]χ&#^_oԑ숌ȁSҲ!k)Ϳtzܳ5/g0tmN4-%:JȰNJYۢa#%;BKO/Ǎ $x\ܺ<@( { iGQ)Z<2|9m6ǧk&]QPDDς('ƍ6ju:T# mg"~%uD :]'ƣM<۹95+d`.!Xy}q< ǤoDxs}t:Z̻6Z(o ljf=ݚPElC+ZCL`wc~cziإxpcAtNBp:3_hI?V({/ ϊ}VpͺLT;Ej9xW&cn1?($nWI 0I6٥YE\FieJlObw/r? E%fBs$uo-klY&ػxX̱K! :> vvsopyV8DnuzdADlV8gCSz{N^x0)}{rOLZ"<:򌱃uqy[\j"D)vn k4VحO4.\|EPΩ#R]-m)@AcP8Ⱦ!|C KN2imH+ Iu\hϊ|wY ]Q.K^;D;%yϕ;֦xA+oh( f+>"v9q I];05A-1a50G# H9`!V?WNrg+#Ip[Xt[!2_A9M0cX| ?Ne#m#_1} ճX>x) o޺WmYh˜1+YCݘh؊TꜙImf؍[.c+g& Q/ n*;u-Muܲ_@ݬL B~nF *T?P@4M=ڊ|!"iKīufC#&[=/6\U_7)'Qw‡R1*~+͟Yc%e {Cf]/Ĩ;XZx|oN:ǘ[1;5ud}7:KiVFJ:a%VLɇc<cW}$os{Dj5m2wluK Đb9 2E{ZI=57dV!N@/A*^0,84ΔC ˉ%ő2qNe5J;ӵ- 3Be#ܷ番w*}HHaby,keSΡVpu'LA~;1u\쀎z7Z g7s#AjF)٘wځDMJ|L[]Ksd^nVSS(Ͷ  ,Ji2mrU"=C%pϑaX=Nԟzf?#)Tz_?ԭKחGkAgjg_S?n{Ur!CG w0-ζ2 O;G sBI\){vkYE*w`K'$lE럈t)_7ܴb4i /_Mui2}E@sݱg=S jeuS`,9aY{s$AIV$zdy\*rUNY@qy_4vHo9e)mdNe(XBȌltK #8\fgm_#s#!܏SŃè>,JFlGDۗ@DmfR2-Ϯ&W3*gS0 .f5&χSDBcԝ9Sqɠ&0tTkI+8y:sy+tĀpJZwVIcż퍢EL(ů_zQun 4w]6S$ĩ t&pT#G^F'GA *cϳ{(sbMKal! OZ?^NsUj-֌UPԤE!TH~Z:u;e|K*eyrO:٭8r)֟٦7[[wht >r>.\ꏣPwNz-ȎΖcc2H`+c5dң4`8@;Mg<(>,Ǫ;BDH@@p|V#m;,|H=Chy1J8M}}܁6'm#* NIԐA*{RXq2  I}$;"N0^~}}2<!@dKM\'AaY7687v. }uR𼼪jܸ<& cOͶKFҰLOY@Bd'W;O, i#89e_k9-v)RT<001)OZN\V.{-ִm2jEr ɐ5eO]{T]|tX(t`ittGdmp&;ȾL{9:CxO-gM 5%hiHIz`E]Oh-~%kq?ZM"2k _43P8Vudl3 *jѠd^ĝO G㪚o0y"8ɸ-4:sYjC =GP EAp'Fv-H#]9aqH(opP1q9|Rk|.3v|?>F,g_c hԏpرɣ<;L]`$EI/6OvUă _LSo!' Uo³0gZl\ gǏw8HMx.z1άw8l1ckp@t쿢Fii7U?h%[Fq8)^yWZl@#X6>X1kp5nq^k*C|'.. W\l7IiaQycY<٪m?6:U˸/'hzy|xj&{Jf(RYu1 `5b]J ە}w6*lq{oFhe$)%;"fH4cL+#ϰoU];c]X~U<㗑B톴b{3$`r1i=#lx^vuFVW(E܂!B('ZvI;mMVT&}*y\K!HDS5FL3D{+/0R!YFA&ռG)srz;\Q8)WŎj`Ū(.ߖanf\3vOӜHi*݅Z^,^o;U;5(:eYF+)(0VQJ !q^'3 dXP-a@^[f( cq"_k>a"w SI9v$r=-.nj!=W?(,9B:'Ɩ!Q.dA4Fd>VUVHQ%iEh.<8m/B5ƛKO#Cp g3+Y[pOk)cQQAT' ixA t,sFJ[έo)wB4çԟp)B}X C&EJ'D̚* F"IVhSt7s ,b>Tbh޺B<)v֡ #R Tjd#T S%-jF7NAg? ÿt?*̍Wnߧ"eo I9Xk:s<(}g4PBǨng1Z-[.VUP^ӫR" tDTdNީ=^rYghےmū.Ox׶׆K%:-L?|mɥ'Qy q /(X(_-4˻ۧђ/߼:aLDiDD& eÓ`tXT`}IX" 5~t{K/7_NԷPzJucrVQ0pDV~B"F3|>D놄D( n 3[ߓc jJ1Rke%lFP&t=`GvjCf2)GJi#tj}ieme1}e; xHC9ㄺthɉʧ 0﫮`Lj^on&єrgJ )8V1c`Q=Ԋ|Ki;c[$3ܺ%sVIc5~FAaÞ+ 0 I\f$FKy@i5A&ױG2IE{~2|D_2VnjMoFtqmx];C+xG(-^ڍ)ă{fPmp\o\8򸳠>nRbSkʻf (r_jMFpXTCdv y_š{s $(KVCe U% eSMr }C~1]uQ꡾_`%B`?,# #dc֫r1^0_/G٩䋞n߳E~:n͡M \co'Pu{i* /"dh'>Kj5f)?vE!%1.l~G5Uk< PT/ʥ;iODn񟬖6y8 NSZuШh'Mf[S6bӛԿ%=:*hXJw8>|W.ƣ sI-@~tLc-<6l@kgMd =ޫfFɬ2 V{pd4ɫTO(|G)H1YꢄqP=|4I FPn*v51tB[y[;K)Fo_}L^##h\/EOPB'0(fܰ#> khg oi*\[tü!#{$|{`"M u뛏$\jO* T^(k+!<=:KwxIOM믢Z=A!TҎůHVJƅkhcTMpqaCZ+Ս`=[/MѶ7.)zG:PzlluaM]#7cjç r-gϞEGazŔ>ߋ0egsDwDp=Wd jJ䥎%jhP4ј=eG\&lC ~b\'锪?Q}vma¿4ӹiؽhԲ9ZXLIbdG:Sv/r67}#vDQQLI+XzW/@󵒛"U&Dd!f1ץgfaR$#֕ieef3>%|AIMASj39\O7L`U Z.pN#너5(d5vTj-aAJq}X$uQGdK;5۬\MȹhVLf7pb؏y09io&ZT^RL>k"6_khzZ! ;:ϴde΢8jKT.D ETZD'VJ>[Êzo!K.UJzNC i:{G;98Վ?aע*?b񔗆CA.}vjJ-Ӣ-n^H83̾^߉O%5$w,іqp ^:12?´zpjSpI*wL+r*߉@!οj 6}tcW P_:L_2OqrwK;6O4:2vBr* |KP2R)P3ېU5w0j*Le"N2>PJwu`~ap❂]LPAkw ^&N9Y M-zdR%`y?{fT3x>z6b*'1팂3(.cUH9a+<yxcykYKTD^BsRӨ endstream endobj 670 0 obj << /Length 665 /Filter /FlateDecode >> stream xmTMk0WhFG*! miʲVZCcYy#9햅ļ{3񸟤e&Oo]&C]]Mq>zwt߉Ǯ)n.pCx?nڽVgx=itO"i [\l\WM}'ԭ̚t4pXeȉeU oq yM\-CnCW_Ey}wP dZz891euB)] W-\v\]~[S!8&+Zce"'2Ɍ5I@|"B2AQhSlLء28a}ɑFq5ҍnnbfǮCG= Wܢe$g;A,:sx l=NOTƘ$0_س/vЧQ%~Zx pX2]$^qnaK??q FqMyc0=) &l(mi,3|d &\c ]͹&ӈ9w{d-tx\ \cΜekqLJs?<@>qhx .׷8wl~1V<*m"mmDa endstream endobj 671 0 obj << /Length 664 /Filter /FlateDecode >> stream xmTMo0WxvB+8l[jWHL7RI;onDo3ތ?n~<&Y$ŝK_IsE77E[^N\5sߖ;7|[lzmS_*7F?h3΃;mc-bB`ew\_7oK׽;(2Z.ETz}ܟ~o9V^MVK7-\f\S}[S!pcSs|TXo1/ȡ aeuC> stream xmTMo0WxvB+8l[+ML7RI;onDo3ތ?n~<&YվI|/ŋ;t硋nn\3<:Wj\=?-wn6pGۦ|Tnʽgxté7~qzxKlqrnX7UޞMjuSAxHiQ,'wͱ 1}hW7q{UEݥ-rG*F>NNL7u]tNhWS;wE )b,#TTHy=)9>*QKr7P:MȡQ^s$LD6aȑ*s.$S56`>ƄmÁ#TL 5kd}WXssc*zRh/#? bE$L|ږ8^y>eSQc̯bV̯cNa'_OAJ195kd3EH@8ܰ%~As*=F 0`{RLPh33Y$LƹǬ oqMsȼ tx\ \cΜ-eksL ?"@>qhx ׷=l~1֍>*]!MBa endstream endobj 673 0 obj << /Length 665 /Filter /FlateDecode >> stream xmTn0C6U@"mTt@;olvR3ތm~<&YվI|+œ;t羋<]3;Wj|{}[ mmᆂMv{Kt=c_~B?zxoBS6wBJ)X7UaMuSxHiQV,4$O;nC-bD/OCnC_n^ѻs׽9X2Z.ET~{~ʶrn_~߼h!R,6ew*ؔb%k e+Kӄ$a"1x*s.$S56P>Ƅm„A Fs 5577vرϾ+uaя6R:!,əCxg+ѧy*JcL|*m:fvuiWUꧏɩ\g%<Ϛ"sÖ0_:3x0kjhyIYx0aCnOg3$cx0<<v5O#ܵu7A 6*sZ ZcΜ-ܠeYksL ?"@>qh|tngk;dGGM@c endstream endobj 674 0 obj << /Length 665 /Filter /FlateDecode >> stream xmTn0C6U@"mTt@;olvR3ތm~<&YվI|+œ;t羋<]3;Wj|{}[ mmᆂMv{Kt=cߚ~B?zxoBS6wBJ)X7UaMuSxHiQV,4$O;nC-bD/OCnC_n^ѻs׽9X2Z.ET~{~ʶrn_~߼h!R,6ew*ؔb%k e+Kӄ$a"1x*s.$S56P>Ƅm„A Fs 5577vرϾ+uaя6R:!,əCxg+ѧy*JcL|*m:fvuiWUꧏɩ\g%<Ϛ"sÖ0_:3x0kjhyIYx0aCnOg3$cx0<<v5O#ܵu7A 6*sZ ZcΜ-ܠeYksL ?"@>qh|tngk;dGGMc endstream endobj 675 0 obj << /Length 799 /Filter /FlateDecode >> stream xuUn@+HɁkc{!5&Q^ үル!zya/W7/~jyld}{9}N=C'u\W;oέO*k`~?''3Ɖt3\;WS]Q?SVk ]{9FSѤoG^ 32j$WC0h޼O~wC4Sy<&>U]Rn·ÛB~,{_=ڰfhm_}4zu|sH]Wb MLD!E!B FAC\dQQ(%T<#h^QqKƊL0cF F͌a._Q mPG9'+X38)+ι7\'~5:r%%Β뤧$1$܋a %aN*Atg&W̡`92/X[B|fAlI)dKdgI$[d$[H$[hv-|9~ddK%[w-t--d ~)BO)Rd dK|ɖNK)K)++Ζ]Rd]Oz͜|x8?<ᤥNO]?p@}_:h? endstream endobj 676 0 obj << /Length 550 /Filter /FlateDecode >> stream xmSˎ0+$1$#8h@Bܰp`~ +8*=SJ]sCM&ESݮ`w z\ħmbo'ޚr028~}uHXz_z.XA_`1o"xR:bct\$7҈٘TmH@ ]W0ywznͩV+1r]oś}X 6g1ͭnm{!^ ' bނP48YhC`୤\UY=0ZĎiơ 7([4r;"A"e"qDgs"2dK$#В%#KDDNs5&]J[/G endstream endobj 630 0 obj << /Type /ObjStm /N 100 /First 910 /Length 3503 /Filter /FlateDecode >> stream x[io_-   N3l'] alOlȒM߹E#YU(D!3C{Brbd٨ fPZfU@sg>(# `RFqBRO-Xfa+z2B1=㙒2RVH:NJѢKKBˀץcZ㾓ic!#:@l=:T NifƤ1zV*i,1qC&Hf!:!B͎A᱗ =80}t߲1H)Ơl13A\a:oEFniC$ AfNUQW& l `Vڡ Ae!`aYv&s+M#lQe0MxIE`7MgEk !c(ƱM=2ICLXH2d!x` qTQgҒE/n }9m\AfT[\m@a26`o .ւfP*S mD "X먁l+6xI)>Bw@)T\q#7]6y N V',rAnD|*|J lBL'yfG6(}<ag&+D2VO͔  H>s>-,vH2A3rLplC #IT k[ %!=!XVxK1.QS98aG~J gA 5+CV$x$B]:E=/˧S fi@.7{0b]&v]>duq޺{3_ntRZQ*=U|7ǏRvϣk1M?V`/҂mƆS]^I%|-Fc/ڷOcFYIՏ#ґ)0?TsMu%|t06g2uzV% %V #QQ~uޝɼ0RI?M9EdR&#нt]kRZG#QUp~F;FjM U$Zs ~Uuje ?\klk^y2ik}BhiY?1C:JZRuY6ͻ*Vtq~]|̯U>WS1u}Hck~= >7 />O/\{VȊ-9wϻ^1{nto|hx0ZIBTv77y27W2ҐG/|Gw|wâ|'} G׃a/'-y؅68Mr_G߽_MFgy81e!M@TVOj%]tSR/aLSXی9OW:ܿ=ڦ\2/؞+{tb:/g ]N%yI#ZsM!kV`hJ$%~|<ǮDT+YR7P<*J\o*?> NUeLK>N 8eX->$IW,7$$Υֿ4e?YG5r.Wg†7^-`Y/|/^܀D#auն$:^!Yaa|)bΞ.9/&gDY1IۄВ]m)Mgǚivq7cbWK 2.ُR pi6'Mc{L6EЙѥ<@56W<.g$dfYJ1ڒ+FZ^1o!=1n8XJh0VNI++ysM0}m5"V9$_,QWLkghEwԙIygUŢzCцGE:?Xq?Et[:ֶ4]VoKl|trº*J%[p&pʽڕpmz:unr\-6!&!oW7OnW`}$kg0GBYř+E*Oge*/3*YEVe,`(X<}T}>-j,#k:4{ǔgKWcRvf l +>3S+^6*4J>SRHC}~ endstream endobj 740 0 obj << /Producer (pdfTeX-1.40.24) /Author(\376\377\000H\000a\000d\000l\000e\000y\000\040\000W\000i\000c\000k\000h\000a\000m\000;\000\040\000J\000i\000m\000\040\000H\000e\000s\000t\000e\000r\000;\000\040\000J\000e\000r\000o\000e\000n\000\040\000O\000o\000m\000s)/Title(\376\377\000x\000m\000l\0002\000:\000\040\000P\000a\000r\000s\000e\000\040\000X\000M\000L)/Subject()/Creator(LaTeX with hyperref)/Keywords() /CreationDate (D:20231204085025-06'00') /ModDate (D:20231204085025-06'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) kpathsea version 6.3.4) >> endobj 679 0 obj << /Type /ObjStm /N 90 /First 791 /Length 3207 /Filter /FlateDecode >> stream xڝoW1Ps!@/m>5y:{swDg29~ѐԮ-mC6BFn$)6JFKxht15N7V7mo'l w{.H-wqZ7& Ny8I(hJ6 kKa3%ۑlOaa|[-5,%{cY:Hal1,)v*£^i/l f5ʵa-foRцgNؙe5F{1Z8I0cc:<ChVbZ$5~ 4sC!g _Ƶ<1rnZ'ȫm<GB4^icj^n<1m y!C,\qֈ gD#6DQSs^0$kcȖ "8Ezy Z{CǐR<4 d!Y2Wx )Z6@(C /Wn>|y?^ݯa;wޝ'U|y׎؄~:^C#?}߻SϦ6 { _bEnބF ~@pz=FBK;*"/̻Gf9  z]Iϓ<~9%7N.v""̪)+NПo%OWթ$NǯW>[>Rk;Dve@O;y^p[U;N5nbx 0}7쾄H r.k,I|=8k_vd:z*Raa1vQhdֶbNmae V<UĒEZZ(<D>ї_t uam#([=Ο208xm<*O"ً(uWCc囫?/* a=AtϻØufj<z^xLQc|@o+r?b }3cW#sPmxj|kݶ*jTa9[L/PqHYBj/uGke~¡e)YNcpUȆCRG8{>bK<:E )-i%U1vbڶԋӥ:0b"*S|KۂSCRA3Dtwg໺L7F?aJZvnی+K2Bu v@Ŷп(`UJ8a[ɅtXu?DT =E]6_T3~ baGF1D[aʧdbpvJhRս(|o5j|D9_lna+O/|6>N~w-Ff/8R=YHc;[z{j:J[lDڢ"lQg a!aAZ `@bh$"&*벷W.!vˠW&d aBżAMbl fSe6DlTI„4h̗4㛧Czi#XwspEPt&~L^9U9hYEȚ.Դc{4gc7Z1k/f0*k񨵡ݮ+QUt&K5\As.ɢ9#pvд-S*A::dDWxҍ̄M"*߮+Q̕Y3HyAU0Ӳ42U HgBHAZeHLi%2UyX$t>X(t6): Wg!9fyT %Ʈ"Y?Hoi얔b:i2a)uۏb5ð 5ð5C$t@NK~L1BLj-,,Y@$J*rYL ̯۸fa]njߊккѺZnmoۺu"bZhQ`= hef Jo uE8f5KʆZI]ϘڬPf[b/fj[1f=hM&h:} КL"fʀ(3@KDa5-u[uYP2 1 mhZmV5-fUmV5-(mvfږbo%(juV;; 8acb_TlvעZ 'D&!ە٦pdJr{NjK=9[çEmr@m(U6Wwށδ^l@Vg1^R"{h{֬MYkx@2ۺbރl mI_1g Ņ\LjbYOZbax >F5B)FqA!eߤ"sfC_XnG|뛝`c+;ߎ_~ !>ʢ endstream endobj 741 0 obj << /Type /XRef /Index [0 742] /Size 742 /W [1 3 1] /Root 739 0 R /Info 740 0 R /ID [ ] /Length 1721 /Filter /FlateDecode >> stream x׹]I}޷6ޗvx D !D@Hh#li&IPADZ1I~u޻u;R AiOKio0[+69 fm[9}$Ns!Vs,{"Fs,{%Zs [9KŖ\VМbĢ?^%vXlf5bWĢ:bK5'^0br6b%2 6W[vy6.vH,^;%f`JXLn#vO>_L~H3ppk B!8,F8*Q,tbSb2bpNb*p N8 `&4.6|%% W*\pn- w.܃#x O)<1#Ob1?y%YyrU>%`.Mx·/'X{F[Qyը7kTQ[or`{*O2Jܷ+a{N?Ifh;@ o硃sp8꭪*늜VcQPUTT7fP3uNl0ߣ)PuT@ HztNjz,EAfVW \%pUVYO4xE87pRz9;YI]%uU>W\sU>\En<I]sCU>-YK H*{9a l `>,8OVNtֵ"؍tuA|kv,K4VCk!vJm_S9Y1]fOg`wN^O*묄uXc`qNDtpٜ|mb2\k+Í^'~pxO)co=,xBTٗӧo-jaZ}9?fRjXh,4+eBO/?,\epY/B\6UBӜ~%vj BmP[X-Q~5Ho&Fc#FclE34uGeSFh#ֶ)m[N_~/:PM6VAstiʴDq8Āb¸lqPM6. m6BFh#jcXm)o㷩jcڔieFm=lSe{f m6Bn1k_0 fp.̃ 7\ 6zRVSp58 N0 Ip? a:X|oS;8 Q{y| 8w_ijr% CUx:a n-_vG/wr}|ӽ+>w?Or0|3z_>aFXh(G=jq`[iMSomSq47M}\[LS)ԛ> qq1p5z馏ͫwzywr^4_ݛ>.D7Ž)gv{߆;7܇8I;`hN-]$ endstream endobj startxref 145344 %%EOF xml2/build/stage23.rdb0000644000176200001440000002162314533363460014207 0ustar liggesusers]{WH7b @B$T  6$Ax$t` InwU`Md#<:; =|=̙0u+,K$%زV_ݺUv_"LtLtw &cؑJ2M^PEe;"~xGY"D-Beł/ &']oOgKcWKk[ޛM#o]eSƫX$ծR&v%Ԓzky+}=T벢yJnM*R؞R,Xb h*;lnol-?-dz0@7jg *;E5Z@ܜN eY \+bpk8q{1'TjHW7Ɖ^n=kW׾'3hX(hǴ]+H/X,-3ɾcEɬ薮x`V7P8Ĵ] _8 gz{!j_z?OOP<Wd*r@Di] h{?t?|jOK(VEYlQ/c„ *&p\XXn"2D<@X/$[) I0rIwʆR/^Ib{Jam.n;@\f\mQ+ķ jtV ۰aLhøW a|\"6uSCQM7 h=6)>Cjʸjʸ;ަLc =!q8Ĩk=ܛ'emHë=syK7Ryy8t9vbAI020> O,6tr?MZ|~[kj":ZVHqȡpM."^F9ԫq "^A9V( #^EjU'"qX-oEm;@X*[zQШGbɠIexq 1 YtXMTjQ F͝ *~m7(9?9 ᄽBN B5 - +${Kv ?!^V#%bUj i7pD5$V]f6K4%]Z1V.bxMeM|A!E#ŤĴ󠰾Պ& M%BfA.u Es1|ȹx L=HmmSƉDX4BKW,LLOQ~9_U(#+8} ^eI2,J*G5Qo%j _5[Nr>BQ$?!^VcKxS(;DE7*,+H*+{aJx+;k3hVG>@A?f@Y=D6*JUjbf;氨XOźk\>9OhB(*H x5[ l$rЏUFMj٬})5txwUdK ^x~arboihi֟trbz>\arR*5Ģa} P zb1i3XwWh^09RE wYK n38/n-/U]ZԀZm"| 緶Z+2dYc~4qcʛՕrȗ%U%R(VL64 Lw h)_~tj{6hܻv><\!dh0L֦r,6׶VZ%*Kk\6CLvӵSS%tks8]S-ߛe; oRcWSG4ܦsyzWV_s[7V`=5o{E˫e|;?MזZޥe)2ѨuSc9k+ EE,F^gơEd^A"8M J'6VZc3\`4GXlUɐ̲kD""5(IŶnl|֡3b1ZfW9,aaQHPAMAzEk JDgĆd*EqЋvkӺMf|ky|޳c2zlӺM X[,,D;ʞuTwũl4S`ߵfvzY]Y[jy}oZ뜲BD+s0a_*{ec *2Jo[X;ddys\ug'>;#iRQ/^`_{?rar;k*9!^ͦט'ٿj[$Q7<UN#DKtB\Fy9_Fâs]eDQ}vG|ξc`|a\˦U64]a؜_;۪L]ࣔOPa(?l|3%ih5!^V)q8ZwqˣΩ]B>~rS74D 2ʗc?;aCrWPӰeiN o sGxϱ7u.QXAaڭ(" fD #.-q^Gz=$x5[X.6!&?Aؙ$@"V/.3Y 㩖 605p̲.eTXJdJq;eDaJÔuAڹdFysKrߗlmR*٘nS*WHoSՁMxE$˳yfky7`/ޙžsE^Tgs JyKu& RfI ] +sS`8j-h^a*8JM]rnd臊BVP+YƊ_7Qju Z`o*:!^K|fPaϣ|>6iT W'˕W#s&` M8sR`Vip:1Bnjף!x5۔"OQFjyl̀I4GXJ6$3hsU {zk<%i!eXV E3;[FP];ʠ c*4R;DeEJ^JfzǮAڿY<<#Cͯ::r]@Ǩ`l?2#s6igk)BOQVIiӀÙLk[X P#8;HQWOtڈ e|'x5[p1Zzc $)+bLUg]lH0vE@-N T;E8ddoܮ?II?K#̣f7PY/l-LO,R铗 svXF-@9kБ^M.b<(Yvܪz՟dUCu/|1jU3G&kR^alZdI#dĘ(X[ƙwH8%3S . Lh'y^C™"^eB.@wX*Pk_e27A*x-H^3^iUZEE(#+}H+J;_.$9SO/H"jx [1pYF/E~*wr:M7#d[oNŏ:H%.Mf;&pw=|V( ^ta^g:oI>EMK`7D.ynfo=ve-)W=_>P@z}|Н5}nJfߕurzZt4 A'>su:Ue >@Uɨϣ<%) r>/So_~{`MzX3kKCLf3zyRWn1u*̣y%S;#_ki_z_! *^OdY{b]^h}r]6Y$ϝ@ac+Ej:eUz*QЁl &#֍YVHOѿyÕ*\BHbQg)zQ;Wu>r kKU台7nX]2vpRV~^dhoyNwrӀo有{Q.]YaᅀH;*?Rެ1`yX2?@_|nK@ד}GtCN|D5L-PmY*\(g-6#Ws^ܝ骏}%YHc'YuG&u*L^L>qjk$֕qՇ2R9s&\vgq= YZ}k&,hщ7 ;I<6qbI?ΕUὥ9;;wP㏍N٧' B×nOigu[8˄y$5c=s?t;]nol- V I*9C2LgR7NdgR_NHFL:ʹY i!L{ƛZ:]2}քb)a Kmfʒ|JkiSN0r9:qF&[>cX ໝ/.#wݍ" pO/yC;"A4AC3D9T r"nAFy;bCWv6:P9+q(<$ɡH)ZQgvz,h:GUzdźk%4ػEC]P^Lq6aMjnA lV!F A'\Fԛ];!x5[KX.6Q> .cedN&jֳFlnHVj hUz_AE9  ~e 3'$C,S,vTli ؋ro|dٞ<,2$q<8A~iOin$ocfqik3'S~[)H\PkHeDsy7B蕝gI!n\̯Nk8ux;1ܥ _E<>"QCӎ]Qb>cP~F/{ը[(/G.N"8pl4lDOJ51iXjLR$^47}@ksyKю%퉆`P}JlIq0RbڧnČ)b+:Yfq7[C,B#F' ,}v,&<ʡr⟪oQ~/pW\Q^l~/qWLّ.m5&(:9+dNFUfiv]+"Y^nIzp{́5M L9qMKr +:ja"AKD9zۡ))PAȁdGvȊ}=`֨=)vF΍oә' GvC@|%Fp-, 2v%AW?E t@Ha,48rxs|ϲjQ2Q,>Qݽwo=$a'; g-Cғ͹t)vw\wgm@= ЈU,AiAl=8c +zZ䈊ީ/ߢ@qe?G?Gv$BζU@UET\+E~Ml9o>3D$Jr+bt.:N¥PC@ε0ҨI:*|=4M10t{MaaOg]C~MTIWumzս5xf K\zՄ*O;Hw?1xml2/tests/0000755000176200001440000000000014532206721012300 5ustar liggesusersxml2/tests/testthat/0000755000176200001440000000000014533377212014145 5ustar liggesusersxml2/tests/testthat/records.dtd0000644000176200001440000000024213633161317016276 0ustar liggesusers xml2/tests/testthat/test-xml_type.R0000644000176200001440000000071414531733657017117 0ustar liggesuserstest_that("xml_type() works", { x <- read_xml("

Some text.

Some other.

No bold text

") children <- xml_children(x) x <- xml_find_first(children, ".//b|.//i") expect_equal(xml_type(x[[1]]), "element") expect_equal(xml_type(x[[3]]), NA_character_) expect_equal(xml_type(x), c("element", "element", NA)) empty <- xml_children(x) expect_identical(xml_type(empty), character()) }) xml2/tests/testthat/test-xml_text.R0000644000176200001440000000401414531733657017117 0ustar liggesuserstest_that("xml_text returns only text without markup", { x <- read_xml("

This is some text. This is bold!

") expect_identical(xml_text(x), "This is some text. This is bold!") expect_identical(xml_text(xml_children(x)), "bold!") }) test_that("xml_text works properly with xml_nodeset objects", { x <- read_xml("

Some text.

Some other.

No bold text

") children <- xml_children(x) x <- xml_find_first(children, ".//b|.//i") expect_identical( xml_text(x), c("text", "other", NA) ) }) test_that("xml_text<- and xml_set_text work properly with xml_nodeset objects", { x <- read_xml("This is some text. This is some nested text.") expect_identical(xml_text(x), "This is some text. This is some nested text.") xml_text(x) <- "test" expect_identical(xml_text(x), "testThis is some nested text.") xml_set_text(x, "test2") expect_identical(xml_text(x), "test2This is some nested text.") }) test_that("xml_text trims whitespace if requested, including non-breaking spaces", { x <- read_html("

Some text €  

") expect_identical( xml_text(x), " Some text \u20ac \u00a0" ) expect_identical( xml_text(x, trim = TRUE), "Some text \u20ac" ) x2 <- read_html("

Some text €  

and more € text  ") expect_identical( xml_text(xml_find_all(x2, ".//p"), trim = TRUE), c("Some text \u20ac", "and more \u20ac text") ) }) test_that("xml_integer() returns an integer vector", { x <- read_xml("") expect_identical( xml_integer(xml_find_all(x, "//@x")), c(1L, 2L) ) }) test_that("xml_double() returns a numeric vector", { x <- read_xml("") expect_identical(xml_double(xml_find_all(x, "//@latitude")), c(42.3466456, -36.8523378)) }) xml2/tests/testthat/test-xml_url.R0000644000176200001440000000454014517773421016736 0ustar liggesuserstest_that("url_absolute", { expect_equal( url_absolute(c(".", "..", "/", "/x"), "http://hadley.nz/a/b/c/d"), c("http://hadley.nz/a/b/c/", "http://hadley.nz/a/b/", "http://hadley.nz/", "http://hadley.nz/x") ) expect_error( url_absolute(c(".", "..", "/", "/x"), c("http://hadley.nz/a/b/c/d", "http://foo.bar")), "Base URL must be length 1" ) }) test_that("url_relative", { # The behavior of libxml2 with relative paths is fragile so we skip this test skip("libxml2-dependent") expect_equal( url_relative("http://hadley.nz/a/c", "http://hadley.nz"), "/a/c" ) expect_equal( url_relative("http://hadley.nz/a/c", "http://hadley.nz/"), "a/c" ) expect_equal( url_relative("http://hadley.nz/a/c", "http://hadley.nz/a/b"), "c" ) expect_equal( url_relative("http://hadley.nz/a/c", "http://hadley.nz/a/b/"), "../c" ) expect_error( url_relative("http://hadley.nz/a/c", c("http://hadley.nz/a/b/c/d", "http://foo.bar")), "Base URL must be length 1" ) }) test_that("url_parse", { expect_equal( url_parse("http://had.co.nz/"), data.frame( scheme = "http", server = "had.co.nz", port = NA_integer_, user = "", path = "/", query = "", fragment = "", stringsAsFactors = FALSE ) ) expect_equal( url_parse("http://had.co.nz:1234/"), data.frame( scheme = "http", server = "had.co.nz", port = 1234L, user = "", path = "/", query = "", fragment = "", stringsAsFactors = FALSE ) ) expect_equal( url_parse("http://had.co.nz:1234/?a=1&b=2"), data.frame( scheme = "http", server = "had.co.nz", port = 1234L, user = "", path = "/", query = "a=1&b=2", fragment = "", stringsAsFactors = FALSE ) ) expect_equal( url_parse("http://had.co.nz:1234/?a=1&b=2#def"), data.frame( scheme = "http", server = "had.co.nz", port = 1234L, user = "", path = "/", query = "a=1&b=2", fragment = "def", stringsAsFactors = FALSE ) ) }) test_that("url_escape", { expect_error( url_escape("a b c", reserved = c("a", "b")), "`reserved` must be character vector of length 1" ) expect_equal( url_escape("a b c"), "a%20b%20c" ) expect_equal( url_escape("a b c", " "), "a b c" ) expect_equal( url_unescape("a%20b%2fc"), "a b/c" ) expect_equal( url_unescape("%C2%B5"), "\u00B5" ) }) xml2/tests/testthat/test-as_list.R0000644000176200001440000000272114517773421016711 0ustar liggesuserslist_xml <- function(x) as_list(read_xml(x)) test_that("empty elements become empty lists", { expect_equal(list_xml(""), list(x = list())) expect_equal(list_xml(""), list(x = list(y = list()))) expect_equal(list_xml(""), list(x = list(y = list(z = list())))) }) test_that("text nodes become character vectors", { expect_equal(list_xml("a"), list(x = list("a"))) expect_equal(list_xml("a"), list(x = list(y = list("a")))) }) test_that("cdata nodes become character vectors", { expect_equal(list_xml("]]>"), list(x = list(""))) }) test_that("xml attributes become R attibutes", { expect_equal(list_xml(""), list(x = structure(list(), a = "1", b = "2"))) }) test_that("xml names are preserved when attributes exist", { expect_equal( list_xml("34"), list(x = structure(list(y = list("3"), z = list("4")), a = "1", b = "2")) ) }) test_that("special attributes are escaped", { expect_equal( list_xml("34"), list(x = structure(list(y = list("3"), z = list("4")), a = "1", b = "2", .names = "esc")) ) }) test_that("attributes in child nodes", { expect_equal( list_xml("34"), list(w = structure(list(x = structure(list(y = list("3"), z = list("4")), a = "1", b = "2", .names = "esc")), aa = "0")) ) }) xml2/tests/testthat/test-xml_serialize.R0000644000176200001440000000320414531733657020122 0ustar liggesusersx <- read_xml(" 123 456 ") test_that("xml_serialize and xml_unserialize work with xml_document input", { out <- xml_unserialize(xml_serialize(x, NULL)) expect_identical(as.character(x), as.character(out)) f <- tempfile() on.exit(unlink(f)) xml_serialize(x, f) expect_identical(as.character(xml_unserialize(f)), as.character(x)) }) test_that("xml_serialize and xml_unserialize work with xml_node input", { b <- xml_find_first(x, "//b") out <- xml_unserialize(xml_serialize(b, NULL)) expect_identical(as.character(b), as.character(out)) f <- tempfile() on.exit(unlink(f)) xml_serialize(b, f) expect_identical(as.character(xml_unserialize(f)), as.character(b)) }) test_that("xml_serialize and xml_unserialize work with xml_nodeset input", { b <- xml_find_all(x, "//b") out <- xml_unserialize(xml_serialize(b, NULL)) expect_identical(as.character(b), as.character(out)) f <- tempfile() on.exit(unlink(f)) xml_serialize(b, f) expect_identical(as.character(xml_unserialize(f)), as.character(b)) }) test_that("xml_serialize and xml_unserialize work with HTML-based xml_document input", { file <- system.file("extdata", "r-project.html", package = "xml2") x <- read_html(file) out <- xml_unserialize(xml_serialize(x, NULL)) expect_identical(as.character(x), as.character(out)) f <- tempfile() on.exit(unlink(f)) xml_serialize(x, f) expect_identical(as.character(xml_unserialize(f)), as.character(x)) }) test_that("xml_unserialize throws an error if given a invalid object", { expect_error(xml_unserialize(serialize(1, NULL)), "Not a serialized xml2 object") }) xml2/tests/testthat/test-classes.R0000644000176200001440000000331314517773421016706 0ustar liggesuserstest_that("CDATA creation works", { x <- xml_new_root("root") xml_add_child(x, xml_cdata("")) expect_identical(as.character(x), "\n]]>\n") }) test_that("Comment creation works", { x <- xml_new_root("root") xml_add_child(x, xml_comment("Hello!")) expect_identical("\n\n", as.character(x, options = "")) }) test_that("xml_dtd works", { r <- xml_new_root(xml_dtd(name = "html", external_id = "-//W3C//DTD XHTML 1.0 Transitional//EN", system_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd")) expect_identical("\n\n", as.character(r)) no_name <- xml_new_root(xml_dtd(external_id = "-//W3C//DTD XHTML 1.0 Transitional//EN", system_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd")) expect_identical("\n\n", as.character(no_name)) no_name_external_id <- xml_new_root(xml_dtd(system_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd")) expect_identical("\n\n", as.character(no_name_external_id)) no_name_external_id_internal_id <- xml_new_root(xml_dtd()) expect_identical("\n\n", as.character(no_name_external_id_internal_id)) }) xml2/tests/testthat/xml0000644000176200001440000000101214517773421014666 0ustar liggesusers Wake up to WonderWidgets! Overview Why WonderWidgets are great Who buys WonderWidgets xml2/tests/testthat/ns-multiple-default.xml0000644000176200001440000000015712471405236020562 0ustar liggesusers xml2/tests/testthat/test-xml_name.R0000644000176200001440000000404414531733657017056 0ustar liggesuserstest_that("xml_name() returns the name", { x <- read_xml("

Some text.

Some other.

No bold text

") children <- xml_children(x) x <- xml_find_first(children, ".//b|.//i") expect_equal(xml_name(x[[1]]), "b") expect_equal(xml_name(x[[2]]), "i") expect_equal(xml_name(x[[3]]), NA_character_) expect_equal(xml_name(x), c("b", "i", NA_character_)) }) test_that("qualified names returned when ns given", { x <- read_xml(test_path("ns-multiple-default.xml")) ns <- xml_ns(x) bars <- xml_children(xml_children(x)) expect_equal(xml_name(bars), c("bar", "bar")) expect_equal(xml_name(bars, ns), c("d1:bar", "d2:bar")) }) test_that("error if missing ns spec", { x <- read_xml(test_path("ns-multiple-default.xml")) ns <- xml_ns(x)[1] bars <- xml_children(xml_children(x)) expect_snapshot_error(xml_name(bars, ns)) }) test_that("xml_name<- modifies the name", { x <- read_xml(test_path("ns-multiple-default.xml")) ns <- xml_ns(x) bars <- xml_children(xml_children(x)) bar <- bars[[1]] xml_name(bar) <- "foo" expect_equal(xml_name(bar), "foo") expect_equal(xml_name(bar, ns), "d1:foo") # ns is ignored xml_name(bar, ns) <- "bar" expect_equal(xml_name(bar), "bar") expect_equal(xml_name(bar, ns), "d1:bar") xml_name(bars) <- "foo" expect_equal(xml_name(bars), c("foo", "foo")) old_mss <- mss <- xml_missing() xml_name(mss) <- "foo" expect_identical(old_mss, mss) }) test_that("xml_set_name modifies the name", { x <- read_xml(test_path("ns-multiple-default.xml")) ns <- xml_ns(x) bars <- xml_children(xml_children(x)) bar <- bars[[1]] xml_set_name(bar, "foo") expect_equal(xml_name(bar), "foo") expect_equal(xml_name(bar, ns), "d1:foo") # ns is ignored xml_set_name(bar, "bar", ns) expect_equal(xml_name(bar), "bar") expect_equal(xml_name(bar, ns), "d1:bar") xml_set_name(bars, "foo") expect_equal(xml_name(bars), c("foo", "foo")) old_mss <- mss <- xml_missing() xml_set_name(mss, "foo") expect_identical(old_mss, mss) }) xml2/tests/testthat/setup.R0000644000176200001440000000011514517773421015431 0ustar liggesuserscat("This is libxml2 version", as.character(xml2:::libxml2_version()), "\n") xml2/tests/testthat/test-xml_find.R0000644000176200001440000001275314532115535017052 0ustar liggesusers# Find one --------------------------------------------------------------------- test_that("xml_find_first returns a missing object if no match", { x <- read_xml("") expect_equal(xml_find_first(x, ".//z"), xml_missing()) }) test_that("xml_find_first returns the first match if more than one match", { x <- read_xml("") y <- xml_find_first(x, ".//y") expect_s3_class(y, "xml_node") }) test_that("xml_find_first does not deduplicate identical results", { x <- read_xml("") y <- xml_find_all(x, ".//y") z <- xml_find_first(y, "..") expect_s3_class(z, "xml_nodeset") expect_equal(length(z), 2) }) # Find all --------------------------------------------------------------------- test_that("unqualified names don't look in default ns", { x <- read_xml(test_path("ns-multiple-default.xml")) expect_equal(length(xml_find_all(x, "//bar")), 0) }) test_that("qualified names matches to namespace", { x <- read_xml(test_path("ns-multiple-default.xml")) ns <- xml_ns(x) expect_equal(length(xml_find_all(x, "//d1:bar", ns)), 1) expect_equal(length(xml_find_all(x, "//d2:bar", ns)), 1) }) test_that("warning if unknown namespace", { x <- read_xml("") maybe_error( expect_warning(xml_find_all(x, "//g:bar"), "Undefined namespace prefix"), "evaluation failed" ) }) test_that("no matches returns empty nodeset", { x <- read_xml("") expect_equal(length(xml_find_all(x, "//baz")), 0) }) test_that("xml_find_all returns nodeset or list of nodesets based on flatten", { x <- read_xml("

Some text.

Some other text.

No bold here!

") y <- xml_find_all(x, ".//p") z <- xml_find_all(y, ".//b", flatten = FALSE) expect_s3_class(xml_find_all(y, ".//b"), "xml_nodeset") expect_type(z, "list") expect_s3_class(z[[1L]], "xml_nodeset") }) # Find num --------------------------------------------------------------------- test_that("xml_find_num errors with non numeric results", { x <- read_xml("") expect_snapshot_error({ xml_find_num(x, "//z") xml_find_num(x, "//y") xml_find_num(x, "1=1") xml_find_num(x, "string(5)") }) }) test_that("xml_find_num returns a numeric result", { x <- read_xml("1") expect_equal(xml_find_num(x, "1 div 0"), Inf) expect_equal(xml_find_num(x, "-1 div 0"), -Inf) expect_equal(xml_find_num(x, "0 div 0"), NaN) expect_equal(xml_find_num(x, "1 div floor(-0.1)"), -1) expect_equal(xml_find_num(x, "1 div floor(0)"), Inf) expect_equal(xml_find_num(x, "1 div floor(-0)"), -Inf) }) # Find int --------------------------------------------------------------------- test_that("xml_find_int errors with non integer results", { x <- read_xml("") expect_snapshot(error = TRUE, { xml_find_int(x, "//z") xml_find_int(x, "//y") xml_find_int(x, "number(1.1)") }) }) test_that("xml_find_int returns a integer result", { x <- read_xml("1") expect_identical(xml_find_int(x, "1 div floor(-0.1)"), -1L) expect_identical(xml_find_int(x, "number(//y)"), 1L) expect_identical(xml_find_int(x, "string-length(string('abcd'))"), 4L) }) # Find chr --------------------------------------------------------------------- test_that("xml_find_chr errors with non character results", { x <- read_xml("") expect_snapshot_error({ xml_find_chr(x, "//z") xml_find_chr(x, "//y") xml_find_chr(x, "1=1") xml_find_chr(x, "1+1") }) }) test_that("xml_find_chr returns a character result", { x <- read_xml("1") expect_equal(xml_find_chr(x, "string(5)"), "5") expect_equal(xml_find_chr(x, "string(0.5)"), "0.5") expect_equal(xml_find_chr(x, "string(-0.5)"), "-0.5") expect_equal(xml_find_chr(x, "concat(\"titi\", \"toto\")"), "tititoto") expect_equal(xml_find_chr(x, "substring(\"12345\", 2, 3)"), "234") expect_equal(xml_find_chr(x, "substring(\"12345\", 2)"), "2345") expect_equal(xml_find_chr(x, "substring(\"12345\", -4)"), "12345") }) # Find lgl --------------------------------------------------------------------- test_that("xml_find_lgl errors with non logical results", { x <- read_xml("") expect_snapshot_error({ xml_find_lgl(x, "//z") xml_find_lgl(x, "//y") xml_find_lgl(x, "string(5)") xml_find_lgl(x, "1+1") }) }) test_that("xml_find_lgl returns a logical result", { x <- read_xml("1") expect_equal(xml_find_lgl(x, "1=1"), TRUE) expect_equal(xml_find_lgl(x, "1!=1"), FALSE) expect_equal(xml_find_lgl(x, "true()=true()"), TRUE) expect_equal(xml_find_lgl(x, "true()=false()"), FALSE) expect_equal(xml_find_lgl(x, "'test'='test'"), TRUE) }) test_that("Searches with empty inputs retain type stability", { empty <- xml_nodeset() expect_equal(xml_find_num(empty, "1 div 0"), integer()) expect_equal(xml_find_chr(empty, "string(0.5)"), character()) expect_equal(xml_find_lgl(empty, "1=1"), logical()) }) test_that("Searches with entities work (#241)", { res <- read_xml(test_path("records.xml"), options = "DTDVALID") field1 <- xml_find_all(res, "//field1") expect_equal(xml_text(field1), "foo bar Quantitative Consultancy") }) test_that("A helpful error is given from non-string xpath in xml_find_first/all", { node <- read_xml("1") expect_error(xml_find_all(node, 1), "XPath must be a string", fixed = TRUE) expect_error(xml_find_first(node, 1), "XPath must be a string", fixed = TRUE) }) xml2/tests/testthat/test-xml_node.R0000644000176200001440000000023414517773421017055 0ustar liggesuserstest_that("print method is correct", { x <- read_html(test_path("lego.html.bz2")) body <- xml_find_first(x, "//body") expect_snapshot(print(body)) }) xml2/tests/testthat/test-xml_nodeset.R0000644000176200001440000000533014531733657017576 0ustar liggesuserstest_that("methods work on empty nodesets", { x <- read_xml("") empty <- xml_find_all(x, "//c") expect_error(empty[[1]], "subscript out of bounds") expect_identical(empty[1], empty) test <- empty xml_attr(test, "test") <- 1 expect_identical(test, empty) xml_attrs(test) <- c("test" = 1) expect_identical(test, empty) xml_name(test) <- "test" expect_identical(test, empty) xml_text(test) <- "test" expect_identical(test, empty) expect_identical(as.character(empty), character(0)) expect_identical(as_list(empty), list()) expect_identical(nodeset_apply(empty, identical), empty) expect_output(print(empty), "\\{xml_nodeset \\(0\\)\\}") expect_output(tree_structure(empty), NA) xml_add_child(test, "test") expect_identical(test, empty) xml_add_sibling(test, "test") expect_identical(test, empty) expect_identical(xml_attr(empty, "test"), character()) expect_identical(xml_attrs(empty), list()) expect_identical(xml_double(empty), numeric()) expect_identical(xml_find_all(empty), empty) expect_identical(xml_find_chr(empty), character()) expect_identical(xml_find_first(empty), empty) expect_identical(xml_find_lgl(empty), logical()) expect_identical(xml_find_num(empty), numeric()) expect_identical(xml_integer(empty), integer()) expect_identical(xml_length(empty), 0L) expect_identical(xml_name(empty), character()) expect_identical(xml_ns(empty), character()) expect_identical(xml_parent(empty), empty) expect_identical(xml_path(empty), character()) xml_remove(test) expect_identical(test, empty) xml_replace(test) expect_identical(test, empty) xml_set_attr(test, "test", 1) expect_identical(test, empty) xml_set_attrs(test, c("test" = 1)) expect_identical(test, empty) xml_set_name(test, "test") expect_identical(test, empty) xml_set_text(test, "test") expect_identical(test, empty) expect_identical(xml_siblings(empty), empty) expect_output(xml_structure(empty), NA) expect_identical(xml_text(empty), character()) expect_identical(xml_url(empty), character()) }) test_that("print method is correct", { skip_if(getOption("width") < 20L, "Screen too narrow") x <- read_html(test_path("lego.html.bz2")) body <- xml_find_first(x, "//body") divs <- xml_find_all(body, ".//div")[1:10] expect_snapshot(print(divs)) # double-substring() logic s <- c( "123456789\\", # always too wide, '\' never encoded "12345", # always fits "12\\45" # doesn't fit when '\' is encoded ) # embed as text on nodes ,, s <- sprintf("<%1$s>%2$s", letters[1:3], s) x <- read_xml(sprintf("%s", paste(s, collapse=""))) expect_snapshot({ print(x, width = 13L) print(x, width = 14L) }) }) xml2/tests/testthat/test-xml_modify.R0000644000176200001440000001626214517773421017427 0ustar liggesuserstest_that("modifying nodes works", { x <- read_xml("") node <- xml_find_first(x, "//x") expect_equal(xml_name(node), "x") .Call(node_set_name, node$node, "y") expect_equal(xml_name(node), "y") expect_equal(xml_text(node), "") .Call(node_set_content, node$node, "test") expect_equal(xml_text(node), "test") }) test_that("xml_text<- only modifies text content", { x <- read_xml("Text1text2") expect_equal(xml_text(x), "Text1text2") # will only change the first text by default xml_text(x) <- "new_text1" expect_equal(xml_text(x), "new_text1text2") # You can change the second by explicitly selecting it text_node <- xml_find_first(x, "//text()[2]") xml_text(text_node) <- "new_text2" expect_equal(xml_text(x), "new_text1new_text2") }) test_that("xml_text<- creates new text nodes if needed", { x <- read_xml("") xml_text(x) <- "test" expect_equal(xml_text(x), "test") }) test_that("xml_remove removes nodes", { x <- read_xml("123") children <- xml_children(x) t1 <- children[[1]] xml_remove(children, free = TRUE) expect_equal(xml_text(x), "") }) test_that("xml_replace replaces nodes", { x <- read_xml("123") children <- xml_children(x) t1 <- children[[1]] t2 <- children[[2]] t3 <- xml_children(children[[2]])[[1]] expect_equal(xml_text(x), "123") xml_replace(t1, t3) expect_equal(xml_text(x), "323") first_child <- xml_children(x)[[1]] xml_replace(first_child, t1, .copy = FALSE) expect_equal(xml_text(x), "123") xml_remove(first_child, free = TRUE) first_child <- xml_children(x)[[1]] xml_replace(first_child, t3, .copy = FALSE) expect_equal(xml_text(x), "32") xml_remove(first_child, free = TRUE) }) test_that("xml_replace works with nodesets", { x <- read_xml("123") children <- xml_children(x) t1 <- children[[1]] xml_replace(children, t1) expect_equal(xml_text(x), "11") }) test_that("xml_sibling adds a sibling node", { x <- read_xml("123") children <- xml_children(x) t1 <- children[[1]] t2 <- children[[2]] t3 <- xml_children(children[[2]])[[1]] xml_add_sibling(t1, t3) expect_length(xml_siblings(t1), 2) expect_equal(xml_text(x), "1323") xml_add_sibling(t1, t3, .where = "before") expect_length(xml_siblings(t1), 3) expect_equal(xml_text(x), "31323") children <- xml_children(x) xml_add_sibling(children, t1) expect_equal(xml_text(x), "311131231") }) test_that("xml_add_child adds a child node", { x <- read_xml("123") children <- xml_children(x) t1 <- children[[1]] t2 <- children[[2]] t3 <- xml_children(children[[2]])[[1]] expect_length(xml_children(t1), 0) xml_add_child(t1, t3, .copy = TRUE) expect_length(xml_children(t1), 1) expect_equal(xml_text(x), "1323") children <- xml_children(x) xml_add_child(children, t1) expect_equal(xml_text(x), "1313231313") }) test_that("xml_add_child can create a new default namespace", { x <- xml_root(xml_add_child(xml_new_document(), "foo", xmlns = "bar")) expect_equal(unclass(xml_ns(x)), c(d1 = "bar")) }) test_that("xml_add_child can create a new prefixed namespace", { x <- xml_root(xml_add_child(xml_new_document(), "foo", "xmlns:bar" = "baz")) expect_equal(unclass(xml_ns(x)), c(bar = "baz")) }) test_that("xml_add_child can create a new attribute", { x <- xml_add_child(xml_new_document(), "foo", "bar" = "baz") expect_equal(xml_attr(x, "bar"), "baz") }) test_that("xml_add_child can create new text", { x <- xml_add_child(xml_new_document(), "foo", "bar") expect_equal(xml_text(x), "bar") }) test_that("xml_add_child can create a new node with the specified prefix", { x <- xml_root(xml_add_child(xml_new_document(), "foo", "xmlns:bar" = "baz")) t1 <- xml_add_child(x, "bar:qux") expect_equal(xml_name(t1), "qux") expect_equal(xml_name(t1, xml_ns(x)), "bar:qux") }) test_that("xml_add_child can create a new node with the specified prefix", { x <- xml_root(xml_add_child(xml_new_document(), "foo", "xmlns:bar" = "baz")) expect_error(xml_add_child(x, "bar2:qux"), "No namespace with prefix `bar2` found") }) # https://github.com/r-lib/xml2/issues/284 test_that("xml_add_child can create a new node with attribute named 'par'", { x <- xml_new_root("foo") t1 <- xml_add_child(x, "a", "par" = "b") expect_true(xml_has_attr(t1, "par")) }) test_that("xml_add_parent works with xml_node input", { x <- read_xml("") y <- xml_find_first(x, ".//y") xml_add_parent(y, "z") expect_equal(xml_name(xml_parent(y)), "z") expect_equal(xml_name(xml_child(x)), "z") }) test_that("xml_add_parent works with xml_nodeset input", { x <- read_xml("") y <- xml_find_all(x, ".//y") xml_add_parent(y, "z") expect_equal(xml_name(xml_parent(y)), c("z", "z")) expect_equal(xml_name(xml_child(x)), "z") }) test_that("xml_add_parent works with xml_missing input", { x <- read_xml("

Some text.

Some other.

No bold text

") y <- xml_find_all(x, ".//p") z <- xml_find_first(y, ".//b") xml_add_parent(z, "em") expect_equal(xml_name(xml_parent(z)), c("em", "em")) expect_equal(xml_name(xml_children(y)), c("em", "em")) }) test_that("xml_new_document adds a default character encoding", { x <- read_xml("\u00E1\u00FC\u00EE") expect_equal(as.character(x), "\n\u00E1\u00FC\u00EE\n") x2 <- xml_new_document() xml_add_child(x2, "root", "\u00E1\u00FC\u00EE") expect_equal(as.character(x2), "\n\u00E1\u00FC\u00EE\n") }) test_that("xml_new_root is equivalent to using xml_new_document xml_add_child", { x1 <- xml_add_child(xml_new_document(), "foo", "bar") x2 <- xml_new_root("foo", "bar") expect_identical(as.character(x1), as.character(x2)) }) test_that("xml_add_child can insert anywhere in the child list", { x <- read_xml("
") xml_add_child(x, "z") expect_equal(c("z"), xml_name(xml_children(x))) xml_add_child(x, "w", .where = 0) expect_equal(c("w", "z"), xml_name(xml_children(x))) xml_add_child(x, "y", .where = 1) expect_equal(c("w", "y", "z"), xml_name(xml_children(x))) xml_add_child(x, "x", .where = 1) expect_equal(c("w", "x", "y", "z"), xml_name(xml_children(x))) }) test_that("xml_add_child can insert anywhere in a nodeset", { x <- read_xml("

Some text.

Some other.

No bold text

") y <- xml_find_all(x, ".//p") z <- xml_find_first(y, ".//b") xml_add_child(z, "bar") xml_add_child(z, "foo", .where = 0) expect_equal(c("foo", "bar", "foo", "bar"), xml_name(xml_children(z))) }) test_that("Can write root nodes with namespaces", { x <- xml_new_root("foo:bar", "xmlns:foo" = "http://foo/bar") expect_equal(unclass(xml_ns(x)), c(foo = "http://foo/bar")) expect_equal(as.character(xml_find_first(x, "/*")), "") }) xml2/tests/testthat/ns-multiple-aliases.xml0000644000176200001440000000016312723353101020545 0ustar liggesusers xml2/tests/testthat/test-xml_parse.R0000644000176200001440000000615514517775125017255 0ustar liggesuserstest_that("download_xml fails if curl is not installed", { skip("how to test error with `check_installed()`?") mockery::stub(download_xml, "requireNamespace", function(...) FALSE) expect_error( download_xml("http://httpbin.org/xml"), "`curl` must be installed to use `download_xml\\(\\)`" ) }) test_that("read_xml errors with an empty document", { expect_snapshot_error({read_xml(character())}) tf <- tempfile() file.create(tf) on.exit(unlink(tf)) expect_error(read_xml(tf), "Document is empty") }) test_that("read_html correctly parses malformed document", { lego <- read_html(test_path("lego.html.bz2")) expect_equal(length(xml_find_all(lego, ".//p")), 39) }) test_that("parse_options errors when given an invalid option", { expect_error( parse_options("INVALID", xml_parse_options()), "`options` 'INVALID' is not a valid option" ) expect_error( read_html(test_path("lego.html.bz2"), options = "INVALID"), "`options` 'INVALID' is not a valid option" ) # Empty inputs returned as 0 expect_identical(0L, parse_options("", xml_parse_options())) expect_identical(0L, parse_options(NULL, xml_parse_options())) # Numerics returned as integers expect_identical(12L, parse_options(12L, xml_parse_options())) expect_identical(12L, parse_options(12, xml_parse_options())) # Multiple inputs summed expect_identical(3L, parse_options(c("RECOVER", "NOENT"), xml_parse_options())) }) test_that("read_html properly passes parser arguments", { skip_if_not(libxml2_version() >= "2.9.2") blanks <- read_html(xml2_example("cd_catalog.xml"), options = c("RECOVER", "NOERROR")) expect_equal( as_list(blanks)$html$body$catalog$cd[[1]], "\r\n " ) no_blanks <- read_html(xml2_example("cd_catalog.xml"), options = c("RECOVER", "NOERROR", "NOBLANKS")) expect_equal( as_list(no_blanks)$html$body$catalog$cd[[1]], list("Empire Burlesque") ) }) test_that("read_xml works with httr response objects", { skip("httpbin is unreliable") x <- read_xml(httr::GET("http://httpbin.org/xml")) expect_s3_class(x, "xml_document") expect_equal(length(xml_find_all(x, "//slide")), 2) }) test_that("read_xml and read_html fail for bad status codes", { skip("httpbin is unreliable") expect_error( read_xml(httr::GET("http://httpbin.org/status/404")), class = "http_404" ) expect_error( read_html(httr::GET("http://httpbin.org/status/404")), class = "http_404" ) }) test_that("read_xml works with raw inputs", { x <- read_xml("") expect_equal(xml_url(x), NA_character_) }) test_that("read_html works with non-ASCII encodings", { tmp <- tempfile() on.exit(unlink(tmp)) writeLines("\U2019", tmp, useBytes = TRUE) res <- read_html(tmp, encoding = "UTF-8") expect_equal( as.character(res, options = ""), "\n\U2019\n" ) }) test_that("read_xml and read_html fail with > 1 input", { expect_snapshot_error({ read_xml(c("foo", "bar")) read_html(c("foo", "bar")) }) }) xml2/tests/testthat/records.xml0000644000176200001440000000021713633161317016325 0ustar liggesusers &hoqc; xml2/tests/testthat/ns-multiple.xml0000644000176200001440000000020712471405137017134 0ustar liggesusers xml2/tests/testthat/test-as_xml_document.R0000644000176200001440000000230114517773421020426 0ustar liggesusersroundtrip_xml <- function(x) { xml <- read_xml(x) lst <- as_list(xml) xml2 <- as_xml_document(lst) expect_equal(as.character(xml), as.character(xml2)) } test_that("roundtrips with single children", { roundtrip_xml("
") roundtrip_xml("") roundtrip_xml("foo") roundtrip_xml("foobar") roundtrip_xml("foobar") }) test_that("roundtrips with multi children", { roundtrip_xml("") roundtrip_xml("") roundtrip_xml("foobar") roundtrip_xml("foobarbaz") roundtrip_xml("foobar") roundtrip_xml("foobarbaz") }) test_that("rountrips with special attributes", { roundtrip_xml("") }) test_that("more than one root node is an error", { expect_error(as_xml_document(list(a = list(), b = list())), "Root nodes must be of length 1") }) test_that("Can convert nodes with leading and trailing text", { roundtrip_xml("foobarbaz") }) xml2/tests/testthat/test-null.R0000644000176200001440000000504714517773421016231 0ustar liggesusersdata <- read_xml(test_path("ns-multiple.xml")) tf <- tempfile() on.exit(unlink(tf)) saveRDS(data, file = tf) x <- readRDS(tf) test_that("accessors all fail rather than crash with NULL Xptrs", { expect_error(as_list(x), "external pointer is not valid") expect_error(html_structure(x), "external pointer is not valid") expect_error(xml_add_child(x, x), "external pointer is not valid") expect_error(xml_add_sibling(x, x), "external pointer is not valid") expect_error(xml_attr(x, "foo"), "external pointer is not valid") expect_error(xml_attr(x, "foo") <- "bar", "external pointer is not valid") expect_error(xml_attrs(x), "external pointer is not valid") expect_error(xml_attrs(x) <- list(), "external pointer is not valid") expect_error(xml_child(x), "external pointer is not valid") expect_error(xml_children(x), "external pointer is not valid") expect_error(xml_contents(x), "external pointer is not valid") expect_error(xml_double(x), "external pointer is not valid") expect_error(xml_find_all(x, ""), "external pointer is not valid") expect_error(xml_find_chr(x, ""), "external pointer is not valid") expect_error(xml_find_first(x, ""), "external pointer is not valid") expect_error(xml_find_lgl(x, ""), "external pointer is not valid") expect_error(xml_find_num(x, ""), "external pointer is not valid") expect_error(xml_has_attr(x, ""), "external pointer is not valid") expect_error(xml_integer(x), "external pointer is not valid") expect_error(xml_length(x), "external pointer is not valid") expect_error(xml_name(x), "external pointer is not valid") expect_error(xml_name(x) <- "foo", "external pointer is not valid") expect_error(xml_ns(x), "external pointer is not valid") expect_error(xml_ns_strip(x), "external pointer is not valid") expect_error(xml_parent(x), "external pointer is not valid") expect_error(xml_parents(x), "external pointer is not valid") expect_error(xml_path(x), "external pointer is not valid") expect_error(xml_remove(x), "external pointer is not valid") expect_error(xml_replace(x, x), "external pointer is not valid") expect_error(xml_set_namespace(x, "foo"), "external pointer is not valid") expect_error(xml_siblings(x), "external pointer is not valid") expect_error(xml_structure(x), "external pointer is not valid") expect_error(xml_text(x), "external pointer is not valid") expect_error(xml_text(x) <- "test", "external pointer is not valid") expect_error(xml_type(x), "external pointer is not valid") expect_error(xml_url(x), "external pointer is not valid") }) xml2/tests/testthat/test-xml_attr.R0000644000176200001440000001643314517773421017112 0ustar liggesuserstest_that("missing attributes returned as NA by default", { x <- read_xml("") expect_equal(xml_attr(x, "id"), NA_character_) }) test_that("missing attributes returned as NA", { x <- read_xml("") expect_equal(xml_attr(x, "id", default = 1), "1") }) test_that("attributes are correctly found", { x <- read_xml("") expect_true(xml_has_attr(x, "id")) expect_false(xml_has_attr(x, "id2")) }) test_that("returning an attribute node prints properly", { x <- read_xml("") t1 <- xml_find_first(x, "//@c") expect_equal(format(t1), "") }) # Namespaces ------------------------------------------------------------------- # Default namespace doesn't apply to attributes test_that("qualified names returned when ns given", { x <- read_xml(test_path("ns-multiple.xml")) ns <- xml_ns(x) bars <- xml_children(xml_children(x)) attr <- xml_attrs(bars, ns) expect_equal(names(attr[[1]]), "f:id") expect_equal(names(attr[[2]]), "g:id") }) x <- read_xml(' ') doc <- xml_children(x)[[1]] docs <- xml_find_all(x, "//doc") ns <- xml_ns(x) test_that("qualified attributes get own values", { expect_equal(xml_attrs(doc, ns), c("b:id" = "b", "f:id" = "f", "id" = "")) }) test_that("unqualified name gets unnamespace attribute", { expect_equal(xml_attr(doc, "id", ns), "") }) test_that("namespace names gets namespaced attribute", { expect_equal(xml_attr(doc, "b:id", ns), "b") expect_equal(xml_attr(doc, "f:id", ns), "f") }) test_that("xml_attr<- modifies properties", { xml_attr(doc, "id", ns) <- "test" expect_equal(xml_attr(doc, "id", ns), "test") xml_attr(doc, "b:id", ns) <- "b_test" expect_equal(xml_attr(doc, "b:id", ns), "b_test") xml_attr(doc, "f:id", ns) <- "f_test" expect_equal(xml_attr(doc, "f:id", ns), "f_test") xml_attr(docs, "f:id", ns) <- "f_test2" expect_equal(xml_attr(docs, "f:id", ns), c("f_test2", "f_test2")) xml_attr(docs, "f:id", ns) <- NULL expect_equal(xml_attr(docs, "f:id", ns), c(NA_character_, NA_character_)) }) test_that("xml_attr<- recycles values", { x <- read_xml("") a <- xml_find_all(x, "a") xml_attr(a, "b") <- c("e", "f") expect_equal(xml_attr(a, "b"), c("e", "f")) }) test_that("xml_attrs<- modifies all attributes", { expect_error(xml_attrs(doc) <- 1, "`value` must be a named character vector or `NULL`") expect_error(xml_attrs(doc) <- "test", "`value` must be a named character vector or `NULL`") xml_attrs(doc, ns) <- c("b:id" = "b", "f:id" = "f", "id" = "test") expect_equal(xml_attrs(doc, ns), c("b:id" = "b", "id" = "test", "f:id" = "f")) xml_attrs(doc, ns) <- c("b:id" = "b", "f:id" = "f") expect_equal(xml_attrs(doc, ns), c("b:id" = "b", "f:id" = "f")) xml_attrs(doc, ns) <- c("b:id" = "b", "id" = "test") expect_equal(xml_attrs(doc, ns), c("b:id" = "b", "id" = "test")) expect_snapshot_error(xml_attrs(docs) <- "test") xml_attrs(docs, ns) <- c("b:id" = "b", "id" = "test") expect_equal( xml_attrs(docs, ns), list( c("b:id" = "b", "id" = "test"), c("b:id" = "b", "id" = "test") ) ) xml_attrs(docs, ns) <- NULL expect_equal(xml_attrs(docs, ns), list(setNames(character(0), character()), setNames(character(0), character()))) }) test_that("xml_attr<- accepts non-character values", { x <- read_xml("") svg <- xml_root(x) xml_attr(svg, "width") <- 8L expect_equal(xml_attr(svg, "width"), "8") xml_attr(svg, "height") <- 12.5 expect_equal(xml_attr(svg, "height"), "12.5") expect_equal(xml_attrs(svg), c(width = "8", height = "12.5")) xml_attrs(svg) <- c(width = 14L, height = 23.45) expect_equal(xml_attrs(svg), c(width = "14", height = "23.45")) }) test_that("xml_attr<- can set empty strings, and removes attributes with NULL", { x <- read_xml("") xml_attr(x, "test") <- "" expect_equal(xml_attr(x, "test"), "") xml_attr(x, "test") <- NULL expect_equal(xml_attr(x, "test"), NA_character_) }) test_that("xml_attr<- removes namespaces if desired", { xml_attr(x, "xmlns:b") <- NULL expect_equal(xml_attrs(x), c("xmlns:f" = "http://foo.com")) }) test_that("xml_attr<- removes namespaces if desired", { x <- read_xml("") # cannot find //b with a default namespace expect_equal(length(xml_find_all(x, "//b")), 0) # unless we specify it explicitly expect_equal(length(xml_find_all(x, "//b")), 0) expect_equal(length(xml_find_all(x, "//d1:b", xml_ns(x))), 1) # but can find it once we remove the namespace xml_attr(x, "xmlns") <- NULL expect_equal(length(xml_find_all(x, "//b")), 1) # and add the old namespace back xml_attr(x, "xmlns") <- "tag:foo" expect_equal(xml_attr(x, "xmlns"), "tag:foo") expect_equal(length(xml_find_all(x, "//b")), 0) expect_equal(length(xml_find_all(x, "//d1:b", xml_ns(x))), 1) expect_equal(xml_attr(x, "xmlns"), "tag:foo") }) test_that("xml_attr<- removes prefixed namespaces if desired", { x <- read_xml("") # cannot find //b with a prefixed namespace expect_equal(length(xml_find_all(x, "//b")), 0) # unless we specify it explicitly expect_equal(length(xml_find_all(x, "//b")), 0) expect_equal(length(xml_find_all(x, "//pre:b", xml_ns(x))), 1) # but can find it once we remove the namespace xml_attr(x, "xmlns:pre") <- NULL expect_equal(length(xml_find_all(x, "//b")), 1) # and add the old namespace back xml_attr(x, "xmlns:pre") <- "tag:foo" xml_set_namespace(xml_children(x)[[1]], "pre") expect_equal(xml_attr(x, "xmlns:pre"), "tag:foo") expect_equal(length(xml_find_all(x, "//b")), 0) expect_equal(length(xml_find_all(x, "//pre:b", xml_ns(x))), 1) expect_equal(xml_attr(x, "xmlns:pre"), "tag:foo") }) test_that("xml_set_attr works identically to xml_attr<-", { content <- "" x <- read_xml(content) y <- read_xml(content) xml_attr(x, "a") <- "test" xml_set_attr(y, "a", "test") expect_equal(as.character(x), as.character(y)) bx <- xml_find_all(x, "//b") by <- xml_find_all(y, "//b") xml_attr(bx, "b") <- "test2" xml_set_attr(by, "b", "test2") expect_equal(as.character(x), as.character(y)) # No errors for xml_missing mss <- xml_find_first(bx, "./c") expect_error(xml_attr(mss[[2]], "b") <- "blah", NA) expect_error(xml_set_attr(mss[[2]], "b", "blah"), NA) }) test_that("xml_set_attrs works identically to xml_attrs<-", { content <- "" x <- read_xml(content) y <- read_xml(content) xml_attrs(x) <- c(a = "test") xml_set_attrs(y, c(a = "test")) expect_equal(as.character(x), as.character(y)) bx <- xml_find_all(x, "//b") by <- xml_find_all(y, "//b") xml_attrs(bx) <- c(b = "test2") xml_set_attrs(by, c(b = "test2")) expect_equal(as.character(x), as.character(y)) # No errors for xml_missing mss <- xml_find_first(bx, "./c") expect_error(xml_attrs(mss[[2]]) <- c("b" = "blah"), NA) expect_error(xml_set_attrs(mss[[2]], c("b" = "blah")), NA) }) test_that("xml_set_attr can set the same namespace multiple times", { doc <- xml_new_root("foo") xml_set_attr(doc, "xmlns:bar", "http://a/namespace") xml_set_attr(doc, "xmlns:bar", "http://b/namespace") expect_equal(xml_attr(doc, "xmlns:bar"), "http://b/namespace") }) xml2/tests/testthat/test-xml_schema.R0000644000176200001440000000135614517773421017376 0ustar liggesuserstest_that("xml schema validates", { doc <- read_xml(system.file("extdata/order-doc.xml", package = "xml2")) schema <- read_xml(system.file("extdata/order-schema.xml", package = "xml2")) expect_true(xml_validate(doc, schema)) }) test_that("xml schema errors", { str <- readLines(system.file("extdata/order-doc.xml", package = "xml2")) str <- sub("1", "", str) str <- sub("95819", "ABC95819", str) str <- sub('partNum="926-AA"', "", str) doc <- read_xml(paste(str, collapse = "\n")) schema <- read_xml(system.file("extdata/order-schema.xml", package = "xml2")) out <- xml_validate(doc, schema) expect_false(out) errors <- attr(out, "errors") expect_type(errors, "character") expect_length(errors, 4) }) xml2/tests/testthat/test-xml_write.R0000644000176200001440000000744214517773421017272 0ustar liggesuserstest_that("write_xml errors for incorrect directory and with invalid inputs", { x <- read_xml("") filename <- "does_not_exist/test.xml" expect_error(write_xml(x, filename), "'does_not_exist' does not exist in current working directory") expect_snapshot_error(write_xml(x, c("test.xml", "foo"))) }) test_that("write_xml works with relative file paths", { x <- read_xml("") filename <- "../test.xml" on.exit(unlink(filename)) write_xml(x, filename, options = "no_declaration") expect_identical(readChar(filename, 1000L), "\n") }) test_that("write_xml works with no options", { x <- read_xml("") filename <- "../test.xml" on.exit(unlink(filename)) write_xml(x, filename, options = NULL) expect_identical(readChar(filename, 1000L), "\n\n") }) test_that("write_xml works with an explicit connections", { x <- read_xml("") filename <- "../test.xml" file <- file(filename, "wb") on.exit(unlink(filename)) write_xml(x, file, options = "no_declaration") close(file) expect_identical(readChar(filename, 1000L), "\n") }) test_that("write_xml works with an implicit connections", { x <- read_xml("") filename <- "../test.xml.gz" write_xml(x, filename, options = "no_declaration") file <- gzfile(filename, "rb") on.exit({ unlink(filename) close(file) }) expect_identical(readChar(file, 1000L), "\n") }) test_that("write_xml works with nodeset input and files", { x <- read_xml("") y <- xml_find_all(x, "//y") filename <- "../test.xml" on.exit(unlink(filename)) expect_error( write_xml(y, filename, options = "no_declaration"), "Can only save length 1 node sets" ) write_xml(y[1], filename, options = "no_declaration") expect_identical(readChar(filename, 1000L), "") }) test_that("write_xml works with nodeset input and connections", { x <- read_xml("") y <- xml_find_all(x, "//y") filename <- "../test.xml.gz" expect_error( write_xml(y, filename, options = "no_declaration"), "Can only save length 1 node sets" ) expect_snapshot_error(write_xml(y[1], c(filename, "foo"))) write_xml(y[1], filename, options = "no_declaration") file <- gzfile(filename, "rb") on.exit({ unlink(filename) close(file) }) expect_identical(readChar(file, 1000L), "") }) test_that("write_xml works with node input and files", { x <- read_xml("") y <- xml_find_first(x, "//y") filename <- "../test.xml" expect_snapshot_error(write_xml(y, c(filename, "foo"))) write_xml(y, filename, options = "no_declaration") on.exit(unlink(filename)) expect_identical(readChar(filename, 1000L), "") }) test_that("write_xml works with node input and connections", { x <- read_xml("") y <- xml_find_first(x, "//y") filename <- "../test.xml.gz" write_xml(y, filename, options = "no_declaration") file <- gzfile(filename, "rb") on.exit({ unlink(filename) close(file) }) expect_identical(readChar(file, 1000L), "") }) test_that("write_html work with html input", { x <- read_html("Foo") filename <- "../test.html.gz" write_html(x, filename) file <- gzfile(filename, "rb") on.exit({ unlink(filename) close(file) }) expect_identical( readChar(file, 1000L), "\n\n\nFoo\n\n" ) }) test_that("write_xml returns invisibly", { x <- read_xml("foo") tf <- tempfile() on.exit(unlink(tf)) res <- withVisible(write_xml(x, tf)) expect_equal(res$value, NULL) expect_equal(res$visible, FALSE) }) xml2/tests/testthat/test-format.R0000644000176200001440000000116714517773421016546 0ustar liggesuserstest_that("format.xml_node prints attributes for root nodes", { x <- read_xml("") expect_equal(format(x), "") }) test_that("format.xml_node prints namespaces for root nodes", { x <- read_xml("") expect_equal(format(x), "") y <- read_xml("") expect_equal(format(y), "") z <- read_xml("") expect_equal(format(z), "") }) xml2/tests/testthat/helper.R0000644000176200001440000000015013633161317015540 0ustar liggesusersmaybe_error <- function(code, ...) { tryCatch(code, error = function(e) expect_error(stop(e), ...)) } xml2/tests/testthat/_snaps/0000755000176200001440000000000014532115535015425 5ustar liggesusersxml2/tests/testthat/_snaps/xml_document.md0000644000176200001440000000053414532206720020444 0ustar liggesusers# print method is correct Code print(x) Output {html_document} [1] \n

Node Modification

Jim Hester

2023-12-04

Modifying Existing XML

Modifying existing XML can be done in xml2 by using the replacement functions of the accessors. They all have methods for both individual xml_node objects as well as xml_nodeset objects. If a vector of values is provided it is applied piecewise over the nodeset, otherwise the value is recycled.

Text Modification

Text modification only happens on text nodes. If a given node has more than one text node only the first will be affected. If you want to modify additional text nodes you need to select them explicitly with /text().

x <- read_xml("<p>This is some <b>text</b>. This is more.</p>")
xml_text(x)
#> [1] "This is some text. This is more."

xml_text(x) <- "This is some other text."
xml_text(x)
#> [1] "This is some other text.text. This is more."

# You can avoid this by explicitly selecting the text node.
x <- read_xml("<p>This is some text. This is <b>bold!</b></p>")
text_only <- xml_find_all(x, "//text()")

xml_text(text_only) <- c("This is some other text. ", "Still bold!")
xml_text(x)
#> [1] "This is some other text. Still bold!"
xml_structure(x)
#> <p>
#>   {text}
#>   <b>
#>     {text}

Attribute and Namespace Definition Modification

Attributes and namespace definitions are modified one at a time with xml_attr() or all at once with xml_attrs(). In both cases using NULL as the value will remove the attribute completely.

x <- read_xml("<a href='invalid!'>xml2</a>")
xml_attr(x, "href")
#> [1] "invalid!"

xml_attr(x, "href") <- "https://github.com/r-lib/xml2"
xml_attr(x, "href")
#> [1] "https://github.com/r-lib/xml2"

xml_attrs(x) <- c(id = "xml2", href = "https://github.com/r-lib/xml2")
xml_attrs(x)
#>                            href                              id 
#> "https://github.com/r-lib/xml2"                          "xml2"
x
#> {xml_document}
#> <a href="https://github.com/r-lib/xml2" id="xml2">

xml_attrs(x) <- NULL
x
#> {xml_document}
#> <a>

# Namespaces are added with as a xmlns or xmlns:prefix attribute
xml_attr(x, "xmlns") <- "http://foo"
x
#> {xml_document}
#> <a xmlns="http://foo">

xml_attr(x, "xmlns:bar") <- "http://bar"
x
#> {xml_document}
#> <a xmlns="http://foo" xmlns:bar="http://bar">

Name Modification

Node names are modified with xml_name().

x <- read_xml("<a><b/></a>")
x
#> {xml_document}
#> <a>
#> [1] <b/>
xml_name(x)
#> [1] "a"
xml_name(x) <- "c"
x
#> {xml_document}
#> <c>
#> [1] <b/>

Node modification

All of these functions have a .copy argument. If this is set to FALSE they will remove the new node from its location before inserting it into the new location. Otherwise they make a copy of the node before insertion.

Replacing existing nodes

x <- read_xml("<parent><child>1</child><child>2<child>3</child></child></parent>")
children <- xml_children(x)
t1 <- children[[1]]
t2 <- children[[2]]
t3 <- xml_children(children[[2]])[[1]]

xml_replace(t1, t3)
#> {xml_node}
#> <child>
x
#> {xml_document}
#> <parent>
#> [1] <child>3</child>
#> [2] <child>2<child>3</child></child>

Add a sibling

x <- read_xml("<parent><child>1</child><child>2<child>3</child></child></parent>")
children <- xml_children(x)
t1 <- children[[1]]
t2 <- children[[2]]
t3 <- xml_children(children[[2]])[[1]]

xml_add_sibling(t1, t3)
x
#> {xml_document}
#> <parent>
#> [1] <child>1</child>
#> [2] <child>3</child>
#> [3] <child>2<child>3</child></child>

xml_add_sibling(t3, t1, where = "before")
x
#> {xml_document}
#> <parent>
#> [1] <child>1</child>
#> [2] <child>3</child>
#> [3] <child>2<child>3</child><child>1</child></child>

Add a child

x <- read_xml("<parent><child>1</child><child>2<child>3</child></child></parent>")
children <- xml_children(x)
t1 <- children[[1]]
t2 <- children[[2]]
t3 <- xml_children(children[[2]])[[1]]

xml_add_child(t1, t3)
x
#> {xml_document}
#> <parent>
#> [1] <child>1<child>3</child></child>
#> [2] <child>2<child>3</child></child>

xml_add_child(t1, read_xml("<test/>"))
x
#> {xml_document}
#> <parent>
#> [1] <child>1<child>3</child><test/></child>
#> [2] <child>2<child>3</child></child>

Removing nodes

The xml_remove() can be used to remove a node (and its children) from a tree. The default behavior is to unlink the node from the tree, but does not free the memory for the node, so R objects pointing to the node are still valid.

This allows code like the following to work without crashing R

x <- read_xml("<foo><bar><baz/></bar></foo>")
x1 <- x %>%
  xml_children() %>%
  .[[1]]
x2 <- x1 %>%
  xml_children() %>%
  .[[1]]

xml_remove(x1)
rm(x1)
gc()
#>           used (Mb) gc trigger (Mb) limit (Mb) max used (Mb)
#> Ncells  598977 32.0    1355532 72.4         NA  1320341 70.6
#> Vcells 1127775  8.7    8388608 64.0      32768  2040786 15.6

x2
#> {xml_node}
#> <baz>

If you are not planning on referencing these nodes again this memory is wasted. Calling xml_remove(free = TRUE) will remove the nodes and free the memory used to store them. Note In this case any node which previously pointed to the node or its children will instead be pointing to free memory and may cause R to crash. xml2 can’t figure this out for you, so it’s your responsibility to remove any objects which are no longer valid.

In particular xml_find_*() results are easy to overlook, for example

x <- read_xml("<a><b /><b><b /></b></a>")
bees <- xml_find_all(x, "//b")
xml_remove(xml_child(x), free = TRUE)
# bees[[1]] is no longer valid!!!
rm(bees)
gc()
#>           used (Mb) gc trigger (Mb) limit (Mb) max used (Mb)
#> Ncells  598883 32.0    1355532 72.4         NA  1320341 70.6
#> Vcells 1127612  8.7    8388608 64.0      32768  2040786 15.6

Namespaces

We want to construct a document with the following namespace layout. (From https://stackoverflow.com/questions/32939229/creating-xml-in-r-with-namespaces/32941524#32941524).

<?xml version = "1.0" encoding="UTF-8"?>
<sld xmlns="http://www.opengis.net/sld"
     xmlns:ogc="http://www.opengis.net/ogc"
     xmlns:se="http://www.opengis.net/se"
     version="1.1.0" >
<layer>
<se:Name>My Layer</se:Name>
</layer>
</sld>
d <- xml_new_root("sld",
  "xmlns" = "http://www.opengis.net/sld",
  "xmlns:ogc" = "http://www.opengis.net/ogc",
  "xmlns:se" = "http://www.opengis.net//se",
  version = "1.1.0"
) %>%
  xml_add_child("layer") %>%
  xml_add_child("se:Name", "My Layer") %>%
  xml_root()

d
#> {xml_document}
#> <sld version="1.1.0" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:se="http://www.opengis.net//se">
#> [1] <layer>\n  <se:Name>My Layer</se:Name>\n</layer>
xml2/inst/include/0000755000176200001440000000000014531733657013552 5ustar liggesusersxml2/inst/include/xml2_types.h0000644000176200001440000000327214531733657016035 0ustar liggesusers#ifndef __XML2_XML2_TYPES__ #define __XML2_XML2_TYPES__ #include #define R_NO_REMAP #include template class XPtr { protected: SEXP data_; public: XPtr(SEXP x) : data_(x) { if (TYPEOF(data_) != EXTPTRSXP) { Rf_error("Expecting an external pointer: [type=%s]", Rf_type2char(TYPEOF(data_))); } R_PreserveObject(data_); } XPtr(T* p) { data_ = R_MakeExternalPtr((void *) p, R_NilValue, R_NilValue); R_PreserveObject(data_); } XPtr(const XPtr &old) { data_ = old.data_; R_PreserveObject(data_); } XPtr& operator=(const XPtr &other) { R_PreserveObject(other.data_); if (data_ != NULL) { R_ReleaseObject(data_); } data_ = other.data_; return *this; } operator SEXP() const { return data_; } T* get() const { return (T*)(R_ExternalPtrAddr(data_)); } T* checked_get() const { T* ptr = get(); if (ptr == NULL) { Rf_error("external pointer is not valid"); } return ptr; } operator T*() { return checked_get(); } T* operator->() const { return checked_get(); } ~XPtr() { R_ReleaseObject(data_); } }; class XPtrDoc : public ::XPtr { static void finalizeXPtrDoc(SEXP p) { if (TYPEOF(p) != EXTPTRSXP) { return; } xmlDoc* ptr = (xmlDoc*) R_ExternalPtrAddr(p); if (ptr == NULL) { return; } R_ClearExternalPtr(p); xmlFreeDoc(ptr); } public: XPtrDoc(xmlDoc* p) : ::XPtr(p) { R_RegisterCFinalizerEx(data_, finalizeXPtrDoc, (Rboolean) false); } XPtrDoc(SEXP x) : ::XPtr(x) {} }; typedef ::XPtr XPtrNode; typedef ::XPtr XPtrNs; #endif xml2/inst/extdata/0000755000176200001440000000000013633161317013547 5ustar liggesusersxml2/inst/extdata/order-schema.xml0000644000176200001440000000461613026552053016646 0ustar liggesusers Purchase order schema for Example.com. Copyright 2000 Example.com. All rights reserved. Purchase order schema for Example.Microsoft.com. Copyright 2001 Example.Microsoft.com. All rights reserved. Application info. xml2/inst/extdata/cd_catalog.xml0000644000176200001440000001173013633161317016353 0ustar liggesusers Empire Burlesque Bob Dylan USA Columbia 10.90 1985 Hide your heart Bonnie Tylor UK CBS Records 9.90 1988 Greatest Hits Dolly Parton USA RCA 9.90 1982 Still got the blues Gary More UK Virgin redords 10.20 1990 Eros Eros Ramazzotti EU BMG 9.90 1997 One night only Bee Gees UK Polydor 10.90 1998 Sylvias Mother Dr.Hook UK CBS 8.10 1973 Maggie May Rod Stewart UK Pickwick 8.50 1990 Romanza Andrea Bocelli EU Polydor 10.80 1996 When a man loves a woman Percy Sledge USA Atlantic 8.70 1987 Black angel Savage Rose EU Mega 10.90 1995 1999 Grammy Nominees Many USA Grammy 10.20 1999 For the good times Kenny Rogers UK Mucik Master 8.70 1995 Big Willie style Will Smith USA Columbia 9.90 1997 Tupelo Honey Van Morrison UK Polydor 8.20 1971 Soulsville Jorn Hoel Norway WEA 7.90 1996 The very best of Cat Stevens UK Island 8.90 1990 Stop Sam Brown UK A and M 8.90 1988 Bridge of Spies T`Pau UK Siren 7.90 1987 Private Dancer Tina Turner UK Capitol 8.90 1983 Midt om natten Kim Larsen EU Medley 7.80 1983 Pavarotti Gala Concert Luciano Pavarotti UK DECCA 9.90 1991 The dock of the bay Otis Redding USA Atlantic 7.90 1987 Picture book Simply Red EU Elektra 7.20 1985 Red The Communards UK London 7.80 1987 Unchain my heart Joe Cocker USA EMI 8.20 1987 xml2/inst/extdata/r-project.html0000644000176200001440000001160112511543055016336 0ustar liggesusers R: The R Project for Statistical Computing

The R Project for Statistical Computing

Getting Started

R is a free software environment for statistical computing and graphics. It compiles and runs on a wide variety of UNIX platforms, Windows and MacOS. To download R, please choose your preferred CRAN mirror.

If you have questions about R like how to download and install the software, or what the license terms are, please read our answers to frequently asked questions before you send an email.

News

  • R 3.2.0 (Full of Ingredients) prerelease versions will appear starting March 19. Final release is scheduled for 2015-04-16.

  • R version 3.1.3 (Smooth Sidewalk) has been released on 2015-03-09.

  • The R Journal Volume 6/2 is available.

  • R version 3.1.2 (Pumpkin Helmet) has been released on 2014-10-31.

  • useR! 2015, will take place at the University of Aalborg, Denmark, June 30 - July 3, 2015.

  • useR! 2014, took place at the University of California, Los Angeles, USA June 30 - July 3, 2014.

xml2/inst/extdata/order-doc.xml0000644000176200001440000000200013026552053016134 0ustar liggesusers Alice Smith 123 Maple Street Mill Valley CA 90952 Robert Smith 8 Oak Avenue Old Town PA 95819 Hurry, my lawn is going wild! Lawnmower 1 148.95 Confirm this is electric Baby Monitor 1 39.98 1999-05-21 xml2/cleanup0000755000176200001440000000003514533363463012521 0ustar liggesusers#!/bin/sh rm -f src/Makevars xml2/configure0000755000176200001440000000655114533363463013064 0ustar liggesusers#!/bin/sh # Anticonf (tm) script by Jeroen Ooms (2015) # This script will query 'pkg-config' for the required cflags and ldflags. # If pkg-config is unavailable or does not find the library, try setting # INCLUDE_DIR and LIB_DIR manually via e.g: # R CMD INSTALL --configure-vars='INCLUDE_DIR=/.../include LIB_DIR=/.../lib' # Library settings PKG_CONFIG_NAME="libxml-2.0" PKG_DEB_NAME="libxml2-dev" PKG_RPM_NAME="libxml2-devel" PKG_CSW_NAME="libxml2_dev" PKG_TEST_HEADER="" PKG_LIBS="-lxml2" OS_TYPE=`uname -s` OS_VERSION=`uname -r | cut -d '.' -f 1` # Note that cflags may be empty in case of success if [ "$INCLUDE_DIR" ] || [ "$LIB_DIR" ]; then echo "Found INCLUDE_DIR and/or LIB_DIR!" PKG_CFLAGS="-I$INCLUDE_DIR $PKG_CFLAGS" PKG_LIBS="-L$LIB_DIR $PKG_LIBS" else # Use xml2-config if available xml2-config --version >/dev/null 2>&1 if [ $? -eq 0 ]; then PKGCONFIG_CFLAGS=`xml2-config --cflags` PKGCONFIG_LIBS=`xml2-config --libs` # MacOS versions El Capitan and later ship a xml2-config which appends `xcrun # --show-sdk-path` to the xml2-config. So we remove it if it is present. # (https://stat.ethz.ch/pipermail/r-sig-mac/2016-September/012046.html) if [ "$OS_TYPE" = "Darwin" ] && [ "$OS_VERSION" -gt "13" ] && [ "$OS_VERSION" -lt "17" ]; then PKGCONFIG_CFLAGS=`echo $PKGCONFIG_CFLAGS | perl -pe "s{\Q\`xcrun -show-sdk-path\`\E}{}"` PKGCONFIG_LIBS=`echo $PKGCONFIG_LIBS | perl -pe "s{\Q\`xcrun -show-sdk-path\`\E}{}"` fi # Fix a missing libxml2 directory on the requested include directory # https://github.com/r-lib/xml2/issues/296 if [ "${OS_TYPE}" = "Darwin" ] && echo "${PKGCONFIG_CFLAGS}" | grep -sq "/usr/include$"; then PKGCONFIG_CFLAGS="$PKGCONFIG_CFLAGS/libxml2" fi else pkg-config --version >/dev/null 2>&1 if [ $? -eq 0 ]; then PKGCONFIG_CFLAGS=`pkg-config --cflags $PKG_CONFIG_NAME` PKGCONFIG_LIBS=`pkg-config --libs $PKG_CONFIG_NAME` fi fi if [ "$PKGCONFIG_CFLAGS" ] || [ "$PKGCONFIG_LIBS" ]; then echo "Found pkg-config cflags and libs!" PKG_CFLAGS=${PKGCONFIG_CFLAGS} PKG_LIBS=${PKGCONFIG_LIBS} fi fi # Find compiler CC=`${R_HOME}/bin/R CMD config CC` CFLAGS=`${R_HOME}/bin/R CMD config CFLAGS` CPPFLAGS=`${R_HOME}/bin/R CMD config CPPFLAGS` # For debugging echo "Using PKG_CFLAGS=$PKG_CFLAGS" echo "Using PKG_LIBS=$PKG_LIBS" # Test configuration echo "#include $PKG_TEST_HEADER" | ${CC} ${CPPFLAGS} ${PKG_CFLAGS} ${CFLAGS} -E -xc - >/dev/null 2>&1 || R_CONFIG_ERROR=1; # Customize the error if [ $R_CONFIG_ERROR ]; then echo "------------------------- ANTICONF ERROR ---------------------------" echo "Configuration failed because $PKG_CONFIG_NAME was not found. Try installing:" echo " * deb: $PKG_DEB_NAME (Debian, Ubuntu, etc)" echo " * rpm: $PKG_RPM_NAME (Fedora, CentOS, RHEL)" echo " * csw: $PKG_CSW_NAME (Solaris)" echo "If $PKG_CONFIG_NAME is already installed, check that 'pkg-config' is in your" echo "PATH and PKG_CONFIG_PATH contains a $PKG_CONFIG_NAME.pc file. If pkg-config" echo "is unavailable you can set INCLUDE_DIR and LIB_DIR manually via:" echo "R CMD INSTALL --configure-vars='INCLUDE_DIR=... LIB_DIR=...'" echo "--------------------------------------------------------------------" exit 1; fi # Write to Makevars sed -e "s|@cflags@|$PKG_CFLAGS|" -e "s|@libs@|$PKG_LIBS|" src/Makevars.in > src/Makevars # Success exit 0