pkgdown/0000755000176200001440000000000014672377072011742 5ustar liggesuserspkgdown/tests/0000755000176200001440000000000014672347601013077 5ustar liggesuserspkgdown/tests/testthat/0000755000176200001440000000000014672377072014744 5ustar liggesuserspkgdown/tests/testthat/test-highlight.R0000644000176200001440000000350614642014746020010 0ustar liggesuserstest_that("highlight_examples captures dependencies", { withr::defer(try(file_delete(test_path("Rplot001.png")), TRUE)) dummy_dep <- htmltools::htmlDependency("dummy", "1.0.0", "dummy.js") widget <- htmlwidgets::createWidget("test", list(), dependencies = dummy_dep) out <- highlight_examples("widget", env = environment()) # htmlwidgets always get dependency on htmlwidgets.js expect_equal(attr(out, "dependencies")[-1], list(dummy_dep)) }) test_that("highlight_examples runs and hides DONTSHOW calls()", { out <- highlight_examples("DONTSHOW(x <- 1)\nx") expect_snapshot(cat(strip_html_tags(out))) }) test_that("highlight_text & highlight_examples include sourceCode div", { withr::defer(try(file_delete(test_path("Rplot001.png")), TRUE)) html <- xml2::read_html(highlight_examples("a + a", "x")) expect_equal(xpath_attr(html, "./body/div", "class"), "sourceCode") html <- xml2::read_html(highlight_text("a + a")) expect_equal(xpath_attr(html, "./body/div", "class"), "sourceCode") }) test_that("pre() can produce needed range of outputs", { expect_snapshot({ cat(pre("x")) cat(pre("x", r_code = TRUE)) }) }) test_that("tweak_highlight_other() renders generic code blocks for roxygen2 >= 7.2.0", { html <- xml2::read_html('
1+1\n
') div <- xml2::xml_find_first(html, "//div") tweak_highlight_other(div) expect_equal(xpath_text(div, "pre/code"), "1+1") }) test_that("tweak_highlight_other() renders nested code blocks for roxygen2 >= 7.2.0", { html <- xml2::read_html(dedent("

    blablabla

    ```{r results='asis'}
    lalala
    ```

    
")) div <- xml2::xml_find_first(html, "//div") tweak_highlight_other(div) expect_snapshot(cat(xpath_text(div, "pre/code"))) }) pkgdown/tests/testthat/test-tweak-tags.R0000644000176200001440000001774414633374223020120 0ustar liggesusers# tables ------------------------------------------------------------- test_that("tables get additional table class", { html <- xml2::read_html("
") tweak_tables(html) expect_equal( xpath_attr(html, ".//table", "class"), c("table", "table a", "table b") ) }) test_that("except in the argument list", { html <- xml2::read_html("
") tweak_tables(html) expect_equal(xpath_attr(html, ".//table", "class"), "ref-arguments") }) # anchors ------------------------------------------------------------- test_that("ids move from div to headings", { html <- xml2::read_xml('

abc

abc

abc

abc

abc
abc
') tweak_anchors(html) expect_equal(xpath_attr(html, ".//h1|//h2|//h3|//h4|//h5|//h6", "id"), as.character(1:6)) expect_equal(xpath_attr(html, ".//div", "id"), rep(NA_character_, 6)) }) test_that("must be in div with section an class and id", { html <- xml2::read_xml('

abc

abc

abc

') tweak_anchors(html) expect_equal(xpath_attr(html, ".//h1", "id"), rep(NA_character_, 3)) }) test_that("anchor html added to headings", { html <- xml2::read_xml('

abc

') tweak_anchors(html) expect_snapshot_output(xpath_xml(html, ".//h1")) }) test_that("deduplicates ids", { html <- xml2::read_xml('

abc

abc

abc

') tweak_anchors(html) expect_equal(xpath_attr(html, ".//h1", "id"), c("x", "x-1", "x-2")) }) test_that("can process multiple header levels", { html <- xml2::read_xml('

abc

abc

abc

abc

') tweak_anchors(html) expect_equal(xpath_attr(html, ".//a", "href"), c("#1", "#2", "#3", "#4")) }) test_that("can handle multiple header", { html <- xml2::read_xml('

one

two

') tweak_anchors(html) expect_equal(xpath_attr(html, ".//div", "id"), NA_character_) expect_equal(xpath_attr(html, ".//h1", "id"), c("x", "x-1")) expect_equal(xpath_attr(html, ".//h1/a", "href"), c("#x", "#x-1")) }) test_that("anchors don't get additional newline", { html <- xml2::read_xml('

abc

') tweak_anchors(html) expect_equal(xpath_text(html, ".//h1"), "abc") }) test_that("empty headings are skipped", { html <- xml2::read_xml('

') tweak_anchors(html) expect_equal(xpath_length(html, ".//h1/a"), 0) }) test_that("docs with no headings are left unchanged", { html <- xml2::read_xml('
Nothing
') tweak_anchors(html) expect_equal(as.character(xpath_xml(html, ".")), '
Nothing
') }) # links ----------------------------------------------------------------- test_that("local md links are replaced with html", { html <- xml2::read_html(' ') tweak_link_md(html) expect_equal( xpath_attr(html, "//a", "href"), c("local.html", "local.html#fragment", "http://remote.com/remote.md") ) }) test_that("tweak_link_external() add the external-link class if needed", { html <- xml2::read_html(' ') pkg <- list(meta = list(url = "http://example.com")) tweak_link_external(html, pkg = pkg) expect_equal( xpath_attr(html, "//a", "class"), c(NA, "external-link", "external-link", "external-link thumbnail", NA) ) }) test_that("tweak_link_absolute() fixes relative paths in common locations", { html <- xml2::read_html(' ') pkg <- list(meta = list(url = "https://example.com")) tweak_link_absolute(html, pkg) expect_equal(xpath_attr(html, "//a", "href"), "https://example.com/a") expect_equal(xpath_attr(html, "//link", "href"), "https://example.com/link") expect_equal(xpath_attr(html, "//img", "src"), "https://example.com/img") }) test_that("tweak_link_absolute() leaves absolute paths alone", { html <- xml2::read_html('') pkg <- list(list(url = "https://example.com")) tweak_link_absolute(html, pkg) expect_equal(xpath_attr(html, "//a", "href"), "https://a.com") }) test_that("tweak_link_r6() correctly modifies link to inherited R6 classes", { skip_on_cran() # in case downlit url changes html <- xml2::read_html(" text text text ") tweak_link_R6(html, "pkgdown") expect_equal( xpath_attr(html, "//a", "href"), c( "Animal.html#method-x", "leave-me.html", "https://downlit.r-lib.org/reference/autolink.html#method-x" ) ) }) test_that("tweak_img_src() updates img and source tags", { html <- xml2::read_html(' ') tweak_img_src(html) expect_equal(xpath_attr(html, ".//img", "src"), "reference/figures/bar.png") expect_equal(xpath_attr(html, ".//source", "srcset"), "reference/figures/foo.png") }) test_that("tweak_img_src() doesn't modify absolute links", { html <- xml2::read_html(' ') urls_before <- xpath_attr(html, ".//img", "src") tweak_img_src(html) expect_equal( xpath_attr(html, ".//img", "src"), urls_before ) }) # stripped divs etc ------------------------------------------------------- test_that("selectively remove hide- divs", { html <- xml2::read_xml("
devel
release
all
") tweak_strip(html, in_dev = TRUE) expect_equal(xpath_text(html, ".//div"), "devel") html <- xml2::read_xml("
devel
release
all
") tweak_strip(html, in_dev = FALSE) expect_equal(xpath_text(html, ".//div"), "release") }) # footnotes --------------------------------------------------------------- test_that("can process footnote with code", { skip_if_no_pandoc("2.17.1") pkg <- local_pkgdown_site() html <- markdown_to_html(pkg, " Hooray[^1] [^1]: Including code: ``` 1 + 2 + ``` And more text ") tweak_footnotes(html) expect_equal(xpath_length(html, "//a[@class='footnote-back']"), 0) expect_equal(xpath_attr(html, ".//a", "class"), "footnote-ref") expect_equal(xpath_attr(html, ".//a", "tabindex"), "0") expect_snapshot(xpath_attr(html, ".//a", "data-bs-content")) }) pkgdown/tests/testthat/test-utils.R0000644000176200001440000000120514634573316017177 0ustar liggesuserstest_that("pkgdown.internet can be set and read", { options(pkgdown.internet = FALSE) expect_false(has_internet()) }) test_that("is_internal_link() works", { pkg=list(meta=list(url="https://pkgdown.r-lib.org")) expect_false(is_internal_link("https://github.com", pkg = pkg)) expect_false(is_internal_link("http://github.com", pkg = pkg)) expect_true(is_internal_link("https://pkgdown.r-lib.org/articles", pkg = pkg)) expect_true(is_internal_link("reference/index.html", pkg = pkg)) expect_true( all.equal( is_internal_link(c("reference/index.html", "https://github.com"), pkg = pkg), c(TRUE, FALSE) ) ) }) pkgdown/tests/testthat/test-topics-external.R0000644000176200001440000000056314633374223021161 0ustar liggesuserstest_that("can get info about external function", { expect_snapshot(str(ext_topics("base::mean"))) # and column names match pkg <- as_pkgdown(test_path("assets/reference")) expect_equal(names(ext_topics("base::mean")), names(pkg$topics)) }) test_that("fails if documentation not available", { expect_snapshot(ext_topics("base::doesntexist"), error = TRUE) }) pkgdown/tests/testthat/test-preview.R0000644000176200001440000000111014634573316017513 0ustar liggesuserstest_that("checks its inputs", { pkg <- local_pkgdown_site() expect_snapshot(error = TRUE, { preview_site(pkg, path = 1) preview_site(pkg, path = "foo") preview_site(pkg, preview = 1) }) }) test_that("local_path adds index.html if needed", { pkg <- local_pkgdown_site() file_create(path(pkg$dst_path, "test.html")) expect_equal( local_path(pkg, "test.html"), path(pkg$dst_path, "test.html") ) dir_create(path(pkg$dst_path, "reference")) expect_equal( local_path(pkg, "reference"), path(pkg$dst_path, "reference", "index.html") ) }) pkgdown/tests/testthat/test-tweak-homepage.R0000644000176200001440000000737114633374223020742 0ustar liggesuserstest_that("first header is wrapped in page-header div", { html <- xml2::read_html('

First

Second

') tweak_homepage_html(html) expect_equal(xpath_attr(html, ".//div", "class"), "page-header") }) test_that("removes dummy page-header", { html <- xml2::read_html('

Header

') tweak_homepage_html(html) expect_equal(xpath_text(html, ".//h1"), "Header") }) test_that("can remove first header", { html <- xml2::read_html('

First

Second

') tweak_homepage_html(html, strip_header = TRUE) expect_equal(xpath_length(html, ".//div"), 0) }) test_that("can remove logo", { # Without link html <- xml2::read_html('

First

') tweak_homepage_html(html, bs_version = 5, logo = "mylogo.png") expect_snapshot(xpath_xml(html, ".//div")) # With link html <- xml2::read_html('

First

') tweak_homepage_html(html, bs_version = 5, logo = "mylogo.png") expect_snapshot(xpath_xml(html, ".//div")) }) # badges ------------------------------------------------------------------- test_that("can move badges to sidebar", { html <- xml2::read_html('

Title

') tweak_sidebar_html(html) expect_snapshot(xpath_xml(html, ".//div")) }) test_that("remove badges even if no dev-status div", { html <- xml2::read_html('

Title

') tweak_sidebar_html(html) expect_snapshot(html) }) test_that("remove dev-status & badges if badges suppress", { html <- xml2::read_html('

Title

') tweak_sidebar_html(html, show_badges = FALSE) expect_equal(xpath_length(html, "//div"), 0) }) test_that("doesn't find badges when they don't exist", { expect_equal(badges_extract_text("

"), character()) expect_equal(badges_extract_text("

"), character()) # first paragraph contains non-image components expect_equal( badges_extract_text('

altHi!

'), character() ) }) test_that("finds single badge", { expect_equal( badges_extract_text('

'), '' ) }) test_that("finds badges in #badges div", { expect_equal( badges_extract_text('

'), '' ) # even if there's extra text expect_equal( badges_extract_text('

Hi!

'), '' ) }) test_that("can find badges in comments", { html <- '

blop

I am the first paragraph!

' expect_equal(badges_extract_text(html), '') # produced by usethis html <- '

blop

I am the first paragraph!

' expect_equal(badges_extract_text(html), '') }) test_that("ignores extraneous content", { html <- '

blop

I am the first paragraph!

a

B

' expect_equal(badges_extract_text(html), '') }) pkgdown/tests/testthat/test-build.R0000644000176200001440000000021214633374223017126 0ustar liggesuserstest_that("both versions of build_site have same arguments", { expect_equal(formals(build_site_local), formals(build_site_external)) }) pkgdown/tests/testthat/test-rd-example.R0000644000176200001440000000571014634573316020102 0ustar liggesusers# run_examples() ----------------------------------------------------------- test_that("warns if unparseable", { expect_warning( run_examples("1 + \\dontrun{2 + }"), "Failed to parse" ) }) # as_example() ------------------------------------------------------------ test_that("dontrun{} wrapped in if(FALSE)", { expect_equal(rd2ex("\\dontrun{1}"), "if (FALSE) 1 # \\dontrun{}") expect_equal( rd2ex("\\dontrun{\n 1\n}"), c("if (FALSE) { # \\dontrun{", " 1", "} # }") ) # unless run_dont_run is true expect_equal(rd2ex("\\dontrun{1}", run_dont_run = TRUE), "1") expect_equal( rd2ex("\\dontrun{\n 1\n}", run_dont_run = TRUE), c("# \\dontrun{", " 1", "# }") ) }) test_that("block donttest{} gets a comment to preserve spacing", { expect_equal(rd2ex("\\donttest{1}"), "1") expect_equal( rd2ex("\\donttest{\n 1\n}"), c("# \\donttest{", " 1", "# }") ) }) test_that("dontshow{} becomes DONTSHOW", { expect_equal(rd2ex("\\dontshow{1}"), "DONTSHOW({1})") expect_equal(rd2ex("\\dontshow{\n 1\n}"), c("DONTSHOW({", " 1", "})")) }) test_that("testonly{} becomes TESTONLY", { expect_equal(rd2ex("\\testonly{1}"), "TESTONLY({1})") expect_equal(rd2ex("\\testonly{\n 1\n}"), c("TESTONLY({", " 1", "})")) }) test_that("handles nested tags", { expect_equal( rd2ex("if(TRUE {\n \\dontrun{\n 1 + 2\n }\n}"), c( "if(TRUE {", " if (FALSE) { # \\dontrun{", " 1 + 2", " } # }", "}" ) ) }) test_that("translate dots and ldots to ...", { expect_equal(rd2ex("\\ldots"), "...") expect_equal(rd2ex("\\dots"), "...") }) test_that("ignores out", { expect_equal(rd2ex("\\out{1 + 2}"), "1 + 2") }) test_that("extracts conditions from if", { expect_equal(rd2ex("\\if{html}{1 + 2}"), "1 + 2") expect_equal(rd2ex("\\if{latex}{1 + 2}"), "") expect_equal(rd2ex("\\ifelse{html}{1 + 2}{3 + 4}"), "1 + 2") expect_equal(rd2ex("\\ifelse{latex}{1 + 2}{3 + 4}"), "3 + 4") }) test_that("@examplesIf", { rd <- paste0( "\\dontshow{if (1 == 0) (if (getRversion() >= \"3.4\") withAutoprint else force)(\\{ # examplesIf}\n", "answer <- 43\n", "\\dontshow{\\}) # examplesIf}" ) exp <- c( "if (FALSE) { # 1 == 0", "answer <- 43", "}" ) expect_warning( expect_equal(rd2ex(rd), exp), "@examplesIf condition" ) rd2 <- paste0( "\\dontshow{if (TRUE) (if (getRversion() >= \"3.4\") withAutoprint else force)(\\{ # examplesIf}\n", "answer <- 43\n", "\\dontshow{\\}) # examplesIf}" ) exp2 <- c( "answer <- 43" ) expect_equal(rd2ex(rd2), exp2) cnd <- paste0(strrep("TRUE && ", 100), "FALSE") rd3 <- paste0( "\\dontshow{if (", cnd, ") (if (getRversion() >= \"3.4\") withAutoprint else force)(\\{ # examplesIf}\n", "answer <- 43\n", "\\dontshow{\\}) # examplesIf}" ) exp3 <- c( paste0("if (FALSE) { # ", cnd), "answer <- 43", "}" ) expect_snapshot( expect_equal(strtrim(rd2ex(rd3), 40), strtrim(exp3, 40)) ) }) pkgdown/tests/testthat/test-usage.R0000644000176200001440000001421314653152407017141 0ustar liggesusers # Reference -------------------------------------------------------------------- test_that("usage escapes special characters", { # parseable expect_equal(usage2text("# <"), "# <") #unparseable expect_equal(usage2text("<"), "<") }) test_that("usage re-renders non-syntactic calls", { expect_equal(usage2text("`<`(x, y)"), "x < y") expect_equal(usage2text("`[`(x, y)"), "x[y]") }) test_that("usage doesn't re-renders syntactic calls", { expect_equal(usage2text("foo(x , y) # hi"), "foo(x , y) # hi") multi_line <- "foo(\n x # x,\n y = 1 # y,\n)" expect_equal(usage2text(multi_line), multi_line) }) test_that("usage generates user facing code for S3/S4 infix/replacement methods", { expect_snapshot({ cat(usage2text("\\S3method{$}{indexed_frame}(x, name)")) cat(usage2text("\\method{[[}{indexed_frame}(x, i) <- value")) cat(usage2text("\\S4method{>=}{MyType,numeric}(e1, e2)")) }) }) test_that("S4 methods gets comment", { out <- rd2html("\\S4method{fun}{class}(x, y)") expect_equal(out[1], "# S4 method for class 'class'") expect_equal(out[2], "fun(x, y)") }) test_that("S3 methods gets comment", { out <- rd2html("\\S3method{fun}{class}(x, y)") expect_equal(out[1], "# S3 method for class 'class'") expect_equal(out[2], "fun(x, y)") out <- rd2html("\\method{fun}{class}(x, y)") expect_equal(out[1], "# S3 method for class 'class'") expect_equal(out[2], "fun(x, y)") }) test_that("Methods for class function work", { out <- rd2html("\\S3method{fun}{function}(x, y)") expect_equal(out[1], "# S3 method for class 'function'") expect_equal(out[2], "fun(x, y)") out <- rd2html("\\method{fun}{function}(x, y)") expect_equal(out[1], "# S3 method for class 'function'") expect_equal(out[2], "fun(x, y)") out <- rd2html("\\S4method{fun}{function,function}(x, y)") expect_equal(out[1], "# S4 method for class 'function,function'") expect_equal(out[2], "fun(x, y)") }) test_that("default methods get custom text", { out <- rd2html("\\S3method{fun}{default}(x, y)") expect_equal(out[1], "# Default S3 method") out <- rd2html("\\S4method{fun}{default}(x, y)") expect_equal(out[1], "# Default S4 method") }) test_that("non-syntactic functions get backquoted, not escaped", { out <- rd2html("\\S3method{<}{foo}(x, y)") expect_equal(out[[2]], "`<`(x, y)") out <- rd2html("\\S4method{bar<-}{foo}(x, y)") expect_equal(out[[2]], "`bar<-`(x, y)") }) # Reference index -------------------------------------------------------------- test_that("can parse data", { usage <- parse_usage("f")[[1]] expect_equal(usage, list(type = "data", name = "f")) usage <- parse_usage("data(f)")[[1]] expect_equal(usage, list(type = "data", name = "f")) }) test_that("can parse function/methods", { usage <- parse_usage("f(x)")[[1]] expect_equal(usage$type, "fun") expect_equal(usage$name, "f") usage <- parse_usage("\\method{f}{bar}(x)")[[1]] expect_equal(usage$type, "s3") expect_equal(usage$name, "f") expect_equal(usage$signature, "bar") usage <- parse_usage("\\S3method{f}{bar}(x)")[[1]] expect_equal(usage$type, "s3") expect_equal(usage$name, "f") expect_equal(usage$signature, "bar") usage <- parse_usage("\\S3method{f}{`foo bar`}(x)")[[1]] expect_equal(usage$type, "s3") expect_equal(usage$name, "f") expect_equal(usage$signature, "foo bar") usage <- parse_usage("\\S4method{f}{bar,baz}(x)")[[1]] expect_equal(usage$type, "s4") expect_equal(usage$name, "f") expect_equal(usage$signature, c("bar", "baz")) usage <- parse_usage("\\S4method{f}{NULL}(x)")[[1]] expect_equal(usage$type, "s4") expect_equal(usage$name, "f") expect_equal(usage$signature, c("NULL")) usage <- parse_usage("\\S4method{f}{function,function}(x, y)")[[1]] expect_equal(usage$type, "s4") expect_equal(usage$name, "f") expect_equal(usage$signature, c("function", "function")) usage <- parse_usage("\\S4method{f}{function,foo bar}(x, y)")[[1]] expect_equal(usage$type, "s4") expect_equal(usage$name, "f") expect_equal(usage$signature, c("function", "foo bar")) usage <- parse_usage("pkg::func()")[[1]] expect_equal(usage$type, "fun") expect_equal(usage$name, "func") usage <- parse_usage("pkg:::func()")[[1]] expect_equal(usage$type, "fun") expect_equal(usage$name, "func") }) test_that("can parse replacement functions", { usage <- parse_usage("f() <- value")[[1]] expect_true(usage$replacement) expect_equal(usage$name, "f<-") usage <- parse_usage("\\S3method{f}{bar}(x) <- value")[[1]] expect_true(usage$replacement) expect_equal(usage$name, "f<-") usage <- parse_usage("\\S4method{f}{bar,baz}(x) <- value")[[1]] expect_true(usage$replacement) expect_equal(usage$name, "f<-") }) test_that("can parse infix functions", { usage <- parse_usage("x \\%f\\% y")[[1]] expect_true(usage$infix) expect_equal(usage$name, "%f%") usage <- parse_usage("\\S3method{[}{bar}(x)")[[1]] expect_true(usage$infix) expect_equal(usage$name, "[") usage <- parse_usage("\\S4method{[}{bar,baz}(x)")[[1]] expect_true(usage$infix) expect_equal(usage$name, "[") }) test_that("can parse infix replacement functions", { usage <- parse_usage("\\S3method{[}{bar}(x) <- value")[[1]] expect_true(usage$infix) expect_true(usage$replacement) expect_equal(usage$name, "[<-") usage <- parse_usage("\\S4method{[}{bar,baz}(x) <- value")[[1]] expect_true(usage$infix) expect_true(usage$replacement) expect_equal(usage$name, "[<-") }) test_that("can parse multistatement usages", { usage <- parse_usage("f()\n%This is a comment\ng(\n\n)") expect_length(usage, 2) expect_equal(usage[[1]]$name, "f") expect_equal(usage[[2]]$name, "g") }) test_that("can parse dots", { usage <- parse_usage("f(\\dots)")[[1]] expect_equal(usage$name, "f") }) test_that("usage2text can parse symbols (#2727)", { expect_no_error(usage2text("viridisLite::viridis(21)")) }) # short_name -------------------------------------------------------------- test_that("infix functions left as", { expect_equal(short_name("%||%", "fun"), "`%||%`") }) test_that("function name and signature is escaped", { expect_equal(short_name("%<%", "fun"), "`%<%`") expect_equal(short_name("f", "S3", "<"), "f(<<>)") }) pkgdown/tests/testthat/test-rd-html.R0000644000176200001440000003043414671042466017412 0ustar liggesuserstest_that("special characters are escaped", { out <- rd2html("a & b") expect_equal(out, "a & b") }) test_that("converts Rd unicode shortcuts", { expect_snapshot(rd2html("``a -- b --- c''")) }) test_that("simple tags translated to known good values", { # Simple insertions expect_equal(rd2html("\\ldots"), "...") expect_equal(rd2html("\\dots"), "...") expect_equal(rd2html("\\R"), "R") expect_equal(rd2html("\\cr"), "
") "Macros" expect_equal(rd2html("\\newcommand{\\f}{'f'} \\f{}"), "'f'") expect_equal(rd2html("\\renewcommand{\\f}{'f'} \\f{}"), "'f'") }) test_that("comments converted to html", { expect_equal(rd2html("a\n%b\nc"), c("a", "", "c")) }) test_that("simple wrappers work as expected", { expect_equal(rd2html("\\strong{x}"), "x") expect_equal(rd2html("\\strong{\\emph{x}}"), "x") }) test_that("subsection generates h3", { expect_snapshot(cli::cat_line(rd2html("\\subsection{A}{B}"))) }) test_that("subsection generates h3", { expect_snapshot(cli::cat_line(rd2html("\\subsection{A}{ p1 p2 }"))) }) test_that("subsection generates generated anchor", { text <- c("", rd2html("\\subsection{A}{B}"), "") html <- xml2::read_xml(paste0(text, collapse = "\n")) tweak_anchors(html) expect_equal(xpath_attr(html, ".//h3", "id"), "a") expect_equal(xpath_attr(html, ".//a", "href"), "#a") }) test_that("nested subsection generates h4", { expect_snapshot(cli::cat_line(rd2html("\\subsection{H3}{\\subsection{H4}{}}"))) }) test_that("if generates html", { expect_equal(rd2html("\\if{html}{\\bold{a}}"), "a") expect_equal(rd2html("\\if{latex}{\\bold{a}}"), character()) }) test_that("ifelse generates html", { expect_equal(rd2html("\\ifelse{html}{\\bold{a}}{x}"), "a") expect_equal(rd2html("\\ifelse{latex}{x}{\\bold{a}}"), "a") }) test_that("out is for raw html", { expect_equal(rd2html("\\out{
}"), "
") }) test_that("support platform specific code", { os_specific <- function(command, os, output) { rd2html(paste0( "#", command, " ", os, "\n", output, "\n", "#endif" )) } expect_equal(os_specific("ifdef", "windows", "X"), character()) expect_equal(os_specific("ifdef", "unix", "X"), "X") expect_equal(os_specific("ifndef", "windows", "X"), "X") expect_equal(os_specific("ifndef", "unix", "X"), character()) }) # tables ------------------------------------------------------------------ test_that("tabular generates complete table html", { table <- "\\tabular{ll}{a \\tab b \\cr}" expectation <- c("", "", "
ab
") expect_equal(rd2html(table), expectation) }) test_that("internal \\crs are stripped", { table <- "\\tabular{l}{a \\cr b \\cr c \\cr}" expectation <- c("", "", "", "", "
a
b
c
") expect_equal(rd2html(table), expectation) }) test_that("can convert single row", { expect_equal( rd2html("\\tabular{lll}{A \\tab B \\tab C \\cr}")[[2]], "ABC" ) }) test_that("don't need internal whitespace", { expect_equal( rd2html("\\tabular{lll}{\\tab\\tab C\\cr}")[[2]], "C" ) expect_equal( rd2html("\\tabular{lll}{\\tab B \\tab\\cr}")[[2]], "B" ) expect_equal( rd2html("\\tabular{lll}{A\\tab\\tab\\cr}")[[2]], "A" ) expect_equal( rd2html("\\tabular{lll}{\\tab\\tab\\cr}")[[2]], "" ) }) test_that("can skip trailing \\cr", { expect_equal( rd2html("\\tabular{lll}{A \\tab B \\tab C}")[[2]], "ABC" ) }) test_that("code blocks in tables render (#978)", { expect_equal( rd2html('\\tabular{ll}{a \\tab \\code{b} \\cr foo \\tab bar}')[[2]], "ab" ) }) test_that("tables with tailing \n (#978)", { expect_equal( rd2html(' \\tabular{ll}{ a \\tab \\cr foo \\tab bar } ')[[2]], "a" ) }) # sexpr ------------------------------------------------------------------ test_that("code inside Sexpr is evaluated", { local_context_eval() expect_equal(rd2html("\\Sexpr{1 + 2}"), "3") }) test_that("can control \\Sexpr output", { local_context_eval() expect_equal(rd2html("\\Sexpr[results=hide]{1}"), character()) expect_equal(rd2html("\\Sexpr[results=text]{1}"), "1") expect_equal(rd2html("\\Sexpr[results=rd]{\"\\\\\\emph{x}\"}"), "x") expect_equal( rd2html("\\Sexpr[results=verbatim]{1 + 2}"), c("
", "[1] 3", "
") ) expect_equal( rd2html("\\Sexpr[results=verbatim]{cat(42)}"), c("
", "42", "
") ) expect_equal( rd2html("\\Sexpr[results=verbatim]{cat('42!\n'); 3}"), c("
", "42!", "[1] 3", "
") ) }) test_that("Sexpr can contain multiple expressions", { local_context_eval() expect_equal(rd2html("\\Sexpr{a <- 1; a}"), "1") }) test_that("Sexprs with multiple args are parsed", { local_context_eval() expect_equal(rd2html("\\Sexpr[results=hide,stage=build]{1}"), character()) }) test_that("Sexprs in file share environment", { local_context_eval() expect_equal(rd2html("\\Sexpr{x <- 1}\\Sexpr{x}"), c("1", "1")) local_context_eval() expect_error(rd2html("\\Sexpr{x}"), "not found") }) test_that("Sexprs run from package root", { local_context_eval(src_path = test_path("assets/reference")) # \packageTitle is built in macro that uses DESCRIPTION expect_equal( rd2html("\\packageTitle{testpackage}"), "A test package" ) }) # links ------------------------------------------------------------------- test_that("simple links generate ", { expect_equal( rd2html("\\href{http://bar.com}{BAR}"), "BAR" ) expect_equal( rd2html("\\email{foo@bar.com}"), "foo@bar.com" ) expect_equal( rd2html("\\url{http://bar.com}"), "http://bar.com" ) }) test_that("can convert cross links to online documentation url", { expect_equal( rd2html("\\link[base]{library}"), a("library", href = "https://rdrr.io/r/base/library.html") ) }) test_that("can convert cross links to the same package (#242)", { withr::local_options(list( "downlit.package" = "test", "downlit.topic_index" = c(x = "y", z = "z"), "downlit.rdname" = "z" )) expect_equal(rd2html("\\link{x}"), "x") expect_equal(rd2html("\\link[test]{x}"), "x") # but no self links expect_equal(rd2html("\\link[test]{z}"), "z") }) test_that("can parse local links with topic!=label", { withr::local_options(list( "downlit.topic_index" = c(x = "y") )) expect_equal(rd2html("\\link[=x]{z}"), "z") }) test_that("functions in other packages generates link to rdrr.io", { withr::local_options(list( "downlit.package" = "test", "downlit.topic_index" = c(x = "y", z = "z") )) expect_equal( rd2html("\\link[stats:acf]{xyz}"), a("xyz", downlit::href_topic("acf", "stats")) ) # Unless it's the current package expect_equal(rd2html("\\link[test:x]{xyz}"), "xyz") }) test_that("link to non-existing functions return label", { expect_equal(rd2html("\\link[xyzxyz:xyzxyz]{abc}"), "abc") expect_equal(rd2html("\\link[base:xyzxyz]{abc}"), "abc") }) test_that("code blocks autolinked to vignettes", { withr::local_options(list( "downlit.package" = "test", "downlit.article_index" = c("abc" = "abc.html") )) expect_equal( rd2html("\\code{vignette('abc')}"), "vignette('abc')" ) }) test_that("link to non-existing functions return label", { withr::local_options(list( "downlit.package" = "test", "downlit.topic_index" = c("TEST-class" = "test") )) expect_equal(rd2html("\\linkS4class{TEST}"), "TEST") }) test_that("bad specs throw errors", { expect_snapshot(error = TRUE, { rd2html("\\url{}") rd2html("\\url{a\nb}") rd2html("\\email{}") rd2html("\\linkS4class{}") }) }) # Paragraphs -------------------------------------------------------------- test_that("empty input gives empty output", { expect_equal(flatten_para(character()), character()) }) test_that("empty lines break paragraphs", { expect_equal( flatten_para(rd_text("a\nb\n\nc")), "

a\nb

\n

c

" ) }) test_that("indented empty lines break paragraphs", { expect_equal( flatten_para(rd_text("a\nb\n \nc")), "

a\nb

\n

c

" ) }) test_that("block tags break paragraphs", { out <- flatten_para(rd_text("a\n\\itemize{\\item b}\nc")) expect_equal(out, "

a

c

") }) test_that("inline tags + empty line breaks", { out <- flatten_para(rd_text("a\n\n\\code{b}")) expect_equal(out, "

a

\n

b

") }) test_that("single item can have multiple paragraphs", { out <- flatten_para(rd_text("\\itemize{\\item a\n\nb}")) expect_equal(out, "\n") }) test_that("nl after tag doesn't trigger paragraphs", { out <- flatten_para(rd_text("One \\code{}\nTwo")) expect_equal(out, "

One \nTwo

") }) test_that("cr generates line break", { out <- flatten_para(rd_text("a \\cr b")) expect_equal(out, "

a
b

") }) # lists ------------------------------------------------------------------- test_that("simple lists work", { expect_equal( rd2html("\\itemize{\\item a}"), c("") ) expect_equal( rd2html("\\enumerate{\\item a}"), c("
    ", "
  1. a

  2. ", "
") ) }) test_that("\\describe items can contain multiple paragraphs", { out <- rd2html("\\describe{ \\item{Label 1}{Contents 1} \\item{Label 2}{Contents 2} }") expect_snapshot_output(cat(out, sep = "\n")) }) test_that("can add ids to descriptions", { out <- rd2html("\\describe{ \\item{abc}{Contents 1} \\item{xyz}{Contents 2} }", id_prefix = "foo") expect_snapshot_output(cat(out, sep = "\n")) }) test_that("\\describe items can contain multiple paragraphs", { out <- rd2html("\\describe{ \\item{Label}{ Paragraph 1 Paragraph 2 } }") expect_snapshot_output(cat(out, sep = "\n")) }) test_that("nested item with whitespace parsed correctly", { out <- rd2html(" \\describe{ \\item{Label}{ This text is indented in a way pkgdown doesn't like. }}") expect_snapshot_output(cat(out, sep = "\n")) }) # Verbatim ---------------------------------------------------------------- test_that("preformatted blocks aren't double escaped", { out <- flatten_para(rd_text("\\preformatted{\\%>\\%}")) expect_equal(out, "
%>%
\n") }) test_that("newlines are preserved in preformatted blocks", { out <- flatten_para(rd_text("\\preformatted{^\n\nb\n\nc}")) expect_equal(out, "
^\n\nb\n\nc
\n") }) test_that("spaces are preserved in preformatted blocks", { out <- flatten_para(rd_text("\\preformatted{^\n\n b\n\n c}")) expect_equal(out, "
^\n\n  b\n\n  c
\n") }) # Other ------------------------------------------------------------------- test_that("eqn", { out <- rd2html(" \\eqn{\\alpha}{alpha}") expect_equal(out, "\\(\\alpha\\)") out <- rd2html(" \\eqn{x}") expect_equal(out, "\\(x\\)") }) test_that("deqn", { out <- rd2html(" \\deqn{\\alpha}{alpha}") expect_equal(out, "$$\\alpha$$") out <- rd2html(" \\deqn{x}") expect_equal(out, "$$x$$") }) test_that("special", { out <- rd2html("\\special{( \\dots )}") expect_equal(out, "( ... )") }) # figures ----------------------------------------------------------------- test_that("figures are converted to img", { expect_equal(rd2html("\\figure{a}"), "") expect_equal(rd2html("\\figure{a}{b}"), "b") expect_equal( rd2html("\\figure{a}{options: height=1}"), "" ) }) test_that("figures with multilines alternative text can be parsed", { expect_equal(rd2html("\\figure{a}{blabla blop}"), "blabla blop") }) pkgdown/tests/testthat/test-pkgdown_print.R0000644000176200001440000000143214633374223020721 0ustar liggesuserstest_that("widgets and browseable html are kept as is", { widget <- htmlwidgets::createWidget("test", list()) expect_s3_class(pkgdown_print(widget), "htmlwidget") html <- htmltools::browsable(htmltools::div("foo")) expect_s3_class(pkgdown_print(html), "shiny.tag") }) test_that("htmlwidgets get sized", { local_context_eval(list(fig.width = 7, dpi = 100, fig.asp = 1)) widget <- htmlwidgets::createWidget("test", list()) value <- pkgdown_print(widget) expect_equal(value$width, 700) expect_equal(value$height, 700) }) test_that("respect htmlwidgets width", { local_context_eval(list(fig.width = 7, dpi = 100, fig.asp = 1)) widget <- htmlwidgets::createWidget("test", list(), width = "100px") value <- pkgdown_print(widget) expect_equal(value$width, "100px") }) pkgdown/tests/testthat/test-navbar-menu.R0000644000176200001440000000671114633374223020254 0ustar liggesuserstest_that("can construct menu with children", { menu <- menu_submenu( "Title", list( menu_heading("Heading"), menu_separator(), menu_link("Link", "https://example.com") ) ) expect_snapshot(cat(navbar_html(menu))) }) test_that("bad inputs give clear error", { submenu <- menu_submenu( "Title", list( menu_submenu("Heading", list(menu_heading("Hi"))) ) ) expect_snapshot(error = TRUE, { navbar_html(1) navbar_html(list(foo = 1)) navbar_html(submenu) }) }) test_that("can construct bullets", { expect_snapshot({ cat(navbar_html(menu_icon("fa-question", "https://example.com", "label"))) cat(navbar_html(menu_heading("Hi"))) cat(navbar_html(menu_link("Hi", "https://example.com"))) }) }) test_that("bullet class varies based on depth", { expect_equal( navbar_html(menu_separator(), menu_depth = 0), '' ) expect_equal( navbar_html(menu_separator(), menu_depth = 1), '
  • ' ) }) test_that("icons warn if no aria-label", { reset_message_verbosity("icon-aria-label") expect_snapshot({ . <- navbar_html(menu_icon("fa-question", "https://example.com", NULL)) }) }) test_that("icons extract base iconset class automatically", { expect_match( navbar_html(menu_icon("fa-question", "https://example.com", "label")), 'class="fa fa-question"', fixed = TRUE ) expect_match( navbar_html(menu_icon("fab fab-github", "https://example.com", "label")), 'class="fab fab-github"', fixed = TRUE ) }) test_that("can specify link target", { expect_match( navbar_html(menu_link("a", "b", target = "_blank")), 'target="_blank"', fixed = TRUE ) }) test_that("can construct theme menu", { pkg <- local_pkgdown_site(meta = list(template = list(bootstrap = 5, `light-switch` = TRUE))) lightswitch <- navbar_components(pkg)$lightswitch expect_snapshot(cat(navbar_html(lightswitch))) }) test_that("simple components don't change without warning", { expect_snapshot({ cat(navbar_html(menu_heading("a"))) cat(navbar_html(menu_link("a", "b"))) cat(navbar_html(menu_separator())) cat(navbar_html(menu_search())) }) }) # Building blocks ----------------------------------------------------------- test_that("navbar_html_text() combines icons and text", { expect_equal(navbar_html_text(list(text = "a")), 'a') expect_equal( navbar_html_text(list(icon = "fas-github", `aria-label` = "github")), '' ) expect_equal( navbar_html_text(list(text = "a", icon = "fas-github", `aria-label` = "github")), ' a' ) }) test_that("navbar_html_text() escapes text", { expect_equal(navbar_html_text(list(text = "<>")), '<>') }) test_that("named arguments become attributes", { expect_equal(html_tag("a"), '') expect_equal(html_tag("a", x = NULL), '') expect_equal(html_tag("a", x = NA), '') expect_equal(html_tag("a", x = 1), '') }) test_that("unnamed arguments become children", { expect_equal(html_tag("a", "b"), 'b') expect_equal(html_tag("a", "b", NULL), 'b') }) test_that("class components are pasted together", { expect_equal(html_tag("a", class = NULL), '') expect_equal(html_tag("a", class = "a"), '') expect_equal(html_tag("a", class = c("a", "b")), '') }) pkgdown/tests/testthat/test-topics.R0000644000176200001440000001506114633374223017340 0ustar liggesusersselect_topics_ <- function(topic, topics, check = TRUE) { pkg <- local_pkgdown_site() select_topics( topic, topics, check = check, error_path = "reference[1].contents", error_pkg = pkg ) } test_that("bad inputs give informative warnings", { topics <- tibble::tribble( ~name, ~alias, ~internal, ~concepts, "x", c("x", "x1"), FALSE, character(), ) expect_snapshot(error = TRUE, { select_topics_("x + ", topics) select_topics_("y", topics) select_topics_("paste(1)", topics) select_topics_("starts_with", topics) select_topics_("1", topics) select_topics_("starts_with('y')", topics) }) }) test_that("selector functions validate their inputs", { topics <- tibble::tribble( ~name, ~alias, ~internal, ~concepts, "x", c("x", "x1"), FALSE, character(), ) expect_snapshot(error = TRUE, { select_topics_("starts_with('x', 'y')", topics) select_topics_("starts_with(c('x', 'y'))", topics) }) }) test_that("empty input returns empty vector", { topics <- tibble::tribble( ~name, ~alias, ~internal, ~concepts, "x", c("x", "x1"), FALSE, character(), ) expect_equal(select_topics(character(), topics), integer()) }) test_that("can select by name or alias", { topics <- tibble::tribble( ~name, ~alias, "x", c("a1", "a2"), "a", c("a3"), "a-b", "b-a", "c::d", "d", ) expect_equal(select_topics_("x", topics), 1) expect_equal(select_topics_("'x'", topics), 1) expect_equal(select_topics_("a1", topics), 1) expect_equal(select_topics_("a2", topics), 1) expect_equal(select_topics_("c::d", topics), 4) # Even if name is non-syntactic expect_equal(select_topics_("a-b", topics), 3) expect_equal(select_topics_("b-a", topics), 3) # Or missing expect_snapshot(error = TRUE, { select_topics_("a4", topics) select_topics_("c::a", topics) }) }) test_that("selection preserves original order", { topics <- tibble::tribble( ~name, ~alias, "x", c("a1", "a2"), "a", c("a3"), "b", "b1" ) expect_equal(select_topics_(c("a", "b1", "x"), topics), c(2, 3, 1)) }) test_that("can select by name", { topics <- tibble::tribble( ~name, ~alias, ~internal, "a", "a", FALSE, "b1", "b1", FALSE, "b2", "b2", FALSE, "b3", "b3", TRUE, ) topics$alias <- as.list(topics$alias) expect_equal(select_topics_("starts_with('a')", topics), 1) expect_equal(select_topics_("ends_with('a')", topics), 1) expect_equal(select_topics_("contains('a')", topics), 1) expect_equal(select_topics_("matches('[a]')", topics), 1) # Match internal when requested expect_equal(select_topics_("starts_with('b')", topics), c(2, 3)) expect_equal(select_topics_("starts_with('b', internal = TRUE)", topics), 2:4) }) test_that("can select by presense or absence of concept", { topics <- tibble::tribble( ~name, ~alias, ~internal, ~concepts, "b1", "b1", FALSE, "a", "b2", "b2", FALSE, c("a", "b"), "b3", "b3", FALSE, character() ) topics$alias <- as.list(topics$alias) expect_equal(select_topics_("has_concept('a')", topics), c(1, 2)) expect_equal(select_topics_("lacks_concept('b')", topics), c(1, 3)) expect_equal(select_topics_("lacks_concepts(c('a', 'b'))", topics), 3) }) test_that("can select by keyword", { topics <- tibble::tribble( ~name, ~alias, ~internal, ~keywords, "b1", "b1", FALSE, "a", "b2", "b2", FALSE, c("a", "b"), ) topics$alias <- as.list(topics$alias) expect_equal(select_topics_("has_keyword('a')", topics), c(1, 2)) expect_equal(select_topics_("has_keyword('b')", topics), c(2)) expect_equal(select_topics_("has_keyword('c')", topics, check = FALSE), integer()) }) test_that("can select by lifecycle", { topics <- tibble::tribble( ~name, ~alias, ~internal, ~keywords, ~lifecycle, "b1", "b1", FALSE, "a", list("stable"), "b2", "b2", FALSE, c("a", "b"), NULL ) expect_equal(select_topics_("has_lifecycle('stable')", topics), 1) expect_equal(select_topics_("has_lifecycle('deprecated')", topics, check = FALSE), integer()) }) test_that("can combine positive and negative selections", { topics <- tibble::tribble( ~name, ~alias, ~internal, "x", c("a1", "a2"), FALSE, "a", c("a3"), FALSE, "b", "b1", FALSE, "d", "d", TRUE, ) expect_equal(select_topics_("-x", topics), c(2, 3)) expect_equal(select_topics_(c("-x", "-a"), topics), 3) expect_equal(select_topics_(c("-x", "x"), topics), c(2, 3, 1)) expect_equal(select_topics_(c("a", "x", "-a"), topics), 1) expect_snapshot(select_topics_("c(a, -x)", topics), error = TRUE) }) test_that("an unmatched selection generates a warning", { topics <- tibble::tribble( ~name, ~alias, ~internal, "x", c("a1", "a2"), FALSE, "a", c("a3"), FALSE, "b", "b1", FALSE, "d", "d", TRUE, ) expect_snapshot(error = TRUE, select_topics_(c("a", "starts_with('unmatched')"), topics), ) }) test_that("uses funs or aliases", { pkg <- local_pkgdown_site() pkg$topics <- tibble::tribble( ~name, ~funs, ~alias, ~file_out, ~title, ~lifecycle, "x", character(), c("x1", "x2"), "x.html", "X", NULL, "y", c("y1", "y2"), "y3", "y.html", "Y", NULL ) out <- section_topics(pkg, c("x", "y"), error_path = "reference[1].contents") expect_equal(out$aliases, list(c("x1", "x2"), c("y1", "y2"))) }) test_that("full topic selection process works", { pkg <- local_pkgdown_site(test_path("assets/reference")) # can mix local and remote out <- section_topics( pkg, c("a", "base::mean"), error_path = "reference[1].contents" ) expect_equal(unname(out$name), c("a", "base::mean")) # concepts and keywords work out <- section_topics( pkg, c("has_concept('graphics')", "has_keyword('foo')"), error_path = "reference[1].contents" ) expect_equal(unname(out$name), c("b", "a")) }) test_that("an unmatched selection with a matched selection does not select everything", { topics <- tibble::tribble( ~name, ~alias, ~internal, "x", c("a1", "a2"), FALSE, "a", c("a3"), FALSE, "b", "b1", FALSE, "d", "d", TRUE, ) expect_equal( select_topics_(c("a", "starts_with('unmatched')"), topics, check = FALSE), 2 ) expect_equal( select_topics_(c("starts_with('unmatched')", "a"), topics, check = FALSE), 2 ) }) pkgdown/tests/testthat/test-build-tutorials.R0000644000176200001440000000257214634573316021172 0ustar liggesuserstest_that("can autodetect tutorials", { pkg <- local_pkgdown_site() base_path <- "vignettes/tutorials/test-1" pkg <- pkg_add_file(pkg, path(base_path, "test-1.Rmd"), c( '---', 'title: "Tutorial"', 'output: learnr::tutorial', 'runtime: shiny_prerendered', '---' )) path <- path(base_path, "rsconnect/documents/test-1.Rmd/shinyapps.io/hadley/tutorial-test-1.dcf") pkg <- pkg_add_file(pkg, path, c( "name: tutorial-test-1", "title: tutorial-test-1", "hostUrl: https://api.shinyapps.io/v1", "when: 1521734722.72611", "url: https://hadley.shinyapps.io/tutorial-test-1/" )) out <- package_tutorials(pkg$src_path) expect_equal(out$name, "test-1") expect_equal(out$file_out, "tutorials/test-1.html") expect_equal(out$url, "https://hadley.shinyapps.io/tutorial-test-1/") # and aren't included in vignettes out <- package_vignettes(pkg$src_path) expect_equal(nrow(out), 0) }) test_that("can manually supply tutorials", { meta <- list( tutorials = list( list(name = "1-name", title = "1-title", url = "1-url"), list(name = "2-name", title = "2-title", url = "2-url") ) ) pkg <- local_pkgdown_site() out <- package_tutorials(pkg, meta) expect_equal(out$name, c("1-name", "2-name")) expect_equal(out$file_out, c("tutorials/1-name.html", "tutorials/2-name.html")) expect_equal(out$url, c("1-url", "2-url")) }) pkgdown/tests/testthat/test-check.R0000644000176200001440000000410014634573316017111 0ustar liggesuserstest_that("sitrep complains about BS3", { pkg <- local_pkgdown_site( meta = list( template = list(bootstrap = 3), url = "https://example.com" ), desc = list(URL = "https://example.com") ) expect_snapshot(pkgdown_sitrep(pkg)) }) test_that("sitrep reports all problems", { pkg <- local_pkgdown_site( test_path("assets/reference"), list(reference = list( list(title = "Title", contents = c("a", "b", "c", "e")) )) ) expect_snapshot(pkgdown_sitrep(pkg)) }) test_that("checks fails on first problem", { pkg <- local_pkgdown_site( test_path("assets/reference"), list(reference = list( list(title = "Title", contents = c("a", "b", "c", "e")) )) ) expect_snapshot(check_pkgdown(pkg), error = TRUE) }) test_that("both inform if everything is ok", { pkg <- local_pkgdown_site( meta = list(url = "https://example.com"), desc = list(URL = "https://example.com") ) expect_snapshot({ pkgdown_sitrep(pkg) check_pkgdown(pkg) }) }) # check urls ------------------------------------------------------------------ test_that("check_urls reports problems", { # URL not in the pkgdown config pkg <- local_pkgdown_site() expect_snapshot(check_urls(pkg), error = TRUE) # URL only in the pkgdown config pkg <- local_pkgdown_site(meta = list(url = "https://testpackage.r-lib.org")) expect_snapshot(check_urls(pkg), error = TRUE) }) # check favicons -------------------------------------------------------------- test_that("check_favicons reports problems", { pkg <- local_pkgdown_site() # no logo no problems expect_no_error(check_favicons(pkg)) # logo but no favicons file_touch(path(pkg$src_path, "logo.svg")) expect_snapshot(check_favicons(pkg), error = TRUE) # logo and old favicons dir_create(path_favicons(pkg)) file_touch(path(path_favicons(pkg), "favicon.ico"), Sys.time() - 86400) expect_snapshot(check_favicons(pkg), error = TRUE) # logo and new favicons file_touch(path(path_favicons(pkg), "favicon.ico"), Sys.time() + 86400) expect_no_error(check_favicons(pkg)) }) pkgdown/tests/testthat/test-utils-fs.R0000644000176200001440000000106214633374223017601 0ustar liggesuserstest_that("missing template package yields custom error", { expect_snapshot(path_package_pkgdown("x", "missing", 3), error = TRUE) }) test_that("out_of_date works as expected", { temp1 <- file_create(withr::local_tempfile()) expect_true(out_of_date(temp1, "doesntexist")) expect_snapshot(out_of_date("doesntexist", temp1), error = TRUE) temp2 <- file_create(withr::local_tempfile()) file_touch(temp2, Sys.time() + 10) expect_true(out_of_date(temp2, temp1)) expect_false(out_of_date(temp1, temp2)) expect_false(out_of_date(temp1, temp1)) }) pkgdown/tests/testthat/test-theme.R0000644000176200001440000000220114634573316017136 0ustar liggesuserstest_that("check_bslib_theme() works", { pkg <- local_pkgdown_site() expect_equal(check_bslib_theme("default", pkg, bs_version = 4), "default") expect_equal(check_bslib_theme("lux", pkg, bs_version = 4), "lux") expect_snapshot(error = TRUE, { check_bslib_theme("paper", pkg, bs_version = 4) }) }) test_that("get_bslib_theme() works with template.bslib.preset", { pkg <- local_pkgdown_site( meta = list( template = list(bslib = list(preset = "shiny"), bootstrap = 5) ) ) expect_equal(get_bslib_theme(pkg), "shiny") expect_no_error(bs_theme(pkg)) pkg <- local_pkgdown_site( meta = list( template = list(bslib = list(preset = "lux"), bootstrap = 5) ) ) expect_equal(get_bslib_theme(pkg), "lux") expect_no_error(bs_theme(pkg)) }) test_that("validations yaml specification", { build_bslib_ <- function(...) { pkg <- local_pkgdown_site( meta = list(template = list(..., bootstrap = 5, `light-switch` = TRUE)) ) build_bslib(pkg) } expect_snapshot(error = TRUE, { build_bslib_(theme = 1) build_bslib_(theme = "fruit") build_bslib_(`theme-dark` = "fruit") }) }) pkgdown/tests/testthat/assets/0000755000176200001440000000000014672347601016241 5ustar liggesuserspkgdown/tests/testthat/assets/reference/0000755000176200001440000000000014672377072020204 5ustar liggesuserspkgdown/tests/testthat/assets/reference/R/0000755000176200001440000000000014633374223020375 5ustar liggesuserspkgdown/tests/testthat/assets/reference/R/funs.R0000644000176200001440000000070314633374223021473 0ustar liggesusers#' A #' @export #' @keywords foo #' @param a a letter #' @param b a a number #' @param c a logical a <- function(a, b, c) {} #' B #' @export #' @concept graphics b <- function() {} #' C #' @export c <- function() {} #' D #' @usage #' \special{?topic} #' @export `?` <- function() {} #' E #' @name e NULL #' F #' @keywords internal #' @examples #' testpackage:::f() f <- function() {runif(5L)} #' g <-> h #' @keywords internal g <- function() 1 pkgdown/tests/testthat/assets/reference/_pkgdown.yml0000644000176200001440000000005714633374223022531 0ustar liggesusersurl: http://test.org template: bootstrap: 5 pkgdown/tests/testthat/assets/reference/NAMESPACE0000644000176200001440000000013014151774277021415 0ustar liggesusers# Generated by roxygen2: do not edit by hand export("?") export(a) export(b) export(c) pkgdown/tests/testthat/assets/reference/man/0000755000176200001440000000000014633374223020747 5ustar liggesuserspkgdown/tests/testthat/assets/reference/man/a.Rd0000644000176200001440000000036314633374223021460 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/funs.R \name{a} \alias{a} \title{A} \usage{ a(a, b, c) } \arguments{ \item{a}{a letter} \item{b}{a a number} \item{c}{a logical} } \description{ A } \keyword{foo} pkgdown/tests/testthat/assets/reference/man/f.Rd0000644000176200001440000000030414633374223021460 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/funs.R \name{f} \alias{f} \title{F} \usage{ f() } \description{ F } \examples{ testpackage:::f() } \keyword{internal} pkgdown/tests/testthat/assets/reference/man/e.Rd0000644000176200001440000000020414633374223021456 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/funs.R \name{e} \alias{e} \title{E} \description{ E } pkgdown/tests/testthat/assets/reference/man/g.Rd0000644000176200001440000000026114633374223021463 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/funs.R \name{g} \alias{g} \title{g <-> h} \usage{ g() } \description{ g <-> h } \keyword{internal} pkgdown/tests/testthat/assets/reference/man/b.Rd0000644000176200001440000000024514633374223021460 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/funs.R \name{b} \alias{b} \title{B} \usage{ b() } \description{ B } \concept{graphics} pkgdown/tests/testthat/assets/reference/man/c.Rd0000644000176200001440000000022213635702026021451 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/funs.R \name{c} \alias{c} \title{C} \usage{ c() } \description{ C } pkgdown/tests/testthat/assets/reference/man/help.Rd0000644000176200001440000000023713731761074022172 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/funs.R \name{?} \alias{?} \title{D} \usage{ \special{?topic} } \description{ D } pkgdown/tests/testthat/assets/reference/DESCRIPTION0000644000176200001440000000021514633374223021700 0ustar liggesusersPackage: testpackage Version: 1.0.0 Title: A test package Description: A test package Authors@R: person("Hadley Wickham") RoxygenNote: 7.3.1 pkgdown/tests/testthat/assets/reference-pre-post/0000755000176200001440000000000014672347601021746 5ustar liggesuserspkgdown/tests/testthat/assets/reference-pre-post/pkgdown/0000755000176200001440000000000014131662734023414 5ustar liggesuserspkgdown/tests/testthat/assets/reference-pre-post/pkgdown/pre-reference.R0000644000176200001440000000000714131662734026256 0ustar liggesusersa <- 1 pkgdown/tests/testthat/assets/reference-pre-post/pkgdown/post-reference.R0000644000176200001440000000001314131662734026452 0ustar liggesusersa <- a + 1 pkgdown/tests/testthat/assets/reference-pre-post/DESCRIPTION0000644000176200001440000000044314131662734023452 0ustar liggesusersPackage: testpackage Version: 1.0.0 Title: A test package Description: A longer statement about the package. Authors@R: c( person("Hadley", "Wickham", , "hadley@rstudio.com", role = c("aut", "cre")), person("RStudio", role = c("cph", "fnd")) ) RoxygenNote: 6.1.1 Encoding: UTF-8 pkgdown/tests/testthat/assets/-find-assets.html0000644000176200001440000030003014633374223021415 0ustar liggesusers R Markdown Vignette with an Image

    R Markdown Vignette with an Image

    Hadley Wickham

    Some words, and then an image like this:

    The pkgdown logo

    pkgdown/tests/testthat/assets/reference-fail/0000755000176200001440000000000014672347601021110 5ustar liggesuserspkgdown/tests/testthat/assets/reference-fail/R/0000755000176200001440000000000013671767227021321 5ustar liggesuserspkgdown/tests/testthat/assets/reference-fail/R/f.R0000644000176200001440000000006613671767227021673 0ustar liggesusers#' Title #' #' \url{} #' @export f <- function() { } pkgdown/tests/testthat/assets/reference-fail/NAMESPACE0000644000176200001440000000007013671767227022334 0ustar liggesusers# Generated by roxygen2: do not edit by hand export(f) pkgdown/tests/testthat/assets/reference-fail/man/0000755000176200001440000000000013671767227021673 5ustar liggesuserspkgdown/tests/testthat/assets/reference-fail/man/f.Rd0000644000176200001440000000023713671767227022411 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/f.R \name{f} \alias{f} \title{Title} \usage{ f() } \description{ Title \url{} } pkgdown/tests/testthat/assets/reference-fail/DESCRIPTION0000644000176200001440000000044313671767227022627 0ustar liggesusersPackage: testpackage Version: 1.0.0 Title: A test package Description: A longer statement about the package. Authors@R: c( person("Hadley", "Wickham", , "hadley@rstudio.com", role = c("aut", "cre")), person("RStudio", role = c("cph", "fnd")) ) RoxygenNote: 6.1.1 Encoding: UTF-8 pkgdown/tests/testthat/assets/reference-selector/0000755000176200001440000000000014633374223022012 5ustar liggesuserspkgdown/tests/testthat/assets/reference-selector/R/0000755000176200001440000000000014633374223022213 5ustar liggesuserspkgdown/tests/testthat/assets/reference-selector/R/funs.R0000644000176200001440000000012314633374223023305 0ustar liggesusers#' matches #' @export matches <- function() {} #' A #' @export A <- function() {} pkgdown/tests/testthat/assets/reference-selector/_pkgdown.yml0000644000176200001440000000005714633374223024347 0ustar liggesusersurl: http://test.org template: bootstrap: 5 pkgdown/tests/testthat/assets/reference-selector/NAMESPACE0000644000176200001440000000011014633374223023221 0ustar liggesusers# Generated by roxygen2: do not edit by hand export(A) export(matches) pkgdown/tests/testthat/assets/reference-selector/NEWS.md0000644000176200001440000000006114633374223023105 0ustar liggesusers# mypackage ## mypackage foo ## mypackage bar pkgdown/tests/testthat/assets/reference-selector/man/0000755000176200001440000000000014633374223022565 5ustar liggesuserspkgdown/tests/testthat/assets/reference-selector/man/A.Rd0000644000176200001440000000022214633374223023230 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/funs.R \name{A} \alias{A} \title{A} \usage{ A() } \description{ A } pkgdown/tests/testthat/assets/reference-selector/man/matches.Rd0000644000176200001440000000026014633374223024476 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/funs.R \name{matches} \alias{matches} \title{matches} \usage{ matches() } \description{ matches } pkgdown/tests/testthat/assets/reference-selector/DESCRIPTION0000644000176200001440000000021514633374223023516 0ustar liggesusersPackage: testpackage Version: 1.0.0 Title: A test package Description: A test package Authors@R: person("Hadley Wickham") RoxygenNote: 7.3.1 pkgdown/tests/testthat/assets/reference-html-dep/0000755000176200001440000000000014633374223021704 5ustar liggesuserspkgdown/tests/testthat/assets/reference-html-dep/R/0000755000176200001440000000000014633374223022105 5ustar liggesuserspkgdown/tests/testthat/assets/reference-html-dep/R/funs.R0000644000176200001440000000040614633374223023203 0ustar liggesusers#' Example with HTML dependency #' #' @examples #' a() #' @export a <- function() { x <- htmltools::tagList( htmltools::p("hello"), rmarkdown::html_dependency_jquery(), rmarkdown::html_dependency_bootstrap("flatly") ) htmltools::browsable(x) } pkgdown/tests/testthat/assets/reference-html-dep/_pkgdown.yml0000644000176200001440000000005714633374223024241 0ustar liggesusersurl: http://test.org template: bootstrap: 5 pkgdown/tests/testthat/assets/reference-html-dep/NAMESPACE0000644000176200001440000000007014633374223023120 0ustar liggesusers# Generated by roxygen2: do not edit by hand export(a) pkgdown/tests/testthat/assets/reference-html-dep/man/0000755000176200001440000000000014633374223022457 5ustar liggesuserspkgdown/tests/testthat/assets/reference-html-dep/man/a.Rd0000644000176200001440000000033114633374223023163 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/funs.R \name{a} \alias{a} \title{Example with HTML dependency} \usage{ a() } \description{ Example with HTML dependency } \examples{ a() } pkgdown/tests/testthat/assets/reference-html-dep/DESCRIPTION0000644000176200001440000000021514633374223023410 0ustar liggesusersPackage: testpackage Version: 1.0.0 Title: A test package Description: A test package Authors@R: person("Hadley Wickham") RoxygenNote: 7.1.2 pkgdown/tests/testthat/assets/figure/0000755000176200001440000000000014633374223017517 5ustar liggesuserspkgdown/tests/testthat/assets/figure/_pkgdown.yml0000644000176200001440000000013614633374223022052 0ustar liggesuserstemplate: bootstrap: 5 figures: dev: "jpeg" fig.ext: "jpg" fig.width: 3 fig.asp: 1 pkgdown/tests/testthat/assets/figure/vignettes/0000755000176200001440000000000014656154156021535 5ustar liggesuserspkgdown/tests/testthat/assets/figure/vignettes/figures.Rmd0000644000176200001440000000014514633374223023637 0ustar liggesusers--- title: "Test: Figures" --- ```{r} #| fig-alt: A scatterplot of the numbers 1-10. plot(1:10) ``` pkgdown/tests/testthat/assets/figure/man/0000755000176200001440000000000014630120337020262 5ustar liggesuserspkgdown/tests/testthat/assets/figure/man/figure.Rd0000644000176200001440000000033714630120337022035 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/bacon.R \name{Figure} \alias{Figure} \title{Figure} \description{ Pulled pork is delicious } \examples{ plot(1:5) hist(1:3) } \keyword{internal} pkgdown/tests/testthat/assets/figure/DESCRIPTION0000644000176200001440000000042314630120337021214 0ustar liggesusersPackage: testpackage Version: 1.0.0 Title: A test package Description: A longer statement about the package. Authors@R: c( person("Hadley", "Wickham", , "hadley@rstudio.com", role = c("aut", "cre")), person("RStudio", role = c("cph", "fnd")) ) RoxygenNote: 6.0.1 pkgdown/tests/testthat/assets/kitten.jpg0000644000176200001440000014335714633374223020253 0ustar liggesusersJFIFHHICC_PROFILE lcmsmntrRGB XYZ )9acspAPPL-lcms desc^cprt\ wtpthbkpt|rXYZgXYZbXYZrTRC@gTRC@bTRC@descc2textIXXYZ -XYZ 3XYZ o8XYZ bXYZ $curvck ?Q4!)2;FQw]kpz|i}0    ##*%%*525EE\    ##*%%*525EE\" ~TQPA 1 "oD@DA@A"" F EEcDD7 " " j PQȂEh" "Tb((QA D*""UU@* "FA@ 4TCv"9@F "*(""#QDD@ADQv Wyr]KD@QF(55j UCv {>{/V"+"A L]^~CXh4D݀(|B_FRJLO>m%|Ķ7=]?]UW]:cXe4AvK;6վ8Līy.2<#PG OWxWu =.7d%ov-yDwn~SyίN೭^lkQ Fpbf7C@Z;B4~[$> `_8noNײt9Y}o0FW=涨3'^hy[\Rv1m(0>{Aύy5 Wb *y3c58(WMWk؇o6=:/}Y hD7( =S)Ǥ(gЪ댧;XGIrdZO}1nA)$[=Wmg]Ӕk_`zkW3Q35ԾcZPPM ( /LM;͙uK2Ãfl\IQ1+.۾]=sɍb T7H{H7TA dql˰x"zvGwms[RݡKʮ*z~c<UE@V( sUعPzGPe'4c^hp= |[p~lkPTQ@TCt_Gc,r5V|FͬkY֎=Sy"M{.͞H(( nDQ`7\o=G7^f}ݤrƮd\}_V7" Uy+EcȖw)yqw,J؛$2#afMlz7ͭDP ((YO4 g1qZpϤ{u-ܻA-+KgA4T{hn];y#S>Q`tFSҺXg͎Dt8f oZ E@ (cs q:K)wYQ6MH-o8 y'>syZҽOK0FsWɍDh@ )踼߈.v|Ӧ~ut$㳾Tj/П}X}#&e$A;㕽~~h (H?(pWuUI&.: Ef';ovvwjO=cgZ5 2 +įHqU8Ӛu\#VHyk,OC{]Y3Vy ("F9f+i=Ns>|vG-iD_h$[\_NzI" 宊rgʹFu~&ISowQ?0rOouH;n3:<ƈTAjnPC=24͉Gz\;L-Μ۩km/ɾ/{o//&D@ "㬧+[H}\`y+vdj5nizM?1As}v{u4ؾO{=sMZAvA%'^b52EDDD{}c|8WQmHˠP??l?I ־BmEͨA"WkO&R _f,'5{n.r:n7[oZwџX:AшDApU k+A7yq*Ҹ0pj{5nɆmfƣ2;dvlcEA& A '0. (WqYhr<4c7ܻ:!m{?3~u^<@"""""5kDžlVG_ +>UxQ)W9%RS,,ws'|zL{s?1 $#Pby5w},! ^vSs(%QYNʉk7[ݛ[A~ٹ4IP5`B9C4[Cwei +)vE4X>3vsBa?F:Q/ E 1#5tIW:JvԯyZCsf%VbbNV[u~^MjpDDֱ Q5P(6CD?.h9.:IbĬ^|΢PV#Ʌfn?/v́~~^lA"cZT\(OBuڭ,ogDq֛:[E_g7Ec,Oq9b $cX5"/v1xȴ6#62Ghdz\:@lK Hw}V/<؈֌hA0"FF N۵2? IJ=? 'AN,=qY9mcԞFQ1D`6|0kp Uzt2J5-d;,\b]uzx3ͪo#Z (yR*6ˏԹ#v;㇗eY$i|bnKvm`0DDֱF#CM."}*LT:mm wo\E+]'鯡c:QF5b5w5Z7EˈpHm9*> dv7O?5Q{[{w@kX#zXK^Y3҆Cˉsv? 6@q"ͳbj"r7ɺ7<#KkQkZDS[ k2 jPuYœWYpVeyK_5{u%gj^`cAs:$]-`G`pSŭ( Ej5]znaK*s[`2g F#֠G9k w!>RlS gz|oU`QjU!F`ئZ[/6ڀ"5cZ:xnN1MePT8ő2V:Y?\Hc;_On /_wWHuսo k֠K AiG"K,[UqlZǩrw%*,]Զ^ש;w5-FcX֠Q^S\b{\tTP>2_:R?OYQJg%޾~Lb%" k#TWg$9,Y6U2qؿct;/Oiyd2)']Yx]-Gֳ-&"#cLm$nV%SMeYpt/֮M d`ɺvư{]4.@Dj#QmD`Cc23>@^쯛{}~M6ʒ{}l*!<};e"@@@TDy[\\OR 9mko8E&Vưuzz,>wM( yxch2AjhsZt _5ac{W·6fU =}WVM QPxj#I+J;Ec2*$n -hڽs]7736D`[=gn?D8+B[9%4^#u&Zzʥ<2k%l#AG=ZZΞ3?w іtq<]9WCV),hcDK*^+bǖﶙ9pDGq+X?WXoʝ/Tlk45 yMrc%TEL}7oڳYNa (sSʦv6Dzbz-~MUW"jZ9Nh/GmNv^Gm" =#GOrOXReqZ:m&un [Q)W{7 WiI'=ܝObs}}^F D+7q\?Zls/sOᇮ>k'/*믤g~x/6}VȻ\]ek+_Id2Kx>uӻ=s9vhQŒ>\i-:K7{iXRMT`sܠ+h5QA珍|yހ~|r]n -pW\9UAA"  *5g0HGGե5DWWEDA@Db"#婮-:ļeY* h  zUxADDA@Aj5v'  \ڀ@A #ִj"AUQ9U6"" AcZ""(5 Usթl mM1a& Mpq=6>0B]2V[|)$g ޾a[:Z} 3Xpz̵v=0g+YoPgW|vXԓMg+._#Wsmf%wO!48g+8;(ǃMmsՄ(K~O#Fn?Ͳ>o`4Vy%ޫ]9\ G껐Rl l2z,ݯU`!BX??Kp櫯 H `B'tSf~A۵NL1+.^s'E'&a#F}Wm<ҷjDsl,erJ%qRcc U5 hR+~t% L% 3>lج5cf@rlNZhӪB8Mʢ940J.qsh7 IEh Tޞaxq!s*5[Zim3䦚bS*UUP5ew*!e{)Wz@L< Elg(֑V@/7NͮKVRG ]˞jHfUn9\|Ɣ]9x.Wȭ.}s͸Ev֔%˧-`G䞫k_v5dzeǒztt:;il 9m͂c!EΣnD`!D)0"*V `1$ZĬb@"&"bbah$+3 @&, DWv"@_-k6_K~O[ \=gqx`{zM*rܶ :ϛ&ks{=߆~.]KO|Ã[>x{>_C=[~go?7G]<_og>w[?K+{9{oc2Vf#$,$)WG]4*-#&fBV1 q($D2!"P@#1 2$03A`BzX+0vcOm[qMhO)\7X-ђm}7ZCodݦFi]h`hKb&&32&2g;|s9#pngb2}r^-,쬸?^͠*\ꮟ핚Wz,_WwXg^f-zWE F$;eyF1,{1%.؍YuV-ϳabC EG"qLO cCRJ[J.,dLaZZ\m6Uk0H5?ySL II+zOʓ$G}C*J?jl鍫6ftc\PnfÇeP:.p#Vɒ. t*w4~qDZk(Њ~jV@Z@q֩-š|\XwύVGgOreuxw7墎ov ŭZN@'S9._M ;[9oi?"wmez<]"Zh(UU5aW©)*4Ɨ-€~#w>UE8 B&[rq%#eO $82qe*{o=M&L]Bß[\p,#AuN.v`%sjk ;/<(sL'ga[~ݓ>bJ >X7E(:vp' ƸRø#y.\ߡ0^Mcwe]4}RJ9V,W8J}T\0mP%u%Ai# 5G~&ԳຣZH'X A|ZHm /Khʻ)SG5ÓRvr}|jUo5dbϰsvٚ-gH@OeI5酟=wp/e;+4Wv7Wmy#;M gnQL'2捞1601|$Y2.oUXֲ&H#YB=;>&i M^ u'բ\gUJdO-z|ڹLD,H` T72y ]fKA6V龱o^ḫ퍒X*܏Z7CLdvwl3FҐA}\~}C?,!l^h4kׄrYAo_W+?3QMbOR>h0 ORp6ЕoEa]B&ڝ=DFU}- |ZN䣉 f*<اډ^Ll{K5ܮSR*~}"y#!⬮-\:3Z lR3uAiRl8T I]٨€+Sg0k~I**gkkw:1)/_ci"C,L"'mp>' Kl45q%Գ$Rho*Eu(+ |鶷:4T}C$f_n5䶮Ix"˘۳Xgfc-0!I~u򱶄HT,3&/۳4@Eq?>3dF]aQG>-SQ<+2_rECXG9J mqM NNW 6i"CVKE#2 c@\RxrZc=8}}__\V["9Α<)q&̖`DN0C,-YO$bR+f&=Jcr,ҕ8ȎЖm i}XCݥW!>#&J&q!idLˀ!\CYCȄgCS'}g"?q77@F/ЭLJ ",{g39 WUDOUc"N\6!0;Q\J_2ڕ+%`m5vzӍvLX 3<@ "J-3KE6VDerCw\17 PBQı<ܪc ~FqVθu>0 sNd[Y*l&M2UO;.32Y)%_W~)y%43s;fybh&r "$GO!hAZ߬.91Avai ٥gg fхjܻ q65|DAgf1]f-,!-,Nh^hvD:g<#^iVV! 9Zf> m)yd-ۈm8;)3q]E ݺmmk;]"n صCa t)b$<Ȓe+)ު%BK"kGXKFc?Έ_rt H l8 @agވ> ضl{T3`.}+]JYCIu#=Ö1败HK 0†fR0Be`K6JDsbӚ!6Q}#'7"}.5bu)5',0UI #xς:nލ]*5nbW; jnZb[‹Q܇ۅf1s<%ߟ\1bg2 hzgOE65Xz8T%#Wly"F!mOr3`1$vC}./צt˱XEjJuϢV7< ^'*eu\ŝ-ˆ,=s&*J6brC Y5 ")fc:=56,%<c cQ5l\,(J;eC"$v91"9ALNk0@dO 1\l+ciT(mI0v|pЭuUQ?J NçjSR`|$S"oanʢ"E ܥjB\N,N{$eM.$ض#YIR3,VSW^-hJe.e+΂߰aA܀?Ϝ`aU尙0~p}FIު^%*g@& s]¥@ذ5EZR7nï~̤֤֔>)E-d,[զPPO#iMEqN'-$66`bވ2$~_rBw99sy`H}e}hO"8,* P`תEFC[NGؙ7ĽevѻAjZz6ͺϛl\]uf$CYwoQYl,dѢ d2j hX;%LY,gެAfC)(j9s9sH aFNB¯%Xx8 VN ĕ >SD6W¶rޫ=A~c{kؖuA)de8-&6Q),lK+6PtݘA"WY;<Ƞ]׎K$YpZ{uOؘs9s9s.d8=m VdJ3R]eĭjnQ\g.4_)˔e.׹zR9`(M6M%+!WdXJ-A2:LJ$!A-DN_oSIg9s9sr8!T^/%Yؿ(zDCUWf#Rcń65a5\eSjEV]#>>BduU!gRFhzR1 0Cbd=c+Yc;PB8&>֥LTul> RZQQRLXapbU,x5[م$秊\J{FʷbeUf"&A*/]lk `0ؒ[2ԭP̤JTve,9s9s?ǜdd16![2X&?DOWn"}/6+Ȱ`,gܻybnVפb=kIr:SZ,E;3}h6卤a6 ]IFWWxZ )oH{x)ǜ2~IJ3 Ab%Vfu}bl7M&lkk6ا,DL ,^l5Wmt@ՊPCn"{Sal@ٙ'V^'NE?1͟4{>XfUSn*5f[ڙ Zr.U^\}r[ o^$  k^g#`J!C%!2omm, .?o&NK'-Aq6 "O2 ei#[skzԶ`O`$e QAqLm!׮)7f2uc,EX*nJn5`C+YBُ}ŝ~Sq0+TTe_oq6}y? g] $B<r#I@F)k.(hmWk1upKc$ aN]eA˝C6&uv w)ַjV"z&z Ky7f =ʐ1MΔAH&fbf y*ȏYrya̡ްv"+ nӚAOhqb|laţ)E MUdsr=d^|ًF@N[@Ƌ՚T&fNȚV":EIjڝbcM<ࢹIݷ01`0JnF!Rϱ2S^<|1wvy%RUZ#5? |~Pv,e XXCKc ܝ(7))a]Vq:Gȃw >lZ#\L?`,"g, 6jmVe5?fB :nƷvL il\s%X?RaV+ֻ8oh/&SյXu1,& L[FjaMd*pG5r-P)Uf$F%ɸJ-gs3+R9aLN2&mkeUqhI-B0{R,;Ckz6E R9u A{n@uۘUlOּ̫{"]YWH=UaA֮BukVkUaj`LS-Ef[hW`)ݷAINec9s(( arg]&\$,ӘbhEq BmeΗvkQZY׮":) eI;Vrj܆aP_g+VçK~6.ygq).ê-Y{Sm㓱^\nv(Z ǐwQ\s8̮2kzSq0Yb-b'*k_+5$Qg_ i XI=49's#K0Ĵ{ |q-%9&YG1{n9_T6O0xŴHC,*]bl*ܰy o"]TZ,,R/JN6WY&.gqz0SE:}8Ȍ8q&m7LZ`^>blyk9M";dHesX۞]0H- ~H޳363]snFeNױ Hhٸ%FMb 6&p䰒z6u\+R+` 2 s[p 3$  +eYi?+kˣKo%XMGnqr9LlA$8MCOcam ,`53fdS31,R}QK]\ su3 #]1WR'B*X2>AȰµͮrݙT=Q26<J!&P&Xʈ:S&7`>-ԛBq{& K3}:s>ʺab>j͆XJ'h9 a4Z0hC$qf3SeSݖ=,eϷ0 rɜE )ZK9|ƫPӁD#"FBc 2 sBXZCkOZL =U[?UXң\AV HMǗ{'uemyl#is\肈|dd&2*dxi G8ŞÌm~=zLWMCι83sM"ϛ6shfұ^U9``tz"bF{mc^qSiO+Dؽn9yOo|Z'fiOQig$bq?6-[υ\7vF7-wxV{5onC@Jڼ -e&+8hL}f+^1Xc!Q#:\Ƣmx;8PH2G$c=c,3Hޙ1XfN>kU+*^][)*1,* "8)ιx38qg\mH,yW-eK #jеOu]h*ڎW¬`xyk(xΛyJ<:mrR3?9o9s?ל99s9s9}sF!1A"Qa2qBP#R3br C$S`@cs?|[U荵wHp?R?of؜b0}UŦx]ęBׇǪc;KKswuuiD{Y6=Т۞5ePuWa2xm#.#CdkwV.$` :T6?n<u='qy>Iś+&jgx> pj3;vY* 'P;8 pas5"'Tkw7 A?GBLQcIɖm FC]tQ"z'puQxD"P`x/-[FiRS_+Ԩ&FF]f_k >v2~9D&*9,7ˊ|Ӎ;aq7ߌ&!UkUFKD v]y[ "mG4" )!E'eU]3꣼8˒"%$Zچ-v%Ibѧ|y;](Mq1qw皍΃M.q^3ztWLwֻm vgt |e&`|cCl&u} 0?izOx^ѡĵOy`3Nc}=OQ!8C;|\Cv#';P%QYZ.QNER߈X":?ě3$.Q|6itF㱟TTAٽ#0/5T,l@''tlV\)kz^ .BmidZrg6Q"Ph?RyBsT!ip"ӧȦ8'\&M%ߢ/P`ȻGȟo dsuDM}ߦB^zkC@kN5Ic@v9ivLu5^ r5Sp "hlW c>i+<;V7K;Eu ˿޳T_b2 e8G-qrt>E= 6=J{&Y#qA÷|4U@ʹwO7DNFqRiig `-r@^˲M 'rwϴaVRkir5Zdq<ԾV}ώă벸`&j4QI{!}!^tQݼy883(=a\AB&:jkL^To4^d7[](q2pFZ:TCsO¿52Y?xwX6NV0Od-glֈ/|HV~hU˧~'kc$Qhcߌi丨GݯNa&]A io ƢH jm>s .QNy\5VtE/i>:]2= !L|S]9mQv]3-Qiո9k4~ctj6b~Tz4y],8`5CSXq\|JYƎw'8F泩B'`dn:ƻNpts? j ԩw%>]K)?a##מ(UwO j׸|g>݀[v"CAqݜ6T鳊2KG"> s sXQhyE-Ĉ=9,(U> 9Ev txsFʘps٢IU#K+'Z"Ne ȣ#I!MR=9!p ' oPWАAsGBa"7Ħj t͊5jd$jyQ嶱D9N!:.]:v5MdOWju?a< N79 AF8'5[7~`]} '|7ڻPs{{O:z[? x.ha9쁕Μge={'KuA: Zz,"7\G*CvQ9փSZEƓiܶt cl8 cDgFz)8S\`]ZA꩜Ds2ַC & 3ISZ+6sx,ԬnUϭ.P-qtC-n̡%2g䎠G䁤 Ĕ׺M]τ|Tx m9yqLòmZ=PLAeLGDD@C Bfciy kG4G,=8=Ӂi73X=ISoL'*4ȩ&$ןScpMJD3zʤqkqa1N8]d3_h < o,b|P4#haѹdUi1|o+N Iԭ}W`+Vh~F8j|fҝ-to9,ynG1 E 6&ɝ6 G9Zk= X"3A13#6D=:E;G$ >(Ϩ[&m~?4k5qZ [FLy [Nd ''}cnw^tYdƫ!81 kyy+y[UINS`d պ`#泩_ܬUK%_g]Rk7^jtMiH ,4G[(T9tݕ a?Nk}!i aIK@eZdܕXBF=Θk[T:Q.#=r(tSu/'S}U :TϪya9!k3Ѫ\:Jwv֎n໨$&?u'GNt{KpVc@X>ȩM{;six:bI;ewר)1ȫ7vgb  ϒ9䋆:ss3þ2WD4 -sm-&:ye<#w n D.h'  z-wZ= y`-w44>)-MtX?&?>Xa%Rj1!9}5Uʎ`J>HnJ88ځs$GD{;vpK0U2 * G]Nuk?G N*&ZwwO%: +hn vaޑLm)"\rui@*C m@8Ժ0ot} exAW!̀x~H49)pOf;#uR<6"Dyu1ZceX5DVtGvce=#PUOc\wb0vXխcv`%PDÈ83 a+Z׀4}YɼX \pdd1=Cy8:c sZ$G3h}٤D:w~H"4h0jQ29'Qp;~Mq@  ؆`C}S=Qhs !H_ƧnI#Q1?NyE޻Xz0hѫ"h4Am`9pQc녒'&B?4x <¶ 't=ϔ9ܵuX@1!;ȉ%m8p1lOAU-E*F'bP>%U}I>klzm%8.DaqϚ9]&v7 'V4iac(mT!&_D1WY5_?WsƤ7椏\Aѱ?s=j"^xa>Z-eNܡ4 "z\'lP@ Z9oI7|̦FO0ާDy,2lݝM9m#KuEx' ,uh݂NuGHcHNy L0 8* ?Aˋ'S-#"ݑFi i[a!07Q֎dʹ NOQ(BwGǡ'ᶋxNe p1vȵp3yO[|HMww][o̦LW'y=dC}pV8ҿYc}hG]ᜋ~82 o7D>j#M ʕf<Be`: 4kCGieYY 2a kn!ٙJN?! -ZgY*{;P殘!bs-m'xPApR˄i|5V磀$S?E뇒Ɵ`߄803 Z2iWԦ`k Ha c sm )ҳ? I|^ꁸ8V各GL'6nVʍĂnIR فn$._5J?ADwS.*x'q'ZL~4UuKzv8"~iELb=C{1s=LDnOA:) #mG+Rk{%(ΫKA^!:8D[R"@# q77஦Vsj"AR6?ܰ~hّ Clqۚ}U₃\OQ!8>*V~hM;h>h+:4!K9D>KU dy~j GI3z D55KY&>Dhzv^D8j?eh;A%SHučmdn1n;|ƅ`:+Z!p_D{0pG~:;8OѐAʁ@'DF$JdcGN%)k" i_T)AK$y}J7E3\Ep3\ ~Ϸ|O8~s<܀yn3r j$e[(hܹ(?"CCFGn^s ,t"!4nfQ]Fx!|6La )w GwGkioi4馨Ō'uTܡb]$k0z( 9(zO-T(΋EM(TF9!E+e]1SgkUi|– 8~&a 5};9m;x'џ'uLX tOm7 k]CҜжGYpTvW9\5IM]>#U4_T}@T7:hW.aZ\cӒt}6'g- }6!v"wr+45htꃇ  ?f+(jRXZAEa -ܮ.=[F6ӪD,(~v" %Jx7V9v䬪lq͎}z!\ `ÓBn;tMez._BZq'nN gчt<ky:sW޴;Pp ^idB-PJ.:,dX%C3CĠ7o/] k?@k?$pxNɭh+ O3N.v~0$k6GMu8.#kT0 ?|dowIJ4lS{@0~@t;l3͇%کwZ-iڹէ֒>~ o4{$KڱAhu2ɏO$\<ܝ:!f`X#E ~J0b)\L*HX\Q)ZTx޾OE/U n:1>qAgxFmX$éG!%3>o>>>tOqʩ*xH0 AeL<*7sOnTjWu oOXjS .iF|3VSj4Kc`/h Kjm#1?T`߆~!~ŏty#/XeT|.?_UŢh걪S)iGۄs#g3: n50 WFct|_KD*i}-ӪP8]j_"e1i_A\tvDc#"E2sAHVf;?ҝWA)(͂8\A[ x|x{ k\x5-|ԏn$ X_; ۊ,/58Z@B C>2c|EJ;YWxm>6 ;PcFָq*.LnSs0rAUli]<˒sa!Fr>P$ƆSY]SkoSwIBs<KP,өO\5GQ?sZnGMS2ٝv?zH>[Nz-NUniY,%V @ۮ;K~}'n}=\m vq!@s+08x8h.* %xpZ`6%m"H5 hVΉn܊twy]QLMh8T]!۹! \u7TpkLftQ i&5xE? UPpޛA] :${ MAa.TeJ:DWemK\zDkb6HFE =y&i&p:d&=NFD޷;_B@ʼCP4Ih`)C 3W @)*e5=Pqo]nҦIG$\) Бh0N.O!rCza$i~Jw2L l:ZUsMhs]H,>u{m n^H5Mm[0Okݼ;6U{=jp{#:\Ҩ4A眅Tՠ*d{F8'57;xc1U@x]CHFoE+Vdp d5q - 5R{;Z:#eW4b& %I!R_j]xGJ?.$6@8 27֖5) 7&(?8XovL;Np"^b5OK" dQN ' |g wZ-UݚNeG#-Uic+^sxEԮ:Cm}G$Ca#MtsM Ntkٱ݈CI^*{#UT"r5k5(I\"J+U3ehЏ݁("n"WvLpK4k䩽xӞ[hپ)$j-'.jGsZ&n'L&xu͍Ahտw8p#L?P2A>X폒@pČnFR=kioG6tSHw\鹜+/Ć8dKTn\qi80s?|ƄgZ}ߢaCc`t+-ROEZZDP Bc ~(o<CW7(iXTpFo+9!^aWdGp@8d[m1Nse`uN]w:(Teg#"9/OAeJsBqu"Fmzwj1̬i [ts[A8j-wgg@]ibfy¸1VZ'Y2 Box!a&T-Z#O@fƜs6 T5 GFg`UJͱ<9UR^91ێ"0XM^A (hmZd@$j1#`8Bvr-hmv? 86p@HKE81w4a{HG1O0׶iy'6CZZXsJecQpQ\9  T8 ~%mlj:O5 &V !(Oz}Eʻ/Nj#4ELH(t'v`9]r 5r_o,.!7=`1D_~4uZ]t)\ *{/x0zS择8OV|tEz\Gn0SCSK/alƕS9M{U杜T۴}P p!4@!e4 e>R?4'AȎJH'}nv a6iQ.iDXU)fע 8_ɮ9d1ƪQXzmVw ʘ@2`,8,7V}P<%C7 `΋!)Ftjo9#Z߾ǪgG"N!;*h_1㎕[$M4~-Uk1kxsSDW'(?n8w-'y9;V\N=JnjtvӉVd!y)pioeV|Qy"ڲ҅% \71C % {Dj<逿֏oݎDTsYP`Gy P?'Tz.5q)!շklA4羈i3th}3]@iʸϯ5Z-8{Lo~Xh!Kͼ)~m?cZxi]a$s[l[{Nz.p捭\+OEdabUoZq貚3`3j?A8pSTO1*@&S{*F:r tkIXjƟ%W1[*-3jbƇBgpٸ%5 85cFr .Z} 喫Ki@8IQYV9 @:m a"ZzZ)!rN2G{ F-vҏ)M$2PcN]z.hcU$9J}Jcx ! 2D(K95LwYfFQū>%גsA әD1({-PV%h[hS#{5Ѕܼ\#p#et!2 `9ʨ)ԣR5Bp: 訢VO4Kϒ NN-kBˣgG>i U)\9P&©ih!?ѫφ$7Tg ծxH^!\ x'6w䆡 H j !`&42ri;(f6L=c s_S=Q($Ϛ`nzXщ$. mULP6?cQ- hO*x<($;G)Y)Zkg>EYQBLèRܷpӺ{ c)2!~9F;HɲUnkP?(?E- ݦ" aW[2¨~EsOTliObe*= $F5zU GDZtENkvEm8(HMnB/G+%`i)ĦϹ2ZQ8Zu” @ 082P:_o ӣCih5U^!QRSɻ.qBFŽKN$PkQs<;E8?hMq~F+䨔@ a9ϢpĎyp4h70 iS;8D pQ0zaX?gA#-5Hגo6Eahe0!> "D#D Z,Pvд] cdHU4J[:iП?![Uy9 NdǵHxSU>!Z KvPjC !zYDGN&4'?aM#Dz[ Y#Dž4Zj!>SFL  o2'( :1K +*[ P'%jA-v?c5GiZt(ۑ[5Q, C*ڇ1ݟcyg;Ear讥\4Rʒ9G2?0 kE/42g(P>)EJӋOV{*hui@GXY0ZcwB'uH{Td,KMnҿipS a7C⅒)kjqnr&JhMPq5$ ,k‰qD"CчJOTB6NrV>^Z-r$$IdZ[~K㓔9YZG%۱‡cslP nٜ8)nTgp ESl d|Hdt*"\=V\'CB h- XX &6QzqdثcEw=v \NJۂ$U;rM{ vVN@Do]ꅦ9eg5EM2 EDBl Q62ܠ+ Os钪S3.]p˓( vwD'Tq+<^V\J:j7š$9@2ؕáVQmHX٢삹vS.SMVįJ7eV\9!GiL++At[ n4"d|K>jXn>yz?fEhZ*A`즴87ݤD7)lmW[u3.<>W*!1AQaq 0@P?ǯ_ge,گ~L?RJ+~|ԩRW|W|T_D_ 5+COϊ*TRJ+TR|J*T_Lrj`ƅێ!\"qI*T*'¥J*T_Rnc|9(Dr1t^FÓ<˗寸 rPw(CQs\Ce~*WJ*TR|:~XdFٔWOʕN0~bMuU @T'qIsD1cM3%a'H0{-"+&g8`h0@Z-[-R_jЂC܁YgyE䢶) 846 @Jh11{%GUEXqvic*s:@hǓk$kULE/գ^awȽ]%)'d @JX`T / 0R4׉ZB/(eUe\5TXj2.ͪ1[ s02!V[{È6 +ia/Aĵub \+MB} އz`>}(5/y%g;#4?7 ӊkP \ $V{Ax/n׈j}#̴,) \bRHkG"k U^nRZ4>qFK)³B4؀Y@Pe_L⠝c!p߰Īb#AWzfUkϾ|AȀS4CGR^a^$2R咺4q|?0>kѮlQ6_JB֗쐲;*Cۆ MJ䰩cܤ,`0!#Z5ٕ$=%{U!X!Y!mDO5C/#$l kn q\-t3O-S^ЃT& <Gs'%&Nzfs Z8?i"XjyieuB̍6T[~ G]d2$lK~<@CuxɄ ՔxfnU 9kX[#qLZnf?d>7I@IAV36hY#{0yU(!:bSc;`:K{Sx@bqR mN4 WF.8Y*jy"5V0Mlr{1_IY >ڀ'gx LSq2ZУBV~,-=F@^ lhIG,!x?cEebpey] q`tkŖ@U^YF`Q3y,z)U+&=dAp#d1P{Q2l ib-XIt_`f*^WY)Gcϰ^A8.S7Zf1f=_WмӜ 4-c -W~̄RVڱz#@x1i5@wTJf-U腏0Ѷi,|t5-V/Y Z)~+=k54, * pbP8}O- ۟au$2*ĪH5q` 4)Tc (}aܢ %֫ fഅnGmnY",XTVE/\Jk*3bK{p¯&Q)n X i.<P0̐EW/VKR7bOd+I[9*(ZG{w}`d)#5e(%4vΉtBsruA[ wAhح*0qGeFglJp(%We׶h0q梣k' b!;<ADRѮ7XXt!B#]Q Xx*_4DFs.u+bQ%ucgJ穙Z,{m+VT(bc4 F0$Oy>01΀Sp":g,H56yȞ 2CO'~rϒXu ;(Jɭ'/iskODh:aj8wZ.OK x}V6b~e(q譮^콡 Јjwg/x#29l47^S4.:;NpJ4#d|ffDf.*5 6l^`  1~n_|˱E:Q+l7͊ԖxS!FIvkI1k) jneZ::ΏZ5 z25>|[r=KUWEi (d?K /ưy>e!ڥאJ-jP%# 7(r]*eP4Ah9`\! !pFJR}!+Zۦ9mGo+V8F & _ihYdzL$Ͽ;2=ăs4HY +X?i򨚅g<]f^J)e  >ma$tٚIH P]n KvAOh: @J=p*Dܲ9"LBB3XTiTL.c0H3fmZ6EXuܰq0[֍t}3`1j.G( eUTcN\1ꀸ:OF^X)t8 &U`4@_ba(*~ܿ*87ѕ]+Մ@WT~\fp1^!ո<S (F9{d#(0)lZμybBڌ[bղDfSPPUR]PBLjSDhsz]䦏,ѺaĪS釰=S:YTd%c v\,uw0cd|oPڃ!LX@<GAsPb(VbQOi6*8k,dշ!fLHN7/'Hm,P 䥟pd#{ ?5Uj!0`J[Ml yfb) L[*(UQbPh)|5EywSxR 2,AʣHt 8ZwRtT$!XRiߨl `x@[cX)V;J\+3ƪ t 8,_,c~l P)JnDһkP7+C:ctV$TcٿQy  Zq,$6)1n|@~Zqbl虅J^Ս)#8.k"I`⅄ ]ljjrU0)Bo(mw3L7edD/"eCw%ۆ#J`ňWDJX\{gf‚")4ėA7×lhU;`/F?Y@0Pū5p=CCwM~hxR[hot)1V* pVhy2vU}=Rw|&Lo [ #BoIJ٠ݎظ_fe :}hFjoEwFG p skt\Y|W0ֺZ<]FmU4{HzU[K@v&}A6D`|`cA^ۯ(o;rׅD/KIh4(О"78GC1o jhSQ&OΙ &tc9, ܨcbcLQv& !u7L =n`b뚁9ol])a g,MPeVy pX]!"!Q_d:Wf|q+xJmRb MmKbg PeEt%Y@[WPV PaG6E;Xc1+HQU[R"A"eTx/ `@V 2Z؄LMY:a´ڎKq5IF:Tr/L wQwAȸ`xGϝr.:Ϙcjny [ E<:Ǹǃ$™:ec9f_ڼK&ع\ D|?EŮǠ>[~Bv, 'nП))\h9~e vҀf[)zp%ԽP8QXXJa^~R;Xa%!Xame,]eEnGc JbF}&ӭ%$ñf@k'f(oֽϻ!#|.8]$)We)#` -r^vY bRg/G鎁N&۴rÛR؛`r"ʑ^_,LJ$Ox )ri{fP0FݿDNХotE[x1V*jߘ9}us+?%=~ecШ_jDw{E t=pLQ5i+RǁD9/Hl˚hf ꈴho'a^e2YJWCoyXL{"dGڨqMca9` s,CdcA0J6H𦖏ҶyEYalش 5eKfkelUY%S^Uq W~~ ezQ@8%]B;P729rĹ.|0ba\4{b gs8`/U .:ŀvBmYja8V#(l+<=ķ`' k>9Iחh|\IJ}TH<֝GaؘP[IǦSy'$eB- +ehtКjv) ꣡d>*e*ʚgM@mC+ɹXu v>"/bTHi)mw@Z+:@L?@ i@DKp}_Pۿ }FECQx:^/\ }Y5JVkBޗ -c0]t&*W_鍊% c dC|BI[6oq5Y F-*b|FO]8K+F 6a-orZY,-zb+[=%t%S&4_ǔaeX  T+7z'uDXZ'׸z];V0%K K(xqu%jS冫\k/%\MpqْO]}2Vp/`+F9 uEh~ [:0oVz$ L;+3iP ʼ^q%J ri"񺱍 `vQc' ze>bwľ̥oܼ"|bg/YA^ h hKhɉ%Iد_͜l(" ps |d,,/\GݪނXǓO,X-P:9/&~<a( w?ңR9i*˦X9{ccJz>) j+ה" vVhSPLS v>S." 8 q)28%Z_C`>mG %֍)ZT4]8M㘰̵ hȑl!cuqM=yP-v{>o,v p ø@Pyn;TpMk9sU&3|-?ʷ(@ADK!̪Z0 KS y& VbV--6<4y>a7CXD"uVฅQxD! !f)f'gFnEG MspPN _ea u|$i QFtj^ [c{MU4˖pV rb2A"D5_ZZeEŒ),в=~K=KY|#0UJP=D!h5 NLƒ8b;\x8r}{\@8pq)0&&ڱπ/CFusq\@[GhWC .s ay]A9Q- ť׷Fd5S}싀v.%ȯ6#@X5M|IW0[ ,ip#c`xqRs42t`({Ƣs Vqth-"я⬛ļTq ZbTFaykÄzaa$("Pb?U?_Zcj.ħ7TFJ+Lxl>^'%x ;C%Ψf[  WQ -$1Nn2{#)(LA1.eWh<0r~CzjFU6BJpS(z ]leZlRRlS0.Y⚎Lan3ʆl+el Lv3Zaśl͑sz4J aP6&/}CW]!WG2^`ut>2D –is^^y&HAzS \ۿEq6)P'SE8j qa7v f7S=%W Q@}BpwNJd(TǛdFBRa7XZ S Wqu)Od3'B®*Ij  # sܿRQ wș-r wz<$`6<'ᶌ0,oɀWp%@]!@l3M T$O#g|C+c~;U esI)N +Д§R.,~?j_g\.3rUѸ`Vm PN*0x "1)wp4+X0AwbI.1(%R3[ 10lGRmI*cQLjJ5_g\ 8EP ]Nj9Q8F-[ J#逡7a@MX8-AcrKtwij41ޠl ʹC"f PЌ0/q e3/l40R/_r<@?vոQn Ii{rnˀ{g8:fXBB|40W회OZ+ak^!{4hXm%IjyK- 5uɻ#MaLSqNV%ؠ'N"%Ff ̬5- "\^j"J2e2 {P4탇PXiG+1o4XByʌcHύCy.0'1ZIDPIb!)zN)v*)([">G E̳R?Vqfbn~ \` YkS,]5l-k˶ rzX0.19Y # M`h(k@1 D5Za_c?#,v)QNf[]0(/`lcB+93KVlLgA(z00#=ѭkgvXLt(/Hx|aʯ=ūeX{o}̔Efd1箆nHani*U~:l@FO_ޑ1z ͓ cRܢ2m sfZ0`_c"`j1D.809rࡶ2jqynad!JPhhB573/-]&,>&`>>N&&4x2Y`HH`0ƠBV pUܮҸFx.*c2*x($[9讔2L"'&pЭ8uA0[,jm"\1尿ZAR K|BKԮMԐ%~.\P <]JBuwIkrtED( O9F+6̨(3EJf 18MmZ4*i D!ۤ$#0p;@IgxUh9=33s2ﰐ8{DVh,4MH ^=ˑ"榊șoL4t m0?)~,D~$H'7/rH`5IUn?G4B#]{j/l]\Bw`e-1/C;%yh3gwl [uyMaup6^).pN^ C'{X282D^#}<QAHȮ5+Phᘄ0Fk(! kG!!6ۆ(^ N4"底A:8Xʂ#KPU$R7WX̑A 6{ca@-Ax?`RrzZ:*z==Y`@ށbcr J5eZ^GB Ő ѭ2?K9]+dE[)_>!yah*LaЬ>  @9 9 0b ]1Giчa2!&eI>KHdplR& 8\GO /_n.8%Hז`V޺d-}d/Jkczn%gWVHa?\C 8EѰp؜BL.V<1MzaױԢ%VвJG^A8mL\  &vHQM`3KϘLoc-4*w&Җ}W#)#20 eFP\wfLEa[ ZafQ3%DO7/4"1 vʴ *n $e#ce 8,XNhץuU2(t+ԙyBcutӑ#vmE5/ FY R ivøT?fSuEįdM60|\I3ae.KeԬy&V+isbJd &AW b1c -WY[03`NASiRn~UfD%*QP=3!T`={ uQhNX8d/y9% !A 0K[j1kDj <==*pĕ@ 3ټ Qc+/1W* BPAT>*' sPC?!ji&tRGFMAىQ+ zanNIIx,щR:ua$pab\ӓZ0Y[ SgK ^21Cَц#4dj8%P`=! ]XXƁ : EM.8Vx[(1?Ԓ"h;;Yg7+•7`Ԥ.eQflB,!vG2yk \~T_l"lLSs~qD(ȑ9k nC!d^$%TvMpዥp̭]f5Ŀ,!0ş*(-'TfpvlG\,7[X @-vm 7(}9%p1"V1O%߅ˠX,H*%1G 1"Mto~ĢƔbs*64%\bV4DcY6aQK(P- .cBJ}cHEȝtEg9yK F}^&QCs/ EtQ39nҔbz 0G$Xv&&n\\.j&J8|$DhbK**0"O`ei1Bj0p%˳{eקے+\$%ڷXh򚊍YC:`U@qCpQ#q9ʱ(X>>Ro(#VL+D3z<5Q%q I> c2bFcTG5}D\&cx+bsshRq/큚w2 Zؖ/Ln?$l@pY!1_Jq.GFk$Q`UPTflt@])CrΠH)oQRJ!cԩUb' @ $"3r%eX,ݑ7N5H3Y,l% ԈhJs dTD5uv# O=c@w]^ZNQ'3aWX*0F vmJNP0@~\4#^"U|^LJ_^U0F-`IhquTq:,2g*&RvY"azW <,, RpJ ?C4In )2$>H|oܸ?-8X\$F\ˑ:X;Yb)P xA|41/ Kڱjpd]⬐F@ET0lJ@*VR*L6@qGO(גV^J+Q'>H2TfWA=EUF@΍BG g: ekiHm?^UGV+dڤe\L/7;"v )*T_ޥ?2BA۞T,# kOs_GXP+#G7 J+~%6&e`4*AD p̚CTHu(@ qQʇ¶~+MϓYrr˗.\<%w.\.\.\.\X˗/.\r>_J%y\ZZ[1h2˗?/!1A 0@a"Qq2#BP?.Ye_ƾ|6YeY~,iYe_/ھ͚ID~1}G #(K2؊g'%rW,D d. p1jeVC_)*R?[-Zz"4-\T_9?4KQ*?Y2Fm~95c!v]W1813b vqiEϤbomVz2:=ei.JYBHݒ(^ʌ+&F$1! dR5yc?9A~c}W;U{fe噚invd[^'G@&Wsi>R8F!w:"i/W*Qj3N'&ISrMZ% Q(憞GJHj6bk>IfQ?-3I6M?j_"V]e'6&cJFm<;LMhhdDCE'\sfƙ4zˊH'#&Q{[}=S3Qۤ&H{YHOzENv?ie䒔"zY>ͅAyBn2bv)ms D䶿zv}JM6C-.3Ou&늤g`҃Qp=5ߓV,nW37+&F]2ͶOOF6f+d };>)#jr+t6HjFij%&mZ|0x0fQ{[/迳U%tzviYq>$yU2}c1_S9IF+ڳ}.)Yq+k5TĠ&Şf,U 3 3O!/,cWřԔ '2zN/&-KzFrK$Mu3w>YeGMZjfҢ1(1SY f6M2Xb"ZXiǿÁF\Q{#S\[mdp*jh)42`9_12U!cJ=lI$wlH|VY~ %$d1O m3+Bp3cmM6R'6h[ZN)"-͘frE쿆dL׸]YdhXvlUi$Ir&$h+_{Q1ߗ/'z7#re&Y /9Cd՚i~>{I8R$+&)q["id+mv;wbfr/⮹o䩍Q[*H&>I5I46_&USV[1I.L3K32N# .K|_d9;7#ctC&+go8IrFM3O߶4IS$](cۥD*uCHcTzx1MŘq Dpv5CIkII%E.l*E%ӿET;P"`eYeLqIG (ԈN b9$!!E~*1K2,DEQ*ĭ. DH|1Z(n$. oj4U&!};"H.fd&Чĉv7ծ%f(lkۘe>xculhl;eȟE4U$$푔sXؤ3w,OqB}T2VAНkY}-qe.!1A 0@"Qa2qB`?/]t]Wˮ?BܢzuAki4cu(N<ů}&GҒV*f,0!T̺X^C2N&Dzf~E=:G,S^`'?GE_َ8!bNŋ&Bm3Iw J䢶\ظcV%\L8B+bٶ(ƙ4woTD™DIu fPkɑMJbssH?_<ۤ(\YTݛ4d[vgIQ(+Ȯ3ѶfMS"+ɨJӦ&(P^3$N.<ˍSIQM5(Y3!E$g$Þm5XۊLMB䵑7iXбKO.In5˟V0($N)Rg&فܘFpBB4&IE;f=JY\j%wG,{Yo|mne:~? ry)O~_ũS[#ZbR_NϨmTO>+{4Mdェ"5X$k7.j1'%&iwCg㒓I0cPH&3ɸ$g',춣IA\#_}dO s|1_䋔/rEɪ)tQgcYOerU3zQTn(l줇}-*chKI1N- TH7BchB4>~ 0% B^mFE;ks$Vihnk)ǃ$j_ Zt'RC*$bHKCϑE"eh͌QE&E=hؕ&}&abl\rEwS"ѵy2I#O{茈MQvq!=d[bo5፶)}¤be2FXֆ"$2iGr>$ll:̑4QB+BE 9]^l[-L䡶įc[c$| DXB}DN}r->#rY.˲'u 2|(_g1ǢD5H=+G&D^,نJ6$Nt(,/8ք4!2D$鮫ً11Hd" 1FR&},WZ"s@-4%f;bآ,Lwća \ 6KJD#d"!fI;V*]eTc"o#ɋUC6ke"Rf6)Q6쮮H/݃c1Y6FԷe)tSHse[Fr Ǖ_'֌$2y7[ԓJIcLWTN/[+z!>fOk%4ENǝv7~WE\בLW^WJQEzpkgdown/tests/testthat/assets/articles-images/0000755000176200001440000000000014672347601021312 5ustar liggesuserspkgdown/tests/testthat/assets/articles-images/_pkgdown.yml0000644000176200001440000000013614633374223023642 0ustar liggesuserstemplate: bootstrap: 5 figures: dev: "jpeg" fig.ext: "jpg" fig.width: 3 fig.asp: 1 pkgdown/tests/testthat/assets/articles-images/vignettes/0000755000176200001440000000000014672347601023322 5ustar liggesuserspkgdown/tests/testthat/assets/articles-images/vignettes/another-kitten.jpg0000644000176200001440000011760614633374223026770 0ustar liggesusersJFIFHHICC_PROFILE lcmsmntrRGB XYZ )9acspAPPL-lcms desc^cprt\ wtpthbkpt|rXYZgXYZbXYZrTRC@gTRC@bTRC@descc2textIXXYZ -XYZ 3XYZ o8XYZ bXYZ $curvck ?Q4!)2;FQw]kpz|i}0    ##*%%*525EE\    ##*%%*525EE\" {{,hGIve#Grw*Wr1Hw"1.hc&"]R:4tR{Rܪ!R=w4bSʮF.T`&NtN,=+ܽȎsB#h \DknTh Z19d̔wƎI{W{!G91Ɗr#n^ww1_QU_Mk'̖wǎys\+Gq5ʮT%0ĮFSM.A#o>AH␎^甅!z )ܮ^F^hbWUA #Bΰ.A!H^kb)B+0ƍ-EU^j2_ůkB˰.AE|!Hr1gsA(X^j2^ܪtkFơ%Ms20ƐR8{9s{xbj+y⿻U=UxְmG˟>\0{9s{"ċr5*^Tht5،k.|EWAHꪎ1 )(!ĎzQ U^hTkՕaa2I8W#Qő$RrcÉ3Q/*/4ZjFjʟc2TŐR#׹œ"IwW41CKWs-ji5kZŕ>lRH1R<ɕ"IWs(qYʮUNe ]5%d&#YoIe:TG )$!TqJ"Ah#B #9UF׻k֤ d8Q_ ) G09G9ZA>W9~zw**)*!k8s yB^^Sʓ&Tz (cW{מUQǁYKEQ|o >|v )yɒr=zaB |;9^dx5TU5jr iM(T B]LR#X0aCb+ȶw;]-D6d $q,=j .\#A 1zuܬ ֺuR# !|.\'#sA 0؜{ǃUMEI ԭQie2\$ys8.xҿA'>Tr{ܭXP C/=Tv+g%ZYΕ-% fL&A@>q'/4+))%n/GΙ(|V3s4x.\'+=BDWp?UOCG>(tOMU]ek>\1I6|åDRJ6\{E z._ʋA2W"|L| i|q7eL({ bLse5%{枾/GdD l)dAfJgT hp BGyt=Z`!VSR՟Ϳ"}&ѴGk=F ,Jc:h(MUΙ*A9(Р=v?0Lzj1}沱{믞PzɖՒlAɑ0pUY.T# c[;گA~HD_~nՊk@lҦ%I$ϛ*IB=Р+UdJښ^ .7]miVGi5ôUGigEG6\#a@;:qFb!0tj/=&f/V+O|rG@C_],jw=qd24H­a/9=w=$H[};7K7[m̗6\<{}uu|dg/=ysE(YSIY⟛r>G`3WysWn8ߴ{hO"l*W=$&'5Tʊh w= o\}^)vwTLϟreSտf>.A3Q^}95}eE< >w{^]̦i>98/Z;OgGPiE{,ښjp1Ryϱ:1y%*jm?~k|SzuiI|m} ?ʟJ}c1,*{j1Bty_SUgEd|=|VNО<[~ko {ɃaraoqG88A4XqG!{sz:e}Hq ::Ϲcxd(5S\C{L^Xcyߝ 1igW"Qic}yŐc X5a`;9͖Lj)Y-.^WÝPJas;k/ٞ!$t@9;yȓXD΁khj,Fz&;KҚuA`}q̐5!…81!4Σs 0%dqQLӪO= Uf>Fg7Ky_:>,:Hǎ0HI2!T@Yq(4B玗/v*\~/>{ٗVfElL GAm#8Q;kKCfk8ޜ#cDR45I?Mgw- }Ag&\D`@a0Yg}w:fDGj5TVWVAesgѤUH.tFRà + fKA!Zʤ3#USg ێ_c;l9˜SSD&Xol=75vonj1W#@H51,e^h?G %L\6Hjv{SU龧0&"r5sA ,JK73 TOB=vIH|gH}^/|v6ǯyN׾c 1NG=#meFs]Ĺ% ze*O|Wӵ5N;cͥ~4l8B6"7y#@POGvst2 7J04+ko6KO1fl!86"5;]l0E(U}'V˿4YLR8jGyW:mkrcBx;#VVÅM JNzGy՝,n5lnJxJq/^F#0CB81j`>JKI=3-6W>\)v35ySeE|?7֟\֣0bD&0pbUƉOB_WMSGu!m%JAOAC $ƥ|[Q1` 15d(ubŋ-GUA~bހזR4<us;]s*LmZ"50l +jjcmZ{rcL<ۋ":AΔ4iya֞F5c1 $8HH@+)t6p͸79[g ly6rkFmmNkyh0lj *xlt'ѭ,UmiG`Gd)г82/#$Hc(*s:8vVjlVʼn|˫qhkYG]g6:լS4R1J ""r3Gΰ{B{[)g~sy&1j4tUU\C*Do#FƣXֵQyWjGY-LTt}&I힅6 Zgkia6YOȈkc@ךakp2-ytS{l}C .?AYAYVsIHo59kֵ`V7-E;PnZϻz~Cu/"D]EVvSLPDF"w#ZֵkG >lBJvuw=h weVQ܈kX0B#B1ap쿒Dbkuv7 O{?~~m].|@ϟƈF5c1G,8UTՙ 6tO/> « i6݅֟=;}f~vmpVCt )7FX h!G8q RFP-E͡eop u3s`sNDF5cZ1(q"Įng$K<{u}%SeSu]|医^o0qF:tהj#Q`ш1bć$Xbg98DLƵ(.~Gzn~Smj ;9ֵ`E0#4z }&CҲuWnBVF齰6H95a8uNDcFǏ]K1U3={W]f2[ kai/DM* ͤҹ0QW~rQ0xB#c;>C1JxFNj͵z?y6|0lb1 ?NFbDGB64Zh~asÃ_Z*ovz4[+ R\5N9`B " т4 *]֛IYMOQQNv5zݷ>m 6Q?IڈBB0@ -<83=>&\%꺊L#+uoW>ly?і`#b>h <`l!j՞1K[_YOUmUaڻP\Or*1" `1! L cXof9uUuTy<[ n?DLR9`C1 k0cC11x%zO+v:J:R2=>5y;Ix}ƴhF 6a&1򿝼I$]$HwQ4F2J#ǎX>FbB,#W^vO,QVRex}>=fŃ] hpFW1`b`Ǎ>Ee"n(Wy{[K) 8pkpF0"ȜNNFXb pE4z3.cL,~=uv绝ʤ{׃,85ՐOg_{GF2|:1j+&@>na)p$euIlaZ67w{ZS9F7NI@ `ԑU|U]vD})i$[5(PzɌQ6=z:Mw3̄! ͔eFӲXg0I \)7ߤ$;Idžj7 + %͊/I$J"S݀A͜ jRH`08uTLEQ%0`ˋ5i:wR*3e sroM]&zpX6eߢoGя?"2t sa\iӼDgq95g] #~&2e9\^]=ΏPT Mn,8 6S(/>eWz߼&xqf4Uw/'=j-:>r݁=]}We',|F1٧U 4ʾ~IקN9̷ֽLGLe#N˃yy)Uw?^:Vm3ژVלoՙWvytB Лߙ\(1:G-6>,=l aeS/QCwծS@Yeq>ݍt g'):eSmu@H)ګm1E0! ]6X@u7)ݰ',$)DH1=YMꀜ l*9a t;e] d 4mkCt;(d焍<3C˱猀n/@Ҥ x'LSw]*nrA[<9W7t,l$t3{sZ_W^3[k;zލevR|U]+{ɼڠg 36_O|gE:bL>~5O|ᶒt=1捶1ne͎Dcy{@]O֮1ʽSǞ6~<<K9nٓ!(OWsOuGF&]JG}'KUmɖ-MtoB"%Vպ\Fpr[4_W~Ky&]2m'z19Mol=m2-V ӽyMPJuNcIm+w5X˦G$tѦ6^96Sb@ yR {VJRۦecJLEyLSÖ)BtgDZP5^4E$mYܧL2ޢ0IV]hcc#p;;"*/|7L\^V۠uBg ˇۯNl*:phtȌ8Հ7Ml&Uλl$H\;R˗PUpP鎥:8hLMɣp mٚSd*C#<ǣ+}puJ 6R9@e#׳]scꠔuך$O5i,Q{9)T(wDD[mӠJTULӌ`!n 5/4qe 0(tߥeUVM>L#<]ʌǷRmAVOGL[qx'^z􁩇vQKmE'EyĒI>mW_O6yisRH4D[Ξz昤I !ZMջßMPL@ M*<8Ѿ4AUNz:eKB$ dٰ)u[m$20c֚D& 0@66>Igu#1B(gg`008#~Cpc(q aG/A08A8A z=6cCq0!P8pb`880`Apd\|o=6c0``p0!a8L?111qpzl>.  >.qcapc.>?bbb`= qllll?~'$qGW67`38cal|$1>b+c 0`08Ä6666Ȍr\ ?Abc 0`>... 0}Ol|%rL>>6qL$'}&&.)C. 0`> 38Q>qL%'> LLL\\ 0}F  =\lll|lo8&M~bbbb}\ b}Nl||l?6>I>q111q}6cCE \0zS0~8&K 1x 8. 0`̌T..... _CGqL&gf2c 1s$qqqqp`}l|||o8qL%1'1q}6c 0bfAS)c6>KL% @8} C&.)Rq F>1OH]...... dz0~$rl|a! MbI+N7axL5\\\\`{8Q8&McJso6Լ旖XaMph *Il>&"#Jhuzڹ+`pc}G2\$WvH Ws!>A[B$)L\\\0zl|||`~}c.L% -?y]v]㈰LRp1qVdҪV0`z8qÆ`,\ɒHkss45 ~(mk\!h_8T׍=9jk  =G6>>>6$̆S)|?^seo_gKw4%uZ8D?j2$Wz \Rp`A7z$X2LLm!洚%(n؅]RBI;Yp0I 8LR0`=ll|loK,X#J]fs5-A_e%%3چSjG^Uyiɉz8qI$݋;H IW + ; M񍷌EV,ɯ{sXM]SQ_mZs,!pWbXnݻr80ab\`a׸]i]-t-o5{Wȼsͼo5NZ}y=S!R7!sس3r8~ܳ D f`e&Lն7Uy!zYVYhnmOȬzĂP*'+ҹZy+Sh5zó^@ORO%Kn7:{ں; 6GK=nUÇ~I_O >D%W䓜`:d|ד5|_`O0Z _૊cqs7Mmso<{CO.D4hn귓D]\8p!I$Yd2Q(J%'' YTu*W FuC#HH3Ç9=נUa%2f^a.*tlݞզi 7/ot-bwŊ&]c2֫SeJ&Dĝ˳3;H\$Cg8+"JY*yF(ER^[7-ITԃoӥt1R -gz+,j>$>:=pT+VB0]\cḚeV۳:U{956fHj MU -]ۯ~n~Q%Ge`I%z>yԡB , b p2LتU45r$6$e&5lbiO)yʺ[PItr"ʲ%7$660`Ap`:*S u *n !Cl=tZ.MB]el֚0KtjּKaZݻOxNk *,[YY +נP tlPB3@u!6*>/Xca͖A&mV~jPCQMfoqf̀,c 0f (S@= +9WW^j+MiY: ѯZͅ[EWOj.%Ib)': AQsqʸi4r|R,vRD16(cZX wDbZu%:f 5#A=q^B zxd1)24Ζ^w04d5zZ7G|m|_Ox}uihl&CEfN=qUT(U0n6B} l#$2ZGゕ櫬|gvZ㥋OC)mF 2lYRdv$deǮ `>7 #G DYd%NIZYdT^GWNޞMfƪi}N2FIs^$^XcЯyz!aF1YQ&FʳxbjREMZ~x+TUO[S_JDruZ#IO|*P  0l(ѴF>$ ]MvT%m hR]^ LX(VJV2fK!Ϯ8q7!` 22eɄ*[+FiJZ4Q@uC0"""lF~\HV*T8bn{ JҴ+M#_+ѭIW۷`#Asd.J3íʹk׆ydjԾ Ԍ&+xUT.Gr n+m"pRz 7pasC8&IHy*d$*Q ։k[G*8*BݝmEnvK77Iqᖜj8p*AS DBdh%YdyXLH>Qp0` kn --`^MM`*AAd!u(=()2&Mu0('';UTTjնQMJζZ%H*C+)q` 2c3I,5`V!`Zxk#|Prp)Fr%g]oSoU5hQ C[kkH pQ&Lf?3*Q\՟qE}SE$:e)N%g]wOsQ5XQJ, *?bXɒE341؂ػ;y/ګNYv9ʙFƶk!-[:ۺky-^C[ *UR8FG$2L8EdXNAIKsOZH|nҎCsݗHJ'bgKvml]Ku ĘZ_Z64SA2A~g$2䤇3G"SQz[_Z-5UY'WF8s3rXnio8ND.jz*v  YYH gq L(j9jEv)Ak)\Ȗ93c̜V@Y#MS/:b%㾈  1&PєᑤY )Z ]m\2@Ն# ~eeGH]⵮x8ޛh 7slFAAR61|>38:LJ+$#ڳPl*4sI*nܮF͒;oY'mi44?5E^V:## VR#}669,pDoivf2KT=-|Dbb92Sars!U<]-RxOJ8AA*T69p;3V4XU-Yюxڰh]9uu+ L&YTeue -}˿/xo 8  AFH:ʍ (4z)g)vxV͈' ~`Ѭql&IU$C)k56>7<-AA2*A}|&Fvwpq/(e +yNmxR5UVDN&Yă9#̤`@&3/pA!ÄK㙙Y0E^c\eRMsne8C(F*!)'Y?~I8pÇlbĽ.0 j'bK(d ª ZCn) bX]pAKɖX/'?rc}gfig콹o˰[ڎVɌV -Ï$a۴&F%ĞLlG*L2EJfD86S DX+Ì^I,Mrmo׭z uVX.ÏF3nj@&Iݍgl6)ڭb9dU@b=6 e|.d1ٹw<הXyMQ U8\YRGbfk,bڵ`Ǖ,YF,d!גG=f$LrA=Ln2X( f-?Cߐ<}׫]؆Y2vE S$# K!Fy$Mjmf=/]ʲx7h10Z{N2%>N˳yy%fK>ݛO%!jԧce֨$^a Tbgkvdn;pZ&Eŧ{vͫO`N(2|Bޏ% ml5:cM-^[Rgx YZJR'kO5$f:5YjWdX=&Itf~oÇ6>J!v<1 AO4~KƩP>,<=RIb3ʓ켰O<ɱgW{PI,%fa( ݤ[g< d&Ia!bYGYY'%GuY3o q!eN%(׮ZixΗuV<3\;$9Ԭ@^T) %˷[݋ZYfirdIY^7y<<РNJx<,Xfvbŋ,Y'9lb(DD^5Ku%yH&aקku=y<9xk*  yGF8}A`)qio`֡jW]B|vov|+—W=gA5 +%:JCV  ½:tS>b1Fc(P I%;R-#ÉUY\UPN:bםi՝GoD|y|v= z|M:tקVR&x¤!qqqqz(Ta05WԞђMmw=o]:/+>:tө^zסRJh6Hep0`qqq^zt1|&X4:ZBN:uׯxԎzשRJ*JCX088^8g^8ԩuuuR R]]$XdӆÍ0#8Fx^8838AVWFGGI")ÍF!1A"Qa 2q#0@BPRb3CSr$`4p? %ș?`c^>KEe~iIua7M`}^e=6F`ҩPT/`ZQ:LveĦUj'_ya62ďs>c=")V6\+4qY|LBZ[=;89yN.9tU= ʊ-2bRi*vE&k޻)!K %@%lhx3G )_mDg_P'g 8 Cd* nzۭ1UldyψB|*Ji&h>#eubPL ˮNe{# l\u ovEM`TZjpKdS9 ʺZZ󛂤[j·Nܤ_.&]@-k+Uыx{O u}ԏ{-KHwv.ŌZ}L6 ,Pk5RPQ?Ke"8`D)]wXn#)݉h/_$B!Uc5],*KbNLn* ۘFuN?ؙDFu~ҠhĊ5QB9uWnU*QaUd'=HwU}%I<Q)OoSif+7hYWu*ᨾG}9zh6ޟi*S=zf6}zVDG"X^7^!$1!cc1BLW̠P\.GIxlA-[b\FGb ۘ( <hgC6N*~֙ *;R^!oȹ4B@!FFPAi%} vJH|+T GSePW'֖j8_CzJմ=>=*b>r37+UUzyE;Ys򴨌n #f^[^&"-MX7 `h=ø!Cc*Ppso8) [,5 p\A|ӨNb}WC1 Gbu7[MWevT]o%)󷨚NUf# ݥS{Aj3)vn }WHMZhf-J(*'Oij FŶe, L m M&G@D Ŗ8׆[OscBT\ F?l*u {d,jfWSTr `Kq5mBU^HDMQJ}y_1(j;8VFNi?ߕv{;2JPdyR]WeV[{6Su:"jEڌa A ̀z@jILN P BEzAm>dC,y:e 0 ZDÄd1X~[MAq|>vosu R=3,Ӥ{m,J7K=FJ p]]rjjoLTt ځ* *i0*۪q+vf=iM:tW#4FnZHoS2XK2:^oT5N#+oD6c~ZTCNr C(uFJy Ii,/J)1VV;~1E} JB>PbWb $߬eh.9h R b0%JZVɼ6JN VO3X^ԚoiHSѽa֙}9ڶ ۃ{4L*.A`h)jPB.u_5ݛhթA*x>bi[[IZ=@]wR P.,=|J(ƣ5fi 01PPlhvXӪWG(M&|;Ŏ>th\Qy1iHFaoѿSw,*/\1c Vo$[pDyߥMFn13]/djay>F{m2&zEesP8&# ĸ62ܟÌpqҨJgR'#fOBco>fi补uj |=@> zhQ:d*_Y+K5:o˷tԩOf=D`^[X3#=#l܎~PkP.Fl" 3k+sɰPR98à2V8bNQA: StaڇȲta+ҪթUOHyE{PЕHJFW}zGIs}vIYlkQzF ?)xŎ261JiB /Ci^fޱj5JYjR}OUxjjd 'XVXfPg*|`e:EjS-+-J}Ʋjh5HDDWڍ>KI ::R TSE\ޡEfp!Xm~>N;|ds`t3cBU!OرSbpD؄ ^^_XiuKJoC?-bGzMOg:}m2>R7=uT.VVCS㶡[K4U7Xqc4ڝ= &f<#^Щk` pV?6t;AGC~֔_PaͦZ1OAG Rz b2/5jiA^B6u#zn7@`L1aLWaz2ѿ.5|M%`RPڤ65-EeF' X\ΪE|;/lme gKkP,r>bRX8X_} za{Rm)x+'yF™_> }YfT{s \e "MLZj@\5`l0? *`7VhW5]Y<@|P9zoP;&D\o+#t7Mm٬ i~DfVZu69Ρu,ŴՏI9 iJ&%jT u)+Te[4EZ'̓ɟßV1N"۲8žbͦz=@Wrf~=ZLƦH'ei/vVaQQduS `Y6 CC E @mZvtV5]V+ije52/-y+S-2K;zJkS`^MR5pT֙W\$Oen[ZGxYM’Te`mlBQN!(QJVwWX6EI]\k{!‚K5]5 WiG܅="1M-ź^h|BX/ Rܣ2WAPǙ]\R+ MQ EQu13n Omٔ ڮ' J|'L~SI7넭K2RCҪajuN$ ?R;j1u:馦hVS?{+4Աt3=fj)ޞ2G4ۣQ+v_j>V@TS)bř.Lн4qj[BԨF}QVTB mۍ JzѥV\ogJ +[|SZS닋_ٹfY 56NRpllZU=g`}oHl@bmo=axGp?R;uȔ*R;V, yhY/J6ܤ3Wٴ)] Z7 紎-Dg&ITb"_9ooI3aqP%|ʕ.L^)$x6 [D 2-Ѓ*|#iUmR TMU#P⦐딲]ZT\yMIi)5Z&h?ٖ\!^-^Qh%H7ǩB$ԳRGK5 UHaɽ/4}vU=Gh1pͱ0+ɶfzܟmaiWR*3ޢioѩ_!YOH.iBW q6 pq O؏D#A7ذ>RJpEMϬ>-o"rώ2uP׊ JEGE 2i_Ċm*#.#[%>&vs. ¬ 9)>:cA[ )CYW8jU5J+f ZN*x߁yzBi .f_U_PnB!0^R F`majh˼YOT‘Q.Np`cUPǨmܘi}ġԠV𷩵Ri D,E tծ:ZT5!VBset$X"wb}Hwr2hLiӐյfAOPBp~Tݠcp,~cST l*ԹPּ A_^+  ۈQx]BE4.>`M54ڕj)l73PR^iT=D@o hJPjj͖=  NO.f&RCbL joJ+smnb5*Sjm_a5U<ލG͔ѽ)lLӷN֨ܖ}B+QuFߵnHP"jc4ui (p.p,䶥C1n7ӹ`f= JB"Uk >aOHyu3Lo`zZi7l[?*15X|h|S lz͋Gwq&ǥJ`6*g5ŘSmAJnZvUU){N}ԒO%o:bj{^GLzM} J*4֒PǙqs(WUB{)jjIU ABJͱ55+iҗ-LCU.pn7\ XMh\f/n4ڟieՂzCj@%mItWO8yZBEڢ6:z4odE<oUyi_? [#ҭ17yw=hfͺDe @E}քaA=S*=n`qkʋETBmX\;Ś J./c{+ԦnPg3ڐ`1+ϣkYyzE.Xt|l(7c?2 .'p Ԛm-`ZuB1jQҕV$x3V7[En{i5QZNj(5Qzbki5lU% >S5kl5&jvJEwzAPu!Xl%=#&QY";Um-J fwR_*R*eYG{cnUV}m7IIk_S{dQM(7O|YQ He8$@`Eѯ~Q,!3`6pL6b{Z ߬˛K%C{TTLξK  ؠ NzPP.iRCNS ]{ER\`) ` dmpqjiֲz,e%jGk(>rrMAh4s'jj}* pcw;M 颽fZ@= 2p 2fTTcn\}XJ\]ԝ jj(# JM73g$_R6S DS[ GW?SNekA06C!?j11 "nb'&.DlÑiv qܻr[x\:Y[E6iMS}VtWGDj?Puϲoog!JT96Zk'(*tӮ) S[T;_X.fqd|Li 8zzHNAfXo!)!UgU=1(v_e=Kn2|a̻6'0d`< tb(?]ߨm*jm_ W下JT@BS YiJyQEeb=3ʞPSRJ_>o%WaMҽc&tgoAhQmFVkߐۙp3hXna+8fKqcc2 SD y17Ȋn&ǸmIXa!Ǩ6B(a`U5wK%ɴQ O(a0d?93~+w'#2H{pV?Aǫ^g*nEI̙jAF()KuTolB^Ш͉lPL,ynmqcJE .A"@#Ӹ0g| flG7XI0nn!(ۭф-V|*n^kmiɵ@@&4SH筥 f'13mH4 d!bK,m/Pp;a%KRiP5`{'*/ /(!U7wBC2Xr|k Q+9L.X0l`g,E>XMɅHoRP%)i^LZ=s*1h:f/*(2-{GP`pi,e/yp faMs :Z2Lm~TfN}Lv| )REl%=gȟХ:I-s(<@E@# =ḨmvGA/a爃m`O[CPTJKN`;VE[ڒ0kz3R-ko(@/bZAdw (Yr nטI%^=s { 28.JX{@%ŁeQF6 ݋R_,5csqct0*?p>$"Ap/K XK/xn/݉`a&[tSӻ?v( AῩLƲjB&j)BU997Rl vig1TffI A!# 1V4ɻ8thiĆ[=&; -;!{TS@o(9.T[ȊIX˘LLAyR mЎ?;{69 j&{hYzGKb,OA}xwD)iS*SchFQ,2LW,oJGa=o_чH 0 >/UҒqe.5*gkcדY!]$# k/y8il:E2p0!T߈k0OY}`0h0w!2G<*"+[)񞧁5U}K'JjNI3GzCuVA5: 76P-k锓"_xA6/Y=atZ2=X0%JULpJZZKtS)iTXsʵ{Zr׉N;. ՗u=Pz•=aRN'֖ކ:Da ̴ q u~ }z0"@&Qq5l~LAnSeBy`CSSۈN>nOn}&nokHcy3pA߶\`=!LrM^%*Lgm%CǓ)ӧw#E}Mv&ȣ(%:"?80GCyu#KK:rbxX 0IoG@/ܓ5V2Ó*ۓMUQ]WOVgNzzRALu*FժIjPtQ`XJj8Q*JN?GbQ;#rn%EkyzC= {2Jr`&#u`0 􌧈Ay&bA'X,<ɔ(^ $h D-QPNZkEv 3ドUShoň nhuw^b^^TBejM̱oF`1OIcap!3m939 Ff79Jj9Y #EcUɛnq[pw($ #*6I67&D @y܉j/8{|CE'FS`0AOL@`7Z6s  =bHHe}E(0~U1#= h6=& R2Qy x^Tb%M8=l%B̄$EĸxqCzb1H8!i^Vc-)MbVOO*9cbbX^k(#s Yl:F&a(zGEf#(B~!+|^rfP^3bor?hPJ xhyKE>eǹ61XX@o݌/V6J􌨖E6Jn#pLVhT\Ɍp O 壓vS~ yd2vPa;v͵w9TTO1R5l}LΓqnEFfJL$ ve廈x/q.J㸊G1Xs#"H oei^VeD#8 ҍKxGۏp%lEdۙ=Ihdŧ{-W2FC~0*": lLE B5U==؉au?0e2Xa.C{v `p .@oA(/)T+8|JɴHu}0 ,P9mʵlɷ 8m䓑)v~+;K_X!G$E´Cէr Lʛ* ߨ;XGkFq2޼#TF^zehqiB@jJ5@n"H|@wxcWW'헊; D [Ģ0.V ^i4T` SY\*?*ZYǡ5qyJFAYZTJN.1Tdu0E(|㜱%YkIojf!-u~b%KDakM8~=GC*zʄc h 'KvZ#]J$nʬJn<ӰZB[Ԕ+(.+DaD`|?j=fW Pd^ZX\c2XxY!A<6i[@|Nn/q T5aYQBP.zN:۬S%0bSۙ͢-/G}`# N7Yգ}QԒveU7 `fw8+\AØ>ՙec)&/KzFlJhI79dľG4Q-5]H,l)ȞƱۋtYM֖m=X Xaa,pwϸ;x1RhN])5Q\X+9zʿH fnwnn6NZ,]kkZ6brm`!UR0&52J)ȰhdH \^8L iʔ=|GFbTe@a"9$!w wa#%4:5.}'h}WzhmPUSDj`}c"g6CRjPQo M:Z: x&9!g`- (:'1xbIFW ꒣Ҥ/ $Ǐu%,A.Ӣs7p{9v'З\@cXH T0xX pe2`Sc19f~ZLq>O!'Oq?ӈg K10fa- @ eAqoڙ6˘okK z4@ DǺ".sf}_xm= b~YOJD',A-m0ܘl ĉ⁌!07V &\˱̶g_HC3øACpf -%9a7'30AyAA;k˓6&X⁌!~^$a.]& Cc>\{\,\c\am-ya2E"I2L \ e ˠ3˷v wq/iDjn"AȄZcb)\s>?1!Y| 1 7"{b`4<߸ߙv "¬8 c!Zg90=ÜC°0_D$b_~ehZ2o!0)ێe `AɛL6 fK/̱׺{ikLg@dE`p!M& b/s&t{ͣ0Ysh;!a0ߘ- - %baP%6N2@هq92`={o26/v c19̷Ywc0;iXIaViec7s=ۄ.KֆBD! #/ " W/a M]DQb(.I3<^xA&֙"q/<q0Cf  ApDL˫M q )ctŧK7ufQs 6'Q5b:wm5ք0`0 X F.ywp#v;o6kiDJ9 =' jeaifֹ,AԎcløN=O#S Gbc2@74!][zw E(,9 [7H 2~>>x\!q^/%^C[ss16`0 M %O+ &ț̺F=cIŢ)91¨,LE )" @jB 0Mre;R Mf.SvXFXr1*/!aeBjERYj[jUbR`_( RL\0r`_1&xLx4Pnf_q<{+ YQi9SS6 3oBaWax˃ & KK9Ogp lK.g]D0ՏLvs掮JN]IۘZPB2O# 9n bh"8K70--&iS662_V> vCMGr&וk̨jqi&X|@7n3jZ1p T`/񙺈k #sX1VJ;^VXbBֹ?+3S"$J ı'JukzB#߈ä>PBGʁ*/aq>;h.8>ደ.`ULu?Z,6/D_OJG DJ?J tE"wwZ;{05&WP@Sum, U9 J݃q|M ca1@t qyAQ}a z{|T\fEQ)%-S5*yZDD@A(b%0(AOs;v1JQY+f+Hw5ª,fRihDXE=x{ޞ;OHQ/{^ydL,LOoɩ+"DEnB6y|GWχd]1HG<)V!oBŵ6&?L9Q Ji^PRV8<䬳Y|myB1ȇ隱TK'ZTȴmn٩?-K=,Lׄ-K(+jȮM4&$ŎX8"6i"ԓ~+iͩS"YeOԏj" )$&&21՗NKGGR2qN)Jz FFE^/eC8(MH ԐfT摧QR}u HHԒw ~T UL,ŹHO %%,3^-VHȡ]()s+K%蜟"jIIq=Y<{PX) Xq(4kKxbXL " 89 [ЋLR(tI544%Y|le^ŊB^$PLHlV,T*FlYbbI&HSQBeLL\a ?X)V"Ћl@9D(쾊ذ+(: fÍ=闾JCE -@i,X\ f+y(= XCB klYYcXd(iL袅ۨ2)1G؋/|d'ұy8E"X}s$K lB샍薛E=-<_DcC=|shR$"ђ+(So- *bHM6K*FhBdhF^|ˬ{%DU.F2jIR䋕NjHq-:ԋOJ5445DŽ.8*Ěbw- צGV?K8j90JLM ",R#3Ӣ:м%k^E!eQv_L&GPSM5]!xMpV(hh4$a݈Q]/*bbj8$!DX^X~QX$+g"{*+k$;%4MlXcmo ^V$K)dCRe+9'b/C#Ð䨲,,N؄9B{YLHQG~Q5>&Fj %<=a bÎ,R/ch鐘1 3h,M G;Sab8HiԶ=2H-,$OQذ/7C'I{hxt/FJVf[<&\,%5{[cyHiDɈ$"Q?M{rD#Tqf^-b"3Z\j+oz5/ݐ%efXBN5_el6^+#Qė#CӢB²&Ņ#o^+!mr8$X9͒|&Kղ"xI}߹(ذNN$Zk(e3g![az[a1z؊1z]oyYӏTk+{MԎzIbڿ:b1XAr -5("zn#(hҏ6H,P4AP!i}>Wp(Qb$&Yc=rBGI4ikѥMȞC[Dz BC$9rhͩ8JUV=qoRk(EHRBp%Ee11"XJdRh]*l$ bDD4 B%-5tY[,QGIt%a bcJE|CP^:WRR~I>G:[iONdRo46ԂtЛOzvגTԩ2Q܅@g:6'Ӵ}.KZ ;WCJ5(9WlqziIկGjk}N} B]6KM覩ІEa"(((x4$Tpv=IMgSˆׁʗ_rsgKzzzwlӕIKJM䖜#ÿElDH V/2ebe"Zw=6+^JMMM.=!Ƈ!HOm% bFB|Bbt6gU2"r~ȩ|5viQ2)B)h<&&X yCBi#uTP Ϩ~[,LuBaq(AUtq_ DWQ[48$"-mG_]4!ρ̾q/%2袈XMП T)Dr,bg5B, ~T6UE^f'B:Yy_$K$k}""- K-ض^/ .I>6XS9/}`"H|ؒ(q)}DYHl >ԓ,M1ĬYx}DBYHhT,d(:ɉ4V_q%cem'JLZLbe!<c)h !7E .v" %\VignetteIndexEntry{kitten} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ## `knitr::include_graphics()` ``` {r} knitr::include_graphics("../man/figures/kitten.jpg") ``` ``` {r} knitr::include_graphics("another-kitten.jpg") ``` ## rmarkdown ![](../man/figures/kitten.jpg) ![](another-kitten.jpg) ## External package ```{r magick} magick::image_read("another-kitten.jpg") ``` ## Plot ```{r plot} plot(1:3) ```pkgdown/tests/testthat/assets/articles-images/docs/0000755000176200001440000000000014614000540022222 5ustar liggesuserspkgdown/tests/testthat/assets/articles-images/docs/reference/0000755000176200001440000000000014614000536024165 5ustar liggesuserspkgdown/tests/testthat/assets/articles-images/docs/reference/figures/0000755000176200001440000000000014614000536025631 5ustar liggesuserspkgdown/tests/testthat/assets/articles-images/docs/reference/figures/kitten.jpg0000644000176200001440000014335714614000536027646 0ustar liggesusersJFIFHHICC_PROFILE lcmsmntrRGB XYZ )9acspAPPL-lcms desc^cprt\ wtpthbkpt|rXYZgXYZbXYZrTRC@gTRC@bTRC@descc2textIXXYZ -XYZ 3XYZ o8XYZ bXYZ $curvck ?Q4!)2;FQw]kpz|i}0    ##*%%*525EE\    ##*%%*525EE\" ~TQPA 1 "oD@DA@A"" F EEcDD7 " " j PQȂEh" "Tb((QA D*""UU@* "FA@ 4TCv"9@F "*(""#QDD@ADQv Wyr]KD@QF(55j UCv {>{/V"+"A L]^~CXh4D݀(|B_FRJLO>m%|Ķ7=]?]UW]:cXe4AvK;6վ8Līy.2<#PG OWxWu =.7d%ov-yDwn~SyίN೭^lkQ Fpbf7C@Z;B4~[$> `_8noNײt9Y}o0FW=涨3'^hy[\Rv1m(0>{Aύy5 Wb *y3c58(WMWk؇o6=:/}Y hD7( =S)Ǥ(gЪ댧;XGIrdZO}1nA)$[=Wmg]Ӕk_`zkW3Q35ԾcZPPM ( /LM;͙uK2Ãfl\IQ1+.۾]=sɍb T7H{H7TA dql˰x"zvGwms[RݡKʮ*z~c<UE@V( sUعPzGPe'4c^hp= |[p~lkPTQ@TCt_Gc,r5V|FͬkY֎=Sy"M{.͞H(( nDQ`7\o=G7^f}ݤrƮd\}_V7" Uy+EcȖw)yqw,J؛$2#afMlz7ͭDP ((YO4 g1qZpϤ{u-ܻA-+KgA4T{hn];y#S>Q`tFSҺXg͎Dt8f oZ E@ (cs q:K)wYQ6MH-o8 y'>syZҽOK0FsWɍDh@ )踼߈.v|Ӧ~ut$㳾Tj/П}X}#&e$A;㕽~~h (H?(pWuUI&.: Ef';ovvwjO=cgZ5 2 +įHqU8Ӛu\#VHyk,OC{]Y3Vy ("F9f+i=Ns>|vG-iD_h$[\_NzI" 宊rgʹFu~&ISowQ?0rOouH;n3:<ƈTAjnPC=24͉Gz\;L-Μ۩km/ɾ/{o//&D@ "㬧+[H}\`y+vdj5nizM?1As}v{u4ؾO{=sMZAvA%'^b52EDDD{}c|8WQmHˠP??l?I ־BmEͨA"WkO&R _f,'5{n.r:n7[oZwџX:AшDApU k+A7yq*Ҹ0pj{5nɆmfƣ2;dvlcEA& A '0. (WqYhr<4c7ܻ:!m{?3~u^<@"""""5kDžlVG_ +>UxQ)W9%RS,,ws'|zL{s?1 $#Pby5w},! ^vSs(%QYNʉk7[ݛ[A~ٹ4IP5`B9C4[Cwei +)vE4X>3vsBa?F:Q/ E 1#5tIW:JvԯyZCsf%VbbNV[u~^MjpDDֱ Q5P(6CD?.h9.:IbĬ^|΢PV#Ʌfn?/v́~~^lA"cZT\(OBuڭ,ogDq֛:[E_g7Ec,Oq9b $cX5"/v1xȴ6#62Ghdz\:@lK Hw}V/<؈֌hA0"FF N۵2? IJ=? 'AN,=qY9mcԞFQ1D`6|0kp Uzt2J5-d;,\b]uzx3ͪo#Z (yR*6ˏԹ#v;㇗eY$i|bnKvm`0DDֱF#CM."}*LT:mm wo\E+]'鯡c:QF5b5w5Z7EˈpHm9*> dv7O?5Q{[{w@kX#zXK^Y3҆Cˉsv? 6@q"ͳbj"r7ɺ7<#KkQkZDS[ k2 jPuYœWYpVeyK_5{u%gj^`cAs:$]-`G`pSŭ( Ej5]znaK*s[`2g F#֠G9k w!>RlS gz|oU`QjU!F`ئZ[/6ڀ"5cZ:xnN1MePT8ő2V:Y?\Hc;_On /_wWHuսo k֠K AiG"K,[UqlZǩrw%*,]Զ^ש;w5-FcX֠Q^S\b{\tTP>2_:R?OYQJg%޾~Lb%" k#TWg$9,Y6U2qؿct;/Oiyd2)']Yx]-Gֳ-&"#cLm$nV%SMeYpt/֮M d`ɺvư{]4.@Dj#QmD`Cc23>@^쯛{}~M6ʒ{}l*!<};e"@@@TDy[\\OR 9mko8E&Vưuzz,>wM( yxch2AjhsZt _5ac{W·6fU =}WVM QPxj#I+J;Ec2*$n -hڽs]7736D`[=gn?D8+B[9%4^#u&Zzʥ<2k%l#AG=ZZΞ3?w іtq<]9WCV),hcDK*^+bǖﶙ9pDGq+X?WXoʝ/Tlk45 yMrc%TEL}7oڳYNa (sSʦv6Dzbz-~MUW"jZ9Nh/GmNv^Gm" =#GOrOXReqZ:m&un [Q)W{7 WiI'=ܝObs}}^F D+7q\?Zls/sOᇮ>k'/*믤g~x/6}VȻ\]ek+_Id2Kx>uӻ=s9vhQŒ>\i-:K7{iXRMT`sܠ+h5QA珍|yހ~|r]n -pW\9UAA"  *5g0HGGե5DWWEDA@Db"#婮-:ļeY* h  zUxADDA@Aj5v'  \ڀ@A #ִj"AUQ9U6"" AcZ""(5 Usթl mM1a& Mpq=6>0B]2V[|)$g ޾a[:Z} 3Xpz̵v=0g+YoPgW|vXԓMg+._#Wsmf%wO!48g+8;(ǃMmsՄ(K~O#Fn?Ͳ>o`4Vy%ޫ]9\ G껐Rl l2z,ݯU`!BX??Kp櫯 H `B'tSf~A۵NL1+.^s'E'&a#F}Wm<ҷjDsl,erJ%qRcc U5 hR+~t% L% 3>lج5cf@rlNZhӪB8Mʢ940J.qsh7 IEh Tޞaxq!s*5[Zim3䦚bS*UUP5ew*!e{)Wz@L< Elg(֑V@/7NͮKVRG ]˞jHfUn9\|Ɣ]9x.Wȭ.}s͸Ev֔%˧-`G䞫k_v5dzeǒztt:;il 9m͂c!EΣnD`!D)0"*V `1$ZĬb@"&"bbah$+3 @&, DWv"@_-k6_K~O[ \=gqx`{zM*rܶ :ϛ&ks{=߆~.]KO|Ã[>x{>_C=[~go?7G]<_og>w[?K+{9{oc2Vf#$,$)WG]4*-#&fBV1 q($D2!"P@#1 2$03A`BzX+0vcOm[qMhO)\7X-ђm}7ZCodݦFi]h`hKb&&32&2g;|s9#pngb2}r^-,쬸?^͠*\ꮟ핚Wz,_WwXg^f-zWE F$;eyF1,{1%.؍YuV-ϳabC EG"qLO cCRJ[J.,dLaZZ\m6Uk0H5?ySL II+zOʓ$G}C*J?jl鍫6ftc\PnfÇeP:.p#Vɒ. t*w4~qDZk(Њ~jV@Z@q֩-š|\XwύVGgOreuxw7墎ov ŭZN@'S9._M ;[9oi?"wmez<]"Zh(UU5aW©)*4Ɨ-€~#w>UE8 B&[rq%#eO $82qe*{o=M&L]Bß[\p,#AuN.v`%sjk ;/<(sL'ga[~ݓ>bJ >X7E(:vp' ƸRø#y.\ߡ0^Mcwe]4}RJ9V,W8J}T\0mP%u%Ai# 5G~&ԳຣZH'X A|ZHm /Khʻ)SG5ÓRvr}|jUo5dbϰsvٚ-gH@OeI5酟=wp/e;+4Wv7Wmy#;M gnQL'2捞1601|$Y2.oUXֲ&H#YB=;>&i M^ u'բ\gUJdO-z|ڹLD,H` T72y ]fKA6V龱o^ḫ퍒X*܏Z7CLdvwl3FҐA}\~}C?,!l^h4kׄrYAo_W+?3QMbOR>h0 ORp6ЕoEa]B&ڝ=DFU}- |ZN䣉 f*<اډ^Ll{K5ܮSR*~}"y#!⬮-\:3Z lR3uAiRl8T I]٨€+Sg0k~I**gkkw:1)/_ci"C,L"'mp>' Kl45q%Գ$Rho*Eu(+ |鶷:4T}C$f_n5䶮Ix"˘۳Xgfc-0!I~u򱶄HT,3&/۳4@Eq?>3dF]aQG>-SQ<+2_rECXG9J mqM NNW 6i"CVKE#2 c@\RxrZc=8}}__\V["9Α<)q&̖`DN0C,-YO$bR+f&=Jcr,ҕ8ȎЖm i}XCݥW!>#&J&q!idLˀ!\CYCȄgCS'}g"?q77@F/ЭLJ ",{g39 WUDOUc"N\6!0;Q\J_2ڕ+%`m5vzӍvLX 3<@ "J-3KE6VDerCw\17 PBQı<ܪc ~FqVθu>0 sNd[Y*l&M2UO;.32Y)%_W~)y%43s;fybh&r "$GO!hAZ߬.91Avai ٥gg fхjܻ q65|DAgf1]f-,!-,Nh^hvD:g<#^iVV! 9Zf> m)yd-ۈm8;)3q]E ݺmmk;]"n صCa t)b$<Ȓe+)ު%BK"kGXKFc?Έ_rt H l8 @agވ> ضl{T3`.}+]JYCIu#=Ö1败HK 0†fR0Be`K6JDsbӚ!6Q}#'7"}.5bu)5',0UI #xς:nލ]*5nbW; jnZb[‹Q܇ۅf1s<%ߟ\1bg2 hzgOE65Xz8T%#Wly"F!mOr3`1$vC}./צt˱XEjJuϢV7< ^'*eu\ŝ-ˆ,=s&*J6brC Y5 ")fc:=56,%<c cQ5l\,(J;eC"$v91"9ALNk0@dO 1\l+ciT(mI0v|pЭuUQ?J NçjSR`|$S"oanʢ"E ܥjB\N,N{$eM.$ض#YIR3,VSW^-hJe.e+΂߰aA܀?Ϝ`aU尙0~p}FIު^%*g@& s]¥@ذ5EZR7nï~̤֤֔>)E-d,[զPPO#iMEqN'-$66`bވ2$~_rBw99sy`H}e}hO"8,* P`תEFC[NGؙ7ĽevѻAjZz6ͺϛl\]uf$CYwoQYl,dѢ d2j hX;%LY,gެAfC)(j9s9sH aFNB¯%Xx8 VN ĕ >SD6W¶rޫ=A~c{kؖuA)de8-&6Q),lK+6PtݘA"WY;<Ƞ]׎K$YpZ{uOؘs9s9s.d8=m VdJ3R]eĭjnQ\g.4_)˔e.׹zR9`(M6M%+!WdXJ-A2:LJ$!A-DN_oSIg9s9sr8!T^/%Yؿ(zDCUWf#Rcń65a5\eSjEV]#>>BduU!gRFhzR1 0Cbd=c+Yc;PB8&>֥LTul> RZQQRLXapbU,x5[م$秊\J{FʷbeUf"&A*/]lk `0ؒ[2ԭP̤JTve,9s9s?ǜdd16![2X&?DOWn"}/6+Ȱ`,gܻybnVפb=kIr:SZ,E;3}h6卤a6 ]IFWWxZ )oH{x)ǜ2~IJ3 Ab%Vfu}bl7M&lkk6ا,DL ,^l5Wmt@ՊPCn"{Sal@ٙ'V^'NE?1͟4{>XfUSn*5f[ڙ Zr.U^\}r[ o^$  k^g#`J!C%!2omm, .?o&NK'-Aq6 "O2 ei#[skzԶ`O`$e QAqLm!׮)7f2uc,EX*nJn5`C+YBُ}ŝ~Sq0+TTe_oq6}y? g] $B<r#I@F)k.(hmWk1upKc$ aN]eA˝C6&uv w)ַjV"z&z Ky7f =ʐ1MΔAH&fbf y*ȏYrya̡ްv"+ nӚAOhqb|laţ)E MUdsr=d^|ًF@N[@Ƌ՚T&fNȚV":EIjڝbcM<ࢹIݷ01`0JnF!Rϱ2S^<|1wvy%RUZ#5? |~Pv,e XXCKc ܝ(7))a]Vq:Gȃw >lZ#\L?`,"g, 6jmVe5?fB :nƷvL il\s%X?RaV+ֻ8oh/&SյXu1,& L[FjaMd*pG5r-P)Uf$F%ɸJ-gs3+R9aLN2&mkeUqhI-B0{R,;Ckz6E R9u A{n@uۘUlOּ̫{"]YWH=UaA֮BukVkUaj`LS-Ef[hW`)ݷAINec9s(( arg]&\$,ӘbhEq BmeΗvkQZY׮":) eI;Vrj܆aP_g+VçK~6.ygq).ê-Y{Sm㓱^\nv(Z ǐwQ\s8̮2kzSq0Yb-b'*k_+5$Qg_ i XI=49's#K0Ĵ{ |q-%9&YG1{n9_T6O0xŴHC,*]bl*ܰy o"]TZ,,R/JN6WY&.gqz0SE:}8Ȍ8q&m7LZ`^>blyk9M";dHesX۞]0H- ~H޳363]snFeNױ Hhٸ%FMb 6&p䰒z6u\+R+` 2 s[p 3$  +eYi?+kˣKo%XMGnqr9LlA$8MCOcam ,`53fdS31,R}QK]\ su3 #]1WR'B*X2>AȰµͮrݙT=Q26<J!&P&Xʈ:S&7`>-ԛBq{& K3}:s>ʺab>j͆XJ'h9 a4Z0hC$qf3SeSݖ=,eϷ0 rɜE )ZK9|ƫPӁD#"FBc 2 sBXZCkOZL =U[?UXң\AV HMǗ{'uemyl#is\肈|dd&2*dxi G8ŞÌm~=zLWMCι83sM"ϛ6shfұ^U9``tz"bF{mc^qSiO+Dؽn9yOo|Z'fiOQig$bq?6-[υ\7vF7-wxV{5onC@Jڼ -e&+8hL}f+^1Xc!Q#:\Ƣmx;8PH2G$c=c,3Hޙ1XfN>kU+*^][)*1,* "8)ιx38qg\mH,yW-eK #jеOu]h*ڎW¬`xyk(xΛyJ<:mrR3?9o9s?ל99s9s9}sF!1A"Qa2qBP#R3br C$S`@cs?|[U荵wHp?R?of؜b0}UŦx]ęBׇǪc;KKswuuiD{Y6=Т۞5ePuWa2xm#.#CdkwV.$` :T6?n<u='qy>Iś+&jgx> pj3;vY* 'P;8 pas5"'Tkw7 A?GBLQcIɖm FC]tQ"z'puQxD"P`x/-[FiRS_+Ԩ&FF]f_k >v2~9D&*9,7ˊ|Ӎ;aq7ߌ&!UkUFKD v]y[ "mG4" )!E'eU]3꣼8˒"%$Zچ-v%Ibѧ|y;](Mq1qw皍΃M.q^3ztWLwֻm vgt |e&`|cCl&u} 0?izOx^ѡĵOy`3Nc}=OQ!8C;|\Cv#';P%QYZ.QNER߈X":?ě3$.Q|6itF㱟TTAٽ#0/5T,l@''tlV\)kz^ .BmidZrg6Q"Ph?RyBsT!ip"ӧȦ8'\&M%ߢ/P`ȻGȟo dsuDM}ߦB^zkC@kN5Ic@v9ivLu5^ r5Sp "hlW c>i+<;V7K;Eu ˿޳T_b2 e8G-qrt>E= 6=J{&Y#qA÷|4U@ʹwO7DNFqRiig `-r@^˲M 'rwϴaVRkir5Zdq<ԾV}ώă벸`&j4QI{!}!^tQݼy883(=a\AB&:jkL^To4^d7[](q2pFZ:TCsO¿52Y?xwX6NV0Od-glֈ/|HV~hU˧~'kc$Qhcߌi丨GݯNa&]A io ƢH jm>s .QNy\5VtE/i>:]2= !L|S]9mQv]3-Qiո9k4~ctj6b~Tz4y],8`5CSXq\|JYƎw'8F泩B'`dn:ƻNpts? j ԩw%>]K)?a##מ(UwO j׸|g>݀[v"CAqݜ6T鳊2KG"> s sXQhyE-Ĉ=9,(U> 9Ev txsFʘps٢IU#K+'Z"Ne ȣ#I!MR=9!p ' oPWАAsGBa"7Ħj t͊5jd$jyQ嶱D9N!:.]:v5MdOWju?a< N79 AF8'5[7~`]} '|7ڻPs{{O:z[? x.ha9쁕Μge={'KuA: Zz,"7\G*CvQ9փSZEƓiܶt cl8 cDgFz)8S\`]ZA꩜Ds2ַC & 3ISZ+6sx,ԬnUϭ.P-qtC-n̡%2g䎠G䁤 Ĕ׺M]τ|Tx m9yqLòmZ=PLAeLGDD@C Bfciy kG4G,=8=Ӂi73X=ISoL'*4ȩ&$ןScpMJD3zʤqkqa1N8]d3_h < o,b|P4#haѹdUi1|o+N Iԭ}W`+Vh~F8j|fҝ-to9,ynG1 E 6&ɝ6 G9Zk= X"3A13#6D=:E;G$ >(Ϩ[&m~?4k5qZ [FLy [Nd ''}cnw^tYdƫ!81 kyy+y[UINS`d պ`#泩_ܬUK%_g]Rk7^jtMiH ,4G[(T9tݕ a?Nk}!i aIK@eZdܕXBF=Θk[T:Q.#=r(tSu/'S}U :TϪya9!k3Ѫ\:Jwv֎n໨$&?u'GNt{KpVc@X>ȩM{;six:bI;ewר)1ȫ7vgb  ϒ9䋆:ss3þ2WD4 -sm-&:ye<#w n D.h'  z-wZ= y`-w44>)-MtX?&?>Xa%Rj1!9}5Uʎ`J>HnJ88ځs$GD{;vpK0U2 * G]Nuk?G N*&ZwwO%: +hn vaޑLm)"\rui@*C m@8Ժ0ot} exAW!̀x~H49)pOf;#uR<6"Dyu1ZceX5DVtGvce=#PUOc\wb0vXխcv`%PDÈ83 a+Z׀4}YɼX \pdd1=Cy8:c sZ$G3h}٤D:w~H"4h0jQ29'Qp;~Mq@  ؆`C}S=Qhs !H_ƧnI#Q1?NyE޻Xz0hѫ"h4Am`9pQc녒'&B?4x <¶ 't=ϔ9ܵuX@1!;ȉ%m8p1lOAU-E*F'bP>%U}I>klzm%8.DaqϚ9]&v7 'V4iac(mT!&_D1WY5_?WsƤ7椏\Aѱ?s=j"^xa>Z-eNܡ4 "z\'lP@ Z9oI7|̦FO0ާDy,2lݝM9m#KuEx' ,uh݂NuGHcHNy L0 8* ?Aˋ'S-#"ݑFi i[a!07Q֎dʹ NOQ(BwGǡ'ᶋxNe p1vȵp3yO[|HMww][o̦LW'y=dC}pV8ҿYc}hG]ᜋ~82 o7D>j#M ʕf<Be`: 4kCGieYY 2a kn!ٙJN?! -ZgY*{;P殘!bs-m'xPApR˄i|5V磀$S?E뇒Ɵ`߄803 Z2iWԦ`k Ha c sm )ҳ? I|^ꁸ8V各GL'6nVʍĂnIR فn$._5J?ADwS.*x'q'ZL~4UuKzv8"~iELb=C{1s=LDnOA:) #mG+Rk{%(ΫKA^!:8D[R"@# q77஦Vsj"AR6?ܰ~hّ Clqۚ}U₃\OQ!8>*V~hM;h>h+:4!K9D>KU dy~j GI3z D55KY&>Dhzv^D8j?eh;A%SHučmdn1n;|ƅ`:+Z!p_D{0pG~:;8OѐAʁ@'DF$JdcGN%)k" i_T)AK$y}J7E3\Ep3\ ~Ϸ|O8~s<܀yn3r j$e[(hܹ(?"CCFGn^s ,t"!4nfQ]Fx!|6La )w GwGkioi4馨Ō'uTܡb]$k0z( 9(zO-T(΋EM(TF9!E+e]1SgkUi|– 8~&a 5};9m;x'џ'uLX tOm7 k]CҜжGYpTvW9\5IM]>#U4_T}@T7:hW.aZ\cӒt}6'g- }6!v"wr+45htꃇ  ?f+(jRXZAEa -ܮ.=[F6ӪD,(~v" %Jx7V9v䬪lq͎}z!\ `ÓBn;tMez._BZq'nN gчt<ky:sW޴;Pp ^idB-PJ.:,dX%C3CĠ7o/] k?@k?$pxNɭh+ O3N.v~0$k6GMu8.#kT0 ?|dowIJ4lS{@0~@t;l3͇%کwZ-iڹէ֒>~ o4{$KڱAhu2ɏO$\<ܝ:!f`X#E ~J0b)\L*HX\Q)ZTx޾OE/U n:1>qAgxFmX$éG!%3>o>>>tOqʩ*xH0 AeL<*7sOnTjWu oOXjS .iF|3VSj4Kc`/h Kjm#1?T`߆~!~ŏty#/XeT|.?_UŢh걪S)iGۄs#g3: n50 WFct|_KD*i}-ӪP8]j_"e1i_A\tvDc#"E2sAHVf;?ҝWA)(͂8\A[ x|x{ k\x5-|ԏn$ X_; ۊ,/58Z@B C>2c|EJ;YWxm>6 ;PcFָq*.LnSs0rAUli]<˒sa!Fr>P$ƆSY]SkoSwIBs<KP,өO\5GQ?sZnGMS2ٝv?zH>[Nz-NUniY,%V @ۮ;K~}'n}=\m vq!@s+08x8h.* %xpZ`6%m"H5 hVΉn܊twy]QLMh8T]!۹! \u7TpkLftQ i&5xE? UPpޛA] :${ MAa.TeJ:DWemK\zDkb6HFE =y&i&p:d&=NFD޷;_B@ʼCP4Ih`)C 3W @)*e5=Pqo]nҦIG$\) Бh0N.O!rCza$i~Jw2L l:ZUsMhs]H,>u{m n^H5Mm[0Okݼ;6U{=jp{#:\Ҩ4A眅Tՠ*d{F8'57;xc1U@x]CHFoE+Vdp d5q - 5R{;Z:#eW4b& %I!R_j]xGJ?.$6@8 27֖5) 7&(?8XovL;Np"^b5OK" dQN ' |g wZ-UݚNeG#-Uic+^sxEԮ:Cm}G$Ca#MtsM Ntkٱ݈CI^*{#UT"r5k5(I\"J+U3ehЏ݁("n"WvLpK4k䩽xӞ[hپ)$j-'.jGsZ&n'L&xu͍Ahտw8p#L?P2A>X폒@pČnFR=kioG6tSHw\鹜+/Ć8dKTn\qi80s?|ƄgZ}ߢaCc`t+-ROEZZDP Bc ~(o<CW7(iXTpFo+9!^aWdGp@8d[m1Nse`uN]w:(Teg#"9/OAeJsBqu"Fmzwj1̬i [ts[A8j-wgg@]ibfy¸1VZ'Y2 Box!a&T-Z#O@fƜs6 T5 GFg`UJͱ<9UR^91ێ"0XM^A (hmZd@$j1#`8Bvr-hmv? 86p@HKE81w4a{HG1O0׶iy'6CZZXsJecQpQ\9  T8 ~%mlj:O5 &V !(Oz}Eʻ/Nj#4ELH(t'v`9]r 5r_o,.!7=`1D_~4uZ]t)\ *{/x0zS择8OV|tEz\Gn0SCSK/alƕS9M{U杜T۴}P p!4@!e4 e>R?4'AȎJH'}nv a6iQ.iDXU)fע 8_ɮ9d1ƪQXzmVw ʘ@2`,8,7V}P<%C7 `΋!)Ftjo9#Z߾ǪgG"N!;*h_1㎕[$M4~-Uk1kxsSDW'(?n8w-'y9;V\N=JnjtvӉVd!y)pioeV|Qy"ڲ҅% \71C % {Dj<逿֏oݎDTsYP`Gy P?'Tz.5q)!շklA4羈i3th}3]@iʸϯ5Z-8{Lo~Xh!Kͼ)~m?cZxi]a$s[l[{Nz.p捭\+OEdabUoZq貚3`3j?A8pSTO1*@&S{*F:r tkIXjƟ%W1[*-3jbƇBgpٸ%5 85cFr .Z} 喫Ki@8IQYV9 @:m a"ZzZ)!rN2G{ F-vҏ)M$2PcN]z.hcU$9J}Jcx ! 2D(K95LwYfFQū>%גsA әD1({-PV%h[hS#{5Ѕܼ\#p#et!2 `9ʨ)ԣR5Bp: 訢VO4Kϒ NN-kBˣgG>i U)\9P&©ih!?ѫφ$7Tg ծxH^!\ x'6w䆡 H j !`&42ri;(f6L=c s_S=Q($Ϛ`nzXщ$. mULP6?cQ- hO*x<($;G)Y)Zkg>EYQBLèRܷpӺ{ c)2!~9F;HɲUnkP?(?E- ݦ" aW[2¨~EsOTliObe*= $F5zU GDZtENkvEm8(HMnB/G+%`i)ĦϹ2ZQ8Zu” @ 082P:_o ӣCih5U^!QRSɻ.qBFŽKN$PkQs<;E8?hMq~F+䨔@ a9ϢpĎyp4h70 iS;8D pQ0zaX?gA#-5Hגo6Eahe0!> "D#D Z,Pvд] cdHU4J[:iП?![Uy9 NdǵHxSU>!Z KvPjC !zYDGN&4'?aM#Dz[ Y#Dž4Zj!>SFL  o2'( :1K +*[ P'%jA-v?c5GiZt(ۑ[5Q, C*ڇ1ݟcyg;Ear讥\4Rʒ9G2?0 kE/42g(P>)EJӋOV{*hui@GXY0ZcwB'uH{Td,KMnҿipS a7C⅒)kjqnr&JhMPq5$ ,k‰qD"CчJOTB6NrV>^Z-r$$IdZ[~K㓔9YZG%۱‡cslP nٜ8)nTgp ESl d|Hdt*"\=V\'CB h- XX &6QzqdثcEw=v \NJۂ$U;rM{ vVN@Do]ꅦ9eg5EM2 EDBl Q62ܠ+ Os钪S3.]p˓( vwD'Tq+<^V\J:j7š$9@2ؕáVQmHX٢삹vS.SMVįJ7eV\9!GiL++At[ n4"d|K>jXn>yz?fEhZ*A`즴87ݤD7)lmW[u3.<>W*!1AQaq 0@P?ǯ_ge,گ~L?RJ+~|ԩRW|W|T_D_ 5+COϊ*TRJ+TR|J*T_Lrj`ƅێ!\"qI*T*'¥J*T_Rnc|9(Dr1t^FÓ<˗寸 rPw(CQs\Ce~*WJ*TR|:~XdFٔWOʕN0~bMuU @T'qIsD1cM3%a'H0{-"+&g8`h0@Z-[-R_jЂC܁YgyE䢶) 846 @Jh11{%GUEXqvic*s:@hǓk$kULE/գ^awȽ]%)'d @JX`T / 0R4׉ZB/(eUe\5TXj2.ͪ1[ s02!V[{È6 +ia/Aĵub \+MB} އz`>}(5/y%g;#4?7 ӊkP \ $V{Ax/n׈j}#̴,) \bRHkG"k U^nRZ4>qFK)³B4؀Y@Pe_L⠝c!p߰Īb#AWzfUkϾ|AȀS4CGR^a^$2R咺4q|?0>kѮlQ6_JB֗쐲;*Cۆ MJ䰩cܤ,`0!#Z5ٕ$=%{U!X!Y!mDO5C/#$l kn q\-t3O-S^ЃT& <Gs'%&Nzfs Z8?i"XjyieuB̍6T[~ G]d2$lK~<@CuxɄ ՔxfnU 9kX[#qLZnf?d>7I@IAV36hY#{0yU(!:bSc;`:K{Sx@bqR mN4 WF.8Y*jy"5V0Mlr{1_IY >ڀ'gx LSq2ZУBV~,-=F@^ lhIG,!x?cEebpey] q`tkŖ@U^YF`Q3y,z)U+&=dAp#d1P{Q2l ib-XIt_`f*^WY)Gcϰ^A8.S7Zf1f=_WмӜ 4-c -W~̄RVڱz#@x1i5@wTJf-U腏0Ѷi,|t5-V/Y Z)~+=k54, * pbP8}O- ۟au$2*ĪH5q` 4)Tc (}aܢ %֫ fഅnGmnY",XTVE/\Jk*3bK{p¯&Q)n X i.<P0̐EW/VKR7bOd+I[9*(ZG{w}`d)#5e(%4vΉtBsruA[ wAhح*0qGeFglJp(%We׶h0q梣k' b!;<ADRѮ7XXt!B#]Q Xx*_4DFs.u+bQ%ucgJ穙Z,{m+VT(bc4 F0$Oy>01΀Sp":g,H56yȞ 2CO'~rϒXu ;(Jɭ'/iskODh:aj8wZ.OK x}V6b~e(q譮^콡 Јjwg/x#29l47^S4.:;NpJ4#d|ffDf.*5 6l^`  1~n_|˱E:Q+l7͊ԖxS!FIvkI1k) jneZ::ΏZ5 z25>|[r=KUWEi (d?K /ưy>e!ڥאJ-jP%# 7(r]*eP4Ah9`\! !pFJR}!+Zۦ9mGo+V8F & _ihYdzL$Ͽ;2=ăs4HY +X?i򨚅g<]f^J)e  >ma$tٚIH P]n KvAOh: @J=p*Dܲ9"LBB3XTiTL.c0H3fmZ6EXuܰq0[֍t}3`1j.G( eUTcN\1ꀸ:OF^X)t8 &U`4@_ba(*~ܿ*87ѕ]+Մ@WT~\fp1^!ո<S (F9{d#(0)lZμybBڌ[bղDfSPPUR]PBLjSDhsz]䦏,ѺaĪS釰=S:YTd%c v\,uw0cd|oPڃ!LX@<GAsPb(VbQOi6*8k,dշ!fLHN7/'Hm,P 䥟pd#{ ?5Uj!0`J[Ml yfb) L[*(UQbPh)|5EywSxR 2,AʣHt 8ZwRtT$!XRiߨl `x@[cX)V;J\+3ƪ t 8,_,c~l P)JnDһkP7+C:ctV$TcٿQy  Zq,$6)1n|@~Zqbl虅J^Ս)#8.k"I`⅄ ]ljjrU0)Bo(mw3L7edD/"eCw%ۆ#J`ňWDJX\{gf‚")4ėA7×lhU;`/F?Y@0Pū5p=CCwM~hxR[hot)1V* pVhy2vU}=Rw|&Lo [ #BoIJ٠ݎظ_fe :}hFjoEwFG p skt\Y|W0ֺZ<]FmU4{HzU[K@v&}A6D`|`cA^ۯ(o;rׅD/KIh4(О"78GC1o jhSQ&OΙ &tc9, ܨcbcLQv& !u7L =n`b뚁9ol])a g,MPeVy pX]!"!Q_d:Wf|q+xJmRb MmKbg PeEt%Y@[WPV PaG6E;Xc1+HQU[R"A"eTx/ `@V 2Z؄LMY:a´ڎKq5IF:Tr/L wQwAȸ`xGϝr.:Ϙcjny [ E<:Ǹǃ$™:ec9f_ڼK&ع\ D|?EŮǠ>[~Bv, 'nП))\h9~e vҀf[)zp%ԽP8QXXJa^~R;Xa%!Xame,]eEnGc JbF}&ӭ%$ñf@k'f(oֽϻ!#|.8]$)We)#` -r^vY bRg/G鎁N&۴rÛR؛`r"ʑ^_,LJ$Ox )ri{fP0FݿDNХotE[x1V*jߘ9}us+?%=~ecШ_jDw{E t=pLQ5i+RǁD9/Hl˚hf ꈴho'a^e2YJWCoyXL{"dGڨqMca9` s,CdcA0J6H𦖏ҶyEYalش 5eKfkelUY%S^Uq W~~ ezQ@8%]B;P729rĹ.|0ba\4{b gs8`/U .:ŀvBmYja8V#(l+<=ķ`' k>9Iחh|\IJ}TH<֝GaؘP[IǦSy'$eB- +ehtКjv) ꣡d>*e*ʚgM@mC+ɹXu v>"/bTHi)mw@Z+:@L?@ i@DKp}_Pۿ }FECQx:^/\ }Y5JVkBޗ -c0]t&*W_鍊% c dC|BI[6oq5Y F-*b|FO]8K+F 6a-orZY,-zb+[=%t%S&4_ǔaeX  T+7z'uDXZ'׸z];V0%K K(xqu%jS冫\k/%\MpqْO]}2Vp/`+F9 uEh~ [:0oVz$ L;+3iP ʼ^q%J ri"񺱍 `vQc' ze>bwľ̥oܼ"|bg/YA^ h hKhɉ%Iد_͜l(" ps |d,,/\GݪނXǓO,X-P:9/&~<a( w?ңR9i*˦X9{ccJz>) j+ה" vVhSPLS v>S." 8 q)28%Z_C`>mG %֍)ZT4]8M㘰̵ hȑl!cuqM=yP-v{>o,v p ø@Pyn;TpMk9sU&3|-?ʷ(@ADK!̪Z0 KS y& VbV--6<4y>a7CXD"uVฅQxD! !f)f'gFnEG MspPN _ea u|$i QFtj^ [c{MU4˖pV rb2A"D5_ZZeEŒ),в=~K=KY|#0UJP=D!h5 NLƒ8b;\x8r}{\@8pq)0&&ڱπ/CFusq\@[GhWC .s ay]A9Q- ť׷Fd5S}싀v.%ȯ6#@X5M|IW0[ ,ip#c`xqRs42t`({Ƣs Vqth-"я⬛ļTq ZbTFaykÄzaa$("Pb?U?_Zcj.ħ7TFJ+Lxl>^'%x ;C%Ψf[  WQ -$1Nn2{#)(LA1.eWh<0r~CzjFU6BJpS(z ]leZlRRlS0.Y⚎Lan3ʆl+el Lv3Zaśl͑sz4J aP6&/}CW]!WG2^`ut>2D –is^^y&HAzS \ۿEq6)P'SE8j qa7v f7S=%W Q@}BpwNJd(TǛdFBRa7XZ S Wqu)Od3'B®*Ij  # sܿRQ wș-r wz<$`6<'ᶌ0,oɀWp%@]!@l3M T$O#g|C+c~;U esI)N +Д§R.,~?j_g\.3rUѸ`Vm PN*0x "1)wp4+X0AwbI.1(%R3[ 10lGRmI*cQLjJ5_g\ 8EP ]Nj9Q8F-[ J#逡7a@MX8-AcrKtwij41ޠl ʹC"f PЌ0/q e3/l40R/_r<@?vոQn Ii{rnˀ{g8:fXBB|40W회OZ+ak^!{4hXm%IjyK- 5uɻ#MaLSqNV%ؠ'N"%Ff ̬5- "\^j"J2e2 {P4탇PXiG+1o4XByʌcHύCy.0'1ZIDPIb!)zN)v*)([">G E̳R?Vqfbn~ \` YkS,]5l-k˶ rzX0.19Y # M`h(k@1 D5Za_c?#,v)QNf[]0(/`lcB+93KVlLgA(z00#=ѭkgvXLt(/Hx|aʯ=ūeX{o}̔Efd1箆nHani*U~:l@FO_ޑ1z ͓ cRܢ2m sfZ0`_c"`j1D.809rࡶ2jqynad!JPhhB573/-]&,>&`>>N&&4x2Y`HH`0ƠBV pUܮҸFx.*c2*x($[9讔2L"'&pЭ8uA0[,jm"\1尿ZAR K|BKԮMԐ%~.\P <]JBuwIkrtED( O9F+6̨(3EJf 18MmZ4*i D!ۤ$#0p;@IgxUh9=33s2ﰐ8{DVh,4MH ^=ˑ"榊șoL4t m0?)~,D~$H'7/rH`5IUn?G4B#]{j/l]\Bw`e-1/C;%yh3gwl [uyMaup6^).pN^ C'{X282D^#}<QAHȮ5+Phᘄ0Fk(! kG!!6ۆ(^ N4"底A:8Xʂ#KPU$R7WX̑A 6{ca@-Ax?`RrzZ:*z==Y`@ށbcr J5eZ^GB Ő ѭ2?K9]+dE[)_>!yah*LaЬ>  @9 9 0b ]1Giчa2!&eI>KHdplR& 8\GO /_n.8%Hז`V޺d-}d/Jkczn%gWVHa?\C 8EѰp؜BL.V<1MzaױԢ%VвJG^A8mL\  &vHQM`3KϘLoc-4*w&Җ}W#)#20 eFP\wfLEa[ ZafQ3%DO7/4"1 vʴ *n $e#ce 8,XNhץuU2(t+ԙyBcutӑ#vmE5/ FY R ivøT?fSuEįdM60|\I3ae.KeԬy&V+isbJd &AW b1c -WY[03`NASiRn~UfD%*QP=3!T`={ uQhNX8d/y9% !A 0K[j1kDj <==*pĕ@ 3ټ Qc+/1W* BPAT>*' sPC?!ji&tRGFMAىQ+ zanNIIx,щR:ua$pab\ӓZ0Y[ SgK ^21Cَц#4dj8%P`=! ]XXƁ : EM.8Vx[(1?Ԓ"h;;Yg7+•7`Ԥ.eQflB,!vG2yk \~T_l"lLSs~qD(ȑ9k nC!d^$%TvMpዥp̭]f5Ŀ,!0ş*(-'TfpvlG\,7[X @-vm 7(}9%p1"V1O%߅ˠX,H*%1G 1"Mto~ĢƔbs*64%\bV4DcY6aQK(P- .cBJ}cHEȝtEg9yK F}^&QCs/ EtQ39nҔbz 0G$Xv&&n\\.j&J8|$DhbK**0"O`ei1Bj0p%˳{eקے+\$%ڷXh򚊍YC:`U@qCpQ#q9ʱ(X>>Ro(#VL+D3z<5Q%q I> c2bFcTG5}D\&cx+bsshRq/큚w2 Zؖ/Ln?$l@pY!1_Jq.GFk$Q`UPTflt@])CrΠH)oQRJ!cԩUb' @ $"3r%eX,ݑ7N5H3Y,l% ԈhJs dTD5uv# O=c@w]^ZNQ'3aWX*0F vmJNP0@~\4#^"U|^LJ_^U0F-`IhquTq:,2g*&RvY"azW <,, RpJ ?C4In )2$>H|oܸ?-8X\$F\ˑ:X;Yb)P xA|41/ Kڱjpd]⬐F@ET0lJ@*VR*L6@qGO(גV^J+Q'>H2TfWA=EUF@΍BG g: ekiHm?^UGV+dڤe\L/7;"v )*T_ޥ?2BA۞T,# kOs_GXP+#G7 J+~%6&e`4*AD p̚CTHu(@ qQʇ¶~+MϓYrr˗.\<%w.\.\.\.\X˗/.\r>_J%y\ZZ[1h2˗?/!1A 0@a"Qq2#BP?.Ye_ƾ|6YeY~,iYe_/ھ͚ID~1}G #(K2؊g'%rW,D d. p1jeVC_)*R?[-Zz"4-\T_9?4KQ*?Y2Fm~95c!v]W1813b vqiEϤbomVz2:=ei.JYBHݒ(^ʌ+&F$1! dR5yc?9A~c}W;U{fe噚invd[^'G@&Wsi>R8F!w:"i/W*Qj3N'&ISrMZ% Q(憞GJHj6bk>IfQ?-3I6M?j_"V]e'6&cJFm<;LMhhdDCE'\sfƙ4zˊH'#&Q{[}=S3Qۤ&H{YHOzENv?ie䒔"zY>ͅAyBn2bv)ms D䶿zv}JM6C-.3Ou&늤g`҃Qp=5ߓV,nW37+&F]2ͶOOF6f+d };>)#jr+t6HjFij%&mZ|0x0fQ{[/迳U%tzviYq>$yU2}c1_S9IF+ڳ}.)Yq+k5TĠ&Şf,U 3 3O!/,cWřԔ '2zN/&-KzFrK$Mu3w>YeGMZjfҢ1(1SY f6M2Xb"ZXiǿÁF\Q{#S\[mdp*jh)42`9_12U!cJ=lI$wlH|VY~ %$d1O m3+Bp3cmM6R'6h[ZN)"-͘frE쿆dL׸]YdhXvlUi$Ir&$h+_{Q1ߗ/'z7#re&Y /9Cd՚i~>{I8R$+&)q["id+mv;wbfr/⮹o䩍Q[*H&>I5I46_&USV[1I.L3K32N# .K|_d9;7#ctC&+go8IrFM3O߶4IS$](cۥD*uCHcTzx1MŘq Dpv5CIkII%E.l*E%ӿET;P"`eYeLqIG (ԈN b9$!!E~*1K2,DEQ*ĭ. DH|1Z(n$. oj4U&!};"H.fd&Чĉv7ծ%f(lkۘe>xculhl;eȟE4U$$푔sXؤ3w,OqB}T2VAНkY}-qe.!1A 0@"Qa2qB`?/]t]Wˮ?BܢzuAki4cu(N<ů}&GҒV*f,0!T̺X^C2N&Dzf~E=:G,S^`'?GE_َ8!bNŋ&Bm3Iw J䢶\ظcV%\L8B+bٶ(ƙ4woTD™DIu fPkɑMJbssH?_<ۤ(\YTݛ4d[vgIQ(+Ȯ3ѶfMS"+ɨJӦ&(P^3$N.<ˍSIQM5(Y3!E$g$Þm5XۊLMB䵑7iXбKO.In5˟V0($N)Rg&فܘFpBB4&IE;f=JY\j%wG,{Yo|mne:~? ry)O~_ũS[#ZbR_NϨmTO>+{4Mdェ"5X$k7.j1'%&iwCg㒓I0cPH&3ɸ$g',춣IA\#_}dO s|1_䋔/rEɪ)tQgcYOerU3zQTn(l줇}-*chKI1N- TH7BchB4>~ 0% B^mFE;ks$Vihnk)ǃ$j_ Zt'RC*$bHKCϑE"eh͌QE&E=hؕ&}&abl\rEwS"ѵy2I#O{茈MQvq!=d[bo5፶)}¤be2FXֆ"$2iGr>$ll:̑4QB+BE 9]^l[-L䡶įc[c$| DXB}DN}r->#rY.˲'u 2|(_g1ǢD5H=+G&D^,نJ6$Nt(,/8ք4!2D$鮫ً11Hd" 1FR&},WZ"s@-4%f;bآ,Lwća \ 6KJD#d"!fI;V*]eTc"o#ɋUC6ke"Rf6)Q6쮮H/݃c1Y6FԷe)tSHse[Fr Ǖ_'֌$2y7[ԓJIcLWTN/[+z!>fOk%4ENǝv7~WE\בLW^WJQEzpkgdown/tests/testthat/assets/articles-images/docs/articles/0000755000176200001440000000000014614000541024031 5ustar liggesuserspkgdown/tests/testthat/assets/articles-images/docs/articles/kitten.html0000644000176200001440000001663514614000564026235 0ustar liggesusers kitten • kittens

    knitr::include_graphics()

    knitr::include_graphics("../man/figures/kitten.jpg")

    knitr::include_graphics("another-kitten.jpg")

    rmarkdown

    External package

    magick::image_read("another-kitten.jpg")

    Plot

    plot(1:3)

    Site built with pkgdown 2.0.9.9000.

    pkgdown/tests/testthat/assets/articles-images/docs/articles/kitten_files/0000755000176200001440000000000014614000540026510 5ustar liggesuserspkgdown/tests/testthat/assets/articles-images/docs/articles/kitten_files/figure-html/0000755000176200001440000000000014614000564030741 5ustar liggesuserspkgdown/tests/testthat/assets/articles-images/docs/articles/kitten_files/figure-html/magick-1.png0000644000176200001440000105524614614000564033055 0ustar liggesusersPNG  IHDR*_iCCPicc(c``I-f``+) rwRR` ̠`\\À|T uAfVp'?@\PTds@HR6]bdO!%`5 g 퐎NBbCd#]M(I(ў 0" !, LKb,' Ēf20loe`SY|riQj) >x9uG67{@iŏ$'Ǿ.b8fMˇ_S# cHRMz&u0`:pQ<bKGD pHYs  ~IDATxg$K&s\DDWv r'+rȟftꊺ%2C0s=\ȌTUan@!U~~"2uS]@_{?xvp{ t9:=yp⹋HDԹ.u6=5 +G^]Sq<^Aa ZWSDgׁWkZkuظưdžA9vO= 78Us#3Hw;JPG?D=ێݽN2 |E8g:\= P2|rq+.Ȼ )TFw|m2p=n߿bKzP{,[auui?Shbw!;~g/@8Qϖ^cxasdz}h0|%佺 |X7 |>ps9t-eQ c ܧa+UO&Oi>lmyzw'#{hu^|U-};1d<!SqCsS_k𩀓!p4}e<".N/8wyΞϤ!@XwĖ8ܡOdOSa(yJ{:Wk!N8}LqR 6x?'4~C#;ew>EY{vutO7T}x9Sߧ<<=NUϡe?.UO~\)qC?'+ ұ{4C~z x]j8e{n/M|s{dj3GܡQZ 8@QDܱ ?!A]D{[v+/ԂlM5 ^ђu~mbB]o;܂:bz+NMT's}bn fI:ak~=mm[T';vh3wdzV֨'`gdͻB}7G+C谶H򸯔@}ܪ ͷ&=oc/6:?%vE1VSIk>q,Tᄿ.yXU6hEpytNA"1oa^s1?Eq=aUũ$')Y*ywZVg w0zq;[݀jrx='m/ 'Щx>_=8a'7xrQ5Y3DO۟z_9gw`WpCY $|`w# w w坲9.ƣ?[KsB^l|8pNIyv{U(;*>+5@L3S|.p ҉CGur<Ç"nw6g7+۲& p:Ӎ+p E@dNԋܟnw%So*?w{ʏ %wmq^9z&騄۞rZu?T@?aVۻ8L[I:_{+<\ ޜp$_Tb~x=={`7<[`V=N|n{mO*cOn@@C.bc*ߜxtunu3}>]xVpl2_: n2E#)Q/Xy}Y\<=p4NG}~z+>^D8b;䧧|=p 7_O}Z1?!<5oNq蓄ũF4><+s`QYv!) (Q`&cJ @;hY!o  ?S"*n8Lo$c`p yG~UOe}f/upyw+6:ptKe§w;6aۅkv,_= Ww~gl<#^vwۭ'F`Ncmxnįcϻ7r]Ú;M#qp_,8`e?AxvNDy_&qBؽ!/{`X'WstpWy}0'C}@}p=7g<3+IX ӒJ$zw^RaaafNi}p¾G2 3'a ~kOn G{;hO4K{w9ʜض2w0{%w8t~OՔy=vrx/4w7o;Z5'~_Fҿ .sIއzl:@q8_,CÃR$o/!vBXsȩ듁w̩^܎ʒom:#-vd5;SA@=ܻiw\ٝ]Ew&p'祩0r=89D\tYu&EQ zGxI kIԝ_liB!N%^rEA?#SY{pV{r-;䌖:=DSk-s*ײpTȏ{zi(~ "}n];#ub{u߿݀QOјS$_A~_^ëC47mQA쵪3]C[Cy4@"aUxN`~3URw/Oݱ15`/wcVi eHTcv'jmqG D8\ctZJS~;l N]!qrǃ⅚?4G݇#hKW+=cEP7L|1o,B[g1QQwoz_etwHp{w#SL~{Zd@}@D@7IYT>'4ނQ@C$8{9.>'ԏG|8Y*pK}@GF[9wr9bp9tXt m{u;y&hxN >z+p)#dݡK?˝8p*EȺpu섄9 pGT: q04z5q{߳ؓC`ރ}>]wp5QzNsCT/" kŝ!N ~ =lV@E0 jpOܓ|<(~4E7|mңr3 mΡS]Jn|ac|[h;Hz"Aߞ LnZ鞢}t į*>x>?Ъk}GƎԳ;kb8?z?dC ]k81',NT ZD J2>s?G@ ;?|aqp&Y}8 =߽C@q8 +C@} jqާg3ǡKdjZ-sOuJSFN9āq{ڟ:/خ7O&~p0FOY݁볩e{jvE1ՙsϫ!Qjqmo>au Žw|t1tʑ=^uV>6 Nܫݑ@ǮCLҌ7^p#}D<2_c- 9-818AN;޳Ӻ-1yl  \ 9Qo"bHzOt"^CV Q9֓OW<,9EۤM!;&Ύ'』_٧?g;[I JKq/??ݡ{DNjԽ{ Fvmȁs#?$qF:[CSc#2W¨@꨿ۏM0%%wl{.1k 0$'gx:?8S"(?u% q{nu7Ɂ<; %q+YQGn[F{: pMp@4'i a!8>$Zq|pOu?G11%A 8iC <)RG<&f8GE  Y A:SU86#~?;G}|2rR+˰ @h^$ X ש<0pƇB!VWK"vTy~^Gz{{D9ٮj8QS85;fWCk죄 lV߱Q5p]| k:WyX[pIފ|髤!-" ^O؍Aq> ީܹQ`u3NPA|w@b;PC|8:?SLa<L}J‡*@p,2w@<#sA=`w\QI`yO?w*'l"0D_qx[ bxn<8;K@/o밹a2H1D ]Eq]>'w$h1;S}ܙ ~)yt[fj Q{ۏ0ꗥ{s.w5:!׃ n3!d8 x iVzxP8+ V!? xL~c(3dp"> 8߀T{{"D `p<!˸ + >87yj2IOQl;0  7sU$ :ZSx;Ġe`}~-HVBÕʔL~DA|f1'PQ[#n!@#l p+,SnԬ+U25WEMcD>t <>l~őַO9}e;~Syew c0:};-uTǤ~f"Gp ؋@F 8a&ARtlx MLՠlIZ x3BϹ?7c&<9>9YŞ28PbG6oO@w!hƉ[C`^"~P x2 iavS~ <ڞm{wr,'ڂ)^ BG.ڝ@ S|GAY̏Nਸ਼D/fL38pѷfBl\?EQ{R|j@;Z@@{ƀo~TvӢGIbHc0>8P ;#(}^T\(z)Ɍ ?GpO|Ў6 xRb MHo@I^ES"{Pޭkܕ9XQL+p?_<]d@"1d+^3vcv9v;Iz曚'^OHbHCd'A }; CGkv瀀N.<uʻ>A=aRf5 h!H рj鰋`@KEO6M+W?FMMOŀ@{3p "G=#xs=I~)>n^p,}w +0]B| Q$y#yc@ڧQSdދo?86sT1e-P1 V~x#Y𬱗VI0*`Ά'ukus@a=x'~}ii *9 NrlʝaRÇKrsSFpҟ$4QzJ_|: 0ұǏzNq4Uih癝 4CS!;=">F@׈ :9P{ U?F&(k7@ v؞$6lO:s"BD A󖳭V4;m_L=æJhҏSz:okfF.*rͧ Q˙0Ȋ,ȑ@[QJEQEQ"9nNWJ\/Q/9t&XWda*?e,>|BdRUC"VOT}"p/"TkI=_'Jۈ"@<6EYH@vcmA"a Ivg`A<✳|YE@i"h"dU#R}ΦBȀo0WbH`ED ;lej8HEB$$ƘQ#C3ms6De@ާBS'XuO6 ߰(}ͽegL盬ȍ--04)ksW7T8 ܽ{6k2ϊ|m|cՄFvV%)Tor)Pe D&~a{5D$q_ "gdZĕe6K*JJ! MTIJZ vý:D / ɓaUG" Y=g2˲l^.W7e^%1Rb(tB:eӕ`GAP%7wJ/c Ц'=j<ØEQjRjqXሰ̸2K:)z+?ltG{#">L_1>Aߏp[1;ޗ(~>Z`g<5E A$ THD30 :%"$۳RU=+补KDHp>1Nx&g."Mݲ,s N 񠶠I=?<_ѵ[os|NHX~fg&_/77!'@UR+iwI@$RG$ZєF#"?_( 8=$v( #gIq#ΥOSQ$OIJOz|08aۜh lYV_|Y.7X+QD!EJk}I"fffNC&@Py1{MuG8 mӉ ZlYqŚhOz6YaU[Rm36+6_nn7;,4)֞HYCZ;D끠"_Dp4@gAg;K+kpɟa+9r^iXܦeXm#Aaʲ\._|)B{zWH)孷@_a_ uX쵡=C CP`NE!Bcȓa F(^G>j99ʙ㵿_n>no9MSM*bO)֠+=n@@ ~pEZ繵R^f@h^ rdDk<# X`m̂EȉXkOWl#BDD"ʒ19g"y4@Pʛpm:gm5+ԛv?dfnNkt(u.gG =+*AD􉛇oH_B)C U4uר6?10xxfaШ9G92/j5C)REDHR*D R*ZG^ Iđ 8G$yѠ,;cWC izuQޓВ;b=bUn/NTq)>Yn90' "g#l4Dqc`F@5"_cQHA"40rNGiKO}(cj32 irՕVZ@T9 S 'DKMӧ>ޚ$"Z{[(bU ըvcFPvw2 b/: hRD$Y$1lL~TFcVJAmEPi VXCDVE"*jw!6͡k8VmGsW\6α`j*+4˗>^\!FZ'I$ V*$ԅBVlppzJχ=t|1:'1%"k$J9V"_Z眏L*41vFQM+Hi@e8$QJYkD!9z;M7<mhfϊyAwOv+Xgx󇏟>}ʲLHIUO}"D5z}=Mp @2L SU. c"J)|ynJgXR*HX+bՓsMJ)u <'85F/&A@}F']:b:\('(•&_f((XVCwT0m,qt]=g3([,#&0sֺSa5qzdf#)RD1lybBD19"GZE16C*>jvaG~P; z@3;61˧rΥQ7I& ?|݋-3MEUTHlYIf*(`afk-hC p>;#"&ffrE!Fqr@+M%J0"?nCfL^on%DO,IQccQiR ?ߢ(-*EiDt鿃*vnM'˩zh0V{n7&6=ޭom+{'ߣ&d\U}~b^C]F&hQ*[*VIP5RǑNWCHN{k}%X#9sœı1+"!bD$J)^fCB;en34zPc븇8nr#B5o1s緷_eoEJiR(ڒgieB6ȈxΓ8`(iHRhZՊMm_k"*Qay^lqQUq"7[jt{{hϊ1$5(9`km y֡_J[5>E33mbܥDaz;mxtV(4%WjUw!*-4Epgq"ZsD,-i.I%R?zhNrJ}1(ހ@#gf./OU5s݄FJX.v%/EQ$1(2#pv6<ϝ)$RiMưsiJD2+ /,q`\e58Jx)t/an$26/H?dYyQf>l6d"R%QJ%uJk,"^@0( w̃ػuF0:_n7Ta+ k/BiʝCfoDZ91QQf9H eΓ4iR~Ζy;-O86*˲( eSg-B!OI\]])ʲZghfR)sbJ&E:a4AWEZ,.wbuքl15 uޭVhb}5Ss6eKbکA&:OPuqH@lOlQ[ QEAV^@ȯ*P%GvGQ)5y烌T> ՙF1|Gtt?)@O}AͩqHDử,vtu6ci_2?kmAG:@w^˲,77^.뵏1^sƘOE4,ʲdf 6MEIx-/3V̳#mFܐYeT_J)y?Ή} W4FG񬀈0+daa?zSTbzPsRŘ}nv֣q-v-ޓ&Lv@#g6糣Wp)or孟b޶mKl6_|,7Y2Kͭbo8P.z6!fRnZZefp 's("l"Y 7F^c>c }muZ3, Zf9WeEQc^)"D`A(mRte#MksΗl> -<ѝ(`E @Cȭհ%"A(iRI=Lnoos5s].ιsfβL)eLX\9a.oSxarE5ZD1²K4"ȓ+j<}]s@+m+kzK-k(,YBHY"V1C)j綽}֟{rsjTѽyxf' xmNL1fFa+7x+cE9QgMQzqeEc-E&Qu[M*j}qq7eO2Kwh>^7~._L{ dJ"u,;oW՘CC͵{z,c{Sw]wcmOBq,5m 9gٕe^)so" Ym?\<U;.9%TJ$0\aMLu("|ެכ( %u|2g6է%P!o|e3RZk!t8*Л:fV˗/y#Bbb\Y֥gI#̋feׯ_gYfY,$-*Q4( *s.uT}?Y-;)Lg]i1iH-&Lp 9ړ&U I/ > d#BZ E扙5&MXۣ sͧ"pk`F,dnf97S$u)9&H"* gdj>v 8#Vpʆ{EoY_s7m+{|[51M47n?컷Q)%oON xロfo޼Z[kU(bk|& U(IsN8)؞-fEQEFDQ90[f „,@H, jQPQa|j$TI}X;vCW^3|nnУY+Wd+)Uі3voi`QO XkKSE\.ͺqbc0""lTj2[Hg6)kc y9WěUgl|ؚ=އS&mZUUǗ0ЌPvicOUTn|8a\0sǶ;*:poO%wUD.(""(iccЌ:\eYyGao!u{{z'Ү44fqr{{K ٚ|fvQZi2K/y{uuU֛r*a$Xqi֋:%T{vx}3F,/ß`E!}ؗՌ('X']N1&7YVB$EH I|bwԘb!@-dO͋7'3(^gvp!oh!cU_ :#MbЖU\6F%?{af1"U#[+q3J&o,~ADJkRo?Y6OgWWo޼Aje'{EQ}7 iɳl6Ǐ?| @>]i{M031s^ -a@>d}qT;pzeLF{s8hShg$fz5knoo땈A|rZy[*Uz,:I($R^`'S_5zMDo߾4Q-߽{wuu:s EYڈT>^Hk,kEc34XV!L)؝C0!>_E>*dEDQ ֕՝m/3B;US{?M w@O>%!Um:\+_!CÇQK6&v.CXP]}^f۽mJ@S.Mߟ_iR%gf4QX'&[e?~5뛛h_*M?1+ez^+4,WM$$IWD @DŽ(N7NQepF;CKLZ;G#c-vFOZ,Mgq""|9UcҪmÅ^+dQq.sT7'A5rCQ{2HZ7Sׇ}uŧrZEQԖyx;)L97޿lHi_b%V;Lj)*yZzW1Fh>( \^6YwT#+]y?֑%a/azޔ{']֌8TwOHCo SAՖSUOࡢ(fy!3T8DBk~ Y)G} K},9a~P)ޯmaC/WLEP%0^C"BkssL9]QE18,SHl8.R*[h()|6)ZnΖo޼yϟ߾}E7L42Wm`Un64Y VѻT"d6َ/Đb#6pmi3wX DDP8$IYkZk4TCDZ[!՚(UoUցjC~1S3j [<ЫΧ;r˞]|[p}'vʷP2 i+ya_}R;k (D@Lf'3<8bv+ED)x2GDPHkR,z_?e_P϶wߟWskCG)(ׯO\yէO6~]Vd՗^>Enlc$UI23ܮgeY*^__+^~]Zns}sY>95Zkbsjd'#U,6OZ *Ď+9!w(,8M Q2[fed'(N!EP?4m@ @Cc F\ϡ`xn;.]!G3}AECj*ѫ5zO`*aJ8P 7?}-i̧9x@tߕA"kT>Q1y^ Hc97tDZkcL+7ggg%T<.;犢u4 6?|.ϟ?}ݻw咈nnn4-P+\i1Ç__a<4J+54Z~wɐyY?Nt>E [k(8NIJ[셖Xűd TQӪۆPtiF*x,J vyK~5l,]s·Run$aduY*H7Z*O1ч0sT@NT7iw~%^F:Oh|suש+ ﮀ0@h&Q"Uw꟫-w7cf\.4I,ooo߼J8`m>U$%N~?۲,__konnT/ `)rKGggglbB߾{O2w?8~fI$"GރJJkM 9DZ5X;*$}W+fQV>|{L,Mp@= wC5#OtJyU5u36"{8BO+Yy]l6k&%އ[)FXEWFaY""THikUOě^{sv+TR4Ʃi~uKs nj?-u/b-Mnp]2lN(h?˲\VeFđJgryy.zi.`)Rܼ{ezgDdEQ\GQH`Kq&4*Wc8^,o߾/77W\!YΘ>dQDDL%*,KL ! H :Ggݝ@צX5'\H Iўnb(\o(ʾeZ[Q]J:PfDćHkhcf*6 o#W 2c.~1q&-/N7ة_5MQu&ʇdmՖ zv[Ի\.-fI D(՗ϟ?74ljR)[JEq6իWR͍0(no4֊_]+gK$]D)ea B'WWWD/|ݻwR\$?1: @"|TgR"sGA߼`X"v(_m%yzʦ]2FNdT ۫mI*'ĺ̫m[0ſtZKJi":|9fٺ1z1~<|xe($ _+ M;mYvX|o޳gb%'C vKHKޡy*N z[d* }Z"-'ڊJ?TO4+'3#*ftJ@"4J{Nڳ fj1DOEqzֱw$:jE hKtS]'nOlWo F n!k3 WWADě{/jӈۚҔekM^/sϝ@g+"58fʼDsu7o,KCgM*(Z[nl)-`eJ)*IYV4MQQ?^(|@$ (HQ*bD$9/6nλF5=fm/DgTFHHc[*rd%R^eEzk4%ulo԰5-#Xpqi'^kj3vV<(aJ)#HR"JʆwmWs"#0o|}^BŜ̡+lEyį.YPDι׿ˇƘ$A8߬$֤izvv6_"xS"BqKٗc8VJi˛jY|>gE^XdztlVէO>}|Z)u@y$Yܬ$IVj(l0c"eZȈR{cWg'WH(}RU$IC#uTmE$d̬A"fWyG "L?yuﮣR)]sHbi˫QG/ FT]ߊH)$Boju IORO<[\em{]qo1ס{$jz)?uŻϣ즻+i~ȑ)>#'[Lļߝʈ2 1Yin<  9I)mq')7NSq5-R#G[%HtU #sn\ӧO?O Ds3E"IGqqqy*"U%`aa޲+ :["eYX[:ˈBJHQE|;k,(y1ӧOIf3cR'IiLQJY:cR fgDPX IZH-5Q;;8@;.BJE*֭lc4PkUͫbm̚HRTEwuDJQDyNPiȏ%eYә!j&c[ȓOh}$n#z36vGgiSttkoAa_?ObdgဝSqk`qJp^1^9͜"cͬF+-݅?MJG `O5\#}fy$ieZ-M,$q,R)b$IcR +Wmse^2/(L(8ё&Egk-,7E~?~ߕ_Q{>Lzl6^9޽{1_ZOJKԊ8s>1T-BHRTѩ9vH)tS0)'։j^,M)퍷RHb }ĦZ~Dp]U-ǸV*kj p{9b[4"-놽wS@,UnTj\1ZMAN7CEDJ#_je·c ;`T"c~w_-\Y y:8beb?k%պmC^Nzԓ_5rZoMTI O-z2Qȗln%HJ 4)4dj狄P?ڔ[F/J[ˍ;r(qrKRJ6ҽ35@c\ xileS"|7 {gx8̩pSӷx"u"N4b< }cztɍk"jR(~_~#rII5D4.ZkE2E˚cf}(H1l9"FYDH/on:H&[1UqI9R@Di_sF +$"RbI-CnOcTcDjTX~j>T%^FCp{BbUJ+`Ea@N|ĴhƴC}YuڣPD[}}K{]mm-S#D;>po w_@|Nw أ)r|ssCJ,Q$5?^882ENgv:sC}ShS+&_iK0BMAamk'"RJ׶S!je1b,u䬮핯njN8P (p3=m"<94%^ b^xoa88.y3|`S!ppR5=vhDﭤϒWU`#*yC[& IKV3k\qY`E*ڥ193'I~SA8DuW-{qsnɫ͝1#ET'lryf:J Xc2/VUEq@ei([V,ދ/6N )ʉY{hZW33)PJIqavYmŬ Mzm=]1 3Sc&Zq*)uHx/mUkܟjvGMg !=JzטepO$co!jєߡm =c?AM~pر|[ He kZxe^iY=cL$J)vhC$qP$6Uεαs@ylITke-K(cf^VI~+D1Xo6:/gjv~j5KW|7gggYWzP(K"O]7777}+X(fۨ DZ XDQ #F?`[ʥ%pr|Hm@ @FBd-f((')=@Z\q}mDi[;ܫ4XYKm[>Evnv?>ɷ@nwEЕg;W;m?in5\X6>p%-,UVx ,, U` $ujMp3 ;:ҚH?͔˙g88Jb[@sDZ- uYθ4I"X1e&JzF(,cgG)eIE^.bH4, gcQ:Q_JcJ[\Ei:bQW.non8"we,clhY9 @E$bEDZ{w< j?U)j*/ -T@JUXIi"#c/"JG$FCU "cJ,$}Ċ\gFʋam2 sa*bbui<׷x~{[h4C#N[2VwVja=[q[0cW?ǵ?h}hCK'|XGt䣉tͣRX=mǵg+@}~'W`4w47{q9Li_GM 3_l^ˆX1jh%bغ(`c=7|`Kd,4ɶ'K1[-9coBQUv_U&b\VeYB͛7?~\o7J)I9"/..Ç}ݻwnno.KTYn,{5^Zk@DܘQoKVܦ@8櫶auWM=}3~i}(] ds!WNSg>NZlXor+4Ol`8ÇTߦp8 ;Hߣt-/l0--Zb wD"x~ff(TK1Yynǹɛ$ZD$rmBWZk}"(BOyaED7~AŨp|}}m埯~_~<{v6e9%[o//?l|*ADƄ?|?߽"Z{{{;׫<"@􁮼6c'cMmju5"C/lO[lKeZ91sj,^mv-n&V=ᇡDWi7CD xwzx+{< ^ u n|-Xn.,AV)01 VQ[I-0X%ojo>dYU](9cG:sX 3֒i~=/)MuCXtQYSxj_,ٹ?._:?sYJJQI2_~l6x%ʪ4ibJ$o?OJo7oV$Itsc>~$ &R-a1U!K G9~CqnӖj5vPDY*h3OiⰅM5YZ ڣ+Y׋/jOV4>UR@P^\|x-=,m\.ww?W;*u+VOf曍٣*B#3TY#s?|kMQ)=c$ъDD,y-JZkٺQ9Vqw[#W9/a˿wnVՕ?$I"(>~x{ső֊"I/~Ero$q"l%!ܓP!)1)A!woԢ{hT=Wmlڭ*[s*a]B!lO0r^p\]?le-iXgwGS7.6+>IOк=܄ ƯhΟ`9S-UO5n2mJ۹^TAe51muΖ%͔J7! 1(Q_Zef""[VbWHW=r"E"Z@@)#I$I4],f^.Wgbt,N@8MWՊHk%IjA+Ec{k&9}QP,N? -Ʒɾ n ox!ƜRBex,ޯ"lST؛ܱ΁n*ٖŰȼ=$?GЮY^1m&]w_?ד!]-G&Jv`@{P ڵ!n9m$av!`?SM7~p^͕xys9Qб34Z[SE\݊.Ͼ{拁MVūׯP@LYXSFZsYEQd)K"$MsyEq331s- {=;AZSp!ZS*H:VZm1̳4EJG_֚_?|LWD ;g]S,n?|3Pg4MҸ,rҔie߿O4M<޼z ,ӟϓdfͲBk5ʟ󻹷 :|jm['B.MLJTYD-*ƘF j&DėQWIyhv6n>QDQZ+YkjrֲF$x"QH5y6wuW))1NPѶ ځBG_C6!#adI9?^?@[0VpԇVm~X|4|,>-,{9[xHwBDsi PKR(PyyG@D*+>|Df11"iP($1UX(VzvDlZ+95w-3x&"EgwP@WZ"/|%qlUe 3!"aYYҸ((εX,ffԛpCM(4ϣj /H>i;@TKUgGҭ542<36xvw6( †XW_?G<\{H+@PZ)gLq3v_[k98:aQrUeFTH +DNLYf wqq'|Eq5[-?QZaQO_n,[D\ٙyi1&SEőVyQZo9͟a[PY8o3卛]uG?z}F5媃 q5JJ͍*qkj ޵UN'֧>5 Iݸ6_ ܮ?࣊ qO@fD J<$G;Ss'{8&\̲l^Vtqvt l8Fzħg{9Ea+H`vdt_+8bmj{Nڷ@I׆qDiWwwRz< $C̷*r#^;\ݮwTz**R޻;Ğ&'-V.E(R|5B·__yH7WDleZˋ$;[sf+]HUoT8ރە}Loի1t 윎HiD&[V?EnpPDfYm6ۏ?m6 DQicRZk qY-a:vnKYMv{mZ H?󪭲,L8( _sstRޠ̳LD[&}jZEzt4ܜ0D-COkLYsz罹Qr8࣊ qoxD?zmq/oߴwl wWKYz7zm{ۏ#Y@mHT__~i$޼bUeiL$"lݶnJ]j8tV*"oL@ U[#IAd Ei]gHtsZ\\}YH+UVrFSXc3JcA /rOt-mr53+Bcl6c Xk<74zK$ j|DZcVX,D\Vq\_?> 1o}6*v~n +)NLg]5YTQ> gEz9-@"PmڶD*CH}[a)}TV|B5 \ IUrB*12:R1uW|kכ( 9g+E⊂*! 쌰jPkbֱ1Q+B`5&V7Pgi8JšٙDDr\!Ig7˛o߾~8Ai+dAh l\Dix}:y:w(`J{yqDıV 8"EZ'䙱VXuXk̶4 :RZkPHؘ”ΕΕZGpH|.4JHi8_F"@`DR0cևIl6̼X,h(-X#ũaШ@VSJ#%$W6_5 *T$U6l^Mo;:-ms o\2}ag "Uqyta-asICtF;`]odCnxn./zzHeF?<4@eܓ5s2/bkY}aexvm3uuD^o)bS=LSD^kF@Mt~~piڲ,=/$Ig:bqBDŐa 6/sx(4X צ󈕪PiV)JO_ݟ_~?H_|DZ|/WB9SEAZ[n6EY_^]EM鬧^yRcmY -묀SJWI!6=@F(/6qNj֞_gX~EQZkeUWĢOcFӉ +""@f=2ۡE7ƾ-2WUWۚ9ĭړG #&_2*3uDǁ~i8F(=^됂{q;cY{zi׀{dSOkNau+Iog&ǓVdS2%"SHY};ؔ6c!H$2 ґ :vc-dq\wnܟ ޟ'IrtV{mLv陑_ÑUܑŦS,@ׇlKncml`.Jb=w.-fzk@ށ4Jh-YEJ)N!y:_wPpY8NegTcG$,7 ٜ5]i#v)f%Mt$EB",-IDATC*Xgzݻ,6LG`qv)|ޜ-WWWeY.oX;Y늲0)gI:AB"$jQBl(^BX+Ds ]eJg KƔ;9oSZoűV8Rk)7̬P-1XQuE99>c뜋O+@ :1֔YHy#jn"^o& aFwf; Zbfٶ 3L]_ҭ#dmD$EX瘝BķO[DtYvuyge^iqY. )Yfgek&"Tw'm?t2/i1F4=??W |2F#FJ`aY[y 8H!E烑l~IQ%]]]E,WfΔDʢD$MdZ;c8FRyWmnOG5jqan+n֧1J!oRUuՕlndˇn۽uNovn`O-A/b`F7jaYSaޡaUiug93xBՏvm֤wL.`BJ\85mUܔ@ HެYooon+Z.BEULK0;aW3^#6JG"RcFċ4MR\%.f d|vְEQy6̔d)G=Ɣ:@EsYG|\ )3;X^>p? f`1Gǵ~WDj]w<֊\#wq12( TeeY H*IҲ,b6c3EV^ؙr;ZleQD&jZ zEɵ !QD9@F[w5v[V@}7[Op{ V3AI1ͰYwAw {X{W9B(TI+Cs'S3-8":1Wk $[ҸW8.!^+t`w{liVREY+E' (^noo1b-œYvJiDp֡$dT{," ۤ"IRj$2ˋ4I$fcfqsS)W?,sc4"gjuZW^f(Ddo6M^8fh:Eʔ*~N7JP9 ;6-W~,Z!;դY:E "@\l|f5D$CeL\FqJUFsm/Qlv&qdLZ-)\.IsAUvD(J)`!XHUu>s܆Ӗl{>:2upSH=nNۺ­ho$xT}`T6E߄z}sZ{ӛ7o4tRT99g!(~dyͬΒFı;Ÿ?JٙҊ̉HXyP8&4g2>||yqq*H@ID7ZOހ9Z+E '"1ܳUKc}(*5f!UzSgɁ6FJc5q+ʲtlqLDEb1,u%ZlܓrimX̙ry[Ej6K,HGRGjXfF&ucnxƢ~{cimGtR| ֭E]2^1[{‱S3fպq~#oĿ9֜Kc{vq7A'>QaFm}u8vB9w)"Ro~D8"cLYyv}}e+plqvfbh"#O뫠^ ;euFLZ& kqJ Olwoa^# c"E4b GDo71\Id6}qDI9c'UrY۳sn&cIi Rj1HYH#cdET(|Em S"mJ'r)q1Ưabrכj9EcSXc8<ϒ$6sV+eYQ~DXMNf-@^VƖe yQQ^y>5" {@uhcv!BoH[s,OH,">6ReUvdO50jھQGоPw;^coɆNFoT`Mv) 2aaΌ~8;߱XyTCX-VYA=D0y.}w<@~:]eUY'.ME+Q qUe%^B@RD"77_>~^8EςѫW6Mزt)(4xAc3={܃!k$5e8I9Q2K"H(ԖXkr͗M-3dvy;α)$#G>Ł62cmggeDIFId܁HE:D`kM%b~>˽?4W 4 9c-* FX\?(e]V8͜s՛7o,):YBf&rEO9\m&<' DM ylel6{(bt'qiE,-$qΕ%izqqY˜ryA8yw^R}lH8ҍS,(4EBc7;$Dn:$Ɣu(ZW!C)ɶ gjI7Jt\Z)E}0Ζ3+R 5\^(,EzƖe’e,|u};f^.XeYYZ:뜳E bqZhhֲsj^oʢi"gz:HQƖ^ORlH٭KJ)j{7y5d& vdZ++a~8I7vpT?C$2^#=ߨڰן(`!W{ְï͕* 1g$T]aax)-T1)4[UIm, v/jL' X,V^z7O?1793l6#"o- )9̘pXkCk_ƈSMrcx)C0v`*FwsapL \}ֶ"c 7{کm]yHl./& X^W>|q{G^u>z#afS~pV@0y\+GRCHdbUDZEӈ0go~xeEY2RH,eYYkcjY|ku~~hZ-Ky^1,Kxޘ4Zc1¢ M~1&ʫWWi:RI"BeEi$ID2gZc"dY)R <7gTʲ0fEZkl~JsH̩^.0JQ.Pqq\HGK"FD_oݹ=hR0ͭ֎/J%רԯF:EzaO;n{2S%cd[*)<+}x3>RvX]}>T,l1Z#OmXEHAE!",|`"Ŏ2g>U 3+yۢfRsP卨]bʲ(9`c 8W*mm3^kȲl^o6ua<+7IZRT1^`bv j53F5ܚE;&Onᄌcg5OyX V!DZO ZOFmkaUL1AFw5cB m`iUԵo[v'eNexjk ^,-1WM3> VyD؄:*0x16 Eoao '7)WBʼn2c'H%sV2!!P|12 >~^|w(JE $BYJYWϮHG9"QD3>cDΝc"_&sX/E,֦4nX,2/bYqXI>eo "&ߤĄ,@;sⱻ+"#fec9^jcY\]gDuoOuϖ]9|(| rZ)EYe߻*o"Ui<ˬGԨPQ4"y`Z[ER=3Cֻ3P>!R&;DZk*Iߴ YZ,Z\o㧶m>}/~Ç#~ ض Ƙ]oCi~N˜\ɂ:DOZA`_-~10ODgY.,cۻDȤL(e9Oas ߻4˲,SH e.2P7M"P>޹䣕RV ŇHIsISQbN c,\J5Q ,KtIZy#yHѵJK ;{۶g(7vUBTUJwhIUJx#"T=% @tC%fqR^N_ sg+ɽV>經  f_F-yZ~N/?}KŰ.<ˮO_ηw|؅iB'9eq {ybdOyܑ=B!}.cr4½d+yD>~ k{A];-#EbnHMics} !Đ4E ޭwhgNSd{AHJI)Qȫ Qև|qs}kH7Zj~u^޶BH#Y%[.4yYeYlDl:uzv)zebfD1zGxWzʘ$Su3#zNKBDQIiI9ƨ,˲{`6Zm `&Didm]b17-e%h|W]~ڇ`{+R2s>o׫RD^Ik|xl.-ic]L^ǮkRJYYgɋ"FiI"<#;FbJn!oyS(Gi; !~bx\ӮvD`!I na<#:ȟ_;%}az4)ON?#Lkqɤ99 k(bkgvF(E}6a<=*D&ȑ H;7 y&Ykmy'Ebܽ~*E{gDqD`Bđ,<.ۺHlȈvun|}ߧLGZ,˲,J*7Y1R)LDftYSPRJ!{f1*FICUJqҗ5GHaKHcb%_r2A'֧KU ~`J ;eB"ϷVg1F ެɒW{.ZgYX<zzrE}#bEB!ҙm;Όw BLUUiuRb;&δIwRJ!$f "9@.9{(D)!S40ER1 =̧f7kg@X _RrR_ކs]l/&MO?WT;n*S i Ry1h? &"; 4Rp%HQ^<XwwҽCxxAg~K$ϗzLCirrH6ABsDm]?>Ų(Pgt)@ !z@K4֤ce/IY>sӐ{ H(5,9C{yo|saE~ssn7}߇HĜe5KCf[ofp)Đ`rZVU%6eC&f34(pL;(.GkmpD\ !LX=$U2QGD,2\x>*`"\"ZeY%|ʦm~gLVŇh /RO>g|Vml,So۶i^E䜍!vm eY*PhH@}oZkgBq|>_.5PRke d2k!#Ds  (Dbăw1F K: &??wg1.y~%?_> /N%'vo}S/  'B5n/Pg쁰>FJ맧'\,}l6z>_(h.BROvkM}}pvA5Dlч)Hp!D>Ɛ)y9D9`$s۶Y]__w]׶mi$TJi=j|6!bI1'$0Ҋ"h1Fsd6Jy,o,{xxFd]%[k̬ժE?<<cf_Rcs@|xZonn)Rw)pfs:\Bۭ1J1J4ƌoB' m[LkwWWWB 9(l߇ TC$9 JZċf29 dA>9cϿ{N}0/EJ }sq*~0҃?L3&胸c7 /K0ek%avk6u=ہF2rfL> k7u^IIκlFD!9!@ G,H/:0 )cL{@$fFR)W ڶmŢ*K^ܼ~Xhmfm9qaJuozݵ-+m@>DymߍF v($}Uʲ, $}2MR(<!V+3;B2 :R %}o!Ee:e)3wnWO@*kݫۖB7mʲȳ9g{1YZ$ haPZ )Ҁbp>i' Rw=刐zk@(8rp!R@b1zAH!R*%5;"T4}FR/1 äR4.4@=6>x%&gd tKӍ Izw=9|x1gܳZO4ڗ Ԝ DLrjE1ϘQ!jz7aaө]Vc;gp @ĔU09 DnmGl9D:#0Q L&h%8{ ,LdԨTZ*RZ7͓9׶mrQEV|>+Q?uimu{J)!,}Ak@)5E׶cp!M L{d'$hGXy#YYǹ:+Đm+˲,iC;SDJI50*7m eQ(zkB}]맇)G↌۶JAcLjB0Q]כfZ^6u yxxjZ'i^ZbHɜ}{yC`5sS1Z(/*_M_؟_srah&,h|?=h%fMt<:r70yq\s!(p:Hc]H]yƦh7 f@@+ j!D2U9_,?~꺶Ȳ4ƴd1eg}xxb"⤙ ) @)<@18tTƏRJc,g7oH!c,7 YkuɢdQ)jBHXk˪HF17wwbx1z5'%"򽅝}5~,Dɸɔ J)"LԔRodefTUUD=3]Oi `՛w^?><<ݽ.b^@EQf>"1%@Ķmu]wumx֮2)\9lWBlVmšc@ ,ZgG"> yR4$ GoKQ1ƶ1F"H1>geh)I!:ED! 4vJ0 1*/b`B0~0!>->Ҁi߻fbϮqr/)Y}}___'Hypέ|63l{Lӵz__]Eh*"6ytBژ0E >R.B Yc!ޮW@$8nb%Zi6F!b$OA$  }|(D.4]u/d^2eչ(z ~=С}?k8,6gs8 q{t'#t‰O`Ž;h _z#~'bT]iy<<`SL~˥|Ty!dDD {`}2麘actBZQ6U󲘕ER? zz1$fvdYyh#w},泮2/˒aLIR&{on1FS}51hs]Raܱ{\ZEQ9I%ιi yuhgYY+9CX.Bu]/?wD1ύ1yY$(nӠ4M3̈́}%R}4ɂ @#[GDzX>}ϗ9(T'v.dYVUsZ,?}4M%Bp`c)%;)rQ͖뇇z^=>b@ . ]UEuuȲC$EQ# + bDiy=19svNm^8 cQ^3\S @=Q?՟/.ɿOwA]Gw<^y% s>:$vmszӝCx}1w9G5ϞPB)um۵;6M4J!IA(zO)9.0 \pu8\ &f!Bv]VOO M!B 18z\R,/#ŇLJǧ""{^tQ'L<7I!AJy ɳ@+v]w)M]#bROF :1sh ;J}2w3EʶZG#v2M{M)SH4b<___YnWOD ZNʄ1Py+l6vB 6Mz||b(!eC6im" 7 t}/JͪY׵z`>ޛyd68Gy>C7a9g}e !8gc Z+TRi*AJ " `Efe̻pҿYg]?ޗ4]{,WX`՞'dL?MО3m^2Aߴ`O>^M!]OO)aO+&ie&>NV托br`PKD؂(i(Rqy#%ͦ/C``EfIc"^\_]]-@`j6ӛwoEs/py}5WW׷wPuibX,fŢi}{8u+onn_ʔ ڤefYfIzstՃ8˓9!u,'R0t0j:\^J w15cӵ*JcWWW&\.c~0m_}?o1"#@(Dsdb buS B#Y?' ̌olݖ\Dpm{[ɔu , ̫۶ylAr`Z}fEn2㼵͌^.FyUy)D,*`J'yg3eDQdF.eY/Qh2m(dceI5\=/B*i|6_~NbdA0Cu^ofwV5J,gs| ̽u CB*۶IFk_~Us{Db%gmˌM QKyZ=|x=^]j)/w Q+ShmE^,@ F)P@(̵\sOYէw~xUۯ]y}ݻo~q_LQ.n^. DJ,L1T,&*fq_M:Ӷ/5A'uPL #Ѕs2)43ș12/@0M?+:/N1a1O%t0cOᓩ#_OG%g{xs̡t> a?ϜlS,AsqнS ՘`R4܃Of/HLQs IJ}C[kVZkZi)%y` JJ)$ (&ؑ"0GzBNlVT3"jgE6.x(˲ۛo^{믿fbG&@$ DyrDZ*Tf&mwy,Kf&3$A/!io8iSj s]LQz368˲r\,V#ͤΌ֦(,ˈ۶J$tUUEQ(VeY"pΦU!CDkf![D',,˼y%tb +Һ^J^Ie#I)]dpx}}4ZS|Ï?&?`(R)M[4 D >#\\7ݏ>՛bbqu}sSyeլZ\-n_(VYBg1&B XS޴01Sz{_~[O}\hF‹}S޲81dP_ڳ B/٦"LJR*.%Kf+$0R,KD'.$Irn !22s$ )KRN5cͶό1:#rRF]qXD+r6UUJz=c s${cQHl;Dsv熙뮮6Xݛ7oc4c'YksmB׶&϶Mp} .W6EjuEYei)EЂ"z(1TTuc7ռFھAj6S@yY:J ԲLKedB" RniBK9/uJk8p/Sԗ<(/._8~JslY#}#uN6'N@[ɶ /.3J1.צ&W ˀgYXF`!kٰ)be0"Nqcs~>Z0YO $i%[Mka>KkMrB JJok}"LJ c]ʡUJ03^yzbQ"3T ĞcZ ffN]̠l} Ajl6]-ntu6__)I)1|v敵`\ ZoWr>B-$5˲iZFI;wɑ7rrM`]ߤ"٬ڶU`=rS #!(X9D&dȑ6H; &ԮVJj%P D Yws>Wׯ߼{(9gK87wv&fTt,\,g!blm[}=H)Zngj"$ƬiATVK}DWJb8٨T\")Moۦ(*pj"cbr1@۶J͆91mQl)ĶCo_=>>~VkzKhRb1rBr9ϟ(!L}(Ĥ7f[M no曦EQ#6ILjsiZB'2ռ쬓ZY.8<|g T2t.JY@ Gr5Q`CGoف3e\ ˕/YwL]S Y=P9qwwk%w{K{u@||&&V/A0Int5=xBdyNx:6Lx78q#d Lλp90>1?EJ'6]״jxxxzlNj?xWUU%u$>7Q1QoV}uB<3l1M`igy9Ƙ$ @H:wIMM>/Cm0ǘ4Nُu8Yk̬2S,Ckl4vY=====uM|`b-ç蜳ziVɺ.bL(D,6JC1~Δ d|Z뛛'@Z^Gcru-,ef.fb]Ƙ:u[eιɌ6R FPR " B:gHmOO &/MU*tmzݬLn&7B)0W6h3?+B 0M0(D TɾӒT:`;xz{RŔH>Հ_?/"𱚛t<ꈣs#C8oN|6w<9F8Bo0xCI;}VG/&gQ㲷hck"40L}E0JwqF^(,#đxatIY j" @TwĹٙvי`!Djm[wufJo6#ru&fZkkl6C![.WWWu]gy( !*sB@4"F OB({fbZ@^(5Mw>|BIJʵ$~jBuPWZ3BeؾeUto/7??|_}R8]O[.nC(g߽tϻގu/zS]/^3J<]?Hٙ%7Y^~rG})}u sCrS|2×$dZ&1R),l|B}R֗I=d`&W=p[( Ӵu^JW3cs=ija91aIDnEQH) 8%xKRGHcQ*!T (tI^Nj(\ejy]bJYk_V1@Y%>2%iߴCy{O>zjqRym۾GReWU[I'=8&ZlMt_1tO7~S^,=eԏ %8p[B9[}Ã?nt b`wynB|Z]s{{YYUͿwY}({#UUU{lW71Ƨl6.y3-A(BpuvB*sBۿw޽{njRꛛ(o{0F(DR =e|6 ,bH2030ÿ__+}s=dM]f̔1k--E ahPrZ?evAG'Vc:abNX$Iۗo1|VTO\sLՒ$񢀿aCi;{1#p^"=Jtt~Ϊ=|<be!z9"ʲlXeID]m-2yr1@reYffy !eO6(eY6y,%;Ru-Ȳ,yC`U$ʩ*7Fg>tu[NJٶcN1 mVmjE1}]oKRJm8ә@`f^??feyWv>{ﻮKt yo[,UnXJ LۺlBJ#(U3%E۫Mr+;\.(11ϻGA<8ym^,ϫH_^zSՕ`jꆙ&˳u K%T S:\3LPC̙ʌ3 Nj/9 ϊS&yy=1L13qC>[Yh^/ , D(>+|~DNN/p _U8S:hmzI㕄 |UIOԘόnU~ !gsf`>JkmBHZ뼵2/  +VY!Fzc11x k!&ު*JP0]uB@!yUVYnwIt])J)h>/sRֺ(lVeY]׍+) $S$8c.+0F|#Tj=vljϹ(,KK]ɳ0ĘcsDmi^IBH6BH@!Hy$F4n Y۷]4} ^ =0Jbz9VDT .YMLXlegywnZ!1ƘLEoodDÉheFk%RpH9Jm]wλBJ2"1""D~ӏ貪ټ* g]p{,Jc(2AZL11#%SfDO}}/ÿ7|b\OpOF( 5ܐ/>)^F1V;gs/*<h08Qr(A?=ѫzZ 0^C ݿxv!٭ر\EAưLʙ%P$ D$bJ#pp!r4ZK]gxuYHglb @!TS&GbOrfrTt}^_;g&3,Kf],ps{ -<˄ VR )icz!S*uwʻ5Dʵ!0"`p.N̕< y/1P ͍1b#pڛ`pRo7z[{'F#B2BlMt9C!pd" ַۦ]vuc.>z|Fdx!tDgYB$ޥef罳^]f.diJ%)˅{׶6:XWeRZ*!2B TBH (u[7]Y, 12)/^~s{{7ZP}ߵ]v nNCh[P8Umwg;ֹDx,P볅]yBӀap>(H2:}%%&A`!x4M۶% mnBv6FB}zlէOzZm6M۵]ߴ)2;bmŠ0xgb1D""}o*bILÓXIDEY:k*ϲoF!BS7R(L !bZg&Z&1DB 1$gJm.Z(?h nڬ^}w5P >ĦC$3E!eH|g H(.e@ ؏<" {3%̏k bLh/ |\Ңv96DP]|asBdI. |Femc{hR1TQΔ.BkFI)yrQQk1j)(A$ Zsuu4fO$UUm;])RիWYV , !"3d1:B$Q "#䲪2w"H!#9|ki_]ϤB*=.4m/o+{e  bHhS} 1><7`Z;b?[rrk˿h;ig# :;;Uy4ݡMbp0!m__;_{_| c_g <y"6 c2["}ZiţsMnO,Ĩ[F 3Ҿ'өaۻS5i73J@cYl\&YzAk*bB`曛jV2sumYAH'CspgE6:3YEQhvZcE~7o!Z)%L9{yJu3s22.S`=!/"j. hpץI֎dcƁH|B_Vu2|>{pfk7}$TJm}Ï~Ӻz뉅0&yeUYB ںiڮ Jnf&<;c c$fיYYwDQegE1:D%2!b!1)K1{R RAR PE:JJ%")b AUEYaɪ~uw]f"3##sGZ(i u⑷Ŝ~9|D7eʹLc4 k=}㰎zrޑ3}H/Z\p)db j_aч4\v})FeτLKst>^]]-l6R]/dZ$!{vfU ^,J 6!yK)Õ gUqX?&s5AR#ȦLY}_|Ç{\o]mj#R$_QXzj#bBf.yƸC|rl<(9S*L _(ڟ'ANQBO:K4sdGd;>0='꽑é?(S ,v=ϩMK;'~|I"ϬP9LL/k{``9BD_&z" ^Uw澮꺮kvvm!Ar6FP|fPJ5MzMUUۧ:"* HB96˲Ȑ@RYQhU,^.e1֮c 3+eQw*OݻwRfnfॶEQeif;-糔1ЇU9ARtZYkG2\X!6TJI&"m+ ;Cmr>9wwͦmTZmW\W럽Z\](gdR))u1˥zl]ׅٮY=>﷛]]׽PZ!Dk3+\RʘE؃:7}dJ1d̼qaVVۺnk!T͛WeYfr$4!x;DBpZ)ܵΫ w11JREMX΢k3e^y6P C &`fvۮkbH+dOa)t};@'Dg=GͱJs}l>湟“5y?9i?r$??D틱P1}nu].c1A]4IH %8e fx޽Nҩv(X Lj'&L\ЇÅ8RW,(@ h8z,.O>&kӃ:NIB٠BH!D A( %M~:+RV; 1Jt1eu{wӏ?z F 26TQɬe RaVBsdzv}5) ԙ1QJ)Lat1QI<1UUU乷nV)PҺ ̊\祏tN**-1:9RSd"e&b!4@R J@db{&F@)L 8|hy_gׯ^X眷D8Xڛn:H#Hw_j &z{_oϾn7͝2Z̲^egPի7_onet(j郠k,ޅ E.P$b%Q DL䛧')CWO"Em2t>P Fnk)Ĭ7?6_{-,DW"Ű\狫(R@ 3;,"lͱWRdyF mS$,G&/Vutm'Pju#H[R9\t $NX=o I=} Y'If:ԣ0 ͎cBrOjS/pJ0/ 9A ԇ#1i g9|*Lo??4g:C|t_Jq89ya/蔢6(|g- 8?ǽu1s,vP:pdx _-N}J-M@?<<(% km]I>yv$3G2!&vhJ}ܺq"3T V{KxRa# {kU)Ӈm@!$oWmn_bdly!," Q }+$Uj>~#kCa)<Ā,X0O B fv1eV^EރHYu];\.n]-˾C(1Ʈksy_g1F(ID}QKc`f!ֆ ?}w L PkRRh2 1z^^OF*b6M˶뺶͝ ]fTbQELR9ڢ)0${.L#/7_. p:?_y',LϦW/_W{tu={T V^>D垐"p xhpWx/#_%J$$de?Ao+pJ<<]GNK$ 5#)H)(/0s̼Z6}\.WJyushf˂ׯ?a7*"Ac3)ɲą$a29<דD@ZK㜳Cb)e[VBxՓ,ZsN)Ud3璯7e/(<<Zk\""Sncu1_C#9!~* NIFVL{ͱ?|$ctuBi1l1?Fj͟W_},f,$HB2I* ^E&Un383}#0w7O?0bCP$H O={ј\J{z|,5#RJ "Jl[HBllu%l/ʲ,Fl6v;riLT`\Z/˻;#y d-13" 9ϋ,ik`/$Dme*Elb&6DHiI>N,pyϔw=RTsni&= QTNODG9UxQ{v-=|埽텹B3'k/ܗϡBbbdu\LC__Sis x<µ玝4r|xO5{\>-qUӡKN7iS2B w;۶m!x,H S& R횒;H3ٮ kTr@}u>5FN!F@0ŝ0J*}a'Ĕ'-j}I'o2(̴TJH) K B% XQ($`i\ [i]=?fMߴ]mWӓ1 o7YTo|_oZ@ϯ evm"hB-TRJm$D01~i#Hx;baw4^s2""ֺ*3 QoZH ><JS#9/J)(Rum:Hy,+(b/OZAy]AۻWww"|2"oNT_I_` Z>c0jly]r^c>hH6^ sbnoНWx|t 7D̝.X Ecs,|&y{)& eO{'䃂~>[v$w5M"y>'lVM8fEJ_=>}ͻLB:S_YkeQ&̗TF1ET(kKZcR"pu٬ʋt]SՊ)\j dBTU#V,KJ|Y)_B2#UO< 1F d!R*=:MCPJ!AM0yGRވ C%SDD P*MBfR-fsD9(>I*sW_-n__El@I@qX+QeY$΢?{xzrg`mWGH RDwM+bHAϨu3ҘLaFf((ևW]i%S$a檚%n)-Xy:6ZJLiUs"[s QQhcI y&8Zbh۾z;f:N " "@b LGR(EdR;xb8|ڹ<3\hd~F} ?_b= `<ex:{z9bbG0p1;Ngy*<<↏ G1%ɳ/b8FRNA`}Eook {/ft:s"9^2fS !&IP9-8mE7E"nLL#mv(R,$8, c$U҃S IՓ GQRJ"2b|yW~#1vK#!^-)!8y2l6ai?o̽ԛb cH@u[rT ]w*)A i#HEu#[!{r-EȊ:B}4yKe}ӂ!(q\cB \41i}ᅦgRJ}KDyE. ,ˋ9Z.-Y襔,r6)s%%D Qr!12xumny-zva#R@1Cܑȟf8Ÿ]hgu;{E&٣#|VaY3M71^Pf.3}6g0\$ƣ`:hvR=N 0рϭQD L^ 55@8Dk9 +>b[9{,P 镲}ܼ~:z`{ Vй0Y${NZ*EUUB E5mLe4M\d{{_u pʲ,^&.Q\D䭥Ln IBJ)&ha4ڝ\S3h )i)jZ|#`MD&ܵͷ?|_wby}?z7]; DRJ-mO{C8p]W?^V>H(D3" W?rmSy%@ 4K!)V{b6QGV(ڦ! WWr) Te,+rZZ21mzRdN~6햢E)ٹ#Y+,KT,ˢ*qeYb`"c( :H>DoEm˲LT1 `ff#: /g_S 휜O9w/ .k2P}%|""1̖tfpQ yrr>[s~@Mz8sT*<?)gSϮ|Ojߘ/\N#"K٘ܘ>3ںaȎ# -Zm Jrߴp xzW7otM>oӂ*{wIu&]̗j6/+HnҔ:眫j>٦CDւw>zyU͋h6HQ%1[,R6q?_g 0Ձ[IINȉ+$h!H4 yGJmvuk)~Cx`?4ZC{z7dv|a9[_6sdvv#k2sAeLvr󲸽KFZD̲uC",!bZ1ݶ((A<<|pc~tymY)UCb{z>_c\T>GD} ;9\ 6sDkM|X)NcURu%3ҀdfpI|){nb9/,r'*d׉xOP}|_A;e/PQ/&ag>v qIE+u4sj`0Nq0䁀ݢ3fq<`^G+/=CNi9 v!ùQtBHD!` LZJ%egyfI]DbD!z~V# 1(6M󬘕B !]ŸnbfjiRJ<˳̠]ۡ@cLYR !4yKPRJ`Y1f6I)hcd#e O%hLX0e2&ij)2Y1h0eLҁJH&Hu<=>2ׯj^| ]Ǐ~7~'(52rلdpl -z:,}@4 |i߷ak~z6rVev}3Օ:])D|e @q)M[gYB"YnM]y׵OO+kfn:!VYfivIǾMVKU1 1z-횾m嬒@}nԼ_TyY͌1J)AR*M°3s(!P ƒ $"(t3@ @{3f*<9w,G^AfOL{$_Gw `#`LļGNCH8g7¡}<ύmn6LJi?xPXm |$)ѹ΍$D ú_F7KUe1r~/K^IDATYWYY7=h1D RawBnDWUp*f}_T1&#!c({onA7Fk-|/;uYD,ZsyND͢ab56N-!ռE!4DB R_cLF:DH4R};9ZL\,N{_:BkArRL뜐g-VpO)oj>L0] 2bBf2{)wC1<-|?m|q~ŃΙ=7{} O9u̸cP(mۥф/\dBy۶OOO1̳"gfBHf1,Z)ֵ\,U1 >b ϖm,&@ȬuۦvΥeUyƻl CP늢H,P"rJQRPw7Os!͇CU>L<,ϣ0FDcQ?=>}Z*S"sk}͛n֭@ "8lld)$fYVж.8[=4l> Q't Z򗿼{qe."!Ĩ,CD!!GH9 .ĔIy˲tNR)OO9U au̘eYݯb:Doc DIk,̐<1R𑙥}ݴmi777߼iȄ:3c۶i]{@@)ppn#)Ly(uu-E%p!V+,R홗wc| QL\TR )RIctf R$u}1HIɼVܼ~'P@Ƶ-P e&tvw[zBWs\6o߽AݷჂy3 DR,",KNF$!H)Ty_6a1"ۺnV ILIZ"%@lL|}ߥʐ1FfH٫R$T_mM EQfYf i)PP)QE!T*RK8xcr'<|gp10i*1>S6Ov/\>@LLIw/ >,w=m#==|>㽛Ck_eOn{HD=?v.:Ln,>ħj38k?tګ'g*q5GyڶmYI-0 k <20E)rC̀E"gq޽7Y&!$&!>/II0`BZ뤁u7&,@D%#h)UX '`j/Lƀ/_hEݗNnkk2 /vΏH؄"CH!0sNy|2z'r̋jxuu5fJ<ϯvnS)80  (AuJ%+%kyyVeLaZWEew'VJYkzRmGRhLw8 =Sʩ$ >D I¥}k)ruTEQ$lT6^(ITRfysމ~e]35D&ۺ?bvQM "D$|V\)"eW )Gn!D‡Ym-| cnEV@tbZH!< #r] D}d2 !'T! "L],n?|\.PhFRQD2DP #1pD̑|2`"}q6N\yihHҗq_>BW?7BO^2:_,_x&=~Fg&,^.!`'x?e?yCDT;hju/0%1v")%]fCuv\AClLy$hEcf̬(!x c`(DݎDNy6Q &QߴlaQ7ie1R"VYi2g 7RZ' $gr$0a9t)"ƒOHD$4 8|gYa;mcCXYd& >3FIcafiL E캾]F=2i)1J oo><]ÇBtB],R D]DFDb oJ,2!2mVJJdDZu 9B0ceQlDx2Hb!^b!u U{/JoZ.1s"#>}|X.o޼*2)d=( B#wQc6F (  G/L*/y.=i@ >LxIg8q_榄˼6t>ʙE r'iH:/"P8 PKRL(@GPLr[$tRԒluv,1I" !S'WoD sMD1D#B޺!Qo@pC$#ozf!*Jk&9*yίn2nGweC[BQ̯u&](ePDa@VzCJ00Rgm9o~ج~UmVb՛~SU9v1fYfv6}nY,Rjv/6ONIDF`!IvadO\כzfRksUU%#!`V[ [3њ:~X@~-5 SFZʀ@DYB,eEd9Ŵ;蝗e Q p3:ΉgfM_wj:m]>uDj>s<A'4Qu/ q

    7o|77W @BSs7.证"?Ghy1 c$~CȄ̃_!FNY+P< W7SC2M~'Wx8zr'mTL J Iʦi}߶>}WotM \֦*)&B6FhZ@yV < %b*vH&p"azOLbkN}Cp`|MeBP2h.H98EQeɈ8)u t!YV^MowV;U2R8(U.z)sgZyol8f"^o?7UU?{{Wee RJ兡hJ)cl6Yt%1ƼȈO8FyeQ"G<ϕ1z%QI) <}U>=?P"VڤW2>'̬vO؞_N @ws>ї.T>Y9gdqs7, LSu?2bnVp{ڬ:OÿOP\ϻd<1POW F4(Q (:K񾑆seY6ϵI2͍LE}߯O8Ͳ,K-L{)ɲd1hdh$#XZ؁S("anDpjwpqB8뀑jH-L<#@8ק|\\-W^o+WEUUM֛߁;(,HCc1H>Y^.nԲtC<= -H )Ri?}w?ȳEW_2xWEVf!Z;Eھp'Dޟ5r$i-b$UsFa<췞骛̬"\9 j΃ qȬw\\OU?%"߶b  @ ޲BD<e3:75wlTQ<Љy9焀s a>0:] 'xj0OѲ{d{ 鳃a;App&%g.'S[{zSDʒR97yޚc:L]uu]ekj6eYZfs{{}\Z)zgER$@Jy&BgEZT4^ L1x:xq4F0cjDS1ɠWR*I4KDDmM<,2 u_9uS*IY֭ۤu:+BK=%'O[JJEfE7[e^ knc5[=?mחWQ%6{'z*Jh:Q8{yR3K^Z_\J9VwtΑsk5R%r$5 H2EP~ٲߖ;@7+޵4MCd:ہ.{rn?iqo!s ~f,:ǧ$ͯ>/Fc_M2TLpC^Y1]ԢTT8^;MF'Ÿ=se|='M .|0G@Dh"&,˒.F9ͭsL%L;UbիW>}ZViuugk%4MTSZD4i$P2#狆޺aBg"⿆HIXW> hoƱ^nv3&0mc$I"$"GD !PJlڮKL (fiȭT*]f4jSm?.K!nMR%|#]\m*kݢ֑omo۪ʴZ_Ҁ^ ls}yj 8/r޴Y5M6+H)@ j!CxO9D(fk<@ HxFRBO\Ί2[=OEzݼ5V&<_^Hpft2 hcl&]xgŤS!ϖZC/O~JG=i? W'P]vnmiY 0'_(}<(Z^)e뺦i9%f^]]Ƙ뺦^rƘz꧟~Rt1+)(;a)I|޶m4|)wa";Uj;BÀ4191tqُE)ЩREQ8"藦)g=֩:YJ{$(gZLWD\8dq5,mzUoŒx(Dif[E m6alתTnmyE&\ݗ_p$5Z|~:sD\,UUm6"Q/j)npȬ(,Y5{czs΃fYuY܀s24' L)!Zjլq& 86iڶm|?|sqn?woNy1F?uOLtp DI9'|i!O3gKhck_{a&ANR"i<k `;?pQs*ޅ "|?Sh#9q,!"XeiH (0WBJ$fn4Mky.͍l潯zݚBfiZ|^r!MfYgq6_嬜,X'Ie;<3MwڮﺾΡ@uy"n众r> @b OC}JrDub(FD$I.Mb2Dʲ\J])E׵iV",˸]D5][۵,'tMTqY|]#aswo*=]wͶWwv?W_Zf$n^Xw]ٮ7qeLOJ)mt#@uvM۰%d{ 3aᣃ_XwGp81gZM._s`W4]! 8m&RpvȲ1ޮH Ũj\BV M6h^*n9D"˲pTWcX+ ;p23TcN swPĠE"&fn& k=Q҈Rʪ AJ\&u)QdYDE(ֹE4yl:kRczNRSrNLs'Dajɒ>wJ)$Է7(լbVR IrcxDRB6A1Mu ԛ&-gʠ̸B*K9D w'$DQtپ uΑYrN gZ%ɖ/bZ"_cvm+Y *C ( x8! GDpQb|&&N%W>G}g'" u-//YS_95{PzD^^Y4fb,벬IOZ|(bn9y"U4Mּ|$I2(,/J%DZRsO!i"Vh1FJW <CD#ﵖ5ml닷_>OΚVIע@Yƈw$|:"aХ!d9H*qO8S) w~;/΄o_OŬ O|Ү&g0xLja Sqa"7N>j4A8gof&0ϵen+;,D@H4RZ )w/|\.iUQUzb6RroڮkZ{}sX,?ˣ1˵ȷ)eԱ~  rjeRx~7v0ԅ{"WvH@h RIhA>(4Ϙ{BIZkA{c[뀻q*uZz$JNs$#F(ӷMu2]42!Gr^ѷCHc?}lZ7+YEu[W?|*vm+\`hHNL'IRUIIy4[(% zo9~=|R2'p΃71KDg9")Ոdκs=K)N IH9*TEaD؏)v4וּWc{%?b>iRˏ|cY?AGɵja꽘>unE`6ihr@xO5|OHK-@B%BIP#&U2(N*o޾ZyID$g^ ]wu @UUmr,3v6Ƥil.uc筳8,8Ypu{?aVg=.S3DƢQ[s*+J$@$IRT* p(H7쇃$l6R߾77UU1F ȓm隺U:cjThq}ۮ+T]ױV[oח2 )4NRՁ)Zo7o3?4M% kmDn6+֫ll(R$ܐMS&01ݝ-< A8 NQiDsN*"m۪nEQu Bj˲,˒; ZkbD G!R2)qr_߷Nj*~O,?N {xpx\%xRB NTJ'vD^.ul۶EDl6SJ=>>><+. I4B4MRy e8H]bG˃7)#`ve9 AveNSBtcZ'UUB@x[o,xjVLZ 9L_׭#f3hJTc5|dL$I״]Z"g'-i:Y}wIޮ$M;< ciGeYQDihq,߉!%טڳD@"_}%>POEtc DODЃ@EiGf1Fy8 )$iMJfe-{ ,u]UUR&:I,($0ӅR"Gĥ1x6 EE]8л3E[оz:R c1 Z磂ȯHtR53{HIŲFjq8뽿/۶+cڡHB[^׵3 tf$9%NdQDg"vB{(LJu) ^i 5JSc 1s @B|D 4BZcL0)19眳!q<ɕRigD=J!xF/X0r b-^Xal+`O'm=yIL{*^gJҗLs3yZ<9g,h E񯎾bP1z8 c?4- II.e*c! 4t]IG)RVEDDKDJ)RW0R2sabˡ~ :s nFbzdހ8|ڢ(sl;ѻ\!hRZZ jN[v]UUB<ê"ʹNI (8Ri֪B9@(sBlƁˋtY޲_,XVEYԕ׶=Y[R q^[.\UUU=>>(Nւ1DĶc@1Xyvuu5ϳt$( TuU5mݘ{i2"$Qi"P!@s}k]emW6+J Cle^l/y9³H>Ojw##xp8WG:䖍r[ 0>&WՓj8X'=qѸf_fp{E" $PJ ,!)$H\-L$X0s5[MZDrTR+fs*chHCs2Ig|_gB\{&STeN<}ʚ_h(ԬPSɴ8ڞȅ>}~GlR0*b*_ ? `(':I)& wH9ѱyYE1I{ι#mzQ9Kk]E3U ս!@"{4lMjc sC$h|ah=`f#-b8bݍ#{e  b sub;@2:Q9gi|d.T$ LR㚜Ʒˋ$IPL8]4Y,-RyTvν}62fysb|@"s)eeܺx삕ȐmIi{ 6M_-8+ hR,Jk~ /lpgk6HvYGę$I5gŋ-GaM#[穗zRa GN𯮞o>R8|bPY?}vПs:xp86}aTG'3 q\:I%5zdTEdi؉ndzq:MRhuel6+2$Dc VJ%c7$OS![QIdYq^fǪ =GŌ+e 1I;qޓ!;vFQJ)(4KA$-4MB窪=Qe :f&fSm<ϓT:>$LAQ)fi;)eߴι꺞1i(;!erC?Rx@/Ip:JNhÑ{{zHO!̇eۡ=% @Ȇ#ð* pxޣwiy"۷vv;ʲg%ι4/_`88v{E3MoIX@9{X DbSX.9˲ޣ'vP:ru]5by!f<*7,IE$mޮ|Rv86XqxˆYD2km[zbQD,Y^6P8$`]㳦< 5FJ jZI){ksbyI=[WuSm@(YQ:|۶{(sޒlg.7-AJ0=ʁkĵE 1D!ϿCy80lֻF4loA8Er>I)= u}߃x@ir환4o0^HvQ&O}cnzn,oI|NcD=rH{ʴ8:}^ &\{cc(<# iuyZ!{FcTَU7x$mXm rg{ ڗKUڇXQ!Dgzk3Qh@B]z|Du}oۺ6]':B""yzޯl{-|6G$Je `~c(Yu-Yʲl>Kq1qiUU[5w1L%$gg&H)X\.&l6ڋ2R(ofޚ@X/8 #2O=p@Pp  e/z h+Kg2?'K'T/>Ҏ.x Վ.8%*仲s G.]"2`;X^_v5̓Bι+1:8V [̓9&.l\!$ 8W9Qj8B!PpoQHʵ ӱ)Zڲ} b5;\Pi;:ZPq3xh<~w v'v7JiH],˲$%@̺*Q!CpCU5VJ)Tk F}||LY{k{)qJqO^/_iz 9n( SPϩ";>LcӬi }m} ) H}N>$ҡ,ɔ=uЂ9Ʉu3#&jvyLg2=]O|XN lx)#I̔'COn;x1ƏrDpuL "hF!8$ zXC ]q]Ɩs0lc %p#4= 1vϮTġA Is0DlL'Ď*VCZIĨ]۶_xWb^EuƘޘcP?VU <ܼ!nZn+5iiggRh 8R)n-"^__/˴M}~xuSy$Ǫ5"J$qZ#AUJJ,<9̟eDARru? dZ5M%$2Jh""նOʲ\,Y9gNcD4k$ kS2dlǐ&,ɘj>lk3+S3'.qV vp'A oo~h_NJԩ'wl})s>5HaO>`4^ 괟@_:~OgOU{c@9qb2wm<.AQJ);< MTʪ_"Bv[tٮg3MS"2&qAgr*ɱų5y)ޣ_"Q/o Z)e0BM B09Y]S >JCZT1A!"4..˲4p??(GVY ]gqDbc&c?WMt~ƥ9j5\eii֌%UVG!q>g@:ˁՕi{ə_R}Qk=+J6>J$Qn>Z*MmkLD.17(R$};ߗscc'Q41B4Sʊ=MY tp6])|Ɂ]lANg[SRXwx 'fNp6v0xSs=x2&_<(Ro IG`o 2>9ogfo<񜲁gg~z`s10 7,9~]ZK/ E6 'occOґ=WW1E 42o8'PJZv*׍.T^5Mydo,"ZꭵB";B2m*0xDagvNak&ubZ?~9g4Uh Ck&x笱( o1 ._#n.l6u]Ø͝...8[Ӷ-JeY&dU%?g:MA ;2k%ﺲ,;UU)!DDjJ&i*$UB=EH}C,!A" Y3-B()Y3@M&t4Zqx jX }^p Zk"2ps6EUk¯x>>Wu0Nש塪0glx^_W>`E$M=5gGByjMI 4v'SVJ>pp}ygO3oS!{Spw:<9gl`ƚ3Vv ؏B)@o덧4:ckaEGĠ;ȹ]8BtAyZ,KC`}@G೔F's OpmA'/q`~DT c%}0"l19XRЕ/8C8k;J!Fd'#dJ)TRJNCnň˟0%w|Vb4#"yXG0B̯H34ρ-i ȚQC,гl68 a<>2όRJ%d]m*)߽ySƜ5}2A:IDuMc۶m]ۊ+IuDJJ+8jHc:4"EUUu]VsnZGA/& "HlDnڶly9(imRYcRPDZ}/9^i T8{2;fGxBc`$.UJU<#5 C*k8ޥgz(v^=/8:~Sz8 .)A0`lD@ i% Ruvh,9`hUU=< h%cΓN5DƔܻ_כȂ;:xb*׌#x0O"O)`WHhZCqI ƨAXMs;8VЈg0,QWdPÞO5D7!jGW;HsŠJ0:C}oBCQl. SoMuQ"Hc ٻݬˌ\Cby*MgfHiH Lsf W}luI˲m٬tNҶ1M뺮Rټ(b>cK3])l5]$ɬK1p_ÂqSᾳׯ^՗]lmi矵WWWMk*%Tv]4BsZHア$/1N>0K@R..~ qb>m;BFVNN3) '*vF M,m(>vt6~A<>A%.2\NgDi|qDp= {Ї."ǞVh;Dq㇁ņ-/?HS{ԵM#qv7W>i2[!w@ z cqlB 5 e(B*Myk-B%yﻶzv9uN&| "9pơFhM׆Në;Jz_M:v;_s^8s~>>q$|Pxx?cʸaݓ@]81GDd󆝈$0$C|Ľ콅yK*|w0M2& k0" "F!=k!fq!Jo8<  ^zﻮocڎf'$ iJ%8 TirQ)U%7R9纺dE.zH^%O֢( W-Q,d(~p8Z+Z.޽˖᦬}Sw!DmIsY|yq1̈́L֙7MӠ(v̗|SW5[Rs5R2z]kVh늜fI {o݈!ơ6\]]$iNDeTbJ5F%M BfejO~;xn)Xo)~nn34=rQ -;nLBt|?rOS"tbǧ:"8OswT͙xzRJ8N!$ρ!qTdynѩp0NOb'N$Pu$5\bw拠2@Cs\ 2KGDf` U)ڝӹYJ)qPԀapËEAX.Ju;<[V`E^UUs>IkZD̲L(1IFa1 fPpMk|7Pz9J၄*0uTM&q7*7 ,gEի<۶ E۶͆;lf[kT,v6dzuH'u]?>9R9襞4C|P(C<˲3lƇ;fPo1m;TH6*^$vPYt}X` jqȴ"((Di+1lnVm 猷.I뮯Q'22ZbNyl64@}o=q^w[캎9mۮڶu!#(IUMt#\*Ig.jJozX)9̙A sB`v|̟&O0Ȼ8F xq^%Iu~:@w|;r"y: S GKgr6 0˙2qC|0D S<3;tSk{f?rx Bi꽗%.8j>$#"'8ND57BCe "t[A;gpD0xwY*8$XqF~"br3x< F͆ %R( 5#붪j='?gY9MPoZnC!ހ"ϵf^=v]w}qݰw*_*87m+QpPW7*r]߿?n6jXKy}V5U~FݽHX.]ol6: z\ {XereAJ388&+rNtH8Xi>bx_yy=[k`D8)٢hgCcO;{J7za}TA3x'+NJ6as^ '8bO#t/,^~M3D +\cN?S?? )s35xODn 9 b࿔= +_>>>rvJerIzO{ =n>[ O$IȘ P34>?Ӷ3 =Ї)!DE@=᎑{?ڕ|wVh'""%"n|OD! iM{=Bv}q9!cgGCLDD},\!hFPO@=mUCJN\ LRrݱRc4 wȁBrX C:=8,Ey}}]%?6MsPs 晤lUfl^|jl+nFsѠYgTZDRJz6樂8\.SUS[yQdJcJvΓDfvmZ)YT4jUUU7cVHL>B, Rpy9IL^B1|5~w=K(K̴?%#]n<=a= pQ,Oxd$(NE0fMx$4Sikjr d{^ nX\'I|H1S=uFDN :?y= q2$~wH#Ҵ߇ 2*K)&ӆnqH*5i`ʵScpBE󖈘`Q!8VBtXcln9A"j9VJucmJ쒪 Ų\z"}&Ҁn~sٲE,p;箮8i~,y_zan[t&l$˘Z kͦjhl|lV*(iaX3q/.;}1J:&Hc vyAv4susu61l&wN^9;zIGD<&ǛɿrT^#CE+`qA9s !WꆏU-&a8jyOu'@Dr43yH(NRb)C3%"$a* !e[VͶbʗmRAH)J M5m8gkZkںaj /YH{,$IeYEmȁN"3!UhH$uI}\V@ _ݧۻ<yִR}Ӿ~z6c$IRm45zϸ<9)w}edw$C;ƧTWȟai8ǻ(,y4(V9(g3bR$Q,?1{{n3M_:Fv:x 'iѱqp ,1@('NXRt${Wb(sJUEIX/&xo< 玟ڹ [at7rgwA? W`) Jk% YI4fBd5ff WNjGr@(m B=Q!2}?vyߩL~>A/]+N R{S[Ta;|~OGh~x{Zײ\ =ИrpSlj8\ND9еw7ޚvnpl7ý1!Jd^j2!< Q;[' 0@FN8,}h8h: *8T_Ѯ*xc_z118"d`{/O"ǀ(CKpbp|V)"` >I y60K...޼~}qq!7aZ6zHY^ ئ0B&IBĺYC(Ҍ9G#Ԭi!c`dkn۶m{/} TZ$da6M3Ͷ}}yy9+Dd! )NӶ7g+H*%$Qr6KӔzkk_%WT)"MXK)jS:$9AJaLbyUSWZyT aȃr&]H l6VR-x5r!r5ϡ8DzMh3uc!91 sYHH̤:3p揚<^Lt=N~C,rP̟SDGYjp*>0{\0{HkƇIJ9J;)aP~oY<鼎Z\o),K7ޡ`L8,*n\H~Q$ |h@ѱ'*#rPƣ*V6' ;}[ fg0qqp@8Np!-R5a'(aT̡ؗ(YQ'<Ա"#w `\....Di*z֛mR`^[U]o6*[ |% )jCsEe0۷iI伒ZYe,=T^k=_,ڦ_׶7$A.2PPot䙕zB̔F%;gھIizkTRJ@!7Sܥv.D!#]I)Rٹ>I]8a%(Ś26 kc.Q`ܚZE/Κ,,yVk搰9(8O9pV3!bÍp \G~2\.Nq/a79Ex')s.C;`ޓ_G<ZPHPj8?{4aO˚8SIgQ1LWl`r;@݌]N;@Eu Q8N{;xB_9  wbU:YG1d g`/[ zlB 5J9o) e$kel۶u_R HbZeyuuU@ιjY=6U-4-k4ze:ыb\ !^?>u:U:xOӴ("͔TܷVCOgb<{IXksT{BlZ( )crw7n62/ʢDI bvھB;r"};XVc$%sNFD\XeYxԸ[sX1ƀ5 ]s131%>x!Pz̈́؜yF"G)OT9F8Ga(΃J7=j'i}430YM C-B3 fGq'o$Nz pB OJ?S"OBЧL3Sz~naߘ 7> F#WXzȍ]ehxE"dL;aGi!Eh_d`ZӵAa3Q_ [( ":nmo4l̓uv0Mnr}}}uueR =?/Ҍ[KycSUUi R'<ꫯ]޶m Dsҹ!, B꺮["M{ ,3RʛkXiX,..nMFRY iEQp6 tDifᎁZ,刈e|3qbV>g-Q-rV9F0Q?`=.*YuA2Mkz׵B¹5>I"I9"KH`+jH} ߬9ךL V]~OGT˔H~+rnH'Bwz Ķ?8%)5|l8p.z* LI.}r]_#hw?Q|0t:dfo/pOr|S򋐆)SB8ӊ(G/ƨ@vX7EU\pIth"yyIX>R];9O| kP w U=O=ϟ3~ HO'$] e=3qS"`hT$BB(?()OyRPcԚFFDƸf!޸"b@DG`]"C D%eYEf|ukmoz ($f52u4}W_w3oB ndV7˓Rf:IӜNbQΔRml6\1/z(Rcj\o\߼}{ssJΑ>/Kb^'YW,lnMvKuXBu$]ݰ/ n$ zX,@Jkb!xي B Pj5CZADZ:Q>2#M( ~0a<wql6 0pgfPs^ X\HCvfDAde 9'1,Uxx:9v&=c8wq:ył +5,[ٿ   1.&u{DZ&m9?~\, FR3}]=oZk4 |]Pn6܃39rQ.v-f3z\ul Ï?UUR... 3n~^Bl1hiY0ƘvlȔb6-y^^\]^^dYy^YVHaP';)Ľϼlf7 ^HYs/B֦J)R!'`4MV!O c*vby̾uv<_^r:ȱO2Lz:)O\iUJu],Ieg#'sP78ѐ:@&'mJD<6f Uqā$u}X)D=/hK9erto$g=xt<q|0S1=8uo'tD'̍cT+1=uid?pܽ6YQHˣ&EË:Xr׳p rXw7@~m٠Y`ۊazBAwv1k9#F; M圈H3={l(WR1ԹfHVO*IurνM1!{To>tw[7բI@)B)5RTnY$IۡX9e#e"mˁXX^^$M4UzdxN P X8#F$=sNβLk4 CּB6,`9\avbX>U _Il'SGN05dM㹳I~xy?SylΗ`!XXmxh1'gu8p Gk !Of:&.7"qK;H ɧ-`Obh\C# *`aun?B)>&J˱6ba {904 !"Cľok[!߀@ftR$K=wy_~YŇfîiRT,ɐ$^9 /X^\m㇟B"ʹIQa -,6x-ŷգrVDG>cLP,ٌ쐳c֫LJV?uNAU؉2339}?<,gyg$yJ)Ue\^.˲ ,U25ڏИp(IFtp'b,|#, vh G2V.I'5y}Z2p>Hh\4EQ{₈m:k9SL,KUuU7m'훷oߢ?j 9+i֝1*MeY8{eYܞYByZNӾYN4M2iWRJxf:v4CNO@e$Hbtֿ>;O}=Nപ>VKQyqS hd(| r=OL@<18+O:6{hGpA(XlX!"x@>6Ə^f0`h#Y K9? D 0@J @ևpߵZiأ;1ta3[g\E$],_~ׯ?}OO޹,$M"+E{6M}///mucRj:Q 3 .I|\UU匕I"Ⱦ]9, {/4B )Hi]3F_m𰺻WNTk-RdIov\x٪_,:KiNhf9`(ɕʃe1+DQETSzkXw>vy餔<ܩ"A,Y;`bwKeP 8KY!X@|f1=4$?Z٠yXbů˜\o*:%d'U}z-I'urvӁ=8:Cw i8Ȃc, )$Bζmkʓkv^Vz`*%RIMgC i( :U2p1J)$Ts|stwYd^#b=0"Sǚ󡸂/:nWwrA8l {]/qc{&hy;rg"}} bk xw "2H{xg {4G=p;h^Wȃ(Ccl/;XKrܗ}ihGpadiFuΑcr0#jSH(ȳBHo;c?l`rsRJVZkI\]]]]]i!?XX{$aơ(A`eٛ?r^?s&uzVJeNC )HD(Bx0Ɂڰi9y{V)%%;krwULRYvDŽjd4͔R(E$zkvsߖ=&BIw\͑N||dů"}eY. nFP93 (Nc08^EfI u oo:GG۞#OtP퉾a{ xRLɧ;Ů$"=q5q`qb2:b4{!Nᓬcۏ#“d=qWR iH2MDkborh(.y<èb2!IDIcr(v!B@(:`~MD) <ÊWJ%BSEl4J(V)Bl6"Y ǘ 8~\:^4 dP .k;btfa$ќc9?{h{K{wq!}ΞSyG+ACQ`ЈADio;^OzlLl]31%D}|A}ţ3Exφ-"@!;\wĴ{Pa_""2Q 1'.n P"R#bl S$T[)'ΓriCD7o\^^~~( ۛo7Zǻ;&2DDr\^\pz~n6uH0+ SY>@Bqj`e0{Y[Y~ތ=@8cDH=ZSЏ0jχt/7x$viDWXCڳ'/uD@FqWyp_cc7$)4"dgaiNycW닢ޥܯ/>~xxx`$ۛm4Ndb53.IX,84üdPy~yy뺩{Jwww/rw}AJ)rhz]|>l6[VB4ϭ-.fe$۶9=Vlp7hp ʢ(R ٙ6̹f4MݶYQp~5<'a)4B%0+Y< AJ.W!=8W5<6Ngb2f'e*6BW4@^rИ F$sO>MS'sͣ%Sx" m&>N]~G?< ;o5c0.Xk{ɯp!N:FR( QDI$`yPhk'!-$c])iCyTnı@QҦgbG[|]0VN%qa0 #j CEb6}?=;pmX,yEQ:R }.1{ ,Ylۏ]iy&-o~K_w]__}1OR1Iټ UQzO7YI}oLv)f]ycR& PY넒\ZE[fxZksO|>"T4H9Ͳ,I(]R&I%q\ab10!1BRPJr RuЗЎ0Am˺Fqcv?'åq1p \\J܋$\;sOp\bRqOB/Կq3Xp>_O*S>1dhv0ı{iXĔV֯1Rˁxlc_q'vD_}~8{;vBEx;=b!1to]D M%KƸ7`! mBpRJBXiӆS Rai/~!k-xb1疎9)e^B ]\?ZNGs2 U:fVggE)cM2ee|0sN 쩟=Ggɫ;=xr-`ϡx_xBI(?r[! -<.kmw3pܥS"04`6]p1&MD@b7w@ށwԁ+w,ErEfoP\&D Pwv4M sfwZKFi}uuUg6}M|>fZHkm]MtB}͛7]gTJO{{8ct^_.r|m$>}u0eYvZn|} "֪m[( ~RR;+m$ID m) Q($ 56D8msNIJܡW1Ͱ941dγ*CPr /~UU9+nR]לͨ>kSS_Zg@Ɣ,ǒ6$<&Wpps=tn]1>xS>0xc}4R/gmr#Xc,Г!K%0uo*٩`Tս-)I@l]j evJB "Ou<@z"}SH(OnNΙщŮqWJ]Z˲,Rm[5"^__Vzgbe4www ]۴u*..qu]wֻ/1͆dι,~$ZD2M1v}u]`Qh9?l`^JBO` x\|7/\t|6 +<9?yS{BfC}ҍ2mr|=NNy{&uٟ?ϣ\Xȩj~v® #;.[OҟD@sc%XN;0 5Mpg{azݩ4Q(|?pIE(mߵ}X\|WUUl6,t{ge~a6gݻbL1/ʋooo{J(fU4?!o۷ۇ޾}?Z 9SX2vz\lO> 1u]uYYh뺮 [m.KWB`6^.5}sœ4/Rhՙ>/̭՞\TIpe.PFKi(UJU[D-μ{`c\}ya / >^rZv|9rvFrZ$8a<~ I bl3ay>xUX- ˮ{J>>wظě0 0dj'5>?Ct;X0p9xpcH.D<ꍧ3>8F4!5gQsz ǢdhY $!Hq&-"8T"b'=!Q($S A!Sl]c|x:FD PL֛YB0=̟4QOuf;`\#h.9/Z{n.%K@_\\cBzxO?ZLݷ///w꺶ֵm*Mt&Zcgˋߗf[\cժ뺋/"=ֺ4Mo޾p_,.닛W}˛o֛6MӶ˲$D|Z{aERo9/Goun[(em]UEn6*Qy>{m^E9tvNbYr6oF!\T~tr$ӿ^o޼{7ͪy-RsґB B*I(b_ Q; xB!|kgZ $xB) MÙKBbXZn_l29uHﭵul˫8APF TynYo۶rrȰA< HPPlVp!.x8F3^ő-^LON:~0L> 6r)G8\4$ Ku(PWJ}rC(y'"1mpУd2aQ%$~m0rB" = 8p Qk E}\1FQ tGCq|k̲lXEsTf2s/ o{}}4? ,㦁~Z]]]}o߿ymRmE<ӟ=nnn[&躎Z6J)mg]:1րj1*YVն3|>/af2`=+a>w]0XCBB.X2[*NM8~m8G=S.:r/ڇq^xqq<}ӑL.PBr_SRJ-wP-;͌cc`c 0v/BI/ݐ GZ?$Rē7y{;~A_3tZ[$Zr%{5s£z~8T .s,Dqc ou@zaw[("p <'oT8D%Sߓ$AA.0*X>tb*Ͳ짟~K8͸麇 J#xU ,뚃UU!|>rnǶ"Ewwy{xxX,_~OI|?~TJ1F۷oǏ7MSm2n[XY%Iȷm]̋V{g岪*}RJg%MӶm350s9\%YX-,ckߵy'iZmZ(W2M-57R&HstTFkK:z86' s\DXn PJw6Ϸ'Cs m2_8=Zk>Ɂ/*3ye;ߘ_UÔB,S'}?XOhnrLS ;f)^ z$`=@ݎAS'zIb0KϡhM 3crisXB}* cl`̭ADbJ c!!dZ? Đ_RsU^^6BHu7okyoիW_|EZ>|oɓOdeO?|7 3iǟ 8o7ۛׯ޾}l6n~bt=8V#u]7MSvzڙ!*g%iEDOV$Iʲ*,r"1{l8?:}{'4H6ܨEBr9H{4s"rT4 J)`_m;>i#OIzoO%`*.F:]8"?t8JSj>u0a !nM$\Hp%ţeFw8 8\.癓#9ûd+6`~~0@!6!rw@, o('I͛7Y}~B\]]- J[ ~yq͛|ӧO>V+Drեfݢ2˝s*M(?]}ۿ+˒>}L qwwNhz||d<-޽{OOL%4ep[% I!7mT,,Uu}}eYl6-'I1v}e1+eYwN2r>ca6u}]UU$y9wS~~Aϱ|" Gkeq]W8w k`Y%2M484dwVL&@JX3=͸G(V*18GIHW9IoR@@$4dۭ'+]~K "4jO  -_ذFG2@ 5&CCΏB+0&/XC>t=&ňhH@1Vj%7f777iÏ ׺7 i% ^yQ}v>o6OW^UU?azd#cLׯs}Z^^,KċxǏnxBx/9/X/# UxG$>.f3hXj^/mF;\c{<Ҧi ;17Y[;Im;+)ȓ^vR~Ծ!竧I @| Dg#xF4Dyj +h1Wx70 v>y#Ѽ&(!_z4eLy(s2;= Mpd ғGt=8ێ?Bc]E#ـ"@<@eחy>Mӛ<ϛm~X1۳Lqgβj>7}ڬgeYLÇ+Dtuu}yyio 6XY"b!R?|Q)%#ֺio®SY{6M|UJpFNAv->kXLHgsU Mr ȷ Z'ulL¼qm|a(ûXX鲞fX ` ɿp'DGwN3gM9^o|ߌ>z>9)ǟ ONJmzԲ)-h:*jh!C|0Z z xO~TekB;ޓ*$r_&p>h*5m@]7qt-nDe?LQb>r0ײ, L#tF[nյI$,˛Ǐl#)eW7\.q~\^]6mnsqqqyy\.7͟vpCM۶ֻ4GfeX,Y]\\p1"&Jm{ͻ7oV#|nwww pΧOy!( 䑲,3mgݼڶvrIDx bL-˒$.Z Wgۦo{IT% O{R%6bUt g8 +'Ƈ1 9z\&In8YS8 ⎛S1r.z5 ^Ł{ sgT_q{"9L^ t86<\v;ÿ0<7y@`(%=9 %;5O" #iphE @XgFurY2 r`=b9ǻ3РXjp$|TxP~ e!4q+s 7@@< [J ),\U!% !B!51_}"~gDo,M˲d9M|V*AH|8o6ju}}_ɲo%r΁GLW_yO~]oqMeyk|5ժ, "_mR˘$I|#JUݻ_J9|` 4BH%Jӻ׊@9ّp2N9׫<_oY.Ľ(_'ډqc&?/e\rz-tw S@wpH?Bf 䋀{7+wOD=NMW&"w76!z ?iM:4JbG߹y׬S_~4zF|n%Rp{T򫯾ᆱۼ,cO}^aRJJP޿5I#i$YU-EfÈcwd9]5nP x13wKf$+ʜFAħ^s)1[:I%u]"Tƍ)Lcz,kJ 說ͦnmYYm"AWK!nS5fm3id]]3]$b2&_)lw9X/`9| az[EjjPW,9q>~Ç?nY]s̽ Hy>SǚSaMXmmƕD{)Ǖm} o=`mrɔ WC5Ǝ J \\+%3L\i(l41_D6 Ff ҞɁBo 2`0'N, [LSLE'0$@- 'lo}3]փuHD8Աq2aHw5}M%>|8f}D1JJUSo/|߷mOU]"j?VUOO]xu<?w!DyN wxxv{:޼z(M* +AXTX*pVޫESSTZȐ<>j)$nW4)Bq9뢰r:#ꪪtEL%S:BGzHOxlp&"YQ!FvN&4 o!@ʛmcnmT츻S?pSn.*Ij(JJhp>R¶*%9jI )/~BWO@`X00oHL0PCV 0+ayeZyk1b0"(j?!Jm((26/$̋mi甊01L`|MMѭ$uE*)ŴP-U>~("TuL]P޽Spp<y{My?_o[]Ÿ'z>~xwwh9F'uzv=o޼,?~Tt@软 zv΁'_I5  -"ΛifJ-0|j rܽWBl:3u]sr`U]{_׍]J2*Qmhp5=ZeH^ٟ a܇> >w=<<@5:$ D.|۶ *<=>>=7+Em[sm6񨠫,9 Br=H[U 8<+m {0Gu:IS΋5^K_ylB,H?x/緉M!"@`Tp+ %NL[HqKJa|YQ&[_%Ȣ1HK!Tu}m{; _~v۷o۶ 42E???<<_zEDxsTՇp-9uo+MDw}Çwoe4v:T;"ru GtDnmUOn9 iJTwZ5M4=v}fp(޹n@Mx_*WG? VGE3*Fөn }Zٱi"`j2R]כMs8WGejU.QMr`QŲYf50ˠ~sVPӊSob~d6VNO]pOb.x|kPm.*y ÍyE&WAr!}Q) 2%?jyk<V㎃`loHx(#)tԱ^QK2H/ @Mm{k=R~fIB MUOӫW/_x]ջNc@_߾}?O?w?v_~w>$>l۷mOe?ʳ50X|*s舓j'j "ի?ϻogfJzӪ|*|~vi6zQyèlw@aKEKnJpFqgK"EcZŐC/HnT|֚Ж3o^J\ v;Y-Kn,&XxTt2;lSb9E_ K.3/PBLJ)q)直[|{bp$$B%Ӫ#r+#"")R]bL LREs]͚#[#BED3]έk6EYm[um7ۍn|mr%7ÃFFYv0[OÇ~~嗿!Nڪ0uw/A=n6Www=^B"pl6IJznov.Elz4)&FW^Nu۾{nHci6-۷lV<7LS37yFD碴[@/r"<+j+r9BȑwGҕ>F4 7LYhN)Ma:7Ehr1ʮ)ҮK{O^2Wզ؈Yv fRbѫYGmj(:"bVt>B{ZofwSاAnK'AѕhjJ|nU.VJ^hL! E2*(0M4uDpZ!!&dԲTz}2Dz`T. 1, (aC*zBZHK@_uOnU&3lwwvpÛ7oݩV@zA-}8%VfCU c9rIjy8M_d3RQ^"QOUDE2}ߕ!OO}G*/jGװsp?M=C$KRj2VZ-Y˖]~I4F)vEN(`B hji.$Ȉ3ZRzȸp0#Z`xZ3Bj{r2*)==%Ŕy?2""Ի];TUS׵ Cpν~9GM A*;@զ~wOxvŔDmo^vQw]UU_K=e?km=RUU@ p<XѢWz_>-EL4&>l6ּ6)bxl6mG.zBMdei>p"sHXdZJOe0=bkƞ>3Mi[<~] nn0Բ D޷v~J;&@zM.ӑ(YziMӜ$џzR5yOhU_R~Ҷr6UiN9ӯJ ٢g~rS"u+p&=l>I0R=? Wd, il;C.W!#1!yYbaJ[*S*箵tT߾:=}mQp\G~+NfU߫f9߿?gD?fCfV$۷ozru·ou}8uU4 8J\L yj:נ@٦@r75D߫}x4Jtx=Uld\(ۥ6Sr֌i:*ڜkhnU >E+nv~X9,D0Ͼitu!"f<&2b0)Rű 1YD 0Ŏz^H |JV 䶫K:X!x+1^iTt:)s$"Yf7O?BǺ?3:!twwwo߾!?#::w_?>}+\v;\܇po6U啢sZ,|"?&j-XۭVTLm v@uWH>G10ƬQp1& ӭP:v$s0H2bxue24 "*`C' "|UcA;tst|ZҘVeVJ'J 4~Ԋ&)BrvUsl6 Mi6Ε%>lFf] ^W{5, "fw5\i8Jf $ɷP  7$7=-] kp XykYa`+טFgS7”c>;{Gﶻv ]Sun *$חKv8-\lKORUe.>A$xXo8^J%jmR?:ŊWsPC I %Hڭ?BB!;WJURlraJcgakgv", ډHEN>L.ӑjj>dHFbM{-{8wʧ( ;Ї;Ew駟m4w!c{nW^uO{&)>]y$GtmםU~7Mضm׺ׯ_7n%nwux8(ӖTUU׵ιnwU۶}ߓX}_{չ}vD"TN5.(U=~]ۍtVzJUF"}'r#U]2'O+?$4ȒC hW95̇.yCPzW)"3("<<a!~Ҷ$|;/I͝`gv9~PdPMUWdRcQz\pm4u{ aZNfA#ȡ$F2,4υbX8S]D՗paÂTc6е3wۦfɡ뙙^x$B8i~0!i~>M+n?QqhWΫQm!޽=OVùS/ j4A=$,n6?_o6-k6 m6^S;W;W׵N`&cɑ:mŢxrtUi&^뺮Ǔ"ԫxYNGK-v 2}VZDfs0Xki聓&pZ&˲ywtҵrQjd9Χ"AU3 ),m_ݹ`tCCuX3P׃#7vԳ9y8$fBdR/119ًCt5v^/D !i2GbTez(/: sN7pja,`$hk!g5y腤}PA,ZDX Qj׸XOܚx<:_WUfZ&df'j}̾޼yCVF:}whv>JS6{4>|8<<޽{m6?.:ݻw?oߝ}Q=[愮ܵ͛7Ï_2,mjӼ}x<72#\HmfbvkV[zW^{8 a[תH::9y r1*s-Zd;2hPűWؐ)E'钥a9N6;3-ŶE>|p<߼yl4}nB1CEui5 cU6u{V[ȯZXk,cղ%Qi [G.~>< ^Ǘ]iDXu%勷E\6=2hWrJv\[00^i%E[:e a"c1# 3?|wT/"Iks6۷}sU sQ}=P YGDʂիWw_ǶmEvu]Nj^vfs<qcUכ65m[ ]]U @UU;x|x:wHU Bi5+;75kr@@Fo8tHD@і ;DR84!:kK}B$峞6+oS+򦛩jUI#{=e2#[ѓ٫'"HDNsUV2ҕ;JU?~ 'Te8wX5ׯA݌D*7U  FkTy_U8%zC&S3:WA9J-j:tT%qYR gzLhΏb?C!3,>״UշvG榮k"P?JdQm6-*]_0!jw '9>y*`/_2_*/8;(mÒ!#(i֥s _wPN 2AӍpI/T1`< 2CT3<ߘB)ߨELVb -ιp;WB~xAk7oހ;Tu[zM޻n'z !ǎCS~9=g̈W?f%RnWŰٞp;0DD' ԪrT[OjVE%&."iT(qT%oLwx'0ɣ] 框 )RTK`IrAijXۋ s X4`XgB6-,;]>w8LE>x_ZMc4뤪Ϫ,YZ&MW`'N>Y]6sk Y: CSČ3lxB$_zF)F_K0۾u[avfR 7w 1Rz`)nͲYQHkҐWD8Q_өUod_WpT,Dl~?yAA?x ~;өׯ_{r?~$@$w<z:>|?mwyRpTwv?~ܧ:q#Su]}A "DDB`*3B*eJ!R&9pU@DTyhMA9pBOD7b\r=Ֆ&2TdK !x&.wJ=֬7T͆  Nԅ 8fy.UWQ5=X|LM*奟_.pw7mI0SV]QIYik+p!k9`.2DV$nb qY,Bm=p<7G>V,$uXw)A5QfSiϭbGP\f}|뺪9BBc~l,wݛ7oN.0?>>HUUrb/G6hv')0V*CAB ! uvtU[ARY.R"rRz%Ƙ7S(*@GqD$ hZaEɌh;}Օ/'!AupA! KH3-\RL˝#[ލV0'b6`V,Qy~1b~v=_}ano/ol=Od͞ޏ}=HyEUjyPfh"Jy^[&[ @heNr/^@G2HzuR @@P'oN9Zե:-*B|n{|||xxQUU՟'-0kMڬۙ'"/],}{>Q㫾Oh|yЧNt i[}C|*b~ ?xG`꒧ϚMY?zsi6t'"HcN!Cġ]"9KƙyK|=& ©=2FCtfZMtxq&X`nϜL!.{0Nj406k"kfuk>OмڟqrKR*ǘ@fmzj7͔n0u6} Cqv%$@D-ZHFkt y @l΢.@\ЃpOYiU<4I9dkDD`9G!$owwsέ׆}u]{K++! ܿ~g"Ћ!r!@ҵo߼{Ç>S#pwx=1oA_Wx<ĕ;ljFғo߾{1 ~[U|Jnm ܉H@M<"Hz-Ac$ [VB"G-#r3UZJP<ɠ$`]vyʈ]w".9MN%lTPG: ! bDƴYT02p.+/$Ri1 %6+꺮CUUmwC`-ED$Bk0ёLۆr ^Dڞx ~PyQxV6C[, B ,/T~I@|~JaqW7܂Rwu0419ŇLuW^H`1,"O$;TUZؔBndEp"H4 \tm'"N) 4ޅrf|EݩN|>K &pL=h=wJN }/Ӈ TzՖ#Y2-q2:ΘR/!XY0%K5oL&oaPP1o4oӫOL2ӫceADp1gE:)veXE+cd<, [>V W;])N>;ej=w]U9I] /Ձ ћ@8{JOdྙfXȊ7?Osnm$8qtZ_6SIx$3 `D0,T50Ж~8yBrG s2W \| ^Rt;900Iu YGDTq~G z3'kXʅد>S19띶[ ~'xᢳc `.?A67 N1oaAb*,i  t!I@pވkψȚZDsD1ß'k ]Z)vumۦi_Ǯ뽫{"j#DλʹPU="A uC9Ii~6"rcՋCD-ň.%2B`L'V'm+L[0]I6℥] bM@F!rF1ӵCɎF D]-mj17y=7[ɣŃGӏ0m[m+=Ÿ] ;FoqL;,fd +R;6I-ķ:`|ɍ zo;}wQlh S!fYGbn6 vQݰB] #]WWD008MmuLDv?~4ElUө57p<RY|5!=jf 缯*vtb/Z)VGoܽjjvhaRj5NZ;*8ŇdZR\<&R(E(YX҂)̬X<]"32 \x.ra"2^0sP-&W{*y]]{6X(cv` iQRJMS K g.09&"I̹q5%< JL̠淩$kndܻU B8B)虃snux'f>vnkMmLa;Pu҈<yv_5!x"Qt@MU؇uŢj5[aia\8sxOCW~|+ 6ϫIf,J02sJDC W\\2/` n_0o0Nɚ.D7:~G*#zb Wx, aҟ]W"!%ӓ"_OЃnDl n 9i80;٭)S <36{ [\wVdG aFrRݪ<-Oza"fB<FS?>>n߾Ô3("̧%v[oGfhwn{:N1!D佈t]G3ٓwDtj["_5z&.1ZLKsiste(!RT}ktEXC7&:mCMW !7Kȶ$kNpژTmZ/DC졓f\iS\荞 3pʓ j^y﫪N-&yXo!jS/}Kf:pMiiip z3ޮٟ3rכ]0:{5سF_ _qnGs e?]U%%76iCAu]sגwVHi}':8H T@ C"DtTR7U9>`L~;Ρ0J #Dz}^]DB4J*8"g)# ùw5TW)#<Y-j@+&,֥L_ oٖWSbsjpERaxw_ؖZIıD m1׎2ʧmlK?N˾0\\|| ᲍13wdgN:%+ix ȄlnǃnZjFuEnFDЫ#t4Hz<DTm]MP/aը" \98R;%@D@ # ="zi/ƅHasZSP\3YjeEy|V8316k, +]ϥmgDD8PFN$ b}1˂p n^9M8NԳiPTڋ&O$<nK3ZEiզk"cn*L/=3r,(RXnLVAoFʛv\ $*G^Dz\m<ЄT9Ք6u8v݂lIMapihI.({$U>R= uTTj3۔^O֣ĺZzfr̅%M-v-+DWdºLMM 2 l?aU+|k\Q7'fv>3 QkTL⎮ƒ(NP\0>EDY4n: lN3!* K`1#,}6x Ԟ#zCZ{GQ?}.}w'!L_LiY2+ڧgR>i1$]+UɉimzDLa)קA,']=_(CɨO&$J_F,|}%gnPm$ Dg!ԉR(߯3dX|If^6K|ݪ[Rl}8%۟1"RaFkeVa*2" o@}C0Օh!6Z&MP]-( t.J" fm"(}A8V#ЕL{Бmض_&D=Ufw85Lp @\] 'DGN43'Lw.Rd"\sY"Wz3PgaW>:<ԥ'Mj"PkzڢY'+?om^i3[8^OSJO? 7 GD Ciq8Bh>MF.CR@0)c !.^j3ḰUpNpx c@8pMꄧ 1|VKQ#A8[fTyF 6 E4,R[p>)O-ysKs>Z.~Qxqk|W FOܞK=HubAgI10<-Iv! In4 ?_'}vqs^3\!KHm5"mdɆ'^Hw:a0@RҀ$7UrT9[Zi08b- LФ!ڶ_6@K3Zvhz@t$8Qf>鋊R#JD)e̐8b ,=9Qq 03 W5H\ju0b"a|Z&l[)_LM=ӕRa+;_Yfrtkz~_d>jHo B?,1mS.0UO\k)OJ.3K0\*mtƤjfEʬȭ@RfQ s}u] ;m"P$y5Хe}>KBBz?ݑ-;?f^WDYR^0bѸ=ULtJ6\5?Q^K]M/O^h8D2N8%8IK1d&v4T<ջz?yFkiǯj7 ؖ@7?8= @c(}mFn+=Cqvs-n-VU+cJt)G.9>ub)dO;3zznF|$)ԙ;¤4b*x:۶;$ ̈)ؼp:!q"QU?OQzK !wIϳMtJ.|֗ٯ:_Q+#{jʝUoޗ9/۞ qs!}SD6ڒzicjTKlS{V2= 7$ 㜤$Im>>W:}4H^I/D\=WBꗙ>*OzӴbr"6,UVzWc"G!C98G>ӝ۶m39@L¨C.ĤFYˉS4&pX0`e皉jˀ9?>]:P@FTC@lW4.ޣ#]P]`go7"2U43{v@s p \7:6+N]<p+t7e4"ɘ}@49=}bL5d̸WkYgj= b5JQ]jB`qAK7c1 :q" D$ AZ(ΡUMZ/bŌMn1Cvv^ʙ(B2ˁSMBT09|Vd6D3'UOEsu=W%}VK~96WoSV2ZhDBCXoUU - GlfFg<B^|-cXBxK7tޮKJ'Z?g2 xmN[eTaF #6]H`;\P5/.d蒧xL`T ?ɱ0 8! Ez6Qu]5hh>0k|TUUk,=83fgDTC.x-!؍l2nS,%֛Lio gjaZ z[8˭ 9U#nc 3J-B.ޯQ9n/N&<Lp(\6q ??oE֋;V>ŭ_soo|GKxKB?+󧏥hɠmo0{W@VE⮠#rzи,Qbusn;B1}u;Wy$ nضZpۮz۶}}PPP3^US,8UtB>;:ڪR3\sWQtx h~  hɱ9|SEGW9 # 4@M]oh[oda4j@9ѡ]u]www׶B8̘9mg}V㤊'OEnX<^SM)fjxz[f(cj8g $^ڋъbRBN !p\KIWUUiҏ"u1jBw䜺,@䘤6WJO8K#v^YWq¤8]A-gkq4>r4-50t= Q [b3e!@(}px~yIam}UZn j$' ^+qpY@zIs5SJ`ʎ (fJ%1D)*r-ɟUU !8.)R$eirAO@)X`@!Ņ*,)yVKp"RdaW9FQS"U B. ;ױo>6ecmzR8wZ1x"Yp 1<=99~8wDv)t!sa-G 5ďN?D)jUGu+DQA^`0 +Z`H帏>V@4gf󈳆yܰ{I5 |SXSQ5x'A9<!5 pAR[|f7oc̋;>srB7J3Dr*:?a4ug`Ȓ! WjթR@-kB= BCua&rrA& FfA.8Md)ΒshX:|;sJA}Qf4#\gA)6'~rʤ,* ,Ef̄hT^fӫ([h͙d$=~e5~sRjZ[MGyA19R:VŴx:>WY\&ԇ8>nȞaj@wR-KpB҈ *R?|L+M8(Tq 13`6w>4vr.4Ce $Y$&Xt#3mԐ*m0 Fq5Fi]Ӗ5 % &-1Kd@3l+a"ˣs"(*KޟKWKWOװ@iu=` ɼ]>,q@pgQE W&˔)0ICZqC5%+;'tu&="$F.( WD6r fz7jt," C; , DG8y(g4)41۩ՕM!&3II+]Lʻ7X; 67AnyW_V\a/oytugae6oSn }1\X@e9k\Kb[D `m:FgvDDo\GRB_:z?g3jG]pAzTR'V۶UYŀ® TR<"UuUW d~qrz۶#ـwKZh+|( v#quztRlQC]PBb >Me@=KvMU"xIyU]1*)l֒0sޛXk2RLG/Z$#NI.|gF{TXf_q+6/1AW>!"86q"O.;vE&y S(@ߦjr~U:VKk=#"sPնUm5rn{DY ]4g/.q.kom+% Y * Zi~ \!22-{ζ5[ ^tqXg*Jy%qGR|t+V62) ">bIDAT᠀ 0pPurh{kUWB )0a4=AP\asvR"g/+Vyv| |*Q&Q`yH$R7v%CHf PuWUw~陼J'NYzCҦƑǕ0DD^?+&o>F`DqG#" .E)Ԓ4:NFm[=AÙlS8.0}ĕSI3rk?y8T꿹MΕ'YuJKiZr[`jq:AС  9z-ڒsW y{㦠*>ݽ<+8?~ W E lUHaXMmsv0@r$0''iwdANlobPf枃K+8geݪ1TqAY& /O3b\(o*;;:`1sS""̬iP;QD&qFBGu3$yMK;SYRN?}4z0R9K$$"`@I-nW_p>-2O֋72tV~%1!8K_=Poķ[\VL[cِM[:z}dEi"a$,ms: !ēp@D L6fse-O۶Ue2d-G 7daMԍey۶ec-K*kZ0Yr˖tӛ"w٢ sH1<INRH"fLǃZR ML𵐰Ǵ'?+㙿ϧxO^?0"n")FMTOS[=>;)" * WΛmӗYtS<(ØW埝s9VtUއRUU Z+{D> }b6^ގUVёyWU.lj`fg}L0+Kq \,0 dQg1`j%6]MjBpU|}-4|/[U(qVX7_A=J% <ťI 61Vas< df+)F>x~}ƀs9?jŔo9xp ߿Y:FF=VA@|{D{@߳_C<җ7eWd3 MN얧ؖM ϋ\KvU⮌Jj{9kL>T!  8l/Үh!^?iϼB{y ^Ü"Ӑ{]]~t`Z~+v~^`nyiO5)#MwϯB)%pHvEFNCvEG~GDrp:!m\z"͈fCs44F7:OqRtk\~XT su"ˌ,bZ̕k"x<gќ!+6Ƿ >C@LA@UfU9jc6\lS,Tť hI/=Gsl$2H- {\ "(j3۔C ou7+ʬ&BCӞW7XnܷURJ#_2Ғ%fvX49kK- Z5s󥚗A"c[)Ԇ@%jDFyD|yƛEDxXfgB|"bC3SGa۶1c뺮kL\ybMNH RiQDDK#*VV(WE,->dzρ /p^s*zZ0e[E4$S ƥ TFpqfNo^y5 ݐ|kOh2!@KBdSfMnvA\t@+33!L62Q;W]DfDT"\)קTA:DBЋ!@l{u(#eu CE t,{"jkt{̬%@\(CF mzNIQLaQ!6\O[:C5>Zgf 3U3POg*sO2GY~E8_ hka_gִ*:1UTc&+Ks#VV.!`*OrI0>Ě9ۿ.)z`mɝ_T08B}E?%XnFs0M/3C_Uu]WUmׁ#䇒і;mR:_ŇtO1BQwAab' d[ 4kp]}N{-Dždg`0 Vfx|C/4y6T , S74յ1:P f&`ѡr0N]/Ck2ev)3"" άOGYoN֗v]׶m]Fs=i#V'XV"¡g֚J/Ă0Bs89):W qsbv騗82J^fc%acD#?;Q+$xt!L|E r, \ɍL\в% 3bH^ Wz|Wa_<l{A_U]mOV6փ#p9,149 $ 嶷+"bu9 !xQ=:0WUն-MJBWFm۪iN[y昌rUk_oT됈62ZV% uA#RЧB{? $['@NK/Wͼdm^}& c5# `JB)n]ZYA/>ί88)"iڰJ/h)0>hr}.}H)хN6U8kݼY3rtFre*{ILLD>|T2'gxV4D"mA.VfP,w)c}s7MSUEʌ 3,\DVð@`몘g +-rh2\mm5$mJf"$ z@gt,,URQfB k!OA!Ta Nc R|(;  # pB ҒP;;Jʗ N p-5aR<°a^Lq[Wakz!Z ۄ_| _,-ȿȞńe5)]*Һ/3$9co!Pt!qA$Χk%]tCƞ">]PUs;/q! "PoC(R(c)wY#ٕu2vUXQ23S 78]} ~_S58KoBxo>}BWZf_X}QrU.52w[HOٹjZp07ٚNExn.8j5POx@S0wO]u2m[$"5@G28Iu з* xEqD}0J07e<:B)@1C*}=&Msa!Kqbݚ0gsy`cDp-W~*#_>ʀ?/3˫ǿjf_CA(?8Όfh%nxm6L߃j NoDdK|:lKU2OլU H")DHhF`)8BQs)%J DCB]H}y"M -OZebڈ]EK Gnpθz-Sd#S%JqZ[4L`$=6dY/k KVAq<]ߜo81-sڍ 'Wˑ9<\r-Ȣ{Mw%+D$p,#"AL*)"9CrŤ)\؛n*zz RaoXI~U9B »3d) 5YF+298  ~dSh\ !fu19<21dmm%6u1EbDeH|+k^mf:_%]Hg!@%218{̌,"4 |( ּ nNj~/\~H#n&`^©*vs0eY>|%y6}Z*|y}4c풬 ϖd;8>^h900zhmbm'@FQ>ۧQbB+l*7jU2>p/1},G"Ԓz8m@\Io4 @ yeBzq(A0b,oIq5Z-qP'1lŀu(л$jV(䇃T yyxQ_%B27_}y}]/65qGq@pr{CD4|히(NKdBm#mB("~! |Qpyn-c4͖:YB=Űit:)UٍoauF+Jl+5%HBE Y/Gq萀n?f/Mz]3о<kd[/9$ǫP a $G9 m{vEӽ0 YMsE. $oV{8(WDNC{:u]n D@Duv^ꇕ ;j$@DBD@#J6ˆNIvoƓƐV؃kb:@},IY8 + 1p\EJ7f_ gɳ{tѾ;as. No'G])DO ä4[d3ZvY@4QF۳~k WD}]5A3Gv]ib*|Mל9pUV6 B4mUU,="VS|l,x_Kxso{}G9 |BDk@ 9-\}UCo42E iыbǗ G;˴5c/(bチ8|Cg߯f/6+Md@b)e%ap""ZvY@t ^ 6?WC#I7Wpz~n<7]z_ˣY7U5.ϯXzY^kJj έB:=\NiMu.Μ>YZ~0⑋\ h L&ъ:8֧?%־0L?t_`j!kxrS5W*!+J]⟽109Fi\#u .cCɯ8XDIٞh b]כƹʓF!{1sz\^v%*T숨y:rV\ ek8m͞>^,^YoJqX*fD,iy!( qyY.s R3d/l_3T{4a4?/cɮfp[dŚƃ R&dKma(#E[z,Ĩ{,.{:>jH$e\U5 j@@eD" rLLM_1'q4GHCJOZ.o>\ޭ?qK ׵uSBHtfN&0T2~}b㿖׾?uřgq픷Z.&/^E,N7S#%& NiY|Wɫ TWSd>t]Bm@Ԅ)&-HBDͥy)l%j!&Ƅ塽O6c=8?H:=\"#^m2[i|畀z)w,ȷ${- 51IPeW$"A$LvmW_X<KteIsK"z]v1ߒbv2>m==v^c̬%"¹Y*靫z"=!"jQ%, !:GԦz u]s)hؚcq }Z- t,=0E:z>VV,\ )9yp= hM(B"0zRb慞\a ZƕƶsuUUih~T:zmmnX/.ZU4Z8\ar'_\ qJtf,qߥg}%4dvmOVL()&oȷdbSkShc!)%$ ߠer%W y[bp~V$υ;"Kh.ݦZ=I.If/i?£X&%""o0\>8.!"QE9%x|* Dɱsu]ov[D_UU5V?UU("|rf@ [Bu`̉h$Mǰ+yr]Q~lW" 0+EbhBz"|GC pUQ5y}_[gnKhsBS|ukBxc>OŁ5NU8sL6,H̠y+NMͅݮuŋ 1dg9̠[`"jO=YQ!Mxu] :aQ{a7Ms8t ]!n9N.G¡RKI![h M=2Ag͸PeOYke/wCdd 0!IC o.>e/ C3JY0ѣ҄\K5OGWG .t|Nr>0,CEM ,qG \5ku(+ty;%j%jSy}U)Kf?1pr:F !]?m[c0Q\uԊ9 omfn۶;x>w*dO@CB=P! KbV8r+ci4,5/X'kzFaV4F%b"rB֔ +NB>#*Ff̥{X5˸7MWMگݺDzWg X~2 Iw+e/"/ty'y0\UU٨7}, HDNá;O\KvW5=;E.~նp4}?><@3YVU4j`fJ(KHݒ1|6'K|~a0O.HNtͳئJ) -JW"qy X]RNLqZ3lb~Mdj$2ƃ 1u[ѯ03p򭭷_gu}IeK\@ɑQFӝԃ\1uƊR؎WLʼnsЋC]& F]=N9t纮CBߓ!Z:@*Vkv[pJE911`TAkŤ8K†:'sIc[{)o_%*Yu_ 3 H9SO{@Lߋj/f Jr>Z< |׏A%Q8 R:fqJK+YەsQ:N+vsf߫~۠4` l( 7l|mOKzl;fC]5yMґ2ĚbΔd 3ON!n$SG8{iNdLWl9lW>/^PvSU0\[{~iSle1 ȨYbn (dWeoYpRzo[%>0F XBm۪9 ڶ }˵7f҃ hkkcq "LϚ%=ݾ yхAP;7ӕۙ^t^iǬTNIv}P:㸲x O ߧ{jߚ_ /1k۷uS[iÃeLqmV]<b>d^b2XDŽPJs J%31TCs'3jkzo6"H43)G%⒊Yh=%4VmLزO\d=_eV]INuϑ-f:,d( Y2'í6Zk.BX۹nIH`xi]}>m A4 u!qkǚ$Y!r\׵hϝĵDT~#G- ",1inMi "B}㈈HǏ}1c0JC&F;ſB"D$3]g|h7M5s~3z L% u8hmYk%IpdOmWGĺFlG,]Uuu="nfXB5ó۶}xxx||DqэRipnӐfPrKs]Z'Mh+kD*eUޓl6>ө:EL>TB$D7 X/BZ( c4-\HC~Lӟ|cʔʂFzJsQܗ>Kl't=#TĔSCa;PZj.0zf3_Kն^7Quus'e1mۨxb+U`q[ijɮ8MC6fSZ&!dNtj7{8 j V1q2UђbD$*SbNr AOxXy>?׮`C>6 KG`,1D8NayU=X0.f!DY{8+g\_gu5b F50שs$')<_@;ct^QvaN,Oz L8 zܺ ֫QѴTU&"ꁕz`\]u}C+{ w18aDbY0 3z)i:>-LV(D²m%Ӈ^l,x3)6\ȕ`$AG({# f>Z\es'yx]>7 MV%[웬d| meUeiPŨtL ]d[N#Y"}tg$r*w #Y>aWVVO1Mm$ADJ麌 E "ZJmR9ڔ˺M$?f[kSҲf-Ma ĀEZ<]*6 bxN՗W;~yk fPmJ.Z~eLl gd5cM}g!~'it]}׏V3frǵ,B9?oq,OM__kΙYUnpifOY*iit]v'q%{rCA;ix(*ș[D$ OTxqٳ J56K=F "\gI6'N^~vvjh $Vltar礬^S1l&WwЩL=cՕVο%궸Q\aȿ;f`0\~,s `.1ؕGGr4[VmH򭇙3eTQ~Uo6 b$sL}}{8e֟WR)ի'CPHn Dr'(}@ѣ yh2b1o$Ww%%B:#\Qq*^3Zʭ $|g0"R,\EwT|>g^ZdI2íAkm{p8.f_"}wދȑ/&whHg'o9jPnZ#*/霮_%tf%+d&K u=8y\Rd%ku4ds9^ +sA c㆗6Cb 3[/NQV7,I[Z;;[ys_G[0 7,oV:,^W=%[/ѠNŽ۶JZP;moƞG 2kT9F to6@,7P>Wr?| 1-,ns@&O yס+:-^jY%&'a)0XMo1%h!̾#Kp^ X=6g:tU?ݸhSz8 OZ\Vٯܮy~.Z[W io5?+ߵ=З͕brP-,i1$Pu;Wl@nx!+d erN5i#Ҫ Im[ 瓠ir-\iU p8}&mWk&[ƕy [!PSb9^x7\YD$+`+*!vlmUEw_!X`U2X6er*Dy#2Y&" QPD6sFĺ _MWn]Pt.a>}VÔ]kzZӃ8vBđ2jU;2A \\U \+^YH B[ƍ~з0g]36>V^j}^ч2N/-%vr6hADu{|YD2i7B ĉtVⲹNǿ1Oۮǿ&2S`5 "YJ9 \OC(A#wJ>ЪD~9WWUu /EdeFnaX{*>sDqF_N}߶-&Hm*AFЋ~rKpAKR5|k_?wg<2bnNv&k78Œ|uĬp,T0͎pIUS͂n^<:[) 뺮ieRD]YZ aaA}oCJUU9 *FDGゴ"K,)9)H#8CسoVi\GLFb-E(+ߩ+ϼYSVc PJDkIreH;O5C/QHN[XGuY&YR;U*,Yk Kk>][ey1ob#&1~%p$r p5:ߚUa($OS8_U2T2\qvP+߾ui*YJd @aLdU68-ʄ"ds[&,eO.HEfCTv\*?]g^Je>Uғ1ۢ#}~>J~6.<'j֍BRL%"DWιy1`}~QQg0khj-Ыu6p1/0HAlɒ%9P@ a.ݪ?#H2.qhgOS&]A,z,K3?sE r3_)֥BN3[DGlOKg!7YtD(e/N&@7O=`AJ#~Yg>*u]̥ #/l O~""< 6Sls=F\s'+3/l¸>5rwu=NA4!K 9$"@Ρ#A Br_NGUqrw`?1*i.:P9ɧu F͢ Yx1 s}9ZNj#7.%l.*#5 y댤>D<<4~Y0㠎?)Ɯk1l7X(H\N,jIϱ--B?׀O;]?ad<+ ªTmj`!#$=EclQmu]׾?1oA)#h=AP=V6$D>S}:sI|>+%S؞guuV'j ʼaL$zg7#{jv|IaXkiRBA%Cmb#˾;Wu]Xҍʐ)e`Mj QZ0&|H]@I4 &=Ld{4c h6HvSX:EkA;a!|C1[,9[VDDMΧө!*W! z0'&:S)Ҥ] a㏜ %ųϹ|ٔ鑼PD>gK$=rM GF"f4 'Wzx0 /\o` 8Vڍ@ώg}槣ZB/ à R-t×qF8AW~~oLKVv6 Oo˺N@0UUP,HA!Ab=!aN$՘ZXG`Mt7c"f^Lbv,g au&{5;'Q4V)3"@q佯kt:X/ HM7.̽w?}]""'$${MAOSι9NmZi4  C 6*8u-KT9IDFْՕ(ra GVg[Z9`1^"Lc5Nb)bO}ZKJsF֪=! 0K nKHq=H9s-BDn^6@DD=Ȫr5*aroy.h9ЬN1S_ x|sO*=[WfW _<9K]‚A eJ&VuS7UZ%B1L3ֶz9Ãi=G %}"Ǐq9a|>S]nO>|A6 Yf~vj5/fK9ɐȄHAgۑ'*yX|'m6}(/j3Ns 2/*g;OmÉǪvz2s̜^d4a!pʊ Xr"륑/ ;$a-̌;]>gurd>&׏P_Лz^0`cm'؜-PiUUiBܵDshA%Q9'$D }/?~l!u]TmXf^4=5eՓQ}NىWU!T>A "z>@Ir*[QYW\2g!| Uj H$G 0,4_eBXL3A@ h@CT \- h dPtKR5cK"gHW) gRVu>{],*0 `Dv+/=EVȴ'\BR9͠|_Zk9}`^b{l6 8]]׏u }?>>*_Nsnfs8N50F#eP%pvg-꺪9Dv4D@C-&1I  f$ur c ;_oS.'0)Z>¨{H,2 `> =d&PV}fɱ1O$D"a脢3\ F8f E@ !35:dئcRrMvLo)ڕL:0^PK<`yE?Xn bj)c~2VƜYBU3!0!(T;'uRG!)nt:}vJUoѾ= (ɨ\|)a_SLsED>Y^14\{^ss|_WҺVm/^% [6q ΡzQ(1-"""o==I8;_CTMMlP 15Օw2 [Pz~5-=&)r1+=aڭ Jȼ^}8Qa@,bcy0CA4rGAr@896+G.ō9p]׻FDu=P]U^E3rgS9^WPʂ"=1HҞΪnEoj]}FゅN6V n:8r*!(L`1@˕5ӁHaXLĈ5% !Gbn!LK%D LkdLG_|//خy{r ^3qRb.q\Gj5}1P1 ,@iA$@ 쐊vV! ?v]+:pJ-e&Y&e:Ϝ`wkWޫ9?sC R@2H`9Lo fUwY*lMGU,>_XS fOK?JQBBW!)Fy$H諕2KQ]A "DB3es[ \Q J1ƀ=Zx2? !s=ggxv9?֕o1L lf%&>){΀4w$#] ")ͮˁﴪJ:_!+H&$ %B5kz1cɣYsx囈^KVf{0l:yX)3N-\Uzc*xn lqΖ3 `d~+d&}}˯Jp#D@"x9P I3 "&/qr{͍ܼb/NN^zlx45KyAÜ8P^vxy-nJuQwvg;6Fi~\r)X staդ5r БFj'ML{与 ~HEkzUw @P=e T>0B:y[A5LB{^[JuTU˹9UDY u=ܙqqX~?}s៤%:R.I < @IvB5>L^FD\)MDfbd8ʩhD݀Ns{K_Uܧ qP/@fx! rnRVB@e PƟFY`(PjY?;Xq ,F-g3CutW^32WP0O)"@!`JI5È֗I Vs_n`S@"F$"IToGa8b}*q=G{x]\^FًwP?ǩ^K&j&ЌP2ΦDfVݖլ6Xab &QF/B@dDFAPXdH܃v [ld[Sm-S>i(`^pp7Icr-O\6Ac^xAbٌEttnVc[?& Tars홙QN|ݬVT"ɺDWbB*fjfqXLbҪsU0S 9` Uq~Z Ё U/:D?ՇzY90@gڟ2+kSu-CByeG\SfL@ʂhdtAUco%С/G)-QZLDQ* !’z#\dwwzrr"^)pc;#nXqFsqFs2|Kt㤧Læ'Ϣj/;$59J0<<JW0$V{W@:g3)rdEX\xSCC]%,WLi5Ov_@@`](B(iD\B-iʀ8H޾\ a"_޾L *!4/SSB[䔒dA523B`"͋SY4/@[ "z=d(wQMm -*_oWPv>jc.l.eHJĢ,E EE4^K ]uȍKSWzY /:^^+gۋ'݋}s{+,EĹ'|!mP" 7nw׈`P=Rgf+n=mM:Lq_vUwCڟp(#fa hƀctx ԵbTj56R0}G mնFUr.f@x+y1*BN!`BL]m?Aܤ`FeYs\' "2!U/ ]퇦^gB5rF;YNasg 0cg\-R^PUSePD,XǦvc˦)_s$lYfDHD@FF"JDJ ,L*"LD3+D=EM2RD16a`ےwvYA>nk9NڞxAJv!7.΂ι?Iu}" ٰ˄HO%Ctfþ֧JTÿ.ݖM+ \˲4ἄbZ!>֐vzjRսZ֣DZyI BD#QT: x6vHOiz~9O `H5I+%@izZ@U6_0cI$H Il/`bQEdW *P#lLdѼp5߿d^txLJx/߶+MTMv{ ?qW{:Gze]}==#^~x+7j{Uu׊_A]P8``xЇ3o,u+@-fR.qUJ˲xvs:nz팈-% 󫟥n!d:#?_c'}ڑ{x)<97Gt9 ܾg@BHuE[FIU<)hfٴUiz)AD!Z[IՄHAJ "DDS`Ad"RgL}U#)wSh 3Lu*jI)TЬϊk>>h.1\˟=S;+Ix2k-xc Ǐz,b3MLPmq"VdrNۂYyonUޤ\1&El]udJ6"wC#xLaqqP$=.Ŧ=>=!^Q *+i"QRߺ:H~x~kbHDJDb"%l+=U.0$0"rt ffR5]H:223FA3 '`#'mc^S6fl?wHM^}]?Tr]Yk?)?tme٪{^dAD8ɽ rz[ض0Ek.^s#dÓxwR ٽw0x'hB| 5Q'wcӸatzabf`y=֞ib֞)ZVܷ{b#њk*!TRʪ(Jz%R}oTUȌI%)3K&"Qb"U 2YFDfFrS3"jJq56|+ nfR@Ui4TcsdZ{q>me^w;lgG9YF~}Z ٳS_WԊAPaLOrwj]m 4VqJU%473-;8M4Mc ͑ j5Þop IB4q*bfrsvduiC.FHq3 잨CːQO+L [f\^ 3;t8G=N$>/i|L2V'[Az/L{JÐ>MPC3l0"fVoX(TQU !"CuѠi_;/$m^+29EnD5[Ao>Ʉ-if(to7vj+ϽOdk4\_cŝ]9jcx7Є`:ֳfO䏖=9!{@Vf؜LSp%\] 4MP O/_BB8dR%'h: j/k.z3rp{mĞUY;]tg@>k3{oU%(j7*Y"64V#q ԤY2r4$\ʲwXge͌^Ǎ ZWϕX5q ".۰|h,aS Tz/Kdj 3SYpQێ6ZG%Z~[͒-@M5Hsr΢ɷK1q.zpǎ1\lT5ZF&" : 1ȎfEnѾ"H!T[%,*)8dh^]_3kDP˚d[oE#;\:CSveٺgD49Vq? P7doǭ@v&siqvY fS萠(RQ*-L 3vP6ug1CW/ Jb =O9X a.ϟLN7 {riDdPh\ ڰE{0)7&~_I|ކ_wԶapeFj{ٴD?>@&؟nnΐsv+`1y)T8r?/:[n&ly?>xT!"*fZjm\V$sFiKc@h[2lx +66!xG~4gɣK%Hsnvĝ޳x:q!eZ!2ȺS֋b)MH f(*ލ$y7u<ՇfflATT" /B ;͎Äԙ-w #bь`gnWpvv}2< szp 6:XgqYm;gE3k8SUU˽|`D5 : eGP{$Us =g4D=U@U%ӐTCu{ޭ8H yȵ,bIi֤aMRЄ q) LTupWnaܡigϪ^j)YsƂ@HIH<rqS"VELuQ؋ Yؘ)33sND$Ϯe. TM^U@p?G忼4?+֢PH *Yr?bExY8s[ѧw{-萩{/g"WO[q\Wg` {-J<*GsU55v}p/B*^ƁIpsKW9~908NJ&۞ݏڻ*@qD h}WdhA 6,)۴@Z!H^^ /SV{ulZaˍB6.x ̌iMjAE!Jff$ d:;  . [w Xs"" )2;32sZ "f S2DP4A^Z%u>/R(h]2zi,̞vS]Hgl鿐;D_{+?հVRClz08bs:nP##IˉJfQP@Pj@=@TIDAT)"hT(7> EJ$b03S㡪<0Ky ΀j%~\-ӧ%XI8#=Uk)pxMrBՅWZmq\j3@QC3ӒcKƪ*(@*Dn֮=NB~L puX3#23dUF&2vSӥ6 "ua׋}AK='D) B1n`SGז&kfoWDP:?P=u~w&WZ)ʶlpe Ddf`HHZ]j~gIDĸVQ\G?xS,.]ݣW7RͦJAb_٣ؔ~ ՍO9!_^9?}F2p_md^j׋Af=[C=⃇STK]cu1f5\';"lbf7ժ!T `rqIi!9B[ߦI$$)@HB"뭹9w^\sV`?.'<|roݝt_{ޢf5liC1~pfW_hnɇU+Q 9l&aSȫiNGzgۮh_6xrfbA8X]TѲkyYW%뉆-1c1i)8?hHW֟׳NW ] )H0<ׁu0lШ:1lrS00MY[J}dž 1L5TuYNɰ\ t[,l%"jMEJ0UvgDvm~O{aj~Cm硫p;|ŞD].[QxUUSV)V(jnWT7ơ&2d fȪB(Hf<4"U FT@LI1`&!;0)s .$̬DHdv],.z3V$#}P1Pƅ<}/H=mv٦5$q7\`.w!}X"i4tN;v룛+6]BJN0 :VU&n߶$Ƚwi63DDo0!#-%ůX֔ntRU9շE|`>-,jcd$3jSJivysD]Rp)ЙVLjqZBsS])2Vi_mǻ;~!a^7H䯈_nD6ղvF|78dԯچ6EDUT!"?2bfj&I몚j*+*`jVG<@TMH1gDH,(l@Fd8!J}G5Hz;~I^,QH~h"0;/58h2 A΍B鍊q;w} nmő,ԏhQaun=J7YyڹGRN8J ,S`32y~'@9%-VsU/Ȟ^Bh bz=%Tcm4ۜWɰ;mC|H`{]m/a"͋S^* UQ-,ϿU`\] ^*;VB5l&\E4lAPGLxf(YKsV$<@VCS/"Y50p * =H V55iqݪT 0wl}9&iY ԫWmKZP<`uQCZߖzYK?9PUD18oT=6tAqW9"r"yRD&H966& 5zn`OWہ*x9B!pDZ;q8thnESY[~fPݴVTͭja$ªR,~"|4yvI٨H5w$&D,RBvVacȈHf0}V{^Ogw`8u3'бP`gP6F=O`׆ã_og3PRWOdPVeW03CD6B"aNSqi{T!bFmɳ:rk56LP*+j)ٌʠfZn+ %UpP3ʙ]#F1B`FDJZ\,ItHkէ))%ˀpxu[96k`r Ofe]|rZ>[m}=P(% 0g,]%T9mjCakpSaDUR T2ےf?B@k29PSzr΋d "K<3̭cwU"{!5۱!ٸW~FDTU`fb&* #!~ȡUEkS,;E2O띶\#Ca3ZM):dbL" ;4Ve]_ȫeb&fvyCr(0\ %s2{z{*|C dCϽ|4_v O')HN=|zlVȫMѭDHtRP] qy<17T ݑsVafjxeԊf& *)F` Y S?DRVaf^P} Wd!0}@ඝ5Fglg}]y?_ԭju1+P CyXLj0o]fDdY$Rk=J-AbX"h0qR*$D$Kڭܽh9ަTL Uxc aj/ 5:a.HK$"˺P5 ^]NeH5j|&I``tY;VLp{ o&JDp1"bΏ,dR U !*R Rճ#q4FWP=`i߶ QMuz5"UJJ3 +*jaF"¨YIx—/ј,QȘHB̬"*KxWpJHEO q_6~i} TxލK׽ o5b͞QI.&6EJڒtc((Mg6+#zojSQСojHLXb +zȈ¸|,-`y"bb>TU`]r$yH>{ɞTOC:s/f>卪b^qۚ73gfd'1;ef`DZH"U [*5ŝċ{\ԟ%@j:MBVN2E`tc&Ds$vJmⲠ͏]VHFh@<2k!q!1 HFLj̊L atru;޳pmpr%~™~>*>$_]&r+[گnD0!1>V`@Ee5i{c{8B"؉$Owz:\] "dU۲,fc aC}U,/uEjYlfqyF?l?13?QBn?eqi;CTYb13S9Pc=)s!q k5AqNP7栯4\R!w-PFƘkkP#x?d@̖ **#1s YrI, " VcI3s03[QwhVSQ0! *"V Nd )HAД(YfnUD @5g@HMYz= f[˒fF"2!#R ;3%0QB8K.!PD**/nOy>rxvFu3lbl쥴FT݅1a~cY6J)`d$j%pHWMR3oubw0,x.9}yn oW"d<QǏűL{riC_~I/ht_(aUU~$7W.2жYILA\YUH !۲ 1 #[[NU21z y.e-*$7ݾ7ZTTDZ4:8E3jX>S.})̔jH&AT݇3O!Z|'6cS~`]ʶMCo nl%s>਎uU{?[!' 7RAb@D&vsIjA?ѝm]=m]89@Çg]Hë_iOl0yJ MC 1""AFS3D));#!&(+; T.ц ] eڮ`K繁ac@U+Ei`bATCD<ʹl,%xֶ|(7CR;"rbB1">OO?]Oůw+Z׍^yޯWY/YV@ٚ$[eߵ!+f롰Z,)-1 PڒD"Pɳe$ dU)"|*%S̘'=L0`\ByZ~7Nk@zÜ;xzh wƾp+g؋:]qTof#FDd׳"*c*f@O!"59Sr)$R!%<5$cqX$Ǧh56e vfF$ŭM {ilj~ꩯ@AYSg@D-,kFe#"0DUIcD/aWL| ه~HO</Wֶ]0AN :v@ٹ4>~x ;T 9.ȇb@f-.6}&WmLҽh?إ)PF>\ SBH|=!-[}6-륏~JEjRP+cWjʦCZrhwlG3hWԅTCn X l ˱Y)/(y}؍DsFU TA!5xÖh?qoAm͢ X}ꛝp0Z3s?[۔mPv[qYw OpWRoZAټ 7X%$ג l$,fEBy`25O%wR͏6ܤ!x$Ub3X1Vw>hJB,]ژILS1폜p/ u!XN~+C@d 4uNX3!C t@9"z!hh؜VvU[_ZnB鶦o8Cf{>#~TM[Y=7z&lugkLKYp4t fZt)P $ֿXOW5_d϶1x^B{2ZllrDG)hOȞF鶃^mW{DuoSJE$sEͷ%Ŀj>rW]f<1`Jm6#tHc%3EUg8a`p=J?c^$ϴ z(l$<ȈKWri^۸VX.>Gʹ9~|-%ϑC1ID>*)I23C4x/R2v︍1%oE Hn윱0,)nEPQ }'yQP-gPcGP"Cֆɹ*ZOdYM h}DSw K :7.okb3y<|+9! Dnf "HFf |ਙYJ * 4Ɲ&PQ:6"%=_o"^^dFP|uZV-y75-BUU0A` ʕ"'L 2ZVIKẢ1xB9!Q'J`qȤRW/ o m(jD%;DPTUP, fԭ} "jK4!ں2/h89owk/w5ʯ[ >7EV;my:p([`{1ȚP#y00^=!rْ]fR""H<%3cجڈ;oU%R금]9 (Z5UKU!`^%\F*KuM=ۓiG$%Cjy].mO3)IY'p̐*_؇t &hYBRJ)Ƹ,so9WMӋ!)3WYVj%mEolV2QgȪGH@II 2oU.Wn+5hu]C" b'?aڅ8{+yX@rMdI^{1l)C˹jց13irmwm܁ȥhN{J 0Y-07),k&3L`f˲,Ҟk\JDxbBJ1{&1x{~O{ }zzg_]g]2MVVJy$UD.!YTeāL2Sٖ%%Q, ">rx)i1ƸKqbULS =Dh9sՊb;q6){\L(HPL Y!sfZA:4$1E) .?1Lb^QK w3ggq,B8h;k (Xm4S*6IVّE zsot Ԭ)?Dz,"x JU9CT U=:0vJ1xRJBZW?ש0 Pga aM~}ձF=SIzOH~H_x|M~l .`׮:BE3'rg<$. I/o/")$cN9Ly)gQ1IMfD`2hyؠ@oqh_ya)U ISaIAD&EE2h *hD$ B)XJaxEMd)ߝ $uGuhAF_^OO?LS%ߺX;]bkhWK4R*4l=wqRjQ)ʭjRɬemnqh6Wv'v8`@prg T LM 1/I)`Hf:!bbLI˒%0m<ܓyb)R2M$YV  y,0lg{+͖c8s'1Ũ~bVpY%Ò%o!M"q7WSIt*&1J#"K*q,%!2[s~U ^$ ,JbB ME`غOrAͽW5(Q5aοk'⦯q\lݞw)ogG^l]ƥAj0:G"pb?Ir˲xp$[DHFjB?Z#<,˲Y1IU%(THW>9I1A`a0aJp@? ߞN'Csupr WS|z_Rse%+|^`5. XU'L5,CBs\ pH13KdFfJ\[r<ǩ/jSҁZXH>ӏӦV9[O? /d;; %ե'}gjgX;CNMQj9oݍ:'d|gj2+"4[N`AjǕ)]s]mb^&-cx^ "2>b H)J*<jQ'c\+Ұ?Q@"QVXt G O_ yGzRg7y&^2 pu?􌎋 _gK>֟xNHU\saia)3QymEi甾)D[r1XX5h,\'rV\hߦѕV1o͛۫X\Ε*AōHEHh̝+ /3˱j' 2yX]ex1',]@|K3V.vI3#zqK0KzUKGkWwPfI Wy} __ j\$"rzP֐ .ՉhPE>ŘgPU9<ڝqd;@*mQz된auCp??ɬv fPxlU]QKSʏRo^0%$SxgH$T  L}`WljaDD2бŠ> e"Ue1Ee@.Bp'g(8!yHsg]~W¥$'8{lw7)􆛇 hRosOi%:Dt]Rؽ%a>`9A) SAdArpdD9n7U4%ٽ/j۩5TsŝʓnLM ::2mmF׎>>M0,Qqiq &$WIn`~؋e7TՏu]i`y[ZC[{CxNvd>GxtC:H]~O_G/R865;Kv\6 #qB 材s^ET^AP1ll6uKŅT= >td8G@M{*ub5= ZEN^~Sן޺N כXڶZݳqU8ԯ3?*7wT夿;!mKY1Ev$*ow#IW "2ϳ D4Mѝ9)@J~u7bfTa4J 99UCP dQEH Z % &RW 4)A&6$%٘<"{/ afs0P̏w5P)i\̯REZ?'F$a\tدoϨ7ɸB:ٽH:U7Zx0B'漂hf[wX+<ВkJZD dHHݦIǃ=qw{ e%hZrΒ?"1̒sdM[9#y1MCx đT_f扼xvvFoմ- >>Zz袕K7 S㣅'a =e!`è"0#"0xjI\u1b h}H0uih3̬`}⪐oj:p ;O[^`xEupE~OSߋ Ԏi J@ \Мc@ H葽vj]+RIțd%3$I =%aʹZ|I<@DHI/f _wm3`OʨjɆ{m^8|t ?5YTu9ϥR$ⲲRm V"m)X XrNCnM\qhpGȞjA0|s$1F,H %˦-y*PWp=u=Or,)/Hȏ)O_B).<5+ɑBsNA0Lӻ@D"-H[(%#t mqd|/_ ;sօ N0$3(3t^N;i =&tw%%s)eZaڞ;ުۆ\Or\߂kd"h\+8No>]=!6sj_xoe{<.];]vjRŰX-GB cJ0#< =NZ˒-C_e10y)D=q![4Z R hnQI% aIuGuZGfꕁT /Ĺ_^ Oqܯ t<X "h~ִh4H3 [z U? .;S^O`Ėk#]f0$Ҡx)& j Ff TR޷axf5.Eo)==~&>jd J3Ó9ҿ2*p;9 E"D:53YCRr>8/G|RzDH)$@SpS4[AR8n;919sF @€D%sK |`nƵ걅9 k/S;[|~zsӜ$ȬWVem;Sӷ H󵴴aշK6dnE,p#D:6373յ`&Xc7)m ؍asܴa&YF 'dRƉi"0rt#(QFr S4zkvH gW3=T!?<;^e_a/m׶sI5UN'oXSArcJiqqY4y;"#%N)cZJy1ibYRz#,Ks\)=ǘx!LZL0Z 3)+ "QLtc< u$w@cq1*Vk)s1vGk_cxb6r^1S>.Us}rymjQ뙉{-eRxN;U4y(O3SԒ@lGVe" ڹ[Dl)sۛ U՟lyAsЏK; m{G]_<^.4\9Uj"5ؤjP{1xAuXD뙙!LYsKn1ާ8DDc~9яlUADRqYeYBt[3Oq&WC=̕ D%]OuPy+n#l3cDo'O?Ӟ/5O?5Sۅvd/^7zh[ggb>;#lm$8ИYP.ҷ%hQK)ݠ@=QF!2r\g@Xi[IUl,z &* 5L'YWqccM]'a'l!|şw_EZb0a,y.ójZu7D 81312!g+1?b#> ȀB!@&׵,9-))O910,2I$BD1F&0Fbà XCV @Ad8Td{mG1t'/9-x6yʶów |__/lm*z̽koKڧk"8s &X;lmaC uOΔ;zم߿[mdUl2ćVܔFl3Z9a-Fi 8T]cf$S3=o[}BXb=JurIWx{hhrJh67ļ1JzD'WYK/bpC 7\H/~Us_*N1e2]TW N2MӴ䛈L~)%RZsSM,,1!0|yDzै9D)F3N 7W#0"RD,q"yL b /o\>{߳羔<뿼Apg>ϊ1o~ #t"k憅aEU5jk2ٳ۵N<=QMg[ݬ@KD$ B1G0Rk{ Kʙ%UzvI5>,R;֤W3@;wv\ ڔᇰ}z?KcOWp04`0#1nNvJ ;"oSb8y,B zĚEDqQA[;QJS^!^Z!=kij: UL$dJD K-Q3|/cw.Oȅ-ʶ-Kڣ>EkлS{4UTRԫ1xзu_l#gZ^[l>{qxTΡC؄c"" mkښvGUkyR),S!6{p&D3Q%Yֈ^O3۪ 1(g'dh{USJۯSEχ=<YW_S:SՐJLRI_F u0Re",ķvď,yYxEׁ"凞pg{ cIn{ppUCjh5k۟Zoӌfm(h3jnƮ1ix I#cB4!HD xujPUi\6ːqS2p$qr;p/v/2 vYtb%WW teK.-d2rϪF*\00i˲Lc)|5!,xxQ,HD(dBie~B4i& a83z_4Z-PS~g,e||||pYI9%Ͳ 檎8~O̜_9toc̳D1zj[ -H\kG1'1zrI3۾Ga q{"t]?#9bp֧[mqk" U1ۉݖd^t#"U;;s1r)'`?41 230YL *6ռN:ƪv>T7AdBɠTܲz, |ϙTz"k/i|U<௝plZM^hvQ̽q vjff"`F-tn1no~~?>}?|R21 ,,"s`s L J~dn֮2 hFՆҟX&@qbfh^j\w1 )$fd 3(o)翇t?>>w~<Y%=ljh W#p[~{?{WxKX,B]klf_ z  #'|[QtMԜcUSJ~`[E\UEu38 ! @h(6GiWB^sWg *#WX"ZQ2Z/ hMQGݽW^$C)g#\1y1rx؏)2K-ssI˲`ZiZyyy $$X,!b?@/e\>vůe3FB3'CsXR|)cߏBg;ez8=ba=޳5txRNk{}p.J{uخ* r= d.FDVEĐCK7Gx<~qx}mC3'uy-Szs"™33V% f8W.Em5,"W.?^nP }`GΉM <@[޴RjE:f^ASߨ1F"pAuVޱD׀3pѨx5-sq5|?bf~<t{<oo} S >?]I3(Qbr{<>[[3,YYlpTi{>3JCҰm.\<;E45|_YO_m`Ucu?ZК&(C )xr[A?ZӪI.evyEy5{66cB) (X)S$Z 5Uy߾}vHCtqb5ݲm PHE:D69xxMB5*cw :\p'Z(6=v&>9{(1Df!b3L2=sMo˼qMo?BH)x6s'ϥ. gاԐ "2("2ar?`10/`Ms'3T40Cq \|vjݬB`YQ"2%%3CUߋQ)iT_]M{y!\?GDH@?T,ܱ$\4^蝀 bSk/|>1x˲$A$%r9M<*i&7sBL *1!`8[ ߿IE:D~G ׿ y^pwyO-1g=(;?7sTf,M,kEz2QF22RaG^A=@[sqkMn6sSrt;MӲ,nVUKcD cgwwrSKղ';B(#"Kxt궱ܪE*rYgmax؛m ÇYr=o~iQ3: RAHuyebt=Y,E"*&&4Mo|x|߿oxܓJvrӻ$BDc1vnmP|ܧqtK DsU t4des uʽM9Efv뻫 JjÚHu5s3owڙzl>ڡ%W8?O6ߞA+TwK=3vssmNo @6CQVDSpQ$Qcs~L1rom#w~ 貈bV*8LrFYrǔ6M,K nҡ75|+z)]'kO2m_Ԁ&{ýQ=I6j#ST d}=/#zQ\킗 /8YەS?+Vu[$;IП~]ri1 ѯKQ28Xx6B@-rH˲ͷ|/?H~/)%b`p2S)SH)q o,3a@(ӄ!c;2-Ű>y"*N_? ˚ %~#  = xѮ:68f+n~HfnUӪ֜WUS]"94|(ٿr<\bS-ES#b1MQi:m- ÃviП}Nfd}^N6=_ҿ]Gk]1uڷ٦e?o"Tbk!ꊊ A(=t7WPZݲ6fmM=WCKqbQP|NNE܄OR`f4OXmާG$I%{ "1j<%^s֠6t>~kWoPЗ~pB"*턝hDD~⇺ҼPצnѽM\\]ÕVy8uCqBD̄@X@DP01EOP{G w`6?ǁ[L=$u0+~ r`$3?WxEA}zb v}!PFh{r\!VU0M0ܒ,߾-9ǒ?߾h~<JFĨES[D!fYAU}TquǨ>ɦe_˞h`lȄfH!!YdG6?noo3=َ D$kZ> g"N90|薄4_fS(y.5WS~u;>̨g#Y=4Q˯Gq7ea!f5U D&ܛ}z$ݷ9ȤxNza)>FzM>Hd?!> ܲ*TBK2al\>q˴6':H*y Pin:6( ˑYʀWJP5ۉtibŜGӃoӧ_>}O>ۿ>/?~˗EDK<!|? k5חֲkɑ׹L^AMzQ 2wCTMGt(e[^c>о5@vڭҙd˝)_ }pǑ"[)n gsv~]ޚP.x%)jInlj6|zY%Z#EݚNdk7t;5S1Y%( NU `x'wA3Ƽp%"⻤[ObLn x;}\Uøj! O˯x/?/?_=_x1 m R[Dy[$rLxAt8X[!^5Nn]|xcn嶯]AF0ZI!v)EtnEޤ;K G/`#{+OĹTłN[==%7 WZ 1,$%ZBr~˯>/_Ͽo_??T? {C·*cוsn?xU"j|{*|_YRug4&%1DUոqAD"#zì˹w$f0*DĶHs7Zz Q2!4c>dB~i^=Ea& r|,?|L&HS-,$ˇᵪ+[L;U dZ` j:yi BS.^lN`D0vBB6,ǣ/>~ϟ?} =||"_D#GfY:^݉1 l$ +:2n+/LW.>*aHRq/"WjZ6:}nBֺ!G,~_tA˗/" @Su/"# kooo<`$M'L`oAvyצ;?L{]S3aD%ݬPnyfAwsaZE|ݱ;0$ GhwI . Oװ6/ϟ??ϟ?<DӯQĉg6-uu;e] vnBEeФr(QďAMؗPrQzn9uN7\kjR"3d@UFa\ i8-nkَpmVL /ېeezҷR[E%lK]: TH ե _sym_*i*@Bi8Oz|ۧ_ӧOϿ׷Y'َ{/^!Wf_rk;c0o1%2u?@qq3k$^']XFB+dr>SG֌R 0/_,(W9"GR> D0fsg)MmuC@¤yud ˗) hFqa8 }CP,nb~Ї~,r<ۯ;.paK"{㆛vT0|r4ԣn=:aKfȣO˗_?}o?Ͽ弧lU~' ^v)|#_ѻ'8e=5)s uhƠQ"}h;m:ݹgڈ9[iz$LHJ.v^2Yg Dqdž8hv vV: #DW8x2X 0naݠw哥DZ-k!",˷WCs0 V' 1G]ڬ}F~#ӧO?矿~+s-)碢uY8| "pbV]Tv i>5/($~a+\4^Dfmϯ,./_jeGiROlrolˉ5KA߬;g #fp/hLhwzNSKS%VXi:i<,}`~)g6ct\i& wUDvuْR&"@TR>(|_>}o K-׋l5w5OPFzPn՞+eNmvdlTU]׫'w/uG. W꥿y}^W<* K7i-4')pO$Y,_n2) @wۙ0_\J|2yFZ(tf<<{,|@te71 9Ws.kg7QYJ~7ӄ X.}S7|@Yp/Qq jIj _ZmاIDAT7JvҎ'ΐƬWQHǧۗ_ o?E9KK\"/]f˕"f7֋Z+(1WN!^|B ZTy>_<4Z.>ְt¶yQjI`,h|Ag]J{g4wc X mvJz~Kϻ>7{NjB(I lܕ,R*6a$yP@n(1@\ qo?>/o>}{`aӃ?VZ&V4M5UdO@vin~~el%oFJ(K^Q,@T+U'//yzتAxߑnBw гY<[ Ag?ϓ*{:Qf)$7K HK4IӸp^&tW|[>GCZ+-EPʛmH P*t **\Y[+d %|Em !G)YO D$( ~Ů1X Q޸OJ)Q~OD aT"BG8\Bª#pvKqƈiW讹[ch^]C|^$|0h `SgH&¢l"G - i1E't~laj@ UM}r$A DZ)h30x7#q|7zhPXAt<ǂi9/YrW'߼˟/V]}\*ymzYiMe25e,{9Ȕ]J,PWqł)tHSq՜v<XpGl# DZ+w+bd&ڸ(~>DDkA;Y犲/yx0CB_;`P Ȯ? ]=Zy-nƸYy0(-~H{ٞ[ Tf2\Bb>OՓ6w:_eI^YhCfv+{V=OOJ*5bJ4g@U&%^julߺ3lޅ.k&%w֑/NkA*&80rni,+1+"L;楲.Sz2F,.H7c^V f  {`>f +nLmSfo`4)Qހ~}Ngle+󭅾/:YfހI<0kk:K5o7}]3.11A{6d?@~xiO7Z2n g>Bn{ #[)\6q T,C`;/m7XJD[vSy7Bmf+6LlnU}L7dpvnr+-eRYY^rk26, q27ECR'YSG!I?B f Qذ_ݵRk.pZˠzYʬ"e{xd׶ ~~Yen]087Pr^qGeQ/R !;)OQXx(9YIu,ep-/18p O^D:GhMΫ@8ڠV~-C\sBD_ R~5yr( W֚ti (xHZ+ճ,@;>H"R@9 J̅8qp @PTR[=D\g}cqBvUTDRq_Jy~tT~J "**L,,RE EiL,m|ad*WH&7{D^,G@`x @EQk,[9tRޝЏ%;H+{bf2ND O{;_7Ys>&;/yV  tMyQ 3)(j:IC0-gމ`;]f`m{#[Vi^iăl^ѱ(D ^͊}-ZdPxMάM0#!=49a,Eom^Fi6R7lp4vDe VJdtH>ClsίYh+zYeDgKk0RwlޘWX#s$ [5~>[6‡s/F VTyU >sZlM'4LymmI!8 y=CZZG\twZV9hP]0컶ʇ`F)/bsa/it״R0:urT W]϶X+^hYgiNJ dhUXǫ 0b~{P9G.|#EĘ)^$9suN%^z^'˼ % b@P_e!].Tk\bsYs~zR>ӰD"Z^fN 2l@ +݇FWf@{|Vha`P_Զa'zo.z}"h!d'~7N;}5Fq0znx jNU#lSuQ#07Z6.+j`TƍH+a2>$" 0NLw^:=0v[ũt6d&8*%H?SWL|-!@F<^̧TsbxZ NNaSSN<UQizSv_H7zY1gI1n &=.Rh<8'ҒkYzܺ,75R/Rhґ5w.9 Vϓ(n? /xƛ,~uyk)>p8N!L-u3^_kO ݡɺ`Lnj|%mB"Rv.e %=l7H욫eInneS= _=}n5Y_,csefb'X;BT&f,9te*IF咪!&;#iZFF`.=涾ɸ4j5?--)(7_[lbv ) wqQ$55@?XcR2̉Dӽr=s7 D r9`8Yp[A0ﶺ-3uvl>k!'3??;/ŎhvW\ B_Ħo_2h>|AX0 hߖWn=|1KF\n.$<E\\uj=Mf׷N3Vj bH*<}mԡ0.V^kku3eo-_hlA:"V|dUlE]Ve3 +8(s cSTҵ1'fe:?/ܡe=I{4_QݽJHngΦx@9 Y>HoViP FXƸ4?YO>m `ćW^(Z"w6حԭan;gzŮzs+t>L\t;[A=vYeg# F$C7˷x]֟"w{ \bz\/[;cA[n~ зVg76Z(Y~Vck!%qŞnWk]dK /^?,!4B*I3FzK59v0`=9GSYตEy@ Qxq`Dd]|NeY\Py'6 {3D5-E`#fPO8+4E S{욡zSN޹fyJ0NH?? IαX㷞NFϗ9/JȜm9lHS}{/$ū哛_;D{ |0BF'j9{m AE׀_ݔ']S\ja,!b& o7琚tM$R {(Z-o.H;KžP[ΕP|=] ?(p%S~?xQ 0ҵ} ʷ#M; ݙD$Xa[Q6Od1 'Q|&"BŏZvs')V%܇Ry+Ӓ+m U?.qk5|(K?nMEV(8cjE ;b Ȯ zp݂c;aOqlܭ".ڶ+J_"fs/" lŏs$k$aοEBL8TEYEmWٟTG; G5mxBn*SҜΧ9uI}l;dDtԳ>?v4TqB4v4}/)>/7]\3#VnzW2ڭk,6\,\T qjӪ L2M|<f׉3WhqJeڱqICŌCHpv1@٤>qg=x<pe;hK~oy"W/-l< DHXfn$U#G)o\[hZyл܅<+ wM2B8#zW'put_ڜ?J['B* A>(w:g.W9wOط :_2}_P]Z>OIn\PaZҎ>[7pT"H{.v}9/wr*E79goO z@:Ya[%`:O90Cjeb*d +}jQenzctz"֩iu8V~P3T'6 1X@C? ݇*&/s9v!Gݙ76ADxi :7liG̹,Og+$r8MD4 / *t#4VR~e)\|Q"}|/c5riaS\j^|wpLyNDyR5TwwX_u=`bl%,}$RF$dӓFK)>@1/UgQs=d,ÀA0Y3ZN ~:<":{hY̽K֑kO[;s8g߁l(;zl4'AG=—=,AiXh[F|%i  ׻N>^_<~skhX KiY'FEx_e&lQ \p7.+hq#rݬکmP3 MJ^,fE57Heg Rn+=V˥K"gSv3<{iRx/p6|]MO ] VTZ8v(,Zhl* /5;J]&c3F Js7wxHцfۭB__w^NT-C.b;޾x vqtn1= <4ciּԀ ^;H4lnȴH*21g_)Mr0DxX}*6=6?G*EZ/ s S裟 tmk> :gbRk|dĺ <2Kk@߾Pk4TnXjrT` `L=v.| ڷ/&Ehqe=ivMӶ{7kFU ,tUo0`AFHw^Z6CSnf~Y{5Z7O"cꝩ}Ȕ 0yKwx^O(Q%ū$Cq"Lw):X<'O 9f>_gf_HH} " f}ݞ\T'V,_ZP=>Oz {=vΒ=Mg>C^*<;zԭD݁h2*HkgbEx{BZËVd˼ՑX|xjQ"ka!b(J?/y=]+cr?~cleW-^mvXPOZHa,4+i~m#Hs=4P#}^FI,]@8li7?q_uKҿNq4@D4j'" *oǧb\ۜ 8tgy-Ji.L Næ~6XG6]ÍPĐ G$_^-XBZ6׀:Hӱ!75s|g}|>\SڜVK{b7z uQZ7H֛m5E* Ab!ƌU*i, '$I;\Ea\]+{8m(o(DmT\2c=}|w|＀$lKl2Lk= מ[VAyH$"#fƆ]yfe2Mf[&B;v5_ sw)lWqG|4{-L|ǏUCe"(lU|G@+]`HKuoB_7}U38Of/<>yʴ\89Qi|7G-:M˒ qEyK7tJۙDwG{*'A+ce%.k[JWg|Z/GG 8;E SޤBܿnu|v >YB, b~^ũp&ܽ7usX3(d,He!+gD!fR|?5٧~U|(4 ?ӥzEE3n,c8;k=H8S'|̜89'~0-_6;AYU7Vh&Q [)sD^H<ݏa/oU zÐ94 4 zW BTMC67Q,%<.ܗ4~0VOHTG*&k|>RygO~6_-A7A?ǵE2r|̒Uf]vm}O]#hʤ.Or/PɳsإoI͓yg{o }\ IX+ 0Xd`p- SB_ B5~0{nnJٓ9=+z›ĕ2 s^AдĘ[sk?)2L-~ҹzSTgrzO tDdGok F]z4VRc~+y7a7qN$i1JQn8[$Kbf.H&CSdY,ϖ~7KG{+ެTD0]uԡ3Ge] BFquP A5&%("<u/z Ed/ R\=oTU; \8MFǣ7l9RY5^W!|=0d+MQI Ԏqe; l߄zڹTDvW*] \ILe99޾&@_Iárz+<!" A!NH!|^3kY}7;_\?̃[,g\kOړM3;ڕar[,)7஭]ve:b?9qVDF!- n[ιJdc"oڧIZRhEwL #ʖL@^zL[8=oi{y̌i&Od.fo/ !H1}fOz>- Ҏ9 8" cp~u BOf;T@bZcqk8/lB`4n@7 H >t=a.W^fkZ{ZRSh̴k&]o=D_m9ݷ4jzp}rRDͶ<]-)!S'12Qƪgbj@@TQu5NmRQR;fJ4Z aw|=|xf{È=hGt9sUxosa.d-5\#&6H}9!&+*l3&;)Nx#η+H?'rXe+αg=dPTF\ԻLy"+@Z0yީ15 qॺLa_``N+&H nϾ1Rwol ys3+"b4hmǍ}@?q'Yۧ @xm%ђgOq +Y\8s|0?CTr@Dѥ8  6^0HhR^7 Xo+j⒥ʸ3 yr|wɀd6B96J^]fGW7 +Пm](S%8"F )ڏf6҆ѤL.aE_`$NeN]>~.Pr^%=w3|W^"]o/{5̓r.WEKt^,g*0`-gYudٕAR5p+>]z뇴Z:a7 =]G騥4MT5ۄ}Aw{l*D̕S]gT;v^G( Z* >rzڎIIچ5`Iz*dkTʐ' ~]/=-Q#ڽb=ѝ`X* ᆾEyݻ /N&غ+ }scvVJ"B4}:3сV[Y@;v>u-4OKzan9GȄ? 3zChEԱ&R< RNrSOm 7O΁b67J]cjmR:6Z+¥Pu@<6]ܵ$5 #b]O*GNf?f-b;ɗͿ뽝- W9YXb2dC^u2@`zvZgrVIrnX2&UU߯XnhWoԻ yr99PM5c>{=y7 ]J={POW&;G50zr@u?(a>(`K+ec񟊿 G)*%N_;sn0!ƲB_(L"Rp][lV#P H!)$(tw<#o8"r5N>q6bP^dG6L"C0Z_=0gʔJcsHwYj+XW;wziXT[5S:-ijhOOؖݦI[$ʝ[hSu k}JS\Aا"-b_72ĒLQv ~,"|ZlHfQVɠRN4SN˝д[m]蛸8@Wx{<>KJ Ih}@/B荏wM"XLXV̼`9bj6}|xlµ.0U}NCi__>5g6b*Oܢ}z{{<^}Ķ1j^ wԖ<ܵpzmx{/t u){ x7ܤҥYxO-ffy6 zp˲SS\Ӫ; GF9 GN 6gx}\=piCZ[3"N cF1acJlwO44AvICug!⸙]}7w dxNDҾz &(P}<AŊA k3~u_{~žB~9 Z,s+& [k0I 28! K^`K^zL l.:d:;2V^ 2q ɭ 4tNۉ;L{f$秱\|S[ν bFl [N>i jv.fkVukie[%V:5>=-5dt-17R"+Z*BEM"9@Em*Vߩ*ROQL{{<dӧO>}z<x(ByD.B8T%L' Z=r>\ͥ60[Ym,c(@wxK(6>r1< YY[tK xn0;{"*ju@~q1 R  Ŀ8r30y:^OĸŊvغLce J r"f3ؒl'Ǖ6[݅umWu݋i;{. # Q |>8(Zjr|xT+,`(ըfS9Rn-m(x=෷RʧO8t<I&>.0 c2(+MZP b~"Aaa"*i-Ca,{Ւ &@>#Bb;؎z Qߴ 0s;Xlߪ[p)θElcB TGqܶݥP~RlmTO@EJSD!=iAEeHEN-Y03K%4}S b.(= .@"W1{?[`NDHk%;TGRaW/&Xaf$M4nޏ)lGI#$iiWcWm [Ț.Qka\zu} ^ 5c<4il jA?ɲ8E_"Ԩ¢Bokgfk3p&>2]M.gw&PрYjZ]ѥBtI-tN/*  NfW`l$ؿy;&ن"eL>گ~;MM܏9Dqr"n qux+U+ :Sոʙue2Gl9zLJ'wdav=54"؝!TIPe[,ؑ75_O7*r.^C]Hav.Ү|ɲ]W3kߵKQ1jܤ)@zmO+#q[KOg BtruչQEnZZ ERρL4"x1u6{}}J6qDkoACsnd<pMhԩntaFTu}{ORT {1eۂ<|1ojߍ{ qд+3i8R)/HrL~M 'qf2V0%[k}SLHZq5nWq{r,r51!L}SPD'~P% /:ւ L[g&}ȼd'$$]f?) ދGzvA$z4aD̬mW> ߐl"Wx3\A'+g<Wz3ȝhq7_05nTL1 joɒ 9;@f@̓^'?8q&ģ%ED{r ʽ ߱ULAvJ0)\Sye ܱ\;+okcaRGN̬.ҞAaZp=|uw?26T](4Pې ?7Ag۠yfj/ѹtc K^Mg#lh۽nUq1E(EH Zџ W l0 ZD"wd +_P8Q237um}_ )A  }1>!x)HȊ_/>gra +dYVH6V;]z pN 7GuWlD tݫZ6s mu*l`GƤsq+x)|Q3{9m*HۂZae+IBBK<\(Y xߜ` 5wK":.^A!#GbrO1bi( P֫m@+805EྫjwN<Ǡ@G)ð@l2D S:7 }$UL\J!c`ˉ@:rE}c3l-[_ɰ]ܕ]T׳6;HRe)bʕ PVm33d<﫿đ8^vtA35Zpޱ'hP~o+,_Kmq~S CX񒆋9*0e9+ izE4"r!!nuJdeJDdD+4zKXG"vm!c7 #2 TSAjOʝg vёahxqJf,^l];R1s]-g"|ifHl{\7BMq\|ǧ_60wh72\i*Dtצa{-.aX_<\p"D[k 9"v f 2l-oIܲȣc0<>}zdGV2l"4ʗA8U̜m$FndS}*}ZƢ~HAbt볼ǢQ-p3Tt,:wk$7z=/@'E ,hC1'g3f nQUsuRY{ Ww8FvC(8a &78=4\ Gߗv7±T xfhNV͂UV4REi"|);ntwWtS.m@rTEGt&>iC-bv5$ֶ/*-uf4Op337SXT7app&I "57AyX/ ZL ɴBGTw+M[s?Bb:e1ˊ`=ǭpDV'86ȯʖ6_1Vd0m>}_Bo( Ȝ\Yjvs}< xxγ"*$;] +=oc_q ]HuH(6wy|k*예\#',9ލliGqF!$*Rkz`."C=EksG@QLsdh.xqW40y=:25 YltϢjq~٨QEhl3 ohzǯO!Q巓YNk!1m^B.4LnWD&OcmEΖԶq :^IjnYO;pURh@a;Z\wJOA!1k[D<>WW,k}.Q; 4A=ثN3Fr(Xc&k;&EmX_aNo`my]$O*|alES=mX!cYG`+~(ܯLZ4F @pBO93(z>[!<%+1 `$LC2[ )-D}b=5@h'F;X0V܍9o3͵9upxǏLۓH$]sT(A#㬕J; |j5Ke3c>. {7o}Y'"/'A_Qo^V9E l6fZA~kG)tRfrC7Duϗh ] KV:(\8db/X\(@ t/,%G`|Ҥc0 tk*Y>|^B7.0eh1U)r:2-9m";^34r"4zڊ㍍4U%:Y6'f>Sd@E)9ڮpd8XԤvcu]åږz ,,+b}aVdTh6qOEƫ(cYJX/om[:# 2p)XߙZΎx+*1$1IL:&ǽUmپ[hk?ӆoW/?y)o;='(-58,*mS9?Z-!!nPM-5z'GbN7 n`"=c{IR3M;6-hø+ "q9nA)RYAſnJnZ;b4Z3aaӌ6z{Phw @}.M4Ԁwh[j,tvIֱ9ŮEmϏj@{6oIЯhV]B)K n<Ů~PÌ61V=j:L뿪{Nv$8Ps~>R?!AHTYH5kV;9{m3[:a{S??NQڹ}l4 XnU+ُbx7yee5z^eFE"7mfH]Ү-6Bh@)Ò{Ǯa6fhp>SޢoBؗ0N~// a~j&ϬU]I{n3Ng eߕw^|S}@{W|UWI.g.ĔHAHoN-ڳ+-^zL*m;`+|33t$$Tyi炈`f ҜAbzn@b~q4#xKf' e7)QsEV`zH#nUE.f@[bfʼkn8Q.tˑQpy{Lh.C֎."?6FdBP_<{X@ 3.+ii5a3rL]a,UG(t1][SLtXn q9 edfXiԨi%TTz)z'pCNuN0xffk"b$iz|6v6y>f>Ϸ8xꈩr2QK'GĘIkq|$E¸7k(B{ͫ,˿[iG%1 }(~ۖ-y ZY^bSךXv(8ݼ+7Sxm8+'\Tk3}Lzzi@dH^-QgcȞMwA(F^ڴ%4 u.LrZr8';E$ $GԆa IؼɴIc4'VsPqtmAۓNk5G͉4 ?V0r2N8(; W+ٛVL}24VNvեO38]/6 3x,%drO77^"AM&ܩc* ŋ9QΗCDC^Z71ܛ;44v"ѭ} p%@u׆i(ak uC!NZ+Ie>kߊ]~QF v }umw{4">%}9ԿdffK^Wl!Cm{0u+kj@4dJ9I1\,3Qg ]w%$_nϦle=0%WPAbS?D"]b5vJXsdL^ oO VU|MMq(WMDPwM& mδiԃ@[[䳻a8+>l Yk`: 0g{i/|;ۼHw$ٙ;X Ryv "?'uu4_eq_J^̓z`hT]_PW x^}xz"RBR } zv3UTUi|<2ف轭"UEg+4mR6*բ'POsLRDժkG3zp!tO! yrFD$RVg~*Z5Z Xl[P9qwBVy-qj"O&h8D7_!~f e9MfY YJns:wA-y#)AԊ/Do*B0r)gR*0H-_]G_i҆zr71Rhvsrmj}6|6caU]bnjl |Z5fqp3ģtߎqILDtEp4fN6q'N݄?!UӅ)uo!:@y|!5VnT0[܂U)3E{eBM,zp`Q2A_ǭ>$-A)~ LCY_c{s.I߼_&鲊J4¼(-} _ڻzRۓɒ<'>⣳=Cʴ]ш'Y]wL3kތ8M"RaZ2룺^h11cKDws/pf?\ J7l1n7~T­h:}*S|\"dazU^zgTҟ)ۣQ>|0Ru%rNҺl^=]"\>ӬO M-Η |ivt.5n ~)ә/"">

    D+3G9LDn7a ;,%/">ZM5o 9XǽƕqWŸ ݼ3<L'Dꖥ4B/y4x5)P2?KTn:ءY'Xڨ1 t/H6h?ctEs=/dYR!.WveE!ˎW?/alxg6puw}kvtffSz6jm (ڎgA`?{r7r"q&bP=8 )z$ 8E)朎lRYok }^/f,Ĝjg_Gɜ0Od۬)L8/38*kf@SO_sԓ0C~VJ}Eikap_`ge_~:5 ht飖0൲-Rp0[1QbX"`zp]‰80P3}*s%"EU"mԀcaW[_`ďp5?c!v[nCSXaրy΃S qx}QO\Toi ,8n[ 갖o_Ҹ=`9+0gx=o\-M)(-'?}*e:,|;RmKqCPD Wv J)\PNz ̠C98=Kzg˓9=2wapShYR (8eׅǪk3e}m]`\הwMcY1=CƩ- OFIG㭝8,Nj1ݿn? GۭJ*Vɓ"諎W>|jĕ~_>Kg-]Q$_xZ'I3)bC\Hpלd6,̋TA-eB >Do|.w6 *vC  օk?I{Nae/3;/쀞t"BuaB]dj2H`Yϗ~-Wk-nįmMwK- |jcאR,PE,7EpYͣe,$㥴*+2㥾7PE\ΪIJ/or_p[8/jocsR*_"- r; -ð~`;#T{6-313ǹ@kW]>~Q26.7%66v1PXW=wlúi6 xpK?+ &wu*bb$_p|Q Q[V { הwEakmEj,*zDam[B3k} t}xY^`;@]S68̭fx1;Y׀耱yv\׻*^ΙWM6ԴZbp7N%fPOGaaSjF"gn ,Vqv~݉440Hl4lpgifk`Q@%Zwb锚t _._-ONKdJi]<_'wk8)iW8;g_W6iX{ꕉa_L-׋q}֘<|74,SO'knJz1 } jRoFmp?%,Q,MU'kGX#-v_wsZK#.i0Q{{_>N?fC(g).f9wA3 {bX!;?eR[OȐc8w)fLlp!v4 ->9Oh"+ő$RNAڢð~Jn s/y7wwhmQ'!qyӸTը+$e{3-6~[NЛlEf| $E[/'i꧄4'I|[k0gXߵnf]榘g~Hp?B!A,^Ы=!s{ kxQܲw<K,+%}("T/B>\B8fe׋4zckBql'͵4T[y^$"Hˋ?:քf@η5ѡ)Nt 3]!RAZv 6j[w^rpO5_;9 y[n!E&UDx%R"!"B&%$D)r,⺘  A\jb. 9@rhp})S.il`wqX<|-s8CsqaT1f8?Ewpϲo=wBOӵ;2FL+\sYDV-tl·Pjǐ>Mհgo^w ioqh"/v.@ܩȊkMr=*aV] c1o@s~X_ߞ?^3\d݆aSah!!g)n5K}%ܽde;ˢBQpKK)䃈'_)#3/;BjZR d4dk71<2?giV-4j )=5 M59-&L<w%2/'Ѽ6ˍMel-7}^Ο,d2Mf;TXarye2k',s_⇐A6o˿ԌDj3G܄x <; >uv@=TX5o9"D>Մm]Y+ [@r^K-*'yHqDvӯm^p`-_ }X~>S :ϙ 'OFph"+J{um]I-9X-Bh4#D[<5o6O!0CC"0:tdݻ$g A\1VbS#&3sã:Z[ K_h5j;&>;zzb"Ma^fg.ՄZ q=4^-?g02M6$9r9oslZVV1}Y27q| ׻d[ߢ2WyK߉$Qnagm)bdr.sujP6,+s%_ZnJ=FnVF氈o^ E:t-BlGqx+׆zw 08[sk8Ծ`?p˳K{R~%).=eY [0 F|&}̝,e0.199d)4ļ$ _P#JckRÆ)Fvc=`ɧ.wv.\Ɖ5g>XK3rĿ .-e൭Aed8`cH!*p3ٚqf ؙElWc>k^}:֖uݬJ]:{#,0Q6# SWyd.V-}]an?^_}.rPN::K &")((q)h՝0M uEa_Jl >.SqyhR=ᚅyRV VhC v30(S7FswU_K=Œe:gO!OEbbh?' ZGh%K"Kb;&GbkxnOڥk0e ѴGk , Ta "qGr<"e.wؾmwR 5 XJsQ}, k,BQ,bWs{;˥&#R;?]LաQ8xٲky))^]} u7%dc.کׅ,skӷr+~G DYTtgGor:)GQLGT"jV'25K eNa#)/&$a,c5@9}0T&M'5PMuҐRAV;8bwVC-WD'K]REnYrj%pw^“ Hf^^j}^GQA!GK?no%O[wю%1p!@ChgDH!q4]b^ٞ| j.BB6|gh &waR`.T} 24rV߰faˬՎ0R\3Q LLR5ah/S+̘7 !yW;w`6hp3MOz!~d7X:KeeQwa?e2rL^ٕ5OŪ`ݏ ZQ_No׷ Wk=_Ӌ&s_W9܌'m}[9mLs<:W()cUF= j-GBF=7#$<ц>re]m\- F-.&KfJ+֛LLTR%֤۶ɚC}j; yV,yk[ jOڍRl~f{ eʀAf5ki~ ۔s=Ao^WfYrdʀô۫rp,kfv!E>xw)r!ZLi_xfd9UPv)s l V(J;뻕.wf]KVzR ?DXJ%%StPv7]XAkT=ϳZaW*Q)_ؕWjxMQN[]ܰ.h CѲ@ٛ'Co u<|xQq:|/S[W'q ܵVBttOKM!@tFm=_k C|$Ud$V }ӌ2Ӵ&)vj.Dvn.nqJSO}`=SSo/3Xy]b1=P E\y!4,=NM1+qG)*<,g5`aa*bwS i /er{f>J ^J`zqyIdavw_0skMt`Xa<.5Ue1/K5QO>I`ngOP?GjO%wYzU5|f ?D[A6ry2B~'qhz;*?N^ċrUܴöx:eyҙL`́f+H}P%ݽ;vh!L F9.Rvf|RG[ۭ2*Bkff:RU>* pW8Ԏ**vlCY zyPiÎt4>9v0=} *{0bCÚƱ];IED9`":("xvJ *L8H3Fa(xQ)G~z UEJ#t&KU:g(~,",'  v٨֊zRY/Uʺay-FQ@L}>V|0 ]FPnHl!Q[6jDz2Ss j bHf^TIa&-}ְ{Kd&^?ӯ/l\莶lȶzZ2Z%_Kn? M0#p,jWŝ+e`!n]kJC$inR֔v|Wѣ농ymX;,M'Ta?(26Ow)ˎnKc+u# .0Q/& _HeГs|raSؙ0C3bi<[~dJ)z*&I/,^q ڴ螽i!u]a76OI6N1Ij=ov?y[2倲27 Z/jSY8ȔNAt>"hso ܁ sIț쵲K+PZ9}MOk_}CofrkڐJ)ݧL o^{,Ft"0;6`<AXd# xӯEoZ\sHY%[v>N2Hv2fƏ;E׀ԘP(rm ѭ .d<0~1*tF%wV[Sa&IDDJ@p~DnR2cz/[AQ߸9cl7^wW2ɫkk8;m9˼Ej87`z3$ -%+$ݼRMBCˎoCɀhn"~$) H!cye&wL%`0h cSO z{&@u -1 Y}Spr5][~i`^[r4,(7< l3,BQ9߷7GʯlYV%\'k /Ͼˎׇouz:20r.A sRZz#" oR+-T?sb/ᘆ{cWـ,д'X5;TeEJ~|vQomznAڙäkFWrlCGP?0X9ϓDxk<)ZP U`:]dmANVZOwx]I Ri3 ^q>R#uw*}V554}0# yk#ۑȈ$IDK[ GIWܪݓh{O _Y-O7IDvnx{e aQhKb%p.$)L;< Cy(e.Χf!2fgn5O^_1bw2LmKDo_s4tn0WԦ'Ke@j%tuEJ&)SNyG @1'/ 2iߴᚪ>s9J~]Ї? xa ̯ ̓e3^,Ni 䶙s-Qv⼴H7hHSei7q5Ttϡ" \cVnE G.ֶjqi5/^lHMv{X~nL[Lexca[[r?1[sX PKUtߗߖmm:qhKoa‹YԲ |n3s9_z$ĕ9B?_.dk|zeh}[ d}䲜Ӱo=Dfl9f9@4Q{+Kcb܍$thW ޳LᎸ`C`Uʳ8TQ>kf;!hYQ`" >`9K^W__Wwi'Xdoy軖_Bʿaԅi5罭}/xUܽh/12H2AߗwKp=0n-\&]9LD3x/sF; ۺΉ௸X<0-U@p'=lg.`" =4rDр=^g )3DD)|u&䯶%4ĵ_/'yL~హ HM}23U!r䘙:\Yϳz=p܃P@#nUv$ޞSN0/A4_y9%`OdH 7E$E 0K_JC_@/nKص?Ta06eX! Rҿ±f;7,akp,< Î]]@M9ΞѽseQVaa??laf3X̟qFl{e%Cy{(nD\`;{gYAp wL{tqGD>}L֤_hP0d_;%8<3=`\֡ 뎧|g}E__H74ڰ=OW2Ujkl焥G8BVx ֚AHw_p 01A;@Z2H1Q~Ȳ6l4;"2]bѬdk3AsOi9CцL{2 mguUo֢."yn}fYߵu1"r#puZgw;5ԑο+&M6}P wl|y|@yzx{ƘXElY0?OjWyvj,ª,P=mF֣Py.AQ8Jwp9 "Ѓ !L<x@;fcml?=9Ffaju-Q0DhHOeUL "v ocZ"SP9JigSRD.@ (yE@,h|R":z0[Jz81"0H"_dZhn|'kg/+\OyVJ`$/RdlPz_nO&@DPH5tLBiBX !܌C.Y; Y3n.WIGcftKVk&-u_O^ZվaDߴeWTƸ!.2PNbRe п Z̠&=(@n%*qW. b"ptNt+q0:VN0AkCz$05Favz̖{̙_73FWʣMup鋾 x7cgyh&i]56(sk!-]O.U ӻ RR<{GRN/ۼjvK*1ͶP) 1 8R&h&-)pfjd]SLncG;١=Dy l9 ;kdL>NB`3,UU2~V4АnQnVb¨yg9|T\{{@4 l[*)'۸"6{}ʲ˟YP8"nʦjҦ/mښ.o o[nK\۳2bޑen$X͖l-ޅ-wEN}Q -!/ϻC _BpT1>cdkg\ɺn=61HOJH`qI%Yy;->kQ/22b+:D̅Ƽ;sOIO|WV? SĆAB(?B004^5T/B 8Q{{[5m{3v3sp64jsn^6G%6x3HLc/P㌬eA!zNo->|GJ8D;jlz0 v&}=2vP?GN`L]6 MO˷0?Y'm3C89yh~D\-8w aɵʛ:Kydz@ߥ 7L ~օwjv_';A!h[%ׯ,[4>|/Λ`4=ȷ(PDR+f\ Ha9T=ꮨy|u`j I)cN3rWZl7< N 7xV')M: XI4;&ʉH q ?uaVcu.'L~Kt ) NO>?-pi(#ؤ%-Ya~ Wu9òQcKXu˷Հ^_}_"gϻ@z=w>&DacpFnu}.gJqEsSWmyP|:>•)h,/cQ;;j_ ;ݍ2[PwiȲSԩ0xXɖo刕DN44lČ V+@,LZ8 [iր˩>n _.w!׀Be‡/?<&hN3u!= /eA/kB~*w 0d 6mza[תkwD F9I >53ijs?N(9]S*@)&Nb IAJNUPW7&C;5= ci3+G"3(]QT3GmKQ-΁ Iq+eV섭 C˄~ =zN!-U$@z؇O;.lNav@HBR-4X9nSFyԆ7#)5C)jj& !!ƙ"/ 8zc䳞zTrYDjK(c0Vw@0LC;f9NBswK+u@7#Fz9/Oo^˺ޫA_z/*\J \BbBYm O}!YZ^4ϻ񪙩'2[Qn@mN֭*,;v1AUm1L#@{cZ̞:U+J?_d Iff|}ńOr(]h9Z0M71_ډi&v91sB+ 0+ SA1qn 9 fIS6y5H p_Ydzx_mx>T_AB+w~ݳ:"d0:lOd7aٚ1J}ZD @k9o*kˉH %"$%knM01Wl!7zk$ zZk=)genW:]nIq37L^086i6!9v(un)k%Co;5 "oy"W'5J'|%4I!6}ȵJAmRMWG0bkQn  Ј2~\Xs5:tgp_mDwʗx>{aK\`0ˢ.1}[K05wqkVSёvyDZhջ~iA݈V!~܀xT4|݀F&+]2/;/h.x0 ЃJ4,4.' ioVl~ǼfY5LWDNp"4n:Id<5>87:Z\aB"R,_A鮜Ytߋ~/{A%|}EPpd5W\fx1թI ?b'ĮiBrJzO#Lnl8@tAa2{ } Tz !swQj`thYJG֊dNk;ռm,OO>H]'_* /Լڝ'GGVLq:kqg}<r$_g&i:xl۹pۥ&|%{qsMCp;jf4N~Jd,~څ!wi*=3¥^|ᦱ7Ҭh-jMfO8CE?j%zu/ j5MXil%sL>1H3%YUkm]딋9z"&׀@USC/fF1LBÕL p,KxځG ٝpؔvb h'f{}O Ev9H/_aX=X:|¤?UH`{Œgہ*RdF\=S@i!bYcPEa=^ :`C l h7/Z*0*T TNr8 VW0qV&**,<+Y>Ud>rowR.Eo>6{FR3j4 ?f )Rba:U :*B,r^L73ŦAQ$C)$ YO"*t'T֍rJZQިPtaLBr&:.ހM@-c3~z ?G/rϳ~~r/||~*\t!KetD]g"AHx"q XS/Y2|f<-%CQ. #m=3[l[0Cx+HDCfoӠb~/ zT 7xxq {l 0ء^-v5cm`bg?ȝyEbvG98ڤZwBH&² P8oWd?^㎪_/gږo%ӯb:{Opb.Rmo"ACǎ/?~y:J'*Kl.bwOzbդY.$5M/h7/·k߆`bvwbŋs7k椁+FH(ۙPC+p/ax< b ݷJwJY_n/'ތ   dn%VA8^[RАUxqWFvV+j4`xVLv8oҠ{c n"6汚'NcfJy*2T +&Gt\uQU_7]pn:"Gp_fPy5=m>4o}~۷3NQU\"ߖv\oOe6Pډa#1o%@u~~=(NNKPofXfU^13N iatu>wJ) %LIjJ3i50ϱR"ݑJ)9q[)OoFY-hSGLr+fS!V$5nxV 1k}$(!gnf^u!( րU?JN 0pZa] 1ؼYme #=wׂ̑*C%meKiD7B^:WwGVCv!}wޝ7^P *r v(՚0j }RQt5"3(sBCٸ<GhBàP$xxӧOy*S)P[}GG&l(P uVh~K)f&8«8ؗ M Z3.*x͖+]j܁+MM?Կ^!"#FF+x{yt2tbDLik9u 7rjY鼶'Ѽ.~,rH`亠#a^mcնESN"K8(yT|vM+Cp7Kw"Eq+кz#W Ҟ#t@b?h@0[_#iYH-{z)(a]{Ra}g;E"bAxj0`JhQlFX Bxt#BYO4v%!gaaqde9nvG-_O7qݶxIRUC h~,>ytms"pU|"Z}WdGH"2w?wHz5:n=j'Բ8e=mAK?m~tluǚO3@]hOZ嗇.ɺzŧrhAC?+Ϟ5Y} Eڬeǣߚ52-[%z|PR2 (޳̽yv`1@ݶ$ ΩK?|}17('3{>ݭsfj† BUʿ0eT&ӯXfu2c/r%1]'ޝfvuyJΠt 8ECzq}(2 +9$"( Bw廾Z6h$+N@L&yVKKQ70>a"{8} ҵ|H֒@FJqjV<]`N+\2^ Aʤ BdJ ErTd\@).%݅*o()cvJc@ߧ(`x pF4`_6S":Eu |6 N{=ś/"0E=̹ꪥS@^9OqnhҴT 7+B0gJz j#L'n7m 9UkjYjRfb(no]} HQKlÓo~0]'+-=`GeK}=x,랒0lvRv |;A&1Z]:̈́o&U,r"f0Zms)e_\Jˣ={qx֪shС1w~v< fHwӯ"qh}z:{J)>@' ģN"2ӖBDq}B ՎPb)X%fQԇ;m< mDm/ BMr"w\هO6hML|`*̋\toJ$g"LgT W)BHl\E6ӎ'מΎE=5fNg2߶VU!)_˚-0keA.woݺ^nW={|Y<>|$uNw8f! a/;3xRʨ2 8(QUydSeZUPUaU z"vY~uܮyپO^T4-L<9ߘϤ)UhlCG&J㇍5=<U wy'ZB棫;uREȅ% UQ?^7Ҕ̈́Nz&hB`P!EgVNrdDqIobܪT-FXm/}gAku"bZ䲪`|=Eo YMm=5u4ޘGMKs;DFc# IWSdԏoe߬p8Njt3ۡj4I ~f<Ɠښ]5_F~E$% Nj4:&DTP-{ )5直94bkYH T?;ffHEt?GލtLκZTJvTiu/r`3 RV!>82y>Oys25Ok^Uʿ{: nj<o4Qa[]^o_OˏȕWcNXTE]8qRDZ E2g `d|y-wʳNQ +{/ + VfFG5{`.[Ak YP`:~m} L!F5f*88>??<+6UQYIF٩U@@vlgqa6 xUo}6k[+Fu嘮lʺyqU/D0>D#BX(Y _Hf ZgƝT;"D|G*BfUK2'Ad3*X+~rTjeVB2J@PnVDbTPǧƿ!?X>!*M.Nغl vR4VF=@@b+RaatHYGz?sK:uDu fooGx=<퉐8(,D 1z?Fn sJߘ.aRarv[R+df{;tec=)­.dn7\] O׏Biqwfyŋ$RHyk,X2<ۍ#VS_ La,G2k9%1)F6n߳5Sutye8? `Vϴ75|_+(~qOIN1_0>^$ͭr\{vGTfWV ۰ Dkj Mq!f˵c3)-~e6/R<'T0<-et&o;.#t@L ŵGRCaUg`|8B<Ґ }u瘘]=U;*w7_AS"x(>1}e\D#'y2tW9iuR$ɪe7Zxr8]KfiwJyO{]h a۶-sjdVO{Nt^Nn84L3 /NEL8ոΒ+&I*u`Kex*Hu֬$?w=h'K[;mgӌSeޗhr*1YUk7j JãShA巴:,%OWu@uF JgOڃӦ;TV8x{p3 VY6Q[ 2Ǒ]-Q0X#DdPpG wSji٧/nxkx+&k;zd-QU."(4 K!g D¢ Z}̅upr>ZB {fyt^K73>r-&l6g2a꜅;ÂSY[q9:J[nR)!{xqDǬ yФ " [ԈkUk2sT3/#S$x?g1LҘSc &s]gW@GӋͫA7I[2S)y`lDD &ʁPR%^kS* 5 )HJu%QGr:b㸌?! oZ?we_ = P0;X?ZЯVЫ'2`b{X?#_ظߘ)6ڔx[SiVicLУYfsy5&pt&J(jqm5T4m52kVv2("~CI. '!}:?e|BO'ݘIy qbCPhh'D{ڶm_Ub?`geՈOm-2l:L"cL2oJSV L^uiu`NR V]aUu@ ͽ J5X͢@!}J7P\7-~&c@$J Z39mLJnl`%rl>Ehٴq:`*+5,a9Lj8wdwTB}d *cKUMF.Te+-;[H"(0?)9 X!-DDHXubA"ʎ8(iTƟ4y>_<q Ɯ/hBޥVǪUY! x` Hi0v+KpwkIS@p6ڈLi!Iv)̴ TcXso1$·[#y;OD?;&&"rĺA_ӂ~2%(X6OuG,<B,j"#l hr /K-SZ (G=G0ON։.rzIdw`yճ5w-3ȀZ{ys炻+z$X•V9DK멲2}  d>^RQ mՂBQI z06MC)LQEU[/S=VOpkC Y1miame+ʸlYBٙ-H ut ďE2,|]EhLszИFK7~ SV'=yYujmHT5[*cP)n].ςEUS}b/K4hV5r{9& vT5~l&٪SfbtFʪ{TZ2&d-m%M-MVkկN rʓ:OqFق9N|;ڔc)be j9 ٳ>"z.h4Pj*]] X?Nŭ&ct %T<Nv|1u'˫mjpV1JXwK HYM0/=ǂfZhAkf߽I~__D~Cm btjmsƳ9UfAcbJcʆI<8&ߚ %7O I`<\f.ѩ(z`'S@Nh mU@O ڽ@XEgpuF$]ˀ)Sʔ:=~!hNI@\ei<ҭr^K#u|JN跗 ioWtUT)՟cV*- PAx(IU\yzWô_WrRT+" sB B =*L1H9l"D<8*rQCH 7QHG -@DqD F?^!85];L5E{+_2m;;<[ܬ/( 2 ֊+_̈́ΞKkEvx^tkuTva> ZJkXNk)CD`???+H.2~EtQ⽽O'ØKGxG8b)}1l:'ʝ!:hK~T!P~ďg"N>Z/I@IH6B~L*'Ta^[(Qwbf=i' m@qb@ź'F-b3_o2ԵhHӦ^UlPDtQX |e֐#*Kv@f.tw uҭi-ctrX6X1u[UpΡ- R 8H yէ=Ȕ: wmێ!鷲t+_m=*tw:3؞\(Mз\ nqgvHB @1ED#TUӍ SeN I"!u-/u z˗4-jq_pΕ.)?]`1M<{m2>W[ߗW+ ONɵXw;E؎,"F -ic٢ftQ $<`'*>< ǰ-%MvqewmUQwѐ;ŒNk AVs=.E9?މ`%}LZ%GIIA{is\`R-azlƹ{^H x `7x<)y 8}ˍއ5[,w/RiϠk3w%sY)[.=u~K~Ș&G& 6R!P"M] yvX!eg*IKͦoBKꅱpNa@Wmd7ga!K]}i ToŊA/Bf: ?_K]ܫ r^u1JS(27 C&:[F̢DBA9O[R>d򌆮uNC+]g9~;ñ=zj<ۊZ8?~{Z|;\Bߧ=E+y9E_- Cn& L ,z,56pʃalsG)١"G)bz],E @>NibMj&ZQ_U+#qjdmvtb*wwmc&W&W~3M*7TE jHf̘\xԣV=R5L XQ_!g <_U菃Wj{α@Ya3!ֵwY佯|AWyaUjMJH' uɴ2j6!ǰYaY c^@58w ?,(aS!ֽXIOXp:H{II@O[WƷnɳ &"(EUv4_ilڣI9ĵAgv }-wpq呂uQnӃJZS:]ᦼ}mzob/@]ɪ6%j2teL]5~<:bc6{ަuSw1 QՈHD($8ٱQ4Ѷ⏚༱2DZ=K݃VS|Gr{N=`.HzbwXd#BywqM~M 9m8E|$w2VqULXfajߢзKPq0PMӶ7nO69m̈J<o3ͺ؉k.^zB;-OdI{s2a6+GG; 6s TT9y_ 4ufHEWj֐});ӘӥBZѣݪ M/~VO+p߂5 E⋙Ϲ5QSW"y^ 8Ο-%R4U2$U\Eo@RiƩ4rĘqar7y6R5)+tÕ2WZj92G Y?3uqdYOI|l,FUU#UJh& t7$Zjޜe˸sS缓n~ʂ&y(\&H)r']M,BW/5ظ<p/5]5caV,_xHHI$q5)GV6Y4EXP a5#.E;s?'7CBRb6\٥Idd ߢݝ0jС '3]8T ]hy`2]C-\'4S(0B@Rk?cKHBf=fvb'UZpzWx<g539hrݝ _~~;ʼnU߂`nټSL%~x{usoMT%Mo%(:΄=nt$"FkRhy/5w5CQ.+2 l8"RKY ڿq :s%Pˁa,QqT !qU( ݽZ`f.1X{*I x!0k I=KE;[JDv4/pVsF @I5>Aߎoƹ;'~R4ְ9Y<zޗU+V-M h\Ǯ{M@z.^Q]zB/38\Î;/0yU^I9 @[vsN,JXG OP(7@"( A@b@BbM95EIlѺP(f"v , 'F]QM\Z]Ny ]eG%TjSd<-|g M-F'kIиOrh^i _Aߗ[~_7ӻy["Wvby, V"aA/?Tk=Mv>&2npe+dܕA18zQi,lxQ!ٍ <=2p昢o' qR08s9`B)cf >DΈrA,'1o!UVe b,,:1 xVstywZIcޒM+纋#YPh;߯)qA_Yg!" - "X1b:Ռ!zMZ"bޘ#3S"S%<26F^fM$wl0O{Jh­n:-@IҞI{JmOЈE3m1Q4Y CB`iL1ߣ)*;DrޚFp=2=ԍ<-.?I>N[5Oa=ϹISOi+}5 _yW(c}j}Vr3e4y(P{7MqUP1YqM' bPN gC}cvL}eu"ъ&o9z ) G1+ }UU5Y`-Hw$n埕 LWOFkP֡ t4"E)/FU=6V[d3y "oQԞ}7B֓r6nϘ01Ģ؈Y{Gt<Np[6]<Bf]p 6{ߋ/٭\<ܻYW ѷoLnCÒM,ByCT]PdHB"/9Ĕ.GUPhk@92d U) Wo Vn:Q/%Bj~r1V(Q&wycQYURG E.p:])OQ7/5` SBY\;cx <+ D1 GXfvI+9]m zW%zsWw}JMw yͰ!~Ǐ19 훶T :2AtU ]IFF.`#YwAݔ*+՜Y>96Etiri,I 9⨟,?e~u3^e(1}(i7i[=̅U-cq8. f(%g-OXXRXϙui[~p/ߕ~]_\|OکO}G(*fd4q PS]%V{ޞV@HXh VQI7-3_T*bc#<|#lD!JX͹36uvDzDRN9#b&ǝaL$cs""m|}s| Iq Z%; d]`'+rZQcNן1ԪOA"u{(`=] bΪ+@[W(^+s7Z[}iٍ>83dYGf[MMDB{ZuMŜb,@{e!M>f;ϓ䨝hUBŶ"wrGPgn-:Uf>$UቈQ^MԝOi'sq _wy!u9M\1/m'WywiAK@[s{  ~BzK[X9PqyG 2wZ\kuF~GmD4H5>괗sӕ@}"βBJyi\@[V+EOc!ꠍ!b"&<;X"~!(@?mT6ܗ,J``b!D"S\⧬i`pfiA{_(ǵ嗷Emhg6Gks`?> <`F`mdo(cIkTIcDY$ѷ}̀Uz1y#&ȑhyaWUOggd`5&^"5?=W3я+Ц6\|NK 93sh0fVshVS3<ޝ"aI~3^O+,6Ƌ>AiU爻ʗ&s.|i"9{sq%#kIJUìCՂ ͡UCRWcQZh@[i3Rqu}Nb9M^%3"d)^t2B2 d c36fszЬVO7YD}1-: r2a/{ʸAɎ.ap.jXβk̬X+vsZy&c #щ w!U='Unc6<]\OA]fšfvjⰼ\>^}#{6~Kp_2ѐT2*QbcCTUQbԐ]TB ԇ D]TT9zHG@5An6Κ<%}u fMo Giw=fw,svנDA4'mi+ C׽ې}IV J xBl5=K>@kO_m'fL+. mO'̿򮻠+r3neu$̺? $h|r)7fq * V7,t8' WRbb!t渄,>@ XIO@]jK3`abeP9-C x_k˝@ޭ~9 S؈ФsW 3WSisjxhu 7NvEپ1BSz,6G_YsJfy־Lo93|^U+n?}_xd gBtt *R|0DtYYcԴo#u=}?fD 0ؘ-m80H5'AuzF̤H:ͩӸOcɫzjЈ[)S&o"kyWU w3[E>C 5Mu`؝D*˽4Kw@p'}*sV+rdh=)ytA`x09>I ohYݽJ^O`TøQ:~=SQ)"3fE`t!gj ۾=>Bv"ڈ>m($2UU=R`&B)Gwz=$3Yjtz\=,3C(`sS6B Y@/X`IDAT|"8 %~;йVkNv0!i`uVuH9 5OgRT<Y>nUf@2ܚN~^h8N=yw>nsE3_";`/Ϙ9tyym4fWw\c?KHZc$ D "bX)!DDmض}6&U|zD7Hxh٪i 1FfSMOV=9 aW%oD`[$PO2 dO٦W)lfʰK4UJG3qL!^ׂ;ӹ#V.JHD9tH:T!} S]%i?&VT>9&E֘L%D?_O<:~,e(dҵږoꪥIaVv ZWfNu<}{*}w{zQK;Q~~~"1{ 6ObH6#!0;mxf" B(y2b2*!vk{M[-Ix]R0$6.mˣtTb=jJ1/Rr]ILl:Wn9 h"B,ugT5)I}]9aYrN4N/[>R[G<%<ʀ=/@f+/v t3=25}Puh<OV ʞbJ%aMJ|KcC x DLD^ +kY0%&8%^K)nSmK)%L0Զ5W*03`mb"4iEyT}i_{7shS"JYA@/ZMK!+YT^!ֱ*3Bw΋vŦؗ_Уkh&1;71طz֮(;sPӭyo|ѿV[3m(\a<[7@!"Ф]5'rJ9&1#O1~~ǏGa1Mܻg@UOQ &+TrsQ(0R&R iBXIwftʐ{II C 7/]:88LrN"нHT>1/IY+Hhdῒ{r;:*'vx)lOfO@w:Sd0NE {E=SXgƾ_^Y􅚟ŷϫi{1@ʬz sћ0fo~%XAhelAl.#ʡ퟈KI%$bQulŁ8~|jlQc欒"0o ٶԨ@tzmv4L>CH%a>˴H.5 1i5EfŒY|VMnaN)` xq~?c2)'+!(궛.L懊¾QA1r؞tSUhbB'̴^}HvV.n)M-Ʊ85dn[sg s_8͔~VX͐TԞUuqDZܝ{s AcSx{2BPQO0ruWs xQy?Qn'<5i˨9?ٜv] l+.esq>ޒn/%\ϭtOo "&ՍxUf B`!l$9B!ۃUQ(LZ&)AD1b+%H+Iz@]96?]QF'muqgHPMhJtiʲ%?/HQȠ$4ߗlD8|-aͽT` mC=D(`biwYЫ>j';0ԥR} NOYO\-I|#U+H|@''/Y,O.K2S{qDd-ZKkmswiF6@d7@DE%rH%F==x`T;JWKym#dXU?v(i.=DL( LU 0O BQV[o!] 31sjMǍҧA !X`5;#kâQ>#%-HQcHNmKjng "*edg$jq EPN\_hL cW\M84(-*[T3Y33iY4JQ1#Qz̻0vCqQ;'fh VFLJHVYr/Ip3|cO2^krbΖn/) h;Rlck(? J 9v.97&d<{}!7!꼧ڞZߟ$Ȕ@8%h;ͰD.Mǐm}?m agfhntGO?E8~ r%|B mSw TUR>BJ`fH5<$5zE??72ΘJʆyv^m%uSyh<)̢XJM<2kghڗs_Q )f\h3PSftNqW[o|ZWU-h#s$ ߻w*f?{̂P8y8;ၘ) @TD>?FNVU(uk¾Kѝc,jqG^2{7ذ %Pd _ ٞSpO:|HpߙF4}!SI9X2D]Ð!Gs΃*ylPgSoVX_PSqّYbwK1oH)0Idw'bz6N2WJ#.t#֗\٪*V.@ÞS0;I4a/G޶=mDLUWlBlZdVUtp@fw[O@@D9SoG4%kKf{QcQJb;ւ~ 1^he$E ]E$*!"#u['P'GWpkil^K4-ϟPx,yx-Xr{ܨ(\Rf 2c<2Dou^2q?#;ߞ.\8rL*ܶf\Def.eʷFR08 -;"!&Q(P-MR9(xHRu WV#smVPQp7J9hwpK v^^TWIXO\4o*9L0v0LWK P&DLJk=$LrEӮ:X~~~" >sA11 VſBX{%RCDD"(@̉Z  U@}SG&yw!CqE6,ӭ0\L`2d* [.4(]{u4Yn>a>pzKyP.ܟr @b+P"또EKaAgI K=zqzy tOЕ{pN`Un˟8:eh9xJٚp wT ,H;s}AF^tj~(ȧv-0UĬ&ͪJqT}"?()e-$Kf8_'rvCI(y]cm6L[5 *mD Ҥ+)m3;sap47"uup^oF.~1b*NXC5ݍ_mX9'oG[OU{3Kҽ#tDsD"ID߇&D@G!X7#D/ؔ]ji !`ʳ$N)T_DeᣑdQB؊:7x-K,5'M@:8 *Q'nN mق7}Q"yU}F̂O'|`x$LRU!$6؄}!oāx˨D fa(*i.YiVmkJO'+o9L7W^җSRW~,W`ӗ^'D-]\PSU$R:.^ :Ƙ;L!PBd1V zh>-$:MpsC)5J#"S;,&!%"F%fsJ$b̴@:p"ӡ 'O G6T34YH6i7Q`+=Ѥ[Z_Ya$(TGqvmC)AmKBx !_Ѷm!-ٗ烔y$z+#`_L2<]ƿ4qtgLhm|9wwSxN׉ݯvnS'?{9B~٫Ӗ{Ӫ-G/* S{F1y)f`:TӔn!׼\BqrC0+AS`$*T%nl@)pC=XQFF2'JQ32-ido&/Ѯcڗ!1Rf?\8P4Uq;/<-*֮،;@3 @MWtC[ !FDqE_;X$ZLLZ{? Tq,\-+\3)ORynˀo6kr_oûz'b#YH*h[ECUDve3=cV'N\ʅ)(H>2UŌ~@#ؠ S2Q5V@ږ~)` J,j+Rf0#v&"sFYDC - ]T|Z<TaL+5@ɼr 2S`{a>Brfn&78 1"dC#\0~.Hs}yOtW,5/z_zFd̿jt7=vU`5w_G^/x;[1ۥ9m-y!%uƼ UrPG$?[>l{{tD;z#)R%.0IjRS 8EYZ%i>d` TX!([o_O˵]#LMlBCzZ$9x<[̙@U'2%@ nFx&2tN514,6> z킥*6B)-"B:tN^ ܮN؟ X v6 jJySYCPgbQdx;3$D!5#m^j| j4mvXg(Xe[^H _2#C1yɮBع ډhvqY $ʀڶc3Bwy o0ǶoàlS_sl& g3P PeZ`MlRQA`5DwEc8-9 N?UXk'Չj^|CRi{LtGP?>.RPT 9l;]U${x<L`sR,($"U !?H$eXVqA'b3>qme–_1ԓ%e{ɚ??!ͮi"]8;is\ڙ&F 4|V omQC+ ;j H ͛t$i,i RTqk=ۗgue"_v}Nt?Cwq[6݈!j|=88I.䩧[BZrzpL#NvJKwWHDDrC4!U*2 ]P+6Ԓi^l A4firCd=1p(&KXh9tڶ Mϖߦieh<8ϼoD B(ŝEFkf*'P}^u/a7oңؑknl+ܧ8{1'6Jf{- zU"td Y^rjd6lL9~'JtS:l?3$&Ty"xʒ=Ji+S=S6oϴ'%W4<*5Le80 {9ZJ L{ bEMiH9EL\8 "ˀ9}-0m \D}g}ߵ;WFAwfEchdy2I] l T==e.$MX G3iw=LzA|>_VFD6uҔZiSx+w*.!8g]Mݯ!gF*a^ůCOfV?䩧խ+C1apQ5BF kxYcef;uY$JzC(PоPFQq"r"t A ؘ͍J!;Պ*(Y[am{PCy Lm[t|0rtvXԹh@9ʔ2-{=|qpԸ!bβSNC[:11nԬŤmv_Q\9Ғ5BqJR)9W$IiJ:9AS]BoOKO=7tn|A/9WӼ1teOqf7_@hqLU 8-霠:- 5Zo${GOЁ1a$*j$r`SIˬPyڗmt<2:iL{TeQfeҌFv_3QS; 6Wkk~Kxn hKgy3Ȳ< V8w)-/{>8#sA٪Us"&EټD߫Mw)]۴WElp[I597̲{Oo|'tw{Z8,̀pkٞ < %_ϞhCY=i˗<7)B9BU^iJ?zb. ż{I5TP\OፑE6hkpyTSUU!I_؏ HD$ Dݶa8sĝC`)$[ 'N&wJ[ `VmfH=PWO9L `|k2ݤKw!暞L06DY^$gMm/JK6Nzp|arǻE(΢"PMV {-K6c|aߤJ'faxҪdwBG֜ҵf"%M]Sj'fUK}t1/ 8_6 1pxdJyUUj+)ed嶊Wx;FQ$Sdy?C`vI)@Ē\ N·S\EJ`fm2rCYZmGm9h;ڳ%ܯ|KhX_Ѡ@P>,r}Q%Th2];1ad9yÆ3$;; j3xgx1|_=ES\U40|~$/;+`Qm_ \E_k)`/p7]^PU=Hj7 S(Y6o3K^gZI>¤ZlOB"`QU<i8=4%b߶1`Eȟ;TFY#f &V2Ŧ!JLEm!T>T$ ǿjnhWHpmF)"j>}pLY$;Th"[H,m-*PG_|JZItnZiw 6ѫTf rOLjtAhp+lBux$z7W|0R9_U6c-3\Nn " gi>Ш:&)PF48BbKtEֻ(ѻ.zDOxٯg*]QꫜU|@Nl#hDl ѵu~έt\|3֫Rs+qn2T=Lx3bI-3*E`Š%be[aXcwfP"(p;SɻlJ\4/fC 48,6{g+{o_W/pNt ͌6w>HA+VΞ,i6mЙ gKJs9]%7mNu"/w|P,^1Hd""snD3=,;xthlS|XmībsXL; ɻ@Zl)ɶlSFjV*,ŔTr#o{E zI z1#YN"kvkXؼJ+ѳȭ8.wykzONmu xxK@ >s=60oJwV+@1б3!JrP0N0$EF$]5Ssl* S)( #D%FD!JD!p}aBrᡗ[ߓW-?N] Sq]ߴPW\gCАp+l@Ò^Mi3bQY2{2R1$ѕ*TU~=Wknɹ͂ز~OxB Fs5t,Meu[wt283S&c @ 3I SA"JԢr1,V_NjNno$ R6j9Z% ƈI8q7fa1SԡoRe;`參BZ1Iw7/~}ʻY4 7v})\=u.l X9Unw:3¾ozS5F^)hHy@_]_"dTִ:3ao~{PFLvyW_rfKq eJHbҍ(Q!!4ċP5.d,WV3Z&"&+u ucuM@Q35DDĜC-(qح[:U!BdB'mqwoz{WZ|h5IgD4Hc%5%qκ%m, Dժ80gQ_ϷWXǯ5zKV9Yׁq<ސEqjw/z뽞9#OEz Z=c; Bd>q>+r !&Pqȼ=t8ԹG @7+zff& g" ƻnDPB'bR!`ĢPMl&x,ln0wk2}V#/7 ׮p綾YYQߝ {S!ɳVkPM:|5w$eۅ٘ю}X_#W_A Hٸi^ctEim|\sq 9 Ŋ =]kLFu-QBضwUFa捡Qm ʑ" q "U5[bQ70krj990o̪ltR[RYda&B0@IHX-E,q{ܗDʜhz=6wLN˴[䪞7<ʜv37Ѣ 7_D\|1PF#>@ܼwUR[_N̫3 ;"^KI/Q}󺋵n˥vj28<N"HM:1IRV[# J|;0\*H\uhADL۶EB=0k򨡬T-VQ%R2YѤV\zgJX&@6Dm)O2Ī5`-laJ?h 1v![xt($o=@Vƻ悋y:mtw'yoZURº/p9b=`j'P>Jvh'M!'|eeV8Ɠy:8^ZQO0VJsΔc35C˟$ ҁ_ԣb2\mXog+GWIS]-bVSّ QP  ~N{yvtl'@T)fgL^$wޘBrB=푴(IfLf:EV,RfZO>/~ݫB3Y=Ii+ljv?-{f2"EK,$IQ7/Y ?qu7}M_o:z}rd^?1xXgjX7&4n+G'SwÐ-?R("1[m> J7w EDì>~(1u34m[ضc #m[cwނ/LOXJHޔssVwpȮ9R^^S F&`4g J* ;կ qR YbAbUcaCǀ]󺜮Um%[|?`v]2r/hAL:WCB0 ɯ2`|3V^cKolTr,@V8$]@Cd WYrK3{ XYKBmo{?hm¶QrEunAoj-|:Vkiy}v&pvZ2)_Rªl $ Z_‚J_` =s%Iz<=!+n\֙)yukokָv%FI9wQ],)W*B, 'I"V JW7 PQڔ8pۃcߙ-c۶}3.oA&v +a~p)4{e3+ܞ wR~"#to;׿2Vlu:9)Qxr[tz|]KsR%p&O6 ^/tsO?%=H>V%"XЗ3͒?T._y U:n(Hq b `Hce7,kǚtJق$. %RED@`̲mvw__۶n!3WD7y!A[Tx qx.Qfuz/}lEmWx]t&]].fZ}Զh` eNx# N5-:5MS~YdO. %33S%=NBy*u+mm˃*F5zcwVD9<أ=:ffs؎0j5Yv͕̂БGb~6ƈ,W|o6tM3CU +y{p/޶㯏<x߶-m;n@ pg.o=YK9΄WET?PހRܠdPSO0|2#DT  L~œY1_."Y|RE`>iÒE4-g1ɑI9үuaUYӚE페jmsaPع‹F"Ev C5ȃ<EIqHEČļ$N$T2mhö>=>>>㯏ma $ ofp[>hd"|U{oɊ} VI tLDލA%V7[-*>|Zn(gw=GA g:f{0}EtxgLFicS\ǽ]՛~Z=tX;.V4@| owHQ\һ+\[EgSYk-l+&@"U%`@BE}c iSGt|B8|2FP>?cջsd8ef0g+GE_xis. 3.גw 9EnEi}ՌZ|W(B5PU*p;j~ogޮ}tiE)F"aДUIU8k;]ѳx)76n7nq}-yrvwwnoj:i?/|iF@uӸoƝ膽Po[7#@L"bD%3{gD$"a#][8OU%öTm ƈ~Axc-ZQ_?epf޶m0U3jJf0Esz|9}$nfQ׬S/RnhF8\o3STt`j;rCw%D\䇏'M)S(+ë]ifWȑ\6J:иϾ HaΠsv1m*ahEނ;qqOUz`10om¾?}vޓmcBvK[#s(|\=){xθ[5,9Gn@vwO'22Wj|tMFrLFJY̿bu ~*ӽxbb2OoW ֞;^t%54,3D}VO[f𡭮]fo{dU1lq8`т4@l _80_۶_ 5 ";gm6۶qΉƵ`cED7rጐᶻ,z/*~OZ -+;꿞ۄ\4{v9[Ț} < [3mIlԕ5w}6y!Xa-/SJQ]/gBa`Y!haFifVzq)`,]jSh OJPf$rU MD 83Ƙ(CcR!:Q1o̼׶m=rBd{)03#ّj4a4zĸaKdsW(>3m~7{EŽ|Rˉx;U:d D"R1d_$_ߓwNҔW<(U0>t,A.R& R V)pJU^tv/bׅcW##]4)N#|sd|5+vؽxL`aF/-f0!n*:CDINcTf40)!e[w=Z,g,fsaQ EjO(ٿ곰nK{߱2/="<\ 1;_a6Xz']FUd0 U $\ӧPPVʡIY(B Mgc'U Xs(s%OSpuZ뺒丁m3 6yoHZoHw%#!똘6V..68ˡHn'wO lFߝo>Y$`pqGD:7oAwf9E篤PƫOM.^ͻqOcm'Iam6{p1RF/DT.ytv;|;ܸ -1|+#es ޒ],{=}SS0xbu拪mT¿넕3 \Y6EU{u˚&߼B25\RR ilg/uz]cSU˸LĊ]M,}M7y4QInʡϟ?w:xBnC=varX[@ =+<ܡ!(5_Fk Ĭ[Ⱥ =Wߍ2ZWһі_+.BQɜ"? 8+rqL$I Às O1BՊS=NȚ~D2~F6•NK;oxf5;n, K5 68 rߩznqkSnI7WNBzo&310vMDgdN~Z)ev+>^ģ3Bc:MjIrMp󟥈!#/5`ފH8a/O)l+A` λ^ ^j^ls;}4P&>jgHSoew\[XyN7MX0+]#B<ԕמROG}_+{]u$TUU|)=9R`%4{2^ten7L vfoNӚ)`WsRZAKaɬ?ute[9`< #|x,R IĴq43\'8+{ם1G9š~KX{oth- )v=]}0rK<폋WH`0ɕLSP̪q>e{k\֑/]= e>teg6)y/~Hw#]mŋ598JQ֪l֒$* C1xKv~ vDuu -20 .6 4-vLfXíC+bTiGOtO_u? grNwIu%=eh˨&g viJsp'3} ZoU67҂,JYeߛ[7iva:8Tk o̕O*<NEQ9iTZi&߬W<S}qX#<ȯn{z O_y E/ ,J#U,CU ^+K*Pc+B5,%DZr՘K/D*JWwi=gާn?}ji#A,B6,E*+7eZ`~ȯ|0_{ϮtWRZY Jz X(~qL҉ҫ۔T[CI5dZ|q]sJ1d|Q5k@Zǝ׳>NLgFeYP2Vnn=&U2:RUV ;D#w2W$fHy߂*49TUoe>2\RsEies HˆA8e?N̐Aqm/x/?2&jWwK%V( 'U =?="RxQUɅQ"VKQUn(e ?}/_mjZu^SXE]-_7\_y_d_H^*oe;Yo ^Sg[eJU'TMn=zUvAܶ|}/CR'<'i'!]R7%w^}+mjkY' ڃ1Zj|wi\$@+uıb8L&5+̒Ay.ZTY!* f|e>k/9'g7w Nl6ULzFoU$'euU;j \рfD"z &gTw-t{~s%|E ? ~~Z6e#I\Dg<3 l+˂.3Q)fu me?$?Wrhn_U|wߕf/~漆W)R-ۣ썃C;z@3o<Ύ&_!UsZtEXticc:copyrightIXOjtEXticc:descriptionc2IENDB`pkgdown/tests/testthat/assets/articles-images/docs/articles/kitten_files/figure-html/plot-1.jpg0000644000176200001440000005303414614000564032564 0ustar liggesusersJFIFHH@ExifMM*i@@ICC_PROFILEappl mntrRGB XYZ   acspAPPLappl-appl descodscmxcprt8wtpt<rXYZPgXYZdbXYZxrTRCchad,bTRCgTRCdescGeneric RGB ProfileGeneric RGB Profilemluc skSK(daDK$caES$viVN$ptBR&ukUA*>frFU(hhuHU(zhTWkoKRnbNO&csCZ"heIL(roRO$FdeDE,jitIT(svSE&zhCNjaJPelGR"ptPO& nlNL(2esES& thTH$ZtrTR"~fiFI(hrHR(plPL,ruRU"enUS&>arEG&dVaeobecn RGB profilGenerel RGB-profilPerfil RGB genricCu hnh RGB ChungPerfil RGB Genrico030;L=89 ?@>D09; RGBProfil gnrique RVBltalnos RGB profilu(RGBr_icϏ| RGB \ |Generisk RGB-profilObecn RGB profil RGB Profil RGB genericAllgemeines RGB-ProfilProfilo RGB genericofnRGBcϏeNN, RGB 000000  RGBPerfil RGB genricoAlgemeen RGB-profielB#D%L RGB 1H'DGenel RGB ProfiliYleinen RGB-profiiliGeneri ki RGB profilUniwersalny profil RGB1I89 ?@>D8;L RGBGeneric RGB ProfileEDA *91JA RGB 'D9'EtextCopyright 2007 Apple Inc., all rights reserved.XYZ RXYZ tM=XYZ Zus4XYZ (6curvsf32 B&l@@" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzC  C $ ?(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((kj?x¿moxRˏ\^q*c ߸ї _5a|uMvo,xeH)+ d_f]|Ӣ1gӝ8? /T|??:_CmXMg8u So+/RpFόCIɌ/=^|`x[5=?gxY]mwڦAfaoQ{ / ,$=YA0[i-m-Ω=bOJǾ2OwNg{&8' ǭ~Y>X6 \"CpH<֕QEQEQEQE(((((.mo䴽. xPz O_ॿ? 85V?D 8M$ELꁶC|GȽOkpDLח?ߵ7?>#\NM3L{65ϾXP5Ÿ\3~u'Ve7t?xVn Fr)YբٕFڿϊ;|7~|Aͦ[j{ E,L+Pmem- QEj/Zt߀;%9=KO{K-dP@B'o3^K~|W1Mr(̊觌+~0n9g@QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE_࡚߈.Ꮖ &t{{ZH 0H?!>)/z巆**9mdFN4tO-GPJ1$]>|'m[:CsirtazXaT5h'ku]?w W6Mӯmܗ R*+=SQZsO{ំ7J`<nk;8Ĺv:=J| K-:v${ȤHd\($@ClJW]\7`?PEPEPEPEP(((((&_>59M/>(?m/Y"57Tӹo -gr+]Ѿ<_Z wH+*LB9 +2m#<a>:gemšx]+=KwnHFҺXݔPB񯀼}zWYxN1dq6[kϴ1R9Vb0~? dp777zďq87rG2Fr [>((/۟NsD~a~s'΀?Oh(((((((((((((((((((+(g_05wGLcҘh?!o%+G~mJ(((((((((((((/۟NsD~a~s'΀?Oh(((((((((((((((((((+(g_05wGLcҘh?!o%+G~mJ((((((((((((߰+Z*6?)ѯ?e@Q? )]ur?ClJW]@Q@Q@Q@Q@(((((((((/۟NsD~a~s'΀?Oh(((((((((((((((((((+(g_05wGLcҘh?!o%+G~mJ(((([>(x SG ϊ&N mtK5\ʬ1T$*v*B04WߎPG]CHbK/ksNgYTd!c Kijrm:I.I|d,3xU~_+~u?;>Y.K94fQu & +"W_i󌟪h((yuS|)~ |59 [UIđ2"n Y5"?bI|sz_A,xjB"Э5-7Q8ԆQ\RpZ( ( ?dOo?~'9"y((((((((((((((((((((.ɖ|UlS }_D>*6?)>"gR~ȇ蔮 ( ( ( (?_8I{ֈ隄~\s".e} V>h4 ~|!>Хk[ u )$goQ 6khtWÝG'X6Y[K %>gh![.ǏZC⿁-CL𦁧寋d3VKV0Gb >Ye_xk爴:M^J-e԰D$)]H(±';'?>k$/ok*ȗ F>V(̿)`v?f3w5in m"3B@YcК((+š--CƚOu{O?!k!3[̛BJ|gd袊(/şGE񖭥x ./Ze[Gc4=OZB0n9g].K?m?t`={o3A,aRˆR@uBTo77O|T^]l|T: NF؉f Iܧy?l+^cJ.h(+ ?mvu{__?cm( ( ( ( ( ( ( ( ( ִm+Z=XN mn]RHH#֝Š? st+OD[ȷ;s 0qٗŞuzeţXZ<}Klః_l;F2\TPEPEPEPEPEPEPEPEPEP_D>*6?)ѯ?e@Q? )]ur?ClJW]@Q@Q@Q@Q@(#N4Hm5n$'-z((((vǟ?!6vڝ[ڰh,sȬb +?K_ſ s4i4xkTՖLm$-e%m!^<ִPEPEP__?cm?dOo?~EQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEWQ2ϊ Jak(g_0ClJW]\7`?PEPEPEPEP((((((((WQH6 n1*sԠ((0n9g_s~ȟ6;:=((((((((((((((((((((?e_hQ2ϊ Jaȇ蔮!o%+(((((((((?*o|W WTծtZɶWFf=7bhoa*i:_υ#&/;HrpJ v"$G<Ѩſ>ەk ? KׄϏu_ _hy3ۺAbGY[rćQ׫vxO''L!qkGkw>*זzo5m#din5(X4:2Lj\((/۟NsD~a~s'΀?Oh?~:7kDy_@titiEVg ss3-y WuQi߁^L"\k6o&0Pז,`E@ TV~gQi1[\BT ?0 tuO6{_?g(7ƿ{S[|?<,Yt@Եk]B8%ݤX偉$p+^ז^! k$>-)m dj[9U[(зGs?V 7૟-)$Q\oOտ"?H(*  oW?[SuoH +{ BŸEU[(.ɖ|UlS |{ |1(3i&WբuR`%6K$ o $g0Q6@#$.<Qx$~ѻʞm^qpMQ@Q@ُfL>=Mҭ+`TtcGEf~_!x__'BVĞ[.%s< YHPYCmQ_=ӿ_?e߄Y%a `LP#B+3V 1HДWW 'Ətuz]y!4' ]3+e~~٢IH)0 Uף)XyQEQEQ_6__-Bv_wWw_xXonc"(^'Ryc8MO~οcTh~'-Fڏ`7!_ed~QE|Ek>24寊]v="Fd޸Jgf 7۴WG4#Eկ'W&>u\6P`̀ȀA iEQEr:>7[Inb 9f aTrNWE~OS>7q.| 9|3Hu}"ڕ$xvMH\۽v)Ӿ~K"} Y.[NִѨ/HRs}A >^]վ8?p$i:iѳ̹ĀbP^OsS'Ox&C7L3VY0;3eW (((((((((((((mONzmޛ%գ/!hZHXrWg4|<% 4Ƕ wy)@O;|͎v.N5_?U/_}B?YxgNJIb.t&&8x yW6_^)ρQ}/Q:}\g)&v3 ZiMjwyVoOsq_]-coxjOTMqߕߎb/O֛῅~#|au㿇: Λ3Mhհ]bۅ'9kWUеܦςF݄"/)e+07J0ފO|((h߄|Gt-;UTѬ8eBmʤ0k*|?-cƃ''yf$KI5#_/)/h+~u_ Y_jCk3\E׫>N{v6syw")7;FH5:?\N5emo-,GxN~ux;XtgP ;.'K;uD??f_ ~ǟρ\jd5kZ7V~TROPՋ3}8/( d׿ҵIyu fS_ ~.|Oxuudoc3qEz_]mҾ5O)K2YMm!vku4k5juݤ܆xZ6؂k _k?ͅ$z.&d3|k?κ8Kcu]S,3?g ;2[%^TnĤ|̱oA r_ǚλxO5O M}R9{ΈIF*Gj5o^zNu7(G;K`3| $ljF]7@~=OZxLIoqqe2G%J\z95#gV}_ #Ky9]rېTXV@Q@Q@Q@Q@(((((((((&3g/dx^5=;&ȼ,{ܾf+~ϟ~|(?'Uϟp7aeg<&Jj(C⯉]6iq=ĈeAY|&.|Öd6ay&\c|J,tPEPEP^L~|,?GӢx,??~s|޽f>!|>_|{ar/"͖6=B"Xo~ Y/ρ4wEijeqE;<kE|!&[GvgF?c"=^~Z>- LO.F>yfbY%$h((|s|SxVzh]շ>nF-tp+Ե~+o|7m> WJԢh.mncYa'dt`U"&Y=Xo.AM:8e/ F Z((OxsGoukv$x1A$l܌uۢ>\Lmw `o/t? =֗_zǖfu$m̧݇_a@3Ͽ|ED5>婲ԾtMYv^^6?7^/O#?<5m=1̉fܒ!3,LG#z/Q#xz^_]\== Kq#ƌwWQ@Q@#*ax ";ſLػ^'z<vV%D{Dg_|~ yZC\Cki0OV=۫;ybO5@3}C^0í'Zu]O2YY?y"T61:i%!thc[KvY$M}Exwgcyg;EI%yUyg}5Q@Q@Q@Q@Q@(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( 3c~9]kB'h>Fۥ~ߴO k'lj|ez-a";{皁BI`{EOfF/ƶ7J#引?7^7>xbO薘]^J"s}\QAf vWY_c_GY뚥jkk-uUgX)#,G7(OK-W’:Vmey6{#vt4QEQEQEQEQEQEQEQEQEQEQEQEQE((((((((((((((((((K#B  |@to~ $NωY>7'y; 6Nzm5lM:uE(N *NQN5Z;+jV#emiKg2iiAD oV$mn>S0S?: |Qc+ ?iaD 4#i`HBEmZ- &[ǑЦקd?a;~z:.*s৾׏ԼG>[ 9 t`Jf__W..|lfBqs}?@1w [*V8~j߲yxgO|Cxj1!N@eR;ÿl?~"/৆3q-:+4*Lbt<ѡ9D#?23/Bja@u?2Ѭ+r[^Ghz|1ys4ݷ ,@|XW@<|-M><7X+ZzIm8p&+$)&@ '>A6x@KQm0ܝZiGfc#ռI'%|)^ZOůYejfb!epQT #rA@>2oWO㻟Il3%NqW8V`d ڃ⯋?j.uܳj:$4F4$XPs7◍ ֬<%+..O᫛ŴO tI[`?g ~4>+yzZ=<ɏ}c_@?| 7_>4~zt?Y[\Bxr&hWFDs$ ⟎5έo|9vC55}2&^2xп6戯C@4QEQEQEQEQEQEQEQEQEQEQEQEQE((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((pkgdown/tests/testthat/assets/articles-images/docs/articles/another-kitten.jpg0000644000176200001440000011760614614000565027510 0ustar liggesusersJFIFHHICC_PROFILE lcmsmntrRGB XYZ )9acspAPPL-lcms desc^cprt\ wtpthbkpt|rXYZgXYZbXYZrTRC@gTRC@bTRC@descc2textIXXYZ -XYZ 3XYZ o8XYZ bXYZ $curvck ?Q4!)2;FQw]kpz|i}0    ##*%%*525EE\    ##*%%*525EE\" {{,hGIve#Grw*Wr1Hw"1.hc&"]R:4tR{Rܪ!R=w4bSʮF.T`&NtN,=+ܽȎsB#h \DknTh Z19d̔wƎI{W{!G91Ɗr#n^ww1_QU_Mk'̖wǎys\+Gq5ʮT%0ĮFSM.A#o>AH␎^甅!z )ܮ^F^hbWUA #Bΰ.A!H^kb)B+0ƍ-EU^j2_ůkB˰.AE|!Hr1gsA(X^j2^ܪtkFơ%Ms20ƐR8{9s{xbj+y⿻U=UxְmG˟>\0{9s{"ċr5*^Tht5،k.|EWAHꪎ1 )(!ĎzQ U^hTkՕaa2I8W#Qő$RrcÉ3Q/*/4ZjFjʟc2TŐR#׹œ"IwW41CKWs-ji5kZŕ>lRH1R<ɕ"IWs(qYʮUNe ]5%d&#YoIe:TG )$!TqJ"Ah#B #9UF׻k֤ d8Q_ ) G09G9ZA>W9~zw**)*!k8s yB^^Sʓ&Tz (cW{מUQǁYKEQ|o >|v )yɒr=zaB |;9^dx5TU5jr iM(T B]LR#X0aCb+ȶw;]-D6d $q,=j .\#A 1zuܬ ֺuR# !|.\'#sA 0؜{ǃUMEI ԭQie2\$ys8.xҿA'>Tr{ܭXP C/=Tv+g%ZYΕ-% fL&A@>q'/4+))%n/GΙ(|V3s4x.\'+=BDWp?UOCG>(tOMU]ek>\1I6|åDRJ6\{E z._ʋA2W"|L| i|q7eL({ bLse5%{枾/GdD l)dAfJgT hp BGyt=Z`!VSR՟Ϳ"}&ѴGk=F ,Jc:h(MUΙ*A9(Р=v?0Lzj1}沱{믞PzɖՒlAɑ0pUY.T# c[;گA~HD_~nՊk@lҦ%I$ϛ*IB=Р+UdJښ^ .7]miVGi5ôUGigEG6\#a@;:qFb!0tj/=&f/V+O|rG@C_],jw=qd24H­a/9=w=$H[};7K7[m̗6\<{}uu|dg/=ysE(YSIY⟛r>G`3WysWn8ߴ{hO"l*W=$&'5Tʊh w= o\}^)vwTLϟreSտf>.A3Q^}95}eE< >w{^]̦i>98/Z;OgGPiE{,ښjp1Ryϱ:1y%*jm?~k|SzuiI|m} ?ʟJ}c1,*{j1Bty_SUgEd|=|VNО<[~ko {ɃaraoqG88A4XqG!{sz:e}Hq ::Ϲcxd(5S\C{L^Xcyߝ 1igW"Qic}yŐc X5a`;9͖Lj)Y-.^WÝPJas;k/ٞ!$t@9;yȓXD΁khj,Fz&;KҚuA`}q̐5!…81!4Σs 0%dqQLӪO= Uf>Fg7Ky_:>,:Hǎ0HI2!T@Yq(4B玗/v*\~/>{ٗVfElL GAm#8Q;kKCfk8ޜ#cDR45I?Mgw- }Ag&\D`@a0Yg}w:fDGj5TVWVAesgѤUH.tFRà + fKA!Zʤ3#USg ێ_c;l9˜SSD&Xol=75vonj1W#@H51,e^h?G %L\6Hjv{SU龧0&"r5sA ,JK73 TOB=vIH|gH}^/|v6ǯyN׾c 1NG=#meFs]Ĺ% ze*O|Wӵ5N;cͥ~4l8B6"7y#@POGvst2 7J04+ko6KO1fl!86"5;]l0E(U}'V˿4YLR8jGyW:mkrcBx;#VVÅM JNzGy՝,n5lnJxJq/^F#0CB81j`>JKI=3-6W>\)v35ySeE|?7֟\֣0bD&0pbUƉOB_WMSGu!m%JAOAC $ƥ|[Q1` 15d(ubŋ-GUA~bހזR4<us;]s*LmZ"50l +jjcmZ{rcL<ۋ":AΔ4iya֞F5c1 $8HH@+)t6p͸79[g ly6rkFmmNkyh0lj *xlt'ѭ,UmiG`Gd)г82/#$Hc(*s:8vVjlVʼn|˫qhkYG]g6:լS4R1J ""r3Gΰ{B{[)g~sy&1j4tUU\C*Do#FƣXֵQyWjGY-LTt}&I힅6 Zgkia6YOȈkc@ךakp2-ytS{l}C .?AYAYVsIHo59kֵ`V7-E;PnZϻz~Cu/"D]EVvSLPDF"w#ZֵkG >lBJvuw=h weVQ܈kX0B#B1ap쿒Dbkuv7 O{?~~m].|@ϟƈF5c1G,8UTՙ 6tO/> « i6݅֟=;}f~vmpVCt )7FX h!G8q RFP-E͡eop u3s`sNDF5cZ1(q"Įng$K<{u}%SeSu]|医^o0qF:tהj#Q`ш1bć$Xbg98DLƵ(.~Gzn~Smj ;9ֵ`E0#4z }&CҲuWnBVF齰6H95a8uNDcFǏ]K1U3={W]f2[ kai/DM* ͤҹ0QW~rQ0xB#c;>C1JxFNj͵z?y6|0lb1 ?NFbDGB64Zh~asÃ_Z*ovz4[+ R\5N9`B " т4 *]֛IYMOQQNv5zݷ>m 6Q?IڈBB0@ -<83=>&\%꺊L#+uoW>ly?і`#b>h <`l!j՞1K[_YOUmUaڻP\Or*1" `1! L cXof9uUuTy<[ n?DLR9`C1 k0cC11x%zO+v:J:R2=>5y;Ix}ƴhF 6a&1򿝼I$]$HwQ4F2J#ǎX>FbB,#W^vO,QVRex}>=fŃ] hpFW1`b`Ǎ>Ee"n(Wy{[K) 8pkpF0"ȜNNFXb pE4z3.cL,~=uv绝ʤ{׃,85ՐOg_{GF2|:1j+&@>na)p$euIlaZ67w{ZS9F7NI@ `ԑU|U]vD})i$[5(PzɌQ6=z:Mw3̄! ͔eFӲXg0I \)7ߤ$;Idžj7 + %͊/I$J"S݀A͜ jRH`08uTLEQ%0`ˋ5i:wR*3e sroM]&zpX6eߢoGя?"2t sa\iӼDgq95g] #~&2e9\^]=ΏPT Mn,8 6S(/>eWz߼&xqf4Uw/'=j-:>r݁=]}We',|F1٧U 4ʾ~IקN9̷ֽLGLe#N˃yy)Uw?^:Vm3ژVלoՙWvytB Лߙ\(1:G-6>,=l aeS/QCwծS@Yeq>ݍt g'):eSmu@H)ګm1E0! ]6X@u7)ݰ',$)DH1=YMꀜ l*9a t;e] d 4mkCt;(d焍<3C˱猀n/@Ҥ x'LSw]*nrA[<9W7t,l$t3{sZ_W^3[k;zލevR|U]+{ɼڠg 36_O|gE:bL>~5O|ᶒt=1捶1ne͎Dcy{@]O֮1ʽSǞ6~<<K9nٓ!(OWsOuGF&]JG}'KUmɖ-MtoB"%Vպ\Fpr[4_W~Ky&]2m'z19Mol=m2-V ӽyMPJuNcIm+w5X˦G$tѦ6^96Sb@ yR {VJRۦecJLEyLSÖ)BtgDZP5^4E$mYܧL2ޢ0IV]hcc#p;;"*/|7L\^V۠uBg ˇۯNl*:phtȌ8Հ7Ml&Uλl$H\;R˗PUpP鎥:8hLMɣp mٚSd*C#<ǣ+}puJ 6R9@e#׳]scꠔuך$O5i,Q{9)T(wDD[mӠJTULӌ`!n 5/4qe 0(tߥeUVM>L#<]ʌǷRmAVOGL[qx'^z􁩇vQKmE'EyĒI>mW_O6yisRH4D[Ξz昤I !ZMջßMPL@ M*<8Ѿ4AUNz:eKB$ dٰ)u[m$20c֚D& 0@66>Igu#1B(gg`008#~Cpc(q aG/A08A8A z=6cCq0!P8pb`880`Apd\|o=6c0``p0!a8L?111qpzl>.  >.qcapc.>?bbb`= qllll?~'$qGW67`38cal|$1>b+c 0`08Ä6666Ȍr\ ?Abc 0`>... 0}Ol|%rL>>6qL$'}&&.)C. 0`> 38Q>qL%'> LLL\\ 0}F  =\lll|lo8&M~bbbb}\ b}Nl||l?6>I>q111q}6cCE \0zS0~8&K 1x 8. 0`̌T..... _CGqL&gf2c 1s$qqqqp`}l|||o8qL%1'1q}6c 0bfAS)c6>KL% @8} C&.)Rq F>1OH]...... dz0~$rl|a! MbI+N7axL5\\\\`{8Q8&McJso6Լ旖XaMph *Il>&"#Jhuzڹ+`pc}G2\$WvH Ws!>A[B$)L\\\0zl|||`~}c.L% -?y]v]㈰LRp1qVdҪV0`z8qÆ`,\ɒHkss45 ~(mk\!h_8T׍=9jk  =G6>>>6$̆S)|?^seo_gKw4%uZ8D?j2$Wz \Rp`A7z$X2LLm!洚%(n؅]RBI;Yp0I 8LR0`=ll|loK,X#J]fs5-A_e%%3چSjG^Uyiɉz8qI$݋;H IW + ; M񍷌EV,ɯ{sXM]SQ_mZs,!pWbXnݻr80ab\`a׸]i]-t-o5{Wȼsͼo5NZ}y=S!R7!sس3r8~ܳ D f`e&Lն7Uy!zYVYhnmOȬzĂP*'+ҹZy+Sh5zó^@ORO%Kn7:{ں; 6GK=nUÇ~I_O >D%W䓜`:d|ד5|_`O0Z _૊cqs7Mmso<{CO.D4hn귓D]\8p!I$Yd2Q(J%'' YTu*W FuC#HH3Ç9=נUa%2f^a.*tlݞզi 7/ot-bwŊ&]c2֫SeJ&Dĝ˳3;H\$Cg8+"JY*yF(ER^[7-ITԃoӥt1R -gz+,j>$>:=pT+VB0]\cḚeV۳:U{956fHj MU -]ۯ~n~Q%Ge`I%z>yԡB , b p2LتU45r$6$e&5lbiO)yʺ[PItr"ʲ%7$660`Ap`:*S u *n !Cl=tZ.MB]el֚0KtjּKaZݻOxNk *,[YY +נP tlPB3@u!6*>/Xca͖A&mV~jPCQMfoqf̀,c 0f (S@= +9WW^j+MiY: ѯZͅ[EWOj.%Ib)': AQsqʸi4r|R,vRD16(cZX wDbZu%:f 5#A=q^B zxd1)24Ζ^w04d5zZ7G|m|_Ox}uihl&CEfN=qUT(U0n6B} l#$2ZGゕ櫬|gvZ㥋OC)mF 2lYRdv$deǮ `>7 #G DYd%NIZYdT^GWNޞMfƪi}N2FIs^$^XcЯyz!aF1YQ&FʳxbjREMZ~x+TUO[S_JDruZ#IO|*P  0l(ѴF>$ ]MvT%m hR]^ LX(VJV2fK!Ϯ8q7!` 22eɄ*[+FiJZ4Q@uC0"""lF~\HV*T8bn{ JҴ+M#_+ѭIW۷`#Asd.J3íʹk׆ydjԾ Ԍ&+xUT.Gr n+m"pRz 7pasC8&IHy*d$*Q ։k[G*8*BݝmEnvK77Iqᖜj8p*AS DBdh%YdyXLH>Qp0` kn --`^MM`*AAd!u(=()2&Mu0('';UTTjնQMJζZ%H*C+)q` 2c3I,5`V!`Zxk#|Prp)Fr%g]oSoU5hQ C[kkH pQ&Lf?3*Q\՟qE}SE$:e)N%g]wOsQ5XQJ, *?bXɒE341؂ػ;y/ګNYv9ʙFƶk!-[:ۺky-^C[ *UR8FG$2L8EdXNAIKsOZH|nҎCsݗHJ'bgKvml]Ku ĘZ_Z64SA2A~g$2䤇3G"SQz[_Z-5UY'WF8s3rXnio8ND.jz*v  YYH gq L(j9jEv)Ak)\Ȗ93c̜V@Y#MS/:b%㾈  1&PєᑤY )Z ]m\2@Ն# ~eeGH]⵮x8ޛh 7slFAAR61|>38:LJ+$#ڳPl*4sI*nܮF͒;oY'mi44?5E^V:## VR#}669,pDoivf2KT=-|Dbb92Sars!U<]-RxOJ8AA*T69p;3V4XU-Yюxڰh]9uu+ L&YTeue -}˿/xo 8  AFH:ʍ (4z)g)vxV͈' ~`Ѭql&IU$C)k56>7<-AA2*A}|&Fvwpq/(e +yNmxR5UVDN&Yă9#̤`@&3/pA!ÄK㙙Y0E^c\eRMsne8C(F*!)'Y?~I8pÇlbĽ.0 j'bK(d ª ZCn) bX]pAKɖX/'?rc}gfig콹o˰[ڎVɌV -Ï$a۴&F%ĞLlG*L2EJfD86S DX+Ì^I,Mrmo׭z uVX.ÏF3nj@&Iݍgl6)ڭb9dU@b=6 e|.d1ٹw<הXyMQ U8\YRGbfk,bڵ`Ǖ,YF,d!גG=f$LrA=Ln2X( f-?Cߐ<}׫]؆Y2vE S$# K!Fy$Mjmf=/]ʲx7h10Z{N2%>N˳yy%fK>ݛO%!jԧce֨$^a Tbgkvdn;pZ&Eŧ{vͫO`N(2|Bޏ% ml5:cM-^[Rgx YZJR'kO5$f:5YjWdX=&Itf~oÇ6>J!v<1 AO4~KƩP>,<=RIb3ʓ켰O<ɱgW{PI,%fa( ݤ[g< d&Ia!bYGYY'%GuY3o q!eN%(׮ZixΗuV<3\;$9Ԭ@^T) %˷[݋ZYfirdIY^7y<<РNJx<,Xfvbŋ,Y'9lb(DD^5Ku%yH&aקku=y<9xk*  yGF8}A`)qio`֡jW]B|vov|+—W=gA5 +%:JCV  ½:tS>b1Fc(P I%;R-#ÉUY\UPN:bםi՝GoD|y|v= z|M:tקVR&x¤!qqqqz(Ta05WԞђMmw=o]:/+>:tө^zסRJh6Hep0`qqq^zt1|&X4:ZBN:uׯxԎzשRJ*JCX088^8g^8ԩuuuR R]]$XdӆÍ0#8Fx^8838AVWFGGI")ÍF!1A"Qa 2q#0@BPRb3CSr$`4p? %ș?`c^>KEe~iIua7M`}^e=6F`ҩPT/`ZQ:LveĦUj'_ya62ďs>c=")V6\+4qY|LBZ[=;89yN.9tU= ʊ-2bRi*vE&k޻)!K %@%lhx3G )_mDg_P'g 8 Cd* nzۭ1UldyψB|*Ji&h>#eubPL ˮNe{# l\u ovEM`TZjpKdS9 ʺZZ󛂤[j·Nܤ_.&]@-k+Uыx{O u}ԏ{-KHwv.ŌZ}L6 ,Pk5RPQ?Ke"8`D)]wXn#)݉h/_$B!Uc5],*KbNLn* ۘFuN?ؙDFu~ҠhĊ5QB9uWnU*QaUd'=HwU}%I<Q)OoSif+7hYWu*ᨾG}9zh6ޟi*S=zf6}zVDG"X^7^!$1!cc1BLW̠P\.GIxlA-[b\FGb ۘ( <hgC6N*~֙ *;R^!oȹ4B@!FFPAi%} vJH|+T GSePW'֖j8_CzJմ=>=*b>r37+UUzyE;Ys򴨌n #f^[^&"-MX7 `h=ø!Cc*Ppso8) [,5 p\A|ӨNb}WC1 Gbu7[MWevT]o%)󷨚NUf# ݥS{Aj3)vn }WHMZhf-J(*'Oij FŶe, L m M&G@D Ŗ8׆[OscBT\ F?l*u {d,jfWSTr `Kq5mBU^HDMQJ}y_1(j;8VFNi?ߕv{;2JPdyR]WeV[{6Su:"jEڌa A ̀z@jILN P BEzAm>dC,y:e 0 ZDÄd1X~[MAq|>vosu R=3,Ӥ{m,J7K=FJ p]]rjjoLTt ځ* *i0*۪q+vf=iM:tW#4FnZHoS2XK2:^oT5N#+oD6c~ZTCNr C(uFJy Ii,/J)1VV;~1E} JB>PbWb $߬eh.9h R b0%JZVɼ6JN VO3X^ԚoiHSѽa֙}9ڶ ۃ{4L*.A`h)jPB.u_5ݛhթA*x>bi[[IZ=@]wR P.,=|J(ƣ5fi 01PPlhvXӪWG(M&|;Ŏ>th\Qy1iHFaoѿSw,*/\1c Vo$[pDyߥMFn13]/djay>F{m2&zEesP8&# ĸ62ܟÌpqҨJgR'#fOBco>fi补uj |=@> zhQ:d*_Y+K5:o˷tԩOf=D`^[X3#=#l܎~PkP.Fl" 3k+sɰPR98à2V8bNQA: StaڇȲta+ҪթUOHyE{PЕHJFW}zGIs}vIYlkQzF ?)xŎ261JiB /Ci^fޱj5JYjR}OUxjjd 'XVXfPg*|`e:EjS-+-J}Ʋjh5HDDWڍ>KI ::R TSE\ޡEfp!Xm~>N;|ds`t3cBU!OرSbpD؄ ^^_XiuKJoC?-bGzMOg:}m2>R7=uT.VVCS㶡[K4U7Xqc4ڝ= &f<#^Щk` pV?6t;AGC~֔_PaͦZ1OAG Rz b2/5jiA^B6u#zn7@`L1aLWaz2ѿ.5|M%`RPڤ65-EeF' X\ΪE|;/lme gKkP,r>bRX8X_} za{Rm)x+'yF™_> }YfT{s \e "MLZj@\5`l0? *`7VhW5]Y<@|P9zoP;&D\o+#t7Mm٬ i~DfVZu69Ρu,ŴՏI9 iJ&%jT u)+Te[4EZ'̓ɟßV1N"۲8žbͦz=@Wrf~=ZLƦH'ei/vVaQQduS `Y6 CC E @mZvtV5]V+ije52/-y+S-2K;zJkS`^MR5pT֙W\$Oen[ZGxYM’Te`mlBQN!(QJVwWX6EI]\k{!‚K5]5 WiG܅="1M-ź^h|BX/ Rܣ2WAPǙ]\R+ MQ EQu13n Omٔ ڮ' J|'L~SI7넭K2RCҪajuN$ ?R;j1u:馦hVS?{+4Աt3=fj)ޞ2G4ۣQ+v_j>V@TS)bř.Lн4qj[BԨF}QVTB mۍ JzѥV\ogJ +[|SZS닋_ٹfY 56NRpllZU=g`}oHl@bmo=axGp?R;uȔ*R;V, yhY/J6ܤ3Wٴ)] Z7 紎-Dg&ITb"_9ooI3aqP%|ʕ.L^)$x6 [D 2-Ѓ*|#iUmR TMU#P⦐딲]ZT\yMIi)5Z&h?ٖ\!^-^Qh%H7ǩB$ԳRGK5 UHaɽ/4}vU=Gh1pͱ0+ɶfzܟmaiWR*3ޢioѩ_!YOH.iBW q6 pq O؏D#A7ذ>RJpEMϬ>-o"rώ2uP׊ JEGE 2i_Ċm*#.#[%>&vs. ¬ 9)>:cA[ )CYW8jU5J+f ZN*x߁yzBi .f_U_PnB!0^R F`majh˼YOT‘Q.Np`cUPǨmܘi}ġԠV𷩵Ri D,E tծ:ZT5!VBset$X"wb}Hwr2hLiӐյfAOPBp~Tݠcp,~cST l*ԹPּ A_^+  ۈQx]BE4.>`M54ڕj)l73PR^iT=D@o hJPjj͖=  NO.f&RCbL joJ+smnb5*Sjm_a5U<ލG͔ѽ)lLӷN֨ܖ}B+QuFߵnHP"jc4ui (p.p,䶥C1n7ӹ`f= JB"Uk >aOHyu3Lo`zZi7l[?*15X|h|S lz͋Gwq&ǥJ`6*g5ŘSmAJnZvUU){N}ԒO%o:bj{^GLzM} J*4֒PǙqs(WUB{)jjIU ABJͱ55+iҗ-LCU.pn7\ XMh\f/n4ڟieՂzCj@%mItWO8yZBEڢ6:z4odE<oUyi_? [#ҭ17yw=hfͺDe @E}քaA=S*=n`qkʋETBmX\;Ś J./c{+ԦnPg3ڐ`1+ϣkYyzE.Xt|l(7c?2 .'p Ԛm-`ZuB1jQҕV$x3V7[En{i5QZNj(5Qzbki5lU% >S5kl5&jvJEwzAPu!Xl%=#&QY";Um-J fwR_*R*eYG{cnUV}m7IIk_S{dQM(7O|YQ He8$@`Eѯ~Q,!3`6pL6b{Z ߬˛K%C{TTLξK  ؠ NzPP.iRCNS ]{ER\`) ` dmpqjiֲz,e%jGk(>rrMAh4s'jj}* pcw;M 颽fZ@= 2p 2fTTcn\}XJ\]ԝ jj(# JM73g$_R6S DS[ GW?SNekA06C!?j11 "nb'&.DlÑiv qܻr[x\:Y[E6iMS}VtWGDj?Puϲoog!JT96Zk'(*tӮ) S[T;_X.fqd|Li 8zzHNAfXo!)!UgU=1(v_e=Kn2|a̻6'0d`< tb(?]ߨm*jm_ W下JT@BS YiJyQEeb=3ʞPSRJ_>o%WaMҽc&tgoAhQmFVkߐۙp3hXna+8fKqcc2 SD y17Ȋn&ǸmIXa!Ǩ6B(a`U5wK%ɴQ O(a0d?93~+w'#2H{pV?Aǫ^g*nEI̙jAF()KuTolB^Ш͉lPL,ynmqcJE .A"@#Ӹ0g| flG7XI0nn!(ۭф-V|*n^kmiɵ@@&4SH筥 f'13mH4 d!bK,m/Pp;a%KRiP5`{'*/ /(!U7wBC2Xr|k Q+9L.X0l`g,E>XMɅHoRP%)i^LZ=s*1h:f/*(2-{GP`pi,e/yp faMs :Z2Lm~TfN}Lv| )REl%=gȟХ:I-s(<@E@# =ḨmvGA/a爃m`O[CPTJKN`;VE[ڒ0kz3R-ko(@/bZAdw (Yr nטI%^=s { 28.JX{@%ŁeQF6 ݋R_,5csqct0*?p>$"Ap/K XK/xn/݉`a&[tSӻ?v( AῩLƲjB&j)BU997Rl vig1TffI A!# 1V4ɻ8thiĆ[=&; -;!{TS@o(9.T[ȊIX˘LLAyR mЎ?;{69 j&{hYzGKb,OA}xwD)iS*SchFQ,2LW,oJGa=o_чH 0 >/UҒqe.5*gkcדY!]$# k/y8il:E2p0!T߈k0OY}`0h0w!2G<*"+[)񞧁5U}K'JjNI3GzCuVA5: 76P-k锓"_xA6/Y=atZ2=X0%JULpJZZKtS)iTXsʵ{Zr׉N;. ՗u=Pz•=aRN'֖ކ:Da ̴ q u~ }z0"@&Qq5l~LAnSeBy`CSSۈN>nOn}&nokHcy3pA߶\`=!LrM^%*Lgm%CǓ)ӧw#E}Mv&ȣ(%:"?80GCyu#KK:rbxX 0IoG@/ܓ5V2Ó*ۓMUQ]WOVgNzzRALu*FժIjPtQ`XJj8Q*JN?GbQ;#rn%EkyzC= {2Jr`&#u`0 􌧈Ay&bA'X,<ɔ(^ $h D-QPNZkEv 3ドUShoň nhuw^b^^TBejM̱oF`1OIcap!3m939 Ff79Jj9Y #EcUɛnq[pw($ #*6I67&D @y܉j/8{|CE'FS`0AOL@`7Z6s  =bHHe}E(0~U1#= h6=& R2Qy x^Tb%M8=l%B̄$EĸxqCzb1H8!i^Vc-)MbVOO*9cbbX^k(#s Yl:F&a(zGEf#(B~!+|^rfP^3bor?hPJ xhyKE>eǹ61XX@o݌/V6J􌨖E6Jn#pLVhT\Ɍp O 壓vS~ yd2vPa;v͵w9TTO1R5l}LΓqnEFfJL$ ve廈x/q.J㸊G1Xs#"H oei^VeD#8 ҍKxGۏp%lEdۙ=Ihdŧ{-W2FC~0*": lLE B5U==؉au?0e2Xa.C{v `p .@oA(/)T+8|JɴHu}0 ,P9mʵlɷ 8m䓑)v~+;K_X!G$E´Cէr Lʛ* ߨ;XGkFq2޼#TF^zehqiB@jJ5@n"H|@wxcWW'헊; D [Ģ0.V ^i4T` SY\*?*ZYǡ5qyJFAYZTJN.1Tdu0E(|㜱%YkIojf!-u~b%KDakM8~=GC*zʄc h 'KvZ#]J$nʬJn<ӰZB[Ԕ+(.+DaD`|?j=fW Pd^ZX\c2XxY!A<6i[@|Nn/q T5aYQBP.zN:۬S%0bSۙ͢-/G}`# N7Yգ}QԒveU7 `fw8+\AØ>ՙec)&/KzFlJhI79dľG4Q-5]H,l)ȞƱۋtYM֖m=X Xaa,pwϸ;x1RhN])5Q\X+9zʿH fnwnn6NZ,]kkZ6brm`!UR0&52J)ȰhdH \^8L iʔ=|GFbTe@a"9$!w wa#%4:5.}'h}WzhmPUSDj`}c"g6CRjPQo M:Z: x&9!g`- (:'1xbIFW ꒣Ҥ/ $Ǐu%,A.Ӣs7p{9v'З\@cXH T0xX pe2`Sc19f~ZLq>O!'Oq?ӈg K10fa- @ eAqoڙ6˘okK z4@ DǺ".sf}_xm= b~YOJD',A-m0ܘl ĉ⁌!07V &\˱̶g_HC3øACpf -%9a7'30AyAA;k˓6&X⁌!~^$a.]& Cc>\{\,\c\am-ya2E"I2L \ e ˠ3˷v wq/iDjn"AȄZcb)\s>?1!Y| 1 7"{b`4<߸ߙv "¬8 c!Zg90=ÜC°0_D$b_~ehZ2o!0)ێe `AɛL6 fK/̱׺{ikLg@dE`p!M& b/s&t{ͣ0Ysh;!a0ߘ- - %baP%6N2@هq92`={o26/v c19̷Ywc0;iXIaViec7s=ۄ.KֆBD! #/ " W/a M]DQb(.I3<^xA&֙"q/<q0Cf  ApDL˫M q )ctŧK7ufQs 6'Q5b:wm5ք0`0 X F.ywp#v;o6kiDJ9 =' jeaifֹ,AԎcløN=O#S Gbc2@74!][zw E(,9 [7H 2~>>x\!q^/%^C[ss16`0 M %O+ &ț̺F=cIŢ)91¨,LE )" @jB 0Mre;R Mf.SvXFXr1*/!aeBjERYj[jUbR`_( RL\0r`_1&xLx4Pnf_q<{+ YQi9SS6 3oBaWax˃ & KK9Ogp lK.g]D0ՏLvs掮JN]IۘZPB2O# 9n bh"8K70--&iS662_V> vCMGr&וk̨jqi&X|@7n3jZ1p T`/񙺈k #sX1VJ;^VXbBֹ?+3S"$J ı'JukzB#߈ä>PBGʁ*/aq>;h.8>ደ.`ULu?Z,6/D_OJG DJ?J tE"wwZ;{05&WP@Sum, U9 J݃q|M ca1@t qyAQ}a z{|T\fEQ)%-S5*yZDD@A(b%0(AOs;v1JQY+f+Hw5ª,fRihDXE=x{ޞ;OHQ/{^ydL,LOoɩ+"DEnB6y|GWχd]1HG<)V!oBŵ6&?L9Q Ji^PRV8<䬳Y|myB1ȇ隱TK'ZTȴmn٩?-K=,Lׄ-K(+jȮM4&$ŎX8"6i"ԓ~+iͩS"YeOԏj" )$&&21՗NKGGR2qN)Jz FFE^/eC8(MH ԐfT摧QR}u HHԒw ~T UL,ŹHO %%,3^-VHȡ]()s+K%蜟"jIIq=Y<{PX) Xq(4kKxbXL " 89 [ЋLR(tI544%Y|le^ŊB^$PLHlV,T*FlYbbI&HSQBeLL\a ?X)V"Ћl@9D(쾊ذ+(: fÍ=闾JCE -@i,X\ f+y(= XCB klYYcXd(iL袅ۨ2)1G؋/|d'ұy8E"X}s$K lB샍薛E=-<_DcC=|shR$"ђ+(So- *bHM6K*FhBdhF^|ˬ{%DU.F2jIR䋕NjHq-:ԋOJ5445DŽ.8*Ěbw- צGV?K8j90JLM ",R#3Ӣ:м%k^E!eQv_L&GPSM5]!xMpV(hh4$a݈Q]/*bbj8$!DX^X~QX$+g"{*+k$;%4MlXcmo ^V$K)dCRe+9'b/C#Ð䨲,,N؄9B{YLHQG~Q5>&Fj %<=a bÎ,R/ch鐘1 3h,M G;Sab8HiԶ=2H-,$OQذ/7C'I{hxt/FJVf[<&\,%5{[cyHiDɈ$"Q?M{rD#Tqf^-b"3Z\j+oz5/ݐ%efXBN5_el6^+#Qė#CӢB²&Ņ#o^+!mr8$X9͒|&Kղ"xI}߹(ذNN$Zk(e3g![az[a1z؊1z]oyYӏTk+{MԎzIbڿ:b1XAr -5("zn#(hҏ6H,P4AP!i}>Wp(Qb$&Yc=rBGI4ikѥMȞC[Dz BC$9rhͩ8JUV=qoRk(EHRBp%Ee11"XJdRh]*l$ bDD4 B%-5tY[,QGIt%a bcJE|CP^:WRR~I>G:[iONdRo46ԂtЛOzvגTԩ2Q܅@g:6'Ӵ}.KZ ;WCJ5(9WlqziIկGjk}N} B]6KM覩ІEa"(((x4$Tpv=IMgSˆׁʗ_rsgKzzzwlӕIKJM䖜#ÿElDH V/2ebe"Zw=6+^JMMM.=!Ƈ!HOm% bFB|Bbt6gU2"r~ȩ|5viQ2)B)h<&&X yCBi#uTP Ϩ~[,LuBaq(AUtq_ DWQ[48$"-mG_]4!ρ̾q/%2袈XMП T)Dr,bg5B, ~T6UE^f'B:Yy_$K$k}""- K-ض^/ .I>6XS9/}`"H|ؒ(q)}DYHl >ԓ,M1ĬYx}DBYHhT,d(:ɉ4V_q%cem'JLZLbe!<c)h !7E .v" pkgdown/tests/testthat/assets/articles-images/man/0000755000176200001440000000000014633374223022062 5ustar liggesuserspkgdown/tests/testthat/assets/articles-images/man/kitten.Rd0000644000176200001440000000013714633374223023650 0ustar liggesusers\name{kitten} \alias{kitten} \title{A picture of a kitten} \description{ \figure{kitten.jpg} } pkgdown/tests/testthat/assets/articles-images/man/figures/0000755000176200001440000000000014633374223023526 5ustar liggesuserspkgdown/tests/testthat/assets/articles-images/man/figures/kitten.jpg0000644000176200001440000014335714633374223025543 0ustar liggesusersJFIFHHICC_PROFILE lcmsmntrRGB XYZ )9acspAPPL-lcms desc^cprt\ wtpthbkpt|rXYZgXYZbXYZrTRC@gTRC@bTRC@descc2textIXXYZ -XYZ 3XYZ o8XYZ bXYZ $curvck ?Q4!)2;FQw]kpz|i}0    ##*%%*525EE\    ##*%%*525EE\" ~TQPA 1 "oD@DA@A"" F EEcDD7 " " j PQȂEh" "Tb((QA D*""UU@* "FA@ 4TCv"9@F "*(""#QDD@ADQv Wyr]KD@QF(55j UCv {>{/V"+"A L]^~CXh4D݀(|B_FRJLO>m%|Ķ7=]?]UW]:cXe4AvK;6վ8Līy.2<#PG OWxWu =.7d%ov-yDwn~SyίN೭^lkQ Fpbf7C@Z;B4~[$> `_8noNײt9Y}o0FW=涨3'^hy[\Rv1m(0>{Aύy5 Wb *y3c58(WMWk؇o6=:/}Y hD7( =S)Ǥ(gЪ댧;XGIrdZO}1nA)$[=Wmg]Ӕk_`zkW3Q35ԾcZPPM ( /LM;͙uK2Ãfl\IQ1+.۾]=sɍb T7H{H7TA dql˰x"zvGwms[RݡKʮ*z~c<UE@V( sUعPzGPe'4c^hp= |[p~lkPTQ@TCt_Gc,r5V|FͬkY֎=Sy"M{.͞H(( nDQ`7\o=G7^f}ݤrƮd\}_V7" Uy+EcȖw)yqw,J؛$2#afMlz7ͭDP ((YO4 g1qZpϤ{u-ܻA-+KgA4T{hn];y#S>Q`tFSҺXg͎Dt8f oZ E@ (cs q:K)wYQ6MH-o8 y'>syZҽOK0FsWɍDh@ )踼߈.v|Ӧ~ut$㳾Tj/П}X}#&e$A;㕽~~h (H?(pWuUI&.: Ef';ovvwjO=cgZ5 2 +įHqU8Ӛu\#VHyk,OC{]Y3Vy ("F9f+i=Ns>|vG-iD_h$[\_NzI" 宊rgʹFu~&ISowQ?0rOouH;n3:<ƈTAjnPC=24͉Gz\;L-Μ۩km/ɾ/{o//&D@ "㬧+[H}\`y+vdj5nizM?1As}v{u4ؾO{=sMZAvA%'^b52EDDD{}c|8WQmHˠP??l?I ־BmEͨA"WkO&R _f,'5{n.r:n7[oZwџX:AшDApU k+A7yq*Ҹ0pj{5nɆmfƣ2;dvlcEA& A '0. (WqYhr<4c7ܻ:!m{?3~u^<@"""""5kDžlVG_ +>UxQ)W9%RS,,ws'|zL{s?1 $#Pby5w},! ^vSs(%QYNʉk7[ݛ[A~ٹ4IP5`B9C4[Cwei +)vE4X>3vsBa?F:Q/ E 1#5tIW:JvԯyZCsf%VbbNV[u~^MjpDDֱ Q5P(6CD?.h9.:IbĬ^|΢PV#Ʌfn?/v́~~^lA"cZT\(OBuڭ,ogDq֛:[E_g7Ec,Oq9b $cX5"/v1xȴ6#62Ghdz\:@lK Hw}V/<؈֌hA0"FF N۵2? IJ=? 'AN,=qY9mcԞFQ1D`6|0kp Uzt2J5-d;,\b]uzx3ͪo#Z (yR*6ˏԹ#v;㇗eY$i|bnKvm`0DDֱF#CM."}*LT:mm wo\E+]'鯡c:QF5b5w5Z7EˈpHm9*> dv7O?5Q{[{w@kX#zXK^Y3҆Cˉsv? 6@q"ͳbj"r7ɺ7<#KkQkZDS[ k2 jPuYœWYpVeyK_5{u%gj^`cAs:$]-`G`pSŭ( Ej5]znaK*s[`2g F#֠G9k w!>RlS gz|oU`QjU!F`ئZ[/6ڀ"5cZ:xnN1MePT8ő2V:Y?\Hc;_On /_wWHuսo k֠K AiG"K,[UqlZǩrw%*,]Զ^ש;w5-FcX֠Q^S\b{\tTP>2_:R?OYQJg%޾~Lb%" k#TWg$9,Y6U2qؿct;/Oiyd2)']Yx]-Gֳ-&"#cLm$nV%SMeYpt/֮M d`ɺvư{]4.@Dj#QmD`Cc23>@^쯛{}~M6ʒ{}l*!<};e"@@@TDy[\\OR 9mko8E&Vưuzz,>wM( yxch2AjhsZt _5ac{W·6fU =}WVM QPxj#I+J;Ec2*$n -hڽs]7736D`[=gn?D8+B[9%4^#u&Zzʥ<2k%l#AG=ZZΞ3?w іtq<]9WCV),hcDK*^+bǖﶙ9pDGq+X?WXoʝ/Tlk45 yMrc%TEL}7oڳYNa (sSʦv6Dzbz-~MUW"jZ9Nh/GmNv^Gm" =#GOrOXReqZ:m&un [Q)W{7 WiI'=ܝObs}}^F D+7q\?Zls/sOᇮ>k'/*믤g~x/6}VȻ\]ek+_Id2Kx>uӻ=s9vhQŒ>\i-:K7{iXRMT`sܠ+h5QA珍|yހ~|r]n -pW\9UAA"  *5g0HGGե5DWWEDA@Db"#婮-:ļeY* h  zUxADDA@Aj5v'  \ڀ@A #ִj"AUQ9U6"" AcZ""(5 Usթl mM1a& Mpq=6>0B]2V[|)$g ޾a[:Z} 3Xpz̵v=0g+YoPgW|vXԓMg+._#Wsmf%wO!48g+8;(ǃMmsՄ(K~O#Fn?Ͳ>o`4Vy%ޫ]9\ G껐Rl l2z,ݯU`!BX??Kp櫯 H `B'tSf~A۵NL1+.^s'E'&a#F}Wm<ҷjDsl,erJ%qRcc U5 hR+~t% L% 3>lج5cf@rlNZhӪB8Mʢ940J.qsh7 IEh Tޞaxq!s*5[Zim3䦚bS*UUP5ew*!e{)Wz@L< Elg(֑V@/7NͮKVRG ]˞jHfUn9\|Ɣ]9x.Wȭ.}s͸Ev֔%˧-`G䞫k_v5dzeǒztt:;il 9m͂c!EΣnD`!D)0"*V `1$ZĬb@"&"bbah$+3 @&, DWv"@_-k6_K~O[ \=gqx`{zM*rܶ :ϛ&ks{=߆~.]KO|Ã[>x{>_C=[~go?7G]<_og>w[?K+{9{oc2Vf#$,$)WG]4*-#&fBV1 q($D2!"P@#1 2$03A`BzX+0vcOm[qMhO)\7X-ђm}7ZCodݦFi]h`hKb&&32&2g;|s9#pngb2}r^-,쬸?^͠*\ꮟ핚Wz,_WwXg^f-zWE F$;eyF1,{1%.؍YuV-ϳabC EG"qLO cCRJ[J.,dLaZZ\m6Uk0H5?ySL II+zOʓ$G}C*J?jl鍫6ftc\PnfÇeP:.p#Vɒ. t*w4~qDZk(Њ~jV@Z@q֩-š|\XwύVGgOreuxw7墎ov ŭZN@'S9._M ;[9oi?"wmez<]"Zh(UU5aW©)*4Ɨ-€~#w>UE8 B&[rq%#eO $82qe*{o=M&L]Bß[\p,#AuN.v`%sjk ;/<(sL'ga[~ݓ>bJ >X7E(:vp' ƸRø#y.\ߡ0^Mcwe]4}RJ9V,W8J}T\0mP%u%Ai# 5G~&ԳຣZH'X A|ZHm /Khʻ)SG5ÓRvr}|jUo5dbϰsvٚ-gH@OeI5酟=wp/e;+4Wv7Wmy#;M gnQL'2捞1601|$Y2.oUXֲ&H#YB=;>&i M^ u'բ\gUJdO-z|ڹLD,H` T72y ]fKA6V龱o^ḫ퍒X*܏Z7CLdvwl3FҐA}\~}C?,!l^h4kׄrYAo_W+?3QMbOR>h0 ORp6ЕoEa]B&ڝ=DFU}- |ZN䣉 f*<اډ^Ll{K5ܮSR*~}"y#!⬮-\:3Z lR3uAiRl8T I]٨€+Sg0k~I**gkkw:1)/_ci"C,L"'mp>' Kl45q%Գ$Rho*Eu(+ |鶷:4T}C$f_n5䶮Ix"˘۳Xgfc-0!I~u򱶄HT,3&/۳4@Eq?>3dF]aQG>-SQ<+2_rECXG9J mqM NNW 6i"CVKE#2 c@\RxrZc=8}}__\V["9Α<)q&̖`DN0C,-YO$bR+f&=Jcr,ҕ8ȎЖm i}XCݥW!>#&J&q!idLˀ!\CYCȄgCS'}g"?q77@F/ЭLJ ",{g39 WUDOUc"N\6!0;Q\J_2ڕ+%`m5vzӍvLX 3<@ "J-3KE6VDerCw\17 PBQı<ܪc ~FqVθu>0 sNd[Y*l&M2UO;.32Y)%_W~)y%43s;fybh&r "$GO!hAZ߬.91Avai ٥gg fхjܻ q65|DAgf1]f-,!-,Nh^hvD:g<#^iVV! 9Zf> m)yd-ۈm8;)3q]E ݺmmk;]"n صCa t)b$<Ȓe+)ު%BK"kGXKFc?Έ_rt H l8 @agވ> ضl{T3`.}+]JYCIu#=Ö1败HK 0†fR0Be`K6JDsbӚ!6Q}#'7"}.5bu)5',0UI #xς:nލ]*5nbW; jnZb[‹Q܇ۅf1s<%ߟ\1bg2 hzgOE65Xz8T%#Wly"F!mOr3`1$vC}./צt˱XEjJuϢV7< ^'*eu\ŝ-ˆ,=s&*J6brC Y5 ")fc:=56,%<c cQ5l\,(J;eC"$v91"9ALNk0@dO 1\l+ciT(mI0v|pЭuUQ?J NçjSR`|$S"oanʢ"E ܥjB\N,N{$eM.$ض#YIR3,VSW^-hJe.e+΂߰aA܀?Ϝ`aU尙0~p}FIު^%*g@& s]¥@ذ5EZR7nï~̤֤֔>)E-d,[զPPO#iMEqN'-$66`bވ2$~_rBw99sy`H}e}hO"8,* P`תEFC[NGؙ7ĽevѻAjZz6ͺϛl\]uf$CYwoQYl,dѢ d2j hX;%LY,gެAfC)(j9s9sH aFNB¯%Xx8 VN ĕ >SD6W¶rޫ=A~c{kؖuA)de8-&6Q),lK+6PtݘA"WY;<Ƞ]׎K$YpZ{uOؘs9s9s.d8=m VdJ3R]eĭjnQ\g.4_)˔e.׹zR9`(M6M%+!WdXJ-A2:LJ$!A-DN_oSIg9s9sr8!T^/%Yؿ(zDCUWf#Rcń65a5\eSjEV]#>>BduU!gRFhzR1 0Cbd=c+Yc;PB8&>֥LTul> RZQQRLXapbU,x5[م$秊\J{FʷbeUf"&A*/]lk `0ؒ[2ԭP̤JTve,9s9s?ǜdd16![2X&?DOWn"}/6+Ȱ`,gܻybnVפb=kIr:SZ,E;3}h6卤a6 ]IFWWxZ )oH{x)ǜ2~IJ3 Ab%Vfu}bl7M&lkk6ا,DL ,^l5Wmt@ՊPCn"{Sal@ٙ'V^'NE?1͟4{>XfUSn*5f[ڙ Zr.U^\}r[ o^$  k^g#`J!C%!2omm, .?o&NK'-Aq6 "O2 ei#[skzԶ`O`$e QAqLm!׮)7f2uc,EX*nJn5`C+YBُ}ŝ~Sq0+TTe_oq6}y? g] $B<r#I@F)k.(hmWk1upKc$ aN]eA˝C6&uv w)ַjV"z&z Ky7f =ʐ1MΔAH&fbf y*ȏYrya̡ްv"+ nӚAOhqb|laţ)E MUdsr=d^|ًF@N[@Ƌ՚T&fNȚV":EIjڝbcM<ࢹIݷ01`0JnF!Rϱ2S^<|1wvy%RUZ#5? |~Pv,e XXCKc ܝ(7))a]Vq:Gȃw >lZ#\L?`,"g, 6jmVe5?fB :nƷvL il\s%X?RaV+ֻ8oh/&SյXu1,& L[FjaMd*pG5r-P)Uf$F%ɸJ-gs3+R9aLN2&mkeUqhI-B0{R,;Ckz6E R9u A{n@uۘUlOּ̫{"]YWH=UaA֮BukVkUaj`LS-Ef[hW`)ݷAINec9s(( arg]&\$,ӘbhEq BmeΗvkQZY׮":) eI;Vrj܆aP_g+VçK~6.ygq).ê-Y{Sm㓱^\nv(Z ǐwQ\s8̮2kzSq0Yb-b'*k_+5$Qg_ i XI=49's#K0Ĵ{ |q-%9&YG1{n9_T6O0xŴHC,*]bl*ܰy o"]TZ,,R/JN6WY&.gqz0SE:}8Ȍ8q&m7LZ`^>blyk9M";dHesX۞]0H- ~H޳363]snFeNױ Hhٸ%FMb 6&p䰒z6u\+R+` 2 s[p 3$  +eYi?+kˣKo%XMGnqr9LlA$8MCOcam ,`53fdS31,R}QK]\ su3 #]1WR'B*X2>AȰµͮrݙT=Q26<J!&P&Xʈ:S&7`>-ԛBq{& K3}:s>ʺab>j͆XJ'h9 a4Z0hC$qf3SeSݖ=,eϷ0 rɜE )ZK9|ƫPӁD#"FBc 2 sBXZCkOZL =U[?UXң\AV HMǗ{'uemyl#is\肈|dd&2*dxi G8ŞÌm~=zLWMCι83sM"ϛ6shfұ^U9``tz"bF{mc^qSiO+Dؽn9yOo|Z'fiOQig$bq?6-[υ\7vF7-wxV{5onC@Jڼ -e&+8hL}f+^1Xc!Q#:\Ƣmx;8PH2G$c=c,3Hޙ1XfN>kU+*^][)*1,* "8)ιx38qg\mH,yW-eK #jеOu]h*ڎW¬`xyk(xΛyJ<:mrR3?9o9s?ל99s9s9}sF!1A"Qa2qBP#R3br C$S`@cs?|[U荵wHp?R?of؜b0}UŦx]ęBׇǪc;KKswuuiD{Y6=Т۞5ePuWa2xm#.#CdkwV.$` :T6?n<u='qy>Iś+&jgx> pj3;vY* 'P;8 pas5"'Tkw7 A?GBLQcIɖm FC]tQ"z'puQxD"P`x/-[FiRS_+Ԩ&FF]f_k >v2~9D&*9,7ˊ|Ӎ;aq7ߌ&!UkUFKD v]y[ "mG4" )!E'eU]3꣼8˒"%$Zچ-v%Ibѧ|y;](Mq1qw皍΃M.q^3ztWLwֻm vgt |e&`|cCl&u} 0?izOx^ѡĵOy`3Nc}=OQ!8C;|\Cv#';P%QYZ.QNER߈X":?ě3$.Q|6itF㱟TTAٽ#0/5T,l@''tlV\)kz^ .BmidZrg6Q"Ph?RyBsT!ip"ӧȦ8'\&M%ߢ/P`ȻGȟo dsuDM}ߦB^zkC@kN5Ic@v9ivLu5^ r5Sp "hlW c>i+<;V7K;Eu ˿޳T_b2 e8G-qrt>E= 6=J{&Y#qA÷|4U@ʹwO7DNFqRiig `-r@^˲M 'rwϴaVRkir5Zdq<ԾV}ώă벸`&j4QI{!}!^tQݼy883(=a\AB&:jkL^To4^d7[](q2pFZ:TCsO¿52Y?xwX6NV0Od-glֈ/|HV~hU˧~'kc$Qhcߌi丨GݯNa&]A io ƢH jm>s .QNy\5VtE/i>:]2= !L|S]9mQv]3-Qiո9k4~ctj6b~Tz4y],8`5CSXq\|JYƎw'8F泩B'`dn:ƻNpts? j ԩw%>]K)?a##מ(UwO j׸|g>݀[v"CAqݜ6T鳊2KG"> s sXQhyE-Ĉ=9,(U> 9Ev txsFʘps٢IU#K+'Z"Ne ȣ#I!MR=9!p ' oPWАAsGBa"7Ħj t͊5jd$jyQ嶱D9N!:.]:v5MdOWju?a< N79 AF8'5[7~`]} '|7ڻPs{{O:z[? x.ha9쁕Μge={'KuA: Zz,"7\G*CvQ9փSZEƓiܶt cl8 cDgFz)8S\`]ZA꩜Ds2ַC & 3ISZ+6sx,ԬnUϭ.P-qtC-n̡%2g䎠G䁤 Ĕ׺M]τ|Tx m9yqLòmZ=PLAeLGDD@C Bfciy kG4G,=8=Ӂi73X=ISoL'*4ȩ&$ןScpMJD3zʤqkqa1N8]d3_h < o,b|P4#haѹdUi1|o+N Iԭ}W`+Vh~F8j|fҝ-to9,ynG1 E 6&ɝ6 G9Zk= X"3A13#6D=:E;G$ >(Ϩ[&m~?4k5qZ [FLy [Nd ''}cnw^tYdƫ!81 kyy+y[UINS`d պ`#泩_ܬUK%_g]Rk7^jtMiH ,4G[(T9tݕ a?Nk}!i aIK@eZdܕXBF=Θk[T:Q.#=r(tSu/'S}U :TϪya9!k3Ѫ\:Jwv֎n໨$&?u'GNt{KpVc@X>ȩM{;six:bI;ewר)1ȫ7vgb  ϒ9䋆:ss3þ2WD4 -sm-&:ye<#w n D.h'  z-wZ= y`-w44>)-MtX?&?>Xa%Rj1!9}5Uʎ`J>HnJ88ځs$GD{;vpK0U2 * G]Nuk?G N*&ZwwO%: +hn vaޑLm)"\rui@*C m@8Ժ0ot} exAW!̀x~H49)pOf;#uR<6"Dyu1ZceX5DVtGvce=#PUOc\wb0vXխcv`%PDÈ83 a+Z׀4}YɼX \pdd1=Cy8:c sZ$G3h}٤D:w~H"4h0jQ29'Qp;~Mq@  ؆`C}S=Qhs !H_ƧnI#Q1?NyE޻Xz0hѫ"h4Am`9pQc녒'&B?4x <¶ 't=ϔ9ܵuX@1!;ȉ%m8p1lOAU-E*F'bP>%U}I>klzm%8.DaqϚ9]&v7 'V4iac(mT!&_D1WY5_?WsƤ7椏\Aѱ?s=j"^xa>Z-eNܡ4 "z\'lP@ Z9oI7|̦FO0ާDy,2lݝM9m#KuEx' ,uh݂NuGHcHNy L0 8* ?Aˋ'S-#"ݑFi i[a!07Q֎dʹ NOQ(BwGǡ'ᶋxNe p1vȵp3yO[|HMww][o̦LW'y=dC}pV8ҿYc}hG]ᜋ~82 o7D>j#M ʕf<Be`: 4kCGieYY 2a kn!ٙJN?! -ZgY*{;P殘!bs-m'xPApR˄i|5V磀$S?E뇒Ɵ`߄803 Z2iWԦ`k Ha c sm )ҳ? I|^ꁸ8V各GL'6nVʍĂnIR فn$._5J?ADwS.*x'q'ZL~4UuKzv8"~iELb=C{1s=LDnOA:) #mG+Rk{%(ΫKA^!:8D[R"@# q77஦Vsj"AR6?ܰ~hّ Clqۚ}U₃\OQ!8>*V~hM;h>h+:4!K9D>KU dy~j GI3z D55KY&>Dhzv^D8j?eh;A%SHučmdn1n;|ƅ`:+Z!p_D{0pG~:;8OѐAʁ@'DF$JdcGN%)k" i_T)AK$y}J7E3\Ep3\ ~Ϸ|O8~s<܀yn3r j$e[(hܹ(?"CCFGn^s ,t"!4nfQ]Fx!|6La )w GwGkioi4馨Ō'uTܡb]$k0z( 9(zO-T(΋EM(TF9!E+e]1SgkUi|– 8~&a 5};9m;x'џ'uLX tOm7 k]CҜжGYpTvW9\5IM]>#U4_T}@T7:hW.aZ\cӒt}6'g- }6!v"wr+45htꃇ  ?f+(jRXZAEa -ܮ.=[F6ӪD,(~v" %Jx7V9v䬪lq͎}z!\ `ÓBn;tMez._BZq'nN gчt<ky:sW޴;Pp ^idB-PJ.:,dX%C3CĠ7o/] k?@k?$pxNɭh+ O3N.v~0$k6GMu8.#kT0 ?|dowIJ4lS{@0~@t;l3͇%کwZ-iڹէ֒>~ o4{$KڱAhu2ɏO$\<ܝ:!f`X#E ~J0b)\L*HX\Q)ZTx޾OE/U n:1>qAgxFmX$éG!%3>o>>>tOqʩ*xH0 AeL<*7sOnTjWu oOXjS .iF|3VSj4Kc`/h Kjm#1?T`߆~!~ŏty#/XeT|.?_UŢh걪S)iGۄs#g3: n50 WFct|_KD*i}-ӪP8]j_"e1i_A\tvDc#"E2sAHVf;?ҝWA)(͂8\A[ x|x{ k\x5-|ԏn$ X_; ۊ,/58Z@B C>2c|EJ;YWxm>6 ;PcFָq*.LnSs0rAUli]<˒sa!Fr>P$ƆSY]SkoSwIBs<KP,өO\5GQ?sZnGMS2ٝv?zH>[Nz-NUniY,%V @ۮ;K~}'n}=\m vq!@s+08x8h.* %xpZ`6%m"H5 hVΉn܊twy]QLMh8T]!۹! \u7TpkLftQ i&5xE? UPpޛA] :${ MAa.TeJ:DWemK\zDkb6HFE =y&i&p:d&=NFD޷;_B@ʼCP4Ih`)C 3W @)*e5=Pqo]nҦIG$\) Бh0N.O!rCza$i~Jw2L l:ZUsMhs]H,>u{m n^H5Mm[0Okݼ;6U{=jp{#:\Ҩ4A眅Tՠ*d{F8'57;xc1U@x]CHFoE+Vdp d5q - 5R{;Z:#eW4b& %I!R_j]xGJ?.$6@8 27֖5) 7&(?8XovL;Np"^b5OK" dQN ' |g wZ-UݚNeG#-Uic+^sxEԮ:Cm}G$Ca#MtsM Ntkٱ݈CI^*{#UT"r5k5(I\"J+U3ehЏ݁("n"WvLpK4k䩽xӞ[hپ)$j-'.jGsZ&n'L&xu͍Ahտw8p#L?P2A>X폒@pČnFR=kioG6tSHw\鹜+/Ć8dKTn\qi80s?|ƄgZ}ߢaCc`t+-ROEZZDP Bc ~(o<CW7(iXTpFo+9!^aWdGp@8d[m1Nse`uN]w:(Teg#"9/OAeJsBqu"Fmzwj1̬i [ts[A8j-wgg@]ibfy¸1VZ'Y2 Box!a&T-Z#O@fƜs6 T5 GFg`UJͱ<9UR^91ێ"0XM^A (hmZd@$j1#`8Bvr-hmv? 86p@HKE81w4a{HG1O0׶iy'6CZZXsJecQpQ\9  T8 ~%mlj:O5 &V !(Oz}Eʻ/Nj#4ELH(t'v`9]r 5r_o,.!7=`1D_~4uZ]t)\ *{/x0zS择8OV|tEz\Gn0SCSK/alƕS9M{U杜T۴}P p!4@!e4 e>R?4'AȎJH'}nv a6iQ.iDXU)fע 8_ɮ9d1ƪQXzmVw ʘ@2`,8,7V}P<%C7 `΋!)Ftjo9#Z߾ǪgG"N!;*h_1㎕[$M4~-Uk1kxsSDW'(?n8w-'y9;V\N=JnjtvӉVd!y)pioeV|Qy"ڲ҅% \71C % {Dj<逿֏oݎDTsYP`Gy P?'Tz.5q)!շklA4羈i3th}3]@iʸϯ5Z-8{Lo~Xh!Kͼ)~m?cZxi]a$s[l[{Nz.p捭\+OEdabUoZq貚3`3j?A8pSTO1*@&S{*F:r tkIXjƟ%W1[*-3jbƇBgpٸ%5 85cFr .Z} 喫Ki@8IQYV9 @:m a"ZzZ)!rN2G{ F-vҏ)M$2PcN]z.hcU$9J}Jcx ! 2D(K95LwYfFQū>%גsA әD1({-PV%h[hS#{5Ѕܼ\#p#et!2 `9ʨ)ԣR5Bp: 訢VO4Kϒ NN-kBˣgG>i U)\9P&©ih!?ѫφ$7Tg ծxH^!\ x'6w䆡 H j !`&42ri;(f6L=c s_S=Q($Ϛ`nzXщ$. mULP6?cQ- hO*x<($;G)Y)Zkg>EYQBLèRܷpӺ{ c)2!~9F;HɲUnkP?(?E- ݦ" aW[2¨~EsOTliObe*= $F5zU GDZtENkvEm8(HMnB/G+%`i)ĦϹ2ZQ8Zu” @ 082P:_o ӣCih5U^!QRSɻ.qBFŽKN$PkQs<;E8?hMq~F+䨔@ a9ϢpĎyp4h70 iS;8D pQ0zaX?gA#-5Hגo6Eahe0!> "D#D Z,Pvд] cdHU4J[:iП?![Uy9 NdǵHxSU>!Z KvPjC !zYDGN&4'?aM#Dz[ Y#Dž4Zj!>SFL  o2'( :1K +*[ P'%jA-v?c5GiZt(ۑ[5Q, C*ڇ1ݟcyg;Ear讥\4Rʒ9G2?0 kE/42g(P>)EJӋOV{*hui@GXY0ZcwB'uH{Td,KMnҿipS a7C⅒)kjqnr&JhMPq5$ ,k‰qD"CчJOTB6NrV>^Z-r$$IdZ[~K㓔9YZG%۱‡cslP nٜ8)nTgp ESl d|Hdt*"\=V\'CB h- XX &6QzqdثcEw=v \NJۂ$U;rM{ vVN@Do]ꅦ9eg5EM2 EDBl Q62ܠ+ Os钪S3.]p˓( vwD'Tq+<^V\J:j7š$9@2ؕáVQmHX٢삹vS.SMVįJ7eV\9!GiL++At[ n4"d|K>jXn>yz?fEhZ*A`즴87ݤD7)lmW[u3.<>W*!1AQaq 0@P?ǯ_ge,گ~L?RJ+~|ԩRW|W|T_D_ 5+COϊ*TRJ+TR|J*T_Lrj`ƅێ!\"qI*T*'¥J*T_Rnc|9(Dr1t^FÓ<˗寸 rPw(CQs\Ce~*WJ*TR|:~XdFٔWOʕN0~bMuU @T'qIsD1cM3%a'H0{-"+&g8`h0@Z-[-R_jЂC܁YgyE䢶) 846 @Jh11{%GUEXqvic*s:@hǓk$kULE/գ^awȽ]%)'d @JX`T / 0R4׉ZB/(eUe\5TXj2.ͪ1[ s02!V[{È6 +ia/Aĵub \+MB} އz`>}(5/y%g;#4?7 ӊkP \ $V{Ax/n׈j}#̴,) \bRHkG"k U^nRZ4>qFK)³B4؀Y@Pe_L⠝c!p߰Īb#AWzfUkϾ|AȀS4CGR^a^$2R咺4q|?0>kѮlQ6_JB֗쐲;*Cۆ MJ䰩cܤ,`0!#Z5ٕ$=%{U!X!Y!mDO5C/#$l kn q\-t3O-S^ЃT& <Gs'%&Nzfs Z8?i"XjyieuB̍6T[~ G]d2$lK~<@CuxɄ ՔxfnU 9kX[#qLZnf?d>7I@IAV36hY#{0yU(!:bSc;`:K{Sx@bqR mN4 WF.8Y*jy"5V0Mlr{1_IY >ڀ'gx LSq2ZУBV~,-=F@^ lhIG,!x?cEebpey] q`tkŖ@U^YF`Q3y,z)U+&=dAp#d1P{Q2l ib-XIt_`f*^WY)Gcϰ^A8.S7Zf1f=_WмӜ 4-c -W~̄RVڱz#@x1i5@wTJf-U腏0Ѷi,|t5-V/Y Z)~+=k54, * pbP8}O- ۟au$2*ĪH5q` 4)Tc (}aܢ %֫ fഅnGmnY",XTVE/\Jk*3bK{p¯&Q)n X i.<P0̐EW/VKR7bOd+I[9*(ZG{w}`d)#5e(%4vΉtBsruA[ wAhح*0qGeFglJp(%We׶h0q梣k' b!;<ADRѮ7XXt!B#]Q Xx*_4DFs.u+bQ%ucgJ穙Z,{m+VT(bc4 F0$Oy>01΀Sp":g,H56yȞ 2CO'~rϒXu ;(Jɭ'/iskODh:aj8wZ.OK x}V6b~e(q譮^콡 Јjwg/x#29l47^S4.:;NpJ4#d|ffDf.*5 6l^`  1~n_|˱E:Q+l7͊ԖxS!FIvkI1k) jneZ::ΏZ5 z25>|[r=KUWEi (d?K /ưy>e!ڥאJ-jP%# 7(r]*eP4Ah9`\! !pFJR}!+Zۦ9mGo+V8F & _ihYdzL$Ͽ;2=ăs4HY +X?i򨚅g<]f^J)e  >ma$tٚIH P]n KvAOh: @J=p*Dܲ9"LBB3XTiTL.c0H3fmZ6EXuܰq0[֍t}3`1j.G( eUTcN\1ꀸ:OF^X)t8 &U`4@_ba(*~ܿ*87ѕ]+Մ@WT~\fp1^!ո<S (F9{d#(0)lZμybBڌ[bղDfSPPUR]PBLjSDhsz]䦏,ѺaĪS釰=S:YTd%c v\,uw0cd|oPڃ!LX@<GAsPb(VbQOi6*8k,dշ!fLHN7/'Hm,P 䥟pd#{ ?5Uj!0`J[Ml yfb) L[*(UQbPh)|5EywSxR 2,AʣHt 8ZwRtT$!XRiߨl `x@[cX)V;J\+3ƪ t 8,_,c~l P)JnDһkP7+C:ctV$TcٿQy  Zq,$6)1n|@~Zqbl虅J^Ս)#8.k"I`⅄ ]ljjrU0)Bo(mw3L7edD/"eCw%ۆ#J`ňWDJX\{gf‚")4ėA7×lhU;`/F?Y@0Pū5p=CCwM~hxR[hot)1V* pVhy2vU}=Rw|&Lo [ #BoIJ٠ݎظ_fe :}hFjoEwFG p skt\Y|W0ֺZ<]FmU4{HzU[K@v&}A6D`|`cA^ۯ(o;rׅD/KIh4(О"78GC1o jhSQ&OΙ &tc9, ܨcbcLQv& !u7L =n`b뚁9ol])a g,MPeVy pX]!"!Q_d:Wf|q+xJmRb MmKbg PeEt%Y@[WPV PaG6E;Xc1+HQU[R"A"eTx/ `@V 2Z؄LMY:a´ڎKq5IF:Tr/L wQwAȸ`xGϝr.:Ϙcjny [ E<:Ǹǃ$™:ec9f_ڼK&ع\ D|?EŮǠ>[~Bv, 'nП))\h9~e vҀf[)zp%ԽP8QXXJa^~R;Xa%!Xame,]eEnGc JbF}&ӭ%$ñf@k'f(oֽϻ!#|.8]$)We)#` -r^vY bRg/G鎁N&۴rÛR؛`r"ʑ^_,LJ$Ox )ri{fP0FݿDNХotE[x1V*jߘ9}us+?%=~ecШ_jDw{E t=pLQ5i+RǁD9/Hl˚hf ꈴho'a^e2YJWCoyXL{"dGڨqMca9` s,CdcA0J6H𦖏ҶyEYalش 5eKfkelUY%S^Uq W~~ ezQ@8%]B;P729rĹ.|0ba\4{b gs8`/U .:ŀvBmYja8V#(l+<=ķ`' k>9Iחh|\IJ}TH<֝GaؘP[IǦSy'$eB- +ehtКjv) ꣡d>*e*ʚgM@mC+ɹXu v>"/bTHi)mw@Z+:@L?@ i@DKp}_Pۿ }FECQx:^/\ }Y5JVkBޗ -c0]t&*W_鍊% c dC|BI[6oq5Y F-*b|FO]8K+F 6a-orZY,-zb+[=%t%S&4_ǔaeX  T+7z'uDXZ'׸z];V0%K K(xqu%jS冫\k/%\MpqْO]}2Vp/`+F9 uEh~ [:0oVz$ L;+3iP ʼ^q%J ri"񺱍 `vQc' ze>bwľ̥oܼ"|bg/YA^ h hKhɉ%Iد_͜l(" ps |d,,/\GݪނXǓO,X-P:9/&~<a( w?ңR9i*˦X9{ccJz>) j+ה" vVhSPLS v>S." 8 q)28%Z_C`>mG %֍)ZT4]8M㘰̵ hȑl!cuqM=yP-v{>o,v p ø@Pyn;TpMk9sU&3|-?ʷ(@ADK!̪Z0 KS y& VbV--6<4y>a7CXD"uVฅQxD! !f)f'gFnEG MspPN _ea u|$i QFtj^ [c{MU4˖pV rb2A"D5_ZZeEŒ),в=~K=KY|#0UJP=D!h5 NLƒ8b;\x8r}{\@8pq)0&&ڱπ/CFusq\@[GhWC .s ay]A9Q- ť׷Fd5S}싀v.%ȯ6#@X5M|IW0[ ,ip#c`xqRs42t`({Ƣs Vqth-"я⬛ļTq ZbTFaykÄzaa$("Pb?U?_Zcj.ħ7TFJ+Lxl>^'%x ;C%Ψf[  WQ -$1Nn2{#)(LA1.eWh<0r~CzjFU6BJpS(z ]leZlRRlS0.Y⚎Lan3ʆl+el Lv3Zaśl͑sz4J aP6&/}CW]!WG2^`ut>2D –is^^y&HAzS \ۿEq6)P'SE8j qa7v f7S=%W Q@}BpwNJd(TǛdFBRa7XZ S Wqu)Od3'B®*Ij  # sܿRQ wș-r wz<$`6<'ᶌ0,oɀWp%@]!@l3M T$O#g|C+c~;U esI)N +Д§R.,~?j_g\.3rUѸ`Vm PN*0x "1)wp4+X0AwbI.1(%R3[ 10lGRmI*cQLjJ5_g\ 8EP ]Nj9Q8F-[ J#逡7a@MX8-AcrKtwij41ޠl ʹC"f PЌ0/q e3/l40R/_r<@?vոQn Ii{rnˀ{g8:fXBB|40W회OZ+ak^!{4hXm%IjyK- 5uɻ#MaLSqNV%ؠ'N"%Ff ̬5- "\^j"J2e2 {P4탇PXiG+1o4XByʌcHύCy.0'1ZIDPIb!)zN)v*)([">G E̳R?Vqfbn~ \` YkS,]5l-k˶ rzX0.19Y # M`h(k@1 D5Za_c?#,v)QNf[]0(/`lcB+93KVlLgA(z00#=ѭkgvXLt(/Hx|aʯ=ūeX{o}̔Efd1箆nHani*U~:l@FO_ޑ1z ͓ cRܢ2m sfZ0`_c"`j1D.809rࡶ2jqynad!JPhhB573/-]&,>&`>>N&&4x2Y`HH`0ƠBV pUܮҸFx.*c2*x($[9讔2L"'&pЭ8uA0[,jm"\1尿ZAR K|BKԮMԐ%~.\P <]JBuwIkrtED( O9F+6̨(3EJf 18MmZ4*i D!ۤ$#0p;@IgxUh9=33s2ﰐ8{DVh,4MH ^=ˑ"榊șoL4t m0?)~,D~$H'7/rH`5IUn?G4B#]{j/l]\Bw`e-1/C;%yh3gwl [uyMaup6^).pN^ C'{X282D^#}<QAHȮ5+Phᘄ0Fk(! kG!!6ۆ(^ N4"底A:8Xʂ#KPU$R7WX̑A 6{ca@-Ax?`RrzZ:*z==Y`@ށbcr J5eZ^GB Ő ѭ2?K9]+dE[)_>!yah*LaЬ>  @9 9 0b ]1Giчa2!&eI>KHdplR& 8\GO /_n.8%Hז`V޺d-}d/Jkczn%gWVHa?\C 8EѰp؜BL.V<1MzaױԢ%VвJG^A8mL\  &vHQM`3KϘLoc-4*w&Җ}W#)#20 eFP\wfLEa[ ZafQ3%DO7/4"1 vʴ *n $e#ce 8,XNhץuU2(t+ԙyBcutӑ#vmE5/ FY R ivøT?fSuEįdM60|\I3ae.KeԬy&V+isbJd &AW b1c -WY[03`NASiRn~UfD%*QP=3!T`={ uQhNX8d/y9% !A 0K[j1kDj <==*pĕ@ 3ټ Qc+/1W* BPAT>*' sPC?!ji&tRGFMAىQ+ zanNIIx,щR:ua$pab\ӓZ0Y[ SgK ^21Cَц#4dj8%P`=! ]XXƁ : EM.8Vx[(1?Ԓ"h;;Yg7+•7`Ԥ.eQflB,!vG2yk \~T_l"lLSs~qD(ȑ9k nC!d^$%TvMpዥp̭]f5Ŀ,!0ş*(-'TfpvlG\,7[X @-vm 7(}9%p1"V1O%߅ˠX,H*%1G 1"Mto~ĢƔbs*64%\bV4DcY6aQK(P- .cBJ}cHEȝtEg9yK F}^&QCs/ EtQ39nҔbz 0G$Xv&&n\\.j&J8|$DhbK**0"O`ei1Bj0p%˳{eקے+\$%ڷXh򚊍YC:`U@qCpQ#q9ʱ(X>>Ro(#VL+D3z<5Q%q I> c2bFcTG5}D\&cx+bsshRq/큚w2 Zؖ/Ln?$l@pY!1_Jq.GFk$Q`UPTflt@])CrΠH)oQRJ!cԩUb' @ $"3r%eX,ݑ7N5H3Y,l% ԈhJs dTD5uv# O=c@w]^ZNQ'3aWX*0F vmJNP0@~\4#^"U|^LJ_^U0F-`IhquTq:,2g*&RvY"azW <,, RpJ ?C4In )2$>H|oܸ?-8X\$F\ˑ:X;Yb)P xA|41/ Kڱjpd]⬐F@ET0lJ@*VR*L6@qGO(גV^J+Q'>H2TfWA=EUF@΍BG g: ekiHm?^UGV+dڤe\L/7;"v )*T_ޥ?2BA۞T,# kOs_GXP+#G7 J+~%6&e`4*AD p̚CTHu(@ qQʇ¶~+MϓYrr˗.\<%w.\.\.\.\X˗/.\r>_J%y\ZZ[1h2˗?/!1A 0@a"Qq2#BP?.Ye_ƾ|6YeY~,iYe_/ھ͚ID~1}G #(K2؊g'%rW,D d. p1jeVC_)*R?[-Zz"4-\T_9?4KQ*?Y2Fm~95c!v]W1813b vqiEϤbomVz2:=ei.JYBHݒ(^ʌ+&F$1! dR5yc?9A~c}W;U{fe噚invd[^'G@&Wsi>R8F!w:"i/W*Qj3N'&ISrMZ% Q(憞GJHj6bk>IfQ?-3I6M?j_"V]e'6&cJFm<;LMhhdDCE'\sfƙ4zˊH'#&Q{[}=S3Qۤ&H{YHOzENv?ie䒔"zY>ͅAyBn2bv)ms D䶿zv}JM6C-.3Ou&늤g`҃Qp=5ߓV,nW37+&F]2ͶOOF6f+d };>)#jr+t6HjFij%&mZ|0x0fQ{[/迳U%tzviYq>$yU2}c1_S9IF+ڳ}.)Yq+k5TĠ&Şf,U 3 3O!/,cWřԔ '2zN/&-KzFrK$Mu3w>YeGMZjfҢ1(1SY f6M2Xb"ZXiǿÁF\Q{#S\[mdp*jh)42`9_12U!cJ=lI$wlH|VY~ %$d1O m3+Bp3cmM6R'6h[ZN)"-͘frE쿆dL׸]YdhXvlUi$Ir&$h+_{Q1ߗ/'z7#re&Y /9Cd՚i~>{I8R$+&)q["id+mv;wbfr/⮹o䩍Q[*H&>I5I46_&USV[1I.L3K32N# .K|_d9;7#ctC&+go8IrFM3O߶4IS$](cۥD*uCHcTzx1MŘq Dpv5CIkII%E.l*E%ӿET;P"`eYeLqIG (ԈN b9$!!E~*1K2,DEQ*ĭ. DH|1Z(n$. oj4U&!};"H.fd&Чĉv7ծ%f(lkۘe>xculhl;eȟE4U$$푔sXؤ3w,OqB}T2VAНkY}-qe.!1A 0@"Qa2qB`?/]t]Wˮ?BܢzuAki4cu(N<ů}&GҒV*f,0!T̺X^C2N&Dzf~E=:G,S^`'?GE_َ8!bNŋ&Bm3Iw J䢶\ظcV%\L8B+bٶ(ƙ4woTD™DIu fPkɑMJbssH?_<ۤ(\YTݛ4d[vgIQ(+Ȯ3ѶfMS"+ɨJӦ&(P^3$N.<ˍSIQM5(Y3!E$g$Þm5XۊLMB䵑7iXбKO.In5˟V0($N)Rg&فܘFpBB4&IE;f=JY\j%wG,{Yo|mne:~? ry)O~_ũS[#ZbR_NϨmTO>+{4Mdェ"5X$k7.j1'%&iwCg㒓I0cPH&3ɸ$g',춣IA\#_}dO s|1_䋔/rEɪ)tQgcYOerU3zQTn(l줇}-*chKI1N- TH7BchB4>~ 0% B^mFE;ks$Vihnk)ǃ$j_ Zt'RC*$bHKCϑE"eh͌QE&E=hؕ&}&abl\rEwS"ѵy2I#O{茈MQvq!=d[bo5፶)}¤be2FXֆ"$2iGr>$ll:̑4QB+BE 9]^l[-L䡶įc[c$| DXB}DN}r->#rY.˲'u 2|(_g1ǢD5H=+G&D^,نJ6$Nt(,/8ք4!2D$鮫ً11Hd" 1FR&},WZ"s@-4%f;bآ,Lwća \ 6KJD#d"!fI;V*]eTc"o#ɋUC6ke"Rf6)Q6쮮H/݃c1Y6FԷe)tSHse[Fr Ǖ_'֌$2y7[ԓJIcLWTN/[+z!>fOk%4ENǝv7~WE\בLW^WJQEzpkgdown/tests/testthat/assets/articles-images/DESCRIPTION0000644000176200001440000000051214633374223023013 0ustar liggesusersPackage: kittens Version: 1.0.0 Title: A test package Description: A longer statement about the package. Authors@R: c( person("Hadley", "Wickham", , "hadley@rstudio.com", role = c("aut", "cre")), person("RStudio", role = c("cph", "fnd")) ) RoxygenNote: 6.0.1 Suggests: knitr, rmarkdown VignetteBuilder: knitr pkgdown/tests/testthat/assets/templates-local/0000755000176200001440000000000014633374223021324 5ustar liggesuserspkgdown/tests/testthat/assets/templates-local/pkgdown/0000755000176200001440000000000014633374223022775 5ustar liggesuserspkgdown/tests/testthat/assets/templates-local/pkgdown/templates/0000755000176200001440000000000014633374223024773 5ustar liggesuserspkgdown/tests/testthat/assets/templates-local/pkgdown/templates/footer-article.html0000644000176200001440000000002714633374223030577 0ustar liggesusersCONTENT ARTICLE FOOTER pkgdown/tests/testthat/assets/templates-local/pkgdown/templates/content-article.html0000644000176200001440000000002514633374223030751 0ustar liggesusersCONTENT ARTICLE BODY pkgdown/tests/testthat/assets/templates-local/DESCRIPTION0000644000176200001440000000042314633374223023031 0ustar liggesusersPackage: testpackage Version: 1.0.0 Title: A test package Description: A longer statement about the package. Authors@R: c( person("Hadley", "Wickham", , "hadley@rstudio.com", role = c("aut", "cre")), person("RStudio", role = c("cph", "fnd")) ) RoxygenNote: 6.0.1 pkgdown/tests/testthat/assets/sitemaps-schema-0.9.xsd0000644000176200001440000000771014634573316022357 0ustar liggesusers XML Schema for Sitemap files. Last Modified 2008-03-26 Container for a set of up to 50,000 document elements. This is the root element of the XML file. Container for the data needed to describe a document to crawl. REQUIRED: The location URI of a document. The URI must conform to RFC 2396 (http://www.ietf.org/rfc/rfc2396.txt). OPTIONAL: The date the document was last modified. The date must conform to the W3C DATETIME format (http://www.w3.org/TR/NOTE-datetime). Example: 2005-05-10 Lastmod may also contain a timestamp. Example: 2005-05-10T17:33:30+08:00 OPTIONAL: Indicates how frequently the content at a particular URL is likely to change. The value "always" should be used to describe documents that change each time they are accessed. The value "never" should be used to describe archived URLs. Please note that web crawlers may not necessarily crawl pages marked "always" more often. Consider this element as a friendly suggestion and not a command. OPTIONAL: The priority of a particular URL relative to other pages on the same site. The value for this element is a number between 0.0 and 1.0 where 0.0 identifies the lowest priority page(s). The default priority of a page is 0.5. Priority is used to select between pages on your site. Setting a priority of 1.0 for all URLs will not help you, as the relative priority of pages on your site is what will be considered. pkgdown/tests/testthat/test-external-deps.R0000644000176200001440000000070514633374223020611 0ustar liggesuserstest_that("check integrity validates integrity", { temp <- withr::local_tempfile(lines = letters) expect_snapshot(error = TRUE, { check_integrity(temp, "sha123-abc") check_integrity(temp, "sha256-abc") }) integrity <- paste0("sha256-", compute_hash(temp, 256L)) expect_no_error(check_integrity(temp, integrity)) }) test_that("can parse integrity", { expect_equal(parse_integrity("sha256-abc"), list(size = 256L, hash = "abc")) }) pkgdown/tests/testthat/test-build-favicons.R0000644000176200001440000000076614633374223020752 0ustar liggesuserstest_that("missing logo generates message", { pkg <- local_pkgdown_site() expect_snapshot(error = TRUE, expect_output(build_favicons(pkg), "Building favicons") ) }) test_that("existing logo generates message", { pkg <- local_pkgdown_site() dir_create(path(pkg$src_path, "pkgdown", "favicon")) file_create(path(pkg$src_path, "pkgdown", "favicon", "favicon.ico")) file_create(path(pkg$src_path, "logo.png")) expect_true(has_favicons(pkg)) expect_snapshot(build_favicons(pkg)) }) pkgdown/tests/testthat/test-build-home-community.R0000644000176200001440000000114414634573316022110 0ustar liggesuserstest_that("handles CoC and SUPPORT if present", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, ".github/SUPPORT.md") pkg <- pkg_add_file(pkg, ".github/CODE_OF_CONDUCT.md") expect_true(has_coc(pkg$src_path)) expect_true(has_support(pkg$src_path)) # And added to sidebar text <- data_home_sidebar_community(pkg) expect_snapshot_output(cat(text)) }) test_that("empty site doesn't have community asserts", { pkg <- local_pkgdown_site() expect_false(has_contributing(pkg$src_path)) expect_false(has_coc(pkg$src_path)) expect_equal(data_home_sidebar_community(pkg$src_path), "") }) pkgdown/tests/testthat/test-html-build.R0000644000176200001440000000234214131662734020076 0ustar liggesuserstest_that("Stripping HTML tags", { expect_identical( strip_html_tags("

    some text about data"), "some text about data" ) }) # links and references in the package description ------------------------- test_that("references in angle brackets are converted to HTML", { ## URL expect_identical( linkify("see ."), "see <https://CRAN.R-project.org/view=SpatioTemporal>." ) ## DOI expect_identical( linkify("M & H (2017) "), "M & H (2017) <doi:10.1093/biostatistics/kxw051>" ) ## arXiv expect_identical( linkify("see ."), "see <arXiv:1802.03967>." ) ## unsupported formats are left alone (just escaping special characters) unsupported <- c( "3.0.CO;2-P>", "" ) expect_identical(linkify(unsupported), escape_html(unsupported)) }) pkgdown/tests/testthat/test-tweak-tabset.R0000644000176200001440000000373214633374223020434 0ustar liggesuserstest_that("sections with class .tabset are converted to tabsets", { skip_on_os("windows") # some line ending problem pkg <- local_pkgdown_site() html <- markdown_to_html(pkg, " # Tabset {.tabset .tabset-pills} ## Tab 1 Contents 1 ## Tab 2 Contents 2 ") tweak_tabsets(html) # strip class for older pandoc compat on GHA headings <- xml2::xml_find_all(html, ".//h1") xml2::xml_set_attr(headings, "class", NULL) expect_snapshot_output(xpath_xml(html, ".//body/div")) }) test_that("can adjust active tab", { skip_on_os("windows") # some line ending problem pkg <- local_pkgdown_site() html <- markdown_to_html(pkg, " ## Tabset {.tabset .tabset-pills} ### Tab 1 Contents 1 ### Tab 2 {.active} Contents 2 ") tweak_tabsets(html) expect_equal( xpath_attr(html, "//div/div/div", "class"), c("tab-pane", "active tab-pane") ) }) test_that("can fade", { pkg <- local_pkgdown_site() html <- markdown_to_html(pkg, " ## Tabset {.tabset .tabset-fade} ### Tab 1 Contents 1 ### Tab 2 {.active} Contents 2 ") tweak_tabsets(html) expect_equal( xpath_attr(html, "//div/div/div", "class"), c("fade tab-pane", "show active fade tab-pane") ) }) test_that("can accept html", { pkg <- local_pkgdown_site() html <- markdown_to_html(pkg, " ## Tabset {.tabset} ### Tab 1 `with_code` {#toc-1} Contents 1 ### Tab 2 {#toc-2} Contents 2 ### Normal Tab {#toc-normal} Contents of normal tab ") tweak_tabsets(html) expect_match( as.character(xpath_xml(html, ".//*[@id = 'toc-1-tab']")), "Tab 1 with_code", fixed = TRUE ) expect_match( as.character(xpath_xml(html, ".//*[@id = 'toc-2-tab']")), " Tab 2", fixed = TRUE ) expect_match( as.character(xpath_xml(html, ".//*[@id = 'toc-normal-tab']")), ">Normal Tab", fixed = TRUE ) }) pkgdown/tests/testthat/test-build-redirects.R0000644000176200001440000000524114633374223021117 0ustar liggesuserstest_that("build_redirect() works", { pkg <- list( src_path = withr::local_tempdir(), dst_path = withr::local_tempdir(), meta = list(url = "https://example.com"), prefix = "", bs_version = 5 ) pkg <- structure(pkg, class = "pkgdown") expect_snapshot( build_redirect(c("old.html", "new.html#section"), 1, pkg = pkg) ) html <- xml2::read_html(path(pkg$dst_path, "old.html")) expect_equal( xpath_attr(html, "//link", "href"), "https://example.com/new.html#section" ) }) test_that("build_redirect() errors if one entry is not right.", { data_redirects_ <- function(...) { pkg <- local_pkgdown_site(meta = list(...)) data_redirects(pkg) } expect_snapshot(error = TRUE, { data_redirects_(redirects = "old.html") data_redirects_(redirects = list("old.html")) }) }) test_that("article_redirects() creates redirects for vignettes in vignettes/articles", { dir <- withr::local_tempdir() dir_create(path(dir, "vignettes", "articles")) file_create(path(dir, "vignettes", "articles", "test.Rmd")) pkg <- list( meta = list(url = "http://foo.com"), vignettes = package_vignettes(dir) ) expect_equal( article_redirects(pkg), list(c("articles/articles/test.html", "articles/test.html")) ) }) # reference_redirects ---------------------------------------------------------- test_that("generates redirects only for non-name aliases", { pkg <- list( meta = list(url = "http://foo.com"), topics = list( alias = list("foo", c("bar", "baz")), name = c("foo", "bar"), file_out = c("foo.html", "bar.html") ) ) expect_equal( reference_redirects(pkg), list(c("reference/baz.html", "reference/bar.html")) ) }) test_that("doesn't generates redirect for aliases that can't be file names", { pkg <- list( meta = list(url = "http://foo.com"), topics = list( name = "bar", alias = list(c("bar", "baz", "[<-.baz")), file_out = "bar.html" ) ) expect_equal( reference_redirects(pkg), list(c("reference/baz.html", "reference/bar.html")) ) }) test_that("never redirects away from existing topic", { pkg <- list( meta = list(url = "http://foo.com"), topics = list( alias = list("foo", c("bar", "foo")), name = c("foo", "bar"), file_out = c("foo.html", "bar.html") ) ) expect_equal( reference_redirects(pkg), list() ) }) test_that("no redirects if no aliases", { pkg <- list( meta = list(url = "http://foo.com"), topics = list( alias = list(c("foo", "bar")), name = c("foo", "bar"), file_out = c("foo.html", "bar.html") ) ) expect_equal(reference_redirects(pkg), list()) }) pkgdown/tests/testthat/helper.R0000644000176200001440000000656014641250500016333 0ustar liggesusersskip_if_no_pandoc <- function(version = "1.12.3") { skip_if_not(rmarkdown::pandoc_available(version), "pandoc not available") } skip_if_no_quarto <- function() { skip_on_os("windows") # quarto set up currently broken? skip_if(is.null(quarto::quarto_path()), "quarto not available") skip_if_not(quarto::quarto_version() >= "1.5", "quarto 1.5 not available") } # Simulate a package -------------------------------------------------------- local_pkgdown_site <- function(path = NULL, meta = list(), desc = list(), env = caller_env()) { check_string(path, allow_null = TRUE) dst_path <- path_real( withr::local_tempdir(.local_envir = env, pattern = "pkgdown-dst") ) # Simulate init_site() so we only have to run it if we care about file_create(path(dst_path, "pkgdown.yml")) dir_create(path(dst_path, "deps")) file_create(path(dst_path, "deps", "data-deps.txt")) meta <- modify_list(meta, list(destination = dst_path)) if (is.null(path)) { path <- path_real( withr::local_tempdir(.local_envir = env, pattern = "pkgdown-src") ) description <- desc::desc("!new") description$set("Package", "testpackage") description$set("Title", "A test package") if (length(desc) > 0) inject(description$set(!!!desc)) description$write(file = path(path, "DESCRIPTION")) # Default to BS5 only if template not specified meta$template <- meta$template %||% list(bootstrap = 5) # Record meta in case we re-run as_pkgdown() yaml::write_yaml(meta, path(path, "_pkgdown.yml")) # Make it a bit easier to create other files dir_create(path(path, "R")) dir_create(path(path, "vignettes")) } as_pkgdown(path, meta) } pkg_add_file <- function(pkg, path, lines = NULL) { full_path <- path(pkg$src_path, path) dir_create(path_dir(full_path)) if (is.null(lines)) { file_create(full_path) } else { write_lines(lines, full_path) } if (path_has_parent(path, "vignettes")) { pkg <- as_pkgdown(pkg$src_path) } pkg } pkg_add_kitten <- function(pkg, path) { full_path <- path(pkg$src_path, path) dir_create(full_path) file_copy(test_path("assets/kitten.jpg"), full_path) pkg } pkg_vignette <- function(..., title = "title") { dots <- list2(title = title, ...) meta <- dots[have_name(dots)] contents <- unlist(dots[!have_name(dots)]) meta$vignette <- paste0("\n", " %\\VignetteIndexEntry{", title, "}") yaml <- yaml::as.yaml( meta, handlers = list(logical = yaml::verbatim_logical) ) c("---", yaml, "---", contents) } r_code_block <- function(...) c("```{r}", ..., "```") # Simulate a template package ------------------------------------------------ local_pkgdown_template_pkg <- function(path = NULL, meta = NULL, env = parent.frame()) { if (is.null(path)) { path <- withr::local_tempdir(.local_envir = env) desc <- desc::desc("!new") desc$set("Package", "templatepackage") desc$set("Title", "A test template package") desc$write(file = path(path, "DESCRIPTION")) } if (!is.null(meta)) { path_pkgdown_yml <- path(path, "inst", "pkgdown", "_pkgdown.yml") dir_create(path_dir(path_pkgdown_yml)) yaml::write_yaml(meta, path_pkgdown_yml) } pkgload::load_all(path, quiet = TRUE) withr::defer(pkgload::unload("templatepackage"), envir = env) path } pkgdown/tests/testthat/test-tweak-reference.R0000644000176200001440000001050114633374223021100 0ustar liggesuserstest_that("highlights

     wrapped in 
    with language info", { skip_if_no_pandoc("2.16") withr::local_options(downlit.topic_index = c(foo = "foo")) html <- xml2::read_html('
    foo(x)
    ') tweak_reference_highlighting(html) expect_equal(xpath_attr(html, ".//code//a", "href"), "foo.html") # Or upper case R html <- xml2::read_html('
    foo(x)
    ') tweak_reference_highlighting(html) expect_equal(xpath_attr(html, ".//code//a", "href"), "foo.html") html <- xml2::read_html('
    field: value
    ') tweak_reference_highlighting(html) # Select all leaf to work around variations in pandoc styling expect_equal(xpath_attr(html, "//code//span[not(span)]", "class")[[1]], "fu") expect_equal(xpath_text(html, "//code//span[not(span)]")[[1]], "field") # But don't touch examples or usage html <- xml2::read_html('
    foo(x)
    ') tweak_reference_highlighting(html) expect_equal(xpath_length(html, "//code//span"), 0) html <- xml2::read_html('
    foo(x)
    ') tweak_reference_highlighting(html) expect_equal(xpath_length(html, "//code//span"), 0) }) test_that("highlight unwrapped
    ", {
      withr::local_options(downlit.topic_index = c(foo = "foo"))
    
      # If parseable, assume R
      html <- xml2::read_html('
        
    foo(x)
    ') tweak_reference_highlighting(html) expect_equal(xpath_attr(html, ".//code//a", "href"), "foo.html") expect_equal(xpath_attr(html, ".//div/div", "class"), "sourceCode") # If not parseable, leave as is html <- xml2::read_html('
    foo(
    ') tweak_reference_highlighting(html) expect_equal(xpath_length(html, "//code//span"), 0) expect_equal(xpath_attr(html, ".//div/div", "class"), "sourceCode") }) # highlighting ------------------------------------------------------------ test_that("can highlight R code", { html <- xml2::read_xml('
    1 + 2
    ') tweak_highlight_r(html) expect_equal(xpath_attr(html, "//code//span[@class]", "class"), c("fl", "op", "fl")) expect_equal(xpath_text(html, "//code//span[@class]"), c("1", "+", "2")) }) test_that("fails cleanly", { html <- xml2::read_xml('
    1 + 
    ') expect_equal(tweak_highlight_r(html), FALSE) html <- xml2::read_xml('
    ') expect_equal(tweak_highlight_r(html), FALSE) html <- xml2::read_xml('
    ') expect_equal(tweak_highlight_r(html), FALSE) }) test_that("can highlight other languages", { skip_if_no_pandoc("2.16") html <- xml2::read_xml('
    field: value
    ') tweak_highlight_other(html) # Select all leaf to work around variations in pandoc styling expect_equal(xpath_attr(html, "//code//span[not(span)]", "class")[[1]], "fu") expect_equal(xpath_text(html, "//code//span[not(span)]")[[1]], "field") }) test_that("can highlight 'rmd'", { skip_if_no_pandoc("2.16") html <- xml2::read_xml('
    field: value
    ') tweak_highlight_other(html) expect_equal(xpath_attr(html, "//code//span[not(span)]", "class")[[1]], "an") }) test_that("fails cleanly", { html <- xml2::read_xml('
    ') tweak_highlight_other(html) expect_equal(xpath_text(html, "//code"), "") html <- xml2::read_xml('
    ') expect_equal(tweak_highlight_other(html), FALSE) }) # logo -------------------------------------------------------------------- test_that("can strip extra logo from description", { html <- xml2::read_html('

    Hi

    Bye

    ') tweak_extra_logo(html) expect_equal(xpath_length(html, "//img"), 0) }) pkgdown/tests/testthat/test-build-home-md.R0000644000176200001440000000146014633374223020460 0ustar liggesuserstest_that("can find files in root and .github", { dir <- withr::local_tempdir() dir_create(path(dir, ".github")) file_create(path(dir, "a.md")) file_create(path(dir, ".github", "b.md")) mds <- withr::with_dir(dir, package_mds(".")) expect_equal(mds, c("a.md", "./.github/b.md")) }) test_that("drops files handled elsewhere", { dir <- withr::local_tempdir() dir_create(path(dir, ".github")) file_create(path(dir, c("README.md", "LICENSE.md", "NEWS.md"))) expect_equal(withr::with_dir(dir, package_mds(".")), character()) }) test_that("drops files that don't need to be rendered", { dir <- withr::local_tempdir() dir_create(path(dir, ".github")) file_create(path(dir, c("cran-comments.md", "issue_template.md"))) expect_equal(withr::with_dir(dir, package_mds(".")), character()) }) pkgdown/tests/testthat/test-render.R0000644000176200001440000000276314633374223017323 0ustar liggesuserstest_that("capture data_template()", { pkg <- local_pkgdown_site() data <- data_template(pkg) data$year <- "" data$footer$right <- gsub(packageVersion("pkgdown"), "{version}", data$footer$right, fixed = TRUE) expect_snapshot_output(data) }) test_that("can include text in header, before body, and after body", { pkg <- local_pkgdown_site(meta = list( template = list( includes = list( in_header = "in header", before_body = "before body", after_body = "after body" ) ) )) expect_named( data_template(pkg)$includes, c("in_header", "before_body", "after_body") ) pkg$bs_version <- 3 html <- render_page_html(pkg, "title-body") expect_equal( xpath_text(html, ".//test"), c("in header", "before body", "after body") ) pkg$bs_version <- 5 suppressMessages(init_site(pkg)) html <- render_page_html(pkg, "title-body") expect_equal( xpath_text(html, ".//test"), c("in header", "before body", "after body") ) }) test_that("check_opengraph validates inputs", { data_open_graph_ <- function(x) { pkg <- local_pkgdown_site(meta = list(template = list(opengraph = x))) data_open_graph(pkg) invisible() } expect_snapshot(error = TRUE, { data_open_graph_(list(foo = list())) data_open_graph_(list(foo = list(), bar = list())) data_open_graph_(list(twitter = 1)) data_open_graph_(list(twitter = list())) data_open_graph_(list(image = 1)) }) }) pkgdown/tests/testthat/test-package.R0000644000176200001440000000732014634573316017436 0ustar liggesuserstest_that("is_pkgdown checks its inputs", { expect_snapshot(error = TRUE, { as_pkgdown(1) as_pkgdown(override = 1) }) }) test_that("package_vignettes() doesn't trip over directories", { dir <- withr::local_tempdir() dir_create(path(dir, "vignettes", "test.Rmd")) file_create(path(dir, "vignettes", "test2.Rmd")) expect_equal(as.character(package_vignettes(dir)$file_in), "vignettes/test2.Rmd") }) test_that("check_bootstrap_version() allows 3, 4 (with warning), and 5", { pkg <- local_pkgdown_site() expect_equal(check_bootstrap_version(3, pkg), 3) expect_snapshot(expect_equal(check_bootstrap_version(4, pkg), 5)) expect_equal(check_bootstrap_version(5, pkg), 5) }) test_that("check_bootstrap_version() gives informative error otherwise", { pkg <- local_pkgdown_site() expect_snapshot(check_bootstrap_version(1, pkg), error = TRUE) }) test_that("package_vignettes() moves vignettes/articles up one level", { dir <- withr::local_tempdir() dir_create(path(dir, "vignettes", "articles")) file_create(path(dir, "vignettes", "articles", "test.Rmd")) pkg_vig <- package_vignettes(dir) expect_equal(as.character(pkg_vig$file_out), "articles/test.html") expect_equal(pkg_vig$depth, 1L) }) test_that("package_vignettes() detects conflicts in final article paths", { dir <- withr::local_tempdir() dir_create(path(dir, "vignettes", "articles")) file_create(path(dir, "vignettes", "test.Rmd")) file_create(path(dir, "vignettes", "articles", "test.Rmd")) expect_error(package_vignettes(dir)) }) test_that("package_vignettes() sorts articles alphabetically by file name", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/a.Rmd") pkg <- pkg_add_file(pkg, "vignettes/b.Rmd") pkg <- pkg_add_file(pkg, "vignettes/c.Rmd") expect_equal( path_file(pkg$vignettes$file_out), c("a.html", "b.html", "c.html") ) }) test_that("override works correctly for as_pkgdown", { pkg1 <- local_pkgdown_site(meta = list(figures = list(dev = "jpeg"))) pkg2 <- as_pkgdown(pkg1, override = list(figures = list(dev = "png"))) expect_equal(pkg2$meta$figures$dev, "png") }) # titles ------------------------------------------------------------------ test_that("multiline titles are collapsed", { rd <- rd_text("\\title{ x }", fragment = FALSE) expect_equal(extract_title(rd), "x") }) test_that("titles can contain other markup", { rd <- rd_text("\\title{\\strong{x}}", fragment = FALSE) expect_equal(extract_title(rd), "x") }) test_that("titles don't get autolinked code", { rd <- rd_text("\\title{\\code{foo()}}", fragment = FALSE) expect_equal(extract_title(rd), "foo()") }) test_that("read_meta() errors gracefully if _pkgdown.yml failed to parse", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "_pkgdown.yml", c( "url: https://pkgdown.r-lib.org", " title: Build websites for R packages" )) expect_snapshot( as_pkgdown(pkg$src_path), error = TRUE, transform = function(x) gsub(pkg$src_path, "", x, fixed = TRUE) ) }) # lifecycle --------------------------------------------------------------- test_that("can extract lifecycle badges from description", { rd_desc <- rd_text( paste0("\\description{", lifecycle::badge("deprecated"), "}"), fragment = FALSE ) rd_param <- rd_text( paste0("\\arguments{\\item{pkg}{", lifecycle::badge("deprecated"), "}}"), fragment = FALSE ) expect_equal(extract_lifecycle(rd_desc), "deprecated") expect_equal(extract_lifecycle(rd_param), NULL) }) test_that("malformed figures fail gracefully", { rd_lifecycle <- function(x) extract_lifecycle(rd_text(x)) expect_null(rd_lifecycle("{\\figure{deprecated.svg}}")) expect_null(rd_lifecycle("{\\figure{}}")) }) pkgdown/tests/testthat/test-rd-data.R0000644000176200001440000000442614633374223017356 0ustar liggesusers# Value blocks ------------------------------------------------------------ test_that("leading text parsed as paragraph", { expected <- c( "

    text

    ", "
    ", "
    x
    ", "

    y

    ", "
    " ) expect_equal(value2html("\ntext\n\\item{x}{y}"), expected) expect_equal(value2html("text\\item{x}{y}"), expected) }) test_that("leading text is optional", { expect_equal( value2html("\\item{x}{y}"), c("
    ", "
    x
    ", "

    y

    ", "
    ") ) }) test_that("can process empty string", { expect_equal(value2html(""), character()) }) test_that("leading text is optional", { expect_equal( value2html("text"),"

    text

    ") }) test_that("items are optional", { value <- rd_text("\\value{text}", fragment = FALSE) expect_equal(as_data(value[[1]])$contents, "

    text

    ") }) test_that("whitespace between items doesn't affect grouping", { expect_equal( value2html("\\item{a}{b}\n\n\\item{c}{d}\n\n\\item{e}{f}"), c( "
    ", "
    a
    ", "

    b

    ", "", "", "
    c
    ", "

    d

    ", "", "", "
    e
    ", "

    f

    ", "
    " ) ) }) test_that("leading whitespace doesn't break items", { expect_equal( value2html("\n\\item{a}{b}\n\n\\item{c}{d}\n\n\\item{e}{f}"), c( "
    ", "
    a
    ", "

    b

    ", "", "", "
    c
    ", "

    d

    ", "", "", "
    e
    ", "

    f

    ", "
    " ) ) }) test_that("whitespace between text is not preserved", { expect_equal( value2html("a\n\nb\n\nc"), c("

    a

    ", "

    b

    ", "

    c

    ") ) }) test_that("can have multiple interleaved blocks", { expect_equal( value2html("text1\\item{a}{b}\\item{c}{d}text2\\item{e}{f}"), c( "

    text1

    ", "
    ", "
    a
    ", "

    b

    ", "
    c
    ", "

    d

    ", "
    ", "

    text2

    ", "
    ", "
    e
    ", "

    f

    ", "
    " ) ) }) test_that("other tags don't affect breaking (#2371)", { expect_equal( value2html("1\\code{xxx}\n2\n3"), c("

    1xxx", "2", "3

    ") ) # additionally teading whitespace expect_equal( value2html("1\\code{xxx}\n 2\n 3"), c("

    1xxx", "2", "3

    ") ) }) pkgdown/tests/testthat/test-build-home-index.R0000644000176200001440000001173214671042466021175 0ustar liggesuserstest_that("messages about reading and writing", { pkg <- local_pkgdown_site() expect_snapshot({ build_home_index(pkg) build_home_index(pkg) }) }) test_that("title and description come from DESCRIPTION by default", { pkg <- local_pkgdown_site(desc = list( Title = "A test title", Description = "A test description." )) expect_equal(data_home(pkg)$pagetitle, "A test title") expect_equal(data_home(pkg)$opengraph$description, "A test description.") # but overridden by home pkg$meta <- list(home = list(title = "X", description = "Y")) expect_equal(data_home(pkg)$pagetitle, "X") expect_equal(data_home(pkg)$opengraph$description, "Y") }) test_that("math is handled", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "README.md", "$1 + 1$") suppressMessages(build_home_index(pkg)) html <- xml2::read_html(path(pkg$dst_path, "index.html")) expect_equal(xpath_length(html, ".//math"), 1) }) test_that("data_home() validates yaml metadata", { data_home_ <- function(...) { pkg <- local_pkgdown_site(meta = list(...)) data_home(pkg) } expect_snapshot(error = TRUE, { data_home_(home = 1) data_home_(home = list(title = 1)) data_home_(home = list(description = 1)) data_home_(template = list(trailing_slash_redirect = 1)) }) }) test_that("version formatting in preserved", { pkg <- local_pkgdown_site(desc = list(Version = "1.0.0-9000")) expect_equal(pkg$version, "1.0.0-9000") suppressMessages(build_home_index(pkg)) index <- read_lines(path(pkg$dst_path, "index.html")) expect_match(index, "1.0.0-9000", fixed = TRUE, all = FALSE) }) test_that("data_home_sidebar() works by default", { pkg <- local_pkgdown_site() expect_snapshot(cat(data_home_sidebar(pkg))) # comments are not included pkg <- local_pkgdown_site(desc = list( `Authors@R` = 'c( person("Hadley", "Wickham", , "hadley@rstudio.com", role = c("aut", "cre")), person("RStudio", role = c("cph", "fnd"), comment = c("Thank you!")) )' )) html <- xml2::read_html(data_home_sidebar(pkg)) expect_snapshot_output(xpath_xml(html, ".//div[@class='developers']")) }) test_that("data_home_sidebar() can be removed", { pkg <- local_pkgdown_site(meta = list(home = list(sidebar = FALSE))) # not built by data_home_sidebar() expect_false(data_home_sidebar(pkg)) # nor later -- so probably not to be tested here?! suppressMessages(build_home_index(pkg)) html <- xml2::read_html(path(pkg$dst_path, "index.html")) expect_equal(xpath_length(html, ".//aside/*"), 0) }) test_that("data_home_sidebar() can be defined by a HTML file", { pkg <- local_pkgdown_site( meta = list(home = list(sidebar = list(html = "sidebar.html"))) ) expect_snapshot(data_home_sidebar(pkg), error = TRUE) pkg <- pkg_add_file(pkg, "sidebar.html", "Hello, world!") expect_equal(data_home_sidebar(pkg), "Hello, world!\n") }) test_that("data_home_sidebar() can get a custom markdown formatted component", { pkg <- local_pkgdown_site(meta = list( home = list( sidebar = list( structure = "fancy", components = list( fancy = list( title = "Fancy section", text = "How *cool* is pkgdown?!" ) ) ) ) )) html <- xml2::read_html(data_home_sidebar(pkg)) expect_snapshot_output(xpath_xml(html, ".//div[@class='fancy-section']")) }) test_that("data_home_sidebar() can add a TOC", { pkg <- local_pkgdown_site(meta = list( home = list(sidebar = list(structure = "toc")) )) html <- xml2::read_html(data_home_sidebar(pkg)) expect_snapshot_output(xpath_xml(html, ".//div[@class='table-of-contents']")) }) test_that("data_home_sidebar() outputs informative error messages", { data_home_sidebar_ <- function(...) { pkg <- local_pkgdown_site(meta = list(home = list(sidebar = list(...)))) data_home_sidebar(pkg) } expect_snapshot(error = TRUE, { data_home_sidebar_(html = 1) data_home_sidebar_(structure = 1) data_home_sidebar_(structure = "fancy") data_home_sidebar_(structure = c("fancy", "cool")) data_home_sidebar_(structure = "fancy", components = list(fancy = list(text = "bla"))) data_home_sidebar_(structure = "fancy", components = list(fancy = list())) }) }) test_that("package repo verification", { skip_on_cran() # requires internet connection expect_null(cran_link("notarealpkg")) expect_equal( cran_link("dplyr"), list(repo = "CRAN", url = "https://cloud.r-project.org/package=dplyr") ) expect_equal( cran_link("Biobase"), list(repo = "Bioconductor", url = "https://www.bioconductor.org/packages/Biobase") ) }) test_that("cran_unquote works", { expect_equal( cran_unquote("'Quoting' is CRAN's thing."), "Quoting is CRAN's thing." ) }) test_that("allow email in BugReports", { # currently desc throws a warning if BugReports is an email pkg <- local_pkgdown_site(desc = list(BugReports = "me@tidyverse.com")) html <- xml2::read_html(data_home_sidebar(pkg)) expect_snapshot(xpath_xml(html, ".//li/a")) }) pkgdown/tests/testthat/test-figure.R0000644000176200001440000000123414641250500017303 0ustar liggesuserstest_that("can override defaults in _pkgdown.yml", { skip_if_no_pandoc() skip_if_no_quarto() withr::local_temp_libpaths() pkg <- local_pkgdown_site(test_path("assets/figure")) suppressMessages(init_site(pkg)) callr::rcmd("INSTALL", pkg$src_path, show = FALSE, fail_on_status = TRUE) suppressMessages(build_reference(pkg, devel = FALSE)) img <- path_file(dir_ls(path(pkg$dst_path, "reference"), glob = "*.jpg")) expect_setequal(img, c("figure-1.jpg", "figure-2.jpg")) suppressMessages(build_articles(pkg)) img <- path_file(dir_ls(path(pkg$dst_path, "articles"), glob = "*.jpg", recurse = TRUE)) expect_equal(img, "unnamed-chunk-1-1.jpg") }) pkgdown/tests/testthat/test-build-home-authors.R0000644000176200001440000001513714634573316021560 0ustar liggesuserstest_that("authors page includes inst/AUTHORS", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "inst/AUTHORS", "Hello") suppressMessages(build_citation_authors(pkg)) lines <- read_lines(path(pkg$dst_path, "authors.html")) expect_match(lines, "
    Hello
    ", all = FALSE) }) test_that("data_authors validates yaml inputs", { data_authors_ <- function(...) { pkg <- local_pkgdown_site(meta = list(...)) data_authors(pkg) } expect_snapshot(error = TRUE, { data_authors_(authors = 1) data_authors_(template = list(authors = list(before = 1))) data_authors_(template = list(authors = list(after = 1))) }) }) test_that("data_home_sidebar_authors validates yaml inputs", { data_home_sidebar_authors_ <- function(...) { pkg <- local_pkgdown_site(meta = list(...)) data_home_sidebar_authors(pkg) } expect_snapshot(error = TRUE, { data_home_sidebar_authors_(authors = list(sidebar = list(roles = 1))) data_home_sidebar_authors_(authors = list(sidebar = list(before = 1))) data_home_sidebar_authors_(authors = list(sidebar = list(before = "x\n\ny"))) }) }) # authors -------------------------------------------------------------------- test_that("ORCID can be identified & removed from all comment styles", { desc <- desc::desc(text = c( 'Authors@R: c(', ' person("no comment"),', ' person("bare comment", comment = "comment"),', ' person("orcid only", comment = c(ORCID = "1")),', ' person("both", comment = c("comment", ORCID = "2"))', ' )' )) authors <- purrr::map(desc$get_authors(), author_list, list()) expect_equal( purrr::map(authors, "orcid"), list(NULL, NULL, orcid_link("1"), orcid_link("2")) ) expect_equal( purrr::map(authors, "comment"), list(character(), "comment", character(), "comment") ) }) test_that("author comments linkified with escaped angle brackets (#2127)", { p <- list(name = "Jane Doe", roles = "rev", comment = "") expect_match( author_desc(p), "<https://x.org/>", fixed = TRUE ) }) test_that("authors data can be filtered with different roles", { pkg <- local_pkgdown_site(desc = list(`Authors@R` = ' c( person("Hadley", "Wickham", , "hadley@rstudio.com", role = c("aut", "cre")), person("RStudio", role = c("cph", "fnd")) )' )) expect_length(data_authors(pkg)$main, 2) expect_length(data_authors(pkg, roles = "cre")$main, 1) }) test_that("authors data includes inst/AUTHORS", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "inst/AUTHORS", "Hello") expect_equal(data_authors(pkg)$inst, "Hello") }) test_that("sidebar can accept additional before and after text", { pkg <- local_pkgdown_site() pkg$meta$authors$sidebar$before <- "BEFORE" pkg$meta$authors$sidebar$after <- "AFTER" expect_snapshot(cat(data_home_sidebar_authors(pkg))) }) test_that("role has multiple fallbacks", { expect_equal(role_lookup("cre"), "maintainer") expect_equal(role_lookup("res"), "researcher") expect_snapshot(role_lookup("unknown")) }) # citations ------------------------------------------------------------------- test_that("can handle UTF-8 encoding (#416, #493)", { # Work around bug in utils::citation() local_options(warnPartialMatchDollar = FALSE) pkg <- local_pkgdown_site(desc = list( Title = "A søphîstiçated påckagé", Date = "2018-02-02" )) meta <- create_citation_meta(pkg$src_path) expect_type(meta, "list") expect_equal(meta$Title, "A søphîstiçated påckagé") pkg <- pkg_add_file(pkg, "inst/CITATION", c( 'citEntry(', ' entry = "Article",', ' title="Title: é",', ' author="Author: é",', ' journal="Journal é",', ' year="2017",', ' textVersion = "é"', ')' )) cit <- read_citation(pkg$src_path) expect_s3_class(cit, "citation") pkg <- pkg_add_file(pkg, "inst/CITATION", "citation(auto = meta)") cit <- read_citation(pkg$src_path) expect_s3_class(cit, "citation") }) test_that("can handle latin1 encoding (#689)", { pkg <- local_pkgdown_site(desc = list( Title = "A søphîstiçated påckagé", Date = "2018-02-02", Encoding = "latin1" )) meta <- create_citation_meta(pkg$src_path) expect_equal(meta$Title, "A søphîstiçated påckagé") expect_equal(Encoding(meta$Title), "UTF-8") pkg <- pkg_add_file(pkg, "inst/CITATION", c( 'citEntry(', ' entry = "Article",', ' title="Title: é",', ' author="Author: é",', ' journal="Journal é",', ' year="2017",', ' textVersion = "é"', ')' )) cit_path <- path(pkg$src_path, "inst/CITATION") citation <- readLines(cit_path) # nolint con <- file(cit_path, open = "w+", encoding = "native.enc") withr::defer(close(con)) base::writeLines(iconv(citation, to = "latin1"), con, useBytes = TRUE) # nolint cit <- read_citation(pkg$src_path) expect_s3_class(cit, "citation") pkg <- pkg_add_file(pkg, "inst/CITATION", "citation(auto = meta)") cit <- read_citation(pkg$src_path) expect_s3_class(cit, "citation") }) test_that("source link is added to citation page", { # Work around bug in utils::citation() local_options(warnPartialMatchDollar = FALSE) pkg <- local_pkgdown_site(meta = list( repo = list(url = list(source = "http://github.com/test/test")) )) pkg <- pkg_add_file(pkg, "inst/CITATION", c( 'citEntry(', ' entry = "Article",', ' title="Title",', ' author="Author",', ' journal="Journal",', ' year="2020",', ' textVersion = ""', ')' )) suppressMessages(build_citation_authors(pkg)) lines <- read_lines(path(pkg$dst_path, "authors.html")) expect_match(lines, "inst/CITATION", all = FALSE, fixed = TRUE) }) test_that("multiple citations all have HTML and BibTeX formats", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "inst/CITATION", c( 'bibentry("misc", title="Proof of b < a > c", author=c("A", "B"), year="2021", textVersion="A & B (2021): Proof of b < a > c.")', 'bibentry("misc", title="Title Two", author="Author Two", year="2022")' )) citations <- data_citations(pkg$src_path) expect_snapshot_output(citations) }) test_that("bibtex is escaped", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "inst/CITATION", c( 'citEntry(', ' entry = "Article",', ' title="test special HTML characters: <&>",', ' author="x",', ' journal="x",', ' year="2017",', ' textVersion = ""', ')' )) suppressMessages(build_citation_authors(pkg)) html <- xml2::read_html(path(pkg$dst_path, "authors.html")) expect_match(xpath_text(html, "//pre"), "<&>", fixed = TRUE) }) pkgdown/tests/testthat/test-tweak-navbar.R0000644000176200001440000000421614150730132020406 0ustar liggesuserstest_that("navbar_links_haystack()", { html <- xml2::read_html(' ') best_match <- function(path) { navbar_links_haystack(html, pkg = list(), path)[1, c("links", "similar")] } # Link to exact path if present expect_equal( best_match("articles/pkgdown.html"), tibble::tibble(links = "articles/pkgdown.html", similar = 2) ) # even if in sub-menu expect_equal( best_match("articles/linking.html"), tibble::tibble(links = "articles/linking.html", similar = 2) ) # ignores index.html expect_equal( best_match("articles/index.html"), tibble::tibble(links = "articles", similar = 1) ) # If not present, guess at top-level home expect_equal( best_match("articles/bla.html"), tibble::tibble(links = "articles", similar = 1) ) }) test_that("activation sets class of best match", { html <- xml2::read_html(' ') activate_navbar(html, "articles/linking.html") expect_equal( xpath_attr(html, "//li", "class"), c("nav-item", "nav-item", "active nav-item dropdown") ) }) pkgdown/tests/testthat/test-navbar.R0000644000176200001440000001237214642014746017313 0ustar liggesuserstest_that("adds github/gitlab link when available", { pkg <- pkg_navbar() expect_snapshot_output(navbar_components(pkg)) pkg <- pkg_navbar(github_url = "https://github.com/r-lib/pkgdown") expect_snapshot_output(navbar_components(pkg)) pkg <- pkg_navbar(github_url = "https://gitlab.com/r-lib/pkgdown") expect_snapshot_output(navbar_components(pkg)) }) test_that("vignette with package name turns into getting started", { vig <- pkg_navbar_vignettes("test") pkg <- pkg_navbar(vignettes = vig) expect_snapshot_output(navbar_components(pkg)) }) test_that("can control articles navbar through articles meta", { pkg <- function(...) { vig <- pkg_navbar_vignettes(c("a", "b")) pkg_navbar(vignettes = vig, meta = list(...)) } "Default: show all alphabetically" expect_snapshot(navbar_articles(pkg())) "No navbar sections: link to index" expect_snapshot( navbar_articles( pkg( articles = list(list(name = "all", contents = c("a", "b")) ) ) ) ) "navbar without text" expect_snapshot( navbar_articles( pkg( articles = list(list(name = "all", contents = c("a", "b"), navbar = NULL)) ) ) ) "navbar with label" expect_snapshot( navbar_articles( pkg( articles = list(list(name = "all", contents = c("a", "b"), navbar = "Label")) ) ) ) "navbar with only some articles" expect_snapshot( navbar_articles( pkg( articles = list( list(name = "a", contents = "a", navbar = NULL), list(name = "b", contents = "b") ) ) ) ) }) test_that("can control articles navbar through navbar meta", { pkg <- local_pkgdown_site(meta = list( navbar = list( components = list(articles = menu_submenu("Hi!", list(menu_heading("Hi")))) ) )) pkg <- pkg_add_file(pkg, "vignettes/a.Rmd", pkg_vignette()) pkg <- pkg_add_file(pkg, "vignettes/b.Rmd", pkg_vignette()) navbar <- navbar_link_components(pkg) expect_equal(navbar$left$articles$text, "Hi!") }) test_that("data_navbar() works by default", { pkg <- local_pkgdown_site(meta = list( repo = list(url = list(home = "https://github.com/r-lib/pkgdown/")) )) file_touch(path(pkg$src_path, "NEWS.md")) expect_snapshot(data_navbar(pkg)) }) test_that("data_navbar() can re-order default elements", { pkg <- local_pkgdown_site(meta = list( repo = list(url = list(home = "https://github.com/r-lib/pkgdown/")), navbar = list( structure = list( left = c("github", "search"), right = "news" ) ) )) file_create(path(pkg$src_path, "NEWS.md")) expect_snapshot(data_navbar(pkg)[c("left", "right")]) }) test_that("data_navbar() can remove elements", { pkg <- local_pkgdown_site(meta = list( navbar = list( structure = list( left = c("github", "search"), right = list() ) ) )) expect_equal(data_navbar(pkg)$right, "") }) test_that("data_navbar() works with empty side", { pkg <- local_pkgdown_site( meta = list(navbar = list(structure = list(left = list(), right = list()))) ) expect_snapshot(data_navbar(pkg)) }) test_that("data_navbar_() errors with bad yaml specifications", { data_navbar_ <- function(...) { pkg <- local_pkgdown_site(meta = list(...)) data_navbar(pkg) } expect_snapshot(error = TRUE, { data_navbar_(navbar = list(structure = list(left = 1))) data_navbar_(navbar = list(right = "github")) }) }) test_that("for bs4, default bg and type come from bootswatch", { style <- navbar_style(bs_version = 5) expect_equal(style, list(bg = "light", type = "light")) style <- navbar_style(theme = "cyborg", bs_version = 5) expect_equal(style, list(bg = "dark", type = "dark")) # but can override style <- navbar_style(list(bg = "primary"), bs_version = 5) expect_equal(style, list(bg = "primary", type = "dark")) style <- navbar_style(list(bg = "primary", type = "light"), bs_version = 5) expect_equal(style, list(bg = "primary", type = "light")) }) test_that("render_navbar_links BS3 & BS4 default", { x <- list( intro = menu_link("Get started", "articles/pkgdown.html"), reference = menu_link("Reference", "reference/index.html"), articles = menu_submenu( "Articles", list( menu_link("Auto-linking", "articles/linking.html"), menu_link("Search", "articles/search.html"), menu_link("Metadata", "articles/metadata.html"), menu_link("Customize your pkgdown website", "articles/customization.html"), menu_separator(), menu_link("More...", "articles/index.html") ) ), news = menu_link("News", "news/index.html") ) expect_snapshot(cat(render_navbar_links(x, pkg = list(bs_version = 3)))) expect_snapshot(cat(render_navbar_links(x, pkg = list(bs_version = 4)))) }) test_that("dropdowns on right are right-aligned", { x <- list( articles = menu_submenu("Articles", list(menu_heading("A"), menu_heading("B"))) ) pkg <- list(bs_version = 5) right <- xml2::read_html(render_navbar_links(x, pkg = pkg, side = "right")) left <- xml2::read_html(render_navbar_links(x, pkg = pkg, side = "left")) expect_equal(xpath_attr(right, ".//ul", "class"), "dropdown-menu dropdown-menu-end") expect_equal(xpath_attr(left, ".//ul", "class"), "dropdown-menu") }) pkgdown/tests/testthat/test-build-github.R0000644000176200001440000000112114634573316020413 0ustar liggesuserstest_that("a CNAME record is built if a url exists in metadata", { pkg <- local_pkgdown_site(meta = list(url = "https://testpackage.r-lib.org")) dir_create(path(pkg$dst_path, "docs")) expect_snapshot(build_github_pages(pkg)) expect_equal(read_lines(path(pkg$dst_path, "CNAME")), "testpackage.r-lib.org") }) test_that("CNAME URLs are valid", { expect_equal(cname_url("http://google.com/"), "google.com") expect_equal(cname_url("https://google.com/"), "google.com") # this is not a valid URL because it has a trailing path expect_null(cname_url("http://google.com/path/")) }) pkgdown/tests/testthat/test-deploy-site.R0000644000176200001440000000101013634412136020256 0ustar liggesusers# ci_commit_sha() ------------------------------------------------------------ test_that("commit sha can be retrieved from travis or GitHub action env vars", { sha <- "XYZ" withr::with_envvar( c("TRAVIS_COMMIT" = sha, "GITHUB_SHA" = ""), expect_equal(ci_commit_sha(), sha) ) withr::with_envvar( c("TRAVIS_COMMIT" = "", "GITHUB_SHA" = sha), expect_equal(ci_commit_sha(), sha) ) withr::with_envvar( c("TRAVIS_COMMIT" = "", "GITHUB_SHA" = ""), expect_equal(ci_commit_sha(), "") ) }) pkgdown/tests/testthat/test-build-home.R0000644000176200001440000000202714634573316020067 0ustar liggesusers# index ------------------------------------------------------------------- test_that("can build site even if no Authors@R present", { skip_if_no_pandoc() pkg <- local_pkgdown_site(desc = list( Author = "Hadley Wickham", Maintainer = "Hadley Wickham ", `Authors@R` = NA )) expect_no_error(suppressMessages(build_home_index(pkg))) }) test_that("can build package without any index/readme", { pkg <- local_pkgdown_site() expect_no_error(suppressMessages(build_home_index(pkg))) }) # .github files ----------------------------------------------------------- test_that(".github files are copied and linked", { skip_if_no_pandoc() pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, ".github/404.md") pkg <- pkg_add_file(pkg, ".github/CODE_OF_CONDUCT.md") suppressMessages(build_home(pkg)) lines <- read_lines(path(pkg$dst_path, "index.html")) expect_match(lines, 'href="CODE_OF_CONDUCT.html"', fixed = TRUE, all = FALSE) expect_true(file_exists(path(pkg$dst_path, "404.html"))) }) pkgdown/tests/testthat/test-build-reference-index.R0000644000176200001440000001010114633374223022165 0ustar liggesuserstest_that("can generate three types of row", { ref <- list( list(title = "A"), list(subtitle = "B"), list(contents = c("a", "b", "c", "e", "?")) ) meta <- list(reference = ref) pkg <- as_pkgdown(test_path("assets/reference"), override = meta) expect_snapshot(data_reference_index(pkg)) }) test_that("can use markdown in title and subtitle", { ref <- list( list(title = "*A*"), list(subtitle = "*B*"), list(contents = c("a", "b", "c", "e", "?")) ) meta <- list(reference = ref) pkg <- as_pkgdown(test_path("assets/reference"), override = meta) data <- data_reference_index(pkg) expect_equal(data$rows[[1]]$title, "A") expect_equal(data$rows[[2]]$subtitle, "B") }) test_that("rows with title internal are dropped", { ref <- list( list(title = "internal", contents = c("a", "b")), list(contents = c("c", "e", "?")), list(title = "internal") ) meta <- list(reference = ref) pkg <- as_pkgdown(test_path("assets/reference"), override = meta) expect_warning(index <- data_reference_index(pkg), NA) expect_equal(length(index$rows), 1) }) test_that("duplicate entries within a group is dropped", { ref <- list( list(contents = c("a", "b", "a", "a")), list(contents = c("b", "c", "?", "e")) ) meta <- list(reference = ref) pkg <- as_pkgdown(test_path("assets/reference"), override = meta) index <- data_reference_index(pkg) expect_equal(length(index$rows[[1]]$topics), 2) expect_equal(length(index$rows[[2]]$topics), 4) }) test_that("warns if missing topics", { ref <- list( list(contents = c("a", "b")) ) meta <- list(reference = ref) pkg <- as_pkgdown(test_path("assets/reference"), override = meta) expect_snapshot(data_reference_index(pkg), error = TRUE) }) test_that("default reference includes all functions, only escaping non-syntactic", { ref <- default_reference_index(test_path("assets/reference")) expect_equal(ref[[1]]$contents, c("a", "b", "c", "e", "`?`")) }) test_that("gives informative errors", { data_reference_index_ <- function(x) { pkg <- local_pkgdown_site(meta = list(reference = x)) data_reference_index(pkg) } expect_snapshot(error = TRUE, { data_reference_index_(1) data_reference_index_(list(1)) data_reference_index_(list(list(title = 1))) data_reference_index_(list(list(title = "a\n\nb"))) data_reference_index_(list(list(subtitle = 1))) data_reference_index_(list(list(subtitle = "a\n\nb"))) data_reference_index_(list(list(title = "bla", contents = 1))) data_reference_index_(list(list(title = "bla", contents = NULL)) ) data_reference_index_(list(list(title = "bla", contents = list("a", NULL)))) data_reference_index_(list(list(title = "bla", contents = list()))) data_reference_index_(list(list(title = "bla", contents = "notapackage::lala"))) data_reference_index_(list(list(title = "bla", contents = "rlang::lala"))) }) }) test_that("can exclude topics", { pkg <- local_pkgdown_site( test_path("assets/reference"), list( reference = list( list(title = "Exclude", contents = c("a", "b", "-a")), list(title = "Exclude multiple", contents = c("a", "b", "c", "-matches('a|b')")), list(title = "Everything else", contents = c("a", "c", "e", "?")) ) ) ) ref <- data_reference_index(pkg) # row 1 is the title row expect_equal(length(ref$rows[[2]]$topics), 1) expect_equal(ref$rows[[2]]$topics[[1]]$aliases, "b()") expect_equal(length(ref$rows[[4]]$topics), 1) expect_equal(ref$rows[[4]]$topics[[1]]$aliases, "c()") }) test_that("can use a topic from another package", { pkg <- local_pkgdown_site(meta = list(reference = list( list(title = "bla", contents = c("rlang::is_installed()", "bslib::bs_add_rules")) ))) expect_snapshot(data_reference_index(pkg)) }) test_that("can use a selector name as a topic name", { pkg <- local_pkgdown_site( test_path("assets/reference-selector"), list( reference = list( list(title = "bla", contents = c("matches", "matches('A')")) ) ) ) expect_snapshot(data_reference_index(pkg)) }) pkgdown/tests/testthat/test-init.R0000644000176200001440000000415714634573316017013 0ustar liggesuserstest_that("informative print method", { pkg <- local_pkgdown_site() expect_snapshot(init_site(pkg)) }) test_that("extra.css and extra.js copied and linked", { pkg <- local_pkgdown_site() dir_create(path(pkg$src_path, "pkgdown")) file_create(path(pkg$src_path, "pkgdown", "extra.css")) file_create(path(pkg$src_path, "pkgdown", "extra.js")) suppressMessages(init_site(pkg)) expect_true(file_exists(path(pkg$dst_path, "extra.css"))) expect_true(file_exists(path(pkg$dst_path, "extra.js"))) skip_if_no_pandoc() # Now check they actually get used . suppressMessages(build_home(pkg)) html <- xml2::read_html(path(pkg$dst_path, "index.html")) paths <- xpath_attr(html, ".//link", "href") expect_true("extra.css" %in% paths) }) test_that("single extra.css correctly copied", { pkg <- local_pkgdown_site() dir_create(path(pkg$src_path, "pkgdown")) file_create(path(pkg$src_path, "pkgdown", "extra.css")) suppressMessages(init_site(pkg)) expect_true(file_exists(path(pkg$dst_path, "extra.css"))) }) test_that("asset subdirectories are copied", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "pkgdown/assets/subdir1/file1.txt") pkg <- pkg_add_file(pkg, "pkgdown/assets/subdir1/subdir2/file2.txt") suppressMessages(init_site(pkg)) expect_true(file_exists(path(pkg$dst_path, "subdir1", "file1.txt"))) expect_true(file_exists(path(pkg$dst_path, "subdir1", "subdir2", "file2.txt"))) }) test_that("site meta doesn't break unexpectedly", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/a.Rmd") pkg <- pkg_add_file(pkg, "vignettes/b.Rmd") # null out components that will vary yaml <- site_meta(pkg) yaml$pkgdown <- "{version}" yaml$pkgdown_sha <- "{sha}" yaml$pandoc <- "{version}" yaml$last_built <- timestamp(as.POSIXct("2020-01-01", tz = "UTC")) expect_snapshot(yaml) }) test_that("site meta includes vignette subdirectories", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/a/a.Rmd") pkg <- pkg_add_file(pkg, "vignettes/a/b.Rmd") meta <- site_meta(pkg) expect_equal(meta$articles, list("a/a" = "a/a.html", "a/b" = "a/b.html")) }) pkgdown/tests/testthat/_snaps/0000755000176200001440000000000014671042466016222 5ustar liggesuserspkgdown/tests/testthat/_snaps/usage.md0000644000176200001440000000100514656154170017643 0ustar liggesusers# usage generates user facing code for S3/S4 infix/replacement methods Code cat(usage2text("\\S3method{$}{indexed_frame}(x, name)")) Output # S3 method for class 'indexed_frame' x$name Code cat(usage2text("\\method{[[}{indexed_frame}(x, i) <- value")) Output # S3 method for class 'indexed_frame' x[[i]] <- value Code cat(usage2text("\\S4method{>=}{MyType,numeric}(e1, e2)")) Output # S4 method for class 'MyType,numeric' e1 >= e2 pkgdown/tests/testthat/_snaps/theme.md0000644000176200001440000000141714656154163017652 0ustar liggesusers# check_bslib_theme() works Code check_bslib_theme("paper", pkg, bs_version = 4) Condition Error: x In _pkgdown.yml, template.bootswatch contains unknown Bootswatch/bslib theme "paper". i Using Bootstrap version 4 (template.bootstrap). # validations yaml specification Code build_bslib_(theme = 1) Condition Error in `bs_theme_rules()`: ! In _pkgdown.yml, template.theme must be a string, not the number 1. Code build_bslib_(theme = "fruit") Condition Error in `build_bslib_()`: ! In _pkgdown.yml, template.theme uses theme "fruit" Code build_bslib_(`theme-dark` = "fruit") Condition Error in `build_bslib_()`: ! In _pkgdown.yml, template.theme-dark uses theme "fruit" pkgdown/tests/testthat/_snaps/navbar-menu.md0000644000176200001440000000675214656154160020767 0ustar liggesusers# can construct menu with children Code cat(navbar_html(menu)) Output # bad inputs give clear error Code navbar_html(1) Condition Error in `menu_type()`: ! Navbar components must be named lists, not the number 1. Code navbar_html(list(foo = 1)) Condition Error in `menu_type()`: ! Unknown navbar component with names foo. Code navbar_html(submenu) Condition Error in `menu_type()`: ! Nested menus are not supported. # can construct bullets Code cat(navbar_html(menu_icon("fa-question", "https://example.com", "label"))) Output Code cat(navbar_html(menu_heading("Hi"))) Output Code cat(navbar_html(menu_link("Hi", "https://example.com"))) Output # icons warn if no aria-label Code . <- navbar_html(menu_icon("fa-question", "https://example.com", NULL)) Message x Icon "fa-question" lacks an `aria-label`. i Specify `aria-label` to make the icon accessible to screen readers. i Learn more in `vignette(pkgdown::accessibility)`. This message is displayed once every 8 hours. # can construct theme menu Code cat(navbar_html(lightswitch)) Output # simple components don't change without warning Code cat(navbar_html(menu_heading("a"))) Output Code cat(navbar_html(menu_link("a", "b"))) Output Code cat(navbar_html(menu_separator())) Output Code cat(navbar_html(menu_search())) Output pkgdown/tests/testthat/_snaps/build-redirects.md0000644000176200001440000000116514656154134021627 0ustar liggesusers# build_redirect() works Code build_redirect(c("old.html", "new.html#section"), 1, pkg = pkg) Message Adding redirect from old.html to new.html#section. # build_redirect() errors if one entry is not right. Code data_redirects_(redirects = "old.html") Condition Error in `data_redirects_()`: ! In _pkgdown.yml, redirects must be a list, not the string "old.html". Code data_redirects_(redirects = list("old.html")) Condition Error in `data_redirects_()`: ! In _pkgdown.yml, redirects[1] must be a character vector of length 2, not the string "old.html". pkgdown/tests/testthat/_snaps/init.md0000644000176200001440000000413014656154160017503 0ustar liggesusers# informative print method Code init_site(pkg) Message -- Initialising site ----------------------------------------------------------- Copying /BS5/assets/katex-auto.js to katex-auto.js Copying /BS5/assets/lightswitch.js to lightswitch.js Copying /BS5/assets/link.svg to link.svg Copying /BS5/assets/pkgdown.js to pkgdown.js Updating deps/bootstrap-5.3.1/bootstrap.bundle.min.js Updating deps/bootstrap-5.3.1/bootstrap.bundle.min.js.map Updating deps/bootstrap-5.3.1/bootstrap.min.css Updating deps/bootstrap-toc-1.0.1/bootstrap-toc.min.js Updating deps/clipboard.js-2.0.11/clipboard.min.js Updating deps/font-awesome-6.4.2/css/all.css Updating deps/font-awesome-6.4.2/css/all.min.css Updating deps/font-awesome-6.4.2/css/v4-shims.css Updating deps/font-awesome-6.4.2/css/v4-shims.min.css Updating deps/font-awesome-6.4.2/webfonts/fa-brands-400.ttf Updating deps/font-awesome-6.4.2/webfonts/fa-brands-400.woff2 Updating deps/font-awesome-6.4.2/webfonts/fa-regular-400.ttf Updating deps/font-awesome-6.4.2/webfonts/fa-regular-400.woff2 Updating deps/font-awesome-6.4.2/webfonts/fa-solid-900.ttf Updating deps/font-awesome-6.4.2/webfonts/fa-solid-900.woff2 Updating deps/font-awesome-6.4.2/webfonts/fa-v4compatibility.ttf Updating deps/font-awesome-6.4.2/webfonts/fa-v4compatibility.woff2 Updating deps/headroom-0.11.0/headroom.min.js Updating deps/headroom-0.11.0/jQuery.headroom.min.js Updating deps/jquery-3.6.0/jquery-3.6.0.js Updating deps/jquery-3.6.0/jquery-3.6.0.min.js Updating deps/jquery-3.6.0/jquery-3.6.0.min.map Updating deps/search-1.0.0/autocomplete.jquery.min.js Updating deps/search-1.0.0/fuse.min.js Updating deps/search-1.0.0/mark.min.js # site meta doesn't break unexpectedly Code yaml Output pandoc: '{version}' pkgdown: '{version}' pkgdown_sha: '{sha}' articles: a: a.html b: b.html last_built: 2020-01-01T00:00Z pkgdown/tests/testthat/_snaps/repo.md0000644000176200001440000000103114656154162017504 0ustar liggesusers# repo_source() truncates automatically Code cat(repo_source(pkg, character())) cat(repo_source(pkg, "a")) Output Source: a Code cat(repo_source(pkg, letters[1:10])) Output Source: a, b, c, and 7 more pkgdown/tests/testthat/_snaps/preview.md0000644000176200001440000000071214656154161020224 0ustar liggesusers# checks its inputs Code preview_site(pkg, path = 1) Condition Error in `preview_site()`: ! `path` must be a single string, not the number 1. Code preview_site(pkg, path = "foo") Condition Error in `preview_site()`: ! Can't find file 'foo'. Code preview_site(pkg, preview = 1) Condition Error in `preview_site()`: ! `preview` must be `TRUE`, `FALSE`, or `NA`, not the number 1. pkgdown/tests/testthat/_snaps/build-article.md0000644000176200001440000000551014656154106021263 0ustar liggesusers# bad width gives nice error Code rmarkdown_setup_pkgdown(pkg) Condition Error in `rmarkdown_setup_pkgdown()`: ! In _pkgdown.yml, code.width must be a whole number, not the string "abc". # output is reproducible by default, i.e. 'seed' is respected Code cat(output) Output ## [1] 0.080750138 0.834333037 0.600760886 0.157208442 0.007399441 # reports on bad open graph meta-data Code build_article("test", pkg) Message Reading vignettes/test.Rmd Condition Error in `build_article()`: ! In vignettes/test.Rmd, opengraph.twitter must be a list, not the number 1. # build_article styles ANSI escapes ## X # build_article yields useful error if pandoc fails Code build_article("test", pkg, pandoc_args = "--fail-if-warnings") Message Reading vignettes/test.Rmd Condition Error in `build_article()`: ! Failed to render 'vignettes/test.Rmd'. x [WARNING] This document format requires a nonempty element. x Defaulting to 'test.knit' as the title. x To specify a title, use 'title' in metadata or --metadata title="...". x Failing because there were warnings. Caused by error: ! pandoc document conversion failed with error 3 # build_article yields useful error if R fails Code build_article("test", pkg) Message Reading vignettes/test.Rmd Condition Error in `build_article()`: ! Failed to render 'vignettes/test.Rmd'. x Quitting from lines 5-9 [unnamed-chunk-1] (test.Rmd) Caused by error: ! Error! --- Code summary(expect_error(build_article("test", pkg))) Message Reading vignettes/test.Rmd Output <error/rlang_error> Error in `build_article()`: ! Failed to render 'vignettes/test.Rmd'. x Quitting from lines 5-9 [unnamed-chunk-1] (test.Rmd) Caused by error: ! Error! --- Backtrace: x 1. \-global f() 2. \-global g() 3. \-global h() # build_article copies image files in subdirectories Code build_article("test", pkg) Message Reading vignettes/test.Rmd Writing `articles/test.html` # warns about missing images Code build_article("kitten", pkg) Message Reading vignettes/kitten.Rmd Writing `articles/kitten.html` Missing images in 'vignettes/kitten.Rmd': 'kitten.jpg' i pkgdown can only use images in 'man/figures' and 'vignettes' # warns about missing alt-text Code build_article("kitten", pkg) Message Reading vignettes/kitten.Rmd Writing `articles/kitten.html` x Missing alt-text in 'vignettes/kitten.Rmd' * kitten.jpg i Learn more in `vignette(pkgdown::accessibility)`. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/tweak-tags.md���������������������������������������������������������0000644�0001762�0000144�00000000457�14656154167�020626� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# anchor html added to headings <h1 id="x">abc<a class="anchor" aria-label="anchor" href="#x"/></h1> # can process footnote with code Code xpath_attr(html, ".//a", "data-bs-content") Output [1] "<p>Including code:</p>\n<pre><code>1 +\n2 +</code></pre>\n<p>And more text</p>" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/build-home-authors.md�������������������������������������������������0000644�0001762�0000144�00000004527�14656154042�022261� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# data_authors validates yaml inputs Code data_authors_(authors = 1) Condition Error in `data_authors_()`: ! In _pkgdown.yml, authors must be a list, not the number 1. Code data_authors_(template = list(authors = list(before = 1))) Condition Error in `data_authors_()`: ! In _pkgdown.yml, template.authors.before must be a string, not the number 1. Code data_authors_(template = list(authors = list(after = 1))) Condition Error in `data_authors_()`: ! In _pkgdown.yml, template.authors.after must be a string, not the number 1. # data_home_sidebar_authors validates yaml inputs Code data_home_sidebar_authors_(authors = list(sidebar = list(roles = 1))) Condition Error in `data_home_sidebar_authors_()`: ! In _pkgdown.yml, authors.sidebar.roles must be a character vector, not the number 1. Code data_home_sidebar_authors_(authors = list(sidebar = list(before = 1))) Condition Error in `data_home_sidebar_authors_()`: ! In _pkgdown.yml, authors.sidebar.before must be a string, not the number 1. Code data_home_sidebar_authors_(authors = list(sidebar = list(before = "x\n\ny"))) Condition Error in `data_home_sidebar_authors_()`: ! In _pkgdown.yml, authors.sidebar.before must be inline markdown. # sidebar can accept additional before and after text Code cat(data_home_sidebar_authors(pkg)) Output <div class='developers'> <h2 data-toc-skip>Developers</h2> <ul class='list-unstyled'> <li>BEFORE</li> <li>Jo Doe <br /> <small class = 'roles'> Author, maintainer </small> </li> <li>AFTER</li> </ul> </div> # role has multiple fallbacks Code role_lookup("unknown") Condition Warning: Unknown MARC role abbreviation: unknown Output [1] "unknown" # multiple citations all have HTML and BibTeX formats [[1]] [[1]]$html [1] "<p>A & B (2021): Proof of b < a > c.</p>" [[1]]$bibtex [1] "@Misc{,\n title = {Proof of b < a > c},\n author = {{A} and {B}},\n year = {2021},\n}" [[2]] [[2]]$html [1] "<p>Two A (2022).\n“Title Two.” \n</p>" [[2]]$bibtex [1] "@Misc{,\n title = {Title Two},\n author = {Author Two},\n year = {2022},\n}" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/package.md������������������������������������������������������������0000644�0001762�0000144�00000002176�14656154161�020144� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# is_pkgdown checks its inputs Code as_pkgdown(1) Condition Error in `as_pkgdown()`: ! `pkg` must be a single string, not the number 1. Code as_pkgdown(override = 1) Condition Error in `as_pkgdown()`: ! `override` must be a list, not the number 1. # check_bootstrap_version() allows 3, 4 (with warning), and 5 Code expect_equal(check_bootstrap_version(4, pkg), 5) Condition Warning: In _pkgdown.yml, `template.bootstrap: 4` no longer supported i Using `template.bootstrap: 5` instead # check_bootstrap_version() gives informative error otherwise Code check_bootstrap_version(1, pkg) Condition Error in `check_bootstrap_version()`: ! In _pkgdown.yml, template.bootstrap must be 3 or 5, not 1. # read_meta() errors gracefully if _pkgdown.yml failed to parse Code as_pkgdown(pkg$src_path) Condition Error in `as_pkgdown()`: ! Could not parse config file at '<src>/_pkgdown.yml'. Caused by error in `yaml.load()`: ! Scanner error: mapping values are not allowed in this context at line 2, column 8 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/build-footer.md�������������������������������������������������������0000644�0001762�0000144�00000002166�14656154041�021140� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# works by default $left [1] "<p>Developed by First Last.</p>" $right [1] "<p>Site built with <a href=\"https://pkgdown.r-lib.org/\">pkgdown</a> {version}.</p>" # validates meta components Code data_footer_(footer = 1) Condition Error in `data_footer_()`: ! In _pkgdown.yml, footer must be a list, not the number 1. Code data_footer_(footer = list(structure = 1)) Condition Error in `data_footer_()`: ! In _pkgdown.yml, footer.structure must be a list, not the number 1. Code data_footer_(footer = list(components = 1)) Condition Error in `data_footer_()`: ! In _pkgdown.yml, footer.components must be a list, not the number 1. Code data_footer_(authors = list(footer = list(roles = 1))) Condition Error in `data_footer_()`: ! In _pkgdown.yml, authors.footer.roles must be a character vector, not the number 1. Code data_footer_(authors = list(footer = list(text = 1))) Condition Error in `data_footer_()`: ! In _pkgdown.yml, authors.footer.text must be a string, not the number 1. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/utils-fs.md�����������������������������������������������������������0000644�0001762�0000144�00000000565�14656154167�020325� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# missing template package yields custom error Code path_package_pkgdown("x", "missing", 3) Condition Error: ! Template package "missing" is not installed. i Please install before continuing. # out_of_date works as expected Code out_of_date("doesntexist", temp1) Condition Error: ! 'doesntexist' does not exist �������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/config.md�������������������������������������������������������������0000644�0001762�0000144�00000001504�14656154153�020011� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# config_pluck_character generates informative error Code config_pluck_character(pkg, "x") Condition Error: ! In _pkgdown.yml, x must be a character vector, not the number 1. # config_pluck_string generates informative error Code config_pluck_string(pkg, "x") Condition Error: ! In _pkgdown.yml, x must be a string, not the number 1. # config_check_list gives informative errors Code config_check_list_(1, has_names = "x") Condition Error in `config_check_list_()`: ! In _pkgdown.yml, path must be a list, not the number 1. Code config_check_list_(list(x = 1, y = 1), has_names = c("y", "z")) Condition Error in `config_check_list_()`: ! In _pkgdown.yml, path must have components "y" and "z". 1 missing component: "z". ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/highlight.md����������������������������������������������������������0000644�0001762�0000144�00000001100�14656154154�020504� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# highlight_examples runs and hides DONTSHOW calls() Code cat(strip_html_tags(out)) Output x #> [1] 1 # pre() can produce needed range of outputs Code cat(pre("x")) Output <pre><code>x</code></pre> Code cat(pre("x", r_code = TRUE)) Output <pre class='sourceCode r'><code>x</code></pre> # tweak_highlight_other() renders nested code blocks for roxygen2 >= 7.2.0 Code cat(xpath_text(div, "pre/code")) Output blablabla ```{r results='asis'} lalala ``` ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/check-built.md��������������������������������������������������������0000644�0001762�0000144�00000000443�14656154152�020736� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# check images in readme Code check_built_site(pkg) Message -- Checking for problems ------------------------------------------------------- Missing images in 'README.md': 'articles/kitten.jpg' i pkgdown can only use images in 'man/figures' and 'vignettes' �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/external-deps.md������������������������������������������������������0000644�0001762�0000144�00000001422�14656154153�021316� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# check integrity validates integrity Code check_integrity(temp, "sha123-abc") Condition Error in `check_integrity()`: ! integrity must use SHA-256, SHA-384, or SHA-512 i This is an internal error that was detected in the pkgdown package. Please report it at <https://github.com/r-lib/pkgdown/issues> with a reprex (<https://tidyverse.org/help/>) and the full backtrace. Code check_integrity(temp, "sha256-abc") Condition Error in `check_integrity()`: ! Downloaded asset does not match known integrity i This is an internal error that was detected in the pkgdown package. Please report it at <https://github.com/r-lib/pkgdown/issues> with a reprex (<https://tidyverse.org/help/>) and the full backtrace. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/topics.md�������������������������������������������������������������0000644�0001762�0000144�00000005411�14656154165�020051� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# bad inputs give informative warnings Code select_topics_("x + ", topics) Condition Error in `select_topics_()`: ! In _pkgdown.yml, reference[1].contents[1] (x + ) must be valid R code. Code select_topics_("y", topics) Condition Error in `select_topics_()`: ! In _pkgdown.yml, reference[1].contents[1] (y) must be a known topic name or alias. Code select_topics_("paste(1)", topics) Condition Error in `select_topics_()`: ! In _pkgdown.yml, reference[1].contents[1] (paste(1)) failed to evaluate. Caused by error in `paste()`: ! could not find function "paste" Code select_topics_("starts_with", topics) Condition Error in `select_topics_()`: ! In _pkgdown.yml, reference[1].contents[1] (starts_with) must be a known topic name or alias. Code select_topics_("1", topics) Condition Error in `select_topics_()`: ! In _pkgdown.yml, reference[1].contents[1] (1) must be a string or function call. Code select_topics_("starts_with('y')", topics) Condition Error in `select_topics_()`: ! In _pkgdown.yml, reference[1].contents failed to match any topics. # selector functions validate their inputs Code select_topics_("starts_with('x', 'y')", topics) Condition Error in `select_topics_()`: ! In _pkgdown.yml, reference[1].contents[1] (starts_with('x', 'y')) failed to evaluate. Caused by error in `starts_with()`: ! `internal` must be `TRUE` or `FALSE`, not the string "y". Code select_topics_("starts_with(c('x', 'y'))", topics) Condition Error in `select_topics_()`: ! In _pkgdown.yml, reference[1].contents[1] (starts_with(c('x', 'y'))) failed to evaluate. Caused by error in `starts_with()`: ! `x` must be a single string, not a character vector. # can select by name or alias Code select_topics_("a4", topics) Condition Error in `select_topics_()`: ! In _pkgdown.yml, reference[1].contents[1] (a4) must be a known topic name or alias. Code select_topics_("c::a", topics) Condition Error in `select_topics_()`: ! In _pkgdown.yml, reference[1].contents[1] (c::a) must be a known topic name or alias. # can combine positive and negative selections Code select_topics_("c(a, -x)", topics) Condition Error in `select_topics_()`: ! In _pkgdown.yml, reference[1].contents[1] (c(a, -x)) must be all negative or all positive. # an unmatched selection generates a warning Code select_topics_(c("a", "starts_with('unmatched')"), topics) Condition Error in `select_topics_()`: ! In _pkgdown.yml, reference[1].contents (starts_with('unmatched')) must match a function or concept. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/render.md�������������������������������������������������������������0000644�0001762�0000144�00000004604�14656154162�020027� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# capture data_template() package: name: testpackage version: 1.0.0 site: root: '' title: testpackage year: <year> lang: en translate: skip: Skip to contents toggle_nav: Toggle navigation on_this_page: On this page source: Source abstract: Abstract authors: Authors version: Version examples: Examples citation: Citation author_details: Additional details toc: Table of contents site_nav: Site navigation has_favicons: no opengraph: [] extra: css: ~ js: ~ yaml: .present: yes headdeps: '' development: destination: dev mode: default version_label: muted in_dev: no prefix: '' version_tooltip: '' navbar: bg: light type: light left: <li class="nav-item"><a class="nav-link" href="reference/index.html">Reference</a></li> right: "<li class=\"nav-item\"><form class=\"form-inline\" role=\"search\">\n <input class=\"form-control\" type=\"search\" name=\"search-input\" id=\"search-input\" autocomplete=\"off\" aria-label=\"Search site\" placeholder=\"Search for\" data-search-index=\"search.json\"> \n</form></li>" footer: left: <p>Developed by Jo Doe.</p> right: <p>Site built with <a href="https://pkgdown.r-lib.org/">pkgdown</a> {version}.</p> lightswitch: no uses_katex: no # check_opengraph validates inputs Code data_open_graph_(list(foo = list())) Condition Warning in `data_open_graph_()`: In _pkgdown.yml, template.opengraph contains unsupported fields "foo". Code data_open_graph_(list(foo = list(), bar = list())) Condition Warning in `data_open_graph_()`: In _pkgdown.yml, template.opengraph contains unsupported fields "foo" and "bar". Code data_open_graph_(list(twitter = 1)) Condition Error in `data_open_graph_()`: ! In _pkgdown.yml, template.opengraph.twitter must be a list, not the number 1. Code data_open_graph_(list(twitter = list())) Condition Error in `data_open_graph_()`: ! In _pkgdown.yml, opengraph.twitter must include either creator or site. Code data_open_graph_(list(image = 1)) Condition Error in `data_open_graph_()`: ! In _pkgdown.yml, template.opengraph.image must be a list, not the number 1. ����������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/build-github.md�������������������������������������������������������0000644�0001762�0000144�00000000362�14656154041�021120� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# a CNAME record is built if a url exists in metadata Code build_github_pages(pkg) Message -- Extra files for GitHub pages ------------------------------------------------ Writing `.nojekyll` Writing `CNAME` ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/topics-external.md����������������������������������������������������0000644�0001762�0000144�00000001602�14656154163�021665� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# can get info about external function Code str(ext_topics("base::mean")) Output tibble [1 x 12] (S3: tbl_df/tbl/data.frame) $ name : chr "base::mean" $ file_in : chr NA $ file_out : chr "https://rdrr.io/r/base/mean.html" $ alias :List of 1 ..$ : chr(0) $ funs :List of 1 ..$ : chr "mean()" $ title : chr "Arithmetic Mean (from base)" $ rd :List of 1 ..$ : chr(0) $ source : chr NA $ keywords :List of 1 ..$ : chr(0) $ concepts :List of 1 ..$ : chr(0) $ internal : logi FALSE $ lifecycle:List of 1 ..$ : NULL # fails if documentation not available Code ext_topics("base::doesntexist") Condition Error in `build_reference_index()`: ! Could not find documentation for `base::doesntexist()`. ������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/navbar.md�������������������������������������������������������������0000644�0001762�0000144�00000015320�14656154161�020015� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# adds github/gitlab link when available reference: text: Reference href: reference/index.html search: search: [] --- reference: text: Reference href: reference/index.html search: search: [] github: icon: fab fa-github fa-lg href: https://github.com/r-lib/pkgdown aria-label: GitHub --- reference: text: Reference href: reference/index.html search: search: [] github: icon: fab fa-gitlab fa-lg href: https://gitlab.com/r-lib/pkgdown aria-label: GitLab # vignette with package name turns into getting started reference: text: Reference href: reference/index.html search: search: [] intro: text: Get started href: test.html # can control articles navbar through articles meta Code navbar_articles(pkg()) Output articles: text: Articles menu: - text: Title a href: a.html - text: Title b href: b.html --- Code navbar_articles(pkg(articles = list(list(name = "all", contents = c("a", "b"))))) Output articles: text: Articles href: articles/index.html --- Code navbar_articles(pkg(articles = list(list(name = "all", contents = c("a", "b"), navbar = NULL)))) Output articles: text: Articles menu: - text: Title a href: a.html - text: Title b href: b.html --- Code navbar_articles(pkg(articles = list(list(name = "all", contents = c("a", "b"), navbar = "Label")))) Output articles: text: Articles menu: - text: '---------' - text: Label - text: Title a href: a.html - text: Title b href: b.html --- Code navbar_articles(pkg(articles = list(list(name = "a", contents = "a", navbar = NULL), list(name = "b", contents = "b")))) Output articles: text: Articles menu: - text: Title a href: a.html - text: '---------' - text: More articles... href: articles/index.html # data_navbar() works by default Code data_navbar(pkg) Output $bg [1] "light" $type [1] "light" $left [1] "<li class=\"nav-item\"><a class=\"nav-link\" href=\"reference/index.html\">Reference</a></li>\n<li class=\"nav-item\"><a class=\"nav-link\" href=\"news/index.html\">Changelog</a></li>" $right [1] "<li class=\"nav-item\"><form class=\"form-inline\" role=\"search\">\n <input class=\"form-control\" type=\"search\" name=\"search-input\" id=\"search-input\" autocomplete=\"off\" aria-label=\"Search site\" placeholder=\"Search for\" data-search-index=\"search.json\"> \n</form></li>\n<li class=\"nav-item\"><a class=\"nav-link\" href=\"https://github.com/r-lib/pkgdown/\" aria-label=\"GitHub\"><span class=\"fa fab fa-github fa-lg\"></span></a></li>" # data_navbar() can re-order default elements Code data_navbar(pkg)[c("left", "right")] Output $left [1] "<li class=\"nav-item\"><a class=\"nav-link\" href=\"https://github.com/r-lib/pkgdown/\" aria-label=\"GitHub\"><span class=\"fa fab fa-github fa-lg\"></span></a></li>\n<li class=\"nav-item\"><form class=\"form-inline\" role=\"search\">\n <input class=\"form-control\" type=\"search\" name=\"search-input\" id=\"search-input\" autocomplete=\"off\" aria-label=\"Search site\" placeholder=\"Search for\" data-search-index=\"search.json\"> \n</form></li>" $right [1] "<li class=\"nav-item\"><a class=\"nav-link\" href=\"news/index.html\">Changelog</a></li>" # data_navbar() works with empty side Code data_navbar(pkg) Output $bg [1] "light" $type [1] "light" $left [1] "" $right [1] "" # data_navbar_() errors with bad yaml specifications Code data_navbar_(navbar = list(structure = list(left = 1))) Condition Error in `data_navbar_()`: ! In _pkgdown.yml, navbar.structure.left must be a character vector, not the number 1. Code data_navbar_(navbar = list(right = "github")) Condition Error in `data_template()`: ! In _pkgdown.yml, navbar is incorrectly specified. i See details in `vignette(pkgdown::customise)`. # render_navbar_links BS3 & BS4 default Code cat(render_navbar_links(x, pkg = list(bs_version = 3))) Output <li> <a href="articles/pkgdown.html">Get started</a> </li> <li> <a href="reference/index.html">Reference</a> </li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false"> Articles <span class="caret"></span> </a> <ul class="dropdown-menu" role="menu"> <li> <a href="articles/linking.html">Auto-linking</a> </li> <li> <a href="articles/search.html">Search</a> </li> <li> <a href="articles/metadata.html">Metadata</a> </li> <li> <a href="articles/customization.html">Customize your pkgdown website</a> </li> <li class="divider"></li> <li> <a href="articles/index.html">More...</a> </li> </ul> </li> <li> <a href="news/index.html">News</a> </li> --- Code cat(render_navbar_links(x, pkg = list(bs_version = 4))) Output <li class="nav-item"><a class="nav-link" href="articles/pkgdown.html">Get started</a></li> <li class="nav-item"><a class="nav-link" href="reference/index.html">Reference</a></li> <li class="nav-item dropdown"> <button class="nav-link dropdown-toggle" type="button" id="dropdown-articles" data-bs-toggle="dropdown" aria-expanded="false" aria-haspopup="true">Articles</button> <ul class="dropdown-menu" aria-labelledby="dropdown-articles"> <li><a class="dropdown-item" href="articles/linking.html">Auto-linking</a></li> <li><a class="dropdown-item" href="articles/search.html">Search</a></li> <li><a class="dropdown-item" href="articles/metadata.html">Metadata</a></li> <li><a class="dropdown-item" href="articles/customization.html">Customize your pkgdown website</a></li> <li><hr class="dropdown-divider"></li> <li><a class="dropdown-item" href="articles/index.html">More...</a></li> </ul> </li> <li class="nav-item"><a class="nav-link" href="news/index.html">News</a></li> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/tweak-tabset.md�������������������������������������������������������0000644�0001762�0000144�00000002002�14656154165�021134� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# sections with class .tabset are converted to tabsets <div class="section level1 tabset tabset-pills"> <h1 id="tabset">Tabset<a class="anchor" aria-label="anchor" href="#tabset"></a> </h1> <ul class="nav nav-pills" id="tabset" role="tablist"> <li role="presentation" class="nav-item"><button data-bs-toggle="tab" data-bs-target="#tab-1" id="tab-1-tab" type="button" role="tab" aria-controls="tab-1" aria-selected="true" class="active nav-link">Tab 1</button></li> <li role="presentation" class="nav-item"><button data-bs-toggle="tab" data-bs-target="#tab-2" id="tab-2-tab" type="button" role="tab" aria-controls="tab-2" aria-selected="false" class="nav-link">Tab 2</button></li> </ul> <div class="tab-content"> <div class="active tab-pane" id="tab-1" role="tabpanel" aria-labelledby="tab-1-tab"> <p>Contents 1</p> </div> <div class="tab-pane" id="tab-2" role="tabpanel" aria-labelledby="tab-2-tab"> <p>Contents 2</p> </div> </div> </div> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/build-reference.md����������������������������������������������������0000644�0001762�0000144�00000001126�14656154036�021577� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# parse failures include file name Code build_reference(pkg) Message -- Building function reference ------------------------------------------------- Writing `reference/index.html` Reading man/f.Rd Condition Error in `build_reference()`: ! Failed to parse Rd in 'f.Rd' Caused by error: ! Failed to parse tag "\\url{}". i Check for empty \url{} tags. # examples are reproducible by default, i.e. 'seed' is respected Code cat(examples) Output #> [1] 0.080750138 0.834333037 0.600760886 0.157208442 0.007399441 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/build-home-index.md���������������������������������������������������0000644�0001762�0000144�00000011136�14671042466�021700� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# messages about reading and writing Code build_home_index(pkg) Message Reading 'DESCRIPTION' Writing `index.html` Code build_home_index(pkg) Message Reading 'DESCRIPTION' # data_home() validates yaml metadata Code data_home_(home = 1) Condition Error in `data_home_()`: ! In _pkgdown.yml, home must be a list, not the number 1. Code data_home_(home = list(title = 1)) Condition Error in `data_home_()`: ! In _pkgdown.yml, home.title must be a string, not the number 1. Code data_home_(home = list(description = 1)) Condition Error in `data_home_()`: ! In _pkgdown.yml, home.description must be a string, not the number 1. Code data_home_(template = list(trailing_slash_redirect = 1)) Condition Error in `data_home_()`: ! In _pkgdown.yml, template.trailing_slash_redirect must be true or false, not the number 1. # data_home_sidebar() works by default Code cat(data_home_sidebar(pkg)) Output <div class='links'> <h2 data-toc-skip>Links</h2> <ul class='list-unstyled'> <li><a href='{{ BugReports }}'>Report a bug</a></li> </ul> </div> <div class='license'> <h2 data-toc-skip>License</h2> <ul class='list-unstyled'> <li>{{ License }}</li> </ul> </div> <div class='citation'> <h2 data-toc-skip>Citation</h2> <ul class='list-unstyled'> <li><a href='authors.html#citation'>Citing testpackage</a></li> </ul> </div> <div class='developers'> <h2 data-toc-skip>Developers</h2> <ul class='list-unstyled'> <li>Jo Doe <br /> <small class = 'roles'> Author, maintainer </small> </li> </ul> </div> <div class='dev-status'> <h2 data-toc-skip>Dev Status</h2> <ul class='list-unstyled'> <li>placeholder</li> </ul> </div> --- <div class="developers"> <h2 data-toc-skip>Developers</h2> <ul class="list-unstyled"> <li>Hadley Wickham <br><small class="roles"> Author, maintainer </small> </li> <li>RStudio <br><small class="roles"> Copyright holder, funder </small> </li> <li><a href="authors.html">More about authors...</a></li> </ul> </div> # data_home_sidebar() can be defined by a HTML file Code data_home_sidebar(pkg) Condition Error: ! In _pkgdown.yml, home.sidebar.html specifies a file that doesn't exist ('sidebar.html'). # data_home_sidebar() can get a custom markdown formatted component <div class="fancy-section"> <h2 data-toc-skip>Fancy section</h2> <ul class="list-unstyled"> <li><p>How <em>cool</em> is pkgdown?!</p></li> </ul> </div> # data_home_sidebar() can add a TOC <div class="table-of-contents"> <h2 data-toc-skip>Table of contents</h2> <ul class="list-unstyled"> <li><nav id="toc"></nav></li> </ul> </div> # data_home_sidebar() outputs informative error messages Code data_home_sidebar_(html = 1) Condition Error in `data_home_sidebar_()`: ! In _pkgdown.yml, home.sidebar.html must be a string, not the number 1. Code data_home_sidebar_(structure = 1) Condition Error in `data_home_sidebar_()`: ! In _pkgdown.yml, home.sidebar.structure must be a character vector, not the number 1. Code data_home_sidebar_(structure = "fancy") Condition Error in `data_home_sidebar_()`: ! In _pkgdown.yml, home.sidebar.components must have component "fancy". 1 missing component: "fancy". Code data_home_sidebar_(structure = c("fancy", "cool")) Condition Error in `data_home_sidebar_()`: ! In _pkgdown.yml, home.sidebar.components must have components "fancy" and "cool". 2 missing components: "fancy" and "cool". Code data_home_sidebar_(structure = "fancy", components = list(fancy = list(text = "bla"))) Condition Error in `data_home_sidebar_()`: ! In _pkgdown.yml, home.sidebar.components.fancy must have components "title" and "text". 1 missing component: "title". Code data_home_sidebar_(structure = "fancy", components = list(fancy = list())) Condition Error in `data_home_sidebar_()`: ! In _pkgdown.yml, home.sidebar.components.fancy must have components "title" and "text". 2 missing components: "title" and "text". # allow email in BugReports Code xpath_xml(html, ".//li/a") Output <a href="mailto:me@tidyverse.com">Report a bug</a> <a href="authors.html#citation">Citing testpackage</a> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/templates.md����������������������������������������������������������0000644�0001762�0000144�00000002107�14656154163�020543� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Invalid bootstrap version spec in template package Code local_pkgdown_site(meta = list(template = list(package = "templatepackage"))) Condition Error in `as_pkgdown()`: ! In _pkgdown.yml, must set only one of template.bootstrap and template.bslib.version. i Specified locally and in template package templatepackage. # Invalid bootstrap version spec in _pkgdown.yml Code local_pkgdown_site(meta = list(template = list(bootstrap = 4, bslib = list( version = 5)))) Condition Error in `as_pkgdown()`: ! In _pkgdown.yml, must set only one of template.bootstrap and template.bslib.version. # Warns when Bootstrap theme is specified in multiple locations Code get_bslib_theme(pkg) Condition Warning: Multiple Bootstrap preset themes were set. Using "flatly" from template.bslib.preset. x Found template.bslib.preset, template.bslib.bootswatch, template.bootswatch, and template.params.bootswatch. i Remove extraneous theme declarations to avoid this warning. Output [1] "flatly" ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/development.md��������������������������������������������������������0000644�0001762�0000144�00000001747�14656154153�021077� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# validates yaml Code data_development_(development = 1) Condition Error in `as_pkgdown()`: ! In _pkgdown.yml, development must be a list, not the number 1. Code data_development_(development = list(mode = 1)) Condition Error in `as_pkgdown()`: ! In _pkgdown.yml, development.mode must be a string, not the number 1. Code data_development_(development = list(mode = "foo")) Condition Error in `as_pkgdown()`: ! In _pkgdown.yml, development.mode must be one of auto, default, release, devel, or unreleased, not foo. Code data_development_(development = list(destination = 1)) Condition Error in `as_pkgdown()`: ! In _pkgdown.yml, development.destination must be a string, not the number 1. Code data_development_(development = list(version_label = 1)) Condition Error in `as_pkgdown()`: ! In _pkgdown.yml, development.version_label must be a string, not the number 1. �������������������������pkgdown/tests/testthat/_snaps/build-favicons.md�����������������������������������������������������0000644�0001762�0000144�00000001165�14656154040�021447� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# missing logo generates message Code expect_output(build_favicons(pkg), "Building favicons") Message -- Building favicons ----------------------------------------------------------- Condition Error in `build_favicons()`: ! Can't find package logo PNG or SVG to build favicons. i See `usethis::use_logo()` for more information. # existing logo generates message Code build_favicons(pkg) Message -- Building favicons ----------------------------------------------------------- Favicons already exist in 'pkgdown' i Set `overwrite = TRUE` to re-create. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/rd-example.md���������������������������������������������������������0000644�0001762�0000144�00000001704�14656154161�020603� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# @examplesIf Code expect_equal(strtrim(rd2ex(rd3), 40), strtrim(exp3, 40)) Condition Warning: @examplesIf condition "TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && FALSE" is "FALSE" ������������������������������������������������������������pkgdown/tests/testthat/_snaps/tweak-homepage.md�����������������������������������������������������0000644�0001762�0000144�00000001371�14656154164�021446� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# can remove logo Code xpath_xml(html, ".//div") Output <div class="page-header"> <img src="mylogo.png" class="logo" alt=""><h1>First </h1> </div> --- Code xpath_xml(html, ".//div") Output <div class="page-header"> <img src="mylogo.png" class="logo" alt=""><h1>First </h1> </div> # can move badges to sidebar Code xpath_xml(html, ".//div") Output <div class="dev-status"> <h2 data-toc-skip>Dev status</h2> <ul class="list-unstyled"> <li><a href="x"><img src="y"></a></li> </ul> </div> # remove badges even if no dev-status div Code html Output {html_document} <html> [1] <body>\n<h1>Title</h1>\n </body> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/build-quarto-articles.md����������������������������������������������0000644�0001762�0000144�00000001235�14656154146�022763� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# we find out if quarto styles change Code cat(data$includes$style) Output code{white-space: pre-wrap;} span.smallcaps{font-variant: small-caps;} div.columns{display: flex; gap: min(4vw, 1.5em);} div.column{flex: auto; overflow-x: auto;} div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} ul.task-list{list-style: none;} ul.task-list li input[type="checkbox"] { width: 0.8em; margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */ vertical-align: middle; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/build-search-docs.md��������������������������������������������������0000644�0001762�0000144�00000001534�14656154153�022037� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# build_search_index() has expected structure Code str(build_search_index(pkg)) Output List of 1 $ :List of 8 ..$ path : chr "https://example.com/index.html" ..$ id : chr "my-package" ..$ dir : chr "" ..$ previous_headings: chr "" ..$ what : chr "A test package" ..$ title : chr "A test package" ..$ text : chr "pakage " ..$ code : chr "" # build sitemap only messages when it updates Code build_sitemap(pkg) Message -- Building sitemap ------------------------------------------------------------ Writing `sitemap.xml` Code build_sitemap(pkg) Message -- Building sitemap ------------------------------------------------------------ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/build-news.md���������������������������������������������������������0000644�0001762�0000144�00000004353�14656154124�020620� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# data_news works as expected for h1 & h2 # A tibble: 2 x 3 version page anchor <chr> <chr> <chr> 1 1.0.0.9000 dev testpackage-1009000 2 1.0.0 1.0 testpackage-100 --- # A tibble: 2 x 3 version page anchor <chr> <chr> <chr> 1 1.0.0.9000 dev testpackage-1009000 2 1.0.0 1.0 testpackage-100 # multi-page news are rendered Code data_news(pkg)[c("version", "page", "anchor")] Output # A tibble: 4 x 3 version page anchor <chr> <chr> <chr> 1 2.0 2.0 testpackage-20 2 1.1 1.1 testpackage-11 3 1.0.1 1.0 testpackage-101 4 1.0.0 1.0 testpackage-100 --- Code build_news(pkg) Message -- Building news --------------------------------------------------------------- Writing `news/news-2.0.html` Writing `news/news-1.1.html` Writing `news/news-1.0.html` Writing `news/index.html` # news headings get class and release date <div> <h2 class="page-header" data-toc-text="1.0"> <small>2020-01-01</small> </h2> </div> --- <div> <h2 class="pkg-version" data-toc-text="1.0"/> <p class="text-muted">CRAN release: 2020-01-01</p> </div> # clear error for bad hierarchy - bad nesting Code data_news(pkg) Condition Error: ! In NEWS.md, inconsistent use of section headings. i Top-level headings must be either all <h1> or all <h2>. i See `?pkgdown::build_news()` for more details. # clear error for bad hierarchy - h3 Code data_news(pkg) Condition Error: ! In NEWS.md, inconsistent use of section headings. i Top-level headings must be either all <h1> or all <h2>. i See `?pkgdown::build_news()` for more details. # news can contain footnotes Code x <- data_news(pkg) Condition Warning: Footnotes in NEWS.md are not currently supported # data_news warns if no headings found Code . <- data_news(pkg) Condition Warning: In NEWS.md, no version headings found i See `?pkgdown::build_news()` for expected structure. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/build-home-community.md�����������������������������������������������0000644�0001762�0000144�00000000421�14656154042�022605� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# handles CoC and SUPPORT if present <div class='community'> <h2 data-toc-skip>Community</h2> <ul class='list-unstyled'> <li><a href='CODE_OF_CONDUCT.html'>Code of conduct</a></li> <li><a href='SUPPORT.html'>Getting help</a></li> </ul> </div> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/rd-html.md������������������������������������������������������������0000644�0001762�0000144�00000004065�14656154162�020120� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# converts Rd unicode shortcuts Code rd2html("``a -- b --- c''") Output [1] "“a – b — c”" # subsection generates h3 Code cli::cat_line(rd2html("\\subsection{A}{B}")) Output <div class='section' id='a'> <h3>A</h3> <p>B</p> </div> --- Code cli::cat_line(rd2html("\\subsection{A}{\n p1\n\n p2\n }")) Output <div class='section' id='a'> <h3>A</h3> <p>p1</p> <p>p2</p> </div> # nested subsection generates h4 Code cli::cat_line(rd2html("\\subsection{H3}{\\subsection{H4}{}}")) Output <div class='section' id='h-'> <h3>H3</h3> <div class='section' id='h-'> <h4>H4</h4> </div> </div> # bad specs throw errors Code rd2html("\\url{}") Condition Error: ! Failed to parse tag "\\url{}". i Check for empty \url{} tags. Code rd2html("\\url{a\nb}") Condition Error: ! Failed to parse tag "\\url{}". i This may be caused by a \url tag that spans a line break. Code rd2html("\\email{}") Condition Error: ! Failed to parse tag "\\email{}". i empty Code rd2html("\\linkS4class{}") Condition Error: ! Failed to parse tag "\\linkS4class{}". # \describe items can contain multiple paragraphs <dl> <dt>Label 1</dt> <dd><p>Contents 1</p></dd> <dt>Label 2</dt> <dd><p>Contents 2</p></dd> </dl> --- <dl> <dt>Label</dt> <dd><p>Paragraph 1</p> <p>Paragraph 2</p></dd> </dl> # can add ids to descriptions <dl> <dt id='fooabc'>abc<a class='anchor' aria-label='anchor' href='#fooabc'></a></dt> <dd><p>Contents 1</p></dd> <dt id='fooxyz'>xyz<a class='anchor' aria-label='anchor' href='#fooxyz'></a></dt> <dd><p>Contents 2</p></dd> </dl> # nested item with whitespace parsed correctly <dl> <dt>Label</dt> <dd> <p>This text is indented in a way pkgdown doesn't like.</p></dd> </dl> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/markdown.md�����������������������������������������������������������0000644�0001762�0000144�00000001224�14656154157�020371� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# markdown_text_inline() works with inline markdown Code markdown_text_inline(pkg, "x\n\ny", error_path = "title") Condition Error: ! In _pkgdown.yml, title must be inline markdown. # validates math yaml Code config_math_rendering_(`math-rendering` = 1) Condition Error in `config_math_rendering_()`: ! In _pkgdown.yml, template.math-rendering must be a string, not the number 1. Code config_math_rendering_(`math-rendering` = "math") Condition Error in `config_math_rendering_()`: ! In _pkgdown.yml, template.math-rendering must be one of mathml, mathjax, and katex, not math. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/build-articles.md�����������������������������������������������������0000644�0001762�0000144�00000006364�14656154040�021453� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# validates articles yaml Code data_articles_index_(1) Condition Error in `data_articles_index_()`: ! In _pkgdown.yml, articles must be a list, not the number 1. Code data_articles_index_(list(1)) Condition Error in `data_articles_index_()`: ! In _pkgdown.yml, articles[1] must be a list, not the number 1. Code data_articles_index_(list(list())) Condition Error in `data_articles_index_()`: ! In _pkgdown.yml, articles[1] must have components "title" and "contents". 2 missing components: "title" and "contents". Code data_articles_index_(list(list(title = 1, contents = 1))) Condition Error in `data_articles_index_()`: ! In _pkgdown.yml, articles[1].title must be a string, not the number 1. Code data_articles_index_(list(list(title = "a\n\nb", contents = 1))) Condition Error in `data_articles_index_()`: ! In _pkgdown.yml, articles[1].title must be inline markdown. Code data_articles_index_(list(list(title = "a", contents = 1))) Condition Error in `data_articles_index_()`: ! In _pkgdown.yml, articles[1].contents[1] must be a string. i You might need to add '' around special YAML values like 'N' or 'off' # validates external-articles Code data_articles_(1) Condition Error in `data_articles_()`: ! In _pkgdown.yml, external-articles must be a list, not the number 1. Code data_articles_(list(1)) Condition Error in `data_articles_()`: ! In _pkgdown.yml, external-articles[1] must be a list, not the number 1. Code data_articles_(list(list(name = "x"))) Condition Error in `data_articles_()`: ! In _pkgdown.yml, external-articles[1] must have components "name", "title", "href", and "description". 3 missing components: "title", "href", and "description". Code data_articles_(list(list(name = 1, title = "x", href = "x", description = "x"))) Condition Error in `data_articles_()`: ! In _pkgdown.yml, external-articles[1].name must be a string, not the number 1. Code data_articles_(list(list(name = "x", title = 1, href = "x", description = "x"))) Condition Error in `data_articles_()`: ! In _pkgdown.yml, external-articles[1].title must be a string, not the number 1. Code data_articles_(list(list(name = "x", title = "x", href = 1, description = "x"))) Condition Error in `data_articles_()`: ! In _pkgdown.yml, external-articles[1].href must be a string, not the number 1. Code data_articles_(list(list(name = "x", title = "x", href = "x", description = 1))) Condition Error in `data_articles_()`: ! In _pkgdown.yml, external-articles[1].description must be a string, not the number 1. # articles in vignettes/articles/ are unnested into articles/ Code build_redirects(pkg) Message -- Building redirects ---------------------------------------------------------- Adding redirect from articles/articles/nested.html to articles/nested.html. # warns about articles missing from index Code . <- data_articles_index(pkg) Condition Error: ! In _pkgdown.yml, 1 vignette missing from index: "c". ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/build-reference-index.md����������������������������������������������0000644�0001762�0000144�00000012216�14656154142�022704� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# can generate three types of row Code data_reference_index(pkg) Output pagetitle: Package index rows: - title: A slug: a desc: ~ is_internal: no - subtitle: B slug: b desc: ~ is_internal: no - topics: - path: a.html title: A lifecycle: ~ aliases: a() icon: ~ - path: b.html title: B lifecycle: ~ aliases: b() icon: ~ - path: c.html title: C lifecycle: ~ aliases: c() icon: ~ - path: e.html title: E lifecycle: ~ aliases: e icon: ~ - path: help.html title: D lifecycle: ~ aliases: '`?`()' icon: ~ names: - a - b - c - e - '?' row_has_icons: no is_internal: no has_icons: no # warns if missing topics Code data_reference_index(pkg) Condition Error: ! In _pkgdown.yml, 3 topics missing from index: "c", "e", and "?". i Either use `@keywords internal` to drop from index, or # gives informative errors Code data_reference_index_(1) Condition Error in `config_pluck_reference()`: ! In _pkgdown.yml, reference must be a list, not the number 1. Code data_reference_index_(list(1)) Condition Error in `data_reference_index_()`: ! In _pkgdown.yml, reference[1] must be a list, not the number 1. Code data_reference_index_(list(list(title = 1))) Condition Error in `data_reference_index_()`: ! In _pkgdown.yml, reference[1].title must be a string, not the number 1. Code data_reference_index_(list(list(title = "a\n\nb"))) Condition Error in `data_reference_index_()`: ! In _pkgdown.yml, reference[1].title must be inline markdown. Code data_reference_index_(list(list(subtitle = 1))) Condition Error in `data_reference_index_()`: ! In _pkgdown.yml, reference[1].subtitle must be a string, not the number 1. Code data_reference_index_(list(list(subtitle = "a\n\nb"))) Condition Error in `data_reference_index_()`: ! In _pkgdown.yml, reference[1].subtitle must be inline markdown. Code data_reference_index_(list(list(title = "bla", contents = 1))) Condition Error in `data_reference_index_()`: ! In _pkgdown.yml, reference[1].contents[1] must be a string. i You might need to add '' around special YAML values like 'N' or 'off' Code data_reference_index_(list(list(title = "bla", contents = NULL))) Condition Error in `data_reference_index_()`: ! In _pkgdown.yml, reference[1].contents is empty. Code data_reference_index_(list(list(title = "bla", contents = list("a", NULL)))) Condition Error in `data_reference_index_()`: ! In _pkgdown.yml, reference[1].contents[2] is empty. Code data_reference_index_(list(list(title = "bla", contents = list()))) Condition Error in `data_reference_index_()`: ! In _pkgdown.yml, reference[1].contents is empty. Code data_reference_index_(list(list(title = "bla", contents = "notapackage::lala"))) Condition Error in `build_reference_index()`: ! The package "notapackage" is required as it's used in the reference index. Code data_reference_index_(list(list(title = "bla", contents = "rlang::lala"))) Condition Error in `build_reference_index()`: ! Could not find documentation for `rlang::lala()`. # can use a topic from another package Code data_reference_index(pkg) Output pagetitle: Package index rows: - title: bla slug: bla desc: ~ is_internal: no - topics: - path: https://rlang.r-lib.org/reference/is_installed.html title: Are packages installed in any of the libraries? (from rlang) lifecycle: ~ aliases: - is_installed() - check_installed() icon: ~ - path: https://rstudio.github.io/bslib/reference/bs_bundle.html title: Add low-level theming customizations (from bslib) lifecycle: ~ aliases: - bs_add_variables() - bs_add_rules() - bs_add_functions() - bs_add_mixins() - bs_bundle() icon: ~ names: - rlang::is_installed() - bslib::bs_add_rules row_has_icons: no is_internal: no has_icons: no # can use a selector name as a topic name Code data_reference_index(pkg) Output pagetitle: Package index rows: - title: bla slug: bla desc: ~ is_internal: no - topics: - path: matches.html title: matches lifecycle: ~ aliases: matches() icon: ~ - path: A.html title: A lifecycle: ~ aliases: A() icon: ~ names: - matches - A row_has_icons: no is_internal: no has_icons: no ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/_snaps/check.md��������������������������������������������������������������0000644�0001762�0000144�00000004537�14656154152�017631� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# sitrep complains about BS3 Code pkgdown_sitrep(pkg) Message -- Sitrep ---------------------------------------------------------------------- x Bootstrap 3 is deprecated; please switch to Bootstrap 5. i Learn more at <https://www.tidyverse.org/blog/2021/12/pkgdown-2-0-0/#bootstrap-5>. v URLs ok. v Favicons ok. v Open graph metadata ok. v Articles metadata ok. v Reference metadata ok. # sitrep reports all problems Code pkgdown_sitrep(pkg) Message -- Sitrep ---------------------------------------------------------------------- x URLs not ok. In DESCRIPTION, URL is missing package url (http://test.org). See details in `vignette(pkgdown::metadata)`. v Favicons ok. v Open graph metadata ok. v Articles metadata ok. x Reference metadata not ok. In _pkgdown.yml, 1 topic missing from index: "?". Either use `@keywords internal` to drop from index, or # checks fails on first problem Code check_pkgdown(pkg) Condition Error in `check_pkgdown()`: ! In DESCRIPTION, URL is missing package url (http://test.org). i See details in `vignette(pkgdown::metadata)`. # both inform if everything is ok Code pkgdown_sitrep(pkg) Message -- Sitrep ---------------------------------------------------------------------- v URLs ok. v Favicons ok. v Open graph metadata ok. v Articles metadata ok. v Reference metadata ok. Code check_pkgdown(pkg) Message v No problems found. # check_urls reports problems Code check_urls(pkg) Condition Error: ! In _pkgdown.yml, url is missing. i See details in `vignette(pkgdown::metadata)`. --- Code check_urls(pkg) Condition Error: ! In DESCRIPTION, URL is missing package url (https://testpackage.r-lib.org). i See details in `vignette(pkgdown::metadata)`. # check_favicons reports problems Code check_favicons(pkg) Condition Error in `check_favicons()`: ! Found package logo but not favicons. i Do you need to run `build_favicons()`? --- Code check_favicons(pkg) Condition Error in `check_favicons()`: ! Package logo is newer than favicons. i Do you need to rerun `build_favicons()`? �����������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/test-templates.R�������������������������������������������������������������0000644�0001762�0000144�00000013425�14633374223�020037� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������test_that("template_candidates look for specific first", { expect_equal( path_file(template_candidates("content", "article")), c("content-article.html", "content.html") ) }) test_that("template_candidates look in template dir then pkgdown", { pkg_dir <- withr::local_tempdir() template_dir <- withr::local_tempdir() pkg <- list( src_path = pkg_dir, meta = list(template = list(path = template_dir)), bs_version = 3 ) # ensure that templates_dir(pkg) returns the specific template path expect_equal(templates_dir(pkg), path(template_dir)) paths <- template_candidates("content", "article", pkg = pkg) dirs <- unique(path_dir(paths)) expect_equal( dirs, c( # search for candidates... path(pkg_dir, "pkgdown", "templates"), # first in local templates path(template_dir), # second in global template path path_pkgdown("BS3", "templates") # finally in pkgdown templates ) ) }) test_that("look for templates_dir in right places", { dir <- withr::local_tempdir() pkg <- list(src_path = dir, meta = list(template = list())) # Look in site templates expect_equal(templates_dir(pkg), path(dir, "pkgdown", "templates")) # Look in specified directory pkg$meta$template$path <- path(withr::local_tempdir()) expect_equal(templates_dir(pkg), pkg$meta$template$path) }) test_that("find templates in local pkgdown first", { pkg <- test_path("assets", "templates-local") # local template used over default pkgdown template expect_equal( find_template("content", "article", pkg = pkg), path_abs(path(pkg, "pkgdown", "templates", "content-article.html")) ) expect_equal( find_template("footer", "article", pkg = pkg), path_abs(path(pkg, "pkgdown", "templates", "footer-article.html")) ) # pkgdown template used (no local template) expect_equal( find_template("content", "tutorial", pkg = pkg), path_pkgdown("BS3", "templates", "content-tutorial.html") ) expect_equal( find_template("footer", "ignored", pkg = pkg), path_pkgdown("BS3", "templates", "footer.html") ) }) # Expected contents ------------------------------------------------------- test_that("BS5 templates have main + aside", { names <- dir_ls(path_pkgdown("BS5", "templates"), regexp = "content-") names <- path_ext_remove(path_file(names)) names <- gsub("content-", "", names) templates <- lapply(names, read_template_html, type = "content", pkg = list(bs_version = 5) ) for (i in seq_along(templates)) { template <- templates[[i]] name <- names[[i]] expect_equal(xpath_length(template, ".//div/main"), 1, info = name) expect_equal(xpath_attr(template, ".//div/main", "id"), "main", info = name) expect_equal(xpath_length(template, ".//div/aside"), 1, info = name) expect_equal(xpath_attr(template, ".//div/aside", "class"), "col-md-3", info = name) } }) # Bootstrap version resolution -------------------------------------------- test_that("Bootstrap version in template package under `template.bootstrap`", { path_template_package <- local_pkgdown_template_pkg( meta = list(template = list(bootstrap = 5)) ) pkg <- local_pkgdown_site(meta = list(template = list(package = "templatepackage"))) expect_equal(pkg$bs_version, 5) }) test_that("Bootstrap version in template package under `template.bslib.version`", { path_template_package <- local_pkgdown_template_pkg( meta = list(template = list(bslib = list(version = 5))) ) pkg <- local_pkgdown_site(meta = list(template = list(package = "templatepackage"))) expect_equal(pkg$bs_version, 5) }) test_that("Invalid bootstrap version spec in template package", { path_template_package <- local_pkgdown_template_pkg( meta = list(template = list(bootstrap = 4, bslib = list(version = 5))) ) expect_snapshot( error = TRUE, local_pkgdown_site(meta = list(template = list(package = "templatepackage"))) ) }) test_that("Invalid bootstrap version spec in _pkgdown.yml", { expect_snapshot( error = TRUE, local_pkgdown_site(meta = list(template = list( bootstrap = 4, bslib = list(version = 5) ))) ) }) test_that("Valid local Bootstrap version masks invalid template package", { path_template_package <- local_pkgdown_template_pkg( meta = list(template = list(bootstrap = 4, bslib = list(version = 5))) ) expect_no_error( local_pkgdown_site(meta = list(template = list( package = "templatepackage", bootstrap = 5 ))) ) }) # Bootstrap theme resolution ---------------------------------------------- test_that("Finds Bootstrap theme in all the places", { pkg_sketchy <- local_pkgdown_site(meta = list(template = list(bslib = list(preset = "sketchy", version = 5))) ) pkg_cosmo <- local_pkgdown_site(meta = list(template = list(bootstrap = 5, bootswatch = "cosmo")) ) pkg_yeti <- local_pkgdown_site(meta = list(template = list(bootstrap = 5, params = list(bootswatch = "yeti"))) ) expect_equal(get_bslib_theme(pkg_sketchy), "sketchy") expect_equal(get_bslib_theme(pkg_cosmo), "cosmo") expect_equal(get_bslib_theme(pkg_yeti), "yeti") }) test_that("Warns when Bootstrap theme is specified in multiple locations", { pkg <- local_pkgdown_site(meta = list( template = list( bootstrap = 5, bootswatch = "cerulean", bslib = list(preset = "flatly", bootswatch = "lux"), params = list(bootswatch = "darkly") ) )) expect_snapshot(get_bslib_theme(pkg)) }) test_that("Doesn't warn when the same Bootstrap theme is specified in multiple locations", { pkg <- local_pkgdown_site(meta = list(template = list( bootstrap = 5, bootswatch = "cerulean", bslib = list(preset = "cerulean") )) ) expect_equal(expect_silent(get_bslib_theme(pkg)), "cerulean") }) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/test-repo.R������������������������������������������������������������������0000644�0001762�0000144�00000014252�14634573316�017012� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# repo_auto_link --------------------------------------------------------- test_that("authors are automatically linked", { pkg <- list(repo = repo_meta(user = "TEST/")) # email addresses shouldn't get linked expect_equal(repo_auto_link(pkg, "x@y.com"), "x@y.com") # must have leading whitespace or open parens expect_equal(repo_auto_link(pkg, "@y"), "<a href='TEST/y'>@y</a>") expect_equal(repo_auto_link(pkg, " @y"), " <a href='TEST/y'>@y</a>") expect_equal(repo_auto_link(pkg, "(@y)"), "(<a href='TEST/y'>@y</a>)") expect_equal(repo_auto_link(pkg, "<p>@y some other text.</p>"), "<p><a href='TEST/y'>@y</a> some other text.</p>") }) test_that("issues are automatically linked", { pkg <- list(repo = repo_meta(issue = "TEST/")) expect_equal(repo_auto_link(pkg, "(#123"), "(<a href='TEST/123'>#123</a>") expect_equal(repo_auto_link(pkg, "in #123"), "in <a href='TEST/123'>#123</a>") expect_equal(repo_auto_link(pkg, "<p>#123 some other text.</p>"), "<p><a href='TEST/123'>#123</a> some other text.</p>") expect_equal(repo_auto_link(pkg, "<p><a href='TEST/123/'>#123</a></p>"), "<p><a href='TEST/123/'>#123</a></p>") }) test_that("already linked issues aren't re-linked", { pkg <- list(repo = repo_meta(issue = "TEST/")) expect_equal(repo_auto_link(pkg, "<p><a href='NOT/ABC/'>#123</a></p>"), "<p><a href='NOT/ABC/'>#123</a></p>") }) test_that("URLs with hash (#) are preserved", { pkg <- list(repo = repo_meta(issue = "TEST/")) expect_equal( repo_auto_link(pkg, "[example 5.4](https:/my.site#5-4-ad)"), "[example 5.4](https:/my.site#5-4-ad)" ) }) test_that("Jira issues are automatically linked", { pkg <- list(repo = repo_meta(issue = "TEST/")) pkg$repo$jira_projects <- c("JIRA", "OTHER") expect_equal(repo_auto_link(pkg, "JIRA-123"), "<a href='TEST/JIRA-123'>JIRA-123</a>") expect_equal(repo_auto_link(pkg, "OTHER-4321"), "<a href='TEST/OTHER-4321'>OTHER-4321</a>") # but only the jira projects specified are caught expect_equal(repo_auto_link(pkg, "NOPE-123"), "NOPE-123") }) # repo_source ------------------------------------------------------------- test_that("repo_source() truncates automatically", { withr::local_envvar(GITHUB_HEAD_REF = "HEAD") pkg <- list(repo = repo_meta_gh_like("https://github.com/r-lib/pkgdown")) expect_snapshot({ cat(repo_source(pkg, character())) cat(repo_source(pkg, "a")) cat(repo_source(pkg, letters[1:10])) }) }) test_that("repo_source() is robust to trailing slash", { pkg <- list(repo = repo_meta_gh_like("https://github.com/r-lib/pkgdown")) meta <- function(x) { list(repo = list(url = list(source = x))) } source <- "Source: <a href='http://example.com/a'><code>a</code></a>" expect_equal(repo_source(meta("http://example.com"), "a"), source) expect_equal(repo_source(meta("http://example.com/"), "a"), source) }) test_that("repo_source() uses the branch setting in meta", { pkg <- local_pkgdown_site( meta = list(repo = list(branch = "main")), desc = list(URL = "https://github.com/r-lib/pkgdown") ) expect_match( repo_source(pkg, "a"), "https://github.com/r-lib/pkgdown/blob/main/a" ) }) # package_repo ------------------------------------------------------------ test_that("can find github from BugReports or URL", { withr::local_envvar(GITHUB_HEAD_REF = "HEAD") expected <- repo_meta_gh_like("https://github.com/r-lib/pkgdown") pkg <- local_pkgdown_site(desc = list( URL = "https://github.com/r-lib/pkgdown" )) expect_equal(package_repo(pkg), expected) # BugReports beats URL pkg <- local_pkgdown_site(desc = list( URL = "https://github.com/r-lib/BLAHBLAH", BugReports = "https://github.com/r-lib/pkgdown/issues" )) expect_equal(package_repo(pkg), expected) # URL can be in any position pkg <- local_pkgdown_site(desc = list( URL = "https://pkgdown.r-lib.org, https://github.com/r-lib/pkgdown" )) expect_equal(package_repo(pkg), expected) }) test_that("can find gitlab url", { withr::local_envvar(GITHUB_HEAD_REF = "HEAD") url <- "https://gitlab.com/msberends/AMR" pkg <- local_pkgdown_site(desc = list(URL = url)) expect_equal(package_repo(pkg), repo_meta_gh_like(url)) }) test_that("uses GITHUB env vars if set", { withr::local_envvar(GITHUB_HEAD_REF = NA, GITHUB_REF_NAME = "abc") expect_equal( repo_meta_gh_like("https://github.com/r-lib/pkgdown")$url$source, "https://github.com/r-lib/pkgdown/blob/abc/" ) withr::local_envvar(GITHUB_HEAD_REF = "xyz") expect_equal( repo_meta_gh_like("https://github.com/r-lib/pkgdown")$url$source, "https://github.com/r-lib/pkgdown/blob/xyz/" ) }) test_that("GitLab subgroups are properly parsed", { issue_url <- function(...) { pkg <- local_pkgdown_site(desc = list(...)) pkg$repo$url$issue } base <- "https://gitlab.com/salim_b/r/pkgs/pal" expected <- paste0(base, "/issues/") expect_equal(issue_url(URL = base), expected) expect_equal(issue_url(URL = paste0(base, "/")), expected) expect_equal(issue_url(BugReports = paste0(base, "/issues")), expected) expect_equal(issue_url(BugReports = paste0(base, "/issues/")), expected) }) test_that("can find github enterprise url", { withr::local_envvar(GITHUB_HEAD_REF = "HEAD") url <- "https://github.acme.com/roadrunner/speed" pkg <- local_pkgdown_site(desc = list(BugReports = url)) expect_equal(package_repo(pkg), repo_meta_gh_like(url)) }) test_that("meta overrides autodetection", { pkg <- local_pkgdown_site( meta = list(repo = list(url = list(home = "http://one.com"))), desc = list(URL = "http://two.com") ) expect_equal(package_repo(pkg)$url$home, "http://one.com") }) test_that("returns NULL if no urls found", { pkg <- local_pkgdown_site(desc = list(URL = "https://pkgdown.r-lib.org")) expect_null(package_repo(pkg)) }) test_that("repo_type detects repo type", { repo_type2 <- function(url) { repo_type(list(repo = list(url = list(home = url)))) } expect_equal(repo_type2("https://github.com/r-lib/pkgdown"), "github") expect_equal(repo_type2("https://github.r-lib.com/pkgdown"), "github") expect_equal(repo_type2("https://gitlab.com/r-lib/pkgdown"), "gitlab") expect_equal(repo_type2("https://gitlab.r-lib.com/pkgdown"), "gitlab") expect_equal(repo_type2(NULL), "other") }) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/test-build-reference.R�������������������������������������������������������0000644�0001762�0000144�00000010774�14671042466�021103� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������test_that("parse failures include file name", { pkg <- local_pkgdown_site(test_path("assets/reference-fail")) expect_snapshot(build_reference(pkg), error = TRUE) }) test_that("examples_env runs pre and post code", { dst_path <- withr::local_tempdir() dir_create(path(dst_path, "reference")) pkg <- list( package = "test", src_path = test_path("assets/reference-pre-post"), dst_path = dst_path ) env <- local(examples_env(pkg)) expect_equal(env$a, 2) }) test_that("examples_env sets width", { pkg <- local_pkgdown_site( test_path("assets/reference"), list(code = list(width = 50)) ) dir_create(path(pkg$dst_path, "reference")) examples_env(pkg) expect_equal(getOption("width"), 50) }) test_that("test usage ok on rendered page", { pkg <- local_pkgdown_site( test_path("assets/reference"), list(template = list(bootstrap = 3)) ) suppressMessages(init_site(pkg)) suppressMessages(build_reference(pkg, topics = "c")) html <- xml2::read_html(path(pkg$dst_path, "reference", "c.html")) expect_equal(xpath_text(html, "//div[@id='ref-usage']", trim = TRUE), "c()") clean_site(pkg, quiet = TRUE) pkg <- local_pkgdown_site(test_path("assets/reference")) suppressMessages(init_site(pkg)) suppressMessages(build_reference(pkg, topics = "c")) html <- xml2::read_html(path(pkg$dst_path, "reference", "c.html")) # tweak_anchors() moves id into <h2> expect_equal(xpath_text(html, "//div[h2[@id='ref-usage']]/div", trim = TRUE), "c()") }) test_that(".Rd without usage doesn't get Usage section", { pkg <- local_pkgdown_site( test_path("assets/reference"), list(template = list(bootstrap = 3)) ) suppressMessages(init_site(pkg)) suppressMessages(build_reference(pkg, topics = "e")) html <- xml2::read_html(path(pkg$dst_path, "reference", "e.html")) expect_equal(xpath_length(html, "//div[@id='ref-usage']"), 0) clean_site(pkg, quiet = TRUE) pkg <- local_pkgdown_site(test_path("assets/reference")) suppressMessages(init_site(pkg)) suppressMessages(build_reference(pkg, topics = "e")) html <- xml2::read_html(path(pkg$dst_path, "reference", "e.html")) # tweak_anchors() moves id into <h2> expect_equal(xpath_length(html, "//div[h2[@id='ref-usage']]"), 0) }) test_that("pkgdown html dependencies are suppressed from examples in references", { pkg <- local_pkgdown_site(test_path("assets/reference-html-dep")) suppressMessages(init_site(pkg)) suppressMessages(build_reference(pkg, topics = "a")) html <- xml2::read_html(path(pkg$dst_path, "reference", "a.html")) # jquery is only loaded once, even though it's included by an example expect_equal(xpath_length(html, ".//script[(@src and contains(@src, '/jquery'))]"), 1) # same for bootstrap js and css str_subset_bootstrap <- function(x) { bs_rgx <- "bootstrap-[\\d.]+" # ex: bootstrap-5.1.0 not bootstrap-toc, grep(bs_rgx, x, value = TRUE, perl = TRUE) } bs_js_src <- str_subset_bootstrap( xpath_attr(html, ".//script[(@src and contains(@src, '/bootstrap'))]", "src") ) expect_length(bs_js_src, 1) bs_css_href <- str_subset_bootstrap( xpath_attr(html, ".//link[(@href and contains(@href, '/bootstrap'))]", "href") ) expect_length(bs_css_href, 1) }) test_that("examples are reproducible by default, i.e. 'seed' is respected", { pkg <- local_pkgdown_site(test_path("assets/reference")) suppressMessages(init_site(pkg)) suppressMessages(build_reference(pkg, topics = "f")) html <- xml2::read_html(path(pkg$dst_path, "reference", "f.html")) examples <- xpath_text(html, ".//code//*[contains(@class, 'r-out')]") expect_snapshot(cat(examples)) }) test_that("arguments get individual ids", { pkg <- local_pkgdown_site(test_path("assets/reference")) suppressMessages(init_site(pkg)) suppressMessages(build_reference(pkg, topics = "a")) html <- xml2::read_html(path(pkg$dst_path, "reference", "a.html")) expect_equal(xpath_attr(html, "//dt", "id"), c("arg-a", "arg-b", "arg-c")) }) test_that("title and page title escapes html", { pkg <- local_pkgdown_site(test_path("assets/reference")) suppressMessages(init_site(pkg)) suppressMessages(build_reference(pkg, topics = "g")) html <- xml2::read_html(path(pkg$dst_path, "reference", "g.html")) expect_equal(xpath_text(html, "//title", trim = TRUE), "g <-> h — g • testpackage") expect_equal(xpath_text(html, "//h1", trim = TRUE), "g <-> h") }) test_that("get_rdname handles edge cases", { expect_equal(get_rdname(list(file_in = "foo..Rd")), "foo.") expect_equal(get_rdname(list(file_in = "foo.rd")), "foo") }) ����pkgdown/tests/testthat/test-check-built.R�����������������������������������������������������������0000644�0001762�0000144�00000001040�14634573316�020226� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������test_that("check images in readme", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "README.md", "![foo](vignettes/kitten.jpg)") suppressMessages(build_home_index(pkg)) # no image, so should warn expect_snapshot(check_built_site(pkg)) # create and build vignette that uses image, so no warning pkg <- pkg_add_file(pkg, "vignettes/kitten.Rmd", "![foo](kitten.jpg)") pkg <- pkg_add_kitten(pkg, "vignettes") suppressMessages(build_article("kitten", pkg)) suppressMessages(expect_no_warning(check_built_site(pkg))) }) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/test-build-footer.R����������������������������������������������������������0000644�0001762�0000144�00000003730�14633374223�020432� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������test_that("works by default", { pkg <- structure( list( desc = desc::desc(text = "Authors@R: person('First', 'Last', role = 'cre')"), src_path = tempdir() ), class = "pkgdown" ) footer <- data_footer(pkg) footer$right <- gsub(packageVersion("pkgdown"), "{version}", footer$right, fixed = TRUE) expect_snapshot_output(footer) }) test_that("includes package component", { pkg <- structure( list( package = "noodlr", desc = desc::desc(text = "Authors@R: person('First', 'Last', role = 'cre')"), src_path = tempdir(), meta = list( footer = list( structure = list(left = "package") ) ) ), class = "pkgdown" ) expect_equal(data_footer(pkg)$left, "<p>noodlr</p>") }) test_that("can use custom components", { pkg <- structure(list( desc = desc::desc(text = "Authors@R: person('a', 'b', roles = 'cre')"), src_path = tempdir(), meta = list( footer = list( structure = list(left = "test"), components = list(test = "_test_") ) )), class = "pkgdown" ) expect_equal(data_footer(pkg)$left, "<p><em>test</em></p>") }) test_that("multiple components are pasted together", { pkg <- structure(list( desc = desc::desc(text = "Authors@R: person('a', 'b', roles = 'cre')"), src_path = tempdir(), meta = list( footer = list( structure = list(left = c("a", "b")), components = list(a = "a", b = "b") ) )), class = "pkgdown" ) expect_equal(data_footer(pkg)$left, "<p>a b</p>") }) test_that("validates meta components", { data_footer_ <- function(...) { pkg <- local_pkgdown_site(meta = list(...)) data_footer(pkg) } expect_snapshot(error = TRUE, { data_footer_(footer = 1) data_footer_(footer = list(structure = 1)) data_footer_(footer = list(components = 1)) data_footer_(authors = list(footer = list(roles = 1))) data_footer_(authors = list(footer = list(text = 1))) }) })����������������������������������������pkgdown/tests/testthat/test-config.R����������������������������������������������������������������0000644�0001762�0000144�00000002612�14633374223�017302� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test_that("config_pluck_character coerces empty values to character", { pkg <- local_pkgdown_site(meta = list(x = NULL, y = list())) expect_equal(config_pluck_character(pkg, "x"), character()) expect_equal(config_pluck_character(pkg, "y"), character()) expect_equal(config_pluck_character(pkg, "z"), character()) }) test_that("config_pluck_character generates informative error", { pkg <- local_pkgdown_site(meta = list(x = 1)) expect_snapshot(config_pluck_character(pkg, "x"), error = TRUE) }) test_that("config_pluck_string generates informative error", { pkg <- local_pkgdown_site(meta = list(x = 1)) expect_snapshot(config_pluck_string(pkg, "x"), error = TRUE) }) # checkers -------------------------------------------------------------------- test_that("config_check_list() returns list if ok", { x <- list(x = 1, y = 2) expect_equal(config_check_list(x), x) expect_equal(config_check_list(x, has_names = "x"), x) expect_equal(config_check_list(x, has_names = c("x", "y")), x) }) test_that("config_check_list gives informative errors", { # Avoid showing unneeded call details in snapshot pkg <- local_pkgdown_site() config_check_list_ <- function(...) { config_check_list(..., error_pkg = pkg, error_path = "path") } expect_snapshot(error = TRUE, { config_check_list_(1, has_names = "x") config_check_list_(list(x = 1, y = 1), has_names = c("y", "z")) }) }) ����������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/test-build-home-license.R����������������������������������������������������0000644�0001762�0000144�00000001067�14671042466�021510� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������test_that("link_license matchs exactly", { # Shouldn't match first GPL-2 expect_equal( autolink_license("LGPL-2"), "<a href='https://www.r-project.org/Licenses/LGPL-2'>LGPL-2</a>" ) expect_equal( autolink_license("MPL-2.0"), "<a href='https://www.mozilla.org/en-US/MPL/2.0/'>MPL-2.0</a>" ) }) test_that("link_license matches LICENSE", { expect_equal( autolink_license("LICENSE"), "<a href='LICENSE-text.html'>LICENSE</a>" ) expect_equal( autolink_license("LICENCE"), "<a href='LICENSE-text.html'>LICENCE</a>" ) }) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/test-build-articles.R��������������������������������������������������������0000644�0001762�0000144�00000007564�14634573316�020760� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������test_that("can recognise intro variants", { expect_true(article_is_intro("package", "package")) expect_true(article_is_intro("articles/package", "package")) expect_true(article_is_intro("pack-age", "pack.age")) expect_true(article_is_intro("articles/pack-age", "pack.age")) }) test_that("validates articles yaml", { data_articles_index_ <- function(x) { pkg <- local_pkgdown_site(meta = list(articles = x)) data_articles_index(pkg) } expect_snapshot(error = TRUE, { data_articles_index_(1) data_articles_index_(list(1)) data_articles_index_(list(list())) data_articles_index_(list(list(title = 1, contents = 1))) data_articles_index_(list(list(title = "a\n\nb", contents = 1))) data_articles_index_(list(list(title = "a", contents = 1))) }) }) test_that("validates external-articles", { data_articles_ <- function(x) { pkg <- local_pkgdown_site(meta = list(`external-articles` = x)) data_articles(pkg) } expect_snapshot(error = TRUE, { data_articles_(1) data_articles_(list(1)) data_articles_(list(list(name = "x"))) data_articles_(list(list(name = 1, title = "x", href = "x", description = "x"))) data_articles_(list(list(name = "x", title = 1, href = "x", description = "x"))) data_articles_(list(list(name = "x", title = "x", href = 1, description = "x"))) data_articles_(list(list(name = "x", title = "x", href = "x", description = 1))) }) }) test_that("data_articles includes external articles", { pkg <- local_pkgdown_site(meta = list( `external-articles` = list( list(name = "c", title = "c", href = "c", description = "*c*") ) )) pkg <- pkg_add_file(pkg, "vignettes/a.Rmd") pkg <- pkg_add_file(pkg, "vignettes/b.Rmd") articles <- data_articles(pkg) expect_equal(articles$name, c("a", "b", "c")) expect_equal(articles$internal, rep(FALSE, 3)) expect_equal(articles$description, list(NULL, NULL, "<p><em>c</em></p>")) }) test_that("articles in vignettes/articles/ are unnested into articles/", { # weird path differences that I don't have the energy to dig into skip_on_cran() pkg <- local_pkgdown_site(meta = list(url = "https://example.com")) pkg <- pkg_add_file(pkg, "vignettes/articles/nested.Rmd") nested <- pkg$vignettes[pkg$vignettes$name == "articles/nested", ] expect_equal(nested$file_out, "articles/nested.html") # Check automatic redirect from articles/articles/foo.html -> articles/foo.html expect_snapshot(build_redirects(pkg)) }) test_that("warns about articles missing from index", { pkg <- local_pkgdown_site(meta = list( articles = list( list(title = "External", contents = c("a", "b")) ) )) pkg <- pkg_add_file(pkg, "vignettes/a.Rmd") pkg <- pkg_add_file(pkg, "vignettes/b.Rmd") pkg <- pkg_add_file(pkg, "vignettes/c.Rmd") expect_snapshot(. <- data_articles_index(pkg), error = TRUE) }) test_that("internal articles aren't included and don't trigger warning", { pkg <- local_pkgdown_site(meta = list(articles = list( list(title = "External", contents = c("a", "b")), list(title = "internal", contents = "c") ) ) ) pkg <- pkg_add_file(pkg, "vignettes/a.Rmd") pkg <- pkg_add_file(pkg, "vignettes/b.Rmd") pkg <- pkg_add_file(pkg, "vignettes/c.Rmd") expect_no_error(index <- data_articles_index(pkg)) expect_length(index$sections, 1) expect_length(index$sections[[1]]$contents, 2) }) test_that("default template includes all articles", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/a.Rmd") expect_equal(default_articles_index(pkg)[[1]]$contents, "a") }) test_that("check doesn't include getting started vignette", { pkg <- local_pkgdown_site(meta = list( articles = list(list(title = "Vignettes", contents = "a")) )) pkg <- pkg_add_file(pkg, "vignettes/a.Rmd") pkg <- pkg_add_file(pkg, "vignettes/testpackage.Rmd") expect_no_error(data_articles_index(pkg)) }) ��������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/test-development.R�����������������������������������������������������������0000644�0001762�0000144�00000003540�14633374223�020360� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������test_that("empty yaml gets correct defaults", { pkg <- local_pkgdown_site() expect_equal(pkg$development$mode, "default") expect_equal(pkg$development$in_dev, FALSE) expect_equal(pkg$development$version_label, "muted") }) test_that("mode = auto uses version", { pkg <- local_pkgdown_site( desc = list(Version = "0.0.9000"), meta = list(development = list(mode = "auto")) ) expect_equal(pkg$development$mode, "devel") expect_equal(pkg$development$in_dev, TRUE) expect_equal(pkg$development$version_label, "danger") }) test_that("mode overrides version", { pkg <- local_pkgdown_site( desc = list(Version = "0.0.9000"), meta = list(development = list(mode = "release")) ) expect_equal(pkg$development$mode, "release") }) test_that("env var overrides mode", { withr::local_envvar("PKGDOWN_DEV_MODE" = "devel") pkg <- local_pkgdown_site( meta = list(development = list(mode = "release")) ) expect_equal(pkg$development$mode, "devel") }) test_that("dev_mode recognises basic version structure", { expect_equal(dev_mode_auto("0.0.0.9000"), "unreleased") expect_equal(dev_mode_auto("0.0.1"), "release") expect_equal(dev_mode_auto("0.1"), "release") expect_equal(dev_mode_auto("0.1.0"), "release") expect_equal(dev_mode_auto("0.1.9000"), "devel") expect_equal(dev_mode_auto("1.0"), "release") expect_equal(dev_mode_auto("1.0.0"), "release") expect_equal(dev_mode_auto("1.0.0.9000"), "devel") }) test_that("validates yaml", { data_development_ <- function(...) { local_pkgdown_site(meta = list(...) ) } expect_snapshot(error = TRUE, { data_development_(development = 1) data_development_(development = list(mode = 1)) data_development_(development = list(mode = "foo")) data_development_(development = list(destination = 1)) data_development_(development = list(version_label = 1)) }) }) ����������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/test-build-news.R������������������������������������������������������������0000644�0001762�0000144�00000015714�14657466716�020134� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������test_that("data_news works as expected for h1 & h2", { skip_if_no_pandoc() lines_h1 <- c( "# testpackage 1.0.0.9000", "", "* bullet (#222 @someone)", "", "# testpackage 1.0.0", "", "## sub-heading", "", "* first thing (#111 @githubuser)", "", "* second thing", "" ) lines_h2 <- gsub("^#", "##", lines_h1) pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "NEWS.md", lines_h1) expect_snapshot_output(data_news(pkg)[c("version", "page", "anchor")]) pkg <- pkg_add_file(pkg, "NEWS.md", lines_h2) expect_snapshot_output(data_news(pkg)[c("version", "page", "anchor")]) }) test_that("news is syntax highlighted once", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "NEWS.md", c( "# testpackage 1.0.0.9000", "```r", "x <- 1", "```" )) suppressMessages(build_news(pkg, preview = FALSE)) html <- xml2::read_html(path(pkg$dst_path, "news", "index.html")) expect_equal(xpath_text(html, "//code"), "x <- 1") }) test_that("multi-page news are rendered", { skip_if_no_pandoc() pkg <- local_pkgdown_site(meta = list(news = list(one_page = FALSE))) pkg <- pkg_add_file(pkg, "NEWS.md", c( "# testpackage 2.0", "", "* bullet (#222 @someone)", "", "# testpackage 1.1", "", "* bullet (#222 @someone)", "", "# testpackage 1.0.1", "", "* bullet (#222 @someone)", "", "# testpackage 1.0.0", "", "## sub-heading", "", "* first thing (#111 @githubuser)", "", "* second thing" )) expect_snapshot(data_news(pkg)[c("version", "page", "anchor")]) expect_snapshot(build_news(pkg)) # test that index links are correct lines <- xml2::read_html(path(pkg$dst_path, "news", "index.html")) expect_equal( xpath_attr(lines, "//main//a", "href"), c("news-2.0.html", "news-1.1.html", "news-1.0.html") ) expect_equal( xpath_text(lines, "//main//a"), c("Version 2.0", "Version 1.1", "Version 1.0") ) # test single page structure lines <- xml2::read_html(path(pkg$dst_path, "news", "news-1.0.html")) expect_equal(xpath_text(lines, ".//h1"), "Version 1.0") expect_equal(xpath_text(lines, ".//main//h2"), c("testpackage 1.0.0", "testpackage 1.0.1")) }) test_that("github links are added to news items", { skip_if_no_pandoc() pkg <- local_pkgdown_site(meta = list( repo = list( url = list( home = "https://github.com/r-lib/pkgdown", user = "https://github.com/", issue = "https://github.com/r-lib/pkgdown/issues/" ) ) )) pkg <- pkg_add_file(pkg, "NEWS.md", c( "# testpackage 0.1.0", "", "## Major changes", "", "- Bug fixes (@hadley, #100)", "", "- Merges (@josue-rodriguez)" )) news_tbl <- data_news(pkg) html <- xml2::read_xml(news_tbl$html) expect_equal( xpath_attr(html, ".//a", "href"), c( "https://github.com/hadley", "https://github.com/r-lib/pkgdown/issues/100", "https://github.com/josue-rodriguez" ) ) }) test_that("pkg_timeline fails cleanly for unknown package", { skip_on_cran() expect_null(pkg_timeline("__XYZ__")) }) test_that("pkg_timeline works for package that have been archived", { skip_on_cran() expect_no_error(pkg_timeline("PF")) }) test_that("correct timeline for first ggplot2 releases", { skip_on_cran() timeline <- pkg_timeline("ggplot2")[1:3, ] expected <- data.frame( version = c("0.5", "0.5.1", "0.5.2"), date = as.Date(c("2007-06-01", "2007-06-09", "2007-06-18")) ) expect_equal(timeline, expected) }) # news_title and version_page ----------------------------------------------- test_that("can recognise common forms of title", { # Variants in beginning version <- news_version(c( "foo 1.3.0", "foo v1.3.0", "foo 1.3.0", "VERSION 1.3.0", "changes in 1.3.0", "changes in foo version 1.3.0" ), "foo") expect_equal(version, rep("1.3.0", length(version))) # Variants in version spec expect_equal( news_version(c("foo 1-2", "foo 1-2-3", "foo 1-2-3-4"), "foo"), c("1-2", "1-2-3", "1-2-3-4") ) expect_equal( news_version("foo (development version)", "foo"), "development version" ) }) test_that("correctly collapses version to page for common cases", { versions <- c("1.0.0", "1.0.0.0", "1.0.0.9000", "development version") pages <- purrr::map_chr(versions, version_page) expect_equal(pages, c("1.0", "1.0", "dev", "dev")) }) # Tweaks ------------------------------------------------------------------ test_that("sections tweaked down a level", { html <- xml2::read_xml("<body> <div class='section level1'><h1></h1></div> <div class='section level2'><h2></h2></div> <div class='section level3'><h3></h3></div> <div class='section level4'><h4></h4></div> <div class='section level5'><h5></h5></div> </body>") tweak_section_levels(html) expect_equal(xml2::xml_name(xpath_xml(html, "//div/*")), paste0("h", 2:6)) expect_equal(xpath_attr(html, "//div", "class"), paste0("section level", 2:6)) }) test_that("anchors de-duplicated with version", { html <- xml2::read_xml("<body> <div class='section' id='x-1'>Heading</div> </body>") tweak_news_anchor(html, "1.0") expect_equal(xpath_attr(html, ".//div", "id"), "x-1-0") }) test_that("news headings get class and release date", { timeline <- tibble::tibble(version = "1.0", date = "2020-01-01") html <- xml2::read_xml("<div><h2></h2></div>") tweak_news_heading(html, version = "1.0", timeline = timeline, bs_version = 3) expect_snapshot_output(xpath_xml(html, "//div")) html <- xml2::read_xml("<div><h2></h2></div>") tweak_news_heading(html, version = "1.0", timeline = timeline, bs_version = 4) expect_snapshot_output(xpath_xml(html, "//div")) }) # Header checks ---------------------------------------------------------- test_that("clear error for bad hierarchy - bad nesting", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "NEWS.md", c( "### testpackage 1.0.0.9000", "", "* bullet (#222 @someone)", "", "# testpackage 1.0.0", "", "## sub-heading", "", "* first thing (#111 @githubuser)", "", "* second thing", "" )) expect_snapshot(data_news(pkg), error = TRUE) }) test_that("clear error for bad hierarchy - h3", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "NEWS.md", c( "### testpackage 1.0.0.9000", "", "* bullet (#222 @someone)", "", "### testpackage 1.0.0", "", "#### sub-heading", "", "* first thing (#111 @githubuser)", "", "* second thing", "" )) expect_snapshot(data_news(pkg), error = TRUE) }) test_that("news can contain footnotes", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "NEWS.md", c( "## testpackage 1.0.0.9000", "", "* bullet", "", "* inline footnote^[used to fail] ", "" )) expect_snapshot(x <- data_news(pkg)) }) test_that("data_news warns if no headings found", { skip_if_no_pandoc() pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "NEWS.md", c( "# mypackage", "", "## mypackage foo", "", "## mypackage bar", "" )) expect_snapshot(. <- data_news(pkg)) }) ����������������������������������������������������pkgdown/tests/testthat/test-tweak-page.R������������������������������������������������������������0000644�0001762�0000144�00000007307�14633374223�020070� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������test_that("links to vignettes & figures tweaked", { html <- xml2::read_html('<body> <img src="vignettes/x.png" /> <img src="../vignettes/x.png" /> <img src="man/figures/x.png" /> <img src="../man/figures/x.png" /> </body>') tweak_page(html, "article", list(bs_version = 3, desc = desc::desc(text = ""))) expect_equal( xpath_attr(html, ".//img", "src"), c("articles/x.png", "../articles/x.png", "reference/figures/x.png", "../reference/figures/x.png") ) }) test_that("reference index table is not altered", { html <- xml2::read_html("<body> <div class='template-reference-index'> <table></table> </div> </body>") pkg <- list(bs_version = 3, desc = desc::desc(text = "")) tweak_page(html, "reference-index", pkg) expect_equal(xpath_attr(html, ".//table", "class"), NA_character_) }) test_that("articles get rescue highlighting for non-collapsed output", { html <- xml2::read_xml("<body> <pre><code>1</code></pre> <pre class='downlit'><code>1</code></pre> <div class='sourceCode'><pre><code>1</code></pre></div> </body>") pkg <- list(bs_version = 3, desc = desc::desc(text = "")) tweak_page(html, "article", pkg) pre <- xml2::xml_find_all(html, ".//pre") expect_equal(xml2::xml_find_num(pre, "count(.//span[@class])"), c(1, 0, 0)) }) test_that("toc removed if one or fewer headings", { html <- xml2::read_html("<body> <main><h2></h2><h2></h2></main> <nav id='toc'></nav> </body>") tweak_useless_toc(html) expect_equal(xpath_length(html, ".//nav"), 1) html <- xml2::read_html("<body> <main><h2></h2></main> <nav id='toc'></nav> </body>") tweak_useless_toc(html) expect_equal(xpath_length(html, ".//nav"), 0) html <- xml2::read_html("<body> <main></main> <nav id='toc'></nav> </body>") tweak_useless_toc(html) expect_equal(xpath_length(html, ".//nav"), 0) }) test_that("toc removed if one or fewer headings", { html <- xml2::read_html("<body> <main><h2></h2><h2></h2></main> <aside><nav id='toc'></nav></aside> </body>") tweak_useless_toc(html) expect_equal(xpath_length(html, ".//nav"), 1) html <- xml2::read_html("<body> <main><h2></h2></main> <aside><nav id='toc'></nav></aside> </body>") tweak_useless_toc(html) expect_equal(xpath_length(html, ".//nav"), 0) html <- xml2::read_html("<body> <main></main> <aside><nav id='toc'></nav></aside> </body>") tweak_useless_toc(html) expect_equal(xpath_length(html, ".//nav"), 0) }) test_that("sidebar removed if empty", { html <- xml2::read_html("<body> <main></main> <aside><nav id='toc'></nav></aside> </body>") tweak_useless_toc(html) expect_equal(xpath_length(html, ".//div"), 0) }) test_that("sidebar removed if empty", { html <- xml2::read_html("<body> <main></main> <aside><nav id='toc'></nav></aside> </body>") tweak_useless_toc(html) expect_equal(xpath_length(html, ".//aside"), 0) }) # rmarkdown --------------------------------------------------------------- test_that("h1 section headings adjusted to h2 (and so on)", { html <- xml2::read_html(" <div class='page-header'> <h1>Title</h1> <h4>Author</h4> </div> <div class='section level1'> <h1>1</h1> <div class='section level2'> <h2>1.1</h2> </div> </div> <div class='section level1'> <h1>2</h1> </div> ") tweak_rmarkdown_html(html) expect_equal(xpath_text(html, ".//h1"), "Title") expect_equal(xpath_text(html, ".//h2"), c("1", "2")) expect_equal(xpath_text(html, ".//h3"), "1.1") expect_equal(xpath_text(html, ".//h4"), "Author") expect_equal( xpath_attr(html, ".//div", "class"), c("page-header", "section level2", "section level3", "section level2") ) }) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/test-build-logo.R������������������������������������������������������������0000644�0001762�0000144�00000000756�14633374223�020101� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������test_that("can handle logo in subdir", { src <- withr::local_tempdir() dst <- withr::local_tempdir() dir_create(path(src, "man", "figures")) file_create(path(src, "man", "figures", "logo.svg")) pkg <- structure(list(src_path = src, dst_path = dst), class = "pkgdown") expect_true(has_logo(pkg)) suppressMessages(copy_logo(pkg)) expect_true(file_exists(path(dst, "logo.svg"))) expect_equal(logo_path(pkg, 0), "logo.svg") expect_equal(logo_path(pkg, 1), "../logo.svg") }) ������������������pkgdown/tests/testthat/test-build-quarto-articles.R�������������������������������������������������0000644�0001762�0000144�00000005776�14634573316�022274� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������test_that("can build all quarto article", { skip_if_no_quarto() pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/vig1.qmd") pkg <- pkg_add_file(pkg, "vignettes/vig2.qmd") suppressMessages(build_articles(pkg)) expect_true(file_exists(path(pkg$dst_path, "articles/vig1.html"))) expect_true(file_exists(path(pkg$dst_path, "articles/vig2.html"))) }) test_that("can build a single quarto article", { skip_if_no_quarto() pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/vig1.qmd") pkg <- pkg_add_file(pkg, "vignettes/vig2.qmd") suppressMessages(build_article("vig1", pkg)) expect_true(file_exists(path(pkg$dst_path, "articles/vig1.html"))) expect_false(file_exists(path(pkg$dst_path, "articles/vig2.html"))) }) test_that("doesn't do anything if no quarto articles", { pkg <- local_pkgdown_site() expect_no_error(suppressMessages(build_quarto_articles(pkg))) }) test_that("can render a pdf qmd", { skip_if_no_quarto() pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/vig1.qmd", pkg_vignette( format = list(pdf = list(toc = TRUE)) )) expect_equal(pkg$vignettes$type, "qmd") expect_equal(pkg$vignettes$file_out, "articles/vig1.pdf") suppressMessages(build_article("vig1", pkg)) expect_true(file_exists(path(pkg$dst_path, "articles/vig1.pdf"))) }) test_that("auto-adjusts heading levels", { skip_if_no_quarto() pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/vig1.qmd", pkg_vignette( "# Heading 1", "# Heading 2" )) suppressMessages(build_article("vig1", pkg)) html <- xml2::read_html(path(pkg$dst_path, "articles/vig1.html")) expect_equal(xpath_text(html, "//h1"), "title") expect_equal(xpath_text(html, "//h2"), c("Heading 1\n", "Heading 2\n")) }) test_that("we find out if quarto styles change", { skip_if_no_quarto() pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/vig1.qmd") output_dir <- quarto_render(pkg, path(pkg$src_path, "vignettes", "vig1.qmd")) data <- data_quarto_article(pkg, path(output_dir, "vig1.html"), "vig1.qmd") expect_snapshot(cat(data$includes$style)) }) test_that("quarto articles are included in the index", { skip_if_no_quarto() pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/vig1.qmd", pkg_vignette( "## Heading 1", "Some text" )) suppressMessages(build_article("vig1", pkg)) index <- build_search_index(pkg) expect_equal(index[[1]]$path, "/articles/vig1.html") expect_equal(index[[1]]$what, "Heading 1") expect_equal(index[[1]]$text, "text") # some is a stop word }) test_that("quarto headings get anchors", { skip_if_no_quarto() pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/vig1.qmd", pkg_vignette( "## Heading 1", "### Heading 2" )) suppressMessages(build_article("vig1", pkg)) html <- xml2::read_html(path(pkg$dst_path, "articles/vig1.html")) headings <- xpath_xml(html, "//h2|//h3") expect_equal(xpath_attr(headings, "./a", "href"), c("#heading-1", "#heading-2")) }) ��pkgdown/tests/testthat/test-build-search-docs.R�����������������������������������������������������0000644�0001762�0000144�00000004054�14634573316�021334� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������test_that("docsearch.json and sitemap.xml are valid for BS 3 site", { pkg <- local_pkgdown_site( meta = list( url = "https://example.com", template = list( bootstrap = 3, params = list( docsearch = list( api_key = "test-api-key", index_name = "test-index-name" ) ) ) ) ) suppressMessages(build_docsearch_json(pkg)) json <- path(pkg$dst_path, "docsearch.json") expect_true(jsonlite::validate(read_lines(json))) suppressMessages(build_sitemap(pkg)) xml <- path(pkg$dst_path, "sitemap.xml") schema <- xml2::read_xml(test_path("assets/sitemaps-schema-0.9.xsd")) expect_true(xml2::xml_validate(xml2::read_xml(xml), schema)) }) test_that("build_search_index() has expected structure", { pkg <- local_pkgdown_site( desc = list(Version = "1.0.0"), meta = list(url = "https://example.com") ) pkg <- pkg_add_file(pkg, "README.md", c( "# My Package", "What the pakage does" )) suppressMessages(init_site(pkg)) suppressMessages(build_home_index(pkg)) expect_snapshot(str(build_search_index(pkg))) }) test_that("build sitemap only messages when it updates", { pkg <- local_pkgdown_site(meta = list(url = "https://example.com")) suppressMessages(init_site(pkg)) suppressMessages(build_home(pkg)) expect_snapshot({ build_sitemap(pkg) build_sitemap(pkg) }) }) test_that("build_search() builds the expected search.json with no URL", { pkg <- local_pkgdown_site(desc = list(Version = "1.0.0")) pkg <- pkg_add_file(pkg, "README.md", c( "# My Package", "What the pakage does" )) suppressMessages(build_home(pkg)) index <- build_search_index(pkg) paths <- purrr::map_chr(index, "path") expect_equal(paths, c("/authors.html", "/authors.html", "/index.html")) }) test_that("sitemap excludes redirects", { pkg <- local_pkgdown_site(meta = list( url = "https://example.com", redirects = list(c("a.html", "b.html")) )) suppressMessages(build_redirects(pkg)) expect_equal(get_site_paths(pkg), character()) }) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/test-build-article.R���������������������������������������������������������0000644�0001762�0000144�00000025370�14657466716�020602� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������test_that("can build article that uses html_vignette", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/test.Rmd", pkg_vignette( output = "rmarkdown::html_vignette", pkgdown = list(as_is = TRUE) )) # theme is not set since html_vignette doesn't support it suppressMessages(expect_no_error(build_article("test", pkg))) }) test_that("can override html_document() options", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/test.Rmd", pkg_vignette( output = list(html_document = list(number_sections = TRUE)), pkgdown = list(as_is = TRUE), "# Heading 1", "# Heading 2" )) suppressMessages(path <- build_article("test", pkg)) # Check that number_sections is respected html <- xml2::read_html(path) expect_equal(xpath_text(html, ".//h2//span"), c("1", "2")) # But title isn't affected expect_equal(xpath_text(html, ".//h1"), "title") # And no links or scripts are inlined expect_equal(xpath_length(html, ".//body//link"), 0) expect_equal(xpath_length(html, ".//body//script"), 0) }) test_that("can set width", { pkg <- local_pkgdown_site(meta = list(code = list(width = 50))) pkg <- pkg_add_file(pkg, "vignettes/test.Rmd", pkg_vignette( r_code_block("getOption('width')") )) suppressMessages(path <- build_article("test", pkg)) html <- xml2::read_html(path) expect_equal(xpath_text(html, ".//pre")[[2]], "## [1] 50") }) test_that("bad width gives nice error", { pkg <- local_pkgdown_site(meta = list(code = list(width = "abc"))) expect_snapshot(rmarkdown_setup_pkgdown(pkg), error = TRUE) }) test_that("BS5 article laid out correctly with and without TOC", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/toc-true.Rmd", pkg_vignette( "## Heading 1", "## Heading 2" )) pkg <- pkg_add_file(pkg, "vignettes/toc-false.Rmd", pkg_vignette( toc = FALSE, "## Heading 1", "## Heading 2" )) suppressMessages(toc_true_path <- build_article("toc-true", pkg)) suppressMessages(toc_false_path <- build_article("toc-false", pkg)) toc_true <- xml2::read_html(toc_true_path) toc_false <- xml2::read_html(toc_false_path) # Always has class col-md-9 expect_equal(xpath_attr(toc_true, ".//main", "class"), "col-md-9") expect_equal(xpath_attr(toc_false, ".//main", "class"), "col-md-9") # The no sidebar without toc expect_equal(xpath_length(toc_true, ".//aside"), 1) expect_equal(xpath_length(toc_false, ".//aside"), 0) }) test_that("BS5 article gets correctly activated navbar", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/article.Rmd", pkg_vignette()) suppressMessages(article_path <- build_article("article", pkg)) html <- xml2::read_html(article_path) navbar <- xml2::xml_find_first(html, ".//div[contains(@class, 'navbar')]") expect_equal( xpath_text(navbar,".//li[contains(@class, 'active')]//button"), "Articles" ) }) test_that("titles are escaped when needed", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/test.Rmd", pkg_vignette(title = "a <-> b")) suppressMessages(path <- build_article("test", pkg)) html <- xml2::read_html(path) expect_equal(xpath_text(html, "//title", trim = TRUE), "a <-> b • testpackage") expect_equal(xpath_text(html, "//h1", trim = TRUE), "a <-> b") }) test_that("output is reproducible by default, i.e. 'seed' is respected", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/test.Rmd", pkg_vignette( r_code_block("runif(5L)") )) suppressMessages(path <- build_article("test", pkg)) html <- xml2::read_html(path) output <- xpath_text(html, "//main//pre")[[2]] expect_snapshot(cat(output)) }) test_that("reports on bad open graph meta-data", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/test.Rmd", pkg_vignette( opengraph = list(twitter = 1) )) expect_snapshot(build_article("test", pkg), error = TRUE) }) test_that("can control math mode", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/math.Rmd", "$1 + 1$") pkg$meta$template$`math-rendering` <- "mathml" suppressMessages(init_site(pkg)) suppressMessages(path <- build_article("math", pkg)) html <- xml2::read_html(path) expect_equal(xpath_length(html, ".//math"), 1) pkg$meta$template$`math-rendering` <- "mathjax" suppressMessages(init_site(pkg)) suppressMessages(path <- build_article("math", pkg)) html <- xml2::read_html(path) expect_equal(xpath_length(html, ".//span[contains(@class, 'math')]"), 1) pkg$meta$template$`math-rendering` <- "katex" suppressMessages(init_site(pkg)) suppressMessages(path <- build_article("math", pkg)) html <- xml2::read_html(path) expect_equal(xpath_length(html, ".//span[contains(@class, 'math')]"), 1) expect_contains( path_file(xpath_attr(html, ".//script", "src")), c("katex-auto.js", "katex.min.js") ) }) test_that("rmarkdown_template cleans up after itself", { pkg <- local_pkgdown_site() path <- NULL local({ path <<- rmarkdown_template(pkg) expect_true(file_exists(path)) }) expect_false(file_exists(path)) }) test_that("build_article styles ANSI escapes", { skip_if_no_pandoc() pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/test.Rmd", pkg_vignette( r_code_block("cat(cli::col_red('X'), '\n')") )) suppressMessages(path <- build_article("test", pkg)) html <- xml2::read_html(path) expect_snapshot_output(xpath_xml(html, ".//code//span[@class='co']")) }) # Errors ----------------------------------------------------------------------- test_that("build_article yields useful error if pandoc fails", { skip_on_cran() # fragile due to pandoc dependency skip_if_no_pandoc("2.18") pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/test.Rmd", "Hi") expect_snapshot( build_article("test", pkg, pandoc_args = "--fail-if-warnings"), error = TRUE ) }) test_that("build_article yields useful error if R fails", { skip_if_no_pandoc() pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/test.Rmd", c( "---", "title: title", "---", "```{r}", "f <- function() g()", "g <- function() h()", "h <- function() rlang::abort('Error!')", "f()", "```" )) # check that error looks good expect_snapshot(build_article("test", pkg), error = TRUE) # check that traceback looks good - need extra work because rlang # avoids tracebacks in snapshots expect_snapshot(summary(expect_error(build_article("test", pkg)))) }) # Images ----------------------------------------------------------------------- test_that("build_article copies image files in subdirectories", { skip_if_no_pandoc() pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/test.Rmd", c( "```{r}", "#| fig-alt: alt-text", "knitr::include_graphics('test/kitten.jpg')", "```" )) pkg <- pkg_add_kitten(pkg, "vignettes/test") expect_snapshot(build_article("test", pkg)) expect_equal(path_file(dir_ls(path(pkg$dst_path, "articles", "test"))), "kitten.jpg") }) test_that("finds external resources referenced by R code", { # weird path differences that I don't have the energy to dig into skip_on_cran() pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/test.Rmd", c( "![external dependency](`r 'kitten.jpg'`)" )) pkg <- pkg_add_kitten(pkg, "vignettes") suppressMessages(path <- build_article("test", pkg)) # ensure that we the HTML references `<img src="external.png" />` directly html <- xml2::read_html(path) expect_equal(xpath_attr(html, ".//img", "src"), "kitten.jpg") # expect that `external.png` was copied to the rendered article directory expect_true(file_exists(path(path_dir(path), "kitten.jpg"))) }) test_that("image links relative to output", { pkg <- local_pkgdown_site(test_path("assets/articles-images")) suppressMessages(init_site(pkg)) suppressMessages(copy_figures(pkg)) suppressMessages(build_article("kitten", pkg)) html <- xml2::read_html(path(pkg$dst_path, "articles", "kitten.html")) src <- xpath_attr(html, "//main//img", "src") expect_equal(src, c( # knitr::include_graphics() "../reference/figures/kitten.jpg", "another-kitten.jpg", # rmarkdown image "../reference/figures/kitten.jpg", "another-kitten.jpg", # magick::image_read() "kitten_files/figure-html/magick-1.png", # figure "kitten_files/figure-html/plot-1.jpg" )) # And files aren't copied expect_false(dir_exists(path(pkg$dst_path, "man"))) }) test_that("warns about missing images", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/kitten.Rmd", "![foo](kitten.jpg)") expect_snapshot(build_article("kitten", pkg)) }) test_that("spaces in sorce paths do work", { # create simulated package pkg0 <- local_pkgdown_site() pkg0 <- pkg_add_file(pkg0, "vignettes/kitten.Rmd", "![Kitten](kitten.jpg)") pkg0 <- pkg_add_kitten(pkg0, "vignettes") # copy simulated pkg to path that contains spaces pkg1 <- fs::dir_copy(pkg0$src_path, fs::file_temp(pattern = "beware of spaces-")) # check that pkgdown site builds anyways expect_no_error(suppressMessages( build_article("kitten", as_pkgdown(pkg1)) )) }) test_that("warns about missing alt-text", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/kitten.Rmd", "![](kitten.jpg)") pkg <- pkg_add_kitten(pkg, "vignettes") expect_snapshot(build_article("kitten", pkg)) }) # External dependencies -------------------------------------------------------- test_that("pkgdown deps are included only once in articles", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/test.Rmd", pkg_vignette( # Some code that adds jquery/bootstrap r_code_block( 'htmltools::tagList( htmltools::p("hello"), rmarkdown::html_dependency_jquery(), rmarkdown::html_dependency_bootstrap("flatly") )' ) )) # Rely on default init_site() from local_pkgdown_site() setting all # the default includes to empty suppressMessages(path <- build_article("test", pkg)) html <- xml2::read_html(path) expect_equal(path_file(xpath_attr(html, ".//script", "src")), "pkgdown.js") expect_equal(path_file(xpath_attr(html, ".//link", "href")), character()) }) test_that("html widgets get needed css/js", { pkg <- local_pkgdown_site() pkg <- pkg_add_file(pkg, "vignettes/test.Rmd", pkg_vignette( r_code_block(' path1 <- tempfile() writeLines(letters, path1) path2 <- tempfile() writeLines(letters[-(10:11)], path2) diffviewer::visual_diff(path1, path2) ') )) suppressMessages(path <- build_article("test", pkg)) html <- xml2::read_html(path) css <- xpath_attr(html, ".//body//link", "href") js <- xpath_attr(html, ".//body//script", "src") expect_true("diffviewer.css" %in% path_file(css)) expect_true("diffviewer.js" %in% path_file(js)) }) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat/test-markdown.R��������������������������������������������������������������0000644�0001762�0000144�00000004044�14634573316�017665� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������test_that("handles empty inputs (returns NULL)", { pkg <- local_pkgdown_site() expect_null(markdown_text_inline(pkg, "")) expect_null(markdown_text_inline(pkg, NULL)) expect_null(markdown_text_block(pkg, NULL)) expect_null(markdown_text_block(pkg, "")) path <- withr::local_tempfile() file_create(path) expect_null(markdown_body(pkg, path)) }) test_that("header attributes are parsed", { pkg <- local_pkgdown_site() text <- markdown_text_block(pkg, "# Header {.class #id}") expect_match(text, "id=\"id\"") expect_match(text, "class=\".*? class\"") }) test_that("markdown_text_inline() works with inline markdown", { pkg <- local_pkgdown_site() expect_equal(markdown_text_inline(pkg, "**lala**"), "<strong>lala</strong>") expect_snapshot(error = TRUE, { markdown_text_inline(pkg, "x\n\ny", error_path = "title") }) }) test_that("markdown_text_block() works with inline and block markdown", { skip_if_no_pandoc("2.17.1") pkg <- local_pkgdown_site() expect_equal(markdown_text_block(pkg, "**x**"), "<p><strong>x</strong></p>") expect_equal(markdown_text_block(pkg, "x\n\ny"), "<p>x</p><p>y</p>") }) test_that("markdown_body() captures title", { pkg <- local_pkgdown_site() temp <- withr::local_tempfile(lines = "# Title\n\nSome text") html <- markdown_body(pkg, temp) expect_equal(attr(html, "title"), "Title") # And can optionally strip it html <- markdown_body(pkg, temp, strip_header = TRUE) expect_equal(attr(html, "title"), "Title") expect_no_match(html, "Title") }) test_that("markdown_text_*() handles UTF-8 correctly", { pkg <- local_pkgdown_site() expect_equal(markdown_text_block(pkg, "\u00f8"), "<p>\u00f8</p>") expect_equal(markdown_text_inline(pkg, "\u00f8"), "\u00f8") }) test_that("validates math yaml", { config_math_rendering_ <- function(...) { pkg <- local_pkgdown_site(meta = list(template = list(...))) config_math_rendering(pkg) } expect_snapshot(error = TRUE, { config_math_rendering_(`math-rendering` = 1) config_math_rendering_(`math-rendering` = "math") }) }) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/tests/testthat.R����������������������������������������������������������������������������0000644�0001762�0000144�00000000072�13750606620�015054� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������library(testthat) library(pkgdown) test_check("pkgdown") ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/MD5�����������������������������������������������������������������������������������������0000644�0001762�0000144�00000066656�14672377072�012275� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������4a855b87f374d30480268569be05973f *DESCRIPTION 86db9af582ce3a04bf47880d25041250 *LICENSE f55dc4830867e4b58555915cbba6455e *NAMESPACE 705b77c2871c0a4f2388bf7c6538c1b9 *NEWS.md ef87846a3b4d19e99b47cde66a43b7c5 *R/autolink_html.R 3dd52f6c5ab15918f5f02ee4ca43f1d4 *R/build-404.R 58cf77e4f6f41ba3040befe6c3d7b1d2 *R/build-article.R f649eafc4f20ed3c218c3595a14abe86 *R/build-articles.R 3c8472e5c05ee9d68e56a1f52ab19354 *R/build-favicons.R d70ec5ec4506d48a37c31f6a55c3bfb9 *R/build-footer.R b1f7dbae3a9d909e8cecfa6972bb13c9 *R/build-github.R 7638a62198b701451dfb6ed6b91d333a *R/build-home-authors.R f484f95911aca741e2693390bf21e3a1 *R/build-home-community.R cbbca902f628b3542582d658677b2678 *R/build-home-index.R bd1f6db947048d13ddaa07e476ff7e67 *R/build-home-license.R 0b0bfe5093e7489c83cbd09be2d9bb85 *R/build-home-md.R c6163678f2a1e0301349ed32c4b9b8aa *R/build-home.R 2fc675da885ca6871765d5b8ea7bc67a *R/build-logo.R f7842f01b21442b8b4b9c11e6c80a68e *R/build-news.R c574776f7e7a066e48cadcfc02c48b34 *R/build-quarto-articles.R fe1151e9c701f2fa8aa48d0f63b0d5f4 *R/build-redirects.R 2a7e1be066725895b8272a829c66e924 *R/build-reference-index.R 0d9a4fb755a931ed54bf6605c9616c63 *R/build-reference.R 51fec23659c10e92cc773f8a8a6b48f2 *R/build-search-docs.R d0abcea30cf5c41dab6915b64b31d41c *R/build-tutorials.R 085344e8af175d6beba4ba928cb970ad *R/build.R 455578b4e72e7497ff4720e1e90f85cf *R/check-built.R 80f68dfbf34bbcfd0de9f23509b67eb0 *R/check.R 950e44b27ab64869700685454f5dc00b *R/clean.R c570afb6d26f57830fd81cc1d4c3707d *R/config.R 43eb786d3d47518f855c78db2a1119da *R/context.R ba70388f556358b30ce8b6587efca8c7 *R/deploy-site.R 0cfef74fd7bb784315b9bc1f9e176804 *R/development.R 4638b46b83685c79e1870824a982e105 *R/external-deps.R 2f4850f92b7ec59548217eb437a23a69 *R/figure.R cda79e496655c45e53e81cb6b5c250b0 *R/highlight.R 80d6120321747b60e3cdac4b33345d22 *R/html-build.R c80a9eb1427c585807cecf618b6f3870 *R/import-standalone-obj-type.R c40f882046a958444c6058a9e2cb9a3b *R/import-standalone-types-check.R 370870988c3a828739b0bea8ddecd7f9 *R/init.R f91e5b643adab02f21f505fc9297e53c *R/markdown.R 366bd7d6b5d4a4ae4dec14d8f1750cc9 *R/navbar-menu.R 298e1ecf3f3bd9f110e3c6293f55ed37 *R/navbar.R 2a8ffab47395c63e40eac0109d289df0 *R/package.R e99fa1b10e6912df678211f63b693e64 *R/pkgdown-package.R 22b0c043d827123d17e59ecb216601ed *R/pkgdown.R c7764db1981f7300cb70944471c982e5 *R/pkgdown_print.R 39f2c2c0c64de9f6386dc64f4faef823 *R/preview.R 41cc461fef0fbfd467356f595968dfce *R/rd-data.R bdb9f09c53da0a63543493ebf4593b66 *R/rd-example.R dfd1741c87892cc09cb1a3496a73f700 *R/rd-html.R 1117cd535cf83b79661d06ca3354d8c4 *R/rd.R 3620932d7790f0fb3612b73ce1ee0862 *R/render.R 68d6406dc1da12b250f7847210f0f9e3 *R/repo.R cc6db878266050cc5f8d68a5c3962901 *R/template.R b30b22af596dce749c9e0711569ec17f *R/templates.R 4cd47d2a83943f5c6996f8318f2357ce *R/test.R c66b598b1bc597072377e67c871f7731 *R/theme.R 6ee3a8dfa12dfce8b95f26f9c0ce3218 *R/topics-external.R 2e7cd186ba8061d322a17b6406f93765 *R/topics.R 5036dbe607db6779659a216a7b7368c7 *R/tweak-homepage.R a8b4a75b59303b5268ce9f03196a23b9 *R/tweak-navbar.R 6cc6e317c6552b3e2169404081602b84 *R/tweak-page.R 1a1fbadb5121c9a9636e31233f01a6cd *R/tweak-reference.R 6f98e3e41fd2f6b1237ee13e260e1a69 *R/tweak-tabset.R ac1b7c049f95ae3e30ebf806812d7ec5 *R/tweak-tags.R 780ef4186f76f95c1c83c8a424c6a58b *R/tweak.R 3738394154d1b2248e0ec1a8209971c8 *R/usage.R 7b0b9921b1211b368b46991517b4dc96 *R/utils-fs.R 4c83eb2ddce460347a219a999eb3530d *R/utils-io.R f63bffac45a3298c91567ff28c8d0756 *R/utils-pdf.R f33583699d575dc20b12f27984c2905b *R/utils.R 0046fc7f3cd966705935d695b9fc8662 *README.md 6a5bd5f88e0836dfcc60b7c0475e9e54 *build/stage23.rdb ac2c305da4a674fddfbaec60cb241594 *build/vignette.rds 5eec6702c35b15a8c2c123301987735d *inst/BS3/assets/bootstrap-toc.css aaa610b29d895e1128447e76b9bc0076 *inst/BS3/assets/bootstrap-toc.js 828dbea96017a994efccb7c30c041577 *inst/BS3/assets/docsearch.css 2f3c1f7995c9f4f966323f008e3984ad *inst/BS3/assets/docsearch.js 4759f31f8a585e9af173fc579d730265 *inst/BS3/assets/link.svg 9cd7da30627ce8d0e18fd1cf1f48c83f *inst/BS3/assets/pkgdown.css 916db342671c073ca830f33df8c36adc *inst/BS3/assets/pkgdown.js c7d93982b5bd95d8bfd02dcc203089cf *inst/BS3/templates/after-body.html 99da4d763bfd415fbf8a47d39e3e327f *inst/BS3/templates/before-body.html be694e1085f52eacbbdc67538154715f *inst/BS3/templates/config-docsearch.json 6ca9f48641134d2ea7308d4152153d77 *inst/BS3/templates/content-article-index.html 794d01127b89987c3edcd901e880c3f0 *inst/BS3/templates/content-article.html b17e8d987ad6cc164911dda22dda7a4e *inst/BS3/templates/content-citation-authors.html 27498f778ae1162bb9043470bc33e1ac *inst/BS3/templates/content-home.html d53bc0b8cbacf5659165f56b0eb1f445 *inst/BS3/templates/content-news-index.html 4767a06ed1ff33b0812cae1053919b49 *inst/BS3/templates/content-news.html 149a3968aa95318544ce87d3422ef2eb *inst/BS3/templates/content-reference-index.html 27dadcf6406485ef9b4bc8d8e9f35d93 *inst/BS3/templates/content-reference-topic.html 2effb010f58761192bb8d310baf05fb4 *inst/BS3/templates/content-title-body.html a973fbc8726549edd09bd0a2aebb991e *inst/BS3/templates/content-tutorial-index.html 9173209b61812d79bae347eaddd96cd4 *inst/BS3/templates/content-tutorial.html a18f6f4b69cc626b06d89759168b8463 *inst/BS3/templates/docsearch.html 3aac39beb5aeb1049269e6bbf02b1afe *inst/BS3/templates/footer.html 6cd8af8a89fc65616b2a10a456c35538 *inst/BS3/templates/head.html d41d8cd98f00b204e9800998ecf8427e *inst/BS3/templates/header.html 24c32452b796b57ffa959d2c414ec2a4 *inst/BS3/templates/in-header.html b02b9d96ff878bfcfa3cecfc62c34d83 *inst/BS3/templates/layout-redirect.html f7780ff5acfd913ddc3e2797290328ee *inst/BS3/templates/layout.html 9fc50d0e252d74e2dd44b55bba668b57 *inst/BS3/templates/navbar.html b6babfc10247cf9190b9fa172dde62b8 *inst/BS5/assets/katex-auto.js 5806fcea81ccc70e1ffc453a7d9e12b5 *inst/BS5/assets/lightswitch.js 4759f31f8a585e9af173fc579d730265 *inst/BS5/assets/link.svg dca708c90eee1f2352a32f4754901a6a *inst/BS5/assets/pkgdown.js 037246de377aeef6f32ce22acfa57b26 *inst/BS5/assets/pkgdown.scss c7d93982b5bd95d8bfd02dcc203089cf *inst/BS5/templates/after-body.html 99da4d763bfd415fbf8a47d39e3e327f *inst/BS5/templates/before-body.html 9f93e2654920065cd7f29b601c90ff82 *inst/BS5/templates/config-docsearch.json e231175debcc602eccb667037cb54213 *inst/BS5/templates/content-article-index.html 023a84df71c1f1df98132f7ff752fba0 *inst/BS5/templates/content-article.html 8785a15857eadc833c3c5d16fb7165ec *inst/BS5/templates/content-authors.html b8382000d19392554e00336198e04045 *inst/BS5/templates/content-citation-authors.html 24e9ad1721b278a24b325163de6617ba *inst/BS5/templates/content-home.html bff9cff56c781de05cab62382d553799 *inst/BS5/templates/content-news-index.html 8f3894fa33760d67e9d3ebe0eb74cc9d *inst/BS5/templates/content-news.html 7fce554cf19be5f108718fa5855b041c *inst/BS5/templates/content-quarto.html 413e9dcb7ed82e05f8524d729237f1a9 *inst/BS5/templates/content-reference-index.html ae9620c485f580c2692d9087e8690cc0 *inst/BS5/templates/content-reference-topic.html 12b955cf7dd62c34f50c5b419edec9bd *inst/BS5/templates/content-title-body.html 35bec3727d15b529a9f128143258d5d9 *inst/BS5/templates/content-tutorial-index.html 64d8b70e89e4044c389e3608d50bb4b1 *inst/BS5/templates/content-tutorial.html 841f25541730c73bcac04bb73c81a556 *inst/BS5/templates/footer.html 608813b031235c66c8e6d99e6212e54b *inst/BS5/templates/head.html d41d8cd98f00b204e9800998ecf8427e *inst/BS5/templates/header.html 24c32452b796b57ffa959d2c414ec2a4 *inst/BS5/templates/in-header.html b02b9d96ff878bfcfa3cecfc62c34d83 *inst/BS5/templates/layout-redirect.html bac5ba630c20ff8470b808d6f50de783 *inst/BS5/templates/layout.html 9575d50f193bcd9e69ebb9a5244c36f4 *inst/BS5/templates/navbar.html 29b0914fe796e88731768796001a3cb9 *inst/doc/accessibility.R 0117ffa2e1cae12eeaf4e60469a6083b *inst/doc/accessibility.Rmd a8a3cd4520dd33ca5e2fbd88199c6a98 *inst/doc/accessibility.html 29b0914fe796e88731768796001a3cb9 *inst/doc/customise.R cc1120f57d9361a92067dc8d45962a83 *inst/doc/customise.Rmd 1182622c9caa446a2c2d5611148f4f25 *inst/doc/customise.html aa2eea0ebf75f5d8a30f97f570bad37d *inst/doc/how-to-update-released-site.R 5b58a4ff3da56e3e57baea50631e3c25 *inst/doc/how-to-update-released-site.Rmd 0cf1694214255fe817451b06519b417a *inst/doc/how-to-update-released-site.html 5e270ae6034b339c2a13d20a5f7d2dec *inst/doc/linking.R 23bd46e4b9f4898e7fc9b9adc94ae1af *inst/doc/linking.Rmd 0a743e51f468cee6a40cd88ab9d4752b *inst/doc/linking.html 5e270ae6034b339c2a13d20a5f7d2dec *inst/doc/metadata.R 19efd0467cc00a875fc5ba303ba9ec5a *inst/doc/metadata.Rmd 61ec80534ee286042547730304a8bf41 *inst/doc/metadata.html 8df022abca97892ea7d8c900bd89488e *inst/doc/pkgdown.R 79ca83ec8c29bf368c79ffdf89f562de *inst/doc/pkgdown.Rmd 56513e9425d433add330077e283b0d3b *inst/doc/pkgdown.html 322a2ba7847648320ea45f5ad940a424 *inst/doc/quarto.R 9a274034bbedcc65d84c0401fb88540a *inst/doc/quarto.html 006968c8f114b58454e5b957689cb06e *inst/doc/quarto.qmd 3a720dfe6954d91ac9552765baad628c *inst/doc/translations.R c4da48c2d7a8712291425c9eb36ab9e8 *inst/doc/translations.Rmd 4a3ca93d23dcc8a623578395113a0e2c *inst/doc/translations.html 831eee68f858583f6c95e60dbf36838f *inst/highlight-styles/a11y-dark.scss 04792c4fb02a33db1ef2a14c8ed06651 *inst/highlight-styles/a11y-light.scss 8bcef9022dd99d22fa9dd9624b95cea6 *inst/highlight-styles/arrow-dark.scss a4fe28ce5e988ce796410495aefd89f5 *inst/highlight-styles/arrow-light.scss 36f195fd2c403d417a43c5cbfe6736c3 *inst/highlight-styles/atom-one-dark.scss b83625ac725d3b7fce2deaf59ae29554 *inst/highlight-styles/atom-one-light.scss d1edda7764a9e58e0ab2efc1e212464d *inst/highlight-styles/ayu-dark.scss 78028498193515e9fe41fdde2fab480f *inst/highlight-styles/ayu-light.scss 824c7f8a16f2a5dbdbcb0addd6449a04 *inst/highlight-styles/ayu-mirage.scss 1830891b18652e65a34b0769e81ef563 *inst/highlight-styles/breeze-dark.scss 6315ad3dfd7aa79b37056147f6effff2 *inst/highlight-styles/breeze-light.scss 864175b7283294b26b2c4812a74786d3 *inst/highlight-styles/breezedark.scss 0525c7deac0ef80d0a70360f797ef6f2 *inst/highlight-styles/dracula.scss 38645fe4c988cc50ca5dd21400e3aa66 *inst/highlight-styles/espresso.scss e1dc9c2ed27598164f7fef3f025cab18 *inst/highlight-styles/github-dark.scss 6079553439a2d52a95d03b2e355f6612 *inst/highlight-styles/github-light.scss 168bb91cd28645fd384c7f05ab4d8df4 *inst/highlight-styles/gruvbox-dark.scss 2d65f57381db7b1ea7c3082901b877ea *inst/highlight-styles/gruvbox-light.scss dbcfda0230811b9a4ae7e40c043b928e *inst/highlight-styles/haddock.scss b1bbf9da25d9c2c56f747e830c4eaa81 *inst/highlight-styles/kate.scss 0592e8498787c952ec19c01a4fe806e3 *inst/highlight-styles/monochrome-dark.scss 6b6e4c361c40198cabfc94c1187e9c75 *inst/highlight-styles/monochrome-light.scss ff10c6adfc88a5b8106d57a309e2cf2b *inst/highlight-styles/monochrome.scss 545bcaea882a705e53696f573d42ff8b *inst/highlight-styles/monokai.scss 6875924895d1226bc27110be2da04666 *inst/highlight-styles/nord.scss 9e16c08a089007339160ed0958a41720 *inst/highlight-styles/oblivion.scss a1b3f1b986e5c32ffa9e7929632ea34c *inst/highlight-styles/printing.scss 8a0bb5551bcb9d90efc5884231f13527 *inst/highlight-styles/pygments.scss f9dc01c62de94948508853856192da5b *inst/highlight-styles/radical.scss 67474264129e6689dd93cb3fd17aec26 *inst/highlight-styles/solarized-dark.scss c1f970d3a36d50b3a7b5f1c39db21a3d *inst/highlight-styles/solarized-light.scss c1f970d3a36d50b3a7b5f1c39db21a3d *inst/highlight-styles/solarized.scss fcb59ae3dc9b0cd37deb35e332fb80e9 *inst/highlight-styles/tango.scss 5f9ec3e22735a2cea4cb7e5d401aa028 *inst/highlight-styles/vim-dark.scss ac49e3cdc01a34d9122772a8819df68b *inst/highlight-styles/zenburn.scss f2e23ef9313b37d9f1f4901b4b055185 *inst/po/ca/LC_MESSAGES/R-pkgdown.mo eebe13496ba38d3ccde95a0eaad9a3a1 *inst/po/de/LC_MESSAGES/R-pkgdown.mo 3a45687394087d3396a583bfadb6fc98 *inst/po/dk/LC_MESSAGES/R-pkgdown.mo c59db6628a4075122d7165fc297ff218 *inst/po/es/LC_MESSAGES/R-pkgdown.mo 0103484ce6e1d91a7e433e1363d99c3f *inst/po/fr/LC_MESSAGES/R-pkgdown.mo 4487ade1c5eae234b7dea92831da9ee8 *inst/po/ko/LC_MESSAGES/R-pkgdown.mo 75d9e3293fa74cd6199d5f8effd20aae *inst/po/kr/LC_MESSAGES/R-pkgdown.mo 3a5612cf257f72aa5fe56a7c439eb972 *inst/po/pt/LC_MESSAGES/R-pkgdown.mo fb20fc1764ea87cd4f7570be815af48b *inst/po/tr/LC_MESSAGES/R-pkgdown.mo a416f53e43f86dd3da9071fb337f40c7 *inst/po/zh_CN/LC_MESSAGES/R-pkgdown.mo 8436355ba20233f185ed7186339d27ff *inst/quarto/template.html dcedbfdf96d8ef6fb3f0c301d65d095c *inst/rstudio/addins.dcf 73623a9540cea9fffbeb18a9951da0fc *man/as_pkgdown.Rd 7c121f3dd6340129e9de15b909dbb936 *man/autolink_html.Rd ba9315c150fea8f249dcbc508acbe152 *man/build_articles.Rd 7fc13c950a83841ff0f0301562c181a0 *man/build_favicons.Rd d8168e9e0e1d93bccd14864932b7e32c *man/build_home.Rd f72216906eb490b0e96876dda5a83eaa *man/build_news.Rd aeb24558af7aeb38c9a8bec9f3566c1f *man/build_redirects.Rd ee3c0201e8fcd7023c3076a653c25317 *man/build_reference.Rd 01baf22c4ed5fa6cf9887a368198d05d *man/build_search.Rd b9548eb7b19d1157607e3a009a647cdf *man/build_site.Rd 078f6ac1d1f04084bd58ed401a24331b *man/build_site_github_pages.Rd 38cc67d727483230b2a632961a33ea27 *man/build_tutorials.Rd 890bc41be0204477dd7d8903db72ba27 *man/check_pkgdown.Rd 7cd446080f192da1e471a93c7dcea07f *man/clean.Rd 42fb78fc70bfb815db8c001d19cf6d4f *man/deploy_site_github.Rd ab81d70c8f5043dc0540c77c073787e9 *man/deploy_to_branch.Rd 10c212ea9868aa62ee069de9e1a37b9c *man/fig_settings.Rd 4ee979c4c83a85a557030d69863e9d13 *man/figures/bacon.jpg cb1e46f469cfbbbde29c8b5113e1d789 *man/figures/lifecycle-archived.svg c0d2e5a54f1fa4ff02bf9533079dd1f7 *man/figures/lifecycle-defunct.svg a1b8c987c676c16af790f563f96cbb1f *man/figures/lifecycle-deprecated.svg c3978703d8f40f2679795335715e98f4 *man/figures/lifecycle-experimental.svg 952b59dc07b171b97d5d982924244f61 *man/figures/lifecycle-maturing.svg 27b879bf3677ea76e3991d56ab324081 *man/figures/lifecycle-questioning.svg 53b3f893324260b737b3c46ed2a0e643 *man/figures/lifecycle-stable.svg 1c1fe7a759b86dc6dbcbe7797ab8246c *man/figures/lifecycle-superseded.svg 136ed38fbd543272864ba3eff0c5a5f2 *man/figures/logo.png 85e8b6d1bcba89ebfd10a182a94447fb *man/in_pkgdown.Rd 321a7798482fe98a4661434a63339530 *man/index.Rd e0f9c43e6c75dadaadacd6db0b3f7da1 *man/init_site.Rd 673c41e90a90cec483c5e6acd3ed1abe *man/pkgdown-package.Rd 74fdb77c11822aa805e8e119af841a10 *man/pkgdown_print.Rd c169f7e6fb43b41454377dcccd3d9e40 *man/preview_page.Rd 76d93d4feb43250ccd8008a976bd4897 *man/preview_site.Rd e2ff3f4601be509c687dbec163154568 *man/rd2html.Rd af0d91bbe60a0a95f737438f58bee0db *man/render_page.Rd 38e60aa25bbe7657e70d3de9a04869d5 *man/templates.Rd 277f7d5b225b1a888b07eede3bc0b045 *man/test-crayon.Rd 267cf596cac959a885e258dcac72158c *man/test-dont.Rd fef5bcdabded18bf11cfadac6ac7d358 *man/test-figures.Rd 2a666d3068bc93f46bdaa6d121b2daa2 *man/test-links.Rd 8680e1e69f1f8a006ecc3224886f2358 *man/test-lists.Rd cf955184ec96fec497c04eba8bfe57e7 *man/test-long-lines.Rd 2e2bbadd497de271eaf7dd33410f9caa *man/test-output-styles.Rd 865f8d8d816c3c67b6eeeefa4e973a14 *man/test-params.Rd ed8c4523a6bea1109b0e5cb53f155768 *man/test-sexpr-title.Rd 1b1f3e16afa79465d1c1d4b5243f5021 *man/test-tables.Rd 49ee760ba54faeb670a777b746105476 *man/test-verbatim.Rd b32d06c21b8122972a0b60250b960c6f *po/R-ca.po 4a4b5700fbfbfb9e8bf41310ebd9ddf8 *po/R-de.po 43ea234b8299793f7d9c1b5b5ba24210 *po/R-dk.po 9ff295f61607028921f6acfc0fc839aa *po/R-es.po 717553869ade2d53f7217fdba6604745 *po/R-fr.po f4a81b1cf9d761947c01ba5b97e4e8d4 *po/R-ko.po 2ba1b3b42bd690e4eefb3aedb8b567a6 *po/R-pkgdown.pot 4ee9fa4bf9916f7fe0550f8fae9c0ffc *po/R-pt.po 79d7640f3ea5d5a88ff4661401367259 *po/R-tr.po 25784eaea50f7e535a404c8424df0274 *po/R-zh_CN.po 60d53d09c368517082fab1b12beb8a73 *tests/testthat.R 6e9964b6ca7b0044512d959dc19803ee *tests/testthat/_snaps/build-article.md c448731e5928c7737eed793459233077 *tests/testthat/_snaps/build-articles.md ac80fd97a6bea6873aa06a9dc0052ad8 *tests/testthat/_snaps/build-favicons.md e4e28e4ca51fd12c6b062200a3c79d06 *tests/testthat/_snaps/build-footer.md 74f816823109729aa9c12f16dcef4b7c *tests/testthat/_snaps/build-github.md 4240776883f959d6fece6027c52f18ed *tests/testthat/_snaps/build-home-authors.md 8d2299d35caad375f285c8ceefae4150 *tests/testthat/_snaps/build-home-community.md 47fee3c837d8b518a237c5b2e64498c7 *tests/testthat/_snaps/build-home-index.md 61e556ae55f36cf952394029f884b9db *tests/testthat/_snaps/build-news.md ab771cae9d479dc4781de8cf80594308 *tests/testthat/_snaps/build-quarto-articles.md b8fa5127d3bffa2735bd9fe8225dc0bb *tests/testthat/_snaps/build-redirects.md f3374260c69bda2260da2b014b1f0ffb *tests/testthat/_snaps/build-reference-index.md a845d345392669e32a27881e35ae455c *tests/testthat/_snaps/build-reference.md 6143ca0e704bfe904cfbf8382ce0bef1 *tests/testthat/_snaps/build-search-docs.md 8c89eb9d79af0f7a6fab82cd7d6c79a4 *tests/testthat/_snaps/check-built.md a9fc94d2e519dd266633c6f7e8cf8d9b *tests/testthat/_snaps/check.md 03fcf6987a51e2712497d07edfa45852 *tests/testthat/_snaps/config.md 700558efec2442751e989fa3c849a8fd *tests/testthat/_snaps/development.md b4e8c693cd973d78317800e3f71bcd5c *tests/testthat/_snaps/external-deps.md cde374550da93185d319d82495a22a31 *tests/testthat/_snaps/highlight.md ab8f007916b42895011008d0dd1f4d15 *tests/testthat/_snaps/init.md 13d8ea709b570b1f968d56972d9cde06 *tests/testthat/_snaps/markdown.md 7fb5aee5787971df3570b9389c753ebd *tests/testthat/_snaps/navbar-menu.md b1c71aa5ecf9dc6beb673fb01c27a7e6 *tests/testthat/_snaps/navbar.md 0a81dc53c73e806bfb8f9fa8188a49dc *tests/testthat/_snaps/package.md f7311fa3dc40ffca37838278693adb4e *tests/testthat/_snaps/preview.md 6e5fb10dda98068d82f5516c8957c2ab *tests/testthat/_snaps/rd-example.md 3fe7c060bcbe2fdcf6bca9e319d06424 *tests/testthat/_snaps/rd-html.md 85b1a5289618cc457bb5ab275663b68b *tests/testthat/_snaps/render.md 70b653aa2476a7b0306e13001932017a *tests/testthat/_snaps/repo.md 155a409d21ac65e87e1a164eb6824610 *tests/testthat/_snaps/templates.md dedbc5c6248a914216046f7cd3aec891 *tests/testthat/_snaps/theme.md 425a565cfd9cebb233a745151a73100e *tests/testthat/_snaps/topics-external.md 3532028ce238eb52545d54e9423152a8 *tests/testthat/_snaps/topics.md 3348176674ba4aa1747e88ca23f943cf *tests/testthat/_snaps/tweak-homepage.md 25e6e274b5a9870ac48571c45dfdbc65 *tests/testthat/_snaps/tweak-tabset.md fac8fe2d0ebad1ae9f83df595e0ce76b *tests/testthat/_snaps/tweak-tags.md bf0162b1b1765b2b92aad86783c3ef45 *tests/testthat/_snaps/usage.md 3a6f8b805da753ec980e7f2701e9aec2 *tests/testthat/_snaps/utils-fs.md 7b44e56c5112271e83d79663d8bea30e *tests/testthat/assets/-find-assets.html 8ba5b489bcd50e8ec4f297593c276c2a *tests/testthat/assets/articles-images/DESCRIPTION 0534fdafdbad1ab9cdee7473880cd993 *tests/testthat/assets/articles-images/README.md 9fbe5b7d712dc924a19010f9cf32e750 *tests/testthat/assets/articles-images/_pkgdown.yml 10ec14048dae2c7313542736845d6f9f *tests/testthat/assets/articles-images/docs/articles/another-kitten.jpg effa016b0241915948bff14e6c64f333 *tests/testthat/assets/articles-images/docs/articles/kitten.html 25800a2464eb26fd916872b93fda2773 *tests/testthat/assets/articles-images/docs/articles/kitten_files/figure-html/magick-1.png e257fff4113e5a4b3008c556052f457f *tests/testthat/assets/articles-images/docs/articles/kitten_files/figure-html/plot-1.jpg c3f6623e38ac7c247d0173d972ba6aea *tests/testthat/assets/articles-images/docs/reference/figures/kitten.jpg c3f6623e38ac7c247d0173d972ba6aea *tests/testthat/assets/articles-images/man/figures/kitten.jpg 08511ffc2e39637dfb78c61713c1d01d *tests/testthat/assets/articles-images/man/kitten.Rd 10ec14048dae2c7313542736845d6f9f *tests/testthat/assets/articles-images/vignettes/another-kitten.jpg 39ff937065d8f892263e6a5def85451d *tests/testthat/assets/articles-images/vignettes/kitten.Rmd 0f28f7215a3207baa4defa481a925d4f *tests/testthat/assets/figure/DESCRIPTION 9fbe5b7d712dc924a19010f9cf32e750 *tests/testthat/assets/figure/_pkgdown.yml 4d450d94a52928bc83ae0d161cf9d587 *tests/testthat/assets/figure/man/figure.Rd bbace9b1a4aa8108214a6097457f1d04 *tests/testthat/assets/figure/vignettes/figures.Rmd c3f6623e38ac7c247d0173d972ba6aea *tests/testthat/assets/kitten.jpg 847e4eab3395d08167eb6e4c6fc17812 *tests/testthat/assets/reference-fail/DESCRIPTION b1e120dca82a29d5d40c7505dc7e7e44 *tests/testthat/assets/reference-fail/NAMESPACE b03772870d4840344465faa9052103f4 *tests/testthat/assets/reference-fail/R/f.R a315840c7c60841e105270f40923ac7c *tests/testthat/assets/reference-fail/man/f.Rd 9436efe6d9f02cdeade7dd29c1b92656 *tests/testthat/assets/reference-html-dep/DESCRIPTION 11d4074aae3b53656376ed92581f1fe9 *tests/testthat/assets/reference-html-dep/NAMESPACE 1cfc8be4f8cc64383042092f626e4259 *tests/testthat/assets/reference-html-dep/R/funs.R a626ef04b37b4659aa5a1d46b80fc1cb *tests/testthat/assets/reference-html-dep/_pkgdown.yml e579ace400ecf275f93f77478312fb44 *tests/testthat/assets/reference-html-dep/man/a.Rd 847e4eab3395d08167eb6e4c6fc17812 *tests/testthat/assets/reference-pre-post/DESCRIPTION 43d2ff36c439c2a0f21b078e260f50df *tests/testthat/assets/reference-pre-post/pkgdown/post-reference.R 26813d0f7f8e272af05102662163c53b *tests/testthat/assets/reference-pre-post/pkgdown/pre-reference.R e14fc358b147815d9a8807b93a35a08b *tests/testthat/assets/reference-selector/DESCRIPTION 03a62fe3fa9a58a0321495fb291e4d5c *tests/testthat/assets/reference-selector/NAMESPACE faca304d0486d794a2506709dd46c0b2 *tests/testthat/assets/reference-selector/NEWS.md 490567409e22b2e559a8e5b7d7f3de65 *tests/testthat/assets/reference-selector/R/funs.R a626ef04b37b4659aa5a1d46b80fc1cb *tests/testthat/assets/reference-selector/_pkgdown.yml 14f1c6c50b986edcbbadda0e8d855af2 *tests/testthat/assets/reference-selector/man/A.Rd d1923bdd40f3626c9de781acb053456c *tests/testthat/assets/reference-selector/man/matches.Rd e14fc358b147815d9a8807b93a35a08b *tests/testthat/assets/reference/DESCRIPTION e61830d6a1d246c9887de8cb4c9bab7c *tests/testthat/assets/reference/NAMESPACE ef7b06c2dcfee5c6163cd69163e211aa *tests/testthat/assets/reference/R/funs.R a626ef04b37b4659aa5a1d46b80fc1cb *tests/testthat/assets/reference/_pkgdown.yml 0e0724089bbdf105db1b51c8dfde8a5f *tests/testthat/assets/reference/man/a.Rd 6c8954c41172f6586c5e4723b67cf461 *tests/testthat/assets/reference/man/b.Rd 7f2d535ded2a310396ed40f3fa0342ae *tests/testthat/assets/reference/man/c.Rd 82bcef0710eefb001571557b5c7dc976 *tests/testthat/assets/reference/man/e.Rd d38e65103dbf88388891f12f465190b2 *tests/testthat/assets/reference/man/f.Rd 06841ddd2937d03fb976eabb50aeeddf *tests/testthat/assets/reference/man/g.Rd b7db9245402493ac1473b6830af151d2 *tests/testthat/assets/reference/man/help.Rd 638a76ef2dd9af66ad2043814f781b57 *tests/testthat/assets/sitemaps-schema-0.9.xsd 0f28f7215a3207baa4defa481a925d4f *tests/testthat/assets/templates-local/DESCRIPTION b51f979e9bd14376f1f80349d9cd1997 *tests/testthat/assets/templates-local/pkgdown/templates/content-article.html 40e2285974dda0a37186b53ebca56f6d *tests/testthat/assets/templates-local/pkgdown/templates/footer-article.html 7b2ffb0da089793613545873939a4e52 *tests/testthat/helper.R f336164e726d8e824534e8b7b554f518 *tests/testthat/test-build-article.R 6a1b25adb3721e0641ccefdfc707eb7c *tests/testthat/test-build-articles.R 3dff8b36d8869b713992d6c97fe882b6 *tests/testthat/test-build-favicons.R 8d74a24a68df3d14df131edaa0b40608 *tests/testthat/test-build-footer.R 203703698cd9c937b5da3e57581785e4 *tests/testthat/test-build-github.R 46fa631b6cba62783d3964e6ac4b1868 *tests/testthat/test-build-home-authors.R 2e2417a3196e27e899d16dcd80bec92b *tests/testthat/test-build-home-community.R ffda6eafd27831a74ffe3c5c6d81f9df *tests/testthat/test-build-home-index.R e40bd86ab775621e385bacc1457bf416 *tests/testthat/test-build-home-license.R fcb332c54b3b7526e15534753b09a992 *tests/testthat/test-build-home-md.R 12003d5868862a348abc3cdba7ac0a83 *tests/testthat/test-build-home.R 8106fefbeef27a937edaadf75a2ec7e2 *tests/testthat/test-build-logo.R 742a733e78b50b7012fdca386fea0264 *tests/testthat/test-build-news.R f64faa62306d51389f2242d17d4c4be1 *tests/testthat/test-build-quarto-articles.R ea4d581bd3e3d93dffabf8a2d5552359 *tests/testthat/test-build-redirects.R 4b9c8a0239450373f319f9acd4a530eb *tests/testthat/test-build-reference-index.R fdc10f24024d6ac31e0b38aba25d6c3b *tests/testthat/test-build-reference.R db17357d56af250fa7c14a3a0b082f5f *tests/testthat/test-build-search-docs.R 7494d9189d96ca2ca70c9f5338a817a7 *tests/testthat/test-build-tutorials.R dfb1f34eeb4b399bf0cd3749c292c157 *tests/testthat/test-build.R b9f63bd40496459fa8b6ebc3ddb683a8 *tests/testthat/test-check-built.R 6edcf7f7dd3e26894b2f38ea55748b51 *tests/testthat/test-check.R 553a3a8042c2c02c8c68a0ad60516767 *tests/testthat/test-config.R d74f456c6ba687026239c4e315542dd0 *tests/testthat/test-deploy-site.R 2e4fb3f7760e906afe7d2cf908f9f981 *tests/testthat/test-development.R 37f25e7cb619d96b80bd8c76f9888b0d *tests/testthat/test-external-deps.R 3cceb7dc99c0714f8047f40a7f5301bd *tests/testthat/test-figure.R 7006999da4698f190eaf428fdd9b8e31 *tests/testthat/test-highlight.R 5574d50f1932a64782cf95168c571f0b *tests/testthat/test-html-build.R bc5f328465ca2c611a2231d460e75ce6 *tests/testthat/test-init.R 5760f3c5d7121ca2ad51f9d9b182313a *tests/testthat/test-markdown.R 4f45989a9ff32d230800611ef7b60809 *tests/testthat/test-navbar-menu.R 6da1e387f92de4a10c9514de85a18f93 *tests/testthat/test-navbar.R c3058bdf63565bae6a697698c8f6df1f *tests/testthat/test-package.R 5dc2286701a77f0c0168a4cde29f7d1d *tests/testthat/test-pkgdown_print.R 0c1b6c31e7d4e7f61d2a8dc10486e8cd *tests/testthat/test-preview.R 193779dfa949237d71077047bbd73c26 *tests/testthat/test-rd-data.R 2dd6eb0659bd38e1f4e5e9266109a3dd *tests/testthat/test-rd-example.R 98c83dd5ba18307e03da1832285f84b7 *tests/testthat/test-rd-html.R 63ad5561fa0ccc37c5328626b60984f4 *tests/testthat/test-render.R dfefdf9bab9a66702503006be1aac89d *tests/testthat/test-repo.R ce737de29e228877272166361cfcf4d6 *tests/testthat/test-templates.R 289f2a228285c7f472cac939c49cb4c6 *tests/testthat/test-theme.R b347ed944c4ee7e84fb4c0f6b1dc238c *tests/testthat/test-topics-external.R e22fd7fa4356eca7d8be718a0f1c7151 *tests/testthat/test-topics.R 423487a3d0d2d4bf7490fc6ad8e48818 *tests/testthat/test-tweak-homepage.R 63c7e53bec61b40e90fb611ca75705da *tests/testthat/test-tweak-navbar.R d3946e12bf7a579b4191e886b0e9c5df *tests/testthat/test-tweak-page.R 38b7809438f8c182d3b14fde0d7a2f89 *tests/testthat/test-tweak-reference.R 70bbfddc3cbc2ff2c689eabe7550ccec *tests/testthat/test-tweak-tabset.R 5cb684ad8b5e15a9a7d797a7b2f6a4c8 *tests/testthat/test-tweak-tags.R bc370190ee04796b9b0cd9cc11bb5eaa *tests/testthat/test-usage.R 55a91821f0f195b2f868270061e0935c *tests/testthat/test-utils-fs.R f4d8e386a7f96bf0654831b2fb617661 *tests/testthat/test-utils.R 0117ffa2e1cae12eeaf4e60469a6083b *vignettes/accessibility.Rmd cc1120f57d9361a92067dc8d45962a83 *vignettes/customise.Rmd 5b58a4ff3da56e3e57baea50631e3c25 *vignettes/how-to-update-released-site.Rmd 23bd46e4b9f4898e7fc9b9adc94ae1af *vignettes/linking.Rmd 19efd0467cc00a875fc5ba303ba9ec5a *vignettes/metadata.Rmd 1e11c14c42755cd47b4bc7b3551f1158 *vignettes/pitbull.jpg 79ca83ec8c29bf368c79ffdf89f562de *vignettes/pkgdown.Rmd 006968c8f114b58454e5b957689cb06e *vignettes/quarto.qmd 1e677b785c965ccc22aa9ad079051765 *vignettes/shar-pei.jpg 4ee979c4c83a85a557030d69863e9d13 *vignettes/test/bacon.jpg 67624f50ef5e6dd6e984bc57792fde16 *vignettes/test/jss.Rmd bc1703f56a03b0f237091ab4426ce580 *vignettes/test/jss.bib 9e13367ef4850e3c0d4fa27c607e2137 *vignettes/test/jss.bst 4d890e205f4c9db08835f10b6bb3febd *vignettes/test/jss.cls dbc2ed1ee2d8d566e27d73160dfb52b1 *vignettes/test/jss.log 9c67cc56ac2c896944706843d90e4766 *vignettes/test/long-toc.Rmd 6ee7d1c05a1f58328015aab801a6c071 *vignettes/test/pdf.Rmd f650f97d9b766091d61238e3e270d40a *vignettes/test/quarto-features.qmd c3484bacd61918761324d9c1415edb57 *vignettes/test/rendering.Rmd 107c3fe335059d0162ca671a1611b937 *vignettes/test/short.Rmd 47ece2e49e5c0333677fc34e044d8257 *vignettes/test/test.txt 27ec3f090077fb6af7bf578d6fdf5346 *vignettes/test/widgets.Rmd c4da48c2d7a8712291425c9eb36ab9e8 *vignettes/translations.Rmd ����������������������������������������������������������������������������������pkgdown/po/�����������������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14642014746�012351� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/po/R-dk.po����������������������������������������������������������������������������������0000644�0001762�0000144�00000013707�14634573316�013522� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������msgid "" msgstr "" "Project-Id-Version: pkgdown 2.0.1.9000\n" "POT-Creation-Date: 2024-05-24 09:36-0500\n" "PO-Revision-Date: 2021-12-20 18:48+0100\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: dk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: build-404.R:11 msgid "Page not found (404)" msgstr "Side ikke fundet (404)" #: build-404.R:12 msgid "Content not found. Please use links in the navbar." msgstr "Indhold ikke fundet. Brug venligst links i menuen" #: build-articles.R:432 navbar.R:186 navbar.R:196 navbar.R:217 msgid "Articles" msgstr "Artikler" #: build-articles.R:570 msgid "All vignettes" msgstr "Alle vignetter" #: build-footer.R:34 msgid "Developed by" msgstr "Udviklet af" #: build-footer.R:41 msgid "Site built with <a href=\"%s\">pkgdown</a> %s." msgstr "Side bygget med <a href=\"%s\">pkgdown</a> %s." #: build-home-authors.R:12 msgid "Authors and Citation" msgstr "Forfattere og citation" #: build-home-authors.R:101 msgid "More about authors..." msgstr "Mere om forfatterene" #: build-home-authors.R:104 msgid "Developers" msgstr "Udviklere" #: build-home-authors.R:190 msgid "author" msgstr "forfatter" #: build-home-authors.R:191 msgid "compiler" msgstr "compiler" #: build-home-authors.R:192 msgid "contractor" msgstr "leverandør" #: build-home-authors.R:193 msgid "contributor" msgstr "Bidragsyder" #: build-home-authors.R:194 msgid "copyright holder" msgstr "Indehaver af ophavsret" #: build-home-authors.R:195 msgid "maintainer" msgstr "maintainer" #: build-home-authors.R:196 msgid "data contributor" msgstr "dataleverandør" #: build-home-authors.R:197 msgid "funder" msgstr "bevilgingsgiver" #: build-home-authors.R:198 msgid "reviewer" msgstr "bedømmer" #: build-home-authors.R:199 msgid "thesis advisor" msgstr "vejleder" #: build-home-authors.R:200 msgid "translator" msgstr "oversætter" #: build-home-authors.R:254 render.R:103 msgid "Citation" msgstr "Reference" #: build-home-authors.R:255 msgid "Citing %s" msgstr "Citér %s" #: build-home-community.R:23 msgid "Contributing guide" msgstr "Guide til bidragsydere" #: build-home-community.R:27 msgid "Code of conduct" msgstr "Etisk regelsæt" #: build-home-community.R:31 msgid "Getting help" msgstr "Få hjælp" #: build-home-community.R:38 msgid "Community" msgstr "Fællesskab" #: build-home-index.R:120 msgid "Dev Status" msgstr "Udviklingsstatus" #: build-home-index.R:162 msgid "View on %s" msgstr "Se på %s" #: build-home-index.R:163 msgid "Browse source code" msgstr "Se kildekode" #: build-home-index.R:164 msgid "Report a bug" msgstr "Rapportér en fejl" #: build-home-index.R:168 msgid "Links" msgstr "Links" #: build-home-index.R:173 render.R:105 msgid "Table of contents" msgstr "Indholdsfortegnelse" #: build-home-license.R:12 build-home-license.R:34 msgid "License" msgstr "Licens" #: build-home-license.R:29 msgid "Full license" msgstr "Fuld licens" #: build-news.R:102 build-news.R:259 build-news.R:263 msgid "Changelog" msgstr "Ændringslog" #: build-news.R:129 msgid "Version %s" msgstr "Version %s" #: build-news.R:141 build-news.R:254 msgid "News" msgstr "Nyheder" #: build-news.R:256 msgid "Releases" msgstr "Udgivelser" #: build-news.R:310 msgid "CRAN release: %s" msgstr "CRAN udgivelse: %s" #: build-reference-index.R:22 msgid "Package index" msgstr "Pakke indeks" #: build-reference-index.R:158 msgid "All functions" msgstr "Alle funktioner" #: build-reference.R:371 msgid "Usage" msgstr "Brug" #: build-tutorials.R:47 navbar.R:152 msgid "Tutorials" msgstr "Vejledning" #: development.R:72 msgid "Released version" msgstr "Udgivet version" #: development.R:73 msgid "In-development version" msgstr "Version under udvikling" #: development.R:74 msgid "Unreleased version" msgstr "Ikke-udgivet version" #: navbar-menu.R:173 #, fuzzy #| msgid "Search for" msgid "Search site" msgstr "Søg" #: navbar-menu.R:174 msgid "Search for" msgstr "Søg" #: navbar.R:129 msgid "Reference" msgstr "Reference" #: navbar.R:140 msgid "Light switch" msgstr "Lyskontakt" #: navbar.R:143 msgid "Light" msgstr "Lys" #: navbar.R:144 msgid "Dark" msgstr "Mørk" #: navbar.R:145 msgid "Auto" msgstr "Auto" #: navbar.R:180 msgid "Get started" msgstr "Kom igang" #: navbar.R:213 msgid "More articles..." msgstr "Flere artikler..." #: package.R:300 msgid "deprecated" msgstr "udfaset" #: package.R:301 msgid "superseded" msgstr "erstattet" #: package.R:302 msgid "experimental" msgstr "eksperimentel" #: package.R:303 msgid "stable" msgstr "stabil" #: rd-data.R:23 msgid "Details" msgstr "Detaljer" #: rd-data.R:27 msgid "Description" msgstr "Beskrivelse" #: rd-data.R:31 msgid "References" msgstr "Referencer" #: rd-data.R:35 render.R:98 msgid "Source" msgstr "Kilde" #: rd-data.R:39 msgid "Format" msgstr "Format" #: rd-data.R:43 msgid "Note" msgstr "Note" #: rd-data.R:47 msgid "Author" msgstr "Forfatter" #: rd-data.R:51 msgid "See also" msgstr "Se også" #: rd-data.R:67 msgid "Arguments" msgstr "Argumenter" #: rd-data.R:75 msgid "Value" msgstr "Værdi" #: render.R:95 msgid "Skip to contents" msgstr "Spring til indhold" #: render.R:96 msgid "Toggle navigation" msgstr "Slå navigation til og fra" #: render.R:97 msgid "On this page" msgstr "På denne side" #: render.R:99 msgid "Abstract" msgstr "Sammenfatning" #: render.R:100 msgid "Authors" msgstr "Forfattere" #: render.R:101 msgid "Version" msgstr "Version" #: render.R:102 msgid "Examples" msgstr "Eksempler" #: render.R:104 msgid "Additional details" msgstr "Yderligere detaljer" #: render.R:106 #, fuzzy #| msgid "Toggle navigation" msgid "Site navigation" msgstr "Slå navigation til og fra" #: repo.R:35 msgid "Source:" msgstr "Kilde:" #: tweak-homepage.R:61 msgid "Dev status" msgstr "Udviklingsstatus" #: usage.R:23 msgid "# Default %s method" msgstr "# Standard %s metode" #: usage.R:25 #, fuzzy #| msgid "# %s method for %s" msgid "# %s method for class '%s'" msgstr "# %s metode for %s" #~ msgid "Function reference" #~ msgstr "Funktionsoversigt" ���������������������������������������������������������pkgdown/po/R-ca.po����������������������������������������������������������������������������������0000644�0001762�0000144�00000014300�14634573316�013475� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������msgid "" msgstr "" "Project-Id-Version: pkgdown 2.0.6.9000\n" "POT-Creation-Date: 2024-05-24 09:36-0500\n" "PO-Revision-Date: 2024-06-16 09:24+0200\n" "Last-Translator: Joan Maspons <joanmaspons@gmail.com>\n" "Language: ca\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Lokalize 24.05.0\n" "Language-Team: Catalan <>\n" #: build-404.R:11 msgid "Page not found (404)" msgstr "No s'ha trobat la pàgina (404)" #: build-404.R:12 msgid "Content not found. Please use links in the navbar." msgstr "" "No s'ha trobat el contingut. Useu els enllaços de la barra de navegació." #: build-articles.R:432 navbar.R:186 navbar.R:196 navbar.R:217 msgid "Articles" msgstr "Articles" #: build-articles.R:570 msgid "All vignettes" msgstr "Totes les vinyetes" #: build-footer.R:34 msgid "Developed by" msgstr "Desenvolupat per" #: build-footer.R:41 msgid "Site built with <a href=\"%s\">pkgdown</a> %s." msgstr "Lloc construït amb <a href=\"%s\">pkgdown</a> %s." #: build-home-authors.R:12 msgid "Authors and Citation" msgstr "Autors i citació" #: build-home-authors.R:101 msgid "More about authors..." msgstr "Més sobre els autors..." #: build-home-authors.R:104 msgid "Developers" msgstr "Desenvolupadors" #: build-home-authors.R:190 msgid "author" msgstr "autor" #: build-home-authors.R:191 msgid "compiler" msgstr "compilador" #: build-home-authors.R:192 msgid "contractor" msgstr "contractista" #: build-home-authors.R:193 msgid "contributor" msgstr "col·laborador" #: build-home-authors.R:194 msgid "copyright holder" msgstr "titular dels drets d'autor" #: build-home-authors.R:195 msgid "maintainer" msgstr "mantenidor" #: build-home-authors.R:196 msgid "data contributor" msgstr "col·laborador de dades" #: build-home-authors.R:197 msgid "funder" msgstr "finançador" #: build-home-authors.R:198 msgid "reviewer" msgstr "revisor" #: build-home-authors.R:199 msgid "thesis advisor" msgstr "supervisor de tesi" #: build-home-authors.R:200 msgid "translator" msgstr "traductor" #: build-home-authors.R:254 render.R:103 msgid "Citation" msgstr "Citació" #: build-home-authors.R:255 msgid "Citing %s" msgstr "Citant %s" #: build-home-community.R:23 msgid "Contributing guide" msgstr "Guia per contribuir" #: build-home-community.R:27 msgid "Code of conduct" msgstr "Codi de conducta" #: build-home-community.R:31 msgid "Getting help" msgstr "Obtenció d'ajuda" #: build-home-community.R:38 msgid "Community" msgstr "Comunitat" #: build-home-index.R:120 msgid "Dev Status" msgstr "Estat de desenvolupament" #: build-home-index.R:162 msgid "View on %s" msgstr "Mostra a %s" #: build-home-index.R:163 msgid "Browse source code" msgstr "Navega pel codi font" #: build-home-index.R:164 msgid "Report a bug" msgstr "Informa d'un error" #: build-home-index.R:168 msgid "Links" msgstr "Enllaços" #: build-home-index.R:173 render.R:105 msgid "Table of contents" msgstr "Taula de continguts" #: build-home-license.R:12 build-home-license.R:34 msgid "License" msgstr "Llicència" #: build-home-license.R:29 msgid "Full license" msgstr "Llicència completa" #: build-news.R:102 build-news.R:259 build-news.R:263 msgid "Changelog" msgstr "Registre de canvis" #: build-news.R:129 msgid "Version %s" msgstr "Versió %s" #: build-news.R:141 build-news.R:254 msgid "News" msgstr "Novetats" #: build-news.R:256 msgid "Releases" msgstr "Versions" #: build-news.R:310 msgid "CRAN release: %s" msgstr "Versió del CRAN: %s" #: build-reference-index.R:22 msgid "Package index" msgstr "Índex del paquet" #: build-reference-index.R:158 msgid "All functions" msgstr "Totes les funcions" #: build-reference.R:371 msgid "Usage" msgstr "Ús" #: build-tutorials.R:47 navbar.R:152 msgid "Tutorials" msgstr "Guies d'aprenentatge" #: development.R:72 msgid "Released version" msgstr "Versió publicada" #: development.R:73 msgid "In-development version" msgstr "Versió en desenvolupament" #: development.R:74 msgid "Unreleased version" msgstr "Versió no publicada" #: navbar-menu.R:173 #| msgid "Search for" msgid "Search site" msgstr "Cerca al lloc" #: navbar-menu.R:174 msgid "Search for" msgstr "Cerca" #: navbar.R:129 msgid "Reference" msgstr "Referència" #: navbar.R:140 msgid "Light switch" msgstr "Interruptor de color" #: navbar.R:143 msgid "Light" msgstr "Clar" #: navbar.R:144 msgid "Dark" msgstr "Fosc" #: navbar.R:145 msgid "Auto" msgstr "Automàtic" #: navbar.R:180 msgid "Get started" msgstr "Comenceu" #: navbar.R:213 msgid "More articles..." msgstr "Més articles..." #: package.R:300 msgid "deprecated" msgstr "obsoleta" #: package.R:301 msgid "superseded" msgstr "reemplaçada" #: package.R:302 msgid "experimental" msgstr "experimental" #: package.R:303 msgid "stable" msgstr "estable" #: rd-data.R:23 msgid "Details" msgstr "Detalls" #: rd-data.R:27 msgid "Description" msgstr "Descripció" #: rd-data.R:31 msgid "References" msgstr "Referències" #: rd-data.R:35 render.R:98 msgid "Source" msgstr "Font" #: rd-data.R:39 msgid "Format" msgstr "Format" #: rd-data.R:43 msgid "Note" msgstr "Nota" #: rd-data.R:47 msgid "Author" msgstr "Autor" #: rd-data.R:51 msgid "See also" msgstr "Vegeu també" #: rd-data.R:67 msgid "Arguments" msgstr "Paràmetres" #: rd-data.R:75 msgid "Value" msgstr "Valor" #: render.R:95 msgid "Skip to contents" msgstr "Salta als continguts" #: render.R:96 msgid "Toggle navigation" msgstr "Commuta la navegació" #: render.R:97 msgid "On this page" msgstr "En aquesta pàgina" #: render.R:99 msgid "Abstract" msgstr "Resum" #: render.R:100 msgid "Authors" msgstr "Autors" #: render.R:101 msgid "Version" msgstr "Versió" #: render.R:102 msgid "Examples" msgstr "Exemples" #: render.R:104 msgid "Additional details" msgstr "Detalls addicionals" #: render.R:106 #| msgid "Toggle navigation" msgid "Site navigation" msgstr "Navegació del lloc" #: repo.R:35 msgid "Source:" msgstr "Font:" #: tweak-homepage.R:61 msgid "Dev status" msgstr "Estat de desenvolupament" #: usage.R:23 msgid "# Default %s method" msgstr "# Mètode %s per defecte" #: usage.R:25 #| msgid "# %s method for %s" msgid "# %s method for class '%s'" msgstr "# Mètode %s per a la classe «%s»" #~ msgid "Function reference" #~ msgstr "Llistat de funcions" ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/po/R-fr.po����������������������������������������������������������������������������������0000644�0001762�0000144�00000014304�14642014746�013521� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������msgid "" msgstr "" "Project-Id-Version: pkgdown 2.0.9.9000\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-05-24 09:36-0500\n" "PO-Revision-Date: 2024-06-15 20:28-0400\n" "Last-Translator: J.P. Le Cavalier <jplecavalier@me.com>\n" "Language-Team: fr\n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: potools 0.2.2\n" #: build-404.R:11 msgid "Page not found (404)" msgstr "Page introuvable (404)" #: build-404.R:12 msgid "Content not found. Please use links in the navbar." msgstr "" "Contenu introuvable. Merci d'utiliser les liens de la barre de navigation." #: build-articles.R:432 navbar.R:186 navbar.R:196 navbar.R:217 msgid "Articles" msgstr "Articles" #: build-articles.R:570 msgid "All vignettes" msgstr "Tous les articles" #: build-footer.R:34 msgid "Developed by" msgstr "Développé par" #: build-footer.R:41 msgid "Site built with <a href=\"%s\">pkgdown</a> %s." msgstr "Site créé avec <a href=\"%s\">pkgdown</a> %s." #: build-home-authors.R:12 msgid "Authors and Citation" msgstr "Auteur·rice·s et Citation" #: build-home-authors.R:101 msgid "More about authors..." msgstr "À propos des auteur·rice·s..." #: build-home-authors.R:104 msgid "Developers" msgstr "Développeur·se·s" #: build-home-authors.R:190 msgid "author" msgstr "auteur·rice" #: build-home-authors.R:191 msgid "compiler" msgstr "compilateur·rice" #: build-home-authors.R:192 msgid "contractor" msgstr "fournisseur·se" #: build-home-authors.R:193 msgid "contributor" msgstr "contributeur·rice" #: build-home-authors.R:194 msgid "copyright holder" msgstr "titulaire des droits d'auteur" #: build-home-authors.R:195 msgid "maintainer" msgstr "mainteneur·se" #: build-home-authors.R:196 msgid "data contributor" msgstr "contributeur·rice des données" #: build-home-authors.R:197 msgid "funder" msgstr "fondateur·rice" #: build-home-authors.R:198 msgid "reviewer" msgstr "réviseur·se" #: build-home-authors.R:199 msgid "thesis advisor" msgstr "directeur·rice de thèse" #: build-home-authors.R:200 msgid "translator" msgstr "traducteur·rice" #: build-home-authors.R:254 render.R:103 msgid "Citation" msgstr "Citation" #: build-home-authors.R:255 msgid "Citing %s" msgstr "Citer %s" #: build-home-community.R:23 msgid "Contributing guide" msgstr "Guide de contribution" #: build-home-community.R:27 msgid "Code of conduct" msgstr "Code de conduite" #: build-home-community.R:31 msgid "Getting help" msgstr "Obtenir de l'aide" #: build-home-community.R:38 msgid "Community" msgstr "Communauté" #: build-home-index.R:120 msgid "Dev Status" msgstr "Statut de développement" #: build-home-index.R:162 msgid "View on %s" msgstr "Voir sur %s" #: build-home-index.R:163 msgid "Browse source code" msgstr "Naviguer le code source" #: build-home-index.R:164 msgid "Report a bug" msgstr "Signaler un bogue" #: build-home-index.R:168 msgid "Links" msgstr "Liens" #: build-home-index.R:173 render.R:105 msgid "Table of contents" msgstr "Table des matières" #: build-home-license.R:12 build-home-license.R:34 msgid "License" msgstr "Licence" #: build-home-license.R:29 msgid "Full license" msgstr "Licence complète" #: build-news.R:102 build-news.R:259 build-news.R:263 msgid "Changelog" msgstr "Changements" #: build-news.R:129 msgid "Version %s" msgstr "Version %s" #: build-news.R:141 build-news.R:254 msgid "News" msgstr "Nouveautés" #: build-news.R:256 msgid "Releases" msgstr "Versions" #: build-news.R:310 msgid "CRAN release: %s" msgstr "Version CRAN : %s" #: build-reference-index.R:22 msgid "Package index" msgstr "Index du paquet" #: build-reference-index.R:158 msgid "All functions" msgstr "Toutes les fonctions" #: build-reference.R:371 msgid "Usage" msgstr "Utilisation" #: build-tutorials.R:47 navbar.R:152 msgid "Tutorials" msgstr "Tutoriels" #: development.R:72 msgid "Released version" msgstr "Dernière version publiée" #: development.R:73 msgid "In-development version" msgstr "Version en développement" #: development.R:74 msgid "Unreleased version" msgstr "Version inédite" #: navbar-menu.R:173 msgid "Search site" msgstr "Rechercher sur le site" #: navbar-menu.R:174 msgid "Search for" msgstr "Rechercher" #: navbar.R:129 msgid "Reference" msgstr "Référence" #: navbar.R:140 msgid "Light switch" msgstr "Interrupteur" #: navbar.R:143 msgid "Light" msgstr "Clair" #: navbar.R:144 msgid "Dark" msgstr "Sombre" #: navbar.R:145 msgid "Auto" msgstr "Automatique" #: navbar.R:180 msgid "Get started" msgstr "Prise en main" #: navbar.R:213 msgid "More articles..." msgstr "Plus d'articles..." #: package.R:300 msgid "deprecated" msgstr "obsolète" #: package.R:301 msgid "superseded" msgstr "remplacée" #: package.R:302 msgid "experimental" msgstr "expérimentale" #: package.R:303 msgid "stable" msgstr "stable" #: rd-data.R:23 msgid "Details" msgstr "Détails" #: rd-data.R:27 msgid "Description" msgstr "Description" #: rd-data.R:31 msgid "References" msgstr "Références" #: rd-data.R:35 render.R:98 msgid "Source" msgstr "Source" #: rd-data.R:39 msgid "Format" msgstr "Format" #: rd-data.R:43 msgid "Note" msgstr "Note" #: rd-data.R:47 msgid "Author" msgstr "Auteur" #: rd-data.R:51 msgid "See also" msgstr "Voir également" #: rd-data.R:67 msgid "Arguments" msgstr "Arguments" #: rd-data.R:75 msgid "Value" msgstr "Valeur de retour" #: render.R:95 msgid "Skip to contents" msgstr "Passer au contenu" #: render.R:96 msgid "Toggle navigation" msgstr "Activer la navigation" #: render.R:97 msgid "On this page" msgstr "Sur cette page" #: render.R:99 msgid "Abstract" msgstr "Résumé" #: render.R:100 msgid "Authors" msgstr "Auteur·rice·s" #: render.R:101 msgid "Version" msgstr "Version" #: render.R:102 msgid "Examples" msgstr "Exemples" #: render.R:104 msgid "Additional details" msgstr "Détails supplémentaires" #: render.R:106 msgid "Site navigation" msgstr "Navigation sur le site" #: repo.R:35 msgid "Source:" msgstr "Source :" #: tweak-homepage.R:61 msgid "Dev status" msgstr "Statut de développement" #: usage.R:23 msgid "# Default %s method" msgstr "# Méthode %s par défaut" #: usage.R:25 msgid "# %s method for class '%s'" msgstr "# Méthode %s pour la classe %s" #~ msgid "Function reference" #~ msgstr "Documentation des fonctions" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/po/R-pkgdown.pot����������������������������������������������������������������������������0000644�0001762�0000144�00000011441�14633374223�014745� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������msgid "" msgstr "" "Project-Id-Version: pkgdown 2.0.9.9000\n" "POT-Creation-Date: 2024-05-24 09:36-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: build-404.R:11 msgid "Page not found (404)" msgstr "" #: build-404.R:12 msgid "Content not found. Please use links in the navbar." msgstr "" #: build-articles.R:432 navbar.R:186 navbar.R:196 navbar.R:217 msgid "Articles" msgstr "" #: build-articles.R:570 msgid "All vignettes" msgstr "" #: build-footer.R:34 msgid "Developed by" msgstr "" #: build-footer.R:41 msgid "Site built with <a href=\"%s\">pkgdown</a> %s." msgstr "" #: build-home-authors.R:12 msgid "Authors and Citation" msgstr "" #: build-home-authors.R:101 msgid "More about authors..." msgstr "" #: build-home-authors.R:104 msgid "Developers" msgstr "" #: build-home-authors.R:190 msgid "author" msgstr "" #: build-home-authors.R:191 msgid "compiler" msgstr "" #: build-home-authors.R:192 msgid "contractor" msgstr "" #: build-home-authors.R:193 msgid "contributor" msgstr "" #: build-home-authors.R:194 msgid "copyright holder" msgstr "" #: build-home-authors.R:195 msgid "maintainer" msgstr "" #: build-home-authors.R:196 msgid "data contributor" msgstr "" #: build-home-authors.R:197 msgid "funder" msgstr "" #: build-home-authors.R:198 msgid "reviewer" msgstr "" #: build-home-authors.R:199 msgid "thesis advisor" msgstr "" #: build-home-authors.R:200 msgid "translator" msgstr "" #: build-home-authors.R:254 render.R:103 msgid "Citation" msgstr "" #: build-home-authors.R:255 msgid "Citing %s" msgstr "" #: build-home-community.R:23 msgid "Contributing guide" msgstr "" #: build-home-community.R:27 msgid "Code of conduct" msgstr "" #: build-home-community.R:31 msgid "Getting help" msgstr "" #: build-home-community.R:38 msgid "Community" msgstr "" #: build-home-index.R:120 msgid "Dev Status" msgstr "" #: build-home-index.R:162 msgid "View on %s" msgstr "" #: build-home-index.R:163 msgid "Browse source code" msgstr "" #: build-home-index.R:164 msgid "Report a bug" msgstr "" #: build-home-index.R:168 msgid "Links" msgstr "" #: build-home-index.R:173 render.R:105 msgid "Table of contents" msgstr "" #: build-home-license.R:12 build-home-license.R:34 msgid "License" msgstr "" #: build-home-license.R:29 msgid "Full license" msgstr "" #: build-news.R:102 build-news.R:259 build-news.R:263 msgid "Changelog" msgstr "" #: build-news.R:129 msgid "Version %s" msgstr "" #: build-news.R:141 build-news.R:254 msgid "News" msgstr "" #: build-news.R:256 msgid "Releases" msgstr "" #: build-news.R:310 msgid "CRAN release: %s" msgstr "" #: build-reference-index.R:22 msgid "Package index" msgstr "" #: build-reference-index.R:158 msgid "All functions" msgstr "" #: build-reference.R:371 msgid "Usage" msgstr "" #: build-tutorials.R:47 navbar.R:152 msgid "Tutorials" msgstr "" #: development.R:72 msgid "Released version" msgstr "" #: development.R:73 msgid "In-development version" msgstr "" #: development.R:74 msgid "Unreleased version" msgstr "" #: navbar-menu.R:173 msgid "Search site" msgstr "" #: navbar-menu.R:174 msgid "Search for" msgstr "" #: navbar.R:129 msgid "Reference" msgstr "" #: navbar.R:140 msgid "Light switch" msgstr "" #: navbar.R:143 msgid "Light" msgstr "" #: navbar.R:144 msgid "Dark" msgstr "" #: navbar.R:145 msgid "Auto" msgstr "" #: navbar.R:180 msgid "Get started" msgstr "" #: navbar.R:213 msgid "More articles..." msgstr "" #: package.R:300 msgid "deprecated" msgstr "" #: package.R:301 msgid "superseded" msgstr "" #: package.R:302 msgid "experimental" msgstr "" #: package.R:303 msgid "stable" msgstr "" #: rd-data.R:23 msgid "Details" msgstr "" #: rd-data.R:27 msgid "Description" msgstr "" #: rd-data.R:31 msgid "References" msgstr "" #: rd-data.R:35 render.R:98 msgid "Source" msgstr "" #: rd-data.R:39 msgid "Format" msgstr "" #: rd-data.R:43 msgid "Note" msgstr "" #: rd-data.R:47 msgid "Author" msgstr "" #: rd-data.R:51 msgid "See also" msgstr "" #: rd-data.R:67 msgid "Arguments" msgstr "" #: rd-data.R:75 msgid "Value" msgstr "" #: render.R:95 msgid "Skip to contents" msgstr "" #: render.R:96 msgid "Toggle navigation" msgstr "" #: render.R:97 msgid "On this page" msgstr "" #: render.R:99 msgid "Abstract" msgstr "" #: render.R:100 msgid "Authors" msgstr "" #: render.R:101 msgid "Version" msgstr "" #: render.R:102 msgid "Examples" msgstr "" #: render.R:104 msgid "Additional details" msgstr "" #: render.R:106 msgid "Site navigation" msgstr "" #: repo.R:35 msgid "Source:" msgstr "" #: tweak-homepage.R:61 msgid "Dev status" msgstr "" #: usage.R:23 msgid "# Default %s method" msgstr "" #: usage.R:25 msgid "# %s method for class '%s'" msgstr "" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/po/R-es.po����������������������������������������������������������������������������������0000644�0001762�0000144�00000014755�14634573316�013537� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������msgid "" msgstr "" "Project-Id-Version: pkgdown 2.0.9.9000\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-05-24 09:36-0500\n" "PO-Revision-Date: 2024-06-17 07:31+0000\n" "Last-Translator: @dieghernan\n" "Language-Team: es\n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Loco-Source-Locale: es_ES\n" "X-Generator: Loco https://localise.biz/\n" "X-Loco-Parser: loco_parse_po\n" #: build-404.R:11 msgid "Page not found (404)" msgstr "Página no encontrada (404)" #: build-404.R:12 msgid "Content not found. Please use links in the navbar." msgstr "" "Contenido no encontrado. Por favor utilice los enlaces de la barra de " "navegación." #: build-articles.R:432 navbar.R:186 navbar.R:196 navbar.R:217 msgid "Articles" msgstr "Artículos" #: build-articles.R:570 msgid "All vignettes" msgstr "Todos los artículos" #: build-footer.R:34 msgid "Developed by" msgstr "Desarrollado por" #: build-footer.R:41 msgid "Site built with <a href=\"%s\">pkgdown</a> %s." msgstr "Sitio creado con <a href=\"%s\">pkgdown</a> %s." #: build-home-authors.R:12 msgid "Authors and Citation" msgstr "Autores y Citas" #: build-home-authors.R:101 msgid "More about authors..." msgstr "Más sobre los autores..." #: build-home-authors.R:104 msgid "Developers" msgstr "Desarrolladores" #: build-home-authors.R:190 msgid "author" msgstr "autor-a" #: build-home-authors.R:191 msgid "compiler" msgstr "compilador-a" #: build-home-authors.R:192 msgid "contractor" msgstr "contratista" #: build-home-authors.R:193 msgid "contributor" msgstr "colaborador-a" #: build-home-authors.R:194 msgid "copyright holder" msgstr "titular de los derechos de autor" #: build-home-authors.R:195 msgid "maintainer" msgstr "mantenedor-a" #: build-home-authors.R:196 msgid "data contributor" msgstr "colaborador-a de datos" #: build-home-authors.R:197 msgid "funder" msgstr "patrocinador-a" #: build-home-authors.R:198 msgid "reviewer" msgstr "revisor-a" #: build-home-authors.R:199 msgid "thesis advisor" msgstr "director-a de tesis" #: build-home-authors.R:200 msgid "translator" msgstr "traductor-a" #: build-home-authors.R:254 render.R:103 msgid "Citation" msgstr "Cita" #: build-home-authors.R:255 msgid "Citing %s" msgstr "Cómo citar %s" #: build-home-community.R:23 msgid "Contributing guide" msgstr "Guía para colaboradores" #: build-home-community.R:27 msgid "Code of conduct" msgstr "Código de conducta" #: build-home-community.R:31 msgid "Getting help" msgstr "Ayuda y soporte" #: build-home-community.R:38 msgid "Community" msgstr "Comunidad" #: build-home-index.R:120 msgid "Dev Status" msgstr "Estado de Desarrollo" #: build-home-index.R:162 msgid "View on %s" msgstr "Ver en %s" #: build-home-index.R:163 msgid "Browse source code" msgstr "Ir al código fuente" #: build-home-index.R:164 msgid "Report a bug" msgstr "Informar de un problema" #: build-home-index.R:168 msgid "Links" msgstr "Enlaces" #: build-home-index.R:173 render.R:105 msgid "Table of contents" msgstr "Índice de contenidos" #: build-home-license.R:12 build-home-license.R:34 msgid "License" msgstr "Licencia" #: build-home-license.R:29 msgid "Full license" msgstr "Licencia completa" #: build-news.R:102 build-news.R:259 build-news.R:263 msgid "Changelog" msgstr "Registro de cambios" #: build-news.R:129 msgid "Version %s" msgstr "Versión %s" #: build-news.R:141 build-news.R:254 msgid "News" msgstr "Noticias" #: build-news.R:256 msgid "Releases" msgstr "Lanzamientos" #: build-news.R:310 msgid "CRAN release: %s" msgstr "Versión CRAN: %s" #: build-reference-index.R:22 msgid "Package index" msgstr "Índice del paquete" #: build-reference-index.R:158 msgid "All functions" msgstr "Todas las funciones" #: build-reference.R:371 msgid "Usage" msgstr "Uso" #: build-tutorials.R:47 navbar.R:152 msgid "Tutorials" msgstr "Tutoriales" #: development.R:72 msgid "Released version" msgstr "Versión publicada" #: development.R:73 msgid "In-development version" msgstr "Versión en desarrollo" #: development.R:74 msgid "Unreleased version" msgstr "Versión no publicada" #: navbar-menu.R:173 #, fuzzy #| msgid "Search for" msgid "Search site" msgstr "Buscar en el sitio" #: navbar-menu.R:174 msgid "Search for" msgstr "Buscar" #: navbar.R:129 msgid "Reference" msgstr "Índice" #: navbar.R:140 msgid "Light switch" msgstr "Interruptor de color" #: navbar.R:143 msgid "Light" msgstr "Claro" #: navbar.R:144 msgid "Dark" msgstr "Oscuro" #: navbar.R:145 msgid "Auto" msgstr "Auto" #: navbar.R:180 msgid "Get started" msgstr "Primeros pasos" #: navbar.R:213 msgid "More articles..." msgstr "Más artículos..." # Assuming feminine (e.g. functions). Arguments in Spanish are masculine (e.g. obsoleto) #: package.R:300 msgid "deprecated" msgstr "obsoleta" # Assuming feminine (e.g. functions). Arguments in Spanish are masculine (e.g. reemplazado) #: package.R:301 msgid "superseded" msgstr "reemplazada" #: package.R:302 msgid "experimental" msgstr "experimental" #: package.R:303 msgid "stable" msgstr "estable" #: rd-data.R:23 msgid "Details" msgstr "Detalles" #: rd-data.R:27 msgid "Description" msgstr "Descripción" #: rd-data.R:31 msgid "References" msgstr "Referencias" #: rd-data.R:35 render.R:98 msgid "Source" msgstr "Fuente" #: rd-data.R:39 msgid "Format" msgstr "Formato" #: rd-data.R:43 msgid "Note" msgstr "Nota" #: rd-data.R:47 msgid "Author" msgstr "Autor-a" #: rd-data.R:51 msgid "See also" msgstr "Ver también" #: rd-data.R:67 msgid "Arguments" msgstr "Argumentos" #: rd-data.R:75 msgid "Value" msgstr "Valor" #: render.R:95 msgid "Skip to contents" msgstr "Ir al contenido" #: render.R:96 msgid "Toggle navigation" msgstr "Cambiar la navegación" #: render.R:97 msgid "On this page" msgstr "En esta página" #: render.R:99 msgid "Abstract" msgstr "Resumen" #: render.R:100 msgid "Authors" msgstr "Autores" #: render.R:101 msgid "Version" msgstr "Versión" #: render.R:102 msgid "Examples" msgstr "Ejemplos" #: render.R:104 msgid "Additional details" msgstr "Detalles adicionales" #: render.R:106 #, fuzzy #| msgid "Toggle navigation" msgid "Site navigation" msgstr "Navegación del sitio" #: repo.R:35 msgid "Source:" msgstr "Código:" #: tweak-homepage.R:61 msgid "Dev status" msgstr "Estado de desarrollo" #: usage.R:23 msgid "# Default %s method" msgstr "# Método %s por defecto" #: usage.R:25 #, fuzzy #| msgid "# %s method for %s" msgid "# %s method for class '%s'" msgstr "# Método %s para la clase %s" #~ msgid "Function reference" #~ msgstr "Índice de funciones" �������������������pkgdown/po/R-pt.po����������������������������������������������������������������������������������0000644�0001762�0000144�00000014250�14634573316�013541� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������msgid "" msgstr "" "Project-Id-Version: pkgdown 2.0.9.9000\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-05-24 09:36-0500\n" "PO-Revision-Date: 2024-06-16 00:00-0500\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: pt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: build-404.R:11 msgid "Page not found (404)" msgstr "Página não encontrada (404)" #: build-404.R:12 msgid "Content not found. Please use links in the navbar." msgstr "Conteúdo não encontrado. Por favor, use links na navbar." #: build-articles.R:432 navbar.R:186 navbar.R:196 navbar.R:217 msgid "Articles" msgstr "Artigos" #: build-articles.R:570 msgid "All vignettes" msgstr "Todas as vinhetas" #: build-footer.R:34 msgid "Developed by" msgstr "Desenvolvido por" #: build-footer.R:41 msgid "Site built with <a href=\"%s\">pkgdown</a> %s." msgstr "Site criado com <a href=\"%s\">pkgdown</a> %s." #: build-home-authors.R:12 msgid "Authors and Citation" msgstr "Autores e citação" #: build-home-authors.R:101 msgid "More about authors..." msgstr "Mais sobre autores..." #: build-home-authors.R:104 msgid "Developers" msgstr "Desenvolvedores" #: build-home-authors.R:190 msgid "author" msgstr "autor" #: build-home-authors.R:191 msgid "compiler" msgstr "compilador" #: build-home-authors.R:192 msgid "contractor" msgstr "contratante" #: build-home-authors.R:193 msgid "contributor" msgstr "contribuinte" #: build-home-authors.R:194 msgid "copyright holder" msgstr "titular dos direitos autorais" #: build-home-authors.R:195 msgid "maintainer" msgstr "mantenedor" #: build-home-authors.R:196 msgid "data contributor" msgstr "contribuidor de dados" #: build-home-authors.R:197 msgid "funder" msgstr "financiador" #: build-home-authors.R:198 msgid "reviewer" msgstr "revisor" #: build-home-authors.R:199 msgid "thesis advisor" msgstr "orientador de tese" #: build-home-authors.R:200 msgid "translator" msgstr "tradutor" #: build-home-authors.R:254 render.R:103 msgid "Citation" msgstr "Citação" #: build-home-authors.R:255 msgid "Citing %s" msgstr "Citando %s" #: build-home-community.R:23 msgid "Contributing guide" msgstr "Guia de contribuição" #: build-home-community.R:27 msgid "Code of conduct" msgstr "Código de conduta" #: build-home-community.R:31 msgid "Getting help" msgstr "Obter ajuda" #: build-home-community.R:38 msgid "Community" msgstr "Comunidade" #: build-home-index.R:120 msgid "Dev Status" msgstr "Estado de Desenvolvimento" #: build-home-index.R:162 msgid "View on %s" msgstr "Veja no %s" #: build-home-index.R:163 msgid "Browse source code" msgstr "Navegue pelo código-fonte" #: build-home-index.R:164 msgid "Report a bug" msgstr "Reportar um erro" #: build-home-index.R:168 msgid "Links" msgstr "Links" #: build-home-index.R:173 render.R:105 msgid "Table of contents" msgstr "Índice" #: build-home-license.R:12 build-home-license.R:34 msgid "License" msgstr "Licença" #: build-home-license.R:29 msgid "Full license" msgstr "Licença completa" #: build-news.R:102 build-news.R:259 build-news.R:263 msgid "Changelog" msgstr "Changelog" #: build-news.R:129 msgid "Version %s" msgstr "Versão %s" #: build-news.R:141 build-news.R:254 msgid "News" msgstr "Notícia" #: build-news.R:256 msgid "Releases" msgstr "Lançamentos" #: build-news.R:310 msgid "CRAN release: %s" msgstr "Lançamento CRAN: %s" #: build-reference-index.R:22 msgid "Package index" msgstr "Índice de pacotes" #: build-reference-index.R:158 msgid "All functions" msgstr "Todas as funções" #: build-reference.R:371 msgid "Usage" msgstr "Uso" #: build-tutorials.R:47 navbar.R:152 msgid "Tutorials" msgstr "Tutoriais" #: development.R:72 msgid "Released version" msgstr "Versão lançada" #: development.R:73 msgid "In-development version" msgstr "Versão em desenvolvimento" #: development.R:74 msgid "Unreleased version" msgstr "Versão não lançada" #: navbar-menu.R:173 #, fuzzy #| msgid "Search for" msgid "Search site" msgstr "Pesquisar site" #: navbar-menu.R:174 msgid "Search for" msgstr "Procurar" #: navbar.R:129 msgid "Reference" msgstr "Referência" #: navbar.R:140 msgid "Light switch" # Appearance msgstr "Interruptor de luz" #: navbar.R:143 msgid "Light" msgstr "Clara" #: navbar.R:144 msgid "Dark" msgstr "Escuro" #: navbar.R:145 msgid "Auto" msgstr "Auto" #: navbar.R:180 msgid "Get started" msgstr "Primeiros passos" #: navbar.R:213 msgid "More articles..." msgstr "Mais artigos..." #: package.R:300 msgid "deprecated" msgstr "obsoleta" #: package.R:301 msgid "superseded" msgstr "substituída" #: package.R:302 msgid "experimental" msgstr "experimental" #: package.R:303 msgid "stable" msgstr "estável" #: rd-data.R:23 msgid "Details" msgstr "Detalhes" #: rd-data.R:27 msgid "Description" msgstr "Descrição" #: rd-data.R:31 msgid "References" msgstr "Referências" #: rd-data.R:35 render.R:98 msgid "Source" msgstr "Fonte" #: rd-data.R:39 msgid "Format" msgstr "Formato" #: rd-data.R:43 msgid "Note" msgstr "Nota" #: rd-data.R:47 msgid "Author" msgstr "Autor" #: rd-data.R:51 msgid "See also" msgstr "Veja também" #: rd-data.R:67 msgid "Arguments" msgstr "Argumentos" #: rd-data.R:75 msgid "Value" msgstr "Valor" #: render.R:95 msgid "Skip to contents" msgstr "Avance para o conteúdo" #: render.R:96 msgid "Toggle navigation" msgstr "Alternar de navegação" #: render.R:97 msgid "On this page" msgstr "Nesta página" #: render.R:99 msgid "Abstract" msgstr "Resumo" #: render.R:100 msgid "Authors" msgstr "Autores" #: render.R:101 msgid "Version" msgstr "Versão" #: render.R:102 msgid "Examples" msgstr "Exemplos" #: render.R:104 msgid "Additional details" msgstr "Detalhes adicionais" #: render.R:106 #, fuzzy #| msgid "Toggle navigation" msgid "Site navigation" msgstr "Ativar/desativar navegação" #: repo.R:35 msgid "Source:" msgstr "Fonte:" #: tweak-homepage.R:61 msgid "Dev status" msgstr "Status de desenvolvimento" #: usage.R:47 msgid "# Default %s method" msgstr "# Método %s padrão" #: usage.R:49 #, fuzzy #| msgid "# %s method for %s" msgid "# %s method for class '%s'" msgstr "# método %s para a classe '%s'" #~ msgid "Function reference" #~ msgstr "Referência para funções" ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/po/R-tr.po����������������������������������������������������������������������������������0000644�0001762�0000144�00000013763�14634573316�013553� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������msgid "" msgstr "" "Project-Id-Version: pkgdown 1.9000.9000.9000\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-05-24 09:36-0500\n" "PO-Revision-Date: 2021-10-28 08:02-0500\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: build-404.R:11 msgid "Page not found (404)" msgstr "Sayfa bulunamıyor (404)" #: build-404.R:12 msgid "Content not found. Please use links in the navbar." msgstr "İçerik bulunamıyor. Lütfen yukarıdaki gezinme çubuğundaki bağları kullanın." #: build-articles.R:432 navbar.R:186 navbar.R:196 navbar.R:217 msgid "Articles" msgstr "Makaleler" #: build-articles.R:570 msgid "All vignettes" msgstr "Bütün makaleler" #: build-footer.R:34 msgid "Developed by" msgstr "Geliştiren" #: build-footer.R:41 msgid "Site built with <a href=\"%s\">pkgdown</a> %s." msgstr "Site <a href=\"%s\">pkgdown</a> %s ile geliştirilmiştir." #: build-home-authors.R:12 msgid "Authors and Citation" msgstr "Yazarlar ve Alıntı" #: build-home-authors.R:101 msgid "More about authors..." msgstr "Yazarlar hakkında daha fazla bilgi..." #: build-home-authors.R:104 msgid "Developers" msgstr "Geliştiriciler" #: build-home-authors.R:190 msgid "author" msgstr "yazar" #: build-home-authors.R:191 msgid "compiler" msgstr "derleyici" #: build-home-authors.R:192 msgid "contractor" msgstr "yüklenici" #: build-home-authors.R:193 msgid "contributor" msgstr "katılımcı" #: build-home-authors.R:194 msgid "copyright holder" msgstr "telif hakkı sahibi" #: build-home-authors.R:195 msgid "maintainer" msgstr "bakımcı" #: build-home-authors.R:196 msgid "data contributor" msgstr "veri katılımcısı" #: build-home-authors.R:197 msgid "funder" msgstr "fon sağlayıcı" #: build-home-authors.R:198 msgid "reviewer" msgstr "eleştirmen" #: build-home-authors.R:199 msgid "thesis advisor" msgstr "tez danışmanı" #: build-home-authors.R:200 msgid "translator" msgstr "çevirmen" #: build-home-authors.R:254 render.R:103 msgid "Citation" msgstr "Alıntı" #: build-home-authors.R:255 msgid "Citing %s" msgstr "%s'ı kaynak gösterme" #: build-home-community.R:23 msgid "Contributing guide" msgstr "Katkıda bulunma rehberi" #: build-home-community.R:27 msgid "Code of conduct" msgstr "Davranış kuralları" #: build-home-community.R:31 msgid "Getting help" msgstr "Yardım" #: build-home-community.R:38 msgid "Community" msgstr "Komünite" #: build-home-index.R:120 msgid "Dev Status" msgstr "Geliştirme statüsü" #: build-home-index.R:162 msgid "View on %s" msgstr "%s'da gör" #: build-home-index.R:163 msgid "Browse source code" msgstr "Kaynak koduna göz at" #: build-home-index.R:164 msgid "Report a bug" msgstr "Hata bildir" #: build-home-index.R:168 msgid "Links" msgstr "Bağlantılar" #: build-home-index.R:173 render.R:105 msgid "Table of contents" msgstr "İçindekiler" #: build-home-license.R:12 build-home-license.R:34 msgid "License" msgstr "Lisans" #: build-home-license.R:29 msgid "Full license" msgstr "Tam lisans" #: build-news.R:102 build-news.R:259 build-news.R:263 msgid "Changelog" msgstr "Değişiklik günlüğü" #: build-news.R:129 msgid "Version %s" msgstr "Sürüm %s" #: build-news.R:141 build-news.R:254 msgid "News" msgstr "Haberler" #: build-news.R:256 msgid "Releases" msgstr "Yayınlar" #: build-news.R:310 msgid "CRAN release: %s" msgstr "CRAN yayını: %s" #: build-reference-index.R:22 msgid "Package index" msgstr "Paket dizini" #: build-reference-index.R:158 msgid "All functions" msgstr "Bütün fonksiyonlar" #: build-reference.R:371 msgid "Usage" msgstr "Kullanım" #: build-tutorials.R:47 navbar.R:152 msgid "Tutorials" msgstr "Öğreticiler" #: development.R:72 msgid "Released version" msgstr "Yayımlanan sürüm" #: development.R:73 msgid "In-development version" msgstr "Geliştirme aşamasındaki sürüm" #: development.R:74 msgid "Unreleased version" msgstr "Yayınlanmamış sürüm" #: navbar-menu.R:173 msgid "Search site" msgstr "Ara" #: navbar-menu.R:174 msgid "Search for" msgstr "Ara" #: navbar.R:129 msgid "Reference" msgstr "Referans" #: navbar.R:140 msgid "Light switch" msgstr "Koyu/açık" #: navbar.R:143 msgid "Light" msgstr "Koyu" #: navbar.R:144 msgid "Dark" msgstr "Açık" #: navbar.R:145 msgid "Auto" msgstr "Otomatik" #: navbar.R:180 msgid "Get started" msgstr "Başla" #: navbar.R:213 msgid "More articles..." msgstr "Diğer makaleler..." #: package.R:300 msgid "deprecated" msgstr "artık kullanılmayan" #: package.R:301 msgid "superseded" msgstr "yerine gelen" #: package.R:302 msgid "experimental" msgstr "deneysel" #: package.R:303 msgid "stable" msgstr "sabit" #: rd-data.R:23 msgid "Details" msgstr "Detaylar" #: rd-data.R:27 msgid "Description" msgstr "Açıklama" #: rd-data.R:31 msgid "References" msgstr "Referanslar" #: rd-data.R:35 render.R:98 msgid "Source" msgstr "Kaynak" #: rd-data.R:39 msgid "Format" msgstr "Format" #: rd-data.R:43 msgid "Note" msgstr "Not" #: rd-data.R:47 msgid "Author" msgstr "Yazar" #: rd-data.R:51 msgid "See also" msgstr "Ayrıca bak" #: rd-data.R:67 msgid "Arguments" msgstr "Argümanlar" #: rd-data.R:75 msgid "Value" msgstr "Değer" #: render.R:95 msgid "Skip to contents" msgstr "İçeriğe atla" #: render.R:96 msgid "Toggle navigation" msgstr "Gezinmeyi aç/kapat" #: render.R:97 msgid "On this page" msgstr "Bu sayfada" #: render.R:99 msgid "Abstract" msgstr "Özet" #: render.R:100 msgid "Authors" msgstr "Yazarlar" #: render.R:101 msgid "Version" msgstr "Sürüm" #: render.R:102 msgid "Examples" msgstr "Örnekler" #: render.R:104 msgid "Additional details" msgstr "Ek detaylar" #: render.R:106 msgid "Site navigation" msgstr "Site navigasyonu" #: repo.R:35 msgid "Source:" msgstr "Kaynak:" #: tweak-homepage.R:61 msgid "Dev status" msgstr "Geliştirme statüsü" #: usage.R:23 msgid "# Default %s method" msgstr "# Varsayılan %s metodu" #: usage.R:25 msgid "# %s method for class '%s'" msgstr "# %s için %s metodu" �������������pkgdown/po/R-de.po����������������������������������������������������������������������������������0000644�0001762�0000144�00000014366�14634573316�013516� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������msgid "" msgstr "" "Project-Id-Version: pkgdown 1.9000.9000.9000\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-05-24 09:36-0500\n" "PO-Revision-Date: 2021-10-28 08:02-0500\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: build-404.R:11 msgid "Page not found (404)" msgstr "Seite nicht gefunden (404)" #: build-404.R:12 msgid "Content not found. Please use links in the navbar." msgstr "Inhalt nicht gefunden. Bitte die Navigationleiste benutzen." #: build-articles.R:432 navbar.R:186 navbar.R:196 navbar.R:217 msgid "Articles" msgstr "Artikel" #: build-articles.R:570 msgid "All vignettes" msgstr "Alle Artikel" #: build-footer.R:34 msgid "Developed by" msgstr "Entwickelt von" #: build-footer.R:41 msgid "Site built with <a href=\"%s\">pkgdown</a> %s." msgstr "Seite erstellt mit <a href=\"%s\">pkgdown</a> %s." #: build-home-authors.R:12 msgid "Authors and Citation" msgstr "Autor:innen und Zitation" #: build-home-authors.R:101 msgid "More about authors..." msgstr "Mehr zu den Autor:innen" #: build-home-authors.R:104 msgid "Developers" msgstr "Entwicker:innen" #: build-home-authors.R:190 msgid "author" msgstr "Autor:in" #: build-home-authors.R:191 msgid "compiler" msgstr "Zusammensteller:in" #: build-home-authors.R:192 msgid "contractor" msgstr "Auftragnehmer:in" #: build-home-authors.R:193 msgid "contributor" msgstr "Beitragende:r" #: build-home-authors.R:194 msgid "copyright holder" msgstr "Urheberrechtsinhaber:in" #: build-home-authors.R:195 msgid "maintainer" msgstr "Maintainer:in" #: build-home-authors.R:196 msgid "data contributor" msgstr "Datenbeitragende:r" #: build-home-authors.R:197 msgid "funder" msgstr "Sponsor:in" #: build-home-authors.R:198 msgid "reviewer" msgstr "Gutachter:in" #: build-home-authors.R:199 msgid "thesis advisor" msgstr "Betreuer:in der Abschlussarbeit" #: build-home-authors.R:200 msgid "translator" msgstr "Übersetzer:in" #: build-home-authors.R:254 render.R:103 msgid "Citation" msgstr "Zitationsvorschlag" #: build-home-authors.R:255 msgid "Citing %s" msgstr "%s zitieren" #: build-home-community.R:23 msgid "Contributing guide" msgstr "Leitfaden zum Mitwirken" #: build-home-community.R:27 msgid "Code of conduct" msgstr "Verhaltensregeln" #: build-home-community.R:31 msgid "Getting help" msgstr "Hilfe erhalten" #: build-home-community.R:38 msgid "Community" msgstr "Community" #: build-home-index.R:120 msgid "Dev Status" msgstr "Entwicklungsstatus" #: build-home-index.R:162 msgid "View on %s" msgstr "Auf %s ansehen" #: build-home-index.R:163 msgid "Browse source code" msgstr "Quellcode ansehen" #: build-home-index.R:164 msgid "Report a bug" msgstr "Bug melden" #: build-home-index.R:168 msgid "Links" msgstr "Links" #: build-home-index.R:173 render.R:105 msgid "Table of contents" msgstr "Inhaltsverzeichnis" #: build-home-license.R:12 build-home-license.R:34 msgid "License" msgstr "Lizenz" #: build-home-license.R:29 msgid "Full license" msgstr "Vollständige Lizenz" #: build-news.R:102 build-news.R:259 build-news.R:263 msgid "Changelog" msgstr "Änderungsprotokoll" #: build-news.R:129 msgid "Version %s" msgstr "Version %s" #: build-news.R:141 build-news.R:254 msgid "News" msgstr "Neuigkeiten" #: build-news.R:256 msgid "Releases" msgstr "Veröffentlichungen" #: build-news.R:310 msgid "CRAN release: %s" msgstr "CRAN-Veröffentlichung: %s" #: build-reference-index.R:22 msgid "Package index" msgstr "Paketindex" #: build-reference-index.R:158 msgid "All functions" msgstr "Alle Funktionen" #: build-reference.R:371 msgid "Usage" msgstr "Verwendung" #: build-tutorials.R:47 navbar.R:152 msgid "Tutorials" msgstr "Tutorien" #: development.R:72 msgid "Released version" msgstr "Veröffentlichte Version" #: development.R:73 msgid "In-development version" msgstr "Version in Entwicklung" #: development.R:74 msgid "Unreleased version" msgstr "Unveröffentlichte Version" #: navbar-menu.R:173 #, fuzzy #| msgid "Search for" msgid "Search site" msgstr "Suchen nach" #: navbar-menu.R:174 msgid "Search for" msgstr "Suchen nach" #: navbar.R:129 msgid "Reference" msgstr "Verzeichnis" #: navbar.R:140 msgid "Light switch" # Appearance msgstr "Erscheinungsbild" #: navbar.R:143 msgid "Light" msgstr "Hell" #: navbar.R:144 msgid "Dark" msgstr "Dunkel" #: navbar.R:145 msgid "Auto" msgstr "Automatisch" #: navbar.R:180 msgid "Get started" msgstr "Erste Schritte" #: navbar.R:213 msgid "More articles..." msgstr "Mehr Artikel ..." #: package.R:300 msgid "deprecated" msgstr "veraltet" #: package.R:301 msgid "superseded" msgstr "überholt" #: package.R:302 msgid "experimental" msgstr "experimentell" #: package.R:303 msgid "stable" msgstr "stabil" #: rd-data.R:23 msgid "Details" msgstr "Details" #: rd-data.R:27 msgid "Description" msgstr "Beschreibung" #: rd-data.R:31 msgid "References" msgstr "Literaturverzeichnis" #: rd-data.R:35 render.R:98 msgid "Source" msgstr "Quelle" #: rd-data.R:39 msgid "Format" msgstr "Format" #: rd-data.R:43 msgid "Note" msgstr "Notiz" #: rd-data.R:47 msgid "Author" msgstr "Autor:in" #: rd-data.R:51 msgid "See also" msgstr "Siehe auch" #: rd-data.R:67 msgid "Arguments" msgstr "Argumente" #: rd-data.R:75 msgid "Value" msgstr "Rückgabewert" #: render.R:95 msgid "Skip to contents" msgstr "Direkt zum Inhalt springen" #: render.R:96 msgid "Toggle navigation" msgstr "Navigation ein-/ausschalten" #: render.R:97 msgid "On this page" msgstr "Auf dieser Seite" #: render.R:99 msgid "Abstract" msgstr "Kurzzusammenfassung" #: render.R:100 msgid "Authors" msgstr "Autor:innen" #: render.R:101 msgid "Version" msgstr "Version" #: render.R:102 msgid "Examples" msgstr "Beispiele" #: render.R:104 msgid "Additional details" msgstr "" #: render.R:106 #, fuzzy #| msgid "Toggle navigation" msgid "Site navigation" msgstr "Navigation ein-/ausschalten" #: repo.R:35 msgid "Source:" msgstr "Quelle:" #: tweak-homepage.R:61 msgid "Dev status" msgstr "Entwicklungsstatus" #: usage.R:47 msgid "# Default %s method" msgstr "# Standard-%s-Methode" #: usage.R:49 #, fuzzy #| msgid "# %s method for %s" msgid "# %s method for class '%s'" msgstr "# %s-Methode für %s" #~ msgid "Function reference" #~ msgstr "Funktionsverzeichnis" ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/po/R-ko.po����������������������������������������������������������������������������������0000644�0001762�0000144�00000013733�14633374223�013527� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������msgid "" msgstr "" "Project-Id-Version: pkgdown 1.9000.9000.9000\n" "POT-Creation-Date: 2024-05-24 09:36-0500\n" "PO-Revision-Date: 2021-11-26 15:57-0600\n" "Last-Translator: Chanyub Park <mrchypark@gmail.com>\n" "Language-Team: @mrchypark\n" "Language: ko\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: build-404.R:11 msgid "Page not found (404)" msgstr "페이지를 찾을 수 없습니다 (404)" #: build-404.R:12 msgid "Content not found. Please use links in the navbar." msgstr "콘텐츠를 찾을 수 없습니다. 네비게이션 바의 링크를 이용해 주세요." #: build-articles.R:432 navbar.R:186 navbar.R:196 navbar.R:217 msgid "Articles" msgstr "관련 글 목록" #: build-articles.R:570 msgid "All vignettes" msgstr "전체 사용설명서(비네트)" #: build-footer.R:34 msgid "Developed by" msgstr "개발자:" #: build-footer.R:41 msgid "Site built with <a href=\"%s\">pkgdown</a> %s." msgstr "" "현재 사이트는 다음 패키지로 생성하였습니다. - <a href=\"%s\">pkgdown</a> %s" #: build-home-authors.R:12 msgid "Authors and Citation" msgstr "저자와 인용" #: build-home-authors.R:101 msgid "More about authors..." msgstr "저자에 대한 부분은..." #: build-home-authors.R:104 msgid "Developers" msgstr "개발자들" #: build-home-authors.R:190 msgid "author" msgstr "저자" #: build-home-authors.R:191 msgid "compiler" msgstr "편집자" #: build-home-authors.R:192 msgid "contractor" msgstr "계약자" #: build-home-authors.R:193 msgid "contributor" msgstr "기여자" #: build-home-authors.R:194 msgid "copyright holder" msgstr "저작권자" #: build-home-authors.R:195 msgid "maintainer" msgstr "관리자" #: build-home-authors.R:196 msgid "data contributor" msgstr "데이터 기여자" #: build-home-authors.R:197 msgid "funder" msgstr "자금 제공자" #: build-home-authors.R:198 msgid "reviewer" msgstr "리뷰어" #: build-home-authors.R:199 msgid "thesis advisor" msgstr "지도교수" #: build-home-authors.R:200 msgid "translator" msgstr "번역자" #: build-home-authors.R:254 render.R:103 msgid "Citation" msgstr "인용" #: build-home-authors.R:255 msgid "Citing %s" msgstr "%s 인용하기" #: build-home-community.R:23 msgid "Contributing guide" msgstr "기여 가이드" #: build-home-community.R:27 msgid "Code of conduct" msgstr "행동강령" #: build-home-community.R:31 msgid "Getting help" msgstr "" #: build-home-community.R:38 msgid "Community" msgstr "커뮤니티" #: build-home-index.R:120 msgid "Dev Status" msgstr "개발 상태" #: build-home-index.R:162 msgid "View on %s" msgstr "%s에서 보기" #: build-home-index.R:163 msgid "Browse source code" msgstr "소스코드 보기" #: build-home-index.R:164 msgid "Report a bug" msgstr "버그 신고" #: build-home-index.R:168 msgid "Links" msgstr "링크" #: build-home-index.R:173 render.R:105 msgid "Table of contents" msgstr "목차" #: build-home-license.R:12 build-home-license.R:34 msgid "License" msgstr "라이선스" #: build-home-license.R:29 msgid "Full license" msgstr "전체 라이선스" #: build-news.R:102 build-news.R:259 build-news.R:263 msgid "Changelog" msgstr "변경 사항" #: build-news.R:129 msgid "Version %s" msgstr "버전 %s" #: build-news.R:141 build-news.R:254 msgid "News" msgstr "뉴스" #: build-news.R:256 msgid "Releases" msgstr "릴리즈" #: build-news.R:310 msgid "CRAN release: %s" msgstr "CRAN 배포: %s" #: build-reference-index.R:22 msgid "Package index" msgstr "" #: build-reference-index.R:158 msgid "All functions" msgstr "" #: build-reference.R:371 msgid "Usage" msgstr "사용법" #: build-tutorials.R:47 navbar.R:152 msgid "Tutorials" msgstr "튜토리얼" #: development.R:72 msgid "Released version" msgstr "배포 버전" #: development.R:73 msgid "In-development version" msgstr "개발 버전" #: development.R:74 msgid "Unreleased version" msgstr "배포전 버전" #: navbar-menu.R:173 #, fuzzy #| msgid "Search for" msgid "Search site" msgstr "검색" #: navbar-menu.R:174 msgid "Search for" msgstr "검색" #: navbar.R:129 msgid "Reference" msgstr "참조" #: navbar.R:140 msgid "Light switch" msgstr "" #: navbar.R:143 msgid "Light" msgstr "" #: navbar.R:144 msgid "Dark" msgstr "" #: navbar.R:145 msgid "Auto" msgstr "" #: navbar.R:180 msgid "Get started" msgstr "시작하기" #: navbar.R:213 msgid "More articles..." msgstr "더 보기..." #: package.R:300 msgid "deprecated" msgstr "" #: package.R:301 msgid "superseded" msgstr "" #: package.R:302 msgid "experimental" msgstr "" #: package.R:303 msgid "stable" msgstr "" #: rd-data.R:23 msgid "Details" msgstr "세부사항" #: rd-data.R:27 msgid "Description" msgstr "설명" #: rd-data.R:31 msgid "References" msgstr "참조" #: rd-data.R:35 render.R:98 msgid "Source" msgstr "소스코드" #: rd-data.R:39 msgid "Format" msgstr "양식" #: rd-data.R:43 msgid "Note" msgstr "노트" #: rd-data.R:47 msgid "Author" msgstr "저자" #: rd-data.R:51 msgid "See also" msgstr "더 보기" #: rd-data.R:67 msgid "Arguments" msgstr "인수" #: rd-data.R:75 msgid "Value" msgstr "값" #: render.R:95 msgid "Skip to contents" msgstr "콘텐츠로 바로가기" #: render.R:96 msgid "Toggle navigation" msgstr "네비게이션바 열기" #: render.R:97 msgid "On this page" msgstr "목차" #: render.R:99 msgid "Abstract" msgstr "초록" #: render.R:100 msgid "Authors" msgstr "저자들" #: render.R:101 msgid "Version" msgstr "버전" #: render.R:102 msgid "Examples" msgstr "예시 코드" #: render.R:104 msgid "Additional details" msgstr "" #: render.R:106 #, fuzzy #| msgid "Toggle navigation" msgid "Site navigation" msgstr "네비게이션바 열기" #: repo.R:35 msgid "Source:" msgstr "소스코드:" #: tweak-homepage.R:61 msgid "Dev status" msgstr "개발 상태" #: usage.R:23 msgid "# Default %s method" msgstr "" #: usage.R:25 #, fuzzy #| msgid "# %s method for %s" msgid "# %s method for class '%s'" msgstr "# %s 타입인 %s의 메서드" #~ msgid "Function reference" #~ msgstr "함수 레퍼런스" �������������������������������������pkgdown/po/R-zh_CN.po�������������������������������������������������������������������������������0000644�0001762�0000144�00000013340�14633374223�014111� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������msgid "" msgstr "" "Project-Id-Version: pkgdown 1.9000.9000.9000\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-05-24 09:36-0500\n" "PO-Revision-Date: 2021-10-28 08:02-0500\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: build-404.R:11 msgid "Page not found (404)" msgstr "页面未找到(404)" #: build-404.R:12 msgid "Content not found. Please use links in the navbar." msgstr "请求的页面未找到。请使用导航栏内的链接。" #: build-articles.R:432 navbar.R:186 navbar.R:196 navbar.R:217 msgid "Articles" msgstr "文章" #: build-articles.R:570 msgid "All vignettes" msgstr "" #: build-footer.R:34 msgid "Developed by" msgstr "开发者:" #: build-footer.R:41 msgid "Site built with <a href=\"%s\">pkgdown</a> %s." msgstr "该网站由 <a href=\"%s\">pkgdown</a> %s 构建。" #: build-home-authors.R:12 msgid "Authors and Citation" msgstr "" #: build-home-authors.R:101 msgid "More about authors..." msgstr "关于作者…" #: build-home-authors.R:104 msgid "Developers" msgstr "开发者" #: build-home-authors.R:190 msgid "author" msgstr "作者" #: build-home-authors.R:191 msgid "compiler" msgstr "编译者" #: build-home-authors.R:192 msgid "contractor" msgstr "合同员工" #: build-home-authors.R:193 msgid "contributor" msgstr "合作者" #: build-home-authors.R:194 msgid "copyright holder" msgstr "版权所有者" #: build-home-authors.R:195 msgid "maintainer" msgstr "维护者" #: build-home-authors.R:196 msgid "data contributor" msgstr "数据提供者" #: build-home-authors.R:197 msgid "funder" msgstr "赞助者" #: build-home-authors.R:198 msgid "reviewer" msgstr "审核者" #: build-home-authors.R:199 msgid "thesis advisor" msgstr "论文导师" #: build-home-authors.R:200 msgid "translator" msgstr "翻译者" #: build-home-authors.R:254 render.R:103 msgid "Citation" msgstr "" #: build-home-authors.R:255 msgid "Citing %s" msgstr "引用 %s" #: build-home-community.R:23 msgid "Contributing guide" msgstr "开发指南" #: build-home-community.R:27 msgid "Code of conduct" msgstr "行为准则" #: build-home-community.R:31 msgid "Getting help" msgstr "" #: build-home-community.R:38 msgid "Community" msgstr "社区" #: build-home-index.R:120 msgid "Dev Status" msgstr "开发状态" #: build-home-index.R:162 msgid "View on %s" msgstr "访问%s" #: build-home-index.R:163 msgid "Browse source code" msgstr "浏览源代码" #: build-home-index.R:164 msgid "Report a bug" msgstr "缺陷报告" #: build-home-index.R:168 msgid "Links" msgstr "链接" #: build-home-index.R:173 render.R:105 msgid "Table of contents" msgstr "目录" #: build-home-license.R:12 build-home-license.R:34 msgid "License" msgstr "许可" #: build-home-license.R:29 msgid "Full license" msgstr "许可全部条款" #: build-news.R:102 build-news.R:259 build-news.R:263 msgid "Changelog" msgstr "更改日志" #: build-news.R:129 msgid "Version %s" msgstr "%s 版" #: build-news.R:141 build-news.R:254 msgid "News" msgstr "新闻" #: build-news.R:256 msgid "Releases" msgstr "发布版本" #: build-news.R:310 msgid "CRAN release: %s" msgstr "CRAN发布版本:%s" #: build-reference-index.R:22 msgid "Package index" msgstr "" #: build-reference-index.R:158 msgid "All functions" msgstr "" #: build-reference.R:371 msgid "Usage" msgstr "" #: build-tutorials.R:47 navbar.R:152 msgid "Tutorials" msgstr "教程" #: development.R:72 msgid "Released version" msgstr "已发布的版本" #: development.R:73 msgid "In-development version" msgstr "开发中的版本" #: development.R:74 msgid "Unreleased version" msgstr "未发布的版本" #: navbar-menu.R:173 #, fuzzy #| msgid "Search for" msgid "Search site" msgstr "搜索" #: navbar-menu.R:174 msgid "Search for" msgstr "搜索" #: navbar.R:129 msgid "Reference" msgstr "参考" #: navbar.R:140 msgid "Light switch" msgstr "" #: navbar.R:143 msgid "Light" msgstr "" #: navbar.R:144 msgid "Dark" msgstr "" #: navbar.R:145 msgid "Auto" msgstr "" #: navbar.R:180 msgid "Get started" msgstr "入门简介" #: navbar.R:213 msgid "More articles..." msgstr "更多文章…" #: package.R:300 msgid "deprecated" msgstr "" #: package.R:301 msgid "superseded" msgstr "" #: package.R:302 msgid "experimental" msgstr "" #: package.R:303 msgid "stable" msgstr "" #: rd-data.R:23 msgid "Details" msgstr "细节" #: rd-data.R:27 msgid "Description" msgstr "概述" #: rd-data.R:31 msgid "References" msgstr "参考文献" #: rd-data.R:35 render.R:98 msgid "Source" msgstr "参考文献出处" #: rd-data.R:39 msgid "Format" msgstr "格式" #: rd-data.R:43 msgid "Note" msgstr "注释" #: rd-data.R:47 msgid "Author" msgstr "作者" #: rd-data.R:51 msgid "See also" msgstr "相关话题" #: rd-data.R:67 msgid "Arguments" msgstr "参数" #: rd-data.R:75 msgid "Value" msgstr "值" #: render.R:95 msgid "Skip to contents" msgstr "跳到正文" #: render.R:96 msgid "Toggle navigation" msgstr "切换导航栏" #: render.R:97 msgid "On this page" msgstr "该页面" #: render.R:99 msgid "Abstract" msgstr "摘要" #: render.R:100 msgid "Authors" msgstr "作者" #: render.R:101 msgid "Version" msgstr "版本" #: render.R:102 msgid "Examples" msgstr "范例" #: render.R:104 msgid "Additional details" msgstr "" #: render.R:106 #, fuzzy #| msgid "Toggle navigation" msgid "Site navigation" msgstr "切换导航栏" #: repo.R:35 msgid "Source:" msgstr "来源:" #: tweak-homepage.R:61 msgid "Dev status" msgstr "开发状态" #: usage.R:23 msgid "# Default %s method" msgstr "" #: usage.R:25 #, fuzzy #| msgid "# %s method for %s" msgid "# %s method for class '%s'" msgstr "# %2$s类的%1$s函数" #~ msgid "Function reference" #~ msgstr "函数参考" ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/������������������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14672347601�012136� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/build-redirects.R�������������������������������������������������������������������������0000644�0001762�0000144�00000007361�14634573316�015353� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' Build redirects #' #' @description #' If you change the structure of your documentation (by renaming vignettes or #' help topics) you can setup redirects from the old content to the new content. #' One or several now-absent pages can be redirected to a new page (or to a new #' section of a new page). This works by creating a html page that performs a #' "meta refresh", which isn't the best way of doing a redirect but works #' everywhere that you might deploy your site. #' #' The syntax is the following, with old paths on the left, and new paths or #' URLs on the right. #' #' ```yaml #' redirects: #' - ["articles/old-vignette-name.html", "articles/new-vignette-name.html"] #' - ["articles/another-old-vignette-name.html", "articles/new-vignette-name.html"] #' - ["articles/yet-another-old-vignette-name.html", "https://pkgdown.r-lib.org/dev"] #' ``` #' #' If for some reason you choose to redirect an existing page make sure to #' exclude it from the search index, see `?build_search`. #' #' @inheritParams as_pkgdown #' @export build_redirects <- function(pkg = ".", override = list()) { pkg <- section_init(pkg, override = override) has_url <- !is.null(config_pluck_string(pkg, "url")) redirects <- data_redirects(pkg, has_url) if (length(redirects) == 0) { return(invisible()) } cli::cli_rule("Building redirects") if (!has_url) { config_abort(pkg, "{.field url} is required to generate redirects.") } # Ensure user redirects override automatic ones from <- purrr::map_chr(redirects, 1) redirects <- redirects[!duplicated(from)] purrr::iwalk(redirects, build_redirect, pkg = pkg) } build_redirect <- function(entry, index, pkg) { new <- entry[2] old <- path(pkg$dst_path, entry[1]) path <- find_template("layout", "redirect", pkg = pkg) template <- read_file(path) url <- sprintf("%s/%s%s", config_pluck_string(pkg, "url"), pkg$prefix, new) lines <- whisker::whisker.render(template, list(url = url)) dir_create(path_dir(old)) if (!file_exists(old)) { cli::cli_inform("Adding redirect from {entry[1]} to {entry[2]}.") } write_lines(lines, old) } data_redirects <- function(pkg, has_url = FALSE, call = caller_env()) { c( if (has_url) reference_redirects(pkg), if (has_url) article_redirects(pkg), config_pluck_redirects(pkg, call = call) ) } reference_redirects <- function(pkg) { aliases <- unname(pkg$topics$alias) aliases <- purrr::map2(aliases, pkg$topics$name, setdiff) names(aliases) <- pkg$topics$file_out redirects <- invert_index(aliases) if (length(redirects) == 0) { return(list()) } names(redirects) <- paste0(names(redirects), ".html") # Ensure we don't create an invalid file name redirects <- redirects[valid_filename(names(redirects))] # Ensure we don't override an existing file redirects <- redirects[setdiff(names(redirects), pkg$topics$file_out)] unname(purrr::imap(redirects, function(to, from) paste0("reference/", c(from, to)))) } valid_filename <- function(x) { x == path_sanitize(x) } article_redirects <- function(pkg) { is_vig_in_articles <- path_has_parent(pkg$vignettes$name, "articles") if (!any(is_vig_in_articles)) { return(NULL) } articles <- pkg$vignettes$file_out[is_vig_in_articles] purrr::map(articles, ~ paste0(c("articles/", ""), .x)) } config_pluck_redirects <- function(pkg, call = caller_env()) { redirects <- config_pluck_list(pkg, "redirects", call = call) for (i in seq_along(redirects)) { redirect <- redirects[[i]] if (!is.character(redirect) || length(redirect) != 2) { not <- obj_type_friendly(redirect) config_abort( pkg, "{.field redirects[{i}]} must be a character vector of length 2, not {not}.", call = call ) } } redirects } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/rd.R��������������������������������������������������������������������������������������0000644�0001762�0000144�00000002663�14671042466�012675� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������rd_text <- function(x, fragment = TRUE) { con <- textConnection(x) on.exit(close(con), add = TRUE) set_classes(tools::parse_Rd(con, fragment = fragment, encoding = "UTF-8")) } rd_file <- function(path, pkg_path = NULL) { set_classes(tools::parse_Rd(path, encoding = "UTF-8")) } #' Translate an Rd string to its HTML output #' #' @param x Rd string. Backslashes must be double-escaped ("\\\\"). #' @param fragment logical indicating whether this represents a complete Rd file #' @param ... additional arguments for as_html #' #' @examples #' rd2html("a\n%b\nc") #' #' rd2html("a & b") #' #' rd2html("\\strong{\\emph{x}}") #' #' @export rd2html <- function(x, fragment = TRUE, ...) { html <- as_html(rd_text(x, fragment = fragment), ...) str_trim(strsplit(str_trim(html), "\n")[[1]]) } print.Rd <- function(x, ...) { utils::str(x) } #' @export print.tag <- function(x, ...) { utils::str(x) } # Convert RD attributes to S3 classes ------------------------------------- set_classes <- function(rd) { if (is.list(rd)) { rd[] <- lapply(rd, set_classes) } set_class(rd) } set_class <- function(x) { structure(x, class = c(attr(x, "class"), tag(x), "tag"), Rd_tag = NULL, srcref = NULL, macros = NULL ) } tag <- function(x) { tag <- attr(x, "Rd_tag") if (is.null(tag)) return() gsub("\\", "tag_", tag, fixed = TRUE) } #' @export `[.tag` <- function(x, ...) { structure(NextMethod(), class = class(x)) } �����������������������������������������������������������������������������pkgdown/R/build-quarto-articles.R�������������������������������������������������������������������0000644�0001762�0000144�00000011465�14641250500�016467� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������build_quarto_articles <- function(pkg = ".", article = NULL, quiet = TRUE) { pkg <- as_pkgdown(pkg) qmds <- pkg$vignettes[pkg$vignettes$type == "qmd", ] if (!is.null(article)) { qmds <- qmds[qmds$name == article, ] } if (nrow(qmds) == 0) { return() } check_installed("quarto") if (quarto::quarto_version() < "1.5") { cli::cli_abort("Quarto articles require version 1.5 and above.", call = NULL) } # Let user know what's happening old_digest <- purrr::map_chr(path(pkg$dst_path, qmds$file_out), file_digest) for (file in qmds$file_in) { cli::cli_inform("Reading {src_path(file)}") } cli::cli_inform("Running {.code quarto render}") # If needed, temporarily make a quarto project so we can build entire dir if (is.null(article)) { project_path <- path(pkg$src_path, "vignettes", "_quarto.yaml") if (!file_exists(project_path)) { yaml::write_yaml(list(project = list(render = list("*.qmd"))), project_path) withr::defer(file_delete(project_path)) } } if (is.null(article)) { src_path <- path(pkg$src_path, "vignettes") } else { src_path <- path(pkg$src_path, qmds$file_in) } output_dir <- quarto_render(pkg, src_path, quiet = quiet) # Read generated data from quarto template and render into pkgdown template unwrap_purrr_error(purrr::walk2(qmds$file_in, qmds$file_out, function(input_file, output_file) { built_path <- path(output_dir, path_rel(output_file, "articles")) if (!file_exists(built_path)) { cli::cli_abort("No built file found for {.file {input_file}}") } if (path_ext(output_file) == "html") { data <- data_quarto_article(pkg, built_path, input_file) render_page(pkg, "quarto", data, output_file, quiet = TRUE) update_html(path(pkg$dst_path, output_file), tweak_quarto_html) } else { file_copy(built_path, path(pkg$dst_path, output_file), overwrite = TRUE) } })) # Report on which files have changed new_digest <- purrr::map_chr(path(pkg$dst_path, qmds$file_out), file_digest) changed <- new_digest != old_digest for (file in qmds$file_out[changed]) { writing_file(path(pkg$dst_path, file), file) } # Copy resources resources <- setdiff( dir_ls(output_dir, recurse = TRUE, type = "file"), path(output_dir, path_rel(qmds$file_out, "articles")) ) file_copy_to( src_paths = resources, dst_paths = path(pkg$dst_path, "articles", path_rel(resources, output_dir)), src_root = output_dir, dst_root = pkg$dst_path, src_label = NULL ) invisible() } quarto_render <- function(pkg, path, quiet = TRUE, frame = caller_env()) { # Override default quarto format metadata_path <- withr::local_tempfile( fileext = ".yml", pattern = "pkgdown-quarto-metadata-", ) write_yaml(quarto_format(pkg), metadata_path) output_dir <- withr::local_tempdir("pkgdown-quarto-", .local_envir = frame) quarto::quarto_render( path, metadata_file = metadata_path, execute_dir = output_dir, quarto_args = c("--output-dir", output_dir), quiet = quiet, as_job = FALSE ) output_dir } quarto_format <- function(pkg) { list( lang = pkg$lang, format = list( html = list( template = system_file("quarto", "template.html", package = "pkgdown"), minimal = TRUE, theme = "none", `html-math-method` = config_math_rendering(pkg), `embed-resources` = FALSE, `citations-hover` = TRUE, `link-citations` = TRUE, `section-divs` = TRUE, toc = FALSE # pkgdown generates with js ) ) ) } data_quarto_article <- function(pkg, path, input_path) { html <- xml2::read_html(path, encoding = "UTF-8") meta_div <- xml2::xml_find_first(html, "//body/div[@class='meta']") # Manually drop any jquery deps head <- xpath_xml(html, "//head/script|//head/link") head <- head[!grepl("jquery", xml2::xml_attr(head, "src"))] list( pagetitle = escape_html(xpath_text(html, "//head/title")), toc = TRUE, source = repo_source(pkg, input_path), includes = list( head = xml2str(head), before = xpath_contents(html, "//body/div[@class='includes-before']"), after = xpath_contents(html, "//body/div[@class='includes-after']"), style = xpath_text(html, "//head/style") ), meta = list( title = xpath_contents(meta_div, "./h1"), subtitle = xpath_contents(meta_div, "./p[@class='subtitle']"), author = xpath_contents(meta_div, "./p[@class='author']"), date = xpath_contents(meta_div, "./p[@class='date']"), abstract = xpath_contents(meta_div, "./div[@class='abstract']") ), body = xpath_contents(html, "//main") ) } tweak_quarto_html <- function(html) { # If top-level headings use h1, move everything down one level h1 <- xml2::xml_find_all(html, "//h1") if (length(h1) > 1) { tweak_section_levels(html) } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/render.R����������������������������������������������������������������������������������0000644�0001762�0000144�00000020337�14641277402�013542� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' Render page with template #' #' Each page is composed of four templates: "head", "header", "content", and #' "footer". Each of these templates is rendered using the `data`, and #' then assembled into an overall page using the "layout" template. #' #' @param pkg Path to package to document. #' @param name Name of the template (e.g. "home", "vignette", "news") #' @param data Data for the template. #' #' This is automatically supplemented with three lists: #' #' * `site`: `title` and path to `root`. #' * `yaml`: the `template` key from `_pkgdown.yml`. #' * `package`: package metadata including `name` and`version`. #' #' See the full contents by running [data_template()]. #' @param path Location to create file; relative to destination directory. #' @param depth Depth of path relative to base directory. #' @param quiet If `quiet`, will suppress output messages #' @export render_page <- function(pkg = ".", name, data, path, depth = NULL, quiet = FALSE) { pkg <- as_pkgdown(pkg) if (is.null(depth)) { depth <- dir_depth(path) } html <- render_page_html(pkg, name = name, data = data, depth = depth) tweak_page(html, name, pkg = pkg) activate_navbar(html, data$output_file %||% path, pkg) rendered <- as.character(html, options = character()) write_if_different(pkg, rendered, path, quiet = quiet) } render_page_html <- function(pkg, name, data = list(), depth = 0L) { data <- modify_list(data_template(pkg, depth = depth), data) # render template components pieces <- c( "head", "in-header", "before-body", "navbar", "content", "footer", "after-body", if (pkg$bs_version == 3) c("header", "docsearch") ) templates <- purrr::map_chr(pieces, find_template, name = name, pkg = pkg) components <- purrr::map(templates, render_template, data = data) components <- purrr::set_names(components, pieces) components$template <- name components$lang <- pkg$lang components$translate <- data$translate # render complete layout template <- find_template("layout", name, pkg = pkg) rendered <- render_template(template, components) # Strip trailing whitespace rendered <- gsub(" +\n", "\n", rendered, perl = TRUE) xml2::read_html(rendered, encoding = "UTF-8") } #' @export #' @rdname render_page data_template <- function(pkg = ".", depth = 0L) { pkg <- as_pkgdown(pkg) out <- list() # Basic metadata out$package <- list( name = pkg$package, version = as.character(pkg$version) ) if (has_logo(pkg)) { out$logo <- list(src = logo_path(pkg, depth = depth)) } out$site <- list( root = up_path(depth), title = config_pluck_string(pkg, "title", default = pkg$package) ) out$year <- strftime(Sys.time(), "%Y") # Language and translations out$lang <- pkg$lang out$translate <- list( skip = tr_("Skip to contents"), toggle_nav = tr_("Toggle navigation"), on_this_page = tr_("On this page"), source = tr_("Source"), abstract = tr_("Abstract"), authors = tr_("Authors"), version = tr_("Version"), examples = tr_("Examples"), citation = tr_("Citation"), author_details = tr_("Additional details"), toc = tr_("Table of contents"), site_nav = tr_("Site navigation") ) # Components that mostly end up in the <head> out$has_favicons <- has_favicons(pkg) out$opengraph <- data_open_graph(pkg) out$extra <- list( css = path_first_existing(pkg$src_path, "pkgdown", "extra.css"), js = path_first_existing(pkg$src_path, "pkgdown", "extra.js") ) out$includes <- config_pluck(pkg, "template.includes") out$yaml <- config_pluck(pkg, "template.params") # Force inclusion so you can reliably refer to objects inside yaml # in the mustache templates out$yaml$.present <- TRUE if (pkg$bs_version > 3) { out$headdeps <- data_deps(pkg = pkg, depth = depth) } # Development settings; tooltip needs to be generated at render time out$development <- pkg$development out$development$version_tooltip <- version_tooltip(pkg$development$mode) out$navbar <- data_navbar(pkg, depth = depth) out$footer <- data_footer(pkg) out$lightswitch <- uses_lightswitch(pkg) out$uses_katex <- config_math_rendering(pkg) == "katex" print_yaml(out) } data_open_graph <- function(pkg = ".", call = caller_env()) { pkg <- as_pkgdown(pkg) og <- config_pluck_list(pkg, "template.opengraph", default = list()) og <- check_open_graph(pkg, og, call = call) logo <- find_logo(pkg$src_path) if (is.null(og$image) && !is.null(logo)) { og$image <- list(src = path_file(logo)) } if (!is.null(og$image) && !grepl("^http", og$image$src)) { site_url <- config_pluck(pkg, "url", default = "/") if (!grepl("/$", site_url)) { site_url <- paste0(site_url, "/") } og$image$src <- gsub("^man/figures/", "reference/figures/", og$image$src) og$image$src <- paste0(site_url, og$image$src) } if (!is.null(og$twitter)) { og$twitter$card <- og$twitter$card %||% "summary" og$twitter$creator <- og$twitter$creator %||% og$twitter$site og$twitter$site <- og$twitter$site %||% og$twitter$creator } og } check_open_graph <- function(pkg, og, file_path = NULL, call = caller_env()) { if (is.null(og)) { return() } is_yaml <- is.null(file_path) base_path <- if (is_yaml) "template.opengraph" else "opengraph" check_open_graph_list( pkg, og, file_path = file_path, error_path = base_path, error_call = call ) supported_fields <- c("image", "twitter") unsupported_fields <- setdiff(names(og), supported_fields) if (length(unsupported_fields)) { msg <- "{.field {base_path}} contains unsupported fields {.val {unsupported_fields}}." config_warn(pkg, msg, path = file_path, call = call) } check_open_graph_list( pkg, og$twitter, file_path = file_path, error_path = paste0(base_path, ".twitter"), error_call = call ) if (!is.null(og$twitter) && is.null(og$twitter$creator) && is.null(og$twitter$site)) { msg <- "{.field opengraph.twitter} must include either {.field creator} or {.field site}." config_abort(pkg, msg, path = file_path, call = call) } check_open_graph_list( pkg, og$image, file_path = file_path, error_path = paste0(base_path, ".image"), error_call = call ) og[intersect(supported_fields, names(og))] } render_template <- function(path, data) { template <- read_file(path) if (length(template) == 0) return("") whisker::whisker.render(template, data) } check_open_graph_list <- function(pkg, x, file_path, error_path, error_call = caller_env()) { if (is.list(x) || is.null(x)) { return() } not <- obj_type_friendly(x) config_abort( pkg, "{.field {error_path}} must be a list, not {not}.", path = file_path, call = error_call ) } write_if_different <- function(pkg, contents, path, quiet = FALSE, check = TRUE) { # Almost all uses are relative to destination, except for rmarkdown templates full_path <- path_abs(path, start = pkg$dst_path) if (check && !made_by_pkgdown(full_path)) { cli::cli_inform("Skipping {.file {path}}: not generated by pkgdown") return(FALSE) } if (same_contents(full_path, contents)) { # touching the file to update its modification time # which is important for proper lazy behavior file_touch(full_path) return(FALSE) } if (!quiet) { writing_file(path_rel(full_path, pkg$dst_path), path) } write_lines(contents, path = full_path) TRUE } same_contents <- function(path, contents) { if (!file_exists(path)) return(FALSE) new_hash <- digest::digest(contents, serialize = FALSE) cur_contents <- paste0(read_lines(path), collapse = "\n") cur_hash <- digest::digest(cur_contents, serialize = FALSE) identical(new_hash, cur_hash) } file_digest <- function(path) { if (file_exists(path)) { digest::digest(file = path, algo = "xxhash64") } else { "MISSING" } } made_by_pkgdown <- function(path) { if (!file_exists(path)) return(TRUE) first <- paste(read_lines(path, n = 2), collapse = "\n") check_made_by(first) } check_made_by <- function(first) { if (length(first) == 0L) return(FALSE) grepl("<!-- Generated by pkgdown", first, fixed = TRUE) } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/context.R���������������������������������������������������������������������������������0000644�0001762�0000144�00000005221�14634573316�013747� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������section_init <- function(pkg, subdir = NULL, override = list(), .frame = parent.frame()) { rstudio_save_all() pkg <- as_pkgdown(pkg, override = override) if (length(dest_files(pkg)) > 0) { check_dest_is_pkgdown(pkg) } else { init_site(pkg) } if (is.null(subdir)) { depth <- 0 } else { depth <- 1 dir_create(path(pkg$dst_path, subdir)) } local_envvar_pkgdown(pkg, .frame) local_options_link(pkg, depth = depth, .frame = .frame) cache_cli_colours(.frame = .frame) pkg } cache_cli_colours <- function(.frame = parent.frame()) { # https://github.com/r-lib/cli/issues/607 num_col <- getOption("cli.num_colors", default = cli::num_ansi_colors()) withr::local_options(cli.num_colors = num_col, .local_envir = .frame) } local_options_link <- function(pkg, depth, .frame = parent.frame()) { article_index <- article_index(pkg) Rdname <- get_rdname(pkg$topics) topic_index <- unlist(invert_index(set_names(pkg$topics$alias, Rdname))) withr::local_options( list( downlit.package = pkg$package, downlit.article_index = article_index, downlit.topic_index = topic_index, downlit.article_path = paste0(up_path(depth), "articles/"), downlit.topic_path = paste0(up_path(depth), "reference/") ), .local_envir = .frame ) } local_context_eval <- function( figures = NULL, src_path = getwd(), sexpr_env = child_env(globalenv()), .frame = parent.frame()) { context_set_scoped("figures", figures, scope = .frame) context_set_scoped("src_path", src_path, scope = .frame) context_set_scoped("sexpr_env", sexpr_env, scope = .frame) } # Manage current topic index ---------------------------------------------------- context <- new_environment() context$packages <- character() context_set <- function(name, value) { old <- if (env_has(context, name)) env_get(context, name) if (is.null(value)) { if (env_has(context, name)) { env_unbind(context, name) } } else { env_bind(context, !!name := value) } invisible(old) } context_get <- function(name) { if (env_has(context, name)) { env_get(context, name) } else { cli::cli_abort("Context {.str name} has not been initialised") } } context_set_scoped <- function(name, value, scope = parent.frame()) { old <- context_set(name, value) withr::defer(context_set(name, old), envir = scope) } article_index <- function(pkg) { set_names( path_rel(pkg$vignettes$file_out, "articles"), pkg$vignettes$name ) } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/highlight.R�������������������������������������������������������������������������������0000644�0001762�0000144�00000004105�14642014746�014226� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# highligh_text() and highlight_examples() are only used for usage # and examples, and are specifically excluded in tweak_reference_highlighting() highlight_text <- function(text) { out <- downlit::highlight(text, classes = downlit::classes_pandoc()) if (!is.na(out)) { sourceCode(pre(out, r_code = TRUE)) } else { sourceCode(pre(escape_html(text))) } } highlight_examples <- function(code, topic, env = globalenv()) { bg <- fig_settings()$bg %||% NA # some options from testthat::local_reproducible_output() # https://github.com/r-lib/testthat/blob/47935141d430e002070a95dd8af6dbf70def0994/R/local.R#L86 withr::local_options(list( device = function(...) ragg::agg_png(..., bg = bg), rlang_interactive = FALSE, cli.num_colors = 256, cli.dynamic = FALSE )) withr::local_envvar(RSTUDIO = NA) withr::local_collate("C") fig_save_topic <- function(plot, id) { name <- paste0(topic, "-", id) do.call(fig_save, c(list(plot, name), fig_settings())) } hide_dontshow <- function(src, expr) { if (is.expression(expr)) { # evaluate 1.0.0 if (length(expr) > 0) { hide <- is_call(expr[[1]], c("DONTSHOW", "TESTONLY")) } else { hide <- FALSE } } else if (is.call(expr)) { # evaluate 0.24.0 hide <- is_call(expr, c("DONTSHOW", "TESTONLY")) } else { hide <- FALSE } if (hide) NULL else src } handler <- evaluate::new_output_handler( value = pkgdown_print, source = hide_dontshow ) eval_env <- child_env(env) eval_env$DONTSHOW <- function(x) invisible(x) eval_env$TESTONLY <- function(x) invisible() out <- downlit::evaluate_and_highlight( code, fig_save = fig_save_topic, env = eval_env, output_handler = handler ) structure( sourceCode(pre(out, r_code = TRUE)), dependencies = attr(out, "dependencies") ) } pre <- function(x, r_code = FALSE) { paste0( "<pre", if (r_code) " class='sourceCode r'", ">", "<code>", x, "</code>","</pre>" ) } sourceCode <- function(x) { paste0("<div class='sourceCode'>", x, "</div>") } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/import-standalone-types-check.R�����������������������������������������������������������0000644�0001762�0000144�00000027616�14633374223�020147� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Standalone file: do not edit by hand # Source: <https://github.com/r-lib/rlang/blob/main/R/standalone-types-check.R> # ---------------------------------------------------------------------- # # --- # repo: r-lib/rlang # file: standalone-types-check.R # last-updated: 2023-03-13 # license: https://unlicense.org # dependencies: standalone-obj-type.R # imports: rlang (>= 1.1.0) # --- # # ## Changelog # # 2023-03-13: # - Improved error messages of number checkers (@teunbrand) # - Added `allow_infinite` argument to `check_number_whole()` (@mgirlich). # - Added `check_data_frame()` (@mgirlich). # # 2023-03-07: # - Added dependency on rlang (>= 1.1.0). # # 2023-02-15: # - Added `check_logical()`. # # - `check_bool()`, `check_number_whole()`, and # `check_number_decimal()` are now implemented in C. # # - For efficiency, `check_number_whole()` and # `check_number_decimal()` now take a `NULL` default for `min` and # `max`. This makes it possible to bypass unnecessary type-checking # and comparisons in the default case of no bounds checks. # # 2022-10-07: # - `check_number_whole()` and `_decimal()` no longer treat # non-numeric types such as factors or dates as numbers. Numeric # types are detected with `is.numeric()`. # # 2022-10-04: # - Added `check_name()` that forbids the empty string. # `check_string()` allows the empty string by default. # # 2022-09-28: # - Removed `what` arguments. # - Added `allow_na` and `allow_null` arguments. # - Added `allow_decimal` and `allow_infinite` arguments. # - Improved errors with absent arguments. # # # 2022-09-16: # - Unprefixed usage of rlang functions with `rlang::` to # avoid onLoad issues when called from rlang (#1482). # # 2022-08-11: # - Added changelog. # # nocov start # Scalars ----------------------------------------------------------------- .standalone_types_check_dot_call <- .Call check_bool <- function(x, ..., allow_na = FALSE, allow_null = FALSE, arg = caller_arg(x), call = caller_env()) { if (!missing(x) && .standalone_types_check_dot_call(ffi_standalone_is_bool_1.0.7, x, allow_na, allow_null)) { return(invisible(NULL)) } stop_input_type( x, c("`TRUE`", "`FALSE`"), ..., allow_na = allow_na, allow_null = allow_null, arg = arg, call = call ) } check_string <- function(x, ..., allow_empty = TRUE, allow_na = FALSE, allow_null = FALSE, arg = caller_arg(x), call = caller_env()) { if (!missing(x)) { is_string <- .rlang_check_is_string( x, allow_empty = allow_empty, allow_na = allow_na, allow_null = allow_null ) if (is_string) { return(invisible(NULL)) } } stop_input_type( x, "a single string", ..., allow_na = allow_na, allow_null = allow_null, arg = arg, call = call ) } .rlang_check_is_string <- function(x, allow_empty, allow_na, allow_null) { if (is_string(x)) { if (allow_empty || !is_string(x, "")) { return(TRUE) } } if (allow_null && is_null(x)) { return(TRUE) } if (allow_na && (identical(x, NA) || identical(x, na_chr))) { return(TRUE) } FALSE } check_name <- function(x, ..., allow_null = FALSE, arg = caller_arg(x), call = caller_env()) { if (!missing(x)) { is_string <- .rlang_check_is_string( x, allow_empty = FALSE, allow_na = FALSE, allow_null = allow_null ) if (is_string) { return(invisible(NULL)) } } stop_input_type( x, "a valid name", ..., allow_na = FALSE, allow_null = allow_null, arg = arg, call = call ) } IS_NUMBER_true <- 0 IS_NUMBER_false <- 1 IS_NUMBER_oob <- 2 check_number_decimal <- function(x, ..., min = NULL, max = NULL, allow_infinite = TRUE, allow_na = FALSE, allow_null = FALSE, arg = caller_arg(x), call = caller_env()) { if (missing(x)) { exit_code <- IS_NUMBER_false } else if (0 == (exit_code <- .standalone_types_check_dot_call( ffi_standalone_check_number_1.0.7, x, allow_decimal = TRUE, min, max, allow_infinite, allow_na, allow_null ))) { return(invisible(NULL)) } .stop_not_number( x, ..., exit_code = exit_code, allow_decimal = TRUE, min = min, max = max, allow_na = allow_na, allow_null = allow_null, arg = arg, call = call ) } check_number_whole <- function(x, ..., min = NULL, max = NULL, allow_infinite = FALSE, allow_na = FALSE, allow_null = FALSE, arg = caller_arg(x), call = caller_env()) { if (missing(x)) { exit_code <- IS_NUMBER_false } else if (0 == (exit_code <- .standalone_types_check_dot_call( ffi_standalone_check_number_1.0.7, x, allow_decimal = FALSE, min, max, allow_infinite, allow_na, allow_null ))) { return(invisible(NULL)) } .stop_not_number( x, ..., exit_code = exit_code, allow_decimal = FALSE, min = min, max = max, allow_na = allow_na, allow_null = allow_null, arg = arg, call = call ) } .stop_not_number <- function(x, ..., exit_code, allow_decimal, min, max, allow_na, allow_null, arg, call) { if (allow_decimal) { what <- "a number" } else { what <- "a whole number" } if (exit_code == IS_NUMBER_oob) { min <- min %||% -Inf max <- max %||% Inf if (min > -Inf && max < Inf) { what <- sprintf("%s between %s and %s", what, min, max) } else if (x < min) { what <- sprintf("%s larger than or equal to %s", what, min) } else if (x > max) { what <- sprintf("%s smaller than or equal to %s", what, max) } else { abort("Unexpected state in OOB check", .internal = TRUE) } } stop_input_type( x, what, ..., allow_na = allow_na, allow_null = allow_null, arg = arg, call = call ) } check_symbol <- function(x, ..., allow_null = FALSE, arg = caller_arg(x), call = caller_env()) { if (!missing(x)) { if (is_symbol(x)) { return(invisible(NULL)) } if (allow_null && is_null(x)) { return(invisible(NULL)) } } stop_input_type( x, "a symbol", ..., allow_na = FALSE, allow_null = allow_null, arg = arg, call = call ) } check_arg <- function(x, ..., allow_null = FALSE, arg = caller_arg(x), call = caller_env()) { if (!missing(x)) { if (is_symbol(x)) { return(invisible(NULL)) } if (allow_null && is_null(x)) { return(invisible(NULL)) } } stop_input_type( x, "an argument name", ..., allow_na = FALSE, allow_null = allow_null, arg = arg, call = call ) } check_call <- function(x, ..., allow_null = FALSE, arg = caller_arg(x), call = caller_env()) { if (!missing(x)) { if (is_call(x)) { return(invisible(NULL)) } if (allow_null && is_null(x)) { return(invisible(NULL)) } } stop_input_type( x, "a defused call", ..., allow_na = FALSE, allow_null = allow_null, arg = arg, call = call ) } check_environment <- function(x, ..., allow_null = FALSE, arg = caller_arg(x), call = caller_env()) { if (!missing(x)) { if (is_environment(x)) { return(invisible(NULL)) } if (allow_null && is_null(x)) { return(invisible(NULL)) } } stop_input_type( x, "an environment", ..., allow_na = FALSE, allow_null = allow_null, arg = arg, call = call ) } check_function <- function(x, ..., allow_null = FALSE, arg = caller_arg(x), call = caller_env()) { if (!missing(x)) { if (is_function(x)) { return(invisible(NULL)) } if (allow_null && is_null(x)) { return(invisible(NULL)) } } stop_input_type( x, "a function", ..., allow_na = FALSE, allow_null = allow_null, arg = arg, call = call ) } check_closure <- function(x, ..., allow_null = FALSE, arg = caller_arg(x), call = caller_env()) { if (!missing(x)) { if (is_closure(x)) { return(invisible(NULL)) } if (allow_null && is_null(x)) { return(invisible(NULL)) } } stop_input_type( x, "an R function", ..., allow_na = FALSE, allow_null = allow_null, arg = arg, call = call ) } check_formula <- function(x, ..., allow_null = FALSE, arg = caller_arg(x), call = caller_env()) { if (!missing(x)) { if (is_formula(x)) { return(invisible(NULL)) } if (allow_null && is_null(x)) { return(invisible(NULL)) } } stop_input_type( x, "a formula", ..., allow_na = FALSE, allow_null = allow_null, arg = arg, call = call ) } # Vectors ----------------------------------------------------------------- check_character <- function(x, ..., allow_null = FALSE, arg = caller_arg(x), call = caller_env()) { if (!missing(x)) { if (is_character(x)) { return(invisible(NULL)) } if (allow_null && is_null(x)) { return(invisible(NULL)) } } stop_input_type( x, "a character vector", ..., allow_na = FALSE, allow_null = allow_null, arg = arg, call = call ) } check_logical <- function(x, ..., allow_null = FALSE, arg = caller_arg(x), call = caller_env()) { if (!missing(x)) { if (is_logical(x)) { return(invisible(NULL)) } if (allow_null && is_null(x)) { return(invisible(NULL)) } } stop_input_type( x, "a logical vector", ..., allow_na = FALSE, allow_null = allow_null, arg = arg, call = call ) } check_data_frame <- function(x, ..., allow_null = FALSE, arg = caller_arg(x), call = caller_env()) { if (!missing(x)) { if (is.data.frame(x)) { return(invisible(NULL)) } if (allow_null && is_null(x)) { return(invisible(NULL)) } } stop_input_type( x, "a data frame", ..., allow_null = allow_null, arg = arg, call = call ) } # nocov end ������������������������������������������������������������������������������������������������������������������pkgdown/R/check-built.R�����������������������������������������������������������������������������0000644�0001762�0000144�00000002360�14657466716�014470� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ check_built_site <- function(pkg = ".") { pkg <- as_pkgdown(pkg) cli::cli_rule("Checking for problems") index_path <- path_index(pkg) if (!is.null(index_path)) { check_missing_images(pkg, index_path, "index.html") } } check_missing_images <- function(pkg, src_path, dst_path) { html <- xml2::read_html(path(pkg$dst_path, dst_path), encoding = "UTF-8") img <- xml2::xml_find_all(html, ".//img") src <- xml2::xml_attr(img, "src") rel_src <- xml2::url_unescape(src[xml2::url_parse(src)$scheme == ""]) rel_path <- path_norm(path(path_dir(dst_path), rel_src)) exists <- file_exists(path(pkg$dst_path, rel_path)) if (any(!exists)) { paths <- rel_src[!exists] cli::cli_inform(c( "Missing images in {.file {path_rel(src_path, pkg$src_path)}}: {.file {paths}}", i = "pkgdown can only use images in {.file man/figures} and {.file vignettes}" )) } alt <- xml2::xml_attr(img, "alt") if (anyNA(alt)) { problems <- src[is.na(alt)] problems[grepl("^data:image", problems)] <- "<base64 encoded image>" cli::cli_inform(c( x = "Missing alt-text in {.file {path_rel(src_path, pkg$src_path)}}", set_names(problems, "*"), i = "Learn more in {.vignette pkgdown::accessibility}." )) } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/topics.R����������������������������������������������������������������������������������0000644�0001762�0000144�00000016530�14633374223�013564� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# @return An integer vector giving selected topics select_topics <- function(match_strings, topics, check = FALSE, error_path, error_pkg, error_call = caller_env()) { n <- nrow(topics) if (length(match_strings) == 0) { return(integer()) } indexes <- unwrap_purrr_error(purrr::imap( match_strings, match_eval, env = match_env(topics), error_path = error_path, error_pkg = error_pkg, error_call = error_call )) # If none of the specified topics have a match, return no topics if (purrr::every(indexes, is_empty)) { if (check) { msg <- "{.field {error_path}} failed to match any topics." config_abort(error_pkg, msg, call = error_call) } return(integer()) } no_match <- match_strings[purrr::map_lgl(indexes, rlang::is_empty)] if (check && length(no_match) > 0) { topic_must( "match a function or concept", toString(no_match), error_pkg = error_pkg, error_path = error_path, error_call = error_call ) } indexes <- purrr::discard(indexes, is_empty) # Combine integer positions; adding if +ve, removing if -ve sign <- all_sign( indexes[[1]], match_strings[[1]], error_pkg = error_pkg, error_path = paste0(error_path, "[1]"), error_call = error_call ) sel <- switch(sign, "+" = integer(), "-" = seq_len(n)[!topics$internal] ) for (i in seq2(1, length(indexes))) { index <- indexes[[i]] sign <- all_sign( indexes[[i]], match_strings[[i]], error_pkg = error_pkg, error_path = paste0(error_path, "[", i, "]"), error_call = error_call ) sel <- switch( sign, "+" = union(sel, indexes[[i]]), "-" = setdiff(sel, -indexes[[i]]) ) } sel } all_sign <- function(x, text, error_pkg, error_path, error_call = caller_env()) { if (is.numeric(x)) { if (all(x < 0)) { return("-") } if (all(x > 0)) { return("+") } } config_abort( error_pkg, "{.field {error_path}} ({text}) must be all negative or all positive.", call = error_call ) } match_env <- function(topics) { fns <- env(empty_env(), "-" = function(x) -x, "c" = function(...) c(...) ) out <- env(fns) topic_index <- seq_along(topics$name) # Each \alias{} is matched to its position topics$alias <- lapply(topics$alias, unique) aliases <- set_names( rep(topic_index, lengths(topics$alias)), unlist(topics$alias) ) env_bind(out, !!!aliases) # As is each \name{} - we bind these second so that if \name{x} and \alias{x} # are in different files, \name{x} wins. This doesn't usually matter, but # \name{} needs to win so that the default_reference_index() matches the # correct files env_bind(out, !!!set_names(topic_index, topics$name)) # dplyr-like matching functions any_alias <- function(f, ..., .internal = FALSE) { f <- as_function(f) alias_match <- purrr::map_lgl(unname(topics$alias), function(x) { any(f(x, ...)) }) name_match <- purrr::map_lgl(topics$name, f, ...) which((alias_match | name_match) & is_public(.internal)) } is_public <- function(internal) { if (!internal) !topics$internal else rep(TRUE, nrow(topics)) } fns$starts_with <- function(x, internal = FALSE) { check_string(x) check_bool(internal) any_alias(~ grepl(paste0("^", x), .), .internal = internal) } fns$ends_with <- function(x, internal = FALSE) { check_string(x) check_bool(internal) any_alias(~ grepl(paste0(x, "$"), .), .internal = internal) } fns$matches <- function(x, internal = FALSE) { check_string(x) check_bool(internal) any_alias(~ grepl(x, .), .internal = internal) } fns$contains <- function(x, internal = FALSE) { check_string(x) check_bool(internal) any_alias(~ grepl(x, ., fixed = TRUE), .internal = internal) } fns$has_keyword <- function(x) { check_character(x) which(purrr::map_lgl(topics$keywords, ~ any(. %in% x))) } fns$has_lifecycle <- function(x) { check_string(x) which(purrr::map_lgl(topics$lifecycle, ~ any(. %in% x))) } fns$has_concept <- function(x, internal = FALSE) { check_string(x) check_bool(internal) match <- purrr::map_lgl(topics$concepts, ~ any(str_trim(.) == x)) which(match & is_public(internal)) } fns$lacks_concepts <- function(x, internal = FALSE) { check_character(x) check_bool(internal) match <- purrr::map_lgl(topics$concepts, ~ any(str_trim(.) == x)) which(!match & is_public(internal)) } fns$lacks_concept <- fns$lacks_concepts out } match_eval <- function(string, index, env, error_pkg, error_path, error_call = caller_env()) { error_path <- paste0(error_path, "[", index, "]") # Early return in case string already matches symbol if (env_has(env, string)) { val <- env[[string]] if (is.integer(val)) { return(val) } } expr <- tryCatch(parse_expr(string), error = function(e) NULL) if (is.null(expr)) { topic_must( "be valid R code", string, error_pkg = error_pkg, error_path = error_path, error_call = error_call ) } if (is_string(expr) || is_symbol(expr)) { expr <- as.character(expr) val <- env_get(env, expr, default = NULL) if (is.integer(val)) { val } else { topic_must( "be a known topic name or alias", string, error_pkg = error_pkg, error_path = error_path, error_call = error_call ) } } else if (is_call(expr, "::")) { name <- paste0(expr[[2]], "::", expr[[3]]) val <- env_get(env, name, default = NULL) if (is.integer(val)) { val } else { topic_must( "be a known topic name or alias", string, error_pkg = error_pkg, error_path = error_path, error_call = error_call ) } } else if (is_call(expr)) { withCallingHandlers( eval(expr, env), error = function(e) { config_abort( error_pkg, "{.field {error_path}} ({string}) failed to evaluate.", parent = e, call = error_call ) } ) } else { topic_must( "be a string or function call", string, error_pkg = error_pkg, error_path = error_path, error_call = error_call ) } } topic_must <- function(message, topic, error_pkg, error_path, error_call, ...) { msg <- "{.field {error_path}} ({topic}) must {message}." config_abort(error_pkg, msg, call = error_call, ...) } section_topics <- function(pkg, match_strings, error_path, error_call = error_call()) { # Add rows for external docs ext_strings <- match_strings[grepl("::", match_strings, fixed = TRUE)] topics <- rbind(pkg$topics, ext_topics(ext_strings)) idx <- select_topics( match_strings, topics, error_pkg = pkg, error_path = error_path, error_call = error_call ) selected <- topics[idx, , drop = FALSE] tibble::tibble( name = selected$name, path = selected$file_out, title = selected$title, lifecycle = selected$lifecycle, aliases = purrr::map2(selected$funs, selected$alias, ~ if (length(.x) > 0) .x else .y), icon = find_icons(selected$alias, path(pkg$src_path, "icons")) ) } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/markdown.R��������������������������������������������������������������������������������0000644�0001762�0000144�00000010136�14633374223�014101� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������markdown_text <- function(pkg, text, ...) { if (identical(text, NA_character_) || is.null(text)) { return(NULL) } md_path <- withr::local_tempfile() write_lines(text, md_path) markdown_path_html(pkg, md_path, ...) } markdown_text_inline <- function(pkg, text, error_path, error_call = caller_env()) { html <- markdown_text(pkg, text) if (is.null(html)) { return() } children <- xml2::xml_children(xml2::xml_find_first(html, ".//body")) if (length(children) > 1) { msg <- "{.field {error_path}} must be inline markdown." config_abort(pkg, msg, call = error_call) } paste0(xml2::xml_contents(children), collapse = "") } markdown_text_block <- function(pkg, text, ...) { html <- markdown_text(pkg, text, ...) if (is.null(html)) { return() } children <- xml2::xml_children(xml2::xml_find_first(html, ".//body")) paste0(as.character(children, options = character()), collapse = "") } markdown_body <- function(pkg, path, strip_header = FALSE) { xml <- markdown_path_html(pkg, path, strip_header = strip_header) if (is.null(xml)) { return(NULL) } # Extract body of html - as.character renders as xml which adds # significant whitespace in tags like pre transformed_path <- withr::local_tempfile() body <- xml2::xml_find_first(xml, ".//body") xml2::write_html(body, transformed_path, format = FALSE) lines <- read_lines(transformed_path) lines <- sub("<body>", "", lines, fixed = TRUE) lines <- sub("</body>", "", lines, fixed = TRUE) structure( paste(lines, collapse = "\n"), title = attr(xml, "title") ) } markdown_path_html <- function(pkg, path, strip_header = FALSE) { html_path <- withr::local_tempfile() convert_markdown_to_html(pkg, path, html_path) xml <- xml2::read_html(html_path, encoding = "UTF-8") if (!inherits(xml, "xml_node")) { return(NULL) } # Capture heading, and optionally remove h1 <- xml2::xml_find_first(xml, ".//h1") title <- xml2::xml_text(h1) if (strip_header) { xml2::xml_remove(h1) } structure(xml, title = title) } markdown_to_html <- function(pkg, text, dedent = 4, bs_version = 3) { if (dedent) { text <- dedent(text, dedent) } md_path <- withr::local_tempfile() html_path <- withr::local_tempfile() write_lines(text, md_path) convert_markdown_to_html(pkg, md_path, html_path) html <- xml2::read_html(html_path, encoding = "UTF-8") tweak_page(html, "markdown", list(bs_version = bs_version)) html } dedent <- function(x, n = 4) { gsub(paste0("($|\n)", strrep(" ", n)), "\\1", x, perl = TRUE) } convert_markdown_to_html <- function(pkg, in_path, out_path, ...) { if (rmarkdown::pandoc_available("2.0")) { from <- "markdown+gfm_auto_identifiers-citations+emoji+autolink_bare_uris" } else if (rmarkdown::pandoc_available("1.12.3")) { from <- "markdown_github-hard_line_breaks+tex_math_dollars+tex_math_single_backslash+header_attributes" } else { if (is_testing()) { testthat::skip("Pandoc not available") } else { cli::cli_abort("Pandoc not available") } } rmarkdown::pandoc_convert( input = in_path, output = out_path, from = from, to = "html", options = purrr::compact(c( if (!rmarkdown::pandoc_available("2.0")) "--smart", if (rmarkdown::pandoc_available("2.0")) c("-t", "html4"), "--indented-code-classes=R", "--section-divs", "--wrap=none", paste0("--", config_math_rendering(pkg)), ... )) ) invisible() } config_math_rendering <- function(pkg, call = caller_env()) { if (is.null(pkg)) { # Special case for tweak_highlight_other() where it's too annoying to # pass down the package, and it doesn't matter much anyway. return("mathml") } math <- config_pluck_string( pkg, "template.math-rendering", default = "mathml", call = call ) allowed <- c("mathml", "mathjax", "katex") if (!math %in% allowed) { msg <- "{.field template.math-rendering} must be one of {allowed}, not {math}." config_abort(pkg, msg, call = call) } math } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/pkgdown_print.R���������������������������������������������������������������������������0000644�0001762�0000144�00000002470�14633374223�015146� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' Print object in pkgdown output #' #' This lets package authors control how objects are printed just for #' pkgdown examples. The default is to call [print()] apart from htmlwidgets #' where the object is returned as is (with sizes tweaked). #' #' @param x Object to display #' @param visible Whether it is visible or not #' @return Either a character vector representing printed output (which #' will be escaped for HTML as necessary) or literal HTML produced #' by the htmltools or htmlwidgets packages. #' @keywords internal #' @export pkgdown_print <- function(x, visible = TRUE) { UseMethod("pkgdown_print") } #' @export pkgdown_print.default <- function(x, visible = TRUE) { if (!visible) { return(invisible()) } # inlined from htmltools::is.browsable() if (isTRUE(attr(x, "browsable_html", exact = TRUE))) { x } else { print(x) } } #' @export pkgdown_print.htmlwidget <- function(x, visible = TRUE) { if (!visible) { return(invisible()) } settings <- fig_settings() x$width <- x$width %||% (settings$fig.width * settings$dpi) x$height <- x$height %||% (settings$fig.height * settings$dpi) x } #' @export pkgdown_print.gt_tbl <- function(x, visible = TRUE) { if (!visible) { return(invisible()) } htmltools::div( class = "gt-table", gt::as_raw_html(x) ) } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/tweak-reference.R�������������������������������������������������������������������������0000644�0001762�0000144�00000005513�14633374223�015331� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Syntax highlighting for `\preformatted{}` blocks in reference topics tweak_reference_highlighting <- function(html) { # There are three cases: # 1) <div> with class sourceCode + r/R, as created by ```R div <- xml2::xml_find_all(html, ".//div") # must have sourceCode and not be in examples or usage is_source <- has_class(div, "sourceCode") & !is_handled_section(div) div_sourceCode <- div[is_source] is_r <- has_class(div_sourceCode, c("r", "R")) div_sourceCode_r <- div_sourceCode[is_r] purrr::walk(div_sourceCode_r, tweak_highlight_r) # 2) <div> with class sourceCode + another language, e.g. ```yaml # or no language e.g. ``` div_sourceCode_other <- div_sourceCode[!is_r] purrr::walk(div_sourceCode_other, tweak_highlight_other) # 3) <pre> with no wrapper <div>, as created by ``` pre <- xml2::xml_find_all(html, ".//pre") handled <- is_wrapped_pre(pre) | is_handled_section(pre) purrr::walk(pre[!handled], tweak_highlight_r) # Add div.sourceCode for copy button xml2::xml_add_parent(pre[!handled], "div", class = "sourceCode") invisible() } is_wrapped_pre <- function(html) { xml2::xml_find_lgl(html, "boolean(parent::div[contains(@class, 'sourceCode')])") } is_handled_section <- function(html) { xml2::xml_find_lgl(html, "boolean(ancestor::div[@id='ref-examples' or @id='ref-usage'])") } tweak_highlight_r <- function(block) { code <- xml2::xml_find_first(block, ".//code") if (is.na(code)) { return(FALSE) } text <- xml2::xml_text(code) out <- downlit::highlight(text, classes = downlit::classes_pandoc()) if (is.na(out) || identical(out, "")) { return(FALSE) } html <- xml2::read_html(out) xml_replace_contents(code, xml2::xml_find_first(html, "body")) TRUE } tweak_highlight_other <- function(div) { code <- xml2::xml_find_first(div, ".//code") if (is.na(code)) { return(FALSE) } lang <- sub("sourceCode ", "", xml2::xml_attr(div, "class")) # since roxygen 7.2.0 generic code blocks have sourceCode with no lang if (!is.na(lang) && lang == "sourceCode") lang <- "r" # Pandoc does not recognize rmd as a language :-) if (tolower(lang) %in% c("rmd", "qmd")) lang <- "markdown" # many backticks to account for possible nested code blocks # like a Markdown code block with code chunks inside md <- paste0("``````", lang, "\n", xml2::xml_text(code), "\n``````") html <- markdown_text(NULL, md) xml_replace_contents(code, xml2::xml_find_first(html, "body/div/pre/code")) TRUE } xml_replace_contents <- function(node, new) { xml2::xml_remove(xml2::xml_contents(node)) contents <- xml2::xml_contents(new) for (child in contents) { xml2::xml_add_child(node, child) } } tweak_extra_logo <- function(html) { img <- xml2::xml_find_all(html, ".//div[contains(@class,'ref-description')]//img[contains(@src,'logo')]") xml2::xml_remove(img) invisible() } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/utils-fs.R��������������������������������������������������������������������������������0000644�0001762�0000144�00000006241�14634573316�014034� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������dir_copy_to <- function(src_dir, dst_dir, src_root, dst_root, src_label = "", dst_label = "") { check_string(src_dir) check_string(dst_dir) if (!dir_exists(src_dir)) { return() } src_paths <- dir_ls(src_dir, recurse = TRUE) is_dir <- is_dir(src_paths) dst_paths <- path(dst_dir, path_rel(src_paths, src_dir)) # First create directories dir_create(dst_paths[is_dir]) # Then copy files file_copy_to( src_paths = src_paths[!is_dir], dst_paths = dst_paths[!is_dir], src_root = src_root, dst_root = dst_root, src_label = src_label, dst_label = dst_label ) } file_copy_to <- function(src_paths, dst_paths, src_root, dst_root, src_label = NULL, dst_label = "") { # Ensure all the "to" directories exist dst_dirs <- unique(path_dir(dst_paths)) dir_create(dst_dirs) eq <- purrr::map2_lgl(src_paths, dst_paths, file_equal) if (any(!eq)) { dst <- paste0(dst_label, path_rel(dst_paths[!eq], dst_root)) if (is.null(src_label)) { purrr::walk(dst, function(dst) { cli::cli_inform("Copying {dst_path(dst)}") }) } else { src <- paste0(src_label, path_rel(src_paths[!eq], src_root)) purrr::walk2(src, dst, function(src, dst) { cli::cli_inform("Copying {src_path(src)} to {dst_path(dst)}") }) } } file_copy(src_paths[!eq], dst_paths[!eq], overwrite = TRUE) } out_of_date <- function(source, target, call = caller_env()) { if (!file_exists(target)) { return(TRUE) } if (!file_exists(source)) { cli::cli_abort("{.path {source}} does not exist", call = call) } file_info(source)$modification_time > file_info(target)$modification_time } # Path helpers ------------------------------------------------------------ path_abs <- function(path, start = ".") { is_abs <- is_absolute_path(path) path[is_abs] <- path_norm(path[is_abs]) path[!is_abs] <- fs::path_abs(path(start, path)) path_tidy(path) } path_first_existing <- function(...) { paths <- path(...) for (path in paths) { if (file_exists(path)) return(path) } NULL } path_package_pkgdown <- function(path, package, bs_version, error_call = caller_env()) { # package will usually be a github package, and check_installed() # tries to install from CRAN, which is highly likely to fail. if (!is_installed(package)) { cli::cli_abort( c( "Template package {.val {package}} is not installed.", i = "Please install before continuing." ), call = error_call ) } base <- system_file("pkgdown", package = package) # If bs_version supplied, first try for versioned template if (!is.null(bs_version)) { ver_path <- path(base, paste0("BS", bs_version), path) if (file_exists(ver_path)) { return(ver_path) } } path(base, path) } path_pkgdown <- function(...) { system_file(..., package = "pkgdown") } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/build-404.R�������������������������������������������������������������������������������0000644�0001762�0000144�00000001040�14137761366�013664� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������build_404 <- function(pkg = ".") { pkg <- as_pkgdown(pkg) # if this file exists, it will be handled by build_home_md() page_md <- path(pkg$src_path, ".github", "404.md") if (!file_exists(page_md)) { render_page( pkg, "title-body", data = list( pagetitle = tr_("Page not found (404)"), body = tr_("Content not found. Please use links in the navbar.") ), path = "404.html" ) update_html(path_abs("404.html", start = pkg$dst_path), tweak_link_absolute, pkg = pkg) } invisible() } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/tweak-tags.R������������������������������������������������������������������������������0000644�0001762�0000144�00000013343�14634573316�014336� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tweak_anchors <- function(html) { headings <- xml2::xml_find_all(html, ".//h1|.//h2|.//h3|.//h4|.//h5|.//h6") # Find all headings that are contained in a div with an id and # have class 'section' is_ok <- xml2::xml_find_lgl(headings, "boolean( (parent::div[contains(@class, 'section') and @id]) or (parent::section[@id]) )" ) headings <- headings[is_ok] if (length(headings) == 0) { return(invisible()) } id <- xml2::xml_find_chr(headings, "string(parent::div/@id|parent::section/@id)") # Update ids: dot in the anchor breaks scrollspy and rd translation # doesn't have enough information to generate unique ids new_id <- make.unique(gsub(".", "-", id, fixed = TRUE), "-") # Move ids to headings so that the js TOC doesn't add create new ids divs <- xml2::xml_parent(headings) xml2::xml_attr(divs, "id") <- NULL xml2::xml_attr(headings, "id") <- new_id # Insert anchors anchor <- anchor_html(new_id) for (i in seq_along(headings)) { heading <- headings[[i]] if (length(xml2::xml_contents(heading)) == 0) { # skip empty headings next } # Insert anchor in first element of header xml2::xml_add_child(heading, xml2::read_xml(anchor[[i]])) } invisible() } anchor_html <- function(id) { paste0("<a class='anchor' aria-label='anchor' href='#", id, "'></a>") } tweak_link_md <- function(html) { links <- xml2::xml_find_all(html, ".//a") if (length(links) == 0) return() hrefs <- xml2::xml_attr(links, "href") urls <- xml2::url_parse(hrefs) needs_tweak <- urls$scheme == "" & grepl("\\.md$", urls$path) fix_links <- function(x) { x <- gsub("\\.md\\b", ".html", x) x <- gsub("\\.github/", "", x) x } if (any(needs_tweak)) { purrr::walk2( links[needs_tweak], fix_links(hrefs[needs_tweak]), xml2::xml_set_attr, attr = "href" ) } invisible() } tweak_link_external <- function(html, pkg = list()) { links <- xml2::xml_find_all(html, ".//a") if (length(links) == 0) return() links <- links[!has_class(links, "external-link")] hrefs <- xml2::xml_attr(links, "href") links <- links[!is_internal_link(hrefs, pkg = pkg)] # Users might have added absolute URLs to e.g. the Code of Conduct tweak_class_prepend(links, "external-link") invisible() } # Fix relative image links tweak_img_src <- function(html) { fix_path <- function(x) { x <- gsub("(^|/)vignettes/", "\\1articles/", x, perl = TRUE) x <- gsub("(^|/)man/figures/", "\\1reference/figures/", x, perl = TRUE) x } imgs <- xml2::xml_find_all(html, ".//img[not(starts-with(@src, 'http'))]") urls <- fix_path(xml2::xml_attr(imgs, "src")) purrr::map2(imgs, urls, ~ xml2::xml_set_attr(.x, "src", .y)) imgs <- xml2::xml_find_all(html, ".//source[not(starts-with(@srcset, 'http'))]") urls <- fix_path(xml2::xml_attr(imgs, "srcset")) purrr::map2(imgs, urls, ~ xml2::xml_set_attr(.x, "srcset", .y)) invisible() } tweak_link_absolute <- function(html, pkg = list()) { # If there's no URL links can't be made absolute if (is.null(pkg$meta$url)) { return() } url <- paste0(pkg$meta$url, "/") # <a> + <link> use href href <- xml2::xml_find_all(html, ".//a | .//link") xml2::xml_attr(href, "href") <- xml2::url_absolute(xml2::xml_attr(href, "href"), url) # <img> + <script> uses src src <- xml2::xml_find_all(html, ".//script | .//img") xml2::xml_attr(src, "src") <- xml2::url_absolute(xml2::xml_attr(src, "src"), url) invisible() } tweak_link_R6 <- function(html, cur_package) { r6_span <- xml2::xml_find_all(html, ".//span[@class=\"pkg-link\"]") if (length(r6_span) == 0) { return() } pkg <- xml2::xml_attr(r6_span, "data-pkg") topic <- xml2::xml_attr(r6_span, "data-topic") id <- xml2::xml_attr(r6_span, "data-id") url <- paste0(topic, ".html") external <- pkg != cur_package if (any(external)) { url[external] <- purrr::map2_chr(topic[external], pkg[external], downlit::href_topic) } url <- paste0(url, ifelse(is.na(id), "", "#method-"), id) r6_a <- xml2::xml_find_first(r6_span, "./a") xml2::xml_attr(r6_a, "href") <- url invisible() } tweak_tables <- function(html) { # Ensure all tables have class="table" apart from arguments table <- xml2::xml_find_all(html, ".//table") table <- table[!has_class(table, "ref-arguments")] tweak_class_prepend(table, "table") invisible() } # from https://github.com/rstudio/bookdown/blob/ed31991df3bb826b453f9f50fb43c66508822a2d/R/bs4_book.R#L307 tweak_footnotes <- function(html) { container <- xml2::xml_find_all(html, ".//div[contains(@class, 'footnotes')]|.//section[contains(@class, 'footnotes')]") if (length(container) != 1) { return() } # Find id and contents footnotes <- xml2::xml_find_all(container, ".//li") id <- xml2::xml_attr(footnotes, "id") xml2::xml_remove(xml2::xml_find_all(footnotes, "//a[@class='footnote-back']")) contents <- vapply(footnotes, FUN.VALUE = character(1), function(x) { paste(as.character(xml2::xml_children(x), options = character()), collapse = "\n") }) # Add popover attributes to links for (i in seq_along(id)) { links <- xml2::xml_find_all(html, paste0(".//a[@href='#", id[[i]], "']")) xml2::xml_attr(links, "href") <- NULL xml2::xml_attr(links, "id") <- NULL xml2::xml_attr(links, "tabindex") <- "0" xml2::xml_attr(links, "data-bs-toggle") <- "popover" xml2::xml_attr(links, "data-bs-content") <- contents[[i]] } # Delete container xml2::xml_remove(container) } tweak_strip <- function(html, in_dev = FALSE) { to_remove <- if (in_dev) "pkgdown-release" else "pkgdown-devel" xpath <- paste0( ".//*[contains(@class, '", to_remove, "')]|", ".//*[contains(@class, 'pkgdown-hide')]" ) nodes <- xml2::xml_find_all(html, xpath) xml2::xml_remove(nodes) } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/import-standalone-obj-type.R��������������������������������������������������������������0000644�0001762�0000144�00000020727�14633374223�017455� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Standalone file: do not edit by hand # Source: <https://github.com/r-lib/rlang/blob/main/R/standalone-obj-type.R> # ---------------------------------------------------------------------- # # --- # repo: r-lib/rlang # file: standalone-obj-type.R # last-updated: 2023-05-01 # license: https://unlicense.org # imports: rlang (>= 1.1.0) # --- # # ## Changelog # # 2023-05-01: # - `obj_type_friendly()` now only displays the first class of S3 objects. # # 2023-03-30: # - `stop_input_type()` now handles `I()` input literally in `arg`. # # 2022-10-04: # - `obj_type_friendly(value = TRUE)` now shows numeric scalars # literally. # - `stop_friendly_type()` now takes `show_value`, passed to # `obj_type_friendly()` as the `value` argument. # # 2022-10-03: # - Added `allow_na` and `allow_null` arguments. # - `NULL` is now backticked. # - Better friendly type for infinities and `NaN`. # # 2022-09-16: # - Unprefixed usage of rlang functions with `rlang::` to # avoid onLoad issues when called from rlang (#1482). # # 2022-08-11: # - Prefixed usage of rlang functions with `rlang::`. # # 2022-06-22: # - `friendly_type_of()` is now `obj_type_friendly()`. # - Added `obj_type_oo()`. # # 2021-12-20: # - Added support for scalar values and empty vectors. # - Added `stop_input_type()` # # 2021-06-30: # - Added support for missing arguments. # # 2021-04-19: # - Added support for matrices and arrays (#141). # - Added documentation. # - Added changelog. # # nocov start #' Return English-friendly type #' @param x Any R object. #' @param value Whether to describe the value of `x`. Special values #' like `NA` or `""` are always described. #' @param length Whether to mention the length of vectors and lists. #' @return A string describing the type. Starts with an indefinite #' article, e.g. "an integer vector". #' @noRd obj_type_friendly <- function(x, value = TRUE) { if (is_missing(x)) { return("absent") } if (is.object(x)) { if (inherits(x, "quosure")) { type <- "quosure" } else { type <- class(x)[[1L]] } return(sprintf("a <%s> object", type)) } if (!is_vector(x)) { return(.rlang_as_friendly_type(typeof(x))) } n_dim <- length(dim(x)) if (!n_dim) { if (!is_list(x) && length(x) == 1) { if (is_na(x)) { return(switch( typeof(x), logical = "`NA`", integer = "an integer `NA`", double = if (is.nan(x)) { "`NaN`" } else { "a numeric `NA`" }, complex = "a complex `NA`", character = "a character `NA`", .rlang_stop_unexpected_typeof(x) )) } show_infinites <- function(x) { if (x > 0) { "`Inf`" } else { "`-Inf`" } } str_encode <- function(x, width = 30, ...) { if (nchar(x) > width) { x <- substr(x, 1, width - 3) x <- paste0(x, "...") } encodeString(x, ...) } if (value) { if (is.numeric(x) && is.infinite(x)) { return(show_infinites(x)) } if (is.numeric(x) || is.complex(x)) { number <- as.character(round(x, 2)) what <- if (is.complex(x)) "the complex number" else "the number" return(paste(what, number)) } return(switch( typeof(x), logical = if (x) "`TRUE`" else "`FALSE`", character = { what <- if (nzchar(x)) "the string" else "the empty string" paste(what, str_encode(x, quote = "\"")) }, raw = paste("the raw value", as.character(x)), .rlang_stop_unexpected_typeof(x) )) } return(switch( typeof(x), logical = "a logical value", integer = "an integer", double = if (is.infinite(x)) show_infinites(x) else "a number", complex = "a complex number", character = if (nzchar(x)) "a string" else "\"\"", raw = "a raw value", .rlang_stop_unexpected_typeof(x) )) } if (length(x) == 0) { return(switch( typeof(x), logical = "an empty logical vector", integer = "an empty integer vector", double = "an empty numeric vector", complex = "an empty complex vector", character = "an empty character vector", raw = "an empty raw vector", list = "an empty list", .rlang_stop_unexpected_typeof(x) )) } } vec_type_friendly(x) } vec_type_friendly <- function(x, length = FALSE) { if (!is_vector(x)) { abort("`x` must be a vector.") } type <- typeof(x) n_dim <- length(dim(x)) add_length <- function(type) { if (length && !n_dim) { paste0(type, sprintf(" of length %s", length(x))) } else { type } } if (type == "list") { if (n_dim < 2) { return(add_length("a list")) } else if (is.data.frame(x)) { return("a data frame") } else if (n_dim == 2) { return("a list matrix") } else { return("a list array") } } type <- switch( type, logical = "a logical %s", integer = "an integer %s", numeric = , double = "a double %s", complex = "a complex %s", character = "a character %s", raw = "a raw %s", type = paste0("a ", type, " %s") ) if (n_dim < 2) { kind <- "vector" } else if (n_dim == 2) { kind <- "matrix" } else { kind <- "array" } out <- sprintf(type, kind) if (n_dim >= 2) { out } else { add_length(out) } } .rlang_as_friendly_type <- function(type) { switch( type, list = "a list", NULL = "`NULL`", environment = "an environment", externalptr = "a pointer", weakref = "a weak reference", S4 = "an S4 object", name = , symbol = "a symbol", language = "a call", pairlist = "a pairlist node", expression = "an expression vector", char = "an internal string", promise = "an internal promise", ... = "an internal dots object", any = "an internal `any` object", bytecode = "an internal bytecode object", primitive = , builtin = , special = "a primitive function", closure = "a function", type ) } .rlang_stop_unexpected_typeof <- function(x, call = caller_env()) { abort( sprintf("Unexpected type <%s>.", typeof(x)), call = call ) } #' Return OO type #' @param x Any R object. #' @return One of `"bare"` (for non-OO objects), `"S3"`, `"S4"`, #' `"R6"`, or `"R7"`. #' @noRd obj_type_oo <- function(x) { if (!is.object(x)) { return("bare") } class <- inherits(x, c("R6", "R7_object"), which = TRUE) if (class[[1]]) { "R6" } else if (class[[2]]) { "R7" } else if (isS4(x)) { "S4" } else { "S3" } } #' @param x The object type which does not conform to `what`. Its #' `obj_type_friendly()` is taken and mentioned in the error message. #' @param what The friendly expected type as a string. Can be a #' character vector of expected types, in which case the error #' message mentions all of them in an "or" enumeration. #' @param show_value Passed to `value` argument of `obj_type_friendly()`. #' @param ... Arguments passed to [abort()]. #' @inheritParams args_error_context #' @noRd stop_input_type <- function(x, what, ..., allow_na = FALSE, allow_null = FALSE, show_value = TRUE, arg = caller_arg(x), call = caller_env()) { # From standalone-cli.R cli <- env_get_list( nms = c("format_arg", "format_code"), last = topenv(), default = function(x) sprintf("`%s`", x), inherit = TRUE ) if (allow_na) { what <- c(what, cli$format_code("NA")) } if (allow_null) { what <- c(what, cli$format_code("NULL")) } if (length(what)) { what <- oxford_comma(what) } if (inherits(arg, "AsIs")) { format_arg <- identity } else { format_arg <- cli$format_arg } message <- sprintf( "%s must be %s, not %s.", format_arg(arg), what, obj_type_friendly(x, value = show_value) ) abort(message, ..., call = call, arg = arg) } oxford_comma <- function(chr, sep = ", ", final = "or") { n <- length(chr) if (n < 2) { return(chr) } head <- chr[seq_len(n - 1)] last <- chr[n] head <- paste(head, collapse = sep) # Write a or b. But a, b, or c. if (n > 2) { paste0(head, sep, final, " ", last) } else { paste0(head, " ", final, " ", last) } } # nocov end �����������������������������������������pkgdown/R/build-articles.R��������������������������������������������������������������������������0000644�0001762�0000144�00000033606�14641303475�015171� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' Build articles section #' #' @description #' `build_articles()` renders each R Markdown file underneath `vignettes/` and #' saves it to `articles/`. There are two exceptions: #' #' * Files that start with `_` (e.g., `_index.Rmd`) are ignored, #' enabling the use of child documents. #' #' * Files in `vignettes/tutorials` are handled by [build_tutorials()] #' #' Vignettes are rendered using a special document format that reconciles #' [rmarkdown::html_document()] with the pkgdown template. This means articles #' behave slightly differently to vignettes, particularly with respect to #' external files, and custom output formats. See below for more details. #' #' Note that when you run `build_articles()` directly (outside of #' [build_site()]) vignettes will use the currently installed version of the #' package, not the current source version. This makes iteration quicker when #' you are primarily working on the text of an article. #' #' # Index and navbar #' You can control the articles index and navbar with a `articles` field in #' your `_pkgdown.yml`. If you use it, pkgdown will check that all articles #' are included, and will error if you have missed any. #' #' The `articles` field defines a list of sections, each of which #' can contain four fields: #' #' * `title` (required): title of section, which appears as a heading on the #' articles index. #' #' * `desc` (optional): An optional markdown description displayed underneath #' the section title. #' #' * `navbar` (optional): A couple of words used to label this section in #' the navbar. If omitted, this section of vignettes will not appear in the #' navbar. #' #' * `contents` (required): a list of article names to include in the #' section. This can either be names of individual vignettes or a #' call to `starts_with()`. The name of a vignette includes its #' path under `vignettes` without extension so that the name of the vignette #' found at `vignettes/pizza/slice.Rmd` is `pizza/slice`. #' #' The title and description of individual vignettes displayed on the index #' comes from `title` and `description` fields of the YAML header in the Rmds. #' #' For example, this yaml might be used for some version of dplyr: #' #' ```yaml #' articles: #' - title: Main verbs #' navbar: ~ #' contents: #' - one-table #' - two-table #' - rowwise #' - colwise #' #' - title: Developer #' desc: Vignettes aimed at package developers #' contents: #' - programming #' - packages #' ``` #' #' Note the use of the `navbar` fields. `navbar: ~` means that the "Main verbs" #' will appear in the navbar without a heading; the absence of the `navbar` #' field in the developer vignettes means that they will only be #' accessible via the articles index. #' #' The navbar will include a link to the articles index if one or more #' vignettes are not available through the navbar. If some vignettes appear #' in the navbar drop-down list and others do not, the list will automatically #' include a "More ..." link at the bottom; if no vignettes appear in the #' the navbar, it will link directly to the articles index instead of #' providing a drop-down. #' #' ## Get started #' Note that a vignette with the same name as the package (e.g., #' `vignettes/pkgdown.Rmd` or `vignettes/articles/pkgdown.Rmd`) automatically #' becomes a top-level "Get started" link, and will not appear in the articles #' drop-down. #' #' (If your package name includes a `.`, e.g. `pack.down`, use a `-` in the #' vignette name, e.g. `pack-down.Rmd`.) #' #' ## Missing articles #' #' pkgdown will warn if there are (non-internal) articles that aren't listed #' in the articles index. You can suppress such warnings by listing the #' affected articles in a section with `title: internal` (case sensitive); #' this section will not be displayed on the index page. #' #' ## External articles #' #' You can link to arbitrary additional articles by adding an #' `external-articles` entry to `_pkgdown.yml`. It should contain an array #' of objects with fields `name`, `title`, `href`, and `description`. #' #' ```yaml #' external-articles: #' - name: subsampling #' title: Subsampling for Class Imbalances #' description: Improve model performance in imbalanced data sets through undersampling or oversampling. #' href: https://www.tidymodels.org/learn/models/sub-sampling/ #' ``` #' #' If you've defined a custom articles index, you'll need to include the name #' in one of the `contents` fields. #' #' # External files #' pkgdown differs from base R in its handling of external files. When building #' vignettes, R assumes that vignettes are self-contained (a reasonable #' assumption when most vignettes were PDFs) and only copies files explicitly #' listed in `.install_extras`. pkgdown takes a different approach based on #' [rmarkdown::find_external_resources()], and it will also copy any images that #' you link to. If for some reason the automatic detection doesn't work, you #' will need to add a `resource_files` field to the yaml metadata, e.g.: #' #' ```yaml #' --- #' title: My Document #' resource_files: #' - data/mydata.csv #' - images/figure.png #' --- #' ``` #' #' Note that you can not use the `fig.path` to change the output directory of #' generated figures as its default value is a strong assumption of rmarkdown. #' #' # Embedding Shiny apps #' If you would like to embed a Shiny app into an article, the app will have #' to be hosted independently, (e.g. <https://www.shinyapps.io>). Then, you #' can embed the app into your article using an `<iframe>`, e.g. #' `<iframe src = "https://gallery.shinyapps.io/083-front-page" class="shiny-app">`. #' #' See <https://github.com/r-lib/pkgdown/issues/838#issuecomment-430473856> for #' some hints on how to customise the appearance with CSS. #' #' # Output formats #' By default, pkgdown builds all articles using the #' [rmarkdown::html_document()] `output` format, ignoring whatever is set in #' your YAML metadata. This is necessary because pkgdown has to integrate the #' HTML/CSS/JS from the vignette with the HTML/CSS/JS from rest of the site. #' Because of the challenges of combining two sources of HTML/CSS/JS, there is #' limited support for other output formats and you have to opt-in by setting #' the `as_is` field in your `.Rmd` metadata: #' #' ```yaml #' pkgdown: #' as_is: true #' ``` #' #' If the output format produces a PDF, you'll also need to specify the #' `extension` field: #' #' ```yaml #' pkgdown: #' as_is: true #' extension: pdf #' ``` #' #' To work with pkgdown, the output format must accept `template`, `theme`, and #' `self_contained` arguments, and must work without any additional CSS or #' JSS files. Note that if you use #' [`_output.yml`](https://bookdown.org/yihui/rmarkdown/html-document.html#shared-options) #' or [`_site.yml`](https://rmarkdown.rstudio.com/docs/reference/render_site.html) #' you'll still need to add `as_is: true` to each individual vignette. #' #' Additionally, htmlwidgets do not work when `as_is: true`. #' #' # Suppressing vignettes #' If you want [articles](https://r-pkgs.org/vignettes.html#sec-vignettes-article) #' that are not vignettes, use `usethis::use_article()` to create it. An articles link will be #' automatically added to the default navbar if the vignettes directory is #' present: if you do not want this, you will need to customise the navbar. See #' [build_site()] details. #' #' @inheritSection build_reference Figures #' @family site components #' #' @inheritParams as_pkgdown #' @param quiet Set to `FALSE` to display output of knitr and #' pandoc. This is useful when debugging. #' @param lazy If `TRUE`, will only re-build article if input file has been #' modified more recently than the output file. #' @param seed Seed used to initialize random number generation in order to #' make article output reproducible. An integer scalar or `NULL` for no seed. #' @param preview If `TRUE`, or `is.na(preview) && interactive()`, will preview #' freshly generated section in browser. #' @export #' @order 1 build_articles <- function(pkg = ".", quiet = TRUE, lazy = TRUE, seed = 1014L, override = list(), preview = FALSE) { pkg <- section_init(pkg, "articles", override = override) check_bool(quiet) check_bool(lazy) check_number_whole(seed, allow_null = TRUE) if (nrow(pkg$vignettes) == 0L) { return(invisible()) } cli::cli_rule("Building articles") build_articles_index(pkg) unwrap_purrr_error(purrr::walk( pkg$vignettes$name[pkg$vignettes$type == "rmd"], build_article, pkg = pkg, lazy = lazy, seed = seed, quiet = quiet )) build_quarto_articles(pkg, quiet = quiet) preview_site(pkg, "articles", preview = preview) } # Articles index ---------------------------------------------------------- #' @export #' @rdname build_articles #' @order 3 build_articles_index <- function(pkg = ".", override = list()) { pkg <- section_init(pkg, "articles", override = override) render_page( pkg, "article-index", data = data_articles_index(pkg), path = path("articles", "index.html") ) invisible() } data_articles_index <- function(pkg = ".", call = caller_env()) { pkg <- as_pkgdown(pkg) articles <- data_articles(pkg, is_index = TRUE, call = call) index <- config_pluck_list(pkg, "articles", call = call) %||% default_articles_index(pkg) sections <- unwrap_purrr_error(purrr::imap( index, data_articles_index_section, articles = articles, pkg = pkg, call = call )) # Check for unlisted vignettes all_names <- purrr::map(sections, function(section) { purrr::map_chr(section$contents, "name") }) listed <- unique(purrr::list_c(all_names)) missing <- setdiff(articles$name, listed) # Exclude get started vignette or article #2150 missing <- missing[!article_is_intro(missing, package = pkg$package)] if (length(missing) > 0) { config_abort( pkg, "{length(missing)} vignette{?s} missing from index: {.val {missing}}.", call = caller_env() ) } # Remove internal section after missing vignettes check sections <- Filter(function(x) x$title != "internal", sections) print_yaml(list( pagetitle = tr_("Articles"), sections = sections )) } data_articles <- function(pkg = ".", is_index = FALSE, call = caller_env()) { pkg <- as_pkgdown(pkg) internal <- tibble::tibble( name = pkg$vignettes$name, title = pkg$vignettes$title, href = pkg$vignettes$file_out, description = pkg$vignettes$description, ) if (is_index) { internal$href <- path_rel(internal$href, "articles") } external <- config_pluck_external_articles(pkg, call = call) articles <- rbind(internal, external) articles$description <- lapply(articles$description, markdown_text_block, pkg = pkg) # Hack data structure so we can use select_topics() articles$alias <- as.list(articles$name) articles$internal <- FALSE articles } config_pluck_external_articles <- function(pkg, call = caller_env()) { external <- config_pluck_list(pkg, "external-articles", call = call) if (is.null(external)) { return(tibble::tibble( name = character(), title = character(), href = character(), description = character() )) } for (i in seq_along(external)) { config_check_list( external[[i]], has_names = c("name", "title", "href", "description"), error_path = paste0("external-articles[", i, "]"), error_pkg = pkg, error_call = call ) config_check_string( external[[i]]$name, error_path = paste0("external-articles[", i, "].name"), error_pkg = pkg, error_call = call ) config_check_string( external[[i]]$title, error_path = paste0("external-articles[", i, "].title"), error_pkg = pkg, error_call = call ) config_check_string( external[[i]]$href, error_path = paste0("external-articles[", i, "].href"), error_pkg = pkg, error_call = call ) config_check_string( external[[i]]$description, error_path = paste0("external-articles[", i, "].description"), error_pkg = pkg, error_call = call ) } tibble::tibble( name = purrr::map_chr(external, "name"), title = purrr::map_chr(external, "title"), href = purrr::map_chr(external, "href"), description = purrr::map_chr(external, "description") ) } data_articles_index_section <- function(section, index, articles, pkg, call = caller_env()) { config_check_list( section, error_path = paste0("articles[", index, "]"), has_names = c("title", "contents"), error_pkg = pkg, error_call = call ) config_check_string( section$title, error_path = paste0("articles[", index, "].title"), error_pkg = pkg, error_call = call ) title <- markdown_text_inline( pkg, section$title, error_path = paste0("articles[", index, "].title"), error_call = call ) config_check_string( section$desc, error_path = paste0("articles[", index, "].desc"), error_pkg = pkg, error_call = call ) check_contents( section$contents, index, pkg, prefix = "articles", call = call ) # Match topics against any aliases idx <- select_topics( section$contents, articles, error_path = paste0("articles[", index, "].contents"), error_pkg = pkg, error_call = call ) contents <- articles[idx, , drop = FALSE] list( title = title, desc = markdown_text_block(pkg, section$desc), class = section$class, contents = purrr::transpose(contents) ) } default_articles_index <- function(pkg = ".") { pkg <- as_pkgdown(pkg) if (nrow(pkg$vignettes) == 0L) { return(NULL) } print_yaml(list( list( title = tr_("All vignettes"), desc = NULL, contents = auto_quote(unname(pkg$vignettes$name)) ) )) } article_is_intro <- function(name, package) { package <- gsub(".", "-", package, fixed = TRUE) name %in% c(package, paste0("articles/", package)) } ��������������������������������������������������������������������������������������������������������������������������pkgdown/R/preview.R���������������������������������������������������������������������������������0000644�0001762�0000144�00000002727�14641252111�013735� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' Open site in browser #' #' `preview_site()` opens your pkgdown site in your browser. pkgdown has been #' carefully designed to work even when served from the file system like #' this; the only part that doesn't work is search. You can use `servr::httw("docs/")` #' to create a server to make search work locally. #' #' @inheritParams build_article #' @param path Path relative to destination #' @export preview_site <- function(pkg = ".", path = ".", preview = TRUE) { path <- local_path(pkg, path) check_bool(preview, allow_na = TRUE) if (is.na(preview)) { preview <- interactive() && !is_testing() } if (preview) { cli::cli_inform(c(i = "Previewing site")) utils::browseURL(path) } invisible() } local_path <- function(pkg, path, call = caller_env()) { pkg <- as_pkgdown(pkg) check_string(path, call = call) abs_path <- path_abs(path, pkg$dst_path) if (!file_exists(abs_path)) { cli::cli_abort("Can't find file {.path {path}}.", call = call) } if (is_dir(abs_path)) { abs_path <- path(abs_path, "index.html") } abs_path } #' Preview a local pkgdown page in the browser #' #' @description #' `r lifecycle::badge("deprecated")` Use [preview_site()] instead. #' #' @export #' @keywords internal preview_page <- function(path, pkg = ".") { lifecycle::deprecate_warn("2.1.0", "preview_page()", "preview_site()") preview_site(pkg, path, preview = TRUE) } is_testing <- function() { identical(Sys.getenv("TESTTHAT"), "true") } �����������������������������������������pkgdown/R/repo.R������������������������������������������������������������������������������������0000644�0001762�0000144�00000006401�14633374223�013224� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������repo_type <- function(pkg) { home <- repo_home(pkg) %||% "" if (grepl("^https?://github\\..+/", home)) { "github" } else if (grepl("^https?://gitlab\\..+/", home)) { "gitlab" } else { "other" } } repo_home <- function(pkg, paths) { pkg$repo$url$home } repo_source <- function(pkg, paths) { url <- pkg$repo$url if (is.null(url$source) || length(paths) == 0) { return() } needs_slash <- !grepl("/$", url$source) & !grepl("^/", paths) links <- a( paste0("<code>", escape_html(paths), "</code>"), paste0(url$source, ifelse(needs_slash, "/", ""), paths) ) n <- length(links) if (n >= 4) { links <- c(links[1:3], paste0("and ", n - 3, " more")) } paste0(tr_("Source:"), " ", paste(links, collapse = ", ")) } repo_auto_link <- function(pkg, text) { url <- pkg$repo$url if (!is.null(url$user)) { user_link <- paste0("\\1<a href='", url$user, "\\2'>@\\2</a>") text <- gsub("(p>|\\s|^|\\()@([-\\w]+)", user_link, text, perl = TRUE) } if (!is.null(url$issue)) { issue_link <- paste0("<a href='", url$issue, "\\2'>#\\2</a>") text <- gsub("(p>|\\(|\\s)#(\\d+)", paste0("\\1", issue_link), text, perl = TRUE) if (!is.null(pkg$repo$jira_projects)) { issue_link <- paste0("<a href='", url$issue, "\\1\\2'>\\1\\2</a>") issue_regex <- paste0("(", paste0(pkg$repo$jira_projects, collapse = "|"),")(-\\d+)") text <- gsub(issue_regex, issue_link, text, perl = TRUE) } } text } # Package data ------------------------------------------------------------- package_repo <- function(pkg) { # Use metadata if available repo <- config_pluck_list(pkg, "repo") url <- config_pluck_list(pkg, "repo.url") if (!is.null(url)) { return(repo) } # Otherwise try and guess from `BugReports` (1st priority) and `URL`s (2nd priority) urls <- c( sub("/issues/?", "/", pkg$desc$get_field("BugReports", default = character())), pkg$desc$get_urls() ) gh_links <- grep("^https?://git(hub|lab)\\..+/", urls, value = TRUE) if (length(gh_links) > 0) { branch <- config_pluck_string(pkg, "repo.branch") return(repo_meta_gh_like(gh_links[[1]], branch)) } NULL } repo_meta <- function(home = NULL, source = NULL, issue = NULL, user = NULL) { list( url = list( home = home, source = source, issue = issue, user = user ) ) } repo_meta_gh_like <- function(link, branch = NULL) { gh <- parse_github_like_url(link) branch <- branch %||% gha_current_branch() repo_meta( paste0(gh$host, "/", gh$owner, "/", gh$repo, "/"), paste0(gh$host, "/", gh$owner, "/", gh$repo, "/blob/", branch, "/"), paste0(gh$host, "/", gh$owner, "/", gh$repo, "/issues/"), paste0(gh$host, "/") ) } gha_current_branch <- function() { # Only set in pull requests ref <- Sys.getenv("GITHUB_HEAD_REF") if (ref != "") { return(ref) } # Set everywhere but might not be a branch ref <- Sys.getenv("GITHUB_REF_NAME") if (ref != "") { return(ref) } "HEAD" } parse_github_like_url <- function(link) { supports_subgroups <- grepl("^https?://gitlab\\.", link) rx <- paste0( "^", "(?<host>https?://[^/]+)/", "(?<owner>[^/]+)/", "(?<repo>[^#", "/"[!supports_subgroups], "]+)/" ) re_match(sub("([^/]$)", "\\1/", link), rx) } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/tweak-tabset.R����������������������������������������������������������������������������0000644�0001762�0000144�00000006504�14633374223�014656� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Tabsets tweaking: find Markdown recommended in # https://bookdown.org/yihui/rmarkdown-cookbook/html-tabs.html # and https://bookdown.org/yihui/rmarkdown/html-document.html#tabbed-sections # i.e. "## Heading {.tabset}" or "## Heading {.tabset .tabset-pills}" # no matter the heading level -- the headings one level down are the tabs # and transform to tabsets HTML a la Bootstrap tweak_tabsets <- function(html) { tabsets <- xml2::xml_find_all(html, ".//div[contains(@class, 'tabset')]") purrr::walk(tabsets, tweak_tabset) invisible() } tweak_tabset <- function(div) { # Get tabs and remove them from original HTML tabs <- xml2::xml_find_all(div, "div") xml2::xml_remove(tabs) # Add empty ul for nav and div for content nav_class <- if (has_class(div, "tabset-pills")) { "nav nav-pills" } else { "nav nav-tabs" } fade <- has_class(div, "tabset-fade") id <- section_id(div) nav <- xml2::xml_add_child(div, "ul", class = nav_class, id = id, role = "tablist") content <- xml2::xml_add_child(div, "div", class = "tab-content") # Fill the ul for nav and div for content purrr::walk(tabs, tablist_item, nav = nav, parent_id = id) purrr::walk(tabs, tablist_content, content = content, parent_id = id, fade = fade) # if not tabs active, activate the first tab if (!any(has_class(xml2::xml_children(content), "active"))) { first_tab <- xml2::xml_find_first(nav, ".//li/button") tweak_class_prepend(first_tab, "active") xml2::xml_attr(first_tab, "aria-selected") <- "true" tab_class <- paste("active", if (has_class(div, "tabset-fade")) "show") tweak_class_prepend(xml2::xml_child(content), tab_class) } } # Add an item (tab) to the tablist tablist_item <- function(tab, nav, parent_id) { id <- section_id(tab) title <- tablist_title(tab) # Activate (if there was "{.active}" in the source Rmd) active <- has_class(tab, "active") li_class <- paste0("nav-link", if (active) " active") li <- xml2::xml_add_child(nav, "li", role = "presentation", class = "nav-item") button <- xml2::xml_add_child(li, "button", `data-bs-toggle` = "tab", `data-bs-target` = paste0("#", id), id = paste0(id, "-tab"), type = "button", role = "tab", `aria-controls` = id, `aria-selected` = tolower(active), class = li_class ) # Preserve html in title by adding from xml_nodeset item by item for (title_item in title) { xml2::xml_add_child(button, title_item) } invisible() } tablist_title <- function(tab) { # remove anchor link from tab heading tab_heading_anchor <- xml2::xml_find_first(tab, ".//a[@class = 'anchor']") xml2::xml_remove(tab_heading_anchor) xml2::xml_contents(xml2::xml_child(tab)) } # Add content of a tab to a tabset tablist_content <- function(tab, content, parent_id, fade) { id <- section_id(tab) # remove the header, the first child xml2::xml_remove(xml2::xml_child(tab)) xml2::xml_attr(tab, "id") <- id # Activate (if there was "{.active}" in the source Rmd) active <- has_class(tab, "active") tab_class <- c( if (fade && active) "show", if (active) "active", if (fade) "fade", "tab-pane" ) xml2::xml_attr(tab, "class") <- paste(tab_class, collapse = " ") xml2::xml_attr(tab, "role") <- "tabpanel" xml2::xml_attr(tab, "aria-labelledby") <- paste0(id, "-tab") xml2::xml_add_child(content, tab) invisible() } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/build-home.R������������������������������������������������������������������������������0000644�0001762�0000144�00000024404�14634573316�014314� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' Build home section #' #' @description #' `build_home()` function generates pages at the top-level of the site #' including: #' #' * The home page #' * HTML files from any `.md` files in `./` or `.github/`. #' * The authors page (from `DESCRIPTION`) #' * The citation page (from `inst/CITATION`, if present). #' * The license page #' * A default 404 page if `.github/404.md` is not found. #' #' `build_home_index()` rebuilds just the index page; it's useful for rapidly #' iterating when experimenting with site styles. #' #' # Home page #' #' The main content of the home page (`index.html`) is generated from #' `pkgdown/index.md`, `index.md`, or `README.md`, in that order. #' Most packages will use `README.md` because that's also displayed by GitHub #' and CRAN. Use `index.md` if you want your package website to look #' different to your README, and use `pkgdown/index.md` if you don't want that #' file to live in your package root directory. #' #' If you use `index.Rmd` or `README.Rmd` it's your responsibility to knit #' the document to create the corresponding `.md`. pkgdown does not do this #' for you because it only touches files in the `doc/` directory. #' #' Extra markdown files in the base directory (e.g. `ROADMAP.md`) or in #' `.github/` (e.g. `CODE_OF_CONDUCT.md`) are copied by `build_home()` to `docs/` and converted to HTML. #' #' The home page also features a sidebar with information extracted from the #' package. You can tweak it via the configuration file, to help make the home #' page an as informative as possible landing page. #' #' ## Images and figures #' #' If you want to include images in your `README.md`, they must be stored #' somewhere in the package so that they can be displayed on the CRAN website. #' The best place to put them is `man/figures`. If you are generating figures #' with R Markdown, make sure you set up `fig.path` as followed: #' #' ``` r #' knitr::opts_chunk$set( #' fig.path = "man/figures/" #' ) #' ``` #' #' This should usually go in a chunk with `include = FALSE`. #' #' ```` markdown #' ```{r chunk-name, include=FALSE}`r ''` #' knitr::opts_chunk$set( #' fig.path = "man/figures/" #' ) #' ``` #' ```` #' #' ## Package logo #' #' If you have a package logo, you can include it at the top of your README #' in a level-one heading: #' #' ``` markdown #' # pkgdown <img src="man/figures/logo.png" align="right" /> #' ``` #' #' [init_site()] will also automatically create a favicon set from your package logo. #' #' ## YAML config - title and description #' #' By default, the page title and description are extracted automatically from #' the `Title` and `Description` fields `DESCRIPTION` (stripping single quotes #' off quoted words). CRAN ensures that these fields don't contain phrases #' like "R package" because that's obvious on CRAN. To make your package more #' findable on search engines, it's good practice to override the `title` and #' `description`, thinking about what people might search for: #' #' ```yaml #' home: #' title: An R package for pool-noodle discovery #' description: > #' Do you love R? Do you love pool-noodles? If so, you might enjoy #' using this package to automatically discover and add pool-noodles #' to your growing collection. #' ``` #' #' (Note the use of YAML's `>` i.e. "YAML pipes"; this is a convenient way of #' writing paragraphs of text.) #' #' ## Dev badges #' #' pkgdown identifies badges in three ways: #' #' - Any image-containing links between `<!-- badges: start -->` and #' `<!-- badges: end -->`, as e.g. created by `usethis::use_readme_md()` #' or `usethis::use_readme_rmd()`. There should always be an empty line after #' the `<!-- badges: end -->` line. If you divide badges into paragraphs, #' make sure to add an empty line before the `<!-- badges: end -->` line. #' #' - Any image-containing links within `<div id="badges"></div>`. #' #' - Within the first paragraph, if it only contains image-containing links. #' #' Identified badges are **removed** from the _main content_. #' They are shown or not in the _sidebar_ depending on the development mode and #' sidebar customization, see the sidebar section. #' #' # Authors #' #' By default, pkgdown will display author information in three places: #' #' * the sidebar, #' * the left part side of the footer, #' * the author page. #' #' This documentation describes how to customise the overall author display. #' See `?build_home` and `?build_site` for details about changing the location #' of the authors information within the home sidebar and the site footer. #' #' ## Authors ORCID and bio #' #' Author ORCID identification numbers in the `DESCRIPTION` are linked using #' the ORCID logo: #' #' ```r #' Authors@R: c( #' person("Hadley", "Wickham", , "hadley@rstudio.com", role = c("aut", "cre"), #' comment = c(ORCID = "0000-0003-4757-117X") #' ), #' person("Jay", "Hesselberth", role = "aut", #' comment = c(ORCID = "0000-0002-6299-179X") #' ) #' ) #' ``` #' #' If you want to add more details about authors or their involvement with the #' package, you can use the comment field, which will be rendered on the #' authors page. #' #' ```r #' Authors@R: c( #' person("Hadley", "Wickham", , "hadley@rstudio.com", role = c("aut", "cre"), #' comment = c(ORCID = "0000-0003-4757-117X", "Indenter-in-chief") #' ), #' person("Jay", "Hesselberth", role = "aut", #' comment = c(ORCID = "0000-0002-6299-179X") #' ) #' ) #' ``` #' #' ## Additional control via YAML #' #' You can control additinal aspects of the authors display via the `authors` #' YAML field: #' #' * display of each author in the footer, sidebar and authors page, #' * which authors (by role) are displayed in the sidebar and footer, #' * text before authors in the footer, #' * text before and after authors in the sidebar, #' * text before and after authors on the authors page. #' #' You can modify how each author's name is displayed by adding a subsection #' for `authors`. Each entry in `authors` should be named the author's name #' (matching `DESCRIPTION`) and can contain `href` and/or `html` fields: #' #' * If `href` is provided, the author's name will be linked to this URL. #' * If `html` is provided, it will be shown instead of the author's name. #' This is particularly useful if you want to display the logo of a corporate #' sponsor. Use an absolute URL to an image, not a relative link. Use an empty #' alternative text rather than no alternative text so a screen-reader would #' skip over it. #' #' ```yaml #' authors: #' firstname lastname: #' href: "http://name-website.com" #' html: "<img src='https://website.com/name-picture.png' width=72 alt=''>" #' ``` #' #' #' By default, the "developers" list shown in the sidebar and footer is #' populated by the maintainer ("cre"), authors ("aut"), and funder ("fnd") #' from the `DESCRIPTION`. You could choose other roles for filtering. #' With the configuration below: #' #' * only the maintainer and funder(s) appear in the footer, after the text #' "Crafted by", #' * all authors and contributors appear in the sidebar, #' * the authors list on the sidebar is preceded and followed by some text, #' * the authors list on the authors page is preceded and followed by some text. #' #' #' ```yaml #' authors: #' footer: #' roles: [cre, fnd] #' text: "Crafted by" #' sidebar: #' roles: [aut, ctb] #' before: "So *who* does the work?" #' after: "Thanks all!" #' before: "This package is proudly brought to you by:" #' after: "See the [changelog](news/index.html) for other contributors. :pray:" #' ``` #' #' If you want to filter authors based on something else than their roles, #' consider using a custom sidebar/footer component #' (see `?build_home`/`?build_site`, respectively). #' #' # Sidebar #' #' You can customise the homepage sidebar with the `home.sidebar` field. #' It's made up of two pieces: `structure`, which defines the overall layout, #' and `components`, which defines what each piece looks like. This organisation #' makes it easy to mix and match the pkgdown defaults with your own #' customisations. #' #' This is the default structure: #' #' ``` yaml #' home: #' sidebar: #' structure: [links, license, community, citation, authors, dev] #' ``` #' #' These are drawn from seven built-in components: #' #' - `links`: automated links generated from `URL` and `BugReports` fields #' from `DESCRIPTION` plus manual links from the `home.links` field: #' #' ``` yaml #' home: #' links: #' - text: Link text #' href: https://website.com #' - text: Roadmap #' href: /roadmap.html #' ``` #' #' - `license`: Licensing information if `LICENSE`/`LICENCE` or #' `LICENSE.md`/`LICENCE.md` files are present. #' #' - `community`: links to to `.github/CONTRIBUTING.md`, #' `.github/CODE_OF_CONDUCT.md`, etc. #' #' - `citation`: link to package citation information. Uses either #' `inst/CITATION` or, if absent, information from the `DESCRIPTION`. #' #' - `authors`: selected authors from the `DESCRIPTION`. #' #' - `dev`: development status badges extracted from `README.md`/`index.md`. #' This is only shown for "development" versions of websites; see #' "Development mode" in `?build_site` for details. #' #' - `toc`: a table of contents for the README (not shown by default). #' #' You can also add your own components, where `text` is markdown text: #' #' ``` yaml #' home: #' sidebar: #' structure: [authors, custom, toc, dev] #' components: #' custom: #' title: Funding #' text: We are *grateful* for funding! #' ``` #' #' Alternatively, you can provide a ready-made sidebar HTML: #' #' ``` yaml #' home: #' sidebar: #' html: path-to-sidebar.html #' ``` #' #' Or completely remove it: #' #' ``` yaml #' home: #' sidebar: FALSE #' ``` #' @inheritParams build_articles #' @family site components #' @export #' @order 1 build_home <- function(pkg = ".", override = list(), preview = FALSE, quiet = TRUE) { pkg <- section_init(pkg, override = override) check_bool(quiet) cli::cli_rule("Building home") build_citation_authors(pkg) build_home_md(pkg) build_home_license(pkg) build_home_index(pkg, quiet = quiet) if (!pkg$development$in_dev) { build_404(pkg) } preview_site(pkg, "/", preview = preview) } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/templates.R�������������������������������������������������������������������������������0000644�0001762�0000144�00000003351�14634573316�014263� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������find_template <- function(type, name, ext = ".html", pkg = ".") { pkg <- as_pkgdown(pkg) paths <- template_candidates(type = type, name = name, ext = ext, pkg = pkg) existing <- paths[file_exists(paths)] if (length(existing) == 0) { tname <- paste0(type, "-", name) cli::cli_abort( "Can't find template for {.val {tname}}.", call = caller_env() ) } existing[[1]] } # Used for testing read_template_html <- function(type, name, pkg = list()) { if (is_list(pkg)) { # promote to a shell "pkgdown" object so we don't need a complete pkg class(pkg) <- "pkgdown" } path <- find_template(type = type, name = name, pkg = pkg) xml2::read_html(path) } template_candidates <- function(type, name, ext = ".html", pkg = list()) { paths <- c( path(pkg$src_path, "pkgdown", "templates"), templates_dir(pkg), path_pkgdown(paste0("BS", pkg$bs_version), "templates") ) names <- c(paste0(type, "-", name, ext), paste0(type, ext)) all <- expand.grid(paths, names) path(all[[1]], all[[2]]) } # Find directory where custom templates might live: # * path supplied in `template.path` # * package supplied in `template.package` # * templates in package itself templates_dir <- function(pkg = list(), call = caller_env()) { config_pluck_list(pkg, "template") path <- config_pluck_string(pkg, "template.path") package <- config_pluck_string(pkg, "template.package") if (!is.null(path)) { if (!dir_exists(path)) { cli::cli_abort("Can't find templates path: {src_path(path)}", call = call) } path_abs(path, start = pkg$src_path) } else if (!is.null(package)) { path_package_pkgdown("templates", package, pkg$bs_version) } else { path(pkg$src_path, "pkgdown", "templates") } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/build-home-index.R������������������������������������������������������������������������0000644�0001762�0000144�00000015315�14672347347�015427� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' @export #' @rdname build_home build_home_index <- function(pkg = ".", override = list(), quiet = TRUE) { pkg <- section_init(pkg, override = override) src_path <- path_index(pkg) dst_path <- path(pkg$dst_path, "index.html") data <- data_home(pkg) if (is.null(src_path)) { cli::cli_inform("Reading {.file DESCRIPTION}") data$index <- linkify(pkg$desc$get_field("Description", "")) } else { cli::cli_inform("Reading {src_path(path_rel(src_path, pkg$src_path))}") local_options_link(pkg, depth = 0L) data$index <- markdown_body(pkg, src_path) } cur_digest <- file_digest(dst_path) render_page(pkg, "home", data, "index.html", quiet = quiet) strip_header <- config_pluck_bool(pkg, "home.strip_header", default = FALSE) hide_badges <- pkg$development$mode == "release" && !pkg$development$in_dev update_html( dst_path, tweak_homepage_html, strip_header = strip_header, sidebar = !isFALSE(pkg$meta$home$sidebar), show_badges = !hide_badges, bs_version = pkg$bs_version, logo = logo_path(pkg, depth = 0) ) new_digest <- file_digest(dst_path) if (cur_digest != new_digest) { writing_file(path_rel(dst_path, pkg$dst_path), "index.html") } invisible() } path_index <- function(pkg) { path_first_existing( pkg$src_path, c("pkgdown/index.md", "index.md", "README.md" ) ) } data_home <- function(pkg = ".", call = caller_env()) { pkg <- as_pkgdown(pkg) config_pluck_list(pkg, "home", call = call) title <- config_pluck_string( pkg, "home.title", default = cran_unquote(pkg$desc$get_field("Title", "")), call = call ) description <- config_pluck_string( pkg, "home.description", default = cran_unquote(pkg$desc$get_field("Description", "")), call = call ) trailing_slash <- config_pluck_bool( pkg, "template.trailing_slash_redirect", default = FALSE, call = call ) print_yaml(list( pagetitle = title, sidebar = data_home_sidebar(pkg, call = call), opengraph = list(description = description), has_trailingslash = trailing_slash )) } data_home_sidebar <- function(pkg = ".", call = caller_env()) { pkg <- as_pkgdown(pkg) sidebar <- config_pluck(pkg, "home.sidebar") if (isFALSE(sidebar)) { return(FALSE) } config_pluck_list(pkg, "home", call = call) html_path <- config_pluck_string(pkg, "home.sidebar.html", call = call) if (!is.null(html_path)) { html_path_abs <- path(pkg$src_path, html_path) if (!file_exists(html_path_abs)) { msg <- "{.field home.sidebar.html} specifies a file that doesn't exist ({.file {html_path}})." config_abort(pkg, msg, call = call) } return(read_file(html_path_abs)) } structure <- config_pluck_character( pkg, "home.sidebar.structure", default = default_sidebar_structure(), call = call ) # compute all default sections default_components <- list( links = data_home_sidebar_links(pkg), license = data_home_sidebar_license(pkg), community = data_home_sidebar_community(pkg), citation = data_home_sidebar_citation(pkg), authors = data_home_sidebar_authors(pkg), dev = sidebar_section(tr_("Dev Status"), "placeholder", class = "dev-status"), toc = data_home_toc(pkg) ) needs_components <- setdiff(structure, names(default_components)) custom_yaml <- config_pluck_sidebar_components(pkg, needs_components, call = call) custom_components <- purrr::map(custom_yaml, function(x) { sidebar_section(x$title, markdown_text_block(pkg, x$text)) }) components <- modify_list(default_components, custom_components) sidebar <- purrr::compact(components[structure]) paste0(sidebar, collapse = "\n") } # Update sidebar-configuration.Rmd if this changes default_sidebar_structure <- function() { c("links", "license", "community", "citation", "authors", "dev") } config_pluck_sidebar_components <- function(pkg, new_components, call = caller_env()) { base_path <- "home.sidebar.components" components <- config_pluck_list(pkg, base_path, has_names = new_components, call = call) for (name in names(components)) { component <- components[[name]] component_path <- paste0(base_path, ".", name) config_pluck_list(pkg, component_path, has_names = c("title", "text"), call = call) config_pluck_string(pkg, paste0(component_path, ".title"), call = call) config_pluck_string(pkg, paste0(component_path, ".text"), call = call) } components } data_home_sidebar_links <- function(pkg = ".") { pkg <- as_pkgdown(pkg) repo <- cran_link(pkg$package) links <- config_pluck(pkg, "home.links") bug_reports <- pkg$desc$get_field("BugReports", default = NULL) if (!is.null(bug_reports) && grepl("@", bug_reports) && !startsWith(bug_reports, "http")) { bug_reports <- paste0("mailto:", bug_reports) } links <- c( link_url(sprintf(tr_("View on %s"), repo$repo), repo$url), link_url(tr_("Browse source code"), repo_home(pkg)), link_url(tr_("Report a bug"), bug_reports), purrr::map_chr(links, ~ link_url(.$text, .$href)) ) sidebar_section(tr_("Links"), links) } data_home_toc <- function(pkg) { sidebar_section( tr_("Table of contents"), '<nav id="toc"></nav>' ) } sidebar_section <- function(heading, bullets, class = make_slug(heading)) { if (length(bullets) == 0) return(character()) paste0( "<div class='", class, "'>\n", "<h2 data-toc-skip>", heading, "</h2>\n", "<ul class='list-unstyled'>\n", paste0("<li>", bullets, "</li>\n", collapse = ""), "</ul>\n", "</div>\n" ) } cran_link <- function(pkg) { if (!has_internet()) { return(NULL) } cran_url <- paste0("https://cloud.r-project.org/package=", pkg) req <- httr2::request(cran_url) req <- req_pkgdown_cache(req) req <- httr2::req_error(req, function(resp) FALSE) resp <- httr2::req_perform(req) if (!httr2::resp_is_error(resp)) { return(list(repo = "CRAN", url = cran_url)) } # bioconductor always returns a 200 status, redirecting to /removed-packages/ bioc_url <- paste0("https://www.bioconductor.org/packages/", pkg) req <- httr2::request(bioc_url) req <- req_pkgdown_cache(req) req <- httr2::req_error(req, function(resp) FALSE) req <- httr2::req_retry(req, max_tries = 3) resp <- httr2::req_perform(req) if (!httr2::resp_is_error(resp) && !grepl("removed-packages", httr2::resp_url(resp))) { return(list(repo = "Bioconductor", url = bioc_url)) } NULL } req_pkgdown_cache <- function(req) { cache_path <- dir_create(path(tools::R_user_dir("pkgdown", "cache"), "http")) httr2::req_cache( req, path = cache_path, max_age = 86400 # 1 day ) } # authors forced to wrap words in '' to prevent spelling errors cran_unquote <- function(string) { gsub("\\'(.*?)\\'", "\\1", string) } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/navbar.R����������������������������������������������������������������������������������0000644�0001762�0000144�00000017511�14642014746�013535� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������data_navbar <- function(pkg = ".", depth = 0L, call = caller_env()) { pkg <- as_pkgdown(pkg) navbar <- config_pluck(pkg, "navbar") if (uses_lightswitch(pkg)) { style <- NULL } else { style <- navbar_style( navbar = navbar, theme = get_bslib_theme(pkg), bs_version = pkg$bs_version ) } links <- navbar_links(pkg, depth = depth, call = call) c(style, links) } uses_lightswitch <- function(pkg) { config_pluck_bool(pkg, "template.light-switch", default = FALSE) } # Default navbar ---------------------------------------------------------- navbar_style <- function(navbar = list(), theme = "_default", bs_version = 3) { if (bs_version == 3) { list(type = navbar$type %||% "default") } else { # bg is usually light, dark, or primary, but can use any .bg-* bg <- navbar$bg %||% bootswatch_bg[[theme]] %||% "light" type <- navbar$type %||% if (bg == "light") "light" else "dark" list(bg = bg, type = type) } } navbar_structure <- function() { print_yaml(list( left = c("intro", "reference", "articles", "tutorials", "news"), right = c("search", "github", "lightswitch") )) } navbar_links <- function(pkg, depth = 0L, call = caller_env()) { components <- navbar_link_components(pkg, call = call) list( left = render_navbar_links( components$left, depth = depth, pkg = pkg, side = "left" ), right = render_navbar_links( components$right, depth = depth, pkg = pkg, side = "right" ) ) } navbar_link_components <- function(pkg, call = caller_env()) { # Combine default components with user supplied: must not merge recursively components <- navbar_components(pkg) components_meta <- config_pluck(pkg, "navbar.components", default = list()) components[names(components_meta)] <- components_meta components <- purrr::compact(components) # Combine default structure with user supplied # (must preserve NULLs in yaml to mean display nothing) pkg$meta$navbar$structure <- modify_list( navbar_structure(), config_pluck(pkg, "navbar.structure") ) right_comp <- intersect( config_pluck_character(pkg, "navbar.structure.right", call = call), names(components) ) left_comp <- intersect( config_pluck_character(pkg, "navbar.structure.left", call = call), names(components) ) # Backward compatibility left <- config_pluck(pkg, "navbar.left") %||% components[left_comp] right <- config_pluck(pkg, "navbar.right") %||% components[right_comp] list(left = left, right = right) } render_navbar_links <- function(x, depth = 0L, pkg, side = c("left", "right")) { if (!is.list(x)) { config_abort( pkg, c( "{.field navbar} is incorrectly specified.", i = "See details in {.vignette pkgdown::customise}." ), call = quote(data_template()) ) } check_number_whole(depth, min = 0) side <- arg_match(side) tweak <- function(x) { if (!is.null(x$menu)) { x$menu <- lapply(x$menu, tweak) x } else if (!is.null(x$href) && !grepl("://", x$href, fixed = TRUE)) { x$href <- paste0(up_path(depth), x$href) x } else { x } } if (depth != 0L) { x <- lapply(x, tweak) } if (pkg$bs_version == 3) { rmarkdown::navbar_links_html(x) } else { navbar_html_list(x, path_depth = depth, side = side) } } # Components -------------------------------------------------------------- navbar_components <- function(pkg = ".") { pkg <- as_pkgdown(pkg) menu <- list() menu$reference <- menu_link(tr_("Reference"), "reference/index.html") # in BS3, search is hardcoded in the template if (pkg$bs_version == 5) { menu$search <- menu_search() } if (uses_lightswitch(pkg)) { menu$lightswitch <- menu_submenu( text = NULL, icon = "fa-sun", label = tr_("Light switch"), id = "lightswitch", list( menu_theme(tr_("Light"), icon = "fa-sun", theme = "light"), menu_theme(tr_("Dark"), icon = "fa-moon", theme = "dark"), menu_theme(tr_("Auto"), icon = "fa-adjust", theme = "auto") ) ) } if (!is.null(pkg$tutorials)) { menu$tutorials <- menu_submenu( tr_("Tutorials"), menu_links(pkg$tutorials$title, pkg$tutorials$file_out) ) } menu$news <- navbar_news(pkg) menu$github <- switch( repo_type(pkg), github = menu_icon("fab fa-github fa-lg", repo_home(pkg), "GitHub"), gitlab = menu_icon("fab fa-gitlab fa-lg", repo_home(pkg), "GitLab"), NULL ) menu <- c(menu, navbar_articles(pkg)) print_yaml(menu) } navbar_articles <- function(pkg = ".") { pkg <- as_pkgdown(pkg) menu <- list() vignettes <- pkg$vignettes pkg_intro <- article_is_intro(vignettes$name, pkg$package) if (any(pkg_intro)) { intro <- vignettes[pkg_intro, , drop = FALSE] menu$intro <- menu_link(tr_("Get started"), intro$file_out) } if (!has_name(pkg$meta, "articles")) { vignettes <- vignettes[!pkg_intro, , drop = FALSE] menu$articles <- menu_submenu( tr_("Articles"), menu_links(vignettes$title, vignettes$file_out) ) } else { articles_index <- config_pluck(pkg, "articles") articles <- data_articles(pkg) navbar <- purrr::keep(articles_index, ~ has_name(.x, "navbar")) if (length(navbar) == 0) { # No articles to be included in navbar so just link to index menu$articles <- menu_link(tr_("Articles"), "articles/index.html") } else { sections <- purrr::imap(navbar, function(section, index) { idx <- select_topics( section$contents, articles, error_pkg = pkg, error_path = paste0("articles[", index, "].contents") ) vig <- articles[idx, , drop = FALSE] vig <- vig[vig$name != pkg$package, , drop = FALSE] c( if (!is.null(section$navbar)) list(menu_separator(), menu_heading(section$navbar)), menu_links(vig$title, vig$href) ) }) children <- unlist(sections, recursive = FALSE, use.names = FALSE) if (length(navbar) != length(articles_index)) { children <- c( children, list( menu_separator(), menu_link(tr_("More articles..."), "articles/index.html") ) ) } menu$articles <- menu_submenu(tr_("Articles"), children) } } print_yaml(menu) } # Testing helpers --------------------------------------------------------- # Simulate minimal package structure so we can more easily test pkg_navbar <- function(meta = NULL, vignettes = pkg_navbar_vignettes(), github_url = NULL) { structure( list( package = "test", src_path = file_temp(), meta = meta, vignettes = vignettes, repo = list(url = list(home = github_url)), bs_version = 5 ), class = "pkgdown" ) } pkg_navbar_vignettes <- function(name = character(), title = NULL, file_out = NULL) { title <- title %||% paste0("Title ", name) file_out <- file_out %||% paste0(name, ".html") tibble::tibble(name = name, title = title, file_out, description = "desc") } # bootswatch defaults ----------------------------------------------------- # Scraped from bootswatch preivews, see code in # <https://github.com/r-lib/pkgdown/issues/1758> bootswatch_bg <- list( "_default" = "light", cerulean = "primary", cosmo = "primary", cyborg = "dark", darkly = "primary", flatly = "primary", journal = "light", litera = "light", lumen = "light", lux = "light", materia = "primary", minty = "primary", morph = "primary", pulse = "primary", quartz = "primary", sandstone = "primary", simplex = "light", sketchy = "light", slate = "primary", solar = "dark", spacelab = "light", superhero = "dark", united = "primary", vapor = "primary", yeti = "primary", zephyr = "primary" ) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/build-footer.R����������������������������������������������������������������������������0000644�0001762�0000144�00000003074�14633374223�014655� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������data_footer <- function(pkg = ".", call = caller_env()) { pkg <- as_pkgdown(pkg) config_pluck_list(pkg, "footer", call = call) meta_components <- config_pluck_list(pkg, "footer.components", call = call) components <- modify_list(footnote_components(pkg, call = call), meta_components) meta_structure <- config_pluck_list(pkg, "footer.structure", call = call) structure <- modify_list(footnote_structure(), meta_structure) left <- markdown_text_block(pkg, paste0(components[structure$left], collapse = " ")) right <- markdown_text_block(pkg, paste0(components[structure$right], collapse = " ")) list(left = left, right = right) } footnote_components <- function(pkg = ".", call = caller_env()) { pkg <- as_pkgdown(pkg) # Authors roles <- config_pluck_character( pkg, "authors.footer.roles", default = default_roles(), call = call ) authors <- data_authors(pkg, roles = roles)$main authors_str <- paste(purrr::map_chr(authors, "name"), collapse = ", ") prefix <- config_pluck_string( pkg, "authors.footer.text", default = tr_("Developed by"), call = call ) developed_by <- paste0(trimws(prefix), " ", authors_str, ".") # pkgdown built_with <- sprintf( tr_('Site built with <a href="%s">pkgdown</a> %s.'), "https://pkgdown.r-lib.org/", utils::packageVersion("pkgdown") ) print_yaml(list( developed_by = developed_by, built_with = built_with, package = pkg[["package"]] )) } footnote_structure <- function() { print_yaml(list( left = "developed_by", right = "built_with" )) } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/pkgdown.R���������������������������������������������������������������������������������0000644�0001762�0000144�00000000670�14634573316�013737� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' Determine if code is executed by pkgdown #' #' This is occasionally useful when you need different behaviour by #' pkgdown and regular documentation. #' #' @export #' @examples #' in_pkgdown() in_pkgdown <- function() { identical(Sys.getenv("IN_PKGDOWN"), "true") } local_envvar_pkgdown <- function(pkg, scope = parent.frame()) { withr::local_envvar( IN_PKGDOWN = "true", LANGUAGE = pkg$lang, .local_envir = scope ) } ������������������������������������������������������������������������pkgdown/R/rd-example.R������������������������������������������������������������������������������0000644�0001762�0000144�00000013050�14671042466�014316� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������rd2ex <- function(x, ...) { x <- rd_text(paste0("\\examples{", x, "}"), fragment = FALSE)[[1]] x <- process_conditional_examples(x) x <- flatten_ex(x, ...) if (grepl("\n", x)) { strsplit(x, "\n")[[1]] } else { x } } run_examples <- function(x, topic = "unknown", env = globalenv(), run_dont_run = FALSE) { if (!inherits(x, "tag")) { x <- rd_text(x) } # Trim newline that usually occurs after \examples{ if (is_newline(x[[1]], trim = TRUE)) { x <- x[-1] } x <- process_conditional_examples(x) code <- flatten_ex(x, run_dont_run = run_dont_run) if (!can_parse(code)) { cli::cli_warn("Failed to parse example for topic {.val {topic}}") return("") } if (!is.null(env)) { highlight_examples(code, topic, env = env) } else { highlight_text(code) } } process_conditional_examples <- function(rd) { if (is.list(rd)) { which_exif <- which(purrr::map_lgl(rd, function(x) { "tag_dontshow" %in% class(x) && is.character(x[[1]]) && grepl("# examplesIf$", x[[1]]) })) if (length(which_exif) == 0) return(rd) if (length(which_exif) %% 2 != 0) { cli::cli_abort("@examplesIf error, not closed?", call = caller_env()) } remove <- integer() modes <- c("begin", "end") for (idx in which_exif) { if (rd[[idx]] != "}) # examplesIf") { # Start of @examplesIf if (modes[1] == "end") { cli::cli_abort("@examplesIf error, not closed?", call = caller_env()) } cond_expr <- parse(text = paste0(rd[[idx]], "\n})"))[[1]][[2]] cond <- eval(cond_expr) if (isTRUE(cond)) { remove <- c(remove, idx, idx + 1L) } else { cond_expr_str <- deparse1(cond_expr) is_false <- cond_expr_str == "FALSE" if (!is_false) { new_cond <- paste0("if (FALSE) { # ", cond_expr_str) cli::cli_warn( "@examplesIf condition {.val {cond_expr_str}} is {.val FALSE}" ) } else { new_cond <- "if (FALSE) {" } rd[[idx]] <- structure(list(new_cond), class = c("RCODE", "tag")) } } else { # End of @examplesIf if (modes[1] == "begin") { cli::cli_abort("@examplesIf error, closed twice?", call = caller_env()) } if (isTRUE(cond)) { remove <- c(remove, idx, idx + 1L) } else { rd[[idx]] <- structure(list("}"), class = c("RCODE", "tag")) } } modes <- rev(modes) } if (length(remove)) rd <- rd[-remove] rd } else { rd } } # as_example -------------------------------------------------------------- as_example <- function(x, run_dont_run = FALSE) { UseMethod("as_example") } #' @export as_example.RCODE <- function(x, run_dont_run = FALSE) as.character(x) #' @export as_example.VERB <- as_example.RCODE #' @export as_example.TEXT <- as_example.RCODE #' @export as_example.COMMENT <- function(x, run_dont_run = FALSE) { if (grepl("^%[^ ]*%", x)) { meant <- gsub("%", "\\\\%", x) xun <- unclass(x) cli::cli_warn(c( "In the examples, {.val {xun}} is an Rd comment", "x" = "did you mean {.val {meant}}?" )) } "" } #' @export as_example.tag_dontrun <- function(x, run_dont_run = FALSE) { if (run_dont_run) { block_tag_to_comment("\\dontrun", x, run_dont_run = run_dont_run) } else { ex <- flatten_ex(x, run_dont_run = run_dont_run) if (is_newline(x[[1]], trim = TRUE)) { paste0("if (FALSE) { # \\dontrun{", ex, "} # }") } else { paste0("if (FALSE) ", ex, " # \\dontrun{}") } } } #' @export as_example.tag_donttest <- function(x, run_dont_run = FALSE) { block_tag_to_comment("\\donttest", x, run_dont_run = run_dont_run) } #' @export as_example.tag_dontshow <- function(x, run_dont_run = FALSE) { ex <- flatten_ex(x, run_dont_run = run_dont_run) paste0("DONTSHOW({", ex, "})") } #' @export as_example.tag_testonly <- function(x, run_dont_run = FALSE) { ex <- flatten_ex(x, run_dont_run = run_dont_run) paste0("TESTONLY({", ex, "})") } block_tag_to_comment <- function(tag, x, run_dont_run = FALSE) { ex <- flatten_ex(x, run_dont_run = run_dont_run) # Not easy to strip leading whitespace because it's attached to the previous # tag. So instead we add a comment to occupy that space if (is_newline(x[[1]], trim = TRUE)) { ex <- paste0("# ", tag, "{", ex, "# }") } ex } #' @export as_example.tag <- function(x, run_dont_run = FALSE) { untag <- paste(class(x), collapse = "/") cli::cli_warn("Unknown tag: {.val {untag}}") } #' @export as_example.tag_dots <- function(x, run_dont_run = FALSE) { "..." } #' @export as_example.tag_ldots <- as_example.tag_dots #' @export as_example.tag_if <- function(x, run_dont_run = FALSE) { if (x[[1]] == "html") { flatten_ex(x[[2]], run_dont_run = run_dont_run) } else { "" } } #' @export as_example.tag_ifelse <- function(x, run_dont_run = FALSE) { if (x[[1]] == "html") { flatten_ex(x[[2]], run_dont_run = run_dont_run) } else { flatten_ex(x[[3]], run_dont_run = run_dont_run) } } #' @export as_example.tag_out <- function(x, run_dont_run = FALSE) { flatten_ex(x, run_dont_run = run_dont_run) } # Helpers ----------------------------------------------------------------- flatten_ex <- function(x, run_dont_run = FALSE) { out <- purrr::map_chr(x, as_example, run_dont_run = run_dont_run) paste(out, collapse = "") } can_parse <- function(x) { tryCatch({ parse(text = x) TRUE }, error = function(e) FALSE) } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/external-deps.R���������������������������������������������������������������������������0000644�0001762�0000144�00000011053�14633374223�015031� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������external_dependencies <- function(pkg, call = caller_env()) { purrr::compact(list( fontawesome::fa_html_dependency(), cached_dependency( name = "headroom", version = "0.11.0", files = list( list( url = "https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/headroom.min.js", integrity = "sha256-AsUX4SJE1+yuDu5+mAVzJbuYNPHj/WroHuZ8Ir/CkE0=" ), list( url = "https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/jQuery.headroom.min.js", integrity = "sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4=" ) ) ), cached_dependency( name = "bootstrap-toc", version = "1.0.1", files = list( list( url = "https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@v1.0.1/dist/bootstrap-toc.min.js", integrity = "sha256-4veVQbu7//Lk5TSmc7YV48MxtMy98e26cf5MrgZYnwo=" ) ) ), cached_dependency( name = "clipboard.js", version = "2.0.11", files = list( list( url = "https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.11/clipboard.min.js", integrity = "sha512-7O5pXpc0oCRrxk8RUfDYFgn0nO1t+jLuIOQdOMRp4APB7uZ4vSjspzp5y6YDtDs4VzUSTbWzBFZ/LKJhnyFOKw==" ) ) ), cached_dependency( name = "search", version = "1.0.0", files = list( list( url = "https://cdnjs.cloudflare.com/ajax/libs/fuse.js/6.4.6/fuse.min.js", integrity = "sha512-KnvCNMwWBGCfxdOtUpEtYgoM59HHgjHnsVGSxxgz7QH1DYeURk+am9p3J+gsOevfE29DV0V+/Dd52ykTKxN5fA==" ), list( url = "https://cdnjs.cloudflare.com/ajax/libs/autocomplete.js/0.38.0/autocomplete.jquery.min.js", integrity = "sha512-GU9ayf+66Xx2TmpxqJpliWbT5PiGYxpaG8rfnBEk1LL8l1KGkRShhngwdXK1UgqhAzWpZHSiYPc09/NwDQIGyg==" ), list( url = "https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/mark.min.js", integrity = "sha512-5CYOlHXGh6QpOFA/TeTylKLWfB3ftPsde7AnmhuitiTX4K5SqCLBeKro6sPS8ilsz1Q4NRx3v8Ko2IBiszzdww==" ) ) ), math_dependency(pkg, call = call) )) } math_dependency <- function(pkg, call = caller_env()) { math <- config_math_rendering(pkg) if (math == "mathjax") { cached_dependency( name = "MathJax", version = "3.2.2", files = list( list( url = "https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-chtml.min.js", integrity = "sha512-T8xxpazDtODy3WOP/c6hvQI2O9UPdARlDWE0CvH1Cfqc0TXZF6GZcEKL7tIR8VbfS/7s/J6C+VOqrD6hIo++vQ==" ) ) ) } else if (math == "katex") { cached_dependency( name = "KaTex", version = "0.16.10", files = list( list( url = "https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.js", integrity = "sha384-hIoBPJpTUs74ddyc4bFZSM1TVlQDA60VBbJS0oA934VSz82sBx1X7kSx2ATBDIyd" ), list( url = "https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.css", integrity = "sha384-wcIxkf4k558AjM3Yz3BBFQUbk/zgIYC2R0QpeeYb+TwlBVMrlgLqwRjRtGZiK7ww" ) ) ) } else { NULL } } cached_dependency <- function(name, version, files) { cache_dir <- path(tools::R_user_dir("pkgdown", "cache"), name, version) dir_create(cache_dir) for (file in files) { cache_path <- path(cache_dir, path_file(file$url)) if (!file_exists(cache_path)) { utils::download.file(file$url, cache_path, quiet = TRUE, mode = "wb") check_integrity(cache_path, file$integrity) } } dep_files <- path_rel(dir_ls(cache_dir), cache_dir) htmltools::htmlDependency( name = name, version = version, src = cache_dir, script = dep_files[path_ext(dep_files) == "js"], stylesheet = dep_files[path_ext(dep_files) == "css"] ) } check_integrity <- function(path, integrity) { parsed <- parse_integrity(integrity) if (!parsed$size %in% c(256L, 384L, 512L)) { cli::cli_abort( "{.field integrity} must use SHA-256, SHA-384, or SHA-512", .internal = TRUE ) } hash <- compute_hash(path, parsed$size) if (hash != parsed$hash) { cli::cli_abort( "Downloaded asset does not match known integrity", .internal = TRUE ) } invisible() } compute_hash <- function(path, size) { con <- file(path, encoding = "UTF-8") openssl::base64_encode(openssl::sha2(con, size)) } parse_integrity <- function(x) { size <- as.integer(regmatches(x, regexpr("(?<=^sha)\\d{3}", x, perl = TRUE))) hash <- regmatches(x, regexpr("(?<=^sha\\d{3}-).+", x, perl = TRUE)) list(size = size, hash = hash) } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/tweak-page.R������������������������������������������������������������������������������0000644�0001762�0000144�00000006431�14657466716�014326� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# File level tweaks -------------------------------------------- tweak_page <- function(html, name, pkg = list(bs_version = 3)) { # Syntax highlighting and linking if (name == "reference-topic") { # Reference topic takes a minimal approach since some is # already handled by Rd processing tweak_reference_highlighting(html) tweak_extra_logo(html) } else { downlit::downlit_html_node(html) # Rescue highlighting of non-collapsed output - needed for ANSI escapes pre <- xml2::xml_find_all(html, ".//pre[not(contains(@class, 'downlit'))]") is_wrapped <- is_wrapped_pre(pre) purrr::walk(pre[!is_wrapped], tweak_highlight_r) } tweak_anchors(html) tweak_link_md(html) tweak_link_external(html, pkg = pkg) tweak_img_src(html) tweak_strip(html, !identical(pkg$development$mode, "release")) # BS3 uses table for layout of reference-index if (name != "reference-index") { tweak_tables(html) } if (pkg$bs_version > 3) { tweak_footnotes(html) tweak_tabsets(html) tweak_useless_toc(html) } if (!is.null(pkg$desc) && pkg$desc$has_dep("R6")) { tweak_link_R6(html, pkg$package) } } tweak_rmarkdown_html <- function(html, input_path, pkg = list(bs_version = 3)) { # Tweak classes of navbar toc <- xml2::xml_find_all(html, ".//div[@id='tocnav']//ul") xml2::xml_attr(toc, "class") <- "nav nav-pills nav-stacked" # Make sure all images use relative paths img <- xml2::xml_find_all(html, "//img") src <- xml2::xml_attr(img, "src") abs_src <- is_absolute_path(src) if (any(abs_src)) { img_target_nodes <- img[abs_src] img_src_real <- path_real(xml2::url_unescape(src[abs_src])) input_path_real <- path_real(xml2::url_unescape(input_path)) img_rel_paths <- path_rel(path = img_src_real, start = input_path_real) img_rel_paths <- xml2::url_escape(img_rel_paths) purrr::walk2( .x = img_target_nodes, .y = img_rel_paths, .f = xml2::xml_set_attr, attr = "src" ) } # If top-level headings use h1, move everything down one level h1 <- xml2::xml_find_all(html, "//h1") if (length(h1) > 1) { tweak_section_levels(html) } # Has to occur after path normalisation # This get called twice on the contents of content-article.html, but that # should be harmless tweak_page(html, "article", pkg = pkg) invisible() } # Strip off #toc if it's not needed; easier to do this here than in js tweak_useless_toc <- function(html) { contents <- xml2::xml_find_all(html, ".//main") headings <- xml2::xml_find_all(contents, ".//h2|.//h3|.//h4|.//h5|.//h6") if (length(headings) > 1) { return() } toc <- xml2::xml_find_first(html, '//nav[@id="toc"]') sidebar <- xml2::xml_parent(toc) if (length(xml2::xml_children(sidebar)) == 1) { xml2::xml_remove(sidebar) } else { xml2::xml_remove(toc) } } # Update file on disk ----------------------------------------------------- update_html <- function(path, tweak, ...) { raw <- read_file(path) # Following the xml 1.0 spec, libxml2 drops low-bit ASCII characters # so we convert to \u2029, relying on downlit to convert back in # token_escape(). raw <- gsub("\033", "\u2029", raw, fixed = TRUE) html <- xml2::read_html(raw, encoding = "UTF-8") tweak(html, ...) xml2::write_html(html, path, format = FALSE) path } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/development.R�����������������������������������������������������������������������������0000644�0001762�0000144�00000003552�14633374223�014605� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������meta_development <- function(pkg, call = caller_env()) { config_pluck_list(pkg, "development", call = call) mode <- dev_mode(pkg, call = call) destination <- config_pluck_string(pkg, "development.destination", default = "dev", call = call) version_label <- config_pluck_string(pkg, "development.version_label", call = call) if (is.null(version_label)) { if (mode %in% c("release", "default")) { version_label <- if (pkg$bs_version == 3) "default" else "muted" } else { version_label <- "danger" } } in_dev <- mode == "devel" list( destination = destination, mode = mode, version_label = version_label, in_dev = in_dev, prefix = if (in_dev) paste0(destination, "/") else "" ) } dev_mode <- function(pkg, call = caller_env()) { mode <- Sys.getenv("PKGDOWN_DEV_MODE") if (identical(mode, "")) { mode <- config_pluck_string(pkg, "development.mode", default = "default", call = call) } if (mode == "auto") { mode <- dev_mode_auto(pkg$version) } else { valid_mode <- c("auto", "default", "release", "devel", "unreleased") if (!mode %in% valid_mode) { msg <- "{.field development.mode} must be one of {.or {valid_mode}}, not {mode}." config_abort(pkg, msg, call = call) } } mode } dev_mode_auto <- function(version) { version <- unclass(package_version(version))[[1]] if (length(version) < 3) { "release" } else if (length(version) == 3) { if (version[3] >= 9000) { "devel" } else { "release" } } else if (identical(version[1:3], c(0L, 0L, 0L))) { "unreleased" } else { "devel" } } # Called in render_page() so that LANG env var set up version_tooltip <- function(mode) { switch(mode, default = "", release = tr_("Released version"), devel = tr_("In-development version"), unreleased = tr_("Unreleased version") ) } ������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/build-reference-index.R�������������������������������������������������������������������0000644�0001762�0000144�00000011056�14641302547�016420� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������data_reference_index <- function(pkg = ".", error_call = caller_env()) { pkg <- as_pkgdown(pkg) meta <- config_pluck_reference(pkg, error_call) if (length(meta) == 0) { return(list()) } rows <- unwrap_purrr_error(purrr::imap(meta, data_reference_index_rows, pkg = pkg, call = error_call)) rows <- purrr::list_c(rows) has_icons <- purrr::some(rows, ~ .x$row_has_icons %||% FALSE) check_missing_topics(rows, pkg, error_call = error_call) rows <- Filter(function(x) !x$is_internal, rows) print_yaml(list( pagetitle = tr_("Package index"), rows = rows, has_icons = has_icons )) } config_pluck_reference <- function(pkg, call = caller_env()) { ref <- config_pluck_list(pkg, "reference", default = default_reference_index(pkg)) for (i in seq_along(ref)) { section <- ref[[i]] config_check_list( section, error_path = paste0("reference[", i, "]"), error_pkg = pkg, error_call = call ) config_check_string( section$title, error_path = paste0("reference[", i, "].title"), error_pkg = pkg, error_call = call ) config_check_string( section$subtitle, error_path = paste0("reference[", i, "].subtitle"), error_pkg = pkg, error_call = call ) if (has_name(section, "contents")) { check_contents(section$contents, i, pkg, prefix = "reference", call = call) } } ref } check_contents <- function(contents, index, pkg, prefix, call = caller_env()) { if (length(contents) == 0) { config_abort(pkg, "{.field {prefix}[{index}].contents} is empty.", call = call) } is_null <- purrr::map_lgl(contents, is.null) if (any(is_null)) { j <- which(is_null)[1] config_abort(pkg, "{.field {prefix}[{index}].contents[{j}]} is empty.", call = call) } is_char <- purrr::map_lgl(contents, is.character) if (!all(is_char)) { j <- which(!is_char)[1] config_abort( pkg, c( "{.field {prefix}[{index}].contents[{j}]} must be a string.", i = "You might need to add '' around special YAML values like 'N' or 'off'" ), call = call ) } } data_reference_index_rows <- function(section, index, pkg, call = caller_env()) { is_internal <- identical(section$title, "internal") rows <- list() if (has_name(section, "title")) { rows[[1]] <- list( title = markdown_text_inline( pkg, section$title, error_path = paste0("reference[", index, "].title"), error_call = call ), slug = make_slug(section$title), desc = markdown_text_block(pkg, section$desc), is_internal = is_internal ) } if (has_name(section, "subtitle")) { rows[[2]] <- list( subtitle = markdown_text_inline( pkg, section$subtitle, error_path = paste0("reference[", index, "].subtitle"), error_call = call ), slug = make_slug(section$subtitle), desc = markdown_text_block(pkg, section$desc), is_internal = is_internal ) } if (has_name(section, "contents")) { topics <- section_topics(pkg, section$contents, error_path = paste0("reference[", index, "].contents"), error_call = call ) names <- topics$name topics$name <- NULL rows[[3]] <- list( topics = purrr::transpose(topics), names = names, row_has_icons = !purrr::every(topics$icon, is.null), is_internal = is_internal ) } purrr::compact(rows) } find_icons <- function(x, path) { purrr::map(x, find_icon, path = path) } find_icon <- function(aliases, path) { names <- paste0(aliases, ".png") exists <- file_exists(path(path, names)) if (!any(exists)) { NULL } else { names[which(exists)[1]] } } default_reference_index <- function(pkg = ".") { pkg <- as_pkgdown(pkg) exported <- pkg$topics[!pkg$topics$internal, , drop = FALSE] if (nrow(exported) == 0) { return(list()) } print_yaml(list( list( title = tr_("All functions"), contents = auto_quote(unname(exported$name)) ) )) } check_missing_topics <- function(rows, pkg, error_call = caller_env()) { # Cross-reference complete list of topics vs. topics found in index page all_topics <- purrr::list_c(purrr::map(rows, "names")) in_index <- pkg$topics$name %in% all_topics missing <- !in_index & !pkg$topics$internal if (any(missing)) { config_abort( pkg, c( "{sum(missing)} topic{?s} missing from index: {.val {pkg$topics$name[missing]}}.", i = "Either use {.code @keywords internal} to drop from index, or" ), call = error_call ) } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/build-home-community.R��������������������������������������������������������������������0000644�0001762�0000144�00000001664�14633374223�016334� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������has_contributing <- function(path = ".") { file_exists(path(path, 'CONTRIBUTING.md')) || file_exists(path(path, '.github', 'CONTRIBUTING.md')) } has_coc <- function(path = ".") { file_exists(path(path, 'CODE_OF_CONDUCT.md')) || file_exists(path(path, '.github', 'CODE_OF_CONDUCT.md')) } has_support <- function(path = ".") { file_exists(path(path, 'SUPPORT.md')) || file_exists(path(path, '.github', 'SUPPORT.md')) } data_home_sidebar_community <- function (pkg){ pkg <- as_pkgdown(pkg) links <- NULL if (has_contributing(pkg$src_path)) { links <- c(links, a(tr_("Contributing guide"), "CONTRIBUTING.html")) } if (has_coc(pkg$src_path)) { links <- c(links, a(tr_("Code of conduct"), "CODE_OF_CONDUCT.html")) } if (has_support(pkg$src_path)) { links <- c(links, a(tr_("Getting help"), "SUPPORT.html")) } if (is.null(links)) { return("") } sidebar_section(tr_("Community"), links) } ����������������������������������������������������������������������������pkgdown/R/usage.R�����������������������������������������������������������������������������������0000644�0001762�0000144�00000015430�14653152407�013365� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Reference page --------------------------------------------------------------- # For testing usage2text <- function(x) { rd <- rd_text(paste0("\\usage{", x, "}"), FALSE)[[1]] strip_html_tags(as_data(rd)) } #' @export as_data.tag_usage <- function(x, ...) { text <- paste(flatten_text(x, ..., escape = FALSE), collapse = "\n") text <- str_trim(text) # Look for single line calls to non-syntactic functions (except for `=` # since that's probably a single argument on its own line) and then use # deparse1 to convert to standard style. We want to avoid reparsing # any other lines to avoid losing whitespace, comments etc. (These # are not generated by roxygen but can be added by the user.) lines <- strsplit(text, "\n", fixed = TRUE)[[1]] parsed <- lapply(lines, function(x) tryCatch(parse(text = x)[[1]], error = function(e) NULL)) needs_tweak <- function(x) { is_call(x) && !is_call(x, "=") && (is_symbol(x[[1]]) && !is_syntactic(x[[1]])) } to_tweak <- vapply(parsed, needs_tweak, logical(1)) lines[to_tweak] <- vapply(parsed[to_tweak], deparse1, character(1)) text <- paste(lines, collapse = "\n") highlight_text(text) } #' @export as_html.tag_method <- function(x, ...) method_usage(x, "S3") #' @export as_html.tag_S3method <- function(x, ...) method_usage(x, "S3") #' @export as_html.tag_S4method <- function(x, ...) method_usage(x, "S4") method_usage <- function(x, type) { # Despite these being called from the as_html() generic, the target isn't # actually HTML, but R code, which is turned into HTML by the syntax # highlighting in as as_data.tag_usage() fun <- as_html(x[[1]], escape = FALSE) class <- as_html(x[[2]], escape = FALSE) if (x[[2]] == "default") { method <- sprintf(tr_("# Default %s method"), type) } else { method <- sprintf(tr_("# %s method for class '%s'"), type, class) } if (!is_syntactic(fun)) { fun <- paste0("`", fun, "`") } paste0(method, "\n", fun) } # Reference index -------------------------------------------------------------- topic_funs <- function(rd) { funs <- parse_usage(rd) # Remove all methods for generics documented in this file name <- purrr::map_chr(funs, "name") type <- purrr::map_chr(funs, "type") gens <- name[type == "fun"] self_meth <- (name %in% gens) & (type %in% c("s3", "s4")) funs <- purrr::map_chr(funs[!self_meth], ~ short_name(.$name, .$type, .$signature)) unique(funs) } parse_usage <- function(x) { if (!inherits(x, "tag")) { usage <- paste0("\\usage{", x, "}") x <- rd_text(usage, fragment = FALSE) } r <- usage_code(x) if (length(r) == 0) { return(list()) } exprs <- tryCatch( parse_exprs(r), error = function(e) { cli::cli_warn("Failed to parse usage: {.code {r}}") list() } ) purrr::map(exprs, usage_type) } short_name <- function(name, type, signature) { name <- escape_html(name) qname <- auto_quote(name) if (type == "data") { qname } else if (type == "fun") { if (is_infix(name)) { qname } else { paste0(qname, "()") } } else { sig <- paste0("<i><", escape_html(signature), "></i>", collapse = ",") paste0(qname, "(", sig, ")") } } # Given single expression generated from usage_code, extract usage_type <- function(x) { if (is_symbol(x)) { list(type = "data", name = as.character(x)) } else if (is_call(x, "data")) { list(type = "data", name = as.character(x[[2]])) } else if (is.call(x)) { if (identical(x[[1]], quote(`<-`))) { replacement <- TRUE x <- x[[2]] } else { replacement <- FALSE } out <- fun_info(x) out$replacement <- replacement out$infix <- is_infix(out$name) if (replacement) { out$name <- paste0(out$name, "<-") } out } else { untype <- paste0(typeof(x), " (in ", as.character(x), ")") cli::cli_abort( "Unknown type: {.val {untype}}", call = caller_env() ) } } is_infix <- function(x) { if (is.null(x)) { return(FALSE) } x <- as.character(x) ops <- c( "+", "-", "*", "^", "/", "==", ">", "<", "!=", "<=", ">=", "&", "|", "[[", "[", "$" ) grepl("^%.*%$", x) || x %in% ops } fun_info <- function(fun) { stopifnot(is.call(fun)) if (is.call(fun[[1]])) { x <- fun[[1]] if (identical(x[[1]], quote(S3method))) { list( type = "s3", name = as.character(x[[2]]), signature = as.character(x[[3]]) ) } else if (identical(x[[1]], quote(S4method))) { list( type = "s4", name = as.character(x[[2]]), signature = sub("^`(.*)`$", "\\1", as.character(as.list(x[[3]])[-1])) ) } else if (is_call(x, c("::", ":::"))) { # TRUE if fun has a namespace, pkg::fun() list( type = "fun", name = call_name(fun) ) } else { cli::cli_abort( "Unknown call: {.val {as.character(x[[1]])}}", call = caller_env() ) } } else { list( type = "fun", name = as.character(fun[[1]]), signature = NULL ) } } # usage_code -------------------------------------------------------------- # Transform Rd embedded inside usage into parseable R code usage_code <- function(x) { UseMethod("usage_code") } #' @export usage_code.Rd <- function(x) { usage <- purrr::detect(x, inherits, "tag_usage") usage_code(usage) } #' @export usage_code.NULL <- function(x) character() # Tag without additional class use #' @export usage_code.tag <- function(x) { if (!identical(class(x), "tag")) { cli::cli_abort( "Undefined tag in usage: {.val class(x)[[1]]}}", call = caller_env() ) } paste0(purrr::flatten_chr(purrr::map(x, usage_code)), collapse = "") } #' @export usage_code.tag_special <- function(x) { paste0(purrr::flatten_chr(purrr::map(x, usage_code)), collapse = "") } #' @export usage_code.tag_dots <- function(x) "..." #' @export usage_code.tag_ldots <- function(x) "..." #' @export usage_code.TEXT <- function(x) as.character(x) #' @export usage_code.RCODE <- function(x) as.character(x) #' @export usage_code.VERB <- function(x) as.character(x) #' @export usage_code.COMMENT <- function(x) character() #' @export usage_code.tag_S3method <- function(x) { generic <- paste0(usage_code(x[[1]]), collapse = "") class <- paste0(usage_code(x[[2]]), collapse = "") paste0("S3method(`", generic, "`, ", class, ")") } #' @export usage_code.tag_method <- usage_code.tag_S3method #' @export usage_code.tag_S4method <- function(x) { generic <- paste0(usage_code(x[[1]]), collapse = "") class <- strsplit(usage_code(x[[2]]), ",")[[1]] class <- paste0("`", class, "`") class <- paste0(class, collapse = ",") paste0("S4method(`", generic, "`, list(", class, "))") } #' @export usage_code.tag_usage <- function(x) { paste0(purrr::flatten_chr(purrr::map(x, usage_code)), collapse = "") } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/theme.R�����������������������������������������������������������������������������������0000644�0001762�0000144�00000014740�14634573316�013373� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������build_bslib <- function(pkg = ".", call = caller_env()) { pkg <- as_pkgdown(pkg) bs_theme <- bs_theme(pkg, call = call) cur_deps <- find_deps(pkg) cur_digest <- purrr::map_chr(cur_deps, file_digest) deps <- c(bslib::bs_theme_dependencies(bs_theme), external_dependencies(pkg)) deps <- lapply(deps, htmltools::copyDependencyToDir, path(pkg$dst_path, "deps")) deps <- lapply(deps, htmltools::makeDependencyRelative, pkg$dst_path) new_deps <- find_deps(pkg) new_digest <- purrr::map_chr(cur_deps, file_digest) all_deps <- union(new_deps, cur_deps) diff <- (cur_digest[all_deps] == new_digest[all_deps]) changed <- all_deps[!diff | is.na(diff)] if (length(changed) > 0) { withr::local_locale(LC_COLLATE = "C") purrr::walk(sort(changed), function(dst) { cli::cli_inform("Updating {dst_path(path_rel(dst, pkg$dst_path))}") }) } head <- htmltools::renderDependencies(deps, srcType = "file") write_lines(head, data_deps_path(pkg)) } data_deps <- function(pkg, depth) { if (!file_exists(data_deps_path(pkg))) { # this is unlikely to occur after #2439 and #2571 cli::cli_abort( "Run {.fn pkgdown::init_site} first.", .internal = TRUE, call = caller_env() ) } deps_path <- paste0(up_path(depth), "deps") data_deps <- read_lines(data_deps_path(pkg)) data_deps <- gsub('src="deps', sprintf('src="%s', deps_path), data_deps) data_deps <- gsub('href="deps', sprintf('href="%s', deps_path), data_deps) paste0(data_deps, collapse = "") } data_deps_path <- function(pkg) { path(pkg$dst_path, "deps", "data-deps.txt") } find_deps <- function(pkg) { deps_path <- path(pkg$dst_path, "deps") if (!dir_exists(deps_path)) { character() } else { dir_ls(deps_path, type = "file", recurse = TRUE) } } bs_theme <- function(pkg = ".", call = caller_env()) { pkg <- as_pkgdown(pkg) bs_theme_args <- pkg$meta$template$bslib %||% list() bs_theme_args[["version"]] <- pkg$bs_version # In bslib >= 0.5.1, bs_theme() takes bootstrap preset theme via `preset` bs_theme_args[["preset"]] <- get_bslib_theme(pkg) bs_theme_args[["bootswatch"]] <- NULL bs_theme <- exec(bslib::bs_theme, !!!bs_theme_args) # Drop bs3 compat files added for shiny/RMarkdown bs_theme <- bslib::bs_remove(bs_theme, "bs3compat") # Add additional pkgdown rules rules <- bs_theme_rules(pkg, call = call) files <- lapply(rules, sass::sass_file) bs_theme <- bslib::bs_add_rules(bs_theme, files) # Add dark theme if needed if (uses_lightswitch(pkg)) { dark_theme <- config_pluck_string(pkg, "template.theme-dark", default = "arrow-dark") check_theme( dark_theme, error_pkg = pkg, error_path = "template.theme-dark", error_call = call ) path <- highlight_path(dark_theme) css <- c('[data-bs-theme="dark"] {', read_lines(path), '}') bs_theme <- bslib::bs_add_rules(bs_theme, css) } bs_theme } bs_theme_rules <- function(pkg, call = caller_env()) { paths <- path_pkgdown("BS5", "assets", "pkgdown.scss") theme <- config_pluck_string(pkg, "template.theme", default = "arrow-light") check_theme( theme, error_pkg = pkg, error_path = "template.theme", error_call = call ) paths <- c(paths, highlight_path(theme)) package <- config_pluck_string(pkg, "template.package") if (!is.null(package)) { package_extra <- path_package_pkgdown("extra.scss", package, pkg$bs_version) if (file_exists(package_extra)) { paths <- c(paths, package_extra) } } # Also look in site supplied site_extra <- path(pkg$src_path, "pkgdown", "extra.scss") if (file_exists(site_extra)) { paths <- c(paths, site_extra) } paths } check_theme <- function(theme, error_pkg, error_path, error_call = caller_env()) { if (theme %in% highlight_styles()) { return() } config_abort( error_pkg, "{.field {error_path}} uses theme {.val {theme}}", call = error_call ) } highlight_path <- function(theme) { path_pkgdown("highlight-styles", paste0(theme, ".scss")) } highlight_styles <- function() { paths <- dir_ls(path_pkgdown("highlight-styles"), glob = "*.scss") path_ext_remove(path_file(paths)) } get_bslib_theme <- function(pkg) { themes <- list( "template.bslib.preset" = pkg$meta[["template"]]$bslib$preset, "template.bslib.bootswatch" = pkg$meta[["template"]]$bslib$bootswatch, "template.bootswatch" = pkg$meta[["template"]]$bootswatch, # Historically (< 0.2.0), bootswatch wasn't a top-level template field "template.params.bootswatch" = pkg$meta[["template"]]$params$bootswatch ) is_present <- !purrr::map_lgl(themes, is.null) n_present <- sum(is_present) n_unique <- length(unique(themes[is_present])) if (n_present == 0) { return("default") } if (n_present > 1 && n_unique > 1) { cli::cli_warn(c( "Multiple Bootstrap preset themes were set. Using {.val {themes[is_present][[1]]}} from {.field {names(themes)[is_present][1]}}.", x = "Found {.and {.field {names(themes)[is_present]}}}.", i = "Remove extraneous theme declarations to avoid this warning." )) } field <- names(themes)[which(is_present)[1]] check_bslib_theme(themes[[field]], pkg, field) } check_bslib_theme <- function(theme, pkg, field = "template.bootswatch", bs_version = pkg$bs_version) { bslib_themes <- c( bslib::bootswatch_themes(bs_version), bslib::builtin_themes(bs_version), # bs_theme() recognizes both below as bare bootstrap "default", "bootstrap" ) if (theme %in% bslib_themes) { return(theme) } config_abort( pkg, c( x = "{.field {field}} contains unknown Bootswatch/bslib theme {.val {theme}}.", i = "Using Bootstrap version {.val {bs_version}} ({.field template.bootstrap})." ), call = caller_env() ) } bs_theme_deps_suppress <- function(deps = list()) { # jquery and bootstrap are provided by bslib # headr-attrs is included for pandoc 2.7.3 - 2.9.2.1 to improve accessibility # but includes javascript that breaks our HTML anchor system bs_dep_names <- c("jquery", "bootstrap", "header-attrs") bs_deps <- purrr::map(bs_dep_names, function(name) { # minimal version of htmltools::htmlDependency() (see suppressDependencies()) structure(list( name = name, version = "9999", src = list(href = ""), all_files = TRUE ), class = "html_dependency") }) c(deps, bs_deps) } ��������������������������������pkgdown/R/utils-pdf.R�������������������������������������������������������������������������������0000644�0001762�0000144�00000001611�14634573316�014171� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Set various env vars (copied from tools::texi2dvi) to ensure that # latex can find bib and style files in the right places local_texi2dvi_envvars <- function(input_path, env = caller_env()) { withr::local_envvar( BSTINPUTS = bst_paths(input_path), TEXINPUTS = tex_paths(input_path), BIBINPUTS = bib_paths(input_path), .local_envir = env ) } bst_paths <- function(path) { paths <- c( Sys.getenv("BSTINPUTS"), path_dir(path), path(R.home("share"), "texmf", "bibtex", "bst") ) paste(paths, collapse = .Platform$path.sep) } tex_paths <- function(path) { paths <- c( Sys.getenv("TEXINPUTS"), path_dir(path), path(R.home("share"), "texmf", "tex", "latex") ) paste(paths, collapse = .Platform$path.sep) } bib_paths <- function(path) { paths <- c( Sys.getenv("BIBINPUTS"), tex_paths(path) ) paste(paths, collapse = .Platform$path.sep) } �����������������������������������������������������������������������������������������������������������������������pkgdown/R/build-reference.R�������������������������������������������������������������������������0000644�0001762�0000144�00000031642�14634573316�015324� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' Build reference section #' #' By default, pkgdown will generate an index that lists all functions in #' alphabetical order. To override this, provide a `reference` section in your #' `_pkgdown.yml` as described below. #' #' # Reference index #' To tweak the index page, add a section called `reference` to `_pkgdown.yml`. #' It can contain three different types of element: #' #' * A **title** (`title` + `desc`), which generates an row containing an `<h2>` #' with optional paragraph description. #' * A **subtitle** (`subtitle` + `desc`), which generates an row containing an #' `<h3>` with optional paragraph description. #' * A **list of topics** (`contents`), which generates one row for each topic, #' with a list of aliases for the topic on the left, and the topic title #' on the right. #' #' (For historical reasons you can include `contents` with a title or #' subtitle, but this is no longer recommended). #' #' Most packages will only need to use `title` and `contents` components. #' For example, here's a snippet from the YAML that pkgdown uses to generate #' its own reference index: #' #' ```yaml #' reference: #' - title: Build #' desc: Build a complete site or its individual section components. #' - contents: #' - starts_with("build_") #' - title: Templates #' - contents: #' - template_navbar #' - render_page #' ``` #' #' Bigger packages, e.g. ggplot2, may need an additional layer of #' structure in order to clearly organise large number of functions: #' #' ```yaml #' reference: #' - title: Layers #' - subtitle: Geoms #' desc: Geom is short for geometric element #' - contents: #' - starts_with("geom") #' - subtitle: Stats #' desc: Statistical transformations transform data before display. #' contents: #' - starts_with("stat") #' ``` #' #' `desc` can use markdown, and if you have a long description it's a good #' idea to take advantage of the YAML `>` notation: #' #' ```yaml #' desc: > #' This is a very _long_ and **overly** flowery description of a #' single simple function. By using `>`, it's easy to write a description #' that runs over multiple lines. #' ``` #' #' ## Topic matching #' `contents` can contain: #' #' * Individual function/topic names. #' * Weirdly named functions with doubled quoting, once for YAML and once for #' R, e.g. `` "`+.gg`" ``. #' * `starts_with("prefix")` to select all functions with common prefix. #' * `ends_with("suffix")` to select all functions with common suffix. #' * `matches("regexp")` for more complex regular expressions. #' * `has_keyword("x")` to select all topics with keyword "x"; #' `has_keyword("datasets")` selects all data documentation. #' * `has_concept("blah")` to select all topics with concept "blah". #' If you are using roxygen2, `has_concept()` also matches family tags, because #' roxygen2 converts them to concept tags. #' * `lacks_concepts(c("concept1", "concept2"))` to select all topics #' without those concepts. This is useful to capture topics not otherwise #' captured by `has_concepts()`. #' * Topics from other installed packages, e.g. `rlang::is_installed()` (function name) #' or `sass::font_face` (topic name). #' * `has_lifecycle("deprecated")` will select all topics with lifecycle #' deprecated. #' #' All functions (except for `has_keyword()`) automatically exclude internal #' topics (i.e. those with `\keyword{internal}`). You can choose to include #' with (e.g.) `starts_with("build_", internal = TRUE)`. #' #' Use a leading `-` to remove topics from a section, e.g. `-topic_name`, #' `-starts_with("foo")`. #' #' pkgdown will check that all non-internal topics are included on #' the reference index page, and error if you have missed any. #' #' ## Missing topics #' #' pkgdown will warn if there are (non-internal) topics that not listed #' in the reference index. You can suppress these warnings by listing the #' topics in section with "title: internal" (case sensitive) which will not be #' displayed on the reference index. #' #' ## Icons #' You can optionally supply an icon for each help topic. To do so, you'll need #' a top-level `icons` directory. This should contain `.png` files that are #' either 30x30 (for regular display) or 60x60 (if you want retina display). #' Icons are matched to topics by aliases. #' #' # Examples #' #' If you need to run extra code before or after all examples are run, you #' can create `pkgdown/pre-reference.R` and `pkgdown/post-reference.R`. #' #' # Figures #' #' You can control the default rendering of figures by specifying the `figures` #' field in `_pkgdown.yml`. The default settings are equivalent to: #' #' ```yaml #' figures: #' dev: ragg::agg_png #' dpi: 96 #' dev.args: [] #' fig.ext: png #' fig.width: 7.2916667 #' fig.height: ~ #' fig.retina: 2 #' fig.asp: 1.618 #' bg: NA #' other.parameters: [] #' ``` #' #' Most of these parameters are interpreted similarly to knitr chunk #' options. `other.parameters` is a list of parameters #' that will be available to custom graphics output devices such #' as HTML widgets. #' #' @inheritParams build_articles #' @family site components #' @param lazy If `TRUE`, only rebuild pages where the `.Rd` #' is more recent than the `.html`. This makes it much easier to #' rapidly prototype. It is set to `FALSE` by [build_site()]. #' @param run_dont_run Run examples that are surrounded in \\dontrun? #' @param examples Run examples? #' @param devel Determines how code is loaded in order to run examples. #' If `TRUE` (the default), assumes you are in a live development #' environment, and loads source package with [pkgload::load_all()]. #' If `FALSE`, uses the installed version of the package. #' @param topics Build only specified topics. If supplied, sets `lazy` #' and `preview` to `FALSE`. #' @export build_reference <- function(pkg = ".", lazy = TRUE, examples = TRUE, run_dont_run = FALSE, seed = 1014L, override = list(), preview = FALSE, devel = TRUE, topics = NULL) { pkg <- section_init(pkg, "reference", override = override) check_bool(lazy) check_bool(examples) check_bool(run_dont_run) check_number_whole(seed, allow_null = TRUE) check_bool(devel) check_character(topics, allow_null = TRUE) cli::cli_rule("Building function reference") build_reference_index(pkg) copy_figures(pkg) if (examples) { examples_env <- examples_env(pkg, seed = seed, devel = devel) } else { examples_env <- NULL } if (!is.null(topics)) { topics <- purrr::transpose(pkg$topics[pkg$topics$name %in% topics, ]) lazy <- FALSE preview <- FALSE } else { topics <- purrr::transpose(pkg$topics) } unwrap_purrr_error(purrr::map( topics, build_reference_topic, pkg = pkg, lazy = lazy, examples_env = examples_env, run_dont_run = run_dont_run )) preview_site(pkg, "reference", preview = preview) } copy_figures <- function(pkg) { # copy everything from man/figures to docs/reference/figures dir_copy_to( src_dir = path(pkg$src_path, "man", "figures"), src_root = pkg$src_path, dst_dir = path(pkg$dst_path, "reference", "figures"), dst_root = pkg$dst_path ) } examples_env <- function(pkg, seed = 1014L, devel = TRUE, envir = parent.frame()) { # Re-loading pkgdown while it's running causes weird behaviour with # the context cache if (isTRUE(devel) && !(pkg$package %in% c("pkgdown", "rprojroot"))) { check_installed("pkgload", "to use `build_reference(devel = TRUE)`") pkgload::load_all(pkg$src_path, export_all = FALSE, helpers = FALSE, quiet = TRUE) } else { library(pkg$package, character.only = TRUE) } # Need to compute before changing working directory pre_path <- path_abs(path(pkg$src_path, "pkgdown", "pre-reference.R")) post_path <- path_abs(path(pkg$src_path, "pkgdown", "post-reference.R")) withr::local_dir(path(pkg$dst_path, "reference"), .local_envir = envir) width <- config_pluck_number_whole(pkg, "code.width", default = 80) withr::local_options(width = width, .local_envir = envir) withr::local_seed(seed, .local_envir = envir) if (requireNamespace("htmlwidgets", quietly = TRUE)) { htmlwidgets::setWidgetIdSeed(seed) } examples_env <- child_env(globalenv()) if (file_exists(pre_path)) { sys.source(pre_path, envir = examples_env) } if (file_exists(post_path)) { withr::defer(sys.source(post_path, envir = examples_env), envir = envir) } examples_env } #' @export #' @rdname build_reference build_reference_index <- function(pkg = ".", override = list()) { pkg <- section_init(pkg, "reference", override = override) # Copy icons, if needed dir_copy_to( src_dir = path(pkg$src_path, "icons"), src_root = pkg$src_path, dst_dir = path(pkg$dst_path, "reference", "icons"), dst_root = pkg$dst_path ) render_page( pkg, "reference-index", data = data_reference_index(pkg), path = "reference/index.html" ) invisible() } build_reference_topic <- function(topic, pkg, lazy = TRUE, examples_env = globalenv(), run_dont_run = FALSE) { in_path <- path(pkg$src_path, "man", topic$file_in) out_path <- path(pkg$dst_path, "reference", topic$file_out) if (lazy && !out_of_date(in_path, out_path)) return(invisible()) cli::cli_inform("Reading {src_path(path('man', topic$file_in))}") data <- withCallingHandlers( data_reference_topic( topic, pkg, examples_env = examples_env, run_dont_run = run_dont_run ), error = function(err) { cli::cli_abort( "Failed to parse Rd in {.file {topic$file_in}}", parent = err, call = quote(build_reference()) ) } ) deps <- data$dependencies data$has_deps <- !is.null(deps) if (data$has_deps) { deps <- bs_theme_deps_suppress(deps) deps <- htmltools::resolveDependencies(deps) deps <- purrr::map( deps, htmltools::copyDependencyToDir, outputDir = path(pkg$dst_path, "reference", "libs"), mustWork = FALSE ) deps <- purrr::map( deps, htmltools::makeDependencyRelative, basepath = path(pkg$dst_path, "reference"), mustWork = FALSE ) data$dependencies <- htmltools::renderDependencies(deps, c("file", "href")) } render_page( pkg, "reference-topic", data = data, path = path("reference", topic$file_out) ) invisible() } # Convert Rd to list ------------------------------------------------------ data_reference_topic <- function(topic, pkg, examples_env = globalenv(), run_dont_run = FALSE) { local_context_eval(pkg$figures, pkg$src_path) withr::local_options(list(downlit.rdname = get_rdname(topic))) tag_names <- purrr::map_chr(topic$rd, ~ class(.)[[1]]) tags <- split(topic$rd, tag_names) out <- list() # Single top-level converted to string out$name <- flatten_text(tags$tag_name[[1]][[1]]) out$title <- extract_title(tags$tag_title) out$pagetitle <- paste0(strip_html_tags(out$title), " \u2014 ", out$name) # File source out$source <- repo_source(pkg, topic$source) out$filename <- topic$file_in # Multiple top-level converted to string out$author <- purrr::map_chr(tags$tag_author %||% list(), flatten_para) out$aliases <- purrr::map_chr(tags$tag_alias %||% list(), flatten_text) out$keywords <- purrr::map_chr(tags$tag_keyword %||% list(), flatten_text) # Sections that contain arbitrary text and need cross-referencing out$description <- as_data(tags$tag_description[[1]]) out$opengraph <- list(description = strip_html_tags(out$description$contents)) if (length(tags$tag_usage[[1]])) { out$usage <- list( title = tr_("Usage"), contents = as_data(tags$tag_usage[[1]]) ) } if (!is.null(tags$tag_examples)) { out$examples <- run_examples( tags$tag_examples[[1]], env = if (is.null(examples_env)) NULL else new.env(parent = examples_env), topic = tools::file_path_sans_ext(topic$file_in), run_dont_run = run_dont_run ) deps <- attr(out$examples, "dependencies") if (!is.null(deps)) { attr(out$examples, "dependencies") <- NULL out$dependencies <- deps } } # Everything else stays in original order, and becomes a list of sections. section_tags <- paste0("tag_", c( "arguments", "value", "details", "references", "source", "format", "note", "seealso", "section", "author" )) sections <- topic$rd[tag_names %in% section_tags] out$sections <- purrr::map(sections, function(section) { data <- as_data(section) data$slug <- make_slug(data$title) data }) out } make_slug <- function(x) { x <- strip_html_tags(x) x <- tolower(x) x <- gsub("[^a-z]+", "-", x) x } get_rdname <- function(topics) { gsub("\\.[Rr]d$", "", topics$file_in) } ����������������������������������������������������������������������������������������������pkgdown/R/rd-html.R���������������������������������������������������������������������������������0000644�0001762�0000144�00000036733�14634573316�013646� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������as_html <- function(x, ...) { UseMethod("as_html") } # Various types of text ------------------------------------------------------ flatten_para <- function(x, ...) { if (length(x) == 0) { return(character()) } # Look for "\n" TEXT blocks after a TEXT block, and not at end of file is_nl <- purrr::map_lgl(x, is_newline, trim = TRUE) is_text <- purrr::map_lgl(x, inherits, "TEXT") is_text_prev <- c(FALSE, is_text[-length(x)]) has_next <- c(rep(TRUE, length(x) - 1), FALSE) is_para_break <- is_nl & is_text_prev & has_next # Or tags that are converted to HTML blocks block_tags <- c( "tag_preformatted", "tag_itemize", "tag_enumerate", "tag_tabular", "tag_describe", "tag_subsection" ) is_block <- purrr::map_lgl(x, inherits, block_tags) # Break before and after each status change before_break <- is_para_break | is_block after_break <- c(FALSE, before_break[-length(x)]) groups <- cumsum(before_break | after_break) unwrap_purrr_error(html <- purrr::map(x, as_html, ...)) # split at line breaks for everything except blocks empty <- purrr::map_lgl(x, purrr::is_empty) needs_split <- !is_block & !empty html[needs_split] <- purrr::map(html[needs_split], split_at_linebreaks) blocks <- purrr::map_chr(split(html, groups), function(x) { paste(unlist(x), collapse = "") }) # There are three types of blocks: # 1. Combined text and inline tags # 2. Paragraph breaks (text containing only "\n") # 3. Block-level tags # # Need to wrap 1 in <p> needs_p <- purrr::map_lgl(split(!(is_nl | is_block), groups), any) blocks[needs_p] <- paste0("<p>", str_trim(blocks[needs_p]), "</p>") paste0(blocks, collapse = "") } split_at_linebreaks <- function(text) { if (length(text) == 0) { character() } else { strsplit(text, "\\n\\s*\\n")[[1]] } } flatten_text <- function(x, ...) { if (length(x) == 0) return("") unwrap_purrr_error(html <- purrr::map_chr(x, as_html, ...)) paste(html, collapse = "") } #' @export as_html.Rd <- function(x, ...) flatten_text(x, ...) #' @export as_html.LIST <- flatten_text # Leaves ----------------------------------------------------------------- #' @export as_html.character <- function(x, ..., escape = TRUE) { # src_highlight (used by usage, examples, and out) also does escaping # so we need some way to turn it off when needed. if (escape) { escape_html(x) } else { as.character(x) } } #' @export as_html.TEXT <- function(x, ..., escape = TRUE) { # tools:::htmlify x <- gsub("---", "\u2014", x) x <- gsub("--", "\u2013", x) x <- gsub("``", "\u201c", x) x <- gsub("''", "\u201d", x) x <- as_html.character(x, ..., escape = escape) x } #' @export as_html.RCODE <- as_html.character #' @export as_html.VERB <- as_html.character #' @export as_html.COMMENT <- function(x, ...) { paste0("<!-- ", flatten_text(x), " -->") } # USERMACRO appears first, followed by the rendered macro #' @export as_html.USERMACRO <- function(x, ...) "" #' @export as_html.tag_subsection <- function(x, ..., subsection_level = 3L) { h <- paste0("h", subsection_level) title <- flatten_text(x[[1]], ...) id <- make_slug(title) text <- flatten_para(x[[2]], ..., subsection_level = subsection_level + 1L) paste0( "<div class='section' id='", id, "'>\n", "<", h, ">", title, "</", h, ">\n", text, "\n", "</div>" ) } # Equations ------------------------------------------------------------------ #' @export as_html.tag_eqn <- function(x, ...) { latex_rep <- x[[1]] paste0("\\(", flatten_text(latex_rep, ...), "\\)") } #' @export as_html.tag_deqn <- function(x, ...) { latex_rep <- x[[1]] paste0("$$", flatten_text(latex_rep, ...), "$$") } # Links ---------------------------------------------------------------------- #' @export as_html.tag_url <- function(x, ...) { if (length(x) != 1) { if (length(x) == 0) { msg <- "Check for empty \\url{{}} tags." } else { msg <- "This may be caused by a \\url tag that spans a line break." } stop_bad_tag("url", msg) } text <- flatten_text(x[[1]]) a(text, href = text) } #' @export as_html.tag_href <- function(x, ...) { a(flatten_text(x[[2]]), href = flatten_text(x[[1]])) } #' @export as_html.tag_email <- function(x, ...) { if (length(x) != 1) { stop_bad_tag("email", "empty {}") } paste0("<a href='mailto:", x[[1]], "'>", x[[1]], "</a>") } # If single, need to look up alias to find file name and package #' @export as_html.tag_link <- function(x, ...) { opt <- attr(x, "Rd_option") in_braces <- flatten_text(x) if (is.null(opt)) { # \link{topic} href <- downlit::href_topic(in_braces) } else if (substr(opt, 1, 1) == "=") { # \link[=dest]{name} href <- downlit::href_topic(substr(opt, 2, nchar(opt))) } else { match <- regexec('^([^:]+)(?:|:(.*))$', opt) parts <- regmatches(opt, match)[[1]][-1] if (parts[[2]] == "") { # \link[pkg]{foo} href <- downlit::href_topic(in_braces, opt) } else { # \link[pkg:bar]{foo} href <- downlit::href_topic(parts[[2]], parts[[1]]) } } a(in_braces, href = href) } #' @export as_html.tag_linkS4class <- function(x, ...) { if (length(x) != 1) { stop_bad_tag("linkS4class") } text <- flatten_text(x[[1]]) href <- downlit::href_topic(paste0(text, "-class")) a(text, href = href) } # Conditionals and Sexprs ---------------------------------------------------- #' @export as_html.tag_Sexpr <- function(x, ...) { code <- flatten_text(x, escape = FALSE) options <- parse_opts(attr(x, "Rd_option")) # Needs to be package root old_wd <- setwd(context_get("src_path")) on.exit(setwd(old_wd), add = TRUE) # Environment shared across a file env <- context_get("sexpr_env") results <- options$results %||% "rd" if (results == "verbatim") { outlines <- utils::capture.output({ out <- withVisible(eval(parse(text = code), env)) res <- out$value if (out$visible) print(res) }) paste0( "<pre>\n", paste0(escape_html(outlines), collapse = "\n"), "\n</pre>\n" ) } else { res <- eval(parse(text = code), env) switch(results, text = as.character(res), rd = flatten_text(rd_text(as.character(res))), hide = "", cli::cli_abort( "unknown \\Sexpr option: results={results}", call = NULL ) ) } } #' @export as_html.tag_if <- function(x, ...) { if (x[[1]] == "html") { as_html(x[[2]], ...) } else { "" } } #' @export as_html.tag_ifelse <- function(x, ...) { if (x[[1]] == "html") as_html(x[[2]], ...) else as_html(x[[3]], ...) } # Used inside a \usage{} Rd tag to prevent the code from being treated as # regular R syntax, either because it is not valid R, or because its usage # intentionally deviates from regular R usage. An example of the former is the # command line documentation, e.g. `R CMD SHLIB` # (https://github.com/wch/r-source/blob/trunk/src/library/utils/man/SHLIB.Rd): # # \special{R CMD SHLIB [options] [-o dllname] files} # # An example of the latter is the documentation shortcut `?` # (https://github.com/wch/r-source/blob/trunk/src/library/utils/man/Question.Rd): # # \special{?topic} # #' @export as_html.tag_special <- function(x, ...) { flatten_text(x, ...) } #' @export `as_html.#ifdef` <- function(x, ...) { os <- trimws(flatten_text(x[[1]])) if (os == "unix") { flatten_text(x[[2]]) } else { "" } } #' @export `as_html.#ifndef` <- function(x, ...) { os <- trimws(flatten_text(x[[1]])) if (os == "windows") { flatten_text(x[[2]]) } else { "" } } # Tables --------------------------------------------------------------------- #' @export as_html.tag_tabular <- function(x, ...) { align_abbr <- strsplit(as_html(x[[1]], ...), "")[[1]] align_abbr <- align_abbr[!(align_abbr %in% c("|", ""))] align <- unname(c("r" = "right", "l" = "left", "c" = "center")[align_abbr]) contents <- x[[2]] class <- purrr::map_chr(contents, ~ class(.x)[[1]]) cell_contents <- purrr::map_chr(contents, flatten_text, ...) row_sep <- class == "tag_cr" contents[row_sep] <- list("") col_sep <- class == "tag_tab" sep <- col_sep | row_sep # Identify groups in reverse order (preserve empty cells) # Negative maintains correct ordering once reversed cell_grp <- rev(cumsum(-rev(sep))) cells <- unname(split(contents, cell_grp)) # Remove trailing content (that does not match the dimensions of the table) cells <- cells[seq_len(length(cells) - length(cells)%%length(align))] cell_contents <- purrr::map_chr(cells, flatten_text, ...) cell_contents <- paste0("<td>", str_trim(cell_contents), "</td>") cell_contents <- matrix(cell_contents, ncol = length(align), byrow = TRUE) rows <- apply(cell_contents, 1, paste0, collapse = "") paste0("<table class='table'>\n", paste0("<tr>", rows, "</tr>\n", collapse = ""), "</table>\n") } # Figures ----------------------------------------------------------------- #' @export as_html.tag_figure <- function(x, ...) { n <- length(x) path <- as.character(x[[1]]) if (n == 1) { paste0("<img src='figures/", path, "' alt='' />") } else if (n == 2) { opt <- paste(trimws(as.character(x[[2]])), collapse = " ") if (substr(opt, 1, 9) == "options: ") { extra <- substr(opt, 9, nchar(opt)) paste0("<img src='figures/", path, "'", extra, " />") } else { paste0("<img src='figures/", path, "' alt='", opt, "' />") } } } # List ----------------------------------------------------------------------- #' @export as_html.tag_itemize <- function(x, ...) { paste0("<ul>\n", parse_items(x[-1], ...), "</ul>") } #' @export as_html.tag_enumerate <- function(x, ...) { paste0("<ol>\n", parse_items(x[-1], ...), "</ol>") } #' @export as_html.tag_describe <- function(x, ...) { paste0("<dl>\n", parse_descriptions(x[-1], ...), "\n</dl>") } # Effectively does nothing: only used by parse_items() to split up # sequence of tags. #' @export as_html.tag_item <- function(x, ...) { "" } parse_items <- function(rd, ...) { separator <- purrr::map_lgl(rd, inherits, "tag_item") group <- cumsum(separator) # Drop anything before first tag_item if (!all(group == 0) && any(group == 0)) { rd <- rd[group != 0] group <- group[group != 0] } parse_item <- function(x) { x <- trim_ws_nodes(x) paste0("<li>", flatten_para(x, ...), "</li>\n") } paste(purrr::map_chr(split(rd, group), parse_item), collapse = "") } parse_descriptions <- function(rd, ..., id_prefix = NULL) { if (length(rd) == 0) { return(character()) } parse_item <- function(x) { if (inherits(x, "tag_item")) { term <- flatten_text(x[[1]], ...) def <- flatten_para(x[[2]], ...) if (!is.null(id_prefix)) { id <- paste0(id_prefix, make_slug(term)) id_attr <- paste0(" id='", id, "'") anchor <- anchor_html(id) } else { id_attr <- "" anchor <- "" } paste0( "<dt", id_attr, ">", term, anchor, "</dt>\n", "<dd>", def , "</dd>\n" ) } else { flatten_text(x, ...) } } paste(purrr::map_chr(rd, parse_item), collapse = "") } # Marking text ------------------------------------------------------------ # https://cran.rstudio.com/doc/manuals/r-devel/R-exts.html#Marking-text tag_wrapper <- function(prefix, suffix = NULL) { function(x, ...) { html <- flatten_text(x, ...) paste0(prefix, html, suffix) } } #' @export as_html.tag_emph <- tag_wrapper("<em>", "</em>") #' @export as_html.tag_strong <- tag_wrapper("<strong>", "</strong>") #' @export as_html.tag_bold <- tag_wrapper("<b>", "</b>") #' @export as_html.tag_dQuote <- tag_wrapper("“", "”") #' @export as_html.tag_sQuote <- tag_wrapper("‘", "’") #' @export as_html.tag_code <- function(x, ..., auto_link = TRUE) { text <- flatten_text(x, ...) if (auto_link) { href <- downlit::autolink_url(text) text <- a(text, href = href) } paste0("<code>", text, "</code>") } #' @export as_html.tag_preformatted <- function(x, ...) { # the language is stored in a prior \if{}{\out{}} block, so we delay # highlighting until we have the complete html page pre(flatten_text(x, ...)) } #' @export as_html.tag_kbd <- tag_wrapper("<kbd>", "</kbd>") #' @export as_html.tag_samp <- tag_wrapper('<samp>',"</samp>") #' @export as_html.tag_verb <- tag_wrapper("<code>", "</code>") #' @export as_html.tag_pkg <- tag_wrapper('<span class="pkg">',"</span>") #' @export as_html.tag_file <- tag_wrapper('<code class="file">', '</code>') #' @export as_html.tag_var <- tag_wrapper("<var>", "</var>") #' @export as_html.tag_env <- tag_wrapper('<code class="env">', '</code>') #' @export as_html.tag_option <- tag_wrapper('<span class="option">',"</span>") #' @export as_html.tag_command <- tag_wrapper("<code class='command'>", "</code>") #' @export as_html.tag_dfn <- tag_wrapper("<dfn>", "</dfn>") #' @export as_html.tag_cite <- tag_wrapper("<cite>", "</cite>") #' @export as_html.tag_acronym <- tag_wrapper('<acronym>','</acronym>') #' @export as_html.tag_out <- function(x, ...) flatten_text(x, ..., escape = FALSE) # Insertions -------------------------------------------------------------- #' @export as_html.tag_R <- function(x, ...) '<span style="R">R</span>' #' @export as_html.tag_dots <- function(x, ...) "..." #' @export as_html.tag_ldots <- function(x, ...) "..." #' @export as_html.tag_cr <- function(x, ...) "<br>" # First element of enc is the encoded version (second is the ascii version) #' @export as_html.tag_enc <- function(x, ...) { if (length(x) == 2) { as_html(x[[1]], ...) } else { stop_bad_tag("enc") } } # Elements that don't return anything ---------------------------------------- #' @export as_html.tag_tab <- function(x, ...) "" #' @export as_html.tag_newcommand <- function(x, ...) "" #' @export as_html.tag_renewcommand <- function(x, ...) "" #' @export as_html.tag <- function(x, ...) { if (identical(class(x), "tag")) { flatten_text(x, ...) } else { cli::cli_inform("Unknown tag: {.cls {class(x)}}") "" } } # Whitespace helper ------------------------------------------------------- trim_ws_nodes <- function(x, side = c("both", "left", "right")) { is_ws <- purrr::map_lgl(x, ~ inherits(., "TEXT") && grepl("^\\s*$", .[[1]])) if (!any(is_ws)) return(x) if (all(is_ws)) return(x[0]) which_not <- which(!is_ws) side <- match.arg(side) if (side %in% c("left", "both")) { start <- which_not[1] } else { start <- 1 } if (side %in% c("right", "both")) { end <- which_not[length(which_not)] } else { end <- length(x) } x[start:end] } # Helpers ----------------------------------------------------------------- parse_opts <- function(string) { if (is.null(string)) { return(list()) } args <- list("text", "verbatim", "rd", "hide", "build", "install", "render") names(args) <- args arg_env <- child_env(baseenv(), !!!args) args <- strsplit(string, ",")[[1]] exprs <- purrr::map(args, parse_expr) env <- child_env(arg_env) purrr::walk(exprs, eval_bare, env = env) as.list(env) } stop_bad_tag <- function(tag, msg = NULL) { bad_tag <- paste0("\\", tag, "{}") msg_abort <- 'Failed to parse tag {.val {bad_tag}}.' cli::cli_abort(c(msg_abort, i = msg), call = NULL) } is_newline <- function(x, trim = FALSE) { if (!inherits(x, "TEXT") && !inherits(x, "RCODE") && !inherits(x, "VERB")) return(FALSE) text <- x[[1]] if (trim) { text <- gsub("^[ \t]+|[ \t]+$", "", text) } identical(text, "\n") } �������������������������������������pkgdown/R/build-home-md.R���������������������������������������������������������������������������0000644�0001762�0000144�00000002726�14633374223�014710� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������build_home_md <- function(pkg) { mds <- package_mds(pkg$src_path, in_dev = pkg$development$in_dev) lapply(mds, render_md, pkg = pkg) invisible() } package_mds <- function(path, in_dev = FALSE) { mds <- dir_ls(path, glob = "*.md") # Also looks in .github, if it exists github_path <- path(path, ".github") if (dir_exists(github_path)) { mds <- c(mds, dir_ls(github_path, glob = "*.md")) } # Remove files handled elsewhere handled <- c("README.md", "LICENSE.md", "LICENCE.md", "NEWS.md") mds <- mds[!path_file(mds) %in% handled] # Do not build 404 page if in-dev if (in_dev) { mds <- mds[path_file(mds) != "404.md"] } # Remove files that don't need to be rendered no_render <- c( "issue_template.md", "pull_request_template.md", "cran-comments.md" ) mds <- mds[!path_file(mds) %in% no_render] unname(mds) } render_md <- function(pkg, filename) { cli::cli_inform("Reading {src_path(path_rel(filename, pkg$src_path))}") body <- markdown_body(pkg, filename, strip_header = TRUE) path <- path_ext_set(path_file(filename), "html") render_page(pkg, "title-body", data = list( pagetitle = attr(body, "title"), body = body, filename = filename, source = repo_source(pkg, path_rel(filename, pkg$src_path)) ), path = path ) if (path == "404.html") { update_html(path(pkg$dst_path, path), tweak_link_absolute, pkg = pkg) } check_missing_images(pkg, filename, path) invisible() } ������������������������������������������pkgdown/R/build-home-license.R����������������������������������������������������������������������0000644�0001762�0000144�00000004047�14633374223�015730� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Renders LICENSE text file into html build_home_license <- function(pkg) { license_md <- path_first_existing(pkg$src_path, c("LICENSE.md", "LICENCE.md")) if (!is.null(license_md)) { render_md(pkg, license_md) } license_raw <- path_first_existing(pkg$src_path, c("LICENSE", "LICENCE")) if (!is.null(license_raw)) { render_page(pkg, "title-body", data = list( pagetitle = tr_("License"), body = paste0("<pre>", escape_html(read_file(license_raw)), "</pre>") ), path = "LICENSE-text.html" ) return() } } data_home_sidebar_license <- function(pkg = ".") { pkg <- as_pkgdown(pkg) link <- autolink_license(pkg$desc$get_field("License", "")) license_md <- path_first_existing(pkg$src_path, c("LICENSE.md", "LICENCE.md")) if (!is.null(license_md)) { link <- c( a(tr_("Full license"), "LICENSE.html"), paste0("<small>", link, "</small>") ) } sidebar_section(tr_("License"), link) } # helpers ----------------------------------------------------------------- autolink_license <- function(x) { db <- licenses_db() for (i in seq_len(nrow(db))) { match <- paste0("\\b\\Q", db$abbr[[i]], "\\E\\b") x <- gsub(match, db$a[[i]], x, perl = TRUE) } x } licenses_db <- function() { path <- path(R.home("share"), "licenses", "license.db") db <- tibble::as_tibble(read.dcf(path)) db <- add_missing_sss(db) abbr <- ifelse(is.na(db$SSS), db$Abbrev, db$SSS) url <- db$URL # Add entry for LICENSE file abbr <- c(abbr, "LICENSE", "LICENCE") url <- c(url, "LICENSE-text.html", "LICENSE-text.html") out <- tibble::tibble(abbr, url) out$a <- paste0("<a href='", url, "'>", abbr, "</a>") out[!is.na(out$abbr), ] } # Add missing standard short specification (SSS) for some licenses # (e.g., Mozilla Public Licences) # see src/library/tools/R/license.R in R source for details add_missing_sss <- function(db) { needs_sss <- !is.na(db$Abbrev) & !is.na(db$Version) & is.na(db$SSS) x <- db[needs_sss, ] db[needs_sss, "SSS"] <- paste0(x$Abbrev, "-", x$Version) db } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/build-favicons.R��������������������������������������������������������������������������0000644�0001762�0000144�00000007150�14634573316�015173� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' Initialise favicons from package logo #' #' @description #' This function auto-detects the location of your package logo (with the name #' `logo.svg` (recommended format) or `logo.png`, created with `usethis::use_logo()`) #' and runs it through the <https://realfavicongenerator.net> API to build a #' complete set of favicons with different sizes, as needed for modern web usage. #' #' You only need to run the function once. The favicon set will be stored in #' `pkgdown/favicon` and copied by [init_site()] to the relevant location when #' the website is rebuilt. #' #' Once complete, you should add `pkgdown/` to `.Rbuildignore ` to avoid a NOTE #' during package checking. (`usethis::use_logo()` does this for you!) #' #' @inheritParams as_pkgdown #' @param overwrite If `TRUE`, re-create favicons from package logo. #' @export build_favicons <- function(pkg = ".", overwrite = FALSE) { rlang::check_installed("openssl") pkg <- as_pkgdown(pkg) cli::cli_rule("Building favicons") logo_path <- find_logo(pkg$src_path) if (is.null(logo_path)) { cli::cli_abort(c( "Can't find package logo PNG or SVG to build favicons.", "i" = "See {.fun usethis::use_logo} for more information." )) } if (has_favicons(pkg) && !overwrite) { cli::cli_inform(c( "Favicons already exist in {.path pkgdown}", "i" = "Set {.code overwrite = TRUE} to re-create." )) return(invisible()) } cli::cli_inform(c( i = "Building favicons with {.url https://realfavicongenerator.net}..." )) logo <- readBin(logo_path, what = "raw", n = file_info(logo_path)$size) json_request <- list( "favicon_generation" = list( "api_key" = "87d5cd739b05c00416c4a19cd14a8bb5632ea563", "master_picture" = list( "type" = "inline", "content" = openssl::base64_encode(logo) ), "favicon_design" = list( "desktop_browser" = list(), "ios" = list( "picture_aspect" = "no_change", "assets" = list( "ios6_and_prior_icons" = FALSE, "ios7_and_later_icons" = TRUE, "precomposed_icons" = FALSE, "declare_only_default_icon" = TRUE ) ) ) ) ) req <- httr2::request("https://realfavicongenerator.net/api/favicon") req <- httr2::req_body_json(req, json_request) withCallingHandlers( resp <- httr2::req_perform(req), error = function(e) { cli::cli_abort("API request failed.", parent = e) } ) content <- httr2::resp_body_json(resp) result <- content$favicon_generation_result if (!identical(result$result$status, "success")) { cli::cli_abort("API request failed.", .internal = TRUE) } tmp <- withr::local_tempfile() req <- httr2::request(result$favicon$package_url) resp <- httr2::req_perform(req, tmp) withCallingHandlers( paths <- utils::unzip(tmp, exdir = path(pkg$src_path, "pkgdown", "favicon")), warning = function(e) { cli::cli_abort("Your logo file couldn't be processed and may be corrupt.", parent = e) }, error = function(e) { cli::cli_abort("Your logo file couldn't be processed and may be corrupt.", parent = e) } ) cli::cli_inform(c("v" = "Added {.path {sort(path_file(paths))}}.")) invisible() } copy_favicons <- function(pkg = ".") { pkg <- as_pkgdown(pkg) dir_copy_to( src_dir = path(pkg$src_path, "pkgdown", "favicon"), src_root = pkg$src_path, dst_dir = pkg$dst_path, dst_root = pkg$dst_path ) } has_favicons <- function(pkg = ".") { pkg <- as_pkgdown(pkg) unname(file_exists(path_favicons(pkg))) } path_favicons <- function(pkg) { path(pkg$src_path, "pkgdown", "favicon") } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/tweak.R�����������������������������������������������������������������������������������0000644�0001762�0000144�00000000564�14134254444�013374� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������has_class <- function(html, class) { classes <- strsplit(xml2::xml_attr(html, "class"), " ") purrr::map_lgl(classes, ~ any(class %in% .x)) } tweak_class_prepend <- function(x, class) { if (length(x) == 0) { return(invisible()) } cur <- xml2::xml_attr(x, "class") xml2::xml_attr(x, "class") <- ifelse(is.na(cur), class, paste(class, cur)) invisible() } ��������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/test.R������������������������������������������������������������������������������������0000644�0001762�0000144�00000012614�14634573316�013246� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' Test case: lists #' #' @noMd #' @description #' #' \subsection{Bulleted list}{ #' \itemize{ #' \item a #' \item This is an item... #' #' That spans multiple paragraphs. #' } #' } #' #' \subsection{Bulleted list (single item)}{ #' \itemize{\item a} #' } #' #' \subsection{Numbered list}{ #' \enumerate{ #' \item a #' \item b #' } #' } #' #' \subsection{Definition list}{ #' \describe{ #' \item{short}{short} #' \item{short}{Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do #' eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad #' minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip #' ex ea commodo consequat. Duis aute irure dolor in reprehenderit in #' voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur #' sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt #' mollit anim id est laborum.} #' \item{Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do #' eiusmod tempor incididunt ut labore et dolore magna aliqua.}{short} #' \item{Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do #' eiusmod tempor incididunt ut labore et dolore magna aliqua.}{Lorem ipsum #' adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore ad #' minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip #' ex ea commodo consequat. Duis aute irure dolor in reprehenderit in #' voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur #' sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt #' mollit anim id est laborum.} #' } #' } #' @keywords internal #' @family tests #' @name test-lists NULL #' Test case: links #' #' ```{r} #' jsonlite::minify("{}") #' ``` #' #' @name test-links #' @keywords internal #' @family tests #' @examples #' jsonlite::minify("{}") #' #' library(jsonlite, warn.conflicts = FALSE) #' minify("{}") NULL #' Test case: figures #' #' \figure{bacon.jpg} #' #' @name test-figures #' @keywords internal #' @family tests #' @examples #' x <- seq(0, 2 * pi, length.out = 25) #' plot(x, sin(x)) #' #' plot(1:10) #' lines(1:10) #' text(2, 5, "Hello", srt = 30, cex = 2) NULL #' Test case: tables #' #' @name test-tables #' @keywords internal #' @family tests #' @examples #' gt::gt(head(mtcars)) NULL #' Test case: don't #' #' @name test-dont #' @keywords internal #' @family tests #' @examples #' # \dontrun{} -------------------------------------------------------- #' # always shown; never run #' #' x <- 1 #' \dontrun{x <- 2} #' \dontrun{ #' x <- 3 #' x <- 4 #' } #' x # should be 1 #' #' # \donttest{} ------------------------------------------------------- #' # only multiline are shown; always run #' #' x <- 1 #' \donttest{x <- 2} #' \donttest{ #' x <- 3 #' x <- 4 #' } #' x # should be 4 #' #' # \testonly{} ----------------------------------------------------- #' # never shown, never run #' #' x <- 1 #' \testonly{x <- 2} #' \testonly{ #' x <- 3 #' x <- 4 #' } #' x # should be 1 #' #' # \dontshow{} ------------------------------------------------------- #' # never shown, always run #' #' x <- 1 #' \dontshow{x <- 2} #' \dontshow{ #' x <- 3 #' x <- 4 #' } #' x # should be 4 #' #' # @examplesIf ------------------------------------------------------ #' # If FALSE, wrapped in if; if TRUE, not seen #' #' x <- 1 #' #' @examplesIf FALSE #' x <- 2 #' @examplesIf TRUE #' x <- 3 #' @examples #' x # should be 3 NULL #' Test case: params #' #' @name test-params #' @param ... ellipsis #' @keywords internal #' @family tests NULL #' Test case: output styles #' #' @name test-output-styles #' @keywords internal #' @family tests #' #' @examples #' # This example illustrates some important output types #' # The following output should be wrapped over multiple lines #' a <- 1:100 #' a #' #' cat("This some text!\n") #' message("This is a message!") #' warning("This is a warning!") #' #' # This is a multi-line block #' { #' 1 + 2 #' 2 + 2 #' } NULL #' Test case: long-lines #' #' The example results should have the copy button correctly placed when #' scrollings #' #' @name test-long-lines #' @keywords internal #' @family tests #' @examples #' pkgdown:::ruler() #' #' cat(rep("x ", 100), sep = "") #' cat(rep("xy", 100), sep = "") #' cat(rep("x ", 100), sep = "") #' cat(rep("xy", 100), sep = "") NULL #' Test case: crayon #' #' @name test-crayon #' @keywords internal #' @family tests #' #' @examples #' cat(cli::col_red("This is red"), "\n") #' cat(cli::col_blue("This is blue"), "\n") #' #' message(cli::col_green("This is green")) #' #' warning(cli::style_bold("This is bold")) NULL #' Test case: preformatted blocks & syntax highlighting #' #' Manual test cases for various ways of embedding code in sections. #' All code blocks should have copy and paste button. #' #' # Should be highlighted #' #' Valid R code in `\preformatted{}`: #' #' ``` #' mean(a + 1) #' ``` #' #' R code in `R` block: #' #' ```R #' mean(a + 1) #' ``` #' #' R code in `r` block: #' #' ```r #' mean(a + 1) #' ``` #' #' Yaml #' #' ```yaml #' yaml: [a, 1] #' ``` #' #' # Shouldn't be highlighted #' #' Non-R code in `\preformatted{}` #' #' ``` #' yaml: [a, b, c] #' ``` #' #' @name test-verbatim #' @keywords internal #' @family tests NULL #' Index #' #' @aliases test-index #' @name index #' @keywords internal #' @family tests NULL #' Test case: \Sexpr[stage=render,results=rd]{"sexpr"} #' #' @name test-sexpr-title #' @keywords internal #' @family tests NULL ��������������������������������������������������������������������������������������������������������������������pkgdown/R/build-news.R������������������������������������������������������������������������������0000644�0001762�0000144�00000023101�14657466716�014343� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' Build news section #' #' @description #' A `NEWS.md` will be broken up into versions using level one (`#`) or #' level two headings (`##`) that (partially) match one of the following forms #' (ignoring case): #' #' * `{package name} 1.3.0` #' * `{package name} v1.3.0` #' * `Version 1.3.0` #' * `Changes in 1.3.0` #' * `Changes in v1.3.0` #' #' @details #' A [common structure](https://style.tidyverse.org/news.html) for news files #' is to use a top level heading for each release, and use a second level #' heading to break up individual bullets into sections. #' #' ```yaml #' # foofy 1.0.0 #' #' ## Major changes #' #' * Can now work with all grooveable grobbles! #' #' ## Minor improvements and bug fixes #' #' * Printing scrobbles no longer errors (@githubusername, #100) #' #' * Wibbles are now 55% less jibbly (#200) #' ``` #' #' Issues and contributors will be automatically linked to the corresponding #' pages on GitHub if the GitHub repo can be discovered from the `DESCRIPTION` #' (typically from a `URL` entry containing `github.com`) #' #' If a version is available on CRAN, the release date will automatically #' be added to the heading (see below for how to suppress); if not #' available on CRAN, "Unreleased" will be added. #' #' # YAML config #' #' To automatically link to release announcements, include a `releases` #' section. #' #' ```yaml #' news: #' releases: #' - text: "usethis 1.3.0" #' href: https://www.tidyverse.org/articles/2018/02/usethis-1-3-0/ #' - text: "usethis 1.0.0 (and 1.1.0)" #' href: https://www.tidyverse.org/articles/2017/11/usethis-1.0.0/ #' ``` #' #' Control whether news is present on one page or multiple pages with the #' `one_page` field. The default is `true`. #' #' ```yaml #' news: #' one_page: false #' ``` #' #' Suppress the default addition of CRAN release dates with: #' #' ```yaml #' news: #' cran_dates: false #' ``` #' @family site components #' #' @seealso [Tidyverse style for News](https://style.tidyverse.org/news.html) #' #' @inheritParams build_articles #' @export build_news <- function(pkg = ".", override = list(), preview = FALSE) { pkg <- section_init(pkg, "news", override = override) if (!has_news(pkg$src_path)) return(invisible()) cli::cli_rule("Building news") one_page <- config_pluck_bool(pkg, "news.one_page", default = TRUE) if (one_page) { build_news_single(pkg) } else { build_news_multi(pkg) } preview_site(pkg, "news", preview = preview) } build_news_single <- function(pkg = ".") { pkg <- as_pkgdown(pkg) news <- data_news(pkg) render_page( pkg, "news", list( contents = purrr::transpose(news), pagetitle = tr_("Changelog"), source = repo_source(pkg, "NEWS.md") ), path("news", "index.html") ) } build_news_multi <- function(pkg = ".") { pkg <- as_pkgdown(pkg) news <- data_news(pkg) page <- factor(news$page, levels = unique(news$page)) news_paged <- tibble::tibble( version = levels(page), file_out = paste0("news-", version, ".html"), contents = split(news[c("html", "version", "anchor")], page) ) render_news <- function(version, file_out, contents) { # Older, major, versions first on each page # https://github.com/r-lib/pkgdown/issues/2285#issuecomment-2070966518 render_page( pkg, "news", list( version = version, contents = rev(purrr::transpose(contents)), pagetitle = sprintf(tr_("Version %s"), version) ), path("news", file_out), ) } purrr::pwalk(news_paged, render_news) render_page( pkg, "news-index", list( versions = purrr::transpose(news_paged), pagetitle = tr_("News") ), path("news", "index.html") ) } data_news <- function(pkg, call = caller_env() ) { html <- markdown_body(pkg, path(pkg$src_path, "NEWS.md")) xml <- xml2::read_html(html) sections <- xml2::xml_find_all(xml, "./body/div") footnotes <- has_class(sections, "footnotes") if (any(footnotes)) { cli::cli_warn("Footnotes in NEWS.md are not currently supported") } sections <- sections[!footnotes] headings <- xml2::xml_find_first(sections, ".//h1|.//h2|.//h3|.//h4|.//h5") levels <- xml2::xml_name(headings) ulevels <- unique(levels) if (!identical(ulevels, "h1") && !identical(ulevels, "h2")) { msg <- c( "inconsistent use of section headings.", i = "Top-level headings must be either all <h1> or all <h2>.", i = "See {.help pkgdown::build_news} for more details." ) config_abort(pkg, msg, path = "NEWS.md", call = call) } if (ulevels == "h1") { # Bump every heading down a level so to get a single <h1> for the page title tweak_section_levels(xml) } titles <- xml2::xml_text(xml2::xml_find_first(sections, ".//h2"), trim = TRUE) versions <- news_version(titles, pkg$package) sections <- sections[!is.na(versions)] if (length(sections) == 0) { msg <- c( "no version headings found", i = "See {.help pkgdown::build_news} for expected structure." ) config_warn(pkg, msg, path = "NEWS.md", call = call) } versions <- versions[!is.na(versions)] show_dates <- config_pluck_bool(pkg, "news.cran_dates", default = !is_testing()) if (show_dates) { timeline <- pkg_timeline(pkg$package) } else { timeline <- NULL } purrr::walk2( sections, versions, tweak_news_heading, timeline = timeline, bs_version = pkg$bs_version ) html <- purrr::map_chr(sections, as.character, options = character()) html <- purrr::map_chr(html, repo_auto_link, pkg = pkg) anchors <- xml2::xml_attr(sections, "id") news <- tibble::tibble( version = versions, page = purrr::map_chr(versions, version_page), anchor = anchors, html = html ) news } news_version <- function(x, pkgname) { pattern <- paste0("(?x) (?:", pkgname, "|version|changes\\ in) \\s+ # whitespace v? # optional v followed by (?<version> (?:\\d+[.-]\\d+)(?:[.-]\\d+)* # digits, dots, and dashes | # OR \\(development\\ version\\) # literal used by usethis ) ") pieces <- re_match(x, pattern, ignore.case = TRUE) gsub("^[(]|[)]$", "", pieces$version) } version_page <- function(x) { if (x == "development version") { return("dev") } ver <- unclass(package_version(x))[[1]] if (length(ver) == 4 && ver[[4]] > 0) { "dev" } else { paste0(ver[[1]], ".", ver[[2]]) } } navbar_news <- function(pkg) { releases_meta <- config_pluck_list(pkg, "news.releases") if (!is.null(releases_meta)) { menu_submenu(tr_("News"), list2( menu_heading(tr_("Releases")), !!!releases_meta, menu_separator(), menu_link(tr_("Changelog"), "news/index.html") ) ) } else if (has_news(pkg$src_path)) { menu_link(tr_("Changelog"), "news/index.html") } } has_news <- function(path = ".") { file_exists(path(path, "NEWS.md")) } pkg_timeline <- function(package) { if (!has_internet()) { return(NULL) } url <- paste0("https://crandb.r-pkg.org/", package, "/all") req <- httr2::request(url) req <- httr2::req_retry(req, max_tries = 3) req <- httr2::req_error(req, function(resp) FALSE) resp <- httr2::req_perform(req) if (httr2::resp_is_error(resp)) { return(NULL) } content <- httr2::resp_body_json(resp) timeline <- unlist(content$timeline) data.frame( version = names(timeline), date = as.Date(timeline), row.names = NULL ) } tweak_news_heading <- function(html, version, timeline, bs_version) { class <- if (bs_version == 3) "page-header" else "pkg-version" h2 <- xml2::xml_find_all(html, ".//h2") xml2::xml_set_attr(h2, "class", class) xml2::xml_set_attr(h2, "data-toc-text", version) # Add release date, if known if (!is.null(timeline)) { date <- timeline$date[match(version, timeline$version)] if (!is.na(date)) { if (bs_version == 3) { release_str <- paste0(" <small>", date, "</small>") release_html <- xml2::xml_find_first(xml2::read_html(release_str), ".//small") xml2::xml_add_child(h2, release_html, .where = 1) } else { release_date <- sprintf(tr_("CRAN release: %s"), date) release_str <- paste0("<p class='text-muted'>", release_date, "</p>") release_html <- xml2::xml_find_first(xml2::read_html(release_str), ".//p") xml2::xml_add_sibling(h2, release_html, .where = "after") } } } tweak_news_anchor(html, version) invisible() } # Manually de-duplicate repeated section anchors using version tweak_news_anchor <- function(html, version) { div <- xml2::xml_find_all(html, ".//div") div <- div[has_class(div, "section")] id <- xml2::xml_attr(div, "id") id <- gsub("-[0-9]+", "", id) # remove pandoc de-duplication suffixes id <- paste0(id, "-", gsub("[^a-z0-9]+", "-", version)) # . breaks scrollspy xml2::xml_attr(div, "id") <- id invisible() } tweak_section_levels <- function(html) { sections <- xml2::xml_find_all(html, ".//div[contains(@class, 'section level')]|//main/section") # Update headings xml2::xml_set_name(xml2::xml_find_all(sections, ".//h5"), "h6") xml2::xml_set_name(xml2::xml_find_all(sections, ".//h4"), "h5") xml2::xml_set_name(xml2::xml_find_all(sections, ".//h3"), "h4") xml2::xml_set_name(xml2::xml_find_all(sections, ".//h2"), "h3") xml2::xml_set_name(xml2::xml_find_all(sections, ".//h1"), "h2") # Update section xml2::xml_attr(sections, "class") <- paste0("section level", get_section_level(sections) + 1) invisible() } news_style <- function(pkg) { one_page <- config_pluck_bool(pkg, "new.one_page") if (one_page) "single" else "multi" } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/check.R�����������������������������������������������������������������������������������0000644�0001762�0000144�00000005763�14633374223�013346� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' Check `_pkgdown.yml` #' #' @description #' This pair of functions checks that your `_pkgdown.yml` is valid without #' building the whole site. `check_pkgdown()` errors at the first problem; #' `pkgdown_sitrep()` reports the status of all checks. #' #' Currently they check that: #' #' * There's a `url` in the pkgdown configuration, which is also recorded #' in the `URL` field of the `DESCRIPTION`. #' #' * All opengraph metadata is valid. #' #' * All reference topics are included in the index. #' #' * All articles/vignettes are included in the index. # #' @export #' @inheritParams as_pkgdown check_pkgdown <- function(pkg = ".") { pkg <- as_pkgdown(pkg) check_urls(pkg) data_open_graph(pkg) data_articles_index(pkg) data_reference_index(pkg) cli::cli_inform(c("v" = "No problems found.")) } #' @export #' @rdname check_pkgdown pkgdown_sitrep <- function(pkg = ".") { cli::cli_rule("Sitrep") pkg <- as_pkgdown(pkg) if (pkg$bs_version == 3) { cli::cli_inform(c( x = "Bootstrap 3 is deprecated; please switch to Bootstrap 5.", i = "Learn more at {.url https://www.tidyverse.org/blog/2021/12/pkgdown-2-0-0/#bootstrap-5}." )) } error_to_sitrep("URLs", check_urls(pkg)) error_to_sitrep("Favicons", check_favicons(pkg)) error_to_sitrep("Open graph metadata", data_open_graph(pkg)) error_to_sitrep("Articles metadata", data_articles_index(pkg)) error_to_sitrep("Reference metadata", data_reference_index(pkg)) } error_to_sitrep <- function(title, code) { tryCatch( { code cli::cli_inform(c("v" = "{title} ok.")) }, rlang_error = function(e) { bullets <- c(cnd_header(e), cnd_body(e)) cli::cli_inform(c(x = "{title} not ok.", set_names(bullets, " "))) } ) invisible() } check_urls <- function(pkg = ".", call = caller_env()) { pkg <- as_pkgdown(pkg) details <- c(i = "See details in {.vignette pkgdown::metadata}.") if (identical(pkg$meta, list())) { cli::cli_abort( c("No {.path _pkgdown.yml} found.", details), call = call ) } url <- pkg$meta[["url"]] if (is.null(url)) { config_abort(pkg, c("{.field url} is missing.", details), call = call) } else { desc_urls <- pkg$desc$get_urls() desc_urls <- sub("/$", "", desc_urls) if (!pkg$meta[["url"]] %in% desc_urls) { msg <- "{.field URL} is missing package url ({url})." config_abort(pkg, c(msg, details), path = "DESCRIPTION", call = call) } } } check_favicons <- function(pkg) { if (!has_logo(pkg)) { return() } if (has_favicons(pkg)) { logo <- find_logo(pkg$src_path) favicon <- path(path_favicons(pkg), "favicon.ico") if (out_of_date(logo, favicon)) { cli::cli_abort(c( "Package logo is newer than favicons.", i = "Do you need to rerun {.run [build_favicons()](pkgdown::build_favicons())}?" )) } } else { cli::cli_abort(c( "Found package logo but not favicons.", i = "Do you need to run {.run [build_favicons()](pkgdown::build_favicons())}?" )) } } �������������pkgdown/R/navbar-menu.R�����������������������������������������������������������������������������0000644�0001762�0000144�00000014632�14633374223�014477� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Menu constructors ----------------------------------------------------------- # Helpers for use within pkgdown itself - these must stay the same as the # yaml structure defined in vignette("customise") menu_submenu <- function(text, menu, icon = NULL, label = NULL, id = NULL) { if (length(menu) == 0) { return() } else { purrr::compact(list( text = text, icon = icon, "aria-label" = label, id = id, menu = menu )) } } menu_link <- function(text, href, target = NULL) { purrr::compact(list(text = text, href = href, target = target)) } menu_links <- function(text, href) { purrr::map2(text, href, menu_link) } menu_theme <- function(text, icon, theme) { purrr::compact(list(text = text, theme = theme, icon = icon)) } menu_heading <- function(text, ...) list(text = text, ...) menu_separator <- function() list(text = "---------") menu_search <- function() list(search = list()) menu_icon <- function(icon, href, label) { list(icon = icon, href = href, "aria-label" = label) } menu_type <- function(x, menu_depth = 0L) { if (!is.list(x) || !is_named(x)) { not <- obj_type_friendly(x) cli::cli_abort("Navbar components must be named lists, not {not}.") } else if (!is.null(x$menu)) { # https://github.com/twbs/bootstrap/pull/6342 if (menu_depth > 0) { cli::cli_abort("Nested menus are not supported.") } "menu" } else if (!is.null(x$text) && grepl("^\\s*-{3,}\\s*$", x$text)) { "separator" } else if (!is.null(x$theme)) { "theme" } else if (!is.null(x$text) && is.null(x$href)) { "heading" } else if ((!is.null(x$text) || !is.null(x$icon)) && !is.null(x$href)) { "link" } else if (!is.null(x$search)) { "search" } else if (!is_named(x)) { "list" } else { cli::cli_abort("Unknown navbar component with names {names(x)}.") } } # Menu renderers -------------------------------------------------------------- navbar_html <- function(x, path_depth = 0L, menu_depth = 0L, side = c("left", "right")) { if (is.null(x)) { return("") } side <- arg_match(side) type <- menu_type(x, menu_depth = menu_depth) text <- switch(type, menu = navbar_html_menu(x, menu_depth = menu_depth, path_depth = path_depth, side = side), heading = navbar_html_heading(x), link = navbar_html_link(x, menu_depth = menu_depth), separator = navbar_html_separator(), search = navbar_html_search(x, path_depth = path_depth), theme = navbar_html_theme(x) ) class <- c( if (menu_depth == 0L) "nav-item", if (type == "menu") "dropdown" ) html_tag("li", class = class, text) } navbar_html_list <- function(x, path_depth = 0L, menu_depth = 0L, side = "left") { tags <- unwrap_purrr_error(purrr::map_chr( x, navbar_html, path_depth = path_depth, menu_depth = menu_depth, side = side )) paste0(tags, collapse = "\n") } navbar_html_menu <- function(x, path_depth = 0L, menu_depth = 0L, side = "left") { id <- paste0("dropdown-", x$id %||% make_slug(x$text)) button <- html_tag("button", type = "button", class = c(if (menu_depth == 0L) "nav-link", "dropdown-toggle"), id = id, `data-bs-toggle` = "dropdown", "aria-expanded" = "false", "aria-haspopup" = "true", "aria-label" = x$`aria-label`, navbar_html_text(x), ) li <- navbar_html_list( x$menu, path_depth = path_depth, menu_depth = menu_depth + 1, side = side ) ul <- html_tag( "ul", class = c("dropdown-menu", if (side == "right") "dropdown-menu-end"), "aria-labelledby" = id, paste0("\n", indent(li, " "), "\n") ) paste0("\n", indent(paste0(button, "\n", ul), " "), "\n") } navbar_html_link <- function(x, menu_depth = 0) { html_tag( "a", class = if (menu_depth == 0) "nav-link" else "dropdown-item", href = x$href, target = x$target, "aria-label" = x$`aria-label`, navbar_html_text(x) ) } navbar_html_theme <- function(x) { html_tag( "button", class = "dropdown-item", "aria-label" = x$`aria-label`, "data-bs-theme-value" = x$theme, navbar_html_text(x) ) } navbar_html_heading <- function(x) { html_tag( "h6", class = "dropdown-header", "data-toc-skip" = NA, navbar_html_text(x) ) } navbar_html_separator <- function() { '<hr class="dropdown-divider">' } navbar_html_search <- function(x, path_depth = 0) { input <- html_tag( "input", type = "search", class = "form-control", name = "search-input", id = "search-input", autocomplete = "off", "aria-label" = tr_("Search site"), placeholder = tr_("Search for"), "data-search-index" = paste0(up_path(path_depth), "search.json") ) html_tag("form", class = "form-inline", role = "search", "\n", input, "\n") } # Reused HTML components ----------------------------------------------------- html_tag <- function(tag, ..., class = NULL) { dots <- list2(...) dots_attr <- dots[have_name(dots)] dots_child <- dots[!have_name(dots)] if (!is.null(class)) { class <- paste0(class, collapse = " ") } attr <- purrr::compact(c(list(class = class), dots_attr)) if (length(attr) > 0) { html_attr <- ifelse( is.na(attr), names(attr), paste0(names(attr), '="', attr, '"') ) html_attr <- paste0(" ", paste0(html_attr, collapse = " ")) } else { html_attr <- "" } html_child <- paste0(purrr::compact(dots_child), collapse = " ") needs_close <- !tag %in% "input" paste0( "<", tag, html_attr, ">", html_child, if (needs_close) paste0("</", tag, ">") ) } navbar_html_text <- function(x) { if (is.null(x$icon)) { icon <- "" } else { # Extract icon set from class name classes <- strsplit(x$icon, " ")[[1]] icon_classes <- classes[grepl("-", classes)] iconset <- purrr::map_chr(strsplit(icon_classes, "-"), 1) icon <- html_tag("span", class = unique(c(iconset, classes))) if (is.null(x$`aria-label`) && is.null(x$text)) { cli::cli_inform( c( x = "Icon {.str {x$icon}} lacks an {.var aria-label}.", i = "Specify {.var aria-label} to make the icon accessible to screen readers.", i = "Learn more in {.vignette pkgdown::accessibility}." ), .frequency = "regularly", .frequency_id = "icon-aria-label" ) } } paste0( icon, if (!is.null(x$icon) && !is.null(x$text)) " ", escape_html(x$text) ) } indent <- function(x, indent) { paste0(indent, gsub("\n", paste0("\n", indent), x)) } ������������������������������������������������������������������������������������������������������pkgdown/R/package.R���������������������������������������������������������������������������������0000644�0001762�0000144�00000027124�14634573316�013664� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' Generate pkgdown data structure #' #' You will generally not need to use this unless you need a custom site #' design and you're writing your own equivalent of [build_site()]. #' #' @param pkg Path to package. #' @param override An optional named list used to temporarily override #' values in `_pkgdown.yml` #' @export as_pkgdown <- function(pkg = ".", override = list()) { if (!is.list(override)) { cli::cli_abort("{.arg override} must be a list, not {obj_type_friendly(override)}.") } if (is_pkgdown(pkg)) { pkg$meta <- modify_list(pkg$meta, override) return(pkg) } check_string(pkg) if (!dir_exists(pkg)) { if (dir.exists(pkg)) { #nolint # path expansion with fs and base R is different on Windows. # By default "~/", is typically C:/Users/username/Documents, while fs see "~/" as C:/Users/username, to be more platform portable. # Read more in ?fs::path_expand cli::cli_abort( "pkgdown accepts {.href [fs paths](https://fs.r-lib.org/reference/path_expand.html#details)}." ) } cli::cli_abort("{.file {pkg}} is not an existing directory") } if (!dir.exists(pkg)) { #nolint # Use complete path if fs path doesn't exist according to base R #2639 pkg <- path_expand(pkg) } src_path <- pkg desc <- read_desc(src_path) meta <- read_meta(src_path) meta <- modify_list(meta, override) # Create a partial pkgdown object so we can use config_pluck_* functions pkg <- list( package = desc$get_field("Package"), version = desc$get_field("Version"), src_path = path_abs(src_path), meta = meta, desc = desc ) class(pkg) <- "pkgdown" # If boostrap version set locally, it drives the template choice # But if it's not set locally, the template may have a default template <- config_pluck_list(pkg, "template") template_package <- config_pluck_string(pkg, "template.package") bs_version_local <- get_bootstrap_version(pkg, pkg$meta$template) template_meta <- find_template_config(template_package, bs_version_local) if (is.null(bs_version_local)) { bs_version_remote <- get_bootstrap_version(pkg, template_meta$template, template_package) } else { bs_version_remote <- NULL } bs_version <- bs_version_local %||% bs_version_remote %||% 3 check_bootstrap_version(bs_version, error_pkg = pkg) pkg$bs_version <- bs_version pkg$meta <- modify_list(template_meta, pkg$meta) # Ensure the URL has no trailing slash if (!is.null(pkg$meta$url)) { pkg$meta$url <- sub("/$", "", pkg$meta$url) } pkg$development <- meta_development(pkg) pkg$prefix <- pkg$development$prefix dest <- config_pluck_string(pkg, "destination") pkg$dst_path <- path_abs(dest %||% "docs", start = src_path) if (pkg$development$in_dev) { pkg$dst_path <- path(pkg$dst_path, pkg$development$destination) } pkg$lang <- pkg$meta$lang %||% "en" pkg$install_metadata <- config_pluck_bool(pkg, "deploy.install_metadata", FALSE) pkg$figures <- meta_figures(pkg) pkg$repo <- package_repo(pkg) pkg$topics <- package_topics(src_path) pkg$tutorials <- package_tutorials(src_path, meta) pkg$vignettes <- package_vignettes(src_path) pkg } is_pkgdown <- function(x) inherits(x, "pkgdown") read_desc <- function(path = ".") { path <- path(path, "DESCRIPTION") if (!file_exists(path)) { cli::cli_abort("Can't find {.file DESCRIPTION}", call = caller_env()) } desc::description$new(path) } get_bootstrap_version <- function(pkg, template, template_package = NULL, call = caller_env()) { if (is.null(template)) { return(NULL) } template_bootstrap <- template[["bootstrap"]] template_bslib <- template[["bslib"]][["version"]] if (!is.null(template_bootstrap) && !is.null(template_bslib)) { if (!is.null(template_package)) { hint <- "Specified locally and in template package {.pkg {template_package}}." } else { hint <- NULL } msg <- "must set only one of {.field template.bootstrap} and {.field template.bslib.version}." config_abort(pkg, c(msg, i = hint), call = call) } template_bootstrap %||% template_bslib } check_bootstrap_version <- function(version, error_pkg, error_call = caller_env()) { if (version %in% c(3, 5)) { version } else if (version == 4) { msg <- c( "{.var template.bootstrap: 4} no longer supported", i = "Using {.var template.bootstrap: 5} instead" ) config_warn(error_pkg, msg, call = error_call) 5 } else { msg <- "{.field template.bootstrap} must be 3 or 5, not {.val {version}}." config_abort(error_pkg, msg, error_call = caller_env()) } } # Metadata ---------------------------------------------------------------- pkgdown_config_path <- function(path) { if (is_pkgdown(path)) { path <- path$src_path } path_first_existing( path, c( "_pkgdown.yml", "_pkgdown.yaml", "pkgdown/_pkgdown.yml", "pkgdown/_pkgdown.yaml", "inst/_pkgdown.yml", "inst/_pkgdown.yaml" ) ) } read_meta <- function(path, call = caller_env()) { path <- pkgdown_config_path(path) if (is.null(path)) { yaml <- list() } else { yaml <- withCallingHandlers( yaml::yaml.load_file(path, error.label = NULL) %||% list(), error = function(e) { cli::cli_abort( "Could not parse config file at {.path {path}}.", call = call, parent = e ) } ) } yaml } # Topics ------------------------------------------------------------------ package_topics <- function(path = ".") { # Needed if title contains sexpr local_context_eval() rd <- package_rd(path) aliases <- purrr::map(rd, extract_tag, "tag_alias") names <- purrr::map_chr(rd, extract_tag, "tag_name") titles <- purrr::map_chr(rd, extract_title) concepts <- unname(purrr::map(rd, extract_tag, "tag_concept")) keywords <- unname(purrr::map(rd, extract_tag, "tag_keyword")) internal <- purrr::map_lgl(keywords, ~ "internal" %in% .) source <- purrr::map(rd, extract_source) lifecycle <- unname(purrr::map(rd, extract_lifecycle)) file_in <- names(rd) file_out <- rd_output_path(file_in) funs <- purrr::map(rd, topic_funs) tibble::tibble( name = names, file_in = file_in, file_out = file_out, alias = aliases, funs = funs, title = titles, rd = rd, source = source, keywords = keywords, concepts = concepts, internal = internal, lifecycle = lifecycle ) } rd_output_path <- function(x) { x <- gsub("\\.Rd$", ".html", x) x[x == "index.html"] <- "index-topic.html" x } package_rd <- function(path = ".") { man_path <- path(path, "man") if (!dir_exists(man_path)) { return(set_names(list(), character())) } rd <- dir_ls(man_path, regexp = "\\.[Rr]d$", type = "file") names(rd) <- path_file(rd) lapply(rd, rd_file, pkg_path = path) } extract_tag <- function(x, tag) { purrr::map_chr(purrr::keep(x, inherits, tag), c(1, 1)) } extract_title <- function(x) { title <- purrr::detect(x, inherits, "tag_title") str_squish(flatten_text(title, auto_link = FALSE)) } extract_source <- function(x) { nl <- purrr::map_lgl(x, inherits, "TEXT") & x == "\n" comment <- purrr::map_lgl(x, inherits, "COMMENT") first_comment <- cumsum(!(nl | comment)) == 0 lines <- as.character(x[first_comment]) text <- paste0(lines, collapse = "") if (!grepl("roxygen2", text)) { return(character()) } m <- gregexpr("R/[^ ]+\\.[rR]", text) regmatches(text, m)[[1]] } extract_lifecycle <- function(x) { desc <- purrr::keep(x, inherits, "tag_description") fig <- extract_figure(desc) if (!is.null(fig) && length(fig) > 0 && length(fig[[1]]) > 0) { path <- as.character(fig[[1]][[1]]) if (grepl("lifecycle", path)) { name <- gsub("lifecycle-", "", path) name <- path_ext_remove(name) # Translate the most common lifecylce names name <- switch(name, deprecated = tr_("deprecated"), superseded = tr_("superseded"), experimental = tr_("experimental"), stable = tr_("stable"), name ) return(name) } } NULL } extract_figure <- function(elements) { for (element in elements) { if (inherits(element, "tag_figure")) { return(element) } else if (inherits(element, "tag")) { child <- extract_figure(element) if (!is.null(child)) { return(child) } } } NULL } # Vignettes --------------------------------------------------------------- package_vignettes <- function(path = ".") { base <- path(path, "vignettes") if (!dir_exists(base)) { vig_path <- character() } else { vig_path <- dir_ls(base, regexp = "\\.[Rrq]md$", type = "file", recurse = TRUE) } vig_path <- path_rel(vig_path, base) vig_path <- vig_path[!grepl("^_", path_file(vig_path))] vig_path <- vig_path[!grepl("^tutorials", path_dir(vig_path))] type <- tolower(path_ext(vig_path)) meta <- purrr::map(path(base, vig_path), article_metadata) title <- purrr::map_chr(meta, "title") desc <- purrr::map_chr(meta, "desc") ext <- purrr::map_chr(meta, "ext") # Vignettes will be written to /articles/ with path relative to vignettes/ # *except* for vignettes in vignettes/articles, which are moved up a level file_in <- path("vignettes", vig_path) file_out <- path_ext_set(vig_path, ext) file_out[!path_has_parent(file_out, "articles")] <- path( "articles", file_out[!path_has_parent(file_out, "articles")] ) check_unique_article_paths(file_in, file_out) out <- tibble::tibble( name = as.character(path_ext_remove(vig_path)), type = type, file_in = as.character(file_in), file_out = as.character(file_out), title = title, description = desc, depth = dir_depth(file_out) ) out[order(path_file(out$file_out)), ] } article_metadata <- function(path) { if (path_ext(path) == "qmd") { inspect <- quarto::quarto_inspect(path) meta <- inspect$formats[[1]]$metadata out <- list( title = meta$title %||% "UNKNOWN TITLE", desc = meta$description %||% NA_character_, ext = path_ext(inspect$formats[[1]]$pandoc$`output-file`) %||% "html" ) } else { yaml <- rmarkdown::yaml_front_matter(path) out <- list( title = yaml$title[[1]] %||% "UNKNOWN TITLE", desc = yaml$description[[1]] %||% NA_character_, ext = yaml$pkgdown$extension %||% "html" ) } if (out$ext == "pdf") { out$title <- paste0(out$title, " (PDF)") } out } find_template_config <- function(package, bs_version = NULL, error_call = caller_env()) { if (is.null(package)) { return(list()) } config <- path_package_pkgdown( "_pkgdown.yml", package, bs_version, error_call = error_call ) if (!file_exists(config)) { return(list()) } yaml::yaml.load_file(config) %||% list() } check_unique_article_paths <- function(file_in, file_out) { if (!any(duplicated(file_out))) { return() } # Since we move vignettes/articles/* up one level, we may end up with two # vignettes destined for the same final location. We also know that if there # are conflicting final paths, they are the result of exactly two source files file_out_dup <- file_out[duplicated(file_out)] same_out_bullets <- purrr::map_chr(file_out_dup, function(f_out) { src_files <- src_path(file_in[which(file_out == f_out)]) src_files <- paste(src_files, collapse = " and ") }) names(same_out_bullets) <- rep_len("x", length(same_out_bullets)) cli::cli_abort( c( "Rendered articles must have unique names. Rename or relocate:", same_out_bullets ), call = caller_env() ) } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/deploy-site.R�����������������������������������������������������������������������������0000644�0001762�0000144�00000016711�14633374223�014522� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' Deploy a pkgdown site on Travis-CI to Github Pages #' #' @description #' `r lifecycle::badge('superseded')` #' #' `deploy_site_github()` was designed to deploy your site from Travis CI, #' which we no longer recommend, so this function is deprecated. There are #' two replacements: #' #' * [usethis::use_pkgdown_github_pages()] will setup a GitHub action to #' automatically build and deploy your package website to GitHub pages. #' #' * [deploy_to_branch()] can be called locally to build and deploy your #' website to any desired branch. #' #' @inheritParams build_site #' @param install Optionally, opt-out of automatic installation. This is #' necessary if the package you're documenting is a dependency of pkgdown #' @param tarball The location of the built package tarball. The default Travis #' configuration for R packages sets `PKG_TARBALL` to this path. #' @param ssh_id The private id to use, a base64 encoded content of the private #' pem file. This should _not_ be your personal private key. Instead create a #' new keypair specifically for deploying the site. The easiest way is to use #' `travis::use_travis_deploy()`. #' @param commit_message The commit message to be used for the commit. #' @param clean Clean all files from old site. #' @param verbose Print verbose output #' @param ... Additional arguments passed to [build_site()]. #' @param host The GitHub host url. #' @param repo_slug The `user/repo` slug for the repository. #' @export #' @keywords internal deploy_site_github <- function( pkg = ".", install = TRUE, tarball = Sys.getenv("PKG_TARBALL", ""), ssh_id = Sys.getenv("id_rsa", ""), commit_message = construct_commit_message(pkg), clean = FALSE, verbose = FALSE, host = "github.com", ..., repo_slug = Sys.getenv("TRAVIS_REPO_SLUG", "")) { rlang::check_installed("openssl") if (!nzchar(tarball)) { cli::cli_abort("No built tarball detected, please provide the location of one with {.var tarball}", call = caller_env()) } if (!nzchar(ssh_id)) { cli::cli_abort("No deploy key found, please setup with {.fn travis::use_travis_deploy}", call = caller_env()) } if (!nzchar(repo_slug)) { cli::cli_abort("No repo detected, please supply one with {.var repo_slug}", call = caller_env()) } cli::cli_alert("Deploying site to GitHub") if (install) { cli::cli_inform("Installing package") callr::rcmd("INSTALL", tarball, show = verbose, fail_on_status = TRUE) } ssh_id_file <- "~/.ssh/id_rsa" cli::cli_inform("Setting up SSH id") cli::cli_inform("Copying private key to {.file ssh_id_file}") write_lines(rawToChar(openssl::base64_decode(ssh_id)), ssh_id_file) cli::cli_inform("Setting private key permissions to 0600") file_chmod(ssh_id_file, "0600") cli::cli_inform("Setting remote to use the ssh url") git("remote", "set-url", "origin", sprintf("git@%s:%s.git", host, repo_slug)) deploy_to_branch( pkg, commit_message = commit_message, clean = clean, branch = "gh-pages", ... ) cli::cli_inform(c(v = "Deploy completed")) } #' Build and deploy a site locally #' #' Assumes that you're in a git clone of the project, and the package is #' already installed. Use [usethis::use_pkgdown_github_pages()] to automate #' this process using GitHub actions. #' #' @param branch The git branch to deploy to #' @param remote The git remote to deploy to #' @param github_pages Is this a GitHub pages deploy. If `TRUE`, adds a `CNAME` #' file for custom domain name support, and a `.nojekyll` file to suppress #' jekyll rendering. #' @param ... Additional arguments passed to [build_site()]. #' @param subdir The sub-directory where the site should be built on the branch. #' This argument can be used to support a number of site configurations. #' For example, you could build version-specific documentation by setting #' `subdir = "v1.2.3"`; `deploy_to_branch()` will build and deploy the #' package documentation in the `v.1.2.3/` directory of your site. #' @inheritParams build_site #' @inheritParams deploy_site_github #' @export deploy_to_branch <- function(pkg = ".", commit_message = construct_commit_message(pkg), clean = TRUE, branch = "gh-pages", remote = "origin", github_pages = (branch == "gh-pages"), ..., subdir = NULL) { dest_dir <- dir_create(file_temp()) on.exit(dir_delete(dest_dir)) if (!git_has_remote_branch(remote, branch)) { old_branch <- git_current_branch() # If no remote branch, we need to create it git("checkout", "--orphan", branch) git("rm", "-rf", "--quiet", ".") git("commit", "--allow-empty", "-m", sprintf("Initializing %s branch", branch)) git("push", remote, paste0("HEAD:", branch)) # checkout the previous branch git("checkout", old_branch) } # Explicitly set the branches tracked by the origin remote. # Needed if we are using a shallow clone, such as on travis-CI git("remote", "set-branches", "--add", remote, branch) git("fetch", remote, branch) github_worktree_add(dest_dir, remote, branch) on.exit(github_worktree_remove(dest_dir), add = TRUE) site_dest_dir <- if (!is.null(subdir)) { dir_create(path(dest_dir, subdir)) } else { dest_dir } pkg <- as_pkgdown(pkg, override = list(destination = site_dest_dir)) if (!is.null(subdir) && !is.null(pkg$meta$url)) { pkg$meta$url <- path(pkg$meta$url, subdir) } build_site_github_pages(pkg, ..., clean = clean) github_push(dest_dir, commit_message, remote, branch) invisible() } git_has_remote_branch <- function(remote, branch) { has_remote_branch <- git("ls-remote", "--quiet", "--exit-code", remote, branch, echo = FALSE, echo_cmd = FALSE, error_on_status = FALSE)$status == 0 } git_current_branch <- function() { branch <- git("rev-parse", "--abbrev-ref", "HEAD", echo = FALSE, echo_cmd = FALSE)$stdout sub("\n$", "", branch) } github_worktree_add <- function(dir, remote, branch) { cli::cli_inform("Adding worktree") git("worktree", "add", "--track", "-B", branch, dir, paste0(remote, "/", branch) ) } github_worktree_remove <- function(dir) { cli::cli_inform("Removing worktree") git("worktree", "remove", dir) } github_push <- function(dir, commit_message, remote, branch) { # force execution before changing working directory force(commit_message) cli::cli_inform("Commiting updated site") withr::with_dir(dir, { git("add", "-A", ".") git("commit", "--allow-empty", "-m", commit_message) cli::cli_alert("Deploying to GitHub Pages") git("remote", "-v") git("push", "--force", remote, paste0("HEAD:", branch)) }) } git <- function(..., echo_cmd = TRUE, echo = TRUE, error_on_status = TRUE) { callr::run("git", c(...), echo_cmd = echo_cmd, echo = echo, error_on_status = error_on_status) } construct_commit_message <- function(pkg = ".", commit = ci_commit_sha()) { pkg <- as_pkgdown(pkg) cli::format_inline("Built site for {pkg$package}@{pkg$version}: {substr(commit, 1, 7)}") } ci_commit_sha <- function() { env_vars <- c( # https://docs.travis-ci.com/user/environment-variables/#default-environment-variables "TRAVIS_COMMIT", # https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables "GITHUB_SHA" ) for (var in env_vars) { commit_sha <- Sys.getenv(var, "") if (commit_sha != "") return(commit_sha) } "" } �������������������������������������������������������pkgdown/R/init.R������������������������������������������������������������������������������������0000644�0001762�0000144�00000010762�14634573316�013234� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' Initialise site infrastructure #' #' @description #' `init_site()`: #' #' * creates the output directory (`docs/`), #' * generates a machine readable description of the site, used for autolinking, #' * copies CSS/JS assets and extra files, and #' * runs `build_favicons()`, if needed. #' #' Typically, you will not need to call this function directly, as all `build_*()` #' functions will run `init_site()` if needed. #' #' The only good reasons to call `init_site()` directly are the following: #' * If you add or modify a package logo. #' * If you add or modify `pkgdown/extra.scss`. #' * If you modify `template.bslib` variables in `_pkgdown.yml`. #' #' See `vignette("customise")` for the various ways you can customise the #' display of your site. #' #' # Build-ignored files #' We recommend using [usethis::use_pkgdown_github_pages()] to build-ignore `docs/` and #' `_pkgdown.yml`. If use another directory, or create the site manually, #' you'll need to add them to `.Rbuildignore` yourself. A `NOTE` about #' an unexpected file during `R CMD CHECK` is an indication you have not #' correctly ignored these files. #' #' @inheritParams build_articles #' @export init_site <- function(pkg = ".", override = list()) { # This is the only user facing function that doesn't call section_init() # because section_init() can conditionally call init_site() rstudio_save_all() cache_cli_colours() pkg <- as_pkgdown(pkg, override = override) cli::cli_rule("Initialising site") dir_create(pkg$dst_path) copy_assets(pkg) if (pkg$bs_version > 3) { build_bslib(pkg) } # Building favicons is expensive, so we hopefully only do it once, locally if (has_logo(pkg) && !has_favicons(pkg) && !on_ci()) { build_favicons(pkg) } copy_favicons(pkg) copy_logo(pkg) build_site_meta(pkg) invisible() } copy_assets <- function(pkg = ".") { pkg <- as_pkgdown(pkg) template <- config_pluck(pkg, "template") # pkgdown assets if (!identical(template$default_assets, FALSE)) { copy_asset_dir( pkg, path_pkgdown(paste0("BS", pkg$bs_version, "/", "assets")), src_root = path_pkgdown(), src_label = "<pkgdown>/" ) } # package assets if (!is.null(template$package)) { copy_asset_dir( pkg, path_package_pkgdown("assets", template$package, pkg$bs_version), src_root = system_file(package = template$package), src_label = paste0("<", template$package, ">/") ) } # extras copy_asset_dir(pkg, "pkgdown", file_regexp = "^extra") # site assets copy_asset_dir(pkg, "pkgdown/assets") invisible() } copy_asset_dir <- function(pkg, dir, src_root = pkg$src_path, src_label = "", file_regexp = NULL) { src_dir <- path_abs(dir, pkg$src_path) if (!file_exists(src_dir)) { return(character()) } src_paths <- dir_ls(src_dir, recurse = TRUE) src_paths <- src_paths[!is_dir(src_paths)] if (!is.null(file_regexp)) { src_paths <- src_paths[grepl(file_regexp, path_file(src_paths))] } src_paths <- src_paths[path_ext(src_paths) != "scss"] # Handled in bs_theme() dst_paths <- path(pkg$dst_path, path_rel(src_paths, src_dir)) file_copy_to( src_paths = src_paths, src_root = src_root, src_label = src_label, dst_paths = dst_paths, dst_root = pkg$dst_path ) } timestamp <- function(time = Sys.time()) { attr(time, "tzone") <- "UTC" strftime(time, "%Y-%m-%dT%H:%MZ", tz = "UTC") } # Generate site meta data file (available to website viewers) build_site_meta <- function(pkg = ".") { meta <- site_meta(pkg) # Install pkgdown.yml to ./inst if requested, install_metadata <- pkg$install_metadata %||% FALSE if (install_metadata) { path_meta <- path(pkg$src_path, "inst", "pkgdown.yml") dir_create(path_dir(path_meta)) write_yaml(meta, path_meta) } path_meta <- path(pkg$dst_path, "pkgdown.yml") write_yaml(meta, path_meta) invisible() } site_meta <- function(pkg) { article_index <- article_index(pkg) yaml <- list( pandoc = as.character(rmarkdown::pandoc_version()), pkgdown = as.character(utils::packageDescription("pkgdown", fields = "Version")), pkgdown_sha = utils::packageDescription("pkgdown")$GithubSHA1, articles = as.list(article_index), last_built = timestamp() ) url <- config_pluck_string(pkg, "url") if (!is.null(url)) { yaml$urls <- list( reference = paste0(url, "/reference"), article = paste0(url, "/articles") ) } print_yaml(yaml) } ��������������pkgdown/R/html-build.R������������������������������������������������������������������������������0000644�0001762�0000144�00000002031�14627633411�014313� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������a <- function(text, href) { ifelse(is.na(href), text, paste0("<a href='", href, "'>", text, "</a>")) } link_url <- function(text, href) { if (!is.null(href)) { paste0("<a href='", href, "'>", text, "</a>") } } linkify <- function(text) { text <- escape_html(text) text <- gsub( "<doi:([^&]+)>", # DOIs with < > & are not supported "<<a href='https://doi.org/\\1'>doi:\\1</a>>", text, ignore.case = TRUE ) text <- gsub( "<arXiv:([^&]+)>", "<<a href='https://arxiv.org/abs/\\1'>arXiv:\\1</a>>", text, ignore.case = TRUE ) text <- gsub( "<((http|ftp)[^&]+)>", # URIs with & are not supported "<<a href='\\1'>\\1</a>>", text ) text } dont_index <- function(x) { paste0("<div class='dont-index'>", x, "</div>") } escape_html <- function(x) { x <- gsub("&", "&", x) x <- gsub("<", "<", x) x <- gsub(">", ">", x) # x <- gsub("'", "'", x) # x <- gsub("\"", """, x) x } strip_html_tags <- function(x) gsub("<.*?>", "", x) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/utils.R�����������������������������������������������������������������������������������0000644�0001762�0000144�00000012421�14657466716�013435� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������up_path <- function(depth) { paste(rep.int("../", depth), collapse = "") } dir_depth <- function(x) { # length(strsplit(path, "/")[[1]]) - 1L purrr::map_int(strsplit(x, ""), function(x) sum(x == "/")) } invert_index <- function(x) { stopifnot(is.list(x)) if (length(x) == 0) return(list()) key <- rep(names(x), purrr::map_int(x, length)) val <- unlist(x, use.names = FALSE) split(key, val) } rstudio_save_all <- function() { if (is_installed("rstudioapi") && rstudioapi::hasFun("documentSaveAll")) { rstudioapi::documentSaveAll() } } is_syntactic <- function(x) x == make.names(x) auto_quote <- function(x) { ifelse(is_syntactic(x), x, paste0("`", x, "`")) } str_trim <- function(x) gsub("^\\s+|\\s+$", "", x) str_squish <- function(x) str_trim(gsub("\\s+", " ", x)) unwrap_purrr_error <- function(code) { withCallingHandlers( code, purrr_error_indexed = function(err) { cnd_signal(err$parent) } ) } tr_ <- function(...) { enc2utf8(gettext(..., domain = "R-pkgdown")) } # devtools metadata ------------------------------------------------------- system_file <- function(..., package) { if (is.null(devtools_meta(package))) { path(system.file(package = package), ...) } else { path(getNamespaceInfo(package, "path"), "inst", ...) } } devtools_meta <- function(x) { ns <- .getNamespace(x) ns[[".__DEVTOOLS__"]] } # CLI --------------------------------------------------------------------- dst_path <- cli::combine_ansi_styles( cli::style_bold, cli::col_cyan ) src_path <- cli::combine_ansi_styles( cli::style_bold, cli::col_green ) writing_file <- function(path, show) { path <- as.character(path) text <- dst_path(as.character(show)) cli::cli_inform("Writing {.run [{text}](pkgdown::preview_site(path='{path}'))}") } has_internet <- function() { getOption("pkgdown.internet", default = TRUE) } modify_list <- function(x, y) { if (is.null(x)) { return(y) } else if (is.null(y)) { return(x) } utils::modifyList(x, y) } # from https://github.com/r-lib/rematch2/blob/8098bd06f251bfe0f20c0598d90fc20b741d13f8/R/package.R#L47 re_match <- function(text, pattern, perl = TRUE, ...) { stopifnot(is.character(pattern), length(pattern) == 1, !is.na(pattern)) text <- as.character(text) match <- regexpr(pattern, text, perl = perl, ...) start <- as.vector(match) length <- attr(match, "match.length") end <- start + length - 1L matchstr <- substring(text, start, end) matchstr[ start == -1 ] <- NA_character_ res <- data.frame( .text = text, .match = matchstr ) if (!is.null(attr(match, "capture.start"))) { gstart <- attr(match, "capture.start") glength <- attr(match, "capture.length") gend <- gstart + glength - 1L groupstr <- substring(text, gstart, gend) groupstr[ gstart == -1 ] <- NA_character_ dim(groupstr) <- dim(gstart) res <- cbind(groupstr, res) } names(res) <- c(attr(match, "capture.names"), ".text", ".match") class(res) <- c("tbl_df", "tbl", class(res)) res } # external links can't be an active item # external links start with http(s) # but are NOT an absolute URL to the pkgdown site at hand is_internal_link <- function(links, pkg) { if (is.null(pkg$meta$url)) { !grepl("https?://", links) } else { !grepl("https?://", links) | grepl(pkg$meta$url, links) } } ruler <- function(width = getOption("width")) { x <- seq_len(width) y <- rep("-", length(x)) y[x %% 5 == 0] <- "+" y[x %% 10 == 0] <- (x[x%%10 == 0] %/% 10) %% 10 cat(y, "\n", sep = "") cat(x %% 10, "\n", sep = "") } get_section_level <- function(section) { class <- xml2::xml_attr(section, "class") level <- as.numeric(re_match(class, "level(\\d+)")[[1]]) level[is.na(level)] <- 0 level } section_id <- function(section) { h <- xml2::xml_find_first(section, ".//h1|.//h2|.//h3|.//h4|.//h5|.//h6") xml2::xml_attr(h, "id") } on_ci <- function() { isTRUE(as.logical(Sys.getenv("CI", "false"))) } # yaml ------------------------------------------------------------ print_yaml <- function(x) { structure(x, class = "print_yaml") } #' @export print.print_yaml <- function(x, ...) { cat(yaml::as.yaml(x), "\n", sep = "") } write_yaml <- function(x, path) { yaml::write_yaml( x, path, handlers = list(logical = yaml::verbatim_logical) ) } # Helpers for testing ----------------------------------------------------- xpath_xml <- function(x, xpath = NULL) { if (!is.null(xpath)) { x <- xml2::xml_find_all(x, xpath) } structure(x, class = c("pkgdown_xml", class(x))) } xpath_contents <- function(x, xpath) { x <- xml2::xml_find_all(x, xpath) contents <- xml2::xml_contents(x) if (length(contents) == 0) { NULL } else { xml2str(contents) } } xml2str <- function(x) { strings <- as.character(x, options = c("format", "no_declaration")) paste0(strings, collapse = "") } xpath_attr <- function(x, xpath, attr) { gsub("\r", "", xml2::xml_attr(xml2::xml_find_all(x, xpath), attr), fixed = TRUE) } xpath_text <- function(x, xpath, trim = FALSE) { xml2::xml_text(xml2::xml_find_all(x, xpath), trim = trim) } xpath_length <- function(x, xpath) { length(xml2::xml_find_all(x, xpath)) } #' @export print.pkgdown_xml <- function(x, ...) { cat(as.character(x, options = c("format", "no_declaration")), sep = "\n") invisible(x) } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/rd-data.R���������������������������������������������������������������������������������0000644�0001762�0000144�00000005771�14633374223�013604� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������as_data <- function(x, ...) { UseMethod("as_data") } #' @export as_data.NULL <- function(x, ...) { NULL } # Sections ---------------------------------------------------------------- parse_section <- function(x, title, ...) { text <- flatten_para(x, ...) list( title = title, contents = text ) } #' @export as_data.tag_details <- function(x, ...) { parse_section(x, tr_("Details"), ...) } #' @export as_data.tag_description <- function(x, ...) { parse_section(x, tr_("Description"), ...) } #' @export as_data.tag_references <- function(x, ...) { parse_section(x, tr_("References"), ...) } #' @export as_data.tag_source <- function(x, ...) { parse_section(x, tr_("Source"), ...) } #' @export as_data.tag_format <- function(x, ...) { parse_section(x, tr_("Format"), ...) } #' @export as_data.tag_note <- function(x, ...) { parse_section(x, tr_("Note"), ...) } #' @export as_data.tag_author <- function(x, ...) { parse_section(x, tr_("Author"), ...) } #' @export as_data.tag_seealso <- function(x, ...) { section <- parse_section(x, tr_("See also"), ...) section$contents <- dont_index(section$contents) section } #' @export as_data.tag_section <- function(x, ...) { parse_section(x[[2]], as_html(x[[1]], ...), ...) } # \arguments{} & \details{} ----------------------------------------------- # Both are like the contents of \description{} but can contain arbitrary # text outside of \item{} #' @export as_data.tag_arguments <- function(x, ...) { list( title = tr_("Arguments"), contents = describe_contents(x, ..., id_prefix = "arg-") ) } #' @export as_data.tag_value <- function(x, ...) { list( title = tr_("Value"), contents = describe_contents(x, ...) ) } describe_contents <- function(x, ..., id_prefix = NULL) { if (length(x) == 0) { return("") } # Group contiguous \items{}/whitespace into a <dl>; everything else # is handled as is block_id <- integer(length(x)) block_id[[1]] <- 1 cur_block_is_dl <- inherits(x[[1]], "tag_item") for (i in seq2(2, length(x))) { is_item <- inherits(x[[i]], "tag_item") if (cur_block_is_dl) { same_type <- is_item || is_whitespace(x[[i]]) } else { same_type <- !is_item } if (same_type) { block_id[[i]] <- block_id[[i - 1]] } else { block_id[[i]] <- block_id[[i - 1]] + 1 cur_block_is_dl <- !cur_block_is_dl } } parse_block <- function(x) { is_dl <- any(purrr::map_lgl(x, inherits, "tag_item")) if (is_dl) { paste0( "<dl>\n", parse_descriptions(x, ..., id_prefix = id_prefix), "</dl>" ) } else { flatten_para(x, ...) } } blocks <- split(x, block_id) out <- purrr::map(blocks, parse_block) paste(unlist(out), collapse = "\n") } is_whitespace <- function(x) { inherits(x, "TEXT") && all(grepl("^\\s*$", x)) } # For testing value2html <- function(x) { rd <- rd_text(paste0("\\value{", x, "}"), fragment = FALSE)[[1]] html <- as_data(rd)$contents str_trim(strsplit(str_trim(html), "\n")[[1]]) } �������pkgdown/R/build-github.R����������������������������������������������������������������������������0000644�0001762�0000144�00000003357�14633374223�014645� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' Build site for GitHub pages #' #' @description #' Designed to be run as part of automated workflows for deploying #' to GitHub pages. It cleans out the old site, builds the site into `dest_dir` #' adds a `.nojekyll` file to suppress rendering by Jekyll, and adds a `CNAME` #' file if needed. #' #' It is designed to be run in CI, so by default it: #' #' * Cleans out the old site. #' * Does not install the package. #' * Runs [build_site()] in process. #' #' @inheritParams build_site #' @inheritParams deploy_to_branch #' @param dest_dir Directory to build site in. #' @export build_site_github_pages <- function(pkg = ".", ..., dest_dir = "docs", clean = TRUE, install = FALSE, new_process = FALSE) { pkg <- as_pkgdown(pkg, override = list(destination = dest_dir)) if (clean) { cli::cli_rule("Cleaning files from old site") clean_site(pkg) } build_site(pkg, preview = FALSE, install = install, new_process = new_process, ...) build_github_pages(pkg) invisible() } build_github_pages <- function(pkg = ".") { cli::cli_rule("Extra files for GitHub pages") pkg <- as_pkgdown(pkg) # Add .nojekyll since site is static HTML write_if_different(pkg, "", ".nojekyll", check = FALSE) # Add CNAME if url present cname <- cname_url(config_pluck_string(pkg, "url")) if (is.null(cname)) { return(invisible()) } write_if_different(pkg, cname, "CNAME", check = FALSE) invisible() } cname_url <- function(url) { if (is.null(url)) return(NULL) pieces <- xml2::url_parse(url) if (!pieces$path %in% c("", "/")) return(NULL) pieces$server } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/tweak-homepage.R��������������������������������������������������������������������������0000644�0001762�0000144�00000006643�14633374223�015165� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tweak_homepage_html <- function(html, strip_header = FALSE, sidebar = TRUE, show_badges = TRUE, bs_version = 3, logo = NULL) { html <- tweak_sidebar_html(html, sidebar = sidebar, show_badges = show_badges) # Always remove dummy page header header <- xml2::xml_find_all(html, ".//div[contains(@class, 'page-header')]") if (length(header) > 0) xml2::xml_remove(header, free = TRUE) header <- xml2::xml_find_first(html, ".//h1") if (strip_header) { page_header <- xml2::xml_remove(header, free = TRUE) } else { page_header <- xml2::xml_add_parent(header, "div", class = "page-header") } if (!is.null(logo) && bs_version > 3) { # Remove logo if added to h1 # Bare image xml2::xml_remove(xml2::xml_find_all(html, ".//h1/img[contains(@src, 'logo')]")) # Image in link xml2::xml_remove( xml2::xml_parent( xml2::xml_find_all(html, ".//h1/a/img[contains(@src, 'logo')]") ) ) # Add back to header xml2::xml_add_sibling(page_header, "img", src = logo, class = "logo", alt = "", .where = "before" ) } invisible() } tweak_sidebar_html <- function(html, sidebar = TRUE, show_badges = TRUE) { if (!sidebar) { return(html) } # this extracts *and removes* badges from HTML badges <- badges_extract(html) dev_status_html <- xml2::xml_find_first(html, ".//div[@class='dev-status']") if (inherits(dev_status_html, "xml_missing")) { return(html) } if (!show_badges || length(badges) == 0) { xml2::xml_remove(dev_status_html) } else { list <- sidebar_section(tr_("Dev status"), badges) list_html <- xml2::xml_find_first(xml2::read_html(list, encoding = "UTF-8"), ".//div") xml2::xml_replace(dev_status_html, list_html) } html } # Mutates `html`, removing the badge container badges_extract <- function(html) { # First try specially named element; x <- xml2::xml_find_first(html, "//div[@id='badges']") strict <- FALSE # then try usethis-readme-like more complex structure; if (length(x) == 0) { # Find start comment, then all elements after # which are followed by the end comment. x <- xml2::xml_find_all(html, " //comment()[contains(., 'badges: start')][1] /following-sibling::*[following-sibling::comment()[contains(., 'badges: end')]] ") } # then try usethis-readme-like paragraph; # where the badges: end comment is inside the paragraph after badges: start if (length(x) == 0) { x <- xml2::xml_find_all(html, ".//*/comment()[contains(., 'badges: start')]/following-sibling::p[1]") } # finally try first paragraph if (length(x) == 0) { # BS5 (main) and BS3 (div) x <- xml2::xml_find_first(html, "//main/p|//div[@class='contents col-md-9']/p") strict <- TRUE } # No paragraph if (length(x) == 0) { return(character()) } # If we guessed the element, # we only proceed if there is no text if (strict && any(xml2::xml_text(x, trim = TRUE) != "")) { return(character()) } # Proceed if we find image-containing links badges <- xml2::xml_find_all(x, ".//a[img]") if (length(badges) == 0) { return(character()) } xml2::xml_remove(x) as.character(badges) } badges_extract_text <- function(x) { html <- xml2::read_html(x, encoding = "UTF-8") badges_extract(html) } ���������������������������������������������������������������������������������������������pkgdown/R/build-logo.R������������������������������������������������������������������������������0000644�0001762�0000144�00000001421�14633374223�014311� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������copy_logo <- function(pkg = ".") { pkg <- as_pkgdown(pkg) logo_path <- find_logo(pkg$src_path) if (!is.null(logo_path)) { file_copy_to( src_paths = logo_path, src_root = pkg$src_path, dst_paths = path(pkg$dst_path, path_file(logo_path)), dst_root = pkg$dst_path ) } } find_logo <- function(path) { path_first_existing( c( path(path, "logo.svg"), path(path, "man", "figures", "logo.svg"), path(path, "logo.png"), path(path, "man", "figures", "logo.png") ) ) } has_logo <- function(pkg) { logo_path <- find_logo(pkg$src_path) !is.null(logo_path) } logo_path <- function(pkg, depth) { path <- find_logo(pkg$src_path) if (is.null(path)) { return() } paste0(up_path(depth), path_file(path)) } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/config.R����������������������������������������������������������������������������������0000644�0001762�0000144�00000015500�14633374223�013524� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������config_pluck <- function(pkg, path, default = NULL) { check_string(path, allow_empty = FALSE, .internal = TRUE) where <- strsplit(path, ".", fixed = TRUE)[[1]] purrr::pluck(pkg$meta, !!!where, .default = default) } config_pluck_list <- function(pkg, path, has_names = NULL, default = NULL, call = caller_env()) { check_string(path, allow_empty = FALSE, .internal = TRUE) x <- config_pluck(pkg, path, default) config_check_list( x, has_names = has_names, error_path = path, error_pkg = pkg, error_call = call ) } config_pluck_character <- function(pkg, path, default = character(), call = caller_env()) { x <- config_pluck(pkg, path, default) config_check_character( x, error_path = path, error_pkg = pkg, error_call = call ) } config_pluck_string <- function(pkg, path, default = NULL, call = caller_env()) { x <- config_pluck(pkg, path, default) config_check_string( x, error_path = path, error_pkg = pkg, error_call = call ) } config_pluck_markdown_inline <- function(pkg, path, default = NULL, call = caller_env()) { text <- config_pluck_string(pkg, path, default, call = call) markdown_text_inline(pkg, text, error_path = path, error_call = call) } config_pluck_markdown_block <- function(pkg, path, default = NULL, call = caller_env()) { text <- config_pluck_string(pkg, path, default, call = call) markdown_text_block(pkg, text) } config_pluck_bool <- function(pkg, path, default = NULL, call = caller_env()) { x <- config_pluck(pkg, path, default) config_check_bool( x, error_path = path, error_pkg = pkg, error_call = call ) } config_pluck_number_whole <- function(pkg, path, default = NULL, call = caller_env()) { x <- config_pluck(pkg, path, default) config_check_number_whole( x, error_path = path, error_pkg = pkg, error_call = call ) } # checks --------------------------------------------------------------------- config_check_character <- function(x, error_pkg, error_path, error_call = caller_env()) { if (is.character(x) || is.null(x)) { x } else if (identical(x, list())) { character() } else { config_abort_type( must_be = "a character vector", not = x, error_pkg = error_pkg, error_path = error_path, error_call = error_call ) } } config_check_string <- function(x, error_pkg, error_path, error_call = caller_env()) { if (is_string(x) || is.null(x)) { x } else { config_abort_type( must_be = "a string", not = x, error_pkg = error_pkg, error_path = error_path, error_call = error_call ) } } config_check_bool <- function(x, error_pkg, error_path, error_call = caller_env()) { if (is_bool(x) || is.null(x)) { x } else { config_abort_type( must_be = "true or false", not = x, error_pkg = error_pkg, error_path = error_path, error_call = error_call ) } } config_check_number_whole <- function(x, error_pkg, error_path, error_call = caller_env()) { is_whole <- (0 == (exit_code <- .standalone_types_check_dot_call( ffi_standalone_check_number_1.0.7, x, allow_decimal = FALSE, min = NULL, max = NULL, allow_infinite = FALSE, allow_na = FALSE, allow_null = TRUE ))) if (is_whole) { x } else { config_abort_type( must_be = "a whole number", not = x, error_pkg = error_pkg, error_path = error_path, error_call = error_call ) } } config_check_list <- function(x, has_names = NULL, error_pkg, error_path, error_call = caller_env()) { if (is_list(x) || is.null(x)) { if (!is.null(has_names) && !all(has_name(x, has_names))) { missing <- setdiff(has_names, names(x)) config_abort( error_pkg, c( "{.field {error_path}} must have {cli::qty(has_names)} component{?s} {.str {has_names}}.", "{length(missing)} missing component{?s}: {.str {missing}}." ), call = error_call ) } else { x } } else { not <- obj_type_friendly(x) config_abort( error_pkg, "{.field {error_path}} must be a list, not {not}.", call = error_call ) } } config_abort_type <- function(must_be, not, error_pkg, error_path, error_call) { not_str <- obj_type_friendly(not) config_abort( error_pkg, "{.field {error_path}} must be {must_be}, not {not_str}.", call = error_call ) } # generic error --------------------------------------------------------------- config_abort <- function(pkg, message, path = NULL, ..., call = caller_env(), .envir = caller_env()) { message <- config_message(pkg, message, path) cli::cli_abort(message, ..., call = call, .envir = .envir) } config_warn <- function(pkg, message, path = NULL, ..., call = caller_env(), .envir = caller_env()) { message <- config_message(pkg, message, path) cli::cli_warn(message, ..., call = call, .envir = .envir) } config_message <- function(pkg, message, path = NULL) { # Not all projects necessary have a _pkgdown.yml (#2542) path <- path %||% pkgdown_config_path(pkg) %||% "_pkgdown.yml" if (is_absolute_path(path)) { path_label <- path_rel(path, pkg$src_path) } else { path_label <- path } link <- cli::style_hyperlink(path_label, paste0("file://", path)) message[[1]] <- paste0("In ", link, ", ", message[[1]]) message } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/pkgdown-package.R�������������������������������������������������������������������������0000644�0001762�0000144�00000000501�14633374223�015314� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' @keywords internal "_PACKAGE" ## usethis namespace: start #' @importFrom utils installed.packages #' @import rlang #' @import fs ## usethis namespace: end NULL release_bullets <- function() { c( "Check that [test/widget.html](https://pkgdown.r-lib.org/dev/articles/) responds to mouse clicks on 5/10/50" ) } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/build-search-docs.R�����������������������������������������������������������������������0000644�0001762�0000144�00000024301�14634573316�015553� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������build_docsearch_json <- function(pkg = ".") { pkg <- as_pkgdown(pkg) index_name <- config_pluck_string(pkg, "template.params.docsearch.index_name") if (is.null(index_name)) { return() } data <- list( index = index_name, package = pkg$package, url = config_pluck_string(pkg, "url") ) template <- find_template("config", "docsearch", ext = ".json", pkg = pkg) json <- render_template(template, data) json_path <- path(pkg$dst_path, "docsearch.json") write_if_different(pkg, json, json_path, check = FALSE) } build_sitemap <- function(pkg = ".") { pkg <- as_pkgdown(pkg) url <- paste0(config_pluck_string(pkg, "url"), "/") if (is.null(url)) { return() } cli::cli_rule("Building sitemap") if (pkg$development$in_dev && pkg$bs_version > 3) { url <- paste0(url, pkg$prefix) } urls <- paste0(url, get_site_paths(pkg)) doc <- paste0( "<urlset xmlns = 'http://www.sitemaps.org/schemas/sitemap/0.9'>\n", paste0("<url><loc>", escape_html(urls), "</loc></url>\n", collapse = ""), "</urlset>\n" ) write_if_different(pkg, doc, "sitemap.xml", check = FALSE) invisible() } #' Build search index #' #' @description #' Generate a JSON search index from the built site. This is used by #' [fuse.js](https://www.fusejs.io/) to provide a javascript powered search for #' BS5 powered pkgdown sites. #' #' NB: `build_search()` is called automatically by [build_site()]; you don't #' need call it yourself. This page documents how it works and its customisation #' options. #' #' # YAML config #' You can exclude some paths from the search index using `search.exclude`. #' Below we exclude the changelog from the search index: #' #' ```yaml #' search: #' exclude: ['news/index.html'] #' ``` #' # Debugging and local testing #' #' Locally (as opposed to on GitHub Pages or Netlify for instance), #' search won't work if you simply use pkgdown preview of the static files. #' You can use `servr::httw("docs")` instead. #' #' If search is not working, run `pkgdown::pkgdown_sitrep()` to eliminate #' common issues such as the absence of URL in the pkgdown configuration file #' of your package. #' #' @inheritParams build_articles #' @export #' build_search <- function(pkg = ".", override = list()) { pkg <- section_init(pkg, override = override) cli::cli_rule("Building search index") search_index <- build_search_index(pkg) jsonlite::write_json( search_index, path(pkg$dst_path, "search.json"), auto_unbox = TRUE ) } build_search_index <- function(pkg) { paths <- get_site_paths(pkg) paths <- paths[!paths %in% c("404.html", "articles/index.html", "reference/index.html")] # user-defined exclusions paths <- paths[!paths %in% config_pluck_character(pkg, "search.exclude")] if ("news/index.html" %in% paths) { index <- lapply(paths[paths != "news/index.html"], file_search_index, pkg = pkg) index <- unlist(index, recursive = FALSE) index <- c(index, news_search_index("news/index.html", pkg = pkg)) } else { index <- lapply(paths, file_search_index, pkg = pkg) index <- unlist(index, recursive = FALSE) } # Make URLs absolute if possible url <- config_pluck_string(pkg, "url", default = "") fix_path <- function(x) { x$path <- sprintf("%s%s", url, x$path) x } purrr::map(index, fix_path) } news_search_index <- function(path, pkg) { html <- xml2::read_html(path(pkg$dst_path, path), encoding = "UTF-8") # Get contents minus logo node <- xml2::xml_find_all(html, ".//main") xml2::xml_remove(xml2::xml_find_first(node, ".//img[contains(@class, 'pkg-logo')]")) sections <- xml2::xml_find_all(node, ".//*[contains(@class, 'section')]") purrr::pmap( list( sections, purrr::map_chr(sections, get_headings, depth = 4), title = purrr::map_chr(sections, get_version) ), bs4_index_data, dir = "Changelog", path = paste0("/", pkg$prefix, path) ) } file_search_index <- function(path, pkg) { html <- xml2::read_html(path(pkg$dst_path, path), encoding = "UTF-8") # Get page title title_element <- xml2::xml_find_first(html, ".//meta[@property='og:title']") title <- xml2::xml_attr(title_element, "content") # Get contents minus logo node <- xml2::xml_find_all(html, ".//main") xml2::xml_remove(xml2::xml_find_first(node, ".//img[contains(@class, 'pkg-logo')]")) sections <- xml2::xml_find_all(node, ".//div[contains(@class, 'section')]|.//section") purrr::pmap( list( sections, purrr::map_chr(sections, get_headings, depth = 3), title = title ), bs4_index_data, dir = get_dir(path), path = paste0("/", pkg$prefix, path) ) } # Directory parts (where in the site) get_dir <- function(path) { dir <- path_dir(path) if (dir == ".") { return("") } paste(capitalise(unlist(path_split(dir))), collapse = " > ") } # Headings (where in the page) get_headings <- function(section, depth) { level <- get_section_level(section) if (level < depth) { return("") } headings <- purrr::map_chr(seq(depth - 1, level - 1), get_h, section = section) paste0(headings[headings != ""], collapse = " > ") } # Function for extracting all headers get_h <- function(level, section) { parents <- xml2::xml_parents(section) if (length(parents) == 0) { return("") } parents <- parents[!is.na(xml2::xml_attr(parents, "class"))] h_section <- parents[grepl(paste0("section level", level), xml2::xml_attr(parents, "class"))] h <- xml2::xml_contents(h_section)[is_heading(xml2::xml_contents(h_section))] sub("^\\n", "", xml_text1(h)) } get_version <- function(section) { parents <- xml2::xml_parents(section) parents <- parents[!is.na(xml2::xml_attr(parents, "class"))] h_section <- parents[grepl("section level2", xml2::xml_attr(parents, "class"))] if (length(h_section) == 0) { h <- xml2::xml_contents(section)[is_heading(xml2::xml_contents(section))] } else { h <- xml2::xml_contents(h_section)[is_heading(xml2::xml_contents(h_section))] } sub("^\\n", "", xml_text1(h)) } # edited from https://github.com/rstudio/bookdown/blob/abd461593033294d82427139040a0a03cfa0390a/R/bs4_book.R#L518 # index ------------------------------------------------------------------- bs4_index_data <- function(node, previous_headings, title, dir, path) { # Make a copy of the node because we will remove contents from it for getting the data node_copy <- node # remove sections nested inside the current section to prevent duplicating content xml2::xml_remove(xml2::xml_find_all(node_copy, ".//*[contains(@class, 'section')]")) # remove dont-index sections xml2::xml_remove(xml2::xml_find_all(node_copy, ".//*[contains(@class, 'dont-index')]")) # Helpers for XPath queries # We want to find all nodes corresponding to ... but whose descendants # do not correspond to any ... otherwise we would treat some text/code twice, # e.g. the text of p nested within li. all <- function(...) { not <- sprintf("[not(%s)]", paste0(paste0("descendant::", c(...)), collapse = "|")) paste0(".//", c(...), not, collapse = "|") } text_xpath <- all("p", "li", "caption", "figcaption", "dt", "dd", "blockquote", "div[contains(@class, 'line-block')]") code_xpath <- all("pre") code <- xml2::xml_find_all(node_copy, code_xpath) # Special case for definitions (mostly encountered in Rd files) if (xml2::xml_name(node_copy) == "dt") { # both argument name and definition text <- paste( xml_text1(node_copy), xml_text1(xml2::xml_find_first(node_copy, "following-sibling::*")), collapse = " " ) heading <- paste(xml_text1(node_copy), "(argument)") } else { # Other cases text <- xml_text1(xml2::xml_find_all(node_copy, text_xpath)) children <- xml2::xml_children(node_copy) heading_node <- children[purrr::map_lgl(children, is_heading)][1] heading <- xml_text1(heading_node) # Add heading for Usage section of Rd if (xml2::xml_attr(node_copy, "id", default = "") == "ref-usage") { heading <- "Usage" } } # If no specific heading, use the title if (nchar(heading) == 0) { heading <- title previous_headings <- "" } index_data <- list( path = path, id = section_id(node_copy), dir = dir, previous_headings = previous_headings, what = heading, title = title, text = strip_stop_words(text), code = xml_text1(code) ) if (index_data$text == "" && index_data$code == "") { return(NULL) } index_data } xml_text1 <- function(x) { trimws( gsub("(\r\n|\r|\n)", " ", paste0(trimws(xml2::xml_text(x)), collapse = " ") ) ) } strip_stop_words <- function(x) { # paste(tidytext::get_stopwords()$word, collapse = "|") pattern <- "\\b(i|me|my|myself|we|our|ours|ourselves|you|your|yours|yourself|yourselves|he|him|his|himself|she|her|hers|herself|it|its|itself|they|them|their|theirs|themselves|what|which|who|whom|this|that|these|those|am|is|are|was|were|be|been|being|have|has|had|having|do|does|did|doing|would|should|could|ought|i'm|you're|he's|she's|it's|we're|they're|i've|you've|we've|they've|i'd|you'd|he'd|she'd|we'd|they'd|i'll|you'll|he'll|she'll|we'll|they'll|isn't|aren't|wasn't|weren't|hasn't|haven't|hadn't|doesn't|don't|didn't|won't|wouldn't|shan't|shouldn't|can't|cannot|couldn't|mustn't|let's|that's|who's|what's|here's|there's|when's|where's|why's|how's|a|an|the|and|but|if|or|because|as|until|while|of|at|by|for|with|about|against|between|into|through|during|before|after|above|below|to|from|up|down|in|out|on|off|over|under|again|further|then|once|here|there|when|where|why|how|all|any|both|each|few|more|most|other|some|such|no|nor|not|only|own|same|so|than|too|very|will)\\b ?" gsub(pattern, "", x, ignore.case = TRUE) } is_heading <- function(node) { xml2::xml_name(node) %in% c("h1", "h2", "h3", "h4", "h5") } capitalise <- function(string) { paste0(toupper(substring(string, 1, 1)), substring(string, 2)) } get_site_paths <- function(pkg) { paths <- dir_ls(pkg$dst_path, glob = "*.html", recurse = TRUE) paths_rel <- path_rel(paths, pkg$dst_path) # do not include dev package website in search index / sitemap paths_rel <- paths_rel[!path_has_parent(paths_rel, pkg$development$destination)] # do not include redirects redirects <- purrr::map_chr(data_redirects(pkg, has_url = TRUE), 1) setdiff(paths_rel, redirects) } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/build-article.R���������������������������������������������������������������������������0000644�0001762�0000144�00000021171�14641277402�015000� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' @order 2 #' @export #' @rdname build_articles #' @param name Name of article to render. This should be either a path #' relative to `vignettes/` without extension, or `index` or `README`. #' @param new_process Build the article in a clean R process? The default, #' `TRUE`, ensures that every article is build in a fresh environment, but #' you may want to set it to `FALSE` to make debugging easier. #' @param pandoc_args Pass additional arguments to pandoc. Used for testing. build_article <- function(name, pkg = ".", lazy = FALSE, seed = 1014L, new_process = TRUE, pandoc_args = character(), override = list(), quiet = TRUE) { pkg <- section_init(pkg, "articles", override = override) # Look up in pkg vignette data - this allows convenient automatic # specification of depth, output destination, and other parameters that # allow code sharing with building of the index. vig <- match(name, pkg$vignettes$name) if (is.na(vig)) { cli::cli_abort("Can't find article {.file {name}}") } input <- pkg$vignettes$file_in[vig] output_file <- pkg$vignettes$file_out[vig] depth <- pkg$vignettes$depth[vig] type <- pkg$vignettes$type[vig] input_path <- path_abs(input, pkg$src_path) output_path <- path_abs(output_file, pkg$dst_path) if (lazy && !out_of_date(input_path, output_path)) { return(invisible()) } if (type == "rmd") { build_rmarkdown_article( pkg = pkg, input_file = input, input_path = input_path, output_file = output_file, output_path = output_path, depth = depth, seed = seed, new_process = new_process, pandoc_args = pandoc_args, quiet = quiet ) } else { build_quarto_articles(pkg = pkg, article = name, quiet = quiet) } } build_rmarkdown_article <- function(pkg, input_file, input_path, output_file, output_path, depth, seed = NULL, new_process = TRUE, pandoc_args = character(), quiet = TRUE, call = caller_env() ) { cli::cli_inform("Reading {src_path(input_file)}") digest <- file_digest(output_path) data <- data_article(pkg, input_file, call = call) if (data$as_is) { if (identical(data$ext, "html")) { setup <- rmarkdown_setup_custom(pkg, input_path, depth = depth, data = data) } else { setup <- list(format = NULL, options = NULL) } } else { setup <- rmarkdown_setup_pkgdown(pkg, depth = depth, data = data, pandoc_args = pandoc_args) } local_envvar_pkgdown(pkg) local_texi2dvi_envvars(input_path) withr::local_envvar(R_CLI_NUM_COLORS = 256) args <- list( input = input_path, output_file = path_file(output_path), output_dir = path_dir(output_path), intermediates_dir = tempdir(), encoding = "UTF-8", seed = seed, output_format = setup$format, output_options = setup$options, quiet = quiet ) if (new_process) { path <- withCallingHandlers( callr::r_safe(rmarkdown_render_with_seed, args = args, show = !quiet), error = function(cnd) wrap_rmarkdown_error(cnd, input_file, call) ) } else { path <- inject(rmarkdown_render_with_seed(!!!args)) } is_html <- identical(path_ext(path)[[1]], "html") if (is_html) { local_options_link(pkg, depth = depth) update_html( path, tweak_rmarkdown_html, input_path = path_dir(input_path), pkg = pkg ) # Need re-active navbar now that we now the target path update_html(path, function(html) { activate_navbar(html, path_rel(path, pkg$dst_path), pkg) }) } if (digest != file_digest(output_path)) { writing_file(path_rel(output_path, pkg$dst_path), output_file) } if (is_html) { copy_article_images(path, input_path, output_path) check_missing_images(pkg, input_path, output_file) } invisible(path) } data_article <- function(pkg, input, call = caller_env()) { yaml <- rmarkdown::yaml_front_matter(path_abs(input, pkg$src_path)) opengraph <- check_open_graph(pkg, yaml$opengraph, input, call = call) opengraph$description <- opengraph$description %||% yaml$description list( opengraph = opengraph, pagetitle = escape_html(yaml$title), toc = yaml$toc %||% TRUE, source = repo_source(pkg, input), filename = path_file(input), as_is = isTRUE(purrr::pluck(yaml, "pkgdown", "as_is")), ext = purrr::pluck(yaml, "pkgdown", "extension", .default = "html") ) } rmarkdown_setup_custom <- function(pkg, input_path, depth = 1L, data = list(), env = caller_env()) { template <- rmarkdown_template(pkg, depth = depth, data = data, env = env) # Override defaults & values supplied in metadata options <- list( template = template, self_contained = FALSE ) output <- rmarkdown::default_output_format(input_path) if (output$name != "rmarkdown::html_vignette") { # Force to NULL unless overridden by user options$theme <- output$options$theme } list(format = NULL, options = options) } rmarkdown_setup_pkgdown <- function(pkg, depth = 1L, data = list(), pandoc_args = character(), env = caller_env()) { template <- rmarkdown_template(pkg, depth = depth, data = data, env = env) format <- rmarkdown::html_document( self_contained = FALSE, theme = NULL, template = template, anchor_sections = FALSE, math_method = config_math_rendering(pkg), extra_dependencies = bs_theme_deps_suppress(), pandoc_args = pandoc_args ) format$knitr$opts_chunk <- fig_opts_chunk(pkg$figures, format$knitr$opts_chunk) width <- config_pluck_number_whole(pkg, "code.width", default = 80) old_pre <- format$pre_knit format$pre_knit <- function(...) { options(width = width) if (is.function(old_pre)) { old_pre(...) } } list(format = format, options = NULL) } # Generates pandoc template by rendering templates/content-article.html rmarkdown_template <- function(pkg, data = list(), depth = 1L, env = caller_env()) { path <- withr::local_tempfile( pattern = "pkgdown-rmd-template-", fileext = ".html", .local_envir = env ) render_page(pkg, "article", data, path, depth = depth, quiet = TRUE) path } copy_article_images <- function(built_path, input_path, output_path) { ext_src <- rmarkdown::find_external_resources(input_path) # temporarily copy the rendered html into the input path directory and scan # again for additional external resources that may be been included by R code tempfile <- path(path_dir(input_path), "--find-assets.html") withr::defer(try(file_delete(tempfile))) file_copy(built_path, tempfile) ext_post <- rmarkdown::find_external_resources(tempfile) ext <- rbind(ext_src, ext_post) ext <- ext[!duplicated(ext$path), ] # copy web + explicit files beneath vignettes/ is_child <- path_has_parent(ext$path, ".") ext_path <- ext$path[(ext$web | ext$explicit) & is_child] src <- path(path_dir(input_path), ext_path) dst <- path(path_dir(output_path), ext_path) # Make sure destination paths exist before copying files there dir_create(unique(path_dir(dst))) file_copy(src, dst, overwrite = TRUE) } wrap_rmarkdown_error <- function(cnd, input, call = caller_env()) { lines <- strsplit(gsub("^\r?\n", "", cnd$stderr), "\r?\n")[[1]] lines <- lines[nchar(lines) > 0] # Feeding random text back into cli, so have to escape lines <- gsub("{", "{{", lines, fixed = TRUE) lines <- gsub("}", "}}", lines, fixed = TRUE) cli::cli_abort( c( "!" = "Failed to render {.path {input}}.", set_names(lines, "x") ), parent = cnd$parent %||% cnd, trace = cnd$parent$trace, call = call ) } rmarkdown_render_with_seed <- function(..., seed = NULL) { if (!is.null(seed)) { set.seed(seed) if (requireNamespace("htmlwidgets", quietly = TRUE)) { htmlwidgets::setWidgetIdSeed(seed) } } # Ensure paths from output are not made relative to input # https://github.com/yihui/knitr/issues/2171 options(knitr.graphics.rel_path = FALSE) rmarkdown::render(envir = globalenv(), ...) } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/build.R�����������������������������������������������������������������������������������0000644�0001762�0000144�00000040170�14671042466�013362� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' Build a complete pkgdown website #' #' @description #' `build_site()` is a convenient wrapper around six functions: #' #' * [init_site()] #' * [build_home()] #' * [build_reference()] #' * [build_articles()] #' * [build_tutorials()] #' * [build_news()] #' * [build_redirects()] #' #' See the documentation for the each function to learn how to control #' that aspect of the site. This page documents options that affect the #' whole site. #' #' # General config #' * `destination` controls where the site will be generated, defaulting to #' `docs/`. Paths are relative to the package root. #' #' * `url` is optional, but strongly recommended. #' #' ```yaml #' url: https://pkgdown.r-lib.org #' ``` #' #' It specifies where the site will be published and is used to allow other #' pkgdown sites to link to your site when needed (`vignette("linking")`), #' generate a `sitemap.xml`, automatically generate a `CNAME` when #' [deploying to github][build_site_github_pages()], generate the metadata needed #' rich social "media cards" (`vignette("metadata")`), and more. #' #' * `title` overrides the default site title, which is the package name. #' It's used in the page title and default navbar. #' #' # Navbar and footer #' #' The `navbar` and `footer` fields control the appearance of the navbar #' footer which appear on every page. Learn more about these fields in #' `vignette("customise")`. #' #' # Development mode #' The `development` field allows you to generate different sites for the #' development and released versions of your package. To use it, you first #' need to set the development `mode`: #' #' ```yaml #' development: #' mode: auto #' ``` #' #' ### Setting development mode #' #' The development `mode` of a site controls where the built site is placed #' and how it is styled (i.e. the colour of the package version in the #' navbar, the version tooltip), and whether or not the site is indexed by #' search engines. There are four possible modes: #' #' * **automatic** (`mode: auto`): determines the mode based on the version: #' #' * `0.0.0.9000` (`0.0.0.*`): unreleased. #' * four version components: development. #' * everything else -> release. #' #' * **release** (`mode: release`), the default. Site is written to `docs/` #' and styled like a released package, even if the content is for an #' unreleased or development version. Version in navbar gets the default #' colouring. Development badges are not shown in the sidebar #' (see `?build_home`). #' #' * **development** (`mode: devel`). Site is written to `docs/dev/`. #' The navbar version gets a "danger" class and a tooltip stating these are #' docs for an in-development version of the package. The `noindex` meta tag #' is used to ensure that these packages are not indexed by search engines. #' Development badges are shown in the sidebar (see `?build_home`). #' #' * **unreleased** (`mode: unreleased`). Site is written to `docs/`. #' Version in navbar gets the "danger" class, and a message indicating the #' package is not yet on CRAN. #' Development badges are shown in the sidebar (see `?build_home`). #' #' Use `mode: auto` if you want both a released and a dev site, and #' `mode: release` if you just want a single site. It is very rare that you #' will need either devel or unreleased modes. #' #' You can override the mode specified in the `_pkgdown.yml` by setting #' by setting `PKGDOWN_DEV_MODE` to `devel` or `release`. #' #' ### Selective HTML #' #' You can selectively show HTML only on the devel or release site by adding #' class `pkgdown-devel` or `pkgdown-release`. This is most easily accessed #' from `.Rmd` files where you can use pandoc's `<div>` syntax to control #' where a block of markdown will display. For example, you can use the #' following markdown in your README to only show GitHub install instructions #' on the development version of your site: #' #' ```md #' ::: {.pkgdown-devel} #' You can install the development version of pkgdown from GitHub with: #' `remotes::install_github("r-lib/pkgdown")` #' ::: #' ``` #' #' You can use a similar technique to control where badges are displayed. #' This markdown show the CRAN status badge on the site for the released #' package and the GitHub check status for the development package: #' #' ```md #' [![CRAN Status](https://www.r-pkg.org/badges/version/pkgdown)] #' (https://cran.r-project.org/package=pkgdown){.pkgdown-release} #' [![R-CMD-check](https://github.com/r-lib/pkgdown/workflows/R-CMD-check/badge.svg)] #' (https://github.com/r-lib/pkgdown/actions){.pkgdown-devel} #' ``` #' #' ### Other options #' #' There are three other options that you can control: #' #' ```yaml #' development: #' destination: dev #' version_label: danger #' version_tooltip: "Custom message here" #' ``` #' #' `destination` allows you to override the default subdirectory used for the #' development site; it defaults to `dev/`. `version_label` allows you to #' override the style used for development (and unreleased) versions of the #' package. It defaults to "danger", but you can set to "default", "info", or #' "warning" instead. (The precise colours are determined by your bootstrap #' theme, but become progressively more eye catching as you go from default #' to danger). Finally, you can choose to override the default tooltip with #' `version_tooltip`. #' #' # Template #' The `template` field is mostly used to control the appearance of the site. #' See `vignette("customise")` for details. But it's also used to control #' #' ## Other aspects #' #' There are a few other `template` fields that control other aspects of the #' site: #' #' * `noindex: true` will suppress indexing of your pages by search engines: #' #' ```yaml #' template: #' params: #' noindex: true #' ``` #' #' * `google_site_verification` allows you to verify your site with google: #' #' ```yaml #' template: #' params: #' google_site_verification: _nn6ile-a6x6lctOW #' ``` #' #' * `trailing_slash_redirect: true` will automatically redirect #' `your-package-url.com` to `your-package-url.com/`, using a JS script #' added to the `<head>` of the home page. This is useful in certain #' redirect scenarios. #' #' ```yaml #' template: #' trailing_slash_redirect: true #' ``` #' #' ## Analytics #' #' To capture usage of your site with a web analytics tool, you can make #' use of the `includes` field to add the special HTML they need. This HTML #' is typically placed `in_header` (actually in the `<head>`), `before_body`, #' or `after_body`. #' You can learn more about how includes work in pkgdown at #' <https://pkgdown.r-lib.org/articles/customise.html#additional-html-and-files>. #' #' I include a few examples of popular analytics platforms below, but we #' recommend getting the HTML directly from the tool: #' #' * [plausible.io](https://plausible.io): #' #' ```yaml #' template: #' includes: #' in_header: | #' <script defer data-domain="{YOUR DOMAIN}" src="https://plausible.io/js/plausible.js"></script> #' ``` #' #' * [Google analytics](https://analytics.google.com/analytics/web/): #' #' ```yaml #' template: #' includes: #' in_header: | #' <!-- Global site tag (gtag.js) - Google Analytics --> #' <script async src="https://www.googletagmanager.com/gtag/js?id={YOUR TRACKING ID}"#' ></script> #' <script> #' window.dataLayer = window.dataLayer || []; #' function gtag(){dataLayer.push(arguments);} #' gtag('js', new Date()); #' #' gtag('config', '{YOUR TRACKING ID}'); #' </script> #' ``` #' * [GoatCounter](https://www.goatcounter.com): #' #' ```yaml #' template: #' includes: #' after_body: > #' <script data-goatcounter="https://{YOUR CODE}.goatcounter.com/count" data-goatcounter-settings="{YOUR SETTINGS}" async src="https://gc.zgo.at/count.js"></script> #' ``` #' #' # Source repository #' #' Use the `repo` field to override pkgdown's automatically discovery #' of your source repository. This is used in the navbar, on the homepage, #' in articles and reference topics, and in the changelog (to link to issue #' numbers and user names). pkgdown can automatically figure out the necessary #' URLs if you link to a GitHub or GitLab repo in your `BugReports` or `URL` #' field. #' #' Otherwise, you can supply your own in the `repo` field: #' #' ```yaml #' repo: #' url: #' home: https://github.com/r-lib/pkgdown/ #' source: https://github.com/r-lib/pkgdown/blob/HEAD/ #' issue: https://github.com/r-lib/pkgdown/issues/ #' user: https://github.com/ #' ``` #' #' * `home`: path to package home on source code repository. #' * `source`: path to source of individual file in default branch #' (more on that below). #' * `issue`: path to individual issue. #' * `user`: path to user. #' #' The varying components (e.g. path, issue number, user name) are pasted on #' the end of these URLs so they should have trailing `/`s. #' #' When creating the link to a package source, we have to link to a specific #' branch. The default behaviour is to use current branch when in GitHub #' actions and `HEAD` otherwise. You can overide this default with #' `repo.branch`: #' #' ```yaml #' repo: #' branch: devel #' ``` #' #' pkgdown can automatically link to Jira issues as well if specify both a #' custom `issue` URL as well Jira project names to auto-link in #' `jira_projects`. You can specify as many projects as you would like: #' #' ```yaml #' repo: #' jira_projects: [this_project, another_project] #' url: #' issue: https://jira.organisation.com/jira/browse/ #' ``` #' #' # Deployment (`deploy`) #' There is a single `deploy` field #' #' * `install_metadata` allows you to install package index metadata into #' the package itself. Normally this metadata is made available on the #' published site; installing it into your package means that it's #' available for autolinking even if your website is not reachable at build #' time (e.g. because behind a firewall or requires auth). #' #' ```yaml #' deploy: #' install_metadata: true #' ``` #' #' # Options #' Users with limited internet connectivity can disable CRAN checks by setting #' `options(pkgdown.internet = FALSE)`. This will also disable some features #' from pkgdown that requires an internet connectivity. However, if it is used #' to build docs for a package that requires internet connectivity in examples #' or vignettes, this connection is required as this option won't apply on them. #' #' Users can set a timeout for `build_site(new_process = TRUE)` with #' `options(pkgdown.timeout = Inf)`, which is useful to prevent stalled builds from #' hanging in cron jobs. #' #' @inheritParams build_articles #' @inheritParams build_reference #' @param lazy If `TRUE`, will only rebuild articles and reference pages #' if the source is newer than the destination. #' @param devel Use development or deployment process? #' #' If `TRUE`, uses lighter-weight process suitable for rapid #' iteration; it will run examples and vignettes in the current process, #' and will load code with `pkgload::load_all()`. #' #' If `FALSE`, will first install the package to a temporary library, #' and will run all examples and vignettes in a new process. #' #' `build_site()` defaults to `devel = FALSE` so that you get high fidelity #' outputs when you building the complete site; `build_reference()`, #' `build_home()` and friends default to `devel = TRUE` so that you can #' rapidly iterate during development. #' @param new_process If `TRUE`, will run `build_site()` in a separate process. #' This enhances reproducibility by ensuring nothing that you have loaded #' in the current process affects the build process. #' @param install If `TRUE`, will install the package in a temporary library #' so it is available for vignettes. #' @export #' @examples #' \dontrun{ #' build_site() #' #' build_site(override = list(destination = tempdir())) #' } build_site <- function(pkg = ".", examples = TRUE, run_dont_run = FALSE, seed = 1014L, lazy = FALSE, override = list(), preview = NA, devel = FALSE, new_process = !devel, install = !devel) { pkg <- as_pkgdown(pkg, override = override) check_bool(devel) check_bool(new_process) check_bool(install) if (install) { withr::local_temp_libpaths() cli::cli_rule("Installing package {.pkg {pkg$package}} into temporary library") # Keep source, so that e.g. pillar can show the source code # of its functions in its articles withr::with_options( list(keep.source.pkgs = TRUE, keep.parse.data.pkgs = TRUE), utils::install.packages(pkg$src_path, repos = NULL, type = "source", quiet = TRUE) ) } if (new_process) { build_site_external( pkg = pkg, examples = examples, run_dont_run = run_dont_run, seed = seed, lazy = lazy, override = override, preview = preview, devel = devel ) } else { build_site_local( pkg = pkg, examples = examples, run_dont_run = run_dont_run, seed = seed, lazy = lazy, override = override, preview = preview, devel = devel ) } } build_site_external <- function(pkg = ".", examples = TRUE, run_dont_run = FALSE, seed = 1014L, lazy = FALSE, override = list(), preview = NA, devel = TRUE) { pkg <- as_pkgdown(pkg, override = override) args <- list( pkg = pkg, examples = examples, run_dont_run = run_dont_run, seed = seed, lazy = lazy, override = override, install = FALSE, preview = FALSE, new_process = FALSE, devel = devel, cli_colors = cli::num_ansi_colors(), hyperlinks = cli::ansi_has_hyperlink_support(), pkgdown_internet = has_internet() ) callr::r( function(..., cli_colors, hyperlinks, pkgdown_internet) { options( cli.num_colors = cli_colors, cli.hyperlink = hyperlinks, cli.hyperlink_run = hyperlinks, pkgdown.internet = pkgdown_internet ) pkgdown::build_site(...) }, args = args, show = TRUE, timeout = getOption('pkgdown.timeout', Inf) ) cli::cli_rule("Finished building pkgdown site for package {.pkg {pkg$package}}") preview_site(pkg, preview = preview) invisible() } build_site_local <- function(pkg = ".", examples = TRUE, run_dont_run = FALSE, seed = 1014L, lazy = FALSE, override = list(), preview = NA, devel = TRUE) { pkg <- section_init(pkg, override = override) cli::cli_rule("Building pkgdown site for package {.pkg {pkg$package}}") cli::cli_inform("Reading from: {src_path(path_abs(pkg$src_path))}") cli::cli_inform("Writing to: {dst_path(path_abs(pkg$dst_path))}") pkgdown_sitrep(pkg) if (!lazy) { # Only force init_site() if `!lazy` # if site is not initialized, it will be in build_home() init_site(pkg, override) } build_home(pkg, override = override, preview = FALSE) build_reference( pkg, lazy = lazy, examples = examples, run_dont_run = run_dont_run, seed = seed, override = override, preview = FALSE, devel = devel ) build_articles(pkg, lazy = lazy, override = override, preview = FALSE) build_tutorials(pkg, override = override, preview = FALSE) build_news(pkg, override = override, preview = FALSE) build_sitemap(pkg) build_redirects(pkg, override = override) if (pkg$bs_version == 3) { build_docsearch_json(pkg) } else { build_search(pkg, override = override) } check_built_site(pkg) cli::cli_rule("Finished building pkgdown site for package {.pkg {pkg$package}}") preview_site(pkg, preview = preview) } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/build-home-authors.R����������������������������������������������������������������������0000644�0001762�0000144�00000016757�14642045634�016007� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������build_citation_authors <- function(pkg = ".") { pkg <- as_pkgdown(pkg) source <- if (has_citation(pkg$src_path)) { repo_source(pkg, "inst/CITATION") } else { repo_source(pkg, "DESCRIPTION") } authors <- data_authors(pkg) data <- list( pagetitle = tr_("Authors and Citation"), citations = data_citations(pkg), authors = unname(authors$all), inst = authors$inst, before = authors$before, after = authors$after, source = source ) render_page(pkg, "citation-authors", data, "authors.html") } data_authors <- function(pkg = ".", roles = default_roles(), call = caller_env()) { pkg <- as_pkgdown(pkg) author_info <- config_pluck_list(pkg, "authors", default = list(), call = call) inst_path <- path(pkg$src_path, "inst", "AUTHORS") if (file_exists(inst_path)) { inst <- read_lines(inst_path) } else { inst <- NULL } authors_all <- pkg_authors(pkg) authors_main <- pkg_authors(pkg, roles) all <- purrr::map(authors_all, author_list, author_info, pkg = pkg) main <- purrr::map(authors_main, author_list, author_info, pkg = pkg) more_authors <- length(main) != length(all) comments <- purrr::compact(purrr::map(all, "comment")) print_yaml(list( all = all, main = main, inst = inst, needs_page = more_authors || length(comments) > 0 || !is.null(inst), before = config_pluck_markdown_block(pkg, "template.authors.before", call = call), after = config_pluck_markdown_block(pkg, "template.authors.after", call = call) )) } default_roles <- function() { c("aut", "cre", "fnd") } pkg_authors <- function(pkg, role = NULL) { if (pkg$desc$has_fields("Authors@R")) { authors <- unclass(pkg$desc$get_authors()) } else { # Just show maintainer authors <- unclass(utils::as.person(pkg$desc$get_maintainer())) authors[[1]]$role <- "cre" } if (is.null(role)) { authors } else { purrr::keep(authors, ~ any(.$role %in% role)) } } data_home_sidebar_authors <- function(pkg = ".", call = caller_env()) { pkg <- as_pkgdown(pkg) config_pluck_list(pkg, "authors.sidebar") roles <- config_pluck_character( pkg, "authors.sidebar.roles", default = default_roles(), call = call ) data <- data_authors(pkg, roles) authors <- purrr::map_chr(data$main, author_desc, comment = FALSE) before <- config_pluck_markdown_inline(pkg, "authors.sidebar.before", call = call) after <- config_pluck_markdown_inline(pkg, "authors.sidebar.after", call = call) bullets <- c(before, authors, after) if (data$needs_page) { bullets <- c(bullets, a(tr_("More about authors..."), "authors.html")) } sidebar_section(tr_("Developers"), bullets) } author_name <- function(x, authors, pkg) { name <- format_author_name(x$given, x$family) if (!(name %in% names(authors))) { return(name) } author <- authors[[name]] if (!is.null(author$html)) { error_path <- paste0("authors.", name, ".html") name <- markdown_text_inline(pkg, author$html, error_path = error_path) } if (is.null(author$href)) { name } else { a(name, author$href) } } format_author_name <- function(given, family) { given <- paste(given, collapse = " ") if (is.null(family)) { given } else { paste0(given, " ", family) } } author_list <- function(x, authors_info = NULL, comment = FALSE, pkg = ".") { name <- author_name(x, authors_info, pkg = pkg) roles <- paste0(role_lookup(x$role), collapse = ", ") substr(roles, 1, 1) <- toupper(substr(roles, 1, 1)) orcid <- purrr::pluck(x$comment, "ORCID") x$comment <- remove_orcid(x$comment) list( name = name, roles = roles, comment = linkify(x$comment), orcid = orcid_link(orcid) ) } author_desc <- function(x, comment = TRUE) { paste( x$name, "<br />\n<small class = 'roles'>", x$roles, "</small>", if (!is.null(x$orcid)) { x$orcid }, if (comment && !is.null(x$comment) && length(x$comment) != 0) { paste0("<br/>\n<small>(", linkify(x$comment), ")</small>") } ) } orcid_link <- function(orcid) { if (is.null(orcid)) { return(NULL) } paste0( "<a href='https://orcid.org/", orcid, "' target='orcid.widget' aria-label='ORCID'>", "<span class='fab fa-orcid orcid' aria-hidden='true'></span></a>" ) } # Derived from: # db <- utils:::MARC_relator_db # db <- db[db$usage != "",] # dput(setNames(tolower(db$term), db$code)) # # and replace creater with maintainer role_lookup <- function(abbr) { # CRAN roles are translated roles <- c( aut = tr_("author"), com = tr_("compiler"), ctr = tr_("contractor"), ctb = tr_("contributor"), cph = tr_("copyright holder"), cre = tr_("maintainer"), dtc = tr_("data contributor"), fnd = tr_("funder"), rev = tr_("reviewer"), ths = tr_("thesis advisor"), trl = tr_("translator") ) # Other roles are left as is marc_db <- getNamespace("utils")$MARC_relator_db extra <- setdiff(marc_db$code, names(roles)) roles[extra] <- tolower(marc_db$term[match(extra, marc_db$code)]) out <- unname(roles[abbr]) if (any(is.na(out))) { missing <- abbr[is.na(out)] cli::cli_warn("Unknown MARC role abbreviation{?s}: {.field {missing}}") out[is.na(out)] <- abbr[is.na(out)] } out } # citation --------------------------------------------------------------------- has_citation <- function(path = ".") { file_exists(path(path, 'inst/CITATION')) } create_citation_meta <- function(path) { path <- path(path, "DESCRIPTION") dcf <- read.dcf(path) desc <- as.list(dcf[1, ]) if (!is.null(desc$Encoding)) { desc <- lapply(desc, iconv, from = desc$Encoding, to = "UTF-8") } else { desc$Encoding <- "UTF-8" } if (!is.null(desc$Title)) desc$Title <- str_squish(desc$Title) desc } read_citation <- function(path = ".") { if (!has_citation(path)) { return(character()) } meta <- create_citation_meta(path) cit_path <- path(path, 'inst/CITATION') utils::readCitationFile(cit_path, meta = meta) } data_home_sidebar_citation <- function(pkg = ".") { pkg <- as_pkgdown(pkg) sidebar_section( heading = tr_("Citation"), bullets = a(sprintf(tr_("Citing %s"), pkg$package), "authors.html#citation") ) } data_citations <- function(pkg = ".") { pkg <- as_pkgdown(pkg) if (has_citation(pkg$src_path)) { return(citation_provided(pkg$src_path)) } citation_auto(pkg) } citation_provided <- function(src_path) { provided_citation <- read_citation(src_path) text_version <- format(provided_citation, style = "textVersion") cit <- list( html = ifelse( text_version == "", format(provided_citation, style = "html"), paste0("<p>", escape_html(text_version), "</p>") ), bibtex = format(provided_citation, style = "bibtex") ) purrr::transpose(cit) } citation_auto <- function(pkg) { desc <- read_desc(pkg$src_path) cit_info <- as.list(desc$get(desc$fields())) # utils::packageDescription( # pkg$package, # lib.loc = path_dir(pkg$src_path) # ) # browser() # C cit_info$`Date/Publication` <- cit_info$`Date/Publication` %||% Sys.time() if (!is.null(cit_info$Title)) cit_info$Title <- str_squish(cit_info$Title) cit <- utils::citation(auto = cit_info) list( html = format(cit, style = "html"), bibtex = format(cit, style = "bibtex") ) } # helpers ------------------------------------------------------------------------- # Not strictly necessary, but produces a simpler data structure testing remove_orcid <- function(x) { out <- x[names2(x) != "ORCID"] if (all(names(out) == "")) { names(out) <- NULL } out } �����������������pkgdown/R/template.R��������������������������������������������������������������������������������0000644�0001762�0000144�00000001705�14633374223�014074� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' Generate YAML templates #' #' Use these function to generate the default YAML that pkgdown uses for #' the different parts of `_pkgdown.yml`. This are useful starting #' points if you want to customise your site. #' #' @param path Path to package root #' @rdname templates #' @examples #' \dontrun{ #' pkgdown::template_navbar() #' } #' #' @export template_navbar <- function(path = ".") { pkg <- as_pkgdown(path) print_yaml(list( navbar = list( structure = navbar_structure(), components = navbar_components(pkg) ) )) } #' @rdname templates #' @examples #' \dontrun{ #' pkgdown::template_reference() #' } #' #' @export template_reference <- function(path = ".") { print_yaml(list(reference = default_reference_index(path))) } #' @rdname templates #' @examples #' \dontrun{ #' pkgdown::template_articles() #' } #' #' @export template_articles <- function(path = ".") { print_yaml(list(articles = default_articles_index(path))) } �����������������������������������������������������������pkgdown/R/figure.R����������������������������������������������������������������������������������0000644�0001762�0000144�00000010361�14633374223�013540� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fig_save <- function(plot, name, dev = "ragg::agg_png", dpi = 96L, dev.args = list(), fig.ext = "png", fig.width = 700 / 96, fig.height = NULL, fig.retina = 2L, fig.asp = 1 / 1.618, # golden ratio bg = NULL, other.parameters = list() ) { path <- paste0(name, ".", fig.ext) dev <- match_fun(dev) if (is.null(fig.height)) { fig.height <- fig.width * fig.asp } else if (is.null(fig.width)) { fig.width <- fig.height / fig.asp } width <- round(dpi * fig.width) height <- round(dpi * fig.height) has_res <- "res" %in% names(formals(dev)) if (has_res) { # raster device; units in pixels, need to rescale for retina args <- list( path, # some devices use file and some use filename width = width * fig.retina, height = height * fig.retina, res = dpi * fig.retina ) } else { # vector device; units in inches; no need to rescale args <- list( path, width = fig.width, height = fig.height ) } # NB: bg is always set to transparent here; it takes effect during # recording in highlight_examples() dev.args$bg <- NA with_device(dev, c(args, dev.args), plot) list(path = path, width = width, height = height) } fig_save_args <- function() { # Avoid having multiple copies of the default settings default <- formals(fig_save) default$plot <- NULL default$name <- NULL default <- lapply(default, eval, baseenv()) default } meta_figures <- function(pkg) { default <- fig_save_args() figures <- config_pluck_list(pkg, "figures") print_yaml(modify_list(default, figures)) } #' Get current settings for figures #' #' @description #' You will generally not need to use this function unless you are handling #' custom plot output. #' #' Packages needing custom parameters should ask users to place them within #' the `other.parameters` entry under the package name, e.g. #' ``` #' figures: #' other.parameters: #' rgl: #' fig.asp: 1 #' ``` #' #' @return #' A list containing the entries from the `figures` field in `_pkgdown.yml` #' (see [build_reference()]), with default values added. Computed `width` and #' `height` values (in pixels) are also included. #' @export #' @keywords internal fig_settings <- function() { result <- fig_save_args() # The context might not be initialized. settings <- tryCatch(context_get("figures"), error = function(e) NULL) result[names(settings)] <- settings if (is.null(result$fig.height)) { result$fig.height <- result$fig.width * result$fig.asp } else if (is.null(result$fig.width)) { result$fig.width <- result$fig.height / result$fig.asp } result } with_device <- function(dev, dev.args, plot) { do.call(dev, dev.args) on.exit(grDevices::dev.off()) print(plot) } fig_opts_chunk <- function(figures, default) { figures$dev <- fun_name(figures$dev) # fig.asp beats fig.height in knitr, so if it's provided only use # it to override the default height if (!is.null(figures$fig.asp) && is.null(figures$fig.height)) { figures$fig.height <- figures$fig.width * figures$fig.asp figures$fig.asp <- NULL } # Copy background into dev.args figures$dev.args <- figures$dev.args %||% list() figures$dev.args$bg <- figures$bg %||% NA modify_list(default, figures) } # Find graphics device ---------------------------------------------------- match_fun <- function(x) { if (is.function(x)) { x } else if (is.character(x) && length(x) == 1) { e <- parse_expr(x) f <- eval(e, globalenv()) if (!is.function(f)) { cli::cli_abort("{.var x} must evaluate to a function", call = caller_env()) } f } else { cli::cli_abort("{.var x} must be a function or string", call = caller_env()) } } # knitr only takes a function name - user will need to load package fun_name <- function(x) { if (x == "ragg::agg_png") { return("ragg_png") } expr <- parse_expr(x) if (is_symbol(expr)) { x } else if (is_call(expr, "::")) { as.character(expr[[3]]) } else { cli::cli_abort("Unknown input", call = caller_env()) } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/utils-io.R��������������������������������������������������������������������������������0000644�0001762�0000144�00000001434�14634573316�014032� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Reading ----------------------------------------------------------------- read_file <- function(path) { lines <- read_lines(path) paste0(lines, "\n", collapse = "") } # Inspired by roxygen2 utils-io.R (https://github.com/klutometis/roxygen/) -------- read_lines <- function(path, n = -1L) { base::readLines(path, n = n, encoding = "UTF-8", warn = FALSE) # nolint } write_lines <- function(text, path) { base::writeLines(enc2utf8(text), path, useBytes = TRUE) # nolint } # Other ------------------------------------------------------------------- file_equal <- function(src, dst) { if (!file_exists(dst)) return(FALSE) src_hash <- digest::digest(file = src, algo = "xxhash64") dst_hash <- digest::digest(file = dst, algo = "xxhash64") identical(src_hash, dst_hash) } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/topics-external.R�������������������������������������������������������������������������0000644�0001762�0000144�00000002705�14633374223�015403� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ext_topics <- function(match_strings) { pieces <- strsplit(match_strings, "::", fixed = TRUE) pkg <- purrr::map_chr(pieces, 1) fun <- sub("\\(\\)$", "", purrr::map_chr(pieces, 2)) unwrap_purrr_error( ext_rd <- purrr::map2(pkg, fun, get_rd_from_help) ) ext_title <- purrr::map_chr(ext_rd, extract_title) ext_href <- purrr::map2_chr(fun, pkg, downlit::href_topic) ext_funs <- purrr::map(ext_rd, topic_funs) tibble::tibble( name = match_strings, file_in = NA_character_, file_out = ext_href, alias = list(character()), # used to find icons, funs = ext_funs, # used list alternative names title = sprintf("%s (from %s)", ext_title, pkg), rd = list(character()), source = NA_character_, keywords = list(character()), # used for has_keyword() concepts = list(character()), # used for has_concept() internal = FALSE, lifecycle = list(NULL) # used for has_lifecycle ) } # Adapted from roxygen2::get_rd_from_help get_rd_from_help <- function(package, alias) { call <- quote(build_reference_index()) check_installed(package, "as it's used in the reference index.", call = call) help <- utils::help((alias), (package)) if (length(help) == 0) { fun <- paste0(package, "::", alias) cli::cli_abort( "Could not find documentation for {.fn {fun}}.", call = call ) return() } out <- get(".getHelpFile", envir = asNamespace("utils"))(help) set_classes(out) } �����������������������������������������������������������pkgdown/R/clean.R�����������������������������������������������������������������������������������0000644�0001762�0000144�00000003152�14645463761�013352� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' Clean site #' #' Delete all files in `docs/` (except for `CNAME`). #' #' @param quiet If `TRUE`, suppresses a message. #' @inheritParams build_site #' @rdname clean #' @export clean_site <- function(pkg = ".", quiet = FALSE) { pkg <- as_pkgdown(pkg) if (!quiet) { cli::cli_inform("Cleaning {.pkg {pkg$package}} pkgdown docs from {.path {pkg$dst_path}}") } if (!dir_exists(pkg$dst_path)) return(invisible()) top_level <- dest_files(pkg) if (length(top_level) > 0) { check_dest_is_pkgdown(pkg) } is_dir <- is_dir(top_level) dir_delete(top_level[is_dir]) file_delete(top_level[!is_dir]) invisible(TRUE) } #' Clean cache #' #' Delete all files in the pkgdown cache directory. #' #' @rdname clean #' @export clean_cache <- function(pkg = ".", quiet = FALSE) { pkg <- as_pkgdown(pkg) cache_path <- tools::R_user_dir("pkgdown", "cache") if (dir_exists(cache_path)) { if (!quiet) { cli::cli_inform( "Cleaning {.pkg {pkg$package}} cache files from {.path {cache_path}}" ) } dir_delete(cache_path) } invisible(TRUE) } check_dest_is_pkgdown <- function(pkg) { if (file_exists(path(pkg$dst_path, "pkgdown.yml"))) { return() } cli::cli_abort(c( "{.file {pkg$dst_path}} is non-empty and not built by pkgdown", "!" = "Make sure it contains no important information \\ and use {.run pkgdown::clean_site()} to delete its contents." ) ) } dest_files <- function(pkg) { if (!dir_exists(pkg$dst_path)) { character() } else { top_level <- dir_ls(pkg$dst_path) top_level[!path_file(top_level) %in% c("CNAME", "dev")] } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/build-tutorials.R�������������������������������������������������������������������������0000644�0001762�0000144�00000007364�14634573316�015420� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' Build tutorials section #' #' learnr tutorials must be hosted elsewhere as they require an #' R execution engine. Currently, pkgdown will not build or publish tutorials #' for you, but makes it easy to embed (using `<iframe>`s) published tutorials. #' Tutorials are automatically discovered from published tutorials in #' `inst/tutorials` and `vignettes/tutorials`. Alternatively, you can #' list in `_pkgdown.yml` as described below. #' #' # YAML config #' To override the default discovery process, you can provide a `tutorials` #' section. This should be a list where each element specifies: #' #' * `name`: used for the generated file name #' * `title`: used in page heading and in navbar #' * `url`: which will be embedded in an iframe #' * `source`: optional, but if present will be linked to #' #' ```yaml #' tutorials: #' - name: 00-setup #' title: Setting up R #' url: https://jjallaire.shinyapps.io/learnr-tutorial-00-setup/ #' - name: 01-data-basics #' title: Data basics #' url: https://jjallaire.shinyapps.io/learnr-tutorial-01-data-basics/ #' ``` #' @inheritParams build_articles #' @family site components #' @export build_tutorials <- function(pkg = ".", override = list(), preview = FALSE) { pkg <- section_init(pkg, "tutorials", override = override) tutorials <- pkg$tutorials if (nrow(tutorials) == 0) { return(invisible()) } cli::cli_rule("Building tutorials") data <- purrr::transpose(tutorials) # Build index render_page(pkg, "tutorial-index", data = list( pagetitle = tr_("Tutorials"), tutorials = purrr::transpose(list( path = path_rel(tutorials$file_out, "tutorials"), title = tutorials$title )) ), path = "tutorials/index.html" ) purrr::pwalk( list(data = data, path = tutorials$file_out), render_page, pkg = pkg, name = "tutorial" ) preview_site(pkg, "tutorials", preview = preview) } package_tutorials <- function(path = ".", meta = list()) { # Look first in meta data tutorials <- purrr::pluck(meta, "tutorials") # Then scan tutorials directories if (length(tutorials) == 0) { tutorials <- c( find_tutorials(path(path, "inst", "tutorials")), find_tutorials(path(path, "vignettes", "tutorials")) ) } name <- purrr::map_chr(tutorials, "name") title <- purrr::map_chr(tutorials, "title") tibble::tibble( name = name, file_out = as.character(path("tutorials", name, ext = "html")), title = title, pagetitle = title, url = purrr::map_chr(tutorials, "url") ) } find_tutorials <- function(path = ".") { if (!dir_exists(path)) { return(character()) } check_installed("rsconnect", "to find published tutorials") rmds <- unname(dir_ls(path, recurse = TRUE, regexp = "\\.[Rrq]md$", type = "file")) info <- purrr::map(rmds, tutorial_info, base_path = path) purrr::compact(info) } tutorial_info <- function(path, base_path) { yaml <- rmarkdown::yaml_front_matter(path) title <- yaml$title if (is.null(title)) { return() } # Must have "runtime: shiny". Partial implementation of full algorithm: # https://github.com/rstudio/rmarkdown/blob/master/R/shiny.R#L72-L100 runtime <- yaml$runtime if (is.null(runtime) || !grepl("^shiny", runtime)) { return() } # Find deployment url. Use excludeOrphaned = FALSE since we don't need # to worry about redeploying and this makes test infrastructure a little # simpler deploys <- rsconnect::deployments(path, excludeOrphaned = FALSE) if (!is.null(deploys) && nrow(deploys) >= 1) { latest <- which.max(deploys$when) url <- deploys$url[[latest]] } else { return() } list( name = as.character(path_ext_remove(path_file(path))), title = yaml$title, url = url # source = as.character(path_rel(path, base_path)) ) } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/tweak-navbar.R����������������������������������������������������������������������������0000644�0001762�0000144�00000005074�14641277402�014646� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������activate_navbar <- function(html, path, pkg = list(bs_version = 5)) { if (pkg$bs_version <= 3) { return() } path <- remove_useless_parts(path, pkg = pkg) # Get nav items, their links, their similarity to the current path navbar_haystack <- navbar_links_haystack(html, pkg, path) if (nrow(navbar_haystack) == 0) { return() } # Pick the most similar link, activate the corresponding nav item best_match <- navbar_haystack[which.max(navbar_haystack$similar), ] tweak_class_prepend(best_match$nav_item[[1]], "active") invisible() } navbar_links_haystack <- function(html, pkg, path) { # Extract links from the menu items html_navbar <- xml2::xml_find_first(html, ".//div[contains(@class, 'navbar')]") nav_items <- xml2::xml_find_all(html_navbar,".//li[contains(@class, 'nav-item')]") get_hrefs <- function(nav_item, pkg = pkg) { href <- xml2::xml_attr(xml2::xml_child(nav_item), "href") if (!is.na(href) && href != "#") { links <- href } else { # links in a drop-down hrefs <- xml2::xml_attr(xml2::xml_find_all(nav_item, ".//a"), "href") links <- hrefs[hrefs != "#"] } tibble::tibble( nav_item = list(nav_item), links = remove_useless_parts(links[is_internal_link(links, pkg = pkg)], pkg = pkg) ) } haystack <- do.call(rbind, lapply(nav_items, get_hrefs, pkg = pkg)) # For each link, calculate similarity to the current path separate_path <- function(link) { strsplit(link, "/")[[1]] } get_similarity <- function(stalk, needle) { needle <- separate_path(needle) stalk <- separate_path(stalk) # Active item can't be more precise than current path/needle if (length(stalk) > length(needle)) { return(0) } # Active item can however be less precise than current path/needle length(stalk) <- length(needle) similar <- (needle == stalk) # Any difference indicates it's not the active item if (any(!similar, na.rm = TRUE)) { 0 } else { sum(similar, na.rm = TRUE) } } haystack$similar <- purrr::map_dbl(haystack$links, get_similarity, needle = path) # Only return rows of links with some similarity to the current path haystack[haystack$similar > 0, ] } remove_useless_parts <- function(links, pkg) { # remove website URL if (!is.null(pkg$meta$url)) { links <- sub(pkg$meta$url, "", links) } # remove first slash from path links <- sub("^/", "", links) # remove /index.html from the end links <- sub("/index.html/?", "", links) # remove ../ from the beginning links <- gsub("\\.\\./", "", links) links } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/R/autolink_html.R���������������������������������������������������������������������������0000644�0001762�0000144�00000002056�14634573316�015140� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#' Automatically link references and articles in an HTML page #' #' @description #' `r lifecycle::badge("deprecated")` #' #' Please use [downlit::downlit_html_path()] instead. #' #' @param input,output Input and output paths for HTML file #' @param local_packages A named character vector providing relative paths #' (value) to packages (name) that can be reached with relative links #' from the target HTML document. #' @export #' @keywords internal #' @examples #' \dontrun{ #' autolink_html("path/to/file.html", #' local_packages = c( #' shiny = "shiny", #' shinydashboard = "shinydashboard" #' ) #' ) #' } autolink_html <- function(input, output = input, local_packages = character()) { lifecycle::deprecate_warn( "1.6.0", "autolink_html()", "downlit::downlit_html_path()" ) withr::local_options(list( downlit.package = "", downlit.local_packages = local_packages )) html <- xml2::read_html(input, encoding = "UTF-8") downlit::downlit_html_node(html) xml2::write_html(html, output, format = FALSE) invisible() } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/vignettes/����������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14672347612�013747� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/vignettes/how-to-update-released-site.Rmd���������������������������������������������������0000644�0001762�0000144�00000025264�14671042554�021641� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- title: "How to update a released site" output: rmarkdown::html_vignette description: > A guide to updating the "released" version of your pkgdown site without having to release a new version of your package. vignette: > %\VignetteIndexEntry{How to update a released site} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", eval = FALSE, purl = FALSE ) ``` This vignette shows you how to update the released version of your site to match the dev version of the site, so the first step is to ensure that the dev site looks the way that you want it. This site assumes that you're using a recent version of our recommended [pkgdown action](https://github.com/r-lib/actions/blob/HEAD/examples/pkgdown.yaml). If your workflow does not contain `workflow_dispatch`, you will need to update `.github/actions/pkgdown.yaml` by running `use_github_action("pkgdown")`. ## Process If you're up to speed with the basic idea and just want some code to follow, here it is. Otherwise, read more below. ### Setup First, make sure you're in the `main` branch, and you have the latest version: ```{r} gert::git_branch_checkout("main") gert::git_pull() ``` Next figure out the released version that you're updating: ```{r} ver <- desc::desc_get_version()[1, 1:3] ``` You will use this to create and checkout the branch that you'll work in: ```{r} gert::git_branch_create(paste0("pkgdown-v", ver), paste0("v", ver)) ``` ### Backport changes Now you need to backport changes from the dev site into this branch. Run this R code to generate the git code to pull changes for the most common locations: ```{r} files <- c( # overall site config "_pkgdown.yml", # the workflow that builds the site ".github/workflows/pkgdown.yaml", # readme and vignettes "README.md", "vignettes", # logo and favicon "man/figures/", "pkgdown/", # Author metadata and Config/Needs/Website "DESCRIPTION" ) glue::glue("git checkout v{ver} -- {files}") ``` If you backport `DESCRIPTION`, you'll also need undo the change to the `Version`: ```{r} desc::desc_set_version(ver) ``` Now build the site locally and check that it looks as expected: ```{r} pkgdown::build_site() ``` ### Publish Now you need to publish the site. First push your branch to GitHub: ```{r} usethis:::git_push_first() ``` Then trigger the pkgdown workflow: 1. Go to your package's GHA page, e.g. with `usethis::browse_github_actions())`. 2. Select the pkgdown workflow. 3. Click *Run workflow* and select the branch you just pushed. If there's no dropdown menu for this, that means your pkgdown workflow config is not current. ## Context Before we talk about **how** to update a released site, we first establish **why** you might need to do this. What is a released site? What other kind of pkgdown site could you have? Why does updating a released site take special effort? ### Automatic development mode Every pkgdown site has a so-called [*development mode*](https://pkgdown.r-lib.org/reference/build_site.html#development-mode), which can be specified via the `development` field in `_pkgdown.yml`. If unspecified, the default is `mode: release`, which results in a single pkgdown site. Despite the name, this single site reflects "the current package state", which could be either a released state or a development state. For packages with a substantial user base, it is recommended instead to specify `mode: auto` like so: ``` yaml development: mode: auto ``` This directs pkgdown to "generate different sites for the development and released versions of your package." The readr package demonstrates what happens in automatic development mode: [readr.tidyverse.org](https://readr.tidyverse.org) documents the released version, i.e. what `install.packages()` will deliver.\ [readr.tidyverse.org/dev/](https://readr.tidyverse.org/dev/) documents the dev version, i.e. what you'd get by installing from GitHub. In this mode, `pkgdown::build_site()`, consults DESCRIPTION to learn the package's version number. For a development version number, the rendered site is written to `docs/dev/`. For a released version number, the site is written to `docs/`. (There are also other signals to alert users that they are reading documentation for a dev version vs. a released version.) Automatic development mode is recommended for packages with a broad user base because it maximizes the chance that a user will read web-based documentation which reflects the package version that is locally installed. ### Publishing Now that we've established the meaning of a released (vs dev) site, we have to consider how the site is built (i.e. how the HTML is generated) and deployed (i.e. how the HTML is published to a website so people can see it.). We recommend `usethis::use_pkgdown_github_pages()` to do basic pkgdown setup and configure a GitHub Actions (GHA) workflow to automatically render and publish the site to GitHub Pages. This function is basically a shortcut for calling the following functions individually: * `use_pkgdown()` * `use_github_pages()` * `use_github_action("pkgdown")` It then adds the pkgdown site's URL to `_pkgdown.yml`, the `URL` field of DESCRIPTION, and the GitHub repo. As a result, the publishing cadence of many pkgdown sites is governed by the workflow maintained at [`r-lib/actions/examples/pkgdown.yaml`](https://github.com/r-lib/actions/blob/v2/examples/pkgdown.yaml). (Do not confuse `_pkgdown.yml`, which gives instructions to the pkgdown package, with `.github/workflows/pkgdown.yaml`, which gives instructions to GHA.) Here are some of the most important bits of the GHA workflow config: ``` yaml on: push: branches: [main, master] pull_request: branches: [main, master] release: types: [published] workflow_dispatch: <snip, snip> - name: Build site run: Rscript -e 'pkgdown::build_site_github_pages(...)' - name: Deploy to GitHub pages 🚀 if: github.event_name != 'pull_request' uses: JamesIves/github-pages-deploy-action@4.1.4 <snip, snip> ``` Altogether this means that we: * Build and deploy for pushes to `main`. * Build, but don't deploy, for pull requests against `main`. This reveals any pkgdown errors, but ensures the live site isn't updated until the pull request is merged (because the code is pushed to `main`). * Build and deploy when we publish a GitHub release. By convention, we assume that a GitHub release coincides with a CRAN release. So this is the **primary mechanism for building the released pkgdown site**. `pkgdown::build_site_github_pages()` consults the version in DESCRIPTION to detect whether it's building from a released version or a dev version. That determines the `dest_dir`, e.g. `docs/` for released and `docs/dev/` for dev. For a package in automatic development mode, this means that almost all of your pushes trigger an update to the dev site. The released site is only updated when you push a state with a non-development version number or when you publish a GitHub release. So how do you tweak things about the released site *in between* releases? That brings us to `workflow_dispatch:`. (Yes that dangling colon is correct.) The inclusion of `workflow_dispatch` as a trigger means the pkgdown workflow can be [run on demand](https://docs.github.com/en/actions/using-workflows/manually-running-a-workflow), most importantly from the browser. ## Construct a branch for the update The overall goal is to create a branch that combines some features of the released website (e.g. the released version) and the development version (e.g. improvements to your `_pkgdown.yml`). The easiest way is to start your branch using the latest release tag, then bring in selected changes or files from the development version. For example, if readr's latest release is 2.1.1: ``` git checkout -b update-pkgdown-2-1-1 v2.1.1 ``` And here is the general pattern: ``` git checkout -b NEW-BRANCH-NAME NAME-OF-RELEASE-TAG ``` Now you should port innovations from the development site that you want to apply to your released site. Files you must update: - `.github/workflows/pkgdown.yaml` - `_pkgdown.yml` - `Config/Needs/website` field of DESCRIPTION (And, probably, only this field! In particular, do not mess with the version number.) Other likely candidates: - `README.Rmd` + `README.md`, e.g., if you've updated badges. - Any documentation fixes that **apply to the released version**. This is the only reason to touch anything below `R/` and even then it should only affect roxygen comments. Don't forget to `document()` if you do this! - Any new vignettes or articles that apply to the released version. Here are some tips on backporting specific changes into this branch. If you are lucky, there are specific commits in your default branch that contain all the necessary changes. In that case, we can cherry pick such a commit by its SHA: ``` git cherry-pick SHA ``` If that doesn't cover everything for each file you want to update, identify a Git reference (meaning: a SHA, tag, or branch) where the file is in the desired state. Checkout that specific file path from that specific ref: ``` git checkout main -- path/to/the/file ``` For example, readr recently gained a new vignette that applies to the released version of readr, i.e. it does not document any dev-only features or functions. We can bring that into the current branch with: ``` git checkout main -- vignettes/column-types.Rmd ``` Commit and push this new branch to GitHub. `usethis::pr_push()` can be handy for this. Just don't bother opening a pull request (the branch will still be pushed). Now we will use the `workflow_dispatch` GHA trigger: 1. Go to the Actions page of your repo, maybe via `usethis::browse_github_actions()`. 1. Click on the `pkgdown` workflow. 1. Click the "Run workflow". 1. In the "Use workflow from" dropdown menu, select the branch you've just made and pushed, then click "Run workflow". This should kick off a pkgdown build-and-deploy and, specifically, it should cause updates to the **released** site. You can keep this branch around for a while, in case you didn't get everything right the first time or if more things crop up that you'd like backport to the released site, before your next CRAN release. ## Problem-solving Another great problem solving technique is to get a bunch of other people's `_pkgdown.yml` files in front of your eyeballs. There are two ways to do this: [GitHub search](https://github.com/search?q=path%3A%22_pkgdown.yml%22+AND+%28org%3Atidyverse+OR+org%3Ar-lib%29&type=code) or [Michael Chirico's `r-ci-samples` repo](https://github.com/MichaelChirico/r-ci-samples/tree/master/pkgdown). For any given `_pkgdown.yml` file, remember that its History and Blame can be helpful for seeing how it has evolved over time. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/vignettes/linking.Rmd�����������������������������������������������������������������������0000644�0001762�0000144�00000005761�14671042466�016055� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- title: "Auto-linking" output: rmarkdown::html_vignette description: > Learn how pkgdown's automatic linking works, and how you can customise it. vignette: > %\VignetteIndexEntry{Auto-linking} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ## Within a package pkgdown will automatically link to documentation and articles wherever it's possible to do unambiguously. This includes: * Bare function calls, like `build_site()`. * Calls to `?`, like `?build_site` or `package?pkgdown`. * Calls to `help()`, like `help("pkgdown")`. * Calls to `vignette()`, like `vignette("pkgdown")`. ## Across packages Linking to documentation in another package is straightforward. Just adapt the call in the usual way: * `purrr::map()`, `MASS::addterm()`. * `?purrr::map`, `?MASS::addterm`. * `vignette("other-langs", package = "purrr")`, `vignette("longintro", package = "rpart")` * `{purrr}` If pkgdown can find a pkgdown site for the remote package, it will link to it; otherwise, it will link to <https://rdrr.io/> for documentation and CRAN for vignettes. In order for a pkgdown site to be findable, it needs to be listed in two places: * In the `URL` field in the `DESCRIPTION`, as in [dplyr](https://github.com/tidyverse/dplyr/blob/85faf79c1fd74f4b4f95319e5be6a124a8075502/DESCRIPTION#L15): ``` URL: https://dplyr.tidyverse.org, https://github.com/tidyverse/dplyr ``` * In the `url` field in `_pkgdown.yml`, as in [dplyr](https://github.com/tidyverse/dplyr/blob/master/_pkgdown.yml#L1) ```yaml url: https://dplyr.tidyverse.org ``` When this field is defined, pkgdown generates a public facing [`pkgdown.yml` file](https://dplyr.tidyverse.org/pkgdown.yml) that provides metadata about the site: ```yaml pandoc: '2.2' pkgdown: 1.3.0 pkgdown_sha: ~ articles: compatibility: compatibility.html dplyr: dplyr.html dplyr_0.8.0: future/dplyr_0.8.0.html dplyr_0.8.0_new_hybrid: future/dplyr_0.8.0_new_hybrid.html programming: programming.html two-table: two-table.html window-functions: window-functions.html urls: reference: https://dplyr.tidyverse.org/reference article: https://dplyr.tidyverse.org/articles ``` Now, when you build a pkgdown site for a package that links to the dplyr documentation (e.g., `dplyr::mutate()`), pkgdown looks first in dplyr's `DESCRIPTION` to find its website, then it looks for `pkgdown.yml`, and uses the metadata to generate the correct links. To allow your package to be linked by other locally installed packages, even if your website is not reachable at build time, the following option needs to be set in `_pkgdown.yml`: ```yaml deploy: install_metadata: true ``` This allows locally installed packages to access package index metadata from the locally installed copy, which may be useful if your website require auth, or you build behind a firewall. ���������������pkgdown/vignettes/pitbull.jpg�����������������������������������������������������������������������0000644�0001762�0000144�00000150424�14634573316�016132� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Exif��MM�*�������������������������b�������j(��������������i�������r�������H������H���������0221����������0100���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������   !!!!!!!!!!###################################################�� �"����������� ���}�!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz������� ��w�!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz� ��?�(((((((((((((((((((((((((((((((((((((((((((L8g"z~&R }R c vJ�j+d|# s+1ڋyU2O+#Դq뤙F#}U=2Iĭ�zc2b�OaT4r4QTz: >[TkN!Ȓ=<UV/?/W۲H$H)2Ĩ$:�@ `2Ju~}#o>W M: ĨLͼ>hA򟻮${U|!B>T'=(N|+_.p&?g #W~\26>H̞ۚE(J+@~'^6^>euȮiEMIr[F(r)k~-X6~&uV?G"*#]WGԢa65�z<=:;m|'~V vҀ(((((((((((((((((((((($^A|[.o4^)9By00kJV T>?/A�Q �@}~/tmmE UX wϧcymةB + =Qi/uo?ޖ"3]=7.Xiv78"}⧁m ڈ01(~ F!�=׉FX˫JF0 : (kr4DQPE`6`u>z[A4eVv3sM[kQk͇ΞM4 $J"*�zIHgk\^f`H¨C&{�.ē~d\SxY]gl` ?uU~y[W ㊫֞2◎H/xؗY�v=|ol}ՆB*7q6{EWjuh$E3ee~~57_Z>gYi1/dO k?S ?L2G)@s",~�6a;Bׁx*pdcn>h7h }TV%Q=Ҽ/uKYx4Q׮㌷64 Xǣi(]w=!@|EPE6^`~ *s%.xM�.%B?vQx${ǹ0F@C}y {Vs"D2iNN3ZTB"Q }E1׊" F;o=?#baǴƒ@ Id(\7'WkGcNv'?3`DyQN?Um.@ n\{F ?@ mvM+c4j�\nkzy:}i-7HݮAd�Yv)~C'hoJ�XwcFա}+T=n1 d_#W_>,͞wXQ#> [Eę}.vm/3? uh-m-E)2:TЂ;T�QE�QE�QE�QE�QE�QE�QE�QE�QE�QE((((((((((j˫xk>|O w$вY#Ne^,F=Wm~DxfɰV 89%i &>'Dײg&ex @Ikc쿁:l~%maM!'Qp+ԵcjId `uczs<ComiUPt<�:qGz}ssߴ@4`�i4ɱX\I,M^|)lr]:o؁m qm�'�C}KHo:2# ,CtONzt:+y]"OmF= P;0h~(g1qJ-C*ohyQ\ߋvzxm9b(HPQ1r7Z&炿XW`}YyH6 ꑯ+þ$̩R?GV̓-|mP0:p0~|8Լ[F&uL6\�i=?D!EFwYgcafN:U izMiz l@$ifHvXtf05AqP&ǭw-|xdUXvEm:}cJOvڛgT;h*":.GOOcֵAnVZ PpZmdbDTV�SvSt^Z޽0ޜ�տqb}\D?qQlFu ?i]Ӯu?16֙p$oӥ�O + E ?ǿIByoz"heV"9 s%>^OB#<G<CwB5_2)0x;I`Oq.,w#9#lywoVXAIL["{+O*R_9 ռ/' u_h%XC筿?Tێ>SېO5~oĖ�iƁmnxEk,�|�ϵn7e:b6�h]rb?j(=]]ͤ?{nҸ8#@3.~%xilU-N뛙1$P[8 9lu׆<ex$[d yH�u*{2)֚MEZ"P89Ob8o!dh7/@#+O3Csm <GlXpz+((((((((((((((((((~$'4Qy3_9W@;3(;Bp_t⾬j_kw򥍰1_!$wdn#,b6)!WTE햺&y%~flKmlc 6#t[5.N>2V8EB: 1N9#FH>FD-V*lygRr#} ͕.^1C8 c8%~\IHixRؑqy,pj]NGG;clu,xFljUnnDC/nvIpdETg,j"儆5+db1 L ^yưqhZt=-` 4К0|9k_<Y6?fCup��!<* 0a4dsŸ+*:|J<VzIu F6ȡJ~1^g~a ffbf#|Y"0=A[Ȯ.'-N߅P~bG5^'Z;)8 <p*G"6�S4=^Q\DsQGoj՟_8C"|O@MҰOu(W3�\~Ҽ_ .xev3<G=.͌_㍯tO4= f~' FDWMDBw#AGmy1-XSa<@=+t+"XczCڦ95M珦zcUmB-493(Ns~ljn\�+uiN0K0{g�+K}(p6-Bjo5KbXӯ࣯aҴ-. OJ�y,U|Y1PI8q2Fqya=GqFbY#,{~ z�>ռ%TS";]*s ?+>3Ϩ3Qu %6 J b7Fȗ$<-~~ژ <R/1ʞ2OOÚ_Xk;̣j6_>b񹗵-JxQx…Y1 2pd�8w_,;<ǹ q CI"pQfZ'\+L~ͭ[==nr~^h~-4;Ayx1A-X}jpUn"=0xt>:ѦM7R'O,7.t'tX�^@n*7DOdۏf {SuEn,$`C.>t�)^zE-|iM#ya@g#kuoynVE ܬ j�EPEPEPEPEPEPEP((((((((((>4ižI72Svʪ+i.hŭ `~W8(L=B88?M|x~&$}"�W 1Sm=ʽ a+r(<2"炍!�Q<R/J!c)R }ߒVڿ6BƤ =ʲ Kb'*yqs5o$1œ;@ q^Џwg>E۲8!Q@LB sڑ7d|;hғkQ?+Eq|mǧ ^< 8qkOM�DA D B8\gk6 Y$xf =:ۧjdsOeǒ"ÆYq05潏¿AU[h<tG~N s 4c4]g§RcO~/h$ЏM!뷒Oa@V<+KdW 6?�A^'Gl�sJ1rv:Nݖ:�'lH`ǡoU|5� O@J_dgc~T -O9u aHy GPO=k?XnsKt&#`tOʿ><⫏ q_B4l|ī{t#H}ڋɘGSBeXwZL2@,6rc%�+H/~4yqvB`�q̜�ehdAs8? α?/N+ ]L$O6>u!yp:l\Jbq?J`zӎʼ 4@%qӒpG+[ N]}�� Ǒ[xj5}Y-Khc9/\gCmʲC?v!g<e3? x`x7_MKf#7$uM?5$:@|6 aF@!W=qz=n۷88Œ܏Z2W{i !"*APq5䷚r), ( []cA=e,;]~#Յ1yO%{n|Mc{ePe~Ó kyw�m< lN2N|bu K+2@֌i%bx?яOeGu O _G{Q :FwVo]I}c ^`S1I#fYE2@6#T$$P7qXӮ_ɻ?*SX˕1>^}7ui}fmc.ny𯚵1_Wڶ2ZD J 2}EBG]AJk2F�F^us^{J`�~0g ODxY#n$zȮQGw͐jjO ܸ<s{zKI!F׊E8tabE�QE�QE�QE�QE�QE((((((((((\7KծgW$P͖6 #:%h~Onq`~T� E֙wA-r?48+ yZfվ|5>|ODi-l?3dRX.Gے,>m@FU�gg "CK[ 1YO1&Dpʽ^]ϭ~ >;G{rk8}#P{ 7C_WWҘv޿U,x79k¿<&%F hmbIЯ@o_lt0?<)1iD_̠aa Ğ=5=V26DY|G%6} ֩iz$ao703emg$~5x¶Oq:%.ͰB(kl4$Αlv c 2H?xK M@lr؄v>Bт 1;sS W\>m" DAV@v'<SCA1o{iquDۆXepF)Š=/tÓYƼ$ojMƽ/TbKmˌs^q:]H**t'@ǩ~Ԗ;O _ rV0!F|jp=В{$?;YxnOyvh'OT5uWRpqǰZ=W0g�}Comұbj^=@;Tc V>Fs$§jz�?O8DGA!? YM~Ӱ2/EwG'\6%rF펻0 fkQ#1s̽�z/Og<9bBGn'45-! ˟ƷVsNXp>^<E\)r}쒹}P5okİ�.&mXQl+?McLmZ ;T:' $'SuG`|}W7R%AK_WlGKB򽦭xfRG3f|8FFz=z}2hH6T09E \=ſXER?ÞGLrWP:E$&:dq?8>6i+}^!D;#Oھv tyWmQyɷĊseW:k-6Lǹ$c'Iu7_ܱ%1ʧvI#٦,.!W1mhVe *Xey'XfHTF:iMk]Um@Qf&@~=*y&J%r?|w*ᗊ=KYcܜ#̟3׌hZHo -)WO-Ėe$dfsq[T$goAȊcF�:}>B(��ejV|}v'QQ8G8jcOc<J(\>]կ_?u? #$,8Hl(HQE�QE�QE�QE�QE((((((((((wErt_W\,c �?W~ IVM:P[,I+!;鳁<P[Zgi?ؗʴӬ!1G}'pʀnOVu,y.g\¯L/3jzUE@e5=y$3�ؤ64D�Mu{3va5܎ο2dqqө?*To-谤DH݅r?ڑJ[*pwp@fiC -{Nscu^Jڸ . ;lEeLq6ݡ8ݩNӵ�MIɽ$S#8j4<5׃v$lxm q�6yI"ix兔r_Y'Q/o-bK|#kMp/N{_U_MjR۪!ʹ!z?XT~$H4A0Ο4�q ~Hw"φǪBCZBv>eQ}~.7h eccWW# [UxQp~oyeITCu;Iv1\uE] f^:UKHI^]ׅH6d^!f@7=1إ֥O)^y _(wpǿҲ piM��;ƾch_] Zrw\Xx¾ẍ́˲ՆUoLG,"%W]mW4Ɍ`ßPW]ckr!BJ(7;J:88?J3[;�isbxÚ̔@2ñ{GY$6( 23=+又ZԖx'M¸(nCɌw|؅4z̿'dH1YgˊTyr =k<-E3Aorw?p1Cuׂ".S.Hn Q<sC1_ݭum`[dEC�-" B?obJ/;;xe�&e�tlqq^փHmcCpY;qUXǧҼG۽g^od"g^�-63z~"p$[؜Fn<|JhX[{"̢Cs6e=+Żd^m�8hxqvk xQl57ww`ʾcu׺w:i'޽m?H +{IIt3X\?p\�rt$r_ja@ܟhϛ._s,(q$oUFs껪j隅ݶ AJU\<W,qclu%}B,I4q;ZX+|0Ȯ]ڴhr8P|LP\%`Td$IƧ$�ZB~'-=bAfnG `r9M~{|.q)d&V7Lbl| ?�+!5Ol~#k[]Mӿ8�-Z%EP (�(�(�(�((((((((((({LСIo܆$䕱cE~ۊȲѭnRג _'W~947'#1nч qzAoI0u N`�&mT?9< E|O%Ս{ȕčA8:gutuyA$g A<7ZmI׼k=uxϗ:)}2֍Ϋ5֟GEscGHox4[B[ʙz{ cWoCY(*C+CH\o&]Ş$?{)]̮_.dx98�zݝſ]V+\HS+ Y`v y²} TCW}c攷 W,[!(K;~ц#7z>#1 {z`ևE @8PH\{*OyJ}KH>*7}X79 17L5c%cŷ2} 85R"H<wnPGO½2k$m/I)a66۲pAZwm)T,X1W ˴BĞ@q=�hMѐ�'ߥr_<z8ڀ>|o <1�'03\QSdqt�_T'瓞[lkPLs$k$xʏVƗw6 _X#7 l ܊�*~\=:W#K=:a"jb=YT{xSD]f.!ho~�cr:#Ζُ"k!pKz E#㸼WuF�ӊ״o>C=qy=vȡrv O8QP<u$Q>i vx�.ov~oRᙕY"{b);v1y؉1󽈺my-4t F6|W؁{V�[?/㹄 "HvsEz�}SH<EpR+eBm dX;sϭu4ox/֧%,YNsLP=:v{q_ֲJBTs\$zHK>77 ~Uķoi1 U]6(ߺ+σd� m9yˤnP{`)fӡW%R hF~vd v\JڸmwS0hzw"26`9Q |wt=ݹUFn ιǬy+{ƥy;JJq0_mvmz!.vQk;B3ƈpG\& [H[O#`,6r돖IR5,qG-FT} !B!?3Չ ~|Լ-<<?ۼONpV[U�8U zŸ_ ck\4.@Ǚ3r�+)jŠ((((((((((((((((()hqCdմc8#O*0Nß`+(2 I3jIaD\AP3_U{u94z3&[~XŜL.i[_t>.f6qP=)N*xM/<F-΃}0A:_:|M/@ NT}9닒B]81X¢Z=->svsjy{4=_-EƩ?p}8ҼChzl'_XVſ?`JῃouJXb^pq}٣3þ$!<也摰=OonI)y( he[~?a^;~6$ ORi# KVP�⼯*m=eʓ:8{`c/*_";ZVd�x)gjcu6>OׁJ2RrZF6Kh5xq{ KQN_VQ ^Sg:\N'u!DC SM.cjl3<7U`ھ1>sK")=<ʼ!gA{lᓰ!_+tʛ`rzta Kǯ_4i^?nʚ{a"qnxڍE?Jn- 0O LV1|Ef=I�NxҨ[iZ6qw|oz8=Gy׋ulfΤ<nU<~UrHtI�2PjԎw =Ρ>F'tYePz|pq\s>}`_2Pql{q: $u�xpFoOw SPx{fȐnm$qzx 28w xƷ1qZF!UX�YW {�İ6X,"BvUT$|?e|9gUW̝KNs\{7<1GWSY1 Ù8m@8 ZA\qXPz Wo.Ę73ݵr(?7b_Zӵ+ԡd"�?{:zd~GoCPwS?Е/SE*>=.$i']7t|vu?56UH%[::9�<igH'ixCH/,-0՘h>bTH)rU??ױRL(�(�(�(�(�(�((((((((((((+^!Ҽ+\kԾMc*噏 S�O^YMDB@ܞ+z o%dvM:|SfIʱ#+޽/}o]Etw9 A:36ZXޫ@ګ `GW|yZx{KdyF0=O]OӼQwqac?ءl0dݟ@O<U/>u+5 s^9@XUʹcx[S]%s'sE&{?O3M8U!Ncas+~ x{YNF�3\xCŋ\i$_#zsi$sZ`6~NWYO:5wy-!y6}r\69kĢ-om@$! zּOiVMxNVgP}ާ$qK ]̫%_`"b1bÛ*GwpH�_ QuvAtW|h*뎝x 3Lg ާp+Դ2Emrvc VxZ�'֮^8bii0}7IIҼ'v3ip7T^ ^r+k osă#$bxV/o5x>?�PM>i6pW[wsW�E�\ْ>hPѕ$9~GoK(l8.3c_^I2Ljpl{PHW kM%݉DG+xk2i2o1Ly6/ȡJߎbcRX=y?a|=ƩEwHBBrֆ_M}mڡ12r=l|,R$:?g>` Sk#`%ԡ\G'u X߽69]> U{COB f@|do08W9Ll8�杄t�mllY](.U?1^s3NOܿoFt\4U^ohJU՘Z('|9l@߂<-nw y?HOjgù!x;evYsGESo:~*Z5^aq&֋y?w@�J&�)hŠ(((((((((((((((((((\-#XtȇAiqhE,PWzo<){}O%-c%#_T{=&5%ּCQi� o6yRO;A� �񟉵gS5U:`c[xB o'ҽ;w)l!Ym@f*JqF?W伷.FnȏN1{Wks7h]I,3E"fu#|?B/:qג~\/#X\hR,Jomʒ 8,X|Xjq᫹/l6mnyqE~U q^_is\ zNzÎԊg|ekmIM66ifr4SmlV8a^ehşI<y cSrG#=+x{"͌!E)n >7Ieu$6ۘ9h3Կ׾{`p)<⾎op ]>mo;u4-䏻 QUn/'$q_XdC�gp?k,M`L@;TuoOO\}Jŭ8u{}BEFƻTzϱ?Y`]n͈73l-hZ)J@c,n7A@VǼC/\XʺhHϘƾ-^y<@uސZk@Vw p;ǚVVG-C$*<sw�feXh#|qQ֨>Bo>@ w=9קCh,eٿ)<8CI^�gXD2hė~p}OV2&m@.c5;Tt̂2:>xůjBY"]"k\@Zo.1՝TKqھ'j/x^HsB̛`q+%EΔe̐LGRr=K-X]ݞgktcQGּol;i>/qmy."D Ԣ�R1U>[C~ j4m/迻vv6>낣>kşQgin|$NjAy|K(b;K59O%o GN}N~((((((((((((((((((((++Z6d)Åx9g }ľu9m ̬FG#` ^}[Ğ"6C>T*��z~%)ۮ>A <4p:漞CskMѱW\lGHb&GZ^Kk FZFрSpH<]O� <wv=ڈn`nS6錅4fI=6QčEFGAǗ ygM:`$ŸFu*KH Oj! 'Z1�|8vbr<c8-!E +:qҾ|_^7<Cg>b0g)﷦y5w�nE[D7XcisFv6rcLa;9!$=3cnb;;p^ڧCrLL7pˎãÏʹհY]xy�ZZlRU#G-==cG-qV|SDZfɀ =>Q{ t%ۄӴ&.F7@[7?p5�K??Jw&s[RNjOq7(W =^>[%69gҾIv/I۷?\<|N6_^0GWK][|?[0ܞ?J$&Z}I# (h$Lהi*b8jmKźȕ)fޛ* =#3;Zı: *۲QqF+]^a#MNdapI}lk5PUpC.GOjMs@a5kǓ3~Q>z|JoD܇R՗1@Iv E� pq{67ky^L| ( ORn}EٙYe ,\!3U nk<O-fdmRHVF<#6Q` -ҀӢ>w�H&嶾@$:q~o|=)|.�k'>['�6#vm5�om֘Vr) ĩ'sڴR> ߖ?;h~Q\Oiryܔr}faEPEPEPEPEPEPEPEPEPEP((((((((((3hë}8?B85u�'`|cx sz=NJ$a>h-B/zt#j1jZyXW$K x+Y˵6 |AcX.mANwjX'Y" ) Ҡ&B_Mm x=}1~2�-R|("R^fy/UW &\Qm jq)ճWk6 �]tY _Zq|.:\K �<-5$t1@|s 7q;'ݣ#ڱ{YhYVt#^hXjn#ʍEUϙH8.q\{n"6pg9}Ԛ5 ZѢWbۀ$ �Ta_EY7OY|rVx#??<n<98L RG`SFLt}:"P)}c*0J@'Wj � Kmxm&UY:<W!Xl[m;TH;6U${Ԣe\uU r1"L3I j'q^p|_ki@�nUsk0ug GX\>dߎcő'A"spݰ@+o|[tAwp0o+e;YY=p1:5mȎT�RNу_N=*7vL˜aМwN>ҲJG]I*8/5�Q B i~NA [dm}Wck5wGp>(fba>ERw\rw?44iV&xsybHy�8@((/o6͹Wo-zdףxVxlQj~yé( \/_ k͒C�5eLݎ0?ȯK-{P5oiy>T=7q^쫩׾&_9ik$y+? ɯxm/|[v i]9-/(@ W踦)(�(�(�(�(�(�(�(�(�((((((((((P뿴ę�--K¾ )X.䑏X-hϯAe-#_N20 ̵ѵZ-6aLD[,7>9r+]'E/XF($�?_~1T"Ko[ER܄H�Jzɷ?t C<�PԠ)"/":/'wG8D^_M<tWI[wemn" ёɖA#cnx5٢mf13 |\`Z >9漎(~5K-Ţ#KʅW6/-x9imt+NF!-ndExje)W@��1>쳰/VvbY[[y3VdySC,=X6yz#[ܬ3P#n Svymݩh܎Hv?Gb)m6}>n}?A]5Ō0 i0)#?t92\Ҩ*p&0(p=})Cig$Oubǣ)6=H4_|3؆qQ98sk$<~X\+~d%"q?*ơ'EVwrM�(_nat٥q��#_ν[q7Ib8�|?xGO ,:v.ZƊ% ژK_kH >W3;1-Ǩ'^_Ϥj+m� NN:Ib٢nǾGC $yDQ_g#gw�ZsF3�i>UK>6H_Hm*21Hplۮ ysYfXy$2Bé]ݛu8l&ԌYʐ 9vV)ީc^mi}WhdX [i]@͜k('(1˛,i..w"۬afFI cin/+4 Xx?PlGXDg~xԅV46}03ȱYLVA1TIд=GGKEG+ąn�+i"G}Mtφqy79d$A61n_ZYj.U#єB�^1Gudm3l~:-:Mi,OQ78gДQE2B((((((((((((((<_xS gcgo4{pdyAG!`6-aLd^8]:8s|^%mtY A>֖7ch`SWue͟隿tMzɬY%)t+=qIO"ȿ-etLDo="JYVHG"+ȯzc~"Hot[fxp F?GH BU[;MB+ Rx&P qL(�jV>>Lљ%CDQI xB>s_N--W,{Qݏ@+?~$<oƗk-Ο!$ϖ0}P.OCیW9|g"@vfY>T*y xjM?53}&+$cԊ^.gD<y_ym&=Քr?붌%W(~<0![5;^7,)Bso4k-q@^YHy8AH1> !�-#o-<h!v˸�tqd#V_"ѭU <|ф 3Nfb;KmJmD˩|d>`8a (+nO7^d4MB5FcJ1Nx@<oNKqwcyOO-Al$ lZDžⳲɭWSqw n 1J |f qP򌯸jxC_W4E`*Y'S*,<ț23oonfIԢID`e7r~ Wldm >@ǠkWcKGlQT0\BJݦt?o<~4,'ѵT6'i~H[F�0WA6mZN�Yk8f8oh|ybOrRa:=rխ.#y1vp]Ǎ##p> f!]FZqema#7u.~}D?;�JG�YAmBLH(b* b~]o�^c3m,: (1Z$ v:ޠZ½_M֡-֟�7Er�;J:+_ťVó@^4KwȤzblk&<+4%#핥̩|Gd%G<V/4K鴭rݠx=Sck5uj ?V-|o%Z~RDfv?U]O~AExն"]ϖ6}N98 ̸տ"2޼Zwr l}fYEd.>heu8'ûNdKm2fifBйiC,gGP9IeA<bI]fء\,,h$9﷧Һ GB6Vo!y.ac$I\HҴx-o-ڵ^# Π@',6+ּ7]:NKpתs,F(`Ӷ&jHHv"b-_K#?1UM K<ئ$�P<nhQtfTs\~g_ s̓4W;Z+t玢söe-ْvڸ,^fJ*̆4+EiKy%$lmmAԛ�+ҭo!4 6į r1)6S<1g'DFd)s}IEPEPEPEPEPEPEPEPEPEP(((((? |KJ]A.cz6{(C?/Ƌ Vcr?w<Ky 4L3?=r2~xº/4 nWwR>ytO~վx>O0\ُ:� �t,/~9\6dI?4"Yɞ|�A!N.bedʲAĕV[u2DGSh<_GWk+dIgix{Z9꾀4)Dz(@3_ T}/x#Af_ 'ԪqI؏0Q܂g7Q/ocY֑ĨH6v@2RW?ɳ7l"=˻}))�i  𭭷<7,ft>mz9ݬ/I`dtiYPā>2#Drle9Q#T *+|U+5oK@^; HЭ'iPİq+@ xګ![7#$s\s>6Ugwߐ @s+_\3 gnܝà #u]LRO±rv7}!dpy�u&[Tp%dY0I<ܞݲ]kmoh01DVt͉$%~\ l�|ewl\KcBhspXqltOjVzݴh)W;Ҳ#e�v žI{ǚ ˇk;Q.XY6c HW=j_ZWRTJe*6!EvU/DaҼ.c"Ha@b8"xmfWct1%;qK}]N-RTٶ oΆp/`&+\+I'[{}BTB m>/2KhyLJ-/v3. ɑꚸw9qy mnKؼ=a)a|\o7Ӻ߉|Zƈ[sBScon-gc 5�![;OA0*p`ȯ+_,bdżB61�a/^Nu-MXt4LФ+FJ,j<8#ZJ]ko&~XĊ j+/ʿHV흌Jv7(_#L=?NM:+Xc $#9�i*ޥ/eǏ)Yr K,Rz[ZC#dQԎ7hYn؞��~wk_<cxk-9<omi*Cc2:xEWۭ/M<D1DXeL6xϷе_Z:5G'U cRO-5Iʚƌʪ6"ޣQJs":M/H] ]\C%k}d'2$E*znjCof 2j G=<c f8l/rWKFf1M-XzT'Og-Ped'r*8펴8[{ 7 [L(i#|I}îBq$VBU"$QFp:l֦^wI4[~8Q9\.UG[4$~os?z` >l2<c0p0܀ +\K[*}j7O,Ӭd$*\:$_G[Ur q=[DgQE ( ( ( ( ( ( ( ( (?((((((}~'<5]5ŷ.9u{_ASH`dki4vp*Mn#]`A/ O5 M?YH!3Co,"4ﶻV<)F8 1]�7~$kZFd)W~  a?U]mDWoܴ�u4 D'_^x!u#4Qq :Zs;ߊ5cqcK)#QO+埃)|UTFFT:=0wY;O"  UӐw1~Kc�EEQ6ľ+U=cl?j•y I-N8Z*s zċuVo'nOAExέ}hCnIm[/e٧ -ܟl�zR4x/r[ooݲ-Y]޸UdW=CW~ZR,0=4FexI-IR:@s^ᅧɥ<-ďf; !ybX]dgMħ zl\9ŨII ſڐ5+N-- #Sȉ-PS^yQu6XgND`˒6E gKִ X h:sS۹(8-'_rVZ ~}cY!|dI�mR9 k<aYXoxMGҮ&Ufo*jZ;s&H#b3c8�q-MjmfV|هIH2J؉2lp2<?<7<hI]ZVeӥkh:EpZ^m96F=bush:x.;HTLdP�К.<mv?ik*-;Ҙm8![Z4bu_b�*zu3_\)*p7Kv1^[{k6Ay-[0<$( {.쬀mqޯC8tˡeo60QA sAQ;7'8=x4I!-<UIաi^B"hU(Ak*7q=EyŔ^$컸V xdFa�k[m& kG<aLJ"k'nY=q_49_yIV tźΘ}ͷlH^2W/#ЊjЦ9o'��s,$Hrќ1}>o?*篵OXKБEC' >w=�UE]&cduS.蘒 ^ps~)UD0k�m۔lp+^<[Z2-/9jޟ(%qБҸ+O[kJ- L@X굯Y, Zymܦ3מjM �q<?{kXV[ ʌgH珣`]xi̝K&.^sm^FXe;bq.@;28S)#ž[ks+Cm$BmEE!uר?>Vk/z:Z4%gb $0s7xܤ>2 $~&xiZ@/P ( ( ( ( ( ( ( ( (?(((((()F �χ<L.p̃˺\.6|$2GfѤ IMi7+n@<*`1_T|b_ 4A,^`rf8Rb! hZtEC4B;=})y/ n,6I"ۙ[��8fFN1~/ZO|1g[=�ryfn\O{y"mWd36Nn=n08rl<?DQkLmNU=}24^"u]GׯgCf/ 6?+ %ŬO .q(ɺ;hW-[UbW;Zm;I+;ey-7C MO:?{/ڼU+Mn`i<Q8f)I[٬#[~y)5+;9l4fE.8!0sg<f2~:ܩg tz^&Fetq f4 dTYJ6A=x!e6MN)P`0*l܃ݦqq"bq"7s=zgx$:|jyYUyTnvT)az�,6<y_.oAt(t<CT1By燾x%V"q $UtɮtHO0UDbxpp `+mbXJGϖ`tU~OԖhܼ~<S&r]6f$�[H(ހ@p8!y=�yX?f.--/#0\Ʋ! `8\"vݿuo��伉Ÿhxm⻁b@д6 8Ӛ+O+lB�>\_O׫7-qw*ߪ1>ꮙ^ |˩G=4Q JE${㷷$}U"�ȪDj k&{}T$aYpqyW;Ud--A~_JM_OHg\r�%_|,?bgim#+JU.+}O@`'McjͽҲ&s铀lt7rz|;wKs}O˼C⟈[獺|_h.{O'ɜ�8\1�#mίy70;;m 0P *kE3HHUcyWxГQ6\2:Z}C+prw>Iك1"Z~ogi.5Kɵi$^UWGzM:kX[y1)wjK-olU$]rP8m%O$� s˙amf: TN2P03n56It"C8oCCy4Y1HJtNaN;F%s .dv\m.{+_Bh\Jo![eç^QR\r0iח (]<jʞ%Nl-�K gJZHA!pY>VoW[�.PGu) vݓ oVMl]F R[v7ǎS;O4m<Ib AIn)6»jcƻ U<[^فhU+d(�(�(�(�(�(�(�(�((((((( uҬ@UG$WWzǴ`]1}E`�a8CsqDzxO<? :zZq?ߌq^ $h6Kvvj@@x =?_ CFv!#(bI7 /=OJlgVf\7/dA&(>M} ;Tyב7`L A:,hvjrYlʰpgl̨yQ/'΋ocɊ'\hqcWAZ =ѓ檉-藟2c=.kSZ{xpoAEi{W1s6/Ö7j[KӉof;qs|1x},b4ǣ POwHF:m"N{yjycM#ܒ!Tm8 8QV+w�Xa}71St؞E#`B$^Wn [vcYF bؑu=>x-춖łx*y&�<} x;ᥑI>GC�8~ [&g|Y7L+q%%vC(8W*Fy}y}oݕw<.@Ҙ3憺}M) )f<p9i@p 0p^6!.̄rE]oV�UvvAF-:6pVy~W)2&ʲX* 9?:g($g#w @8KkZ{J|.p?j�o ij\is)Nq=3X%xո⍸3.Tr!T{W.YXFx#د=5|f,1_$0+qM[Y Kՙ۞خ^Ե߈D5jo$"w(d�Xǂ�z>?|+Ң:K_J/!>fGxqxwI5_ɳbǏJ/mkd�,{zI[HŧC  Um[UKV #+qڝvA.qvB0ˤfAU'sknnnTyh>_;)1 ~]f79p�$J2#d;者�{ $Sʎy ۀkŮ<$2Y%8(�rI=i<9:muUF0TCoR<%4~"2>qm=Rgy^vBձO1ҵV BG,rղ�.hgc[V|9ilq=^m]u1pmRȄp"z`'r?=͠{! ~i�`"n_MhWK>J g#$S%pw[|n?cxkѾs�:@ |Pےl813Xm.3%d|D~Jʝб3>^G/N+yRt呜mr>\㧡._#|z`ng+L:҆G`Ƿn t(a#5WkOO'6]a;I."9lo!MQLAEPEPEPEPEPEPEPEP(((((gG'pu;K=>kcWW>,ߛ [60q gȠ}7Pe_)i6QI奸$cM;IQ3l-$|4 8PIͭji lY= «Gn~1.-q�- @ϋ4ƽ0Dr.d~_v|7=Կv5U mlqRod<ܱ�wenx}Q5sf 9ͨ$~z&$*.2 R*y>O3Yf OevQ[[u޲ 0640$�c�gw,n&kp . r~P"Ҁ1.QuDӭabaCHxv^oggLm]r%8) ) ]Z@mDefxlpN|:6B08ɯ>%2}U[S|m"79_!m.|>g!ҽ@WQ T;wcZĿjq~_s6c m$r{�YDV#n={M�ϩ4WDBᙉ 1bp:W](O}�ok<:e&!)H$q|p8S B *#~ bD |\SU$�F�[===*Ő[*k1� lu*a^o`њ8mS:B}i|Ii(n9 yp#rY3y:ط$?*~*My#}|Yv }q«<_rQc?|UwIiҳGgo'`yW|\Ldmha)ybwɯ�Wu, #VnUG~3>2*QscweA`쫱6 g�)~4k? A'?L ]ZU.Yƀp0>oN�LmVA34P ( 3GP|r91SQkNh"O:G,Io}y#1xLV3%jx|;q:'ڀ:(㴷0iaS�y6oif2 H"j+B�|u«gol|LE 8>Q)�q <�K}*̓ʀ/b)U=HڣA𧎮+~k <WL  FAw&K-NG h|ۛk\tQAךǾ,Zot*X��MJEEf:?u! :P?H'W< -R|)ϗnzq|=j]"W%R{,Q;uS!4c ==09>&6 ?x@Xd~EXwvH�1\ [Ocھ)�n(UqmIv'+Ok<4@AG ; "C|bG𬱤K�oJhL>+<MEbo6O }IJV yR+cU7 } aa coҰgB֦7+=|]ض<O S i.f-Ƞ.k~ 7َO]V ȾiVERvex+ ۾x\�6( J(Q@Q@Q@Q@Q@Q@Q@Q@(((((sm<BKIW5ex>jKՌgkG[�y{*5}"IO۝d\>&ZrϏ/{d? /M.�v̇R~Go\per ^]mws#ݤiye"bh6~6OkZlWv؆U>r}+P?<Rg2x_V ,\z,o.W_$t[*y5;&֗uc|y�Hh߶lw6oF#$LizxcӯC̢[epnHa27r:`{W>3iAxI8Iu ;x!dlq@AH+4\䶉Jp,G{q&�~\\1]vm%6|5]-XC@/Դ/}mnUIDe6ۛn*1̽O#Kd*r۳l}Tc-u>b0qF!nݳ1zW^.cyxJV8Mc9F9fM/#U}6I`1{pzϮ/p$ mP&G׬]w \yIW'Q�<aTu5<�gvg!h򞯎JF)db3�)9a_Jt1oF-o˓MKm=  UI5X~6{�m�q%Օ*1�x�:$0�u!oZ;sho\.3<.�cWh�s;p wG.L o5Epm,OG9 !�eGnY-3Hr弤oW1HmV1BGA {c^_B4wyDI_x"|oVSN1]٨摜emOLTK:]V Gpkd< yy0V~4JҼ w*�}�#F<K y%d!?`kRI_>B'w\S|MFƥ{?bD fm<yTjIIZZH(Kz{V[ebG˷ c5x`9gg}(- m2wst71#R_ƾ!vĬ~|z3rߎۑw"ER5$q�`+kO*ۇ#,n^ecՀc?#zJBF%2E ,}|Yjj@�b_-> (ɯDCa 4i2S$@cl#phv4^ycͶ]EgsHFp:[n'մmdrD)QpR>W_C%l.DjT9t'%EtlpJ,=iSǷ?ҙ'IorNosrL7p{ �k%7gW|Awq �e=z'`9kHǹF @|;yGRiykRѼ{u-9!1t]gW{G\_Ok:Y䰒wܼ1`'+~ |�voHl(�(�(�(�(�(�(�(�((((((o.eŴ0= s5@dl'j`hSbXH" }hiEֵ/ 1zN<FJ};j2^&!.oZTFᘭǠ<̾,G7񞐷.ktU+|?{r4gގAmS<+3|j�m#Kao2qÍt$zW~5OxzH!چv;� 7̨x1O>%ͦ\l㟃|Eivڶż\?և޷m8�m (]Zizbw۱;I�z~c*"q)B00;LА�aڼZeedch?-\*Zַv'!$O+s⤴}rGʎR Qй~+VVu"1̏ E {)-ZTٶE0:P6nݐ?ӊei2a^9op(�SnIs@$((_rƸ6} W|G7<(k{;ln z]N5U^F7IQUH @�9S]3B=vnL>eB$H;[NG3|5ňLe'2d<s)$u̮j&Pjn#/ğylҾ\}qIJ$ceBf=b`۰}v6Dcӧ!m6-�?tHjmBE}̩7P;AzV&$AA}h|BmCPĥT/IQ_n [_['*�?{ݸh3 m^]#uv_3`%}ڀ<w?h'_Iy"[dj~Vl0zo"Q4`I.\gg?AvEo.s@{ReEjHq{3!'!ei0a?+5^+l[n. 制O|&l0qNWcH'4:X!@  l1H]jo'nE->wkrkv#tp-ߐ}+|?t"[#mKtz+0T�6W_y +Ex#w{p{sd؋U'{pY �SE퍼zToijv뻆dspy> Dn֥gje`rs3^:(8J#*HL||zԄHOPdeQ9qʨ^eY鳶Ot \>U+ּKBnK4q e=)k=q�19sB*ŝ5k}VF2,p+`;IG_Q[mkB$Ay |čfm@] ,QbZǁ*п4{U3}&\F:+V6s6< I򭕜-гSq vM4n9im4R]Irs囘o+v${'+@Mέ$qj˽i4 mSKV;6w;nGuC1[JzOl>h]|$濗Eqq um7J6m2't$;MN4,.' };J/n<;V@^ }R�>Y =%r?GO$mar JHW�a5W\Om!i�d"Z,dk/47WQr{]sޫ~FQ%\z7r8>TQE1Q@Q@Q@Q@Q@Q@Q@Q@(((((hkO^7F� +?54|EoR2A՘Qr9 QWk_hrjN>Q lqĒ_J~#m|;6ˍǐ:�8kõ ~ Ι] VvUXQr�QHhc[٫an%3ƪZ994@<Up>$f.j{!r4 \chHn[T-j>!e(m]ȍEi$f(QC! خ; B<1Q5Md|dPe ! 9l<!EZx~&abY~cn� 0WՁ_φd�_5:#qϮ>ιj3ݰYl35 20.Fc1'Fko-"4NM=ʢĘhs݊>uy9^h(R#d\ѹ pO⽦U֡'8cXB1J˹,JW]hK<IPv>v4mYmfTm %]da` c#tۢ9bBJ"SI%Xtl>Quht'u(v $qWoeXċ#d2|rq|uHM?P%A'b|A,�lϭ.t]W/x/&Te8t3=Dә()ŒWh uBDD?wlCj?K sQmS[<ae֗ip yA)-~,we(j*g[DG~O^%k>kɥS!$TN?S[vN| 9dor;};{W!a3,m{x~y۷:3cr\| Xy�t{.:_v[_ċ%"u폰'o^:v-J,g5d4?l{/_ M JY!ϠZmB&d0wK+vhqpq]ok}b]ګ#srB$atN{v'ޤR5lW*'IVg<yhp"XC\]ML+hleN3q-LKֵHmRvf+}�* nI)9 revJ>u/`?#v'ϻW#Xx<*&a�* ?.I'̼6%1q&]-xV=FpqH;y!c6v18أZ`.XʂHD7ı LdD  cYu98﯈QM JįCx<-ka/+@c F;qi?69 W�Wc|;nu#7py8u+[1x˜pp>�pHk%ϒp:#j*AWIŸs+|7gi_d/ȟub7,hG=GF]bwglVƤ<86o>kei,xs }s"qJNvWxj_m5,w `ʱ8� ;䲟Oҭ-̤ov9b?wh (̪FP+xkR|KeuhzN@#pg<*i/|Mx{Cy-,NG;p#`Ҿn1r}Oz7ý;džad58�VD3GA &ck 9<eA:rф�j]lѵN>t Nwj 2i=imY-"D}[~ށG*[iҐgpt{O.9YB k.u/P!g*°Yk̋pLՋMsF6P/ @T}ESQE�QE�QE�QE�QE�QE�QE�QE((((((3 NºxWn>㯺lXj+'{[}5dOo?y0=\~ׅbK'G'N]˿o"'>tI>M<O k8آIcsʮJ. z##5ݏ0S@WJ$73Ҡ10�5l.4:/N}w)�4h\цF֮_[ =Z2¶:S!}* EOQi/晆5u%.f?,K,w6` uM;] ai<GT2#.wm#ԭΟM6V72[K̼*gU9c(QV;b"D<`PVhP`k ukv<}ޝ8-ɩGR]JAy# QG%?8=kW/9R^ >R 1Air%tvۆ_z9Ov_ 26bfIo6a UZ# Džv˃,Ll6�]f֯w>ͮգ^WЮ ¨kZMޛlɋM{bwXNYAV۽=nZ#NW_dqN�g|;{s%ڵH�yUvH)A8 4HR Wj2KkpGhXAU0Wx;Ak]>͈kaQ,e߾nE^wbDUKXX qК;kGnđvV,Vy xz$�Gh+w-=2HATq Z_Op)@*+~6#Ui-[Q|pzﴎD|F 6d`+{ÕW '[|D2c I[Xq: 77pjWE%b Lh0^yڭ]F͖&tfG##yva8!8ᇘLFߴM-#0' fG%p0:( T5V\2(9(> >ثiG7#mN%mkl ;p*Dn:bx'p) i:�1m`^]caQ@g+ 5I[ԗ<+qo̧Ƚzk/jzBV~j#zcccns4no=[ķ:ՖVbŔs$^(O&k �}D볆=ovfUA?.G\s{&LWXH7xLP+Ʊ.Yg} 0;Jcx<f m"X4p0]ܾ SO>bOrN7^8�w @dCl90 ~$xwNO6Cc%ԪVL1-Љg֚<4y@:*AC{{ףEBd<Mr1 �BxJiZ]浺8'S\�=խ&[y7M_8D1{NQH)ٵa/?5 0M? h2azks\[X-[o5$ү|#mMܥ͓h�lazb{5IWOBB'|`WT�4{[]QeӤc ֻ]k\{k 7(P,\\g#W! 68|7+6[#۔#�?1HJ\:zFL(�(�(�(�(�(�(�((((((((i�z^!Xkz #(<z 5VQii[]5m+yiiL@> ag[[_ڼ(݃OU$tĞqڲO V2pT\LqO<7זyȢ7`|]S1&emz :fj7m2lRd m͜X6G S3_jwE�GHL<5<^O]e$ s"ka!XLe8ILq +M@"#y: :| q^~R?C;qiq1X0 \}hތ\S�U8Ī0Yr�p((k%*N?{C^jwz9ZWoeP̷unT}sXI);~]l%sʟ?$7zu\; xӎdu8>S d> :}ʉ2ASb6m@5֒Ga 0l Wr٩v(r�pΧ?OuOufQFjo V$+g@$L�$({ԼYFx5u0cuD� CKS]n돯^9 L{{cVN?<"esMkʥP,rK8g=\qG!a\c?2OIqϠ}j7"B!f@=y?Z�I̖8Pm_~Қ|WS%ե݄?u<or}\�;u{vF?m;^ѱ~+z|gO. @>E9q*;])Id ˱G؂LzVs,d0Dдvn%%\u$zsiWwzGo*J.o3ɰ/{k|A[/mb :�2� �Ȁq$*<65[y07LnGR}G7wXllRB�ta.zzv?}m/-�m L@w9zwҼG~w2O8d+_?`P | qZxkQm]H-ѱoN[C«,1( mEqltx-UcAq1^W|K,i=֛m<NUcv;1ھyT2rn#)3eٲA &r jZM#˟/m*H82cGNIh7LMm5M.~mssx.z_aq@A83<AԤ;3+l.N|L1 5Y V&wL_FVPIPal^q�hLzlH.SΎEqe2FL~8.u(B{ƒ8tf;O\ԖvW#藫-"y \S ߈vp^i0ܴLZ" Ux| 0EuWõux-p,d#t-`zտmtXAL!fD<靝|3ͥA0[ć|ƈFF;Vׂ5�ZIq2G{dZ8"(Z L7oܶgygTtI7pFVb l/<C=+TlutYve#vwރ1X Ij ȑn>�;qD duQ@Q@Q@Q@Q@Q@Q@Q@(((((͸+|6x�ޢîJ?M, Fb%.ʪ2I8(O|5Ўl;ypA,c}A_xN׾+xx:K6s8!nZo px >0|aIaC-|4�2S�-�玬EzKO JeMܿ,;m̪q|{_H1X"K�L6.c τsZiBH0CpXS$@}ixb�ǪoCI. ;\gSЮv* @Ǯ}{Xw>W_ƂZYXWg1ƃF~bȁP\5_:Ο5^dW!Cogr>R^>/Vkʷg]�QsrN8�tbֹ V xۗ( dvS[ʄB.0IH�&O[9v�~*<CcCqf'2^m`^ʣs뚓H6{i:߀k߽k1]!6pm,vqؓUzy~'JNv}p?:P_ޯG{E,B< Q"cPY--.gW]-rs ]06:WzJN[Xګ#�yqf )UлZ1U8T6? $>Laa'p}3�+^-[X"YH$©'C��yrHѲ*_3u}2>SPo C|i #208`v |M4,fwU?vFXx_c7=OJ<qNhQ }!HglCt;_l=i5ȑ[da@'zګ,m]d~[}y�x#^a+k$;3WU&O]I �A+t~}QMυ}7Emfd` GʡG�fOjpOY0E2B@\c2A_8$"cI`+hv Rs A~ i^wP n2kWvؐȮ?OnotC[_NcXG +w.q^"iIs2} xG-F�c'IWqi_4U؅jz#NZQ4cZE$61ߺObF2@k緋Qċ[rrǕ?&7_C `A;{Ox;Nahh!D$|4b�ȯ:ҼM+.t{{In`Z8]M#C�QWU}ͽ zz-好Wh$d1X`ʾ3#╃)0 S%8'zR}@Q Xm'K^ZDoXڇЏL6gi6H8s) x8y [j/o5YLnP-۳W[}#I6~Ĉ~�Ì~\�QjXǾXFg'=F}X[8hn_Ƅ�5Ƚ30RC2A]琎8Kv6Č<?MQ6:+[XFXO%|ճ{naMrv uim *VmKr$8_OUOg#n J~M@ihkxu  "/S|KuL&<W0tTI:0:]4~ ۽hvUV*�#)R]ƚtO!'!`P3ZB_P]/Oimo^Z'+(|ץkO!{-ayg( ˈdଋQ8 @&XJ( ( ( ( ( ( (?((((WUyZ TH"k]ju}2#E}tilb>ILq� �TMyioY76!s[SQZhu4yY|c]h6?`T $I#bBn5};O2A#4N-*O67 W_1|z ^f| 6r>Fk]tԤNdHexFuym=7Lg}OW))#pv:6D>+�h5o(Yj TrFBx%ۤ6~\P=(>}:7X9U۸=:U9gJg]u^iUү/ȟfG>THPcrPrq_@ǩ2�Aǿ2Og:[)|RӸ#ձvS{Ҿ{=Bl/TN{|k}GD|6}!00 d]a#/n%մ (J2ab<GGu `BcyL*`ݸ1H .Lq__|mv$ 2D$8s_B^J!E.2 %I=�a읧H>դi\#F S7MLb-5A!.i;|*�:zM_[HJ堵E#B~{a7׎d#z8p2@܃(Fl}.y[[@坶.�Wel\: foY8G@9^Gj֒nn6  S*#˿qp|[{Vޓsm$k"3 Q U~l%<VQFUqcL~Uj�E◉8ޛ8�3Qw7roy#C ۪ V<5몣MCZJ�#c80N8-\�4{κl�[L$U;I[4.R1~#nH&㑐:cw^kO_zi j,�ONin_)zq]ŮjEC-Z�ry_ wFvougj5V=AhF-T+?C#cxR9$ �<׌D:duoǂ1 Lڽϯzb[OJi \ 0�NSƾ#-'\gDLByP?&k9/ Ӟ=8_C2Ɖk]oqq4� )B#?1ڙ>Z9cuH秥}]qt1b}>#9f#F c5Cw)zޠu�m㶙<�yB`rF=*g=re$Go yqc=P+xqEi #S´n�hfB8+aY?b?<+GХӯ|GY%YĎ0C #ڃvNxѨoM Ӭ>?Ƈ[O)[eE�S:'^06p^~ܗIdvͷWx#?-ND6ij΀ l_8>~]WüR%P- O#426&�0n r; kӴ�Q n2ܓɯ爮m!e �d+t@$S#>h<5?dGksCp V^0VRʃ+yJ؜pvK0H`<W:ewFmwC*0dq}+֙{V )}ĖP7`C�3tsa?DmcPhL�p_i //If Ohr?vwi$7mjW<_៉ZżÕ`7F8�_8|jUj<KJGiA( ː� Zմ߂c,8*1` /Dz|[Eռq~rc Xe*H`}x#V^5𭇉8K2f9Fǿ� ZY/6XW�O#1QE�QE�QE�QE�QE�QE((((^i~At]9 xZ8jq6?_hQ2+F?{{@�  dß:{(9ϖ�Pҵ/\#>- W|P$6CDԣ1�M *d_fnVA�hJǓ7; ަ�씆~oɩ8=ѨXH_ RVZ.7X_.cL?{Tܧ =>Q@m7a|?!Zw<7_Ǧ䈤/O~x 3?IUCEX/n%ګ,rFHS}]I8a/i~mB[o5~d4San֍ž~8W/ɖ~k{HaQ�7P;#,~1(APk o$\ώ^2nUê/�Wj3n\�Tz�ł-BٱN,YT[|EO3D3Vc. X;U_#y$Uح*`�m�}}'-x_òxSwҕ6IyykY-eb\ ;kEmG^9o^(Cd|Om1[\<;y*2n 2O3XMAs,w2 bs|@WBi|7Ή>[̽zF:wZoxdK >Z[7Ta>C)"0rGAW0mA|jM"=5sH9>&G?ڍgy=;zcVNl& 8@"|> _=Sb{kX* $q`a_ZW@)V":|]4}JmhѰAo~Qg*mȠ~5n¿4-~HЦZTF2 ;9*9x#N6I�Fќ~Ӛ3x2=vɂn�Vzŧu}: Eo&[`07XqHϔ^ԭɣjwㆴhWN`#GND�f)+-#v7oJxDQMyo%cg{WC n@όvI٧3ND[ ǰtꡀ$o%C/^=1r| KHVU$~Ë+olА˝|cκ񯥤e?$ (8l�04m4 ӷ^{y t tx?}Rd(U7dz(?@\M5kFǗ [:b/\GwՏCM �*~x|u++jEou5^1XToJd8=iUi&yPqتOU^+ܬl NpWGF$r>uZzԕՕW883i^56ïl|w�Rk�:F=ޏow 0EFJp_[l!ȁ }&TƼWfӴxW<9b\f�P �$9=I>7: ֓si m3X.ܩ*�~Cy^=+Ş zά5X#f/4K K*#)ᾝgR-cq7Q.vGʣ#ҁXGӼmzEӞSD`SW|Apj_^-ľ�^ڦR,DiG#ZH>|\]j[M3[Z-Yd2PJ{cүX| _u΍ "ܛx|0�I;1\~4 _lb_e4 w. Fk&WLhnn|ХqײZ[!a]8Hq~'QQB"T8T�QE�QE�QE�QE�QE((((((( /S-%Q�Ud֙q�I@�A6"e6V{Iq,Ѧq@M-=1\�([Hjp船rA=[u?QoCQK0`0`Oq@]syIz\4[U~M-} i{h~&Qm<z\~2(h"qӈTtBclzt^qV@aߩ#a8Ƿjg u6!FۃĿџj ~|OOͮ-1,S/ϰcԌ╋Oxak'X%qq_ |Ko^HPem�Zs]N'3ʀv{  ;$lW`H[;;@~iZ(lgALWlVkO H행�+c~!=]4Hk[Z=�+$i'x|ka|Pth&ӒLqLIW�<7\iq^ * K䝡RP9+  9|HZ foq2{xR[ `9I+N.gX7* V8,P@OJcEwaV-R3z,$q-g֛ۦ[-iJ<(:;W=^ Y|Koo co,qɰI< IgWjʹoHmkiV�緙T%_UA;#^=ӼK{TnRK=F/;Kk9G4_)w+d_Ix:LGw , YZĻ}qk596si]1FW6ڛ#^ZH.q%cK=bcP۬1 gSQE�QE�QE�QE�8%~(w_ [ZG}F FWFF>SkϺTGrUTa@0�k@ׇB^L(G劭 �R Lv�]E�y Sۮv!E 7c5*X ( ( ( ( ( ( (?(((((((( mBLIܱ"Bc{/ߦ]E=\3H3 iF"e[9�ЛuP/lU -VSon<XO35P wo5 d*[@?& 5!MKK-g(B<pB=ú?d{?i-[]_Ļ'm` 튖H߾mi`sۗ _n@\CDw\FKU&'ԛcA$HB%>xwKr:Tgٶ="Yiz~aipHHF8�.q-Af� ~W]E< N[HO3鳴+ǐ?k�l<qaA�g[ؓm O¯E�QE�QE�QE�QE�QE�QE�QE�QE�QE�QE�QE�QE�QE�QE�QE�((((((((((((((((((((((((((((((((��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/vignettes/pkgdown.Rmd�����������������������������������������������������������������������0000644�0001762�0000144�00000016170�14671042466�016067� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- title: "Introduction to pkgdown" description: > Learn how to get started with the basics of pkgdown. output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Introduction to pkgdown} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- The goal of pkgdown is to make it easy to make an elegant and useful package website with a minimum of work. You can get a basic website up and running in just a couple of minutes. If you're using GitHub, we recommend setting up pkgdown and GitHub actions to automatically build and publish your site: ```{r, eval = FALSE} # Run this once to publish your site regularly usethis::use_pkgdown_github_pages() ``` If you are not using GitHub, you will have to run `pkgdown::build_site()` manually everytime you want to update the site. ```{r, eval = FALSE} # Run once # Remove docs/ from gitignore to ensure it is checked into git. usethis::use_pkgdown() # Run everytime you want to update your site pkgdown::build_site() ``` While you'll get a decent website without any additional work, if you want a website that really pops, you'll need to read the rest of this vignette. It starts by showing you how to configure pkgdown with a `_pkgdown.yml`. You'll learn about the main components of the site (the home page, reference, articles, and news), and then how to publish and promote your site. ## Metadata You can override pkgdown's defaults with a YAML file called `_pkgdown.yml`[^1]. The most important field is `url`, which gives the final location of the site: [^1]: You can also put it in `pkgdown/_pkgdown.yml` if you want to keep the package root clutter-free, or in `inst/_pkgdown.yml` if you want to make it available when your package is installed. You can also use `.yaml` as the extension if desired. ``` yaml url: https://pkgdown.r-lib.org ``` `url` is used throughout the site to generate absolute urls where they are needed. `url` is also part of what enables auto-links to your help topics or vignettes from sites external to your package, such as from other pkgdown sites or from Quarto websites. See `vignette("linking")` for more. Another important option is `template`, which allows you to control the overall appearance of your site: ``` yaml template: bootstrap: 5 bootswatch: cerulean ``` You can learn more about controlling the appearance of your site in `vignette("customise")`. ## Accessibility pkgdown's defaults work to ensure that your site is accessible to as many people as possible. But there are some accessibilty issues that only a human can solve, so make sure to also read `vignette("accessibility")` to learn about them. ## Home page The contents of the home page are automatically generated from `index.md` or `README.md`. pkgdown tries to put them in order, so it's possible to have a different display on GitHub and pkgdown by providing both files. The homepage also includes a sidebar full of useful links (see `?build_home` for how these are generated and how you can customise them). ## Reference pkgdown creates a function reference in `reference/` that includes one page for each `.Rd` help topic in `man/`. The translation of individual help topics from Rd to HTML is generally straightforward, but there are a couple of things you should bear in mind: - pkgdown does its best to autolink all references to help topics and articles described in `vignette("linking")`. - pkgdown executes all examples, inserting the rendered results in the generated HTML files. By default, pkgdown generates a reference index that is just an alphabetically-ordered list of functions. The index is much more useful with human curation because functions can be grouped and described in categories. To override the default, provide a `reference` field in `_pkgdown.yml`. Each entry in `reference` can take one of three forms: - A title, defined by `title` and optional `desc` (description) fields. - A subtitle, defined by `subtitle` and optional `desc` (description) fields. - A list of topics defined by a `contents` field. ``` yaml reference: - title: "Connecting to Spark" desc: > Functions for installing Spark components and managing connections to Spark contents: - spark_config - spark_connect - spark_disconnect - spark_install - spark_log - title: "Reading and Writing Data" desc: "Functions for reading and writing Spark DataFrames." contents: - starts_with("spark_read") - starts_with("spark_write") - matches("saveload") ``` Note the use of `starts_with()` to select all functions with a common prefix. You can also use `ends_with()` and `matches()`. See complete details in `?build_reference`, including other topic matching helper functions. While iterating on the reference index you might want to run `pkgdown::build_reference_index()`. It just re-builds the index page, making it faster to quickly change `_pkgdown.yml` and see how it affects your site. ## Articles pkgdown will automatically build all vignettes found in `vignettes/`, translating them to HTML files in `articles/`. It is recommended to name your intro article with your package name to generate a "Get Started" page automatically. Due to the way that pkgdown has to integrate R Markdown generated HTML with its own HTML, relatively little control is available over the output format. You can see the details in `?build_articles`. If you want to include an [article](https://r-pkgs.org/website.html#non-vignette-articles) on the website but not in the package (e.g., because it's large), you can use `usethis::use_article()` to set it up. ## News If `NEWS.md` is present, it will be rendered into a single-page changelog based on markdown level headings. pkgdown assumes your `NEWS.md` is formatted using level one headings (`#`) to specify package name and version number, and level two headings (`##`) to provide topical organization for each release. ``` markdown # pkgdown 1.1.0 ## Bug Fixes * Lots of them # pkgdown 1.0.0 * This is the first release of pkgdown. ``` See more suggestions for writing news bullets in the [tidyverse style guide](https://style.tidyverse.org/news.html). See `?build_news` for more customisation options including how to: - Create one page for each major version and related minor versions. - Add release announcements to the news navbar drop-down. ## Publishing If you use GitHub, the easiest way to build and publish your site is via GitHub actions. Using GitHub actions automatically builds and publishes the site every time you make a change. The easiest way to set this up is to run `usethis::use_pkgdown_github_pages()`, and if you need to customize the action, see [README.md r-lib/actions](https://github.com/r-lib/actions/tree/v2-branch/examples#build-pkgdown-site). ## Promoting Once your finalized site is built and published on the web, you should publicize its URL in a few places: 1. The `URL` field of your package `DESCRIPTION`, alongside a link to its source: URL: https://pkgdown.r-lib.org, https://github.com/r-lib/pkgdown (`usethis::use_pkgdown_github_pages()` does this for you.) 2. Your repository description on GitHub. (`usethis::use_pkgdown_github_pages()` does this for you.) 3. On social media (make sure to include `#rstats`). ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/vignettes/shar-pei.jpg����������������������������������������������������������������������0000644�0001762�0000144�00000147171�14634573316�016174� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Exif��MM�*�������������������������b�������j(��������������i�������r�������H������H���������0221����������0100���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������   %%%%%%+++++0000000000  2""22222222222222222222222222222222222222222222222222�� �"����������� ���}�!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz������� ��w�!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz� ��?�((((((((((((([xTrzVT2G�iK(x(rUդ8Əs1<+ eOȫ}W8(~0>EcK{sn%ň'NNk:__-AO*Vr?m'e�R>P~8Aa>ԅ<N;@t +ź$$W}V_] DYq_})޸@}h1OUmNm*: RSҖ ( ( ( ( ( ( ( ( ( ( ( (?((((((((((+:U\rp8<x@4W u>o\OXf^xKC,6|Y1Ҁ; GZ}\eodjmAnI#v z'ke21ˆzż\? Z4 )j}#s.ǍN#P= zWiGMp>*�o MR;'E]F*GzMq鸯~!KXgT F<}@i;ӵ!iѺ#?|kʀ=iptk~3yx�|hSTʛ~R+{[{rBH^0E{}8L�mlctYy3 7"`{bRD"01ާ<׍h!DjZ#N7b'G֏N2ye:z R\0 .眓���v!HrrG䓏ԟjclю�[ lP^6d<J3/̈#;w Cw_GXg|zoЯ#"L dHNB>XxkѼ/[j5H92V @yzts@[{kWd^q(ͬHi//˷r�Q,?*wBMոc03<S̞;�Fs0+<HU|~:z( ( ( ( ( ( ( ( ( ( (?(((((((((=RH7,h8 d8[3K h5c|Ѥ9�aaCxνԋ*1({j�Ķ6.!v=x�z7ӡRj f]d-deOQta8Q-8ʘ8 JoⱏR4K?ۣϱb't) |KLKQf֨j6voKdP2 ~;|8:}+<S}:و|`oy(]]|1"ZvuQێq^|G[7%LG;H1<=̬<?7y*yH;UA:Ҿ<VH e| t?(_oic888lu cO�vݓ�я?CV7V&e#q{ χ^6xF [ {(8\4;WhnW =1WB=á##cf<¾!ú"Z>S 0E{moqIN=2y-ZMw8:cY"GdK#EmS8#鎔N[P�W+|>浶fXC$1O\ +t1|'*9`c]+WL<Քtt{1m4x.?8:B1`WYZ֟ o3c v@ٮY .A\ޥ9.7MHw$H=qq�_ ^ksF2/L+1잀WxS4KYFr(@!O+ꨵ[n$X&}yHǘOq|iHNk^O3c>hS@^>;$+ [Ȳ$U\`%gcEե/e,m0ȹ9z0Gqڣ_ Jc9eѸ/v ǧJH|q9K\^UG?΀=ƳP*zɵKmV?&L208t�u*].gU�Npy۱7>ހ=>'[?�HP<<yч;^v7_m1$MsoЊ8aO :QE�QE�QE�QE�QE�QE�QE�QE�QE�QE(((((((($Wj#<UO :6mX1Vu ZwGm�ġ ^JE�a@�� �xsM~b+#zޗ$v6X>acoʻ_WOf \�{W>3eխA(ܸ?8a �{.cYӮk{MHΌWzJ1$8pG?W\Դ0&3$i2 <Æ Pqڽ"h#q$vQҀ<^ 2ohY]1A)|'ST Qq힟OpkO]s]^ b}XG�760�2K[[eX\P�ToH`Pz?^mo6e%Cu�8 <obbex\~S`z�*! s_޾cĩcDa9>b~ړë,ɜ4�w'�c^f{Y.%ЍYqu4/t-4nOoJ61Z̓h'M?=2)=N1^]e I< �ox]؞ZX9pg^h*]wB0?!]giii<" z.su ٶxK!=�AcQh<?7Q Tgvǽu1| mXOc&d`: .?>ݫ;KXl 0�ou;?j&{{PΈL@C}qӑݱʼn;J00:�{T4 V.,R"1:( _FX*8p?)xr;Z9Xs7L($zzU_:K!,E1c8WRD}#_HT&o� c遁@=94OK.y\.ѓ��tEt?c ߀ȏ+g[oiZ>m;I!!v(ׂIkQj0odx$|@PA#�zSЁڶa|`�W>%n6i$jʹ'fVFI+:9ǧ�tvFo[YY|ܫ�x +M_BռquaJcUn!;w\G"(?ZoSO iҲ[Tg5vOzW'˨xftԡl X.� tN5u+̻]V4 bH wj&b= �QE�QE�QE�QE�QE�QE�QE�QE�QE(((((((?j$<.ˀ"ORO�뢾[A+!FI+gԵG^HK0r0O c8i8�iVz=7Vf%O�Z=onw^3#o~ʼVcE^�Ҁ= W mc_j,E=kuowRy[ !G{ �B杯xbc5;vx BN^kIMC6 CN {b>gxn]sS ۅ^qӊxZź0?U T5XuX:}~da}T{id���nVu碨OĺW3ɜ1׏ĀB5گrM+L-c7!p+ݴ/h[-.��>~5cm"^(~csWZVqVТ/{x4^V�*?ҨxoƖ!ɵ[n7cz.ޘK0I=i$gMb-=+>hq`q}:j�t𯏥K`n^ڱ"b=+<$2 %:NP}LWv{A8vPouo qo#68Ě#-�ofrӤcvܙ\}�_zg4l�B&Ce?J�K|&ėZ٣2P8w u)IT@~4=OmV9}=i+=N= ?9bt֠,h`םi?W47YUFN} >WU}r5򗄾%ͤލ+y &OtzQ4O?�s]iZ|2uP\zt=[Em$L+.ң;~eV2s۰&ѝ÷?)zfxFݐnU=�*�^Ggcyx9?8<`_ӡnv9y$NJ4MV٢R|g[gpx,1|Pfvf1Ͽx꺽xGE\qxAڸjڤe' {{o-� 3K 1C0='<9t4DQ$}1G_=k Z�(�(�(�(�(�(�(�(�(�((((((*Vv]p!v(ɠ;V d=B�xS6s9,OI=9fh#�E1\~<G,A^1c�w[JVQAǧdQ;rp?ib&$ fw`]_dc.9$>-66C¼I[_k:\ۅ2�ŷ@/ɷ_O¼oPa4UK:b@ËcbuK!sMPλo.F˒6Q{wBn-2Ij] \$i6s>ۆ@!�^zPQO֕Y7;Iz mK9U+?xQפ}'ҖX v@ kψ4Cw4d0;c콽: H^jRi^%=R?߳HEn1 dz+<x *�}+6�Q}ۏQ.k٦2=+7MNBIUA:x@݁_S|bb:$Z @q^ObPZ@8e*~<�ЦTĒ?�g0? j+]OSgƷ2]MOC|ykހu5>xXt":[ئdGsz ӎ8ż31:W6cX88kZ*Ávc |TK\'J8^e;K$ShB8tYk,pP?+gGCL!]\0 QPž# ,q* CVoo$:x"K9)(PAqZRj:sʥSpP\8n:zPz:S,C rF11xgm~_x})쳱!NNAtxo*7{gWrAa6 .7=1>�e={W9W"T/<k iL[n�o__ ,K]}B8ERD�潯஁,tm+|soʰ,1.u's;@9tZx~ʕXT woJ�ߢ(�(�(�(�(�(�(�(�(�(((((((�aKnISpR20Zk5ͧ,2-IGR<&gA[^-/X?3 qz9_WiiW,Ooϕq'@9t58n5@R߼q;W t+e3mpu2䞆=:NpߗzׅOgu8sMSºd6L|<~Q$f *~:NM3A SvN3/c{hv[E(b φZeNj<S M?t�Ve+@r�y[۸ry)$ }7s]枰iPC)J+I\O"a~sӚMGTNPP�<Cy}{bVttZ<i"SC~ {z /aڼc%vF+K%E3`ι+O#qPx0+Z џ C_XG?ҾCϩSK[e]yFg?A_JN,7p}h<9�? Kxe n08� ~-eUʣ8KW6$ &8cҀ>,1*�;V% !P2O 7VBhXo_}IyzYcmƍ9&:.-4jH#h|s[}Vcb~wºzٯ մ $6A8^G ÌtWW_`}9ac`J�-{ Τ猌p'~FGڭ R&B7㜃bo$S}OE9QxGĞ !$`�m�W#&o!w,p,ysq<)^|9W%+t�l^mwFƜK b nYOB+2( [׾qn|`߼Vtӡ� [91jwn>خ<d| tRӹta@H<a!0 O\cyA#־\Sy+cAx>�p1�r+Y p.p@;[ʭx*;/-% J" mUHkveMƲ1+($QE�QE�QE�QE�QE�QE�QE�QE�QE�QE((((((F -3QkRX̶̽)`=WF׊367 +8Aku+inን}b>9g)cnS>m=N~U_c<3K rWn :dQ۷j5:9C hEOQAn !KsG NV[87?(?`fb@H;}\�FSq1Zz7q!�|J,�#Hd{vU{ 3"�w?ּ]|urG_q,bYB'\ H4GēuhN'W.IdIrQse3pzڽ_,*<SF_FY1e\q@+5];Og5I$8pv>@�5: ec#3:Ei !qpU\;F1Q*+eb@8|)д]z7w s$ӎ:bH"@008�U;[[]݄p*"(inʬ�+Ml;#k8xQ\ XZ�(E0+$KA8dBhiUfh8<}+%tbR }9鷰�1;pOoT϶jv'gL ?¯"y,==~Џ|~TjW_:Am'[{GxVhgxU#9SȜ͊8jj7_GP՚s;V�g?� @iڽ�U9_O&Ioo>sc�zWԞ=lПFB0Âq4ɣD,`=:E!�w�W6t| {�g}4t�+㏇>%Aɏ~x@tP˅; ?~Ux^"%1+]H�8Qæ{� S*1׷q nڧ#?p`ߏC;( ( ( ( ( ( ( ( ( (?((((((((^<OY6,aDsWZfw=^g%#d(;�A '}@#x-S.[v&Τq$a{ZCԟfL@[Rk:Px�GZvn92?.Yh9#E?@%M37"F0?ϭp su^ å{n?-Hn6 ;!WH"FϨ@?뚀):6 \<*8+G$jY�S[6�Wu-n(3uqT$aNTc%m͝ Ԇ.o0H8-~ifXԯ؟6ſչG�xS g\N7C򩥸H?*:`Ҁ5a_`bSSV#�J+ePOz�ѣ.GkkĎȏQyJŖ�^��vM8axpNq�=]+rdmt�kqd{pj)o!��"2/Wv{vCW&KE?¯;}֗Pػ 1<^01qu�+EZqF2W)}r֟:zc �px_6*Yk/ݠLW@r9;W#A-mp ЩF8s^]XBI^<0#8_[oqիy͔?q@c3x}B7[`_`iAi~3w[KONt)L{ ɶdoW?$w*m ydWa#91}?m/|ᅀA?V9S:r(h�(�(�(�(�(�(�(�(�(�(((((((($ W,U!C-Oݍ~jaP#&8]y4eqt mt#�z FI4+`a=8tJ<a iMӜqךN2 eOO2\FƌmyTYk:rtOo('b\�-x|[c)�ћjN.WX_ǧY>[i󉹑%~F˧}2/I Xtnn^Qqjϧg9G@m>StCЎ=+�!,2gJSYj,.9�>|{۔+ӿ�tǽ�z+( 3ҸMSїw�=+uvYfrgh8PX -=0Suܪ dKDv�+KIY|JW$B?2kOMeZ% �PCW*f*}K}=?Z>#l mG9=w7`1WEa:vK 3NqU}:HCYH ~�:Wʞ<=l[Od7RpA}=ׯx;zcԵ-+ +%^B8+#$dqӒG`*=GLN?|L=#ϯP+Ѯ~I�m\c�"e~`~qے_n} sm:<-h?|mvAGqrprxv vє@};~:t7qv z{(o۶[́#OJ>1k:(1�~lc`~xN+smN�LOb' UXFx c�}4%�֮ 7&�PnD2,!GɃJձ_Hq=TzW#�C<Zy7 2c?x}@E5]C):S�(�(�(�(�(�(�(�(�(((((((((Ia&Kor 2HJ2GBG`xnk+wfRڽNxg[6 AQ@cg%WK*W໥o[ ~2uaAܸ<ǖs;O�vxɨ~ ?3˅,b;ˣ\F[`ۜUjJ %(,:tvGlA )?\gW;tD#h`ω~&l ]#S ?/ ~0~]."GOҼ*m,ԑRקֽ"!7>?l 8 ?xcwliy ~?{V'dymH9;zW}"@uMJ!<`Tgj�</ڰ>ѻGUcrU?ӥj}A nVXxSҾ[? hZlvV)?A-I9|-P#ҙ-6B8LgweXO�rSux,]Ta ~Eֱ_΢^/1uڼG+I G sB'ӁXGo#"H61�j�謝gځr'9|1m�wHdep厂� ":@~PЭ7t<7ȳ濺h~hytXo/ͳjL]̒2^yKOv8Hh^D{�ƀ1Sv= $!;p==tstȥm=+׿5/v*Iyh-~@>Z<Vfh#8n܍~zdRD2/on{T?_#gGg%ʔ,r ZɣW>$n[=1€=?J~Ϭ*9g x5 �Fh2:6NAZ.Ce]85K(r=-ڛ~ҷ&8޿('ڠdeZNݤ\Nc8>*i.y?/ GO$رFR;cJ� _oVdp: `8#Wg^kmxq$0w)un ?(O JK"aڀ,E�QE�QE�QE�QE�QE�QE�QE�QE((((((((np =3H+GQ ?4e"=#_i'aP1_*;JjSbyj[yk#8BlRAs4~a`?zM` ܃c�Hg9�jxqdO7�[SE<m,O,aHڒ0P@㢌=+-$$ca'(9/EsLnFq@|dP|C"2ڤ',G©@[= 8I1]Əi[V9<׋OM;:1z�t/.vz=Вᗿ]>+*EFrT{$csHnp0J�:- c�o+i^46n3cF?t61h r}h4?!W|J}FX}ܚ&<X7*8 Ct詣0#Ӄ^Sf� �Ox+hr"NB+uDR:qڽ/]p|A듓\\fvoz€5-WT嵱gG#O&Lo\'/]𾘚B8F2'8_jkh~ĿtlIc{]v$Y #cBR>PuR TA%T#O]ڭĊx+L}p�=*kȂhԣgϮ;PO ^7\%|]iP}m bR2�?>�Aysf)yllk�Vnjִ$f <G-Tt/ B +*n\>z=/đi-渳pw}@t+Ԯt rhZ1ڦ?y8Nt>(~nS5�zuH/!ʰ#+z&Ld%\z :jt/͡lc7=c?. H=q�q ,.@̫)? Glr `,<%VCOƻַI0yg F=PD _ /CbG@h^NZUU8R#d'6rGԌBVZBN所icprmq\D-=YFC}<Dn +J,͓ QU."Y#GCV(�(�(�(�(�(�(�(�((((((((( ,'z 8?-18<z]֯q;6~ '8\B`݃�-\)̎?w-&LJ䌼myh>Z: ~1\E 9gVڭ 'gAs:Yy`Q;�n< ^+0}#뷑<qD3 ϓkt o6:aTdWϑxKs1vl`yjP'v[xcӁ�7RF ƿ.M1zw?z% wrFxSplPg}syl,Rym;('v~[F𦁣GSN%l \!ss qtUoNC/+uM<$S씮K@2@� xgE�Ken-QOZ&Ůʛ"PH8;:gҰ#^Х޻Lu]~B1KI>V7I6d?L �|EaIj2F=Eo4h5YG:);qN?V< F8lv^gjtvɽx =v r]J~^^c`cϱu& ۠6֯L=գ.VMX|;pW[it$QLJF|b#^Ak!}N�'~#vk1BIC+Mop#=@ej1kFt{7QqˢiasubBўrW޼i(PGn:g+G8ebQ\''61ڀ=EL 1X� 5\Y|,ycqKYn&TW`pzz+AYwFs%^m-'HKFd)RiP%LEJN,1�֪jZ\]tt\2ٵ�X*~\}@[Ϗ2ٙBJx6B[a6%znc}}:vyawqFq'{:)~A*ʼnԾf1u*�X>٤yt ERz}:jWmu,j86O]?m D TKpXr{�w{v@$+208ux G\+; a麍�6仍]зH7Õ`p}swԵ!E>\qft $vg+KPsA$#v"@V�ʌ9pܬ_2@>w+& adQp@׏SXwX.ugL@&Vt{:�  ( ( ( ( ( ( ( (?(((((((*mlEP IFعez?Q[aXfi7?etTL@W /Dj1v<޴;-F(KiyA}4v]v\W7zq6y㟗i d^>;{c;vyێq\r[Cw,S$1etu0j�̹۱&Px\8лRY:m_+VJɅ@Qc�U<Pow4Q,S{:)S�)u YN£\ ,:"W>-R3x,zqqx/ty,H3O(2Ga@O7+|]9(cGl~UkH8ںg^&O2K4.;Ap:touFHu@߆7e{݇�lAƍV%Xǩ<*QM@_%h@ߠ8Ϳ[�,+t=^58*qRzEд_Fyxi|`qJu=ĭb/lP{Oҳun'eԯX` �/^rz�8~X30<`qv{g#j(v2_{V*«A3/9~?SYԀTF[W?g @u�XI3ya8Ќ}93+)9@o$ӏJ�-S7`ػ_"<pFzcbB,!}b�IGV�{}GH%dޱϮ:� Ë{ 85n\p8Ri~׮]%U#wV2iAtG.Nj(Rwp;r>YALWW,O]8{{?Jw;c<P >1&V>O-6(<,-QymF43st [ŴVy�ryb~? iOMO2HGw{3W񖑤XH2%~O~=ּ&5?<u 6,S"$m_h~J�+ӌF̥\m;qqr:21\Vn6's#j}8QO8P/7-ª*̒9V\pY?L}}F2,:O v�vHM$1 M/g^V$c+ۥs^-O`D,nc(1eu#�!J;xm=h>ұXN8 {P8C}[�tW) :D[/#9_\ jpDm;Gt �(�(�(�(�(�(�(�((((((( e#/}+w k4};o@:t]:tGAf"zij\fPI+E9CuP+Fbo�17Ams|UPd_ܯoj[ksihfQ0v d z_3^뵛_2US ~nhx,g3Αou {r @vF Hʎ� # Sm݀y<8w>j6F6ʩ(ld6s^Ei?u ?S,  �}fmX/-$f_2 Ӕm@_qZ:W7gnaQ|j^R'z&u㏥t?Y/6J94!q�}'>WkZ>=֕ mU7RN=r ֶ# �dq6G0�^?�דR4u*;0Azxg#yPXm Qi:q@X}OJi5yơvKS ,(ӡ$Bzt1e ~>Yi}IϹq[Gm�-ޝ*}KSj E /Um <|.�[ �odO͌y>iɹ a폗�:(22Ƚ= c߭jţڬf=6bFV\hl0r88 ĭj{_k2vlʲG``[5#Շlkf|jɐmƀ99mvn:cI1Ȭ˫m {WXZiP?( vR[*]B: g#/\vǡ@FȏOǭuZ4֣8n8,UL �]Co3s 8'txPi]#vwa8(?P5/̑!X#)^+WDZ/5D*v-dNI.x�JƳL@:I+#.̈w$<> �XBf矘t"*20ܲʎVDrTH~#5c0LZR0�o[J֬MBPجirڻK TDQG0%x{H}Iv$00fU� �nO}2slpTx\Ɍ t*[CrYm*>k!-}Һ[e!lRx(T{?#Ͻ\KIn$zXa\;GEzOȬO)Lsʶ@ojl_1xI˙Nl:Eս473Ԧ@ p+?k 2G?9^Gc((�(�(�(�(�(�(�((((((((|CfLЁw+j=(4f+Vg`d9?96⽆i~W>+珌ZnnQGsQ| \4?|W (,_VS�gE8c8tfټdzl<Hn৶qһ"rp8mFalpj�i3L+2ۜ2ɱWیaZ%&r#&չ%K`%prpz."hee?sמ0a2Xd$,.H< w|'c@rvp;O»Ł7Es:ʲ IK8=Er{˷HPyV8R/i 0sקf'W͊ɿ瞣eƝ߇+03Q|GL+Լ%k Yor6_=1P;|sFZI8:8;W)gtlh}֌Ax!B᳸z$9Ұ' Nr1}O_L ?KV(?4W3zHn9kUS>WSCuw"(C{YNd:w_PUuMv{q W$TR?Qɬ{Xoј`V?`3@ q)JjhbOڀ+dk^O�v&<Lpq^}4^R/Xg'?>aNvx`Oºm \1Hې^8?u:Vcvq֦4p.@U{s )i6Y�?t_ |뎞RIg mܬb ?F#pp1oc{3e 5 H,<7K)1+}Xc u)]{I;w: <;u{՗Ϙze=1ڰSwt"B,Fv$c끎tKH<`>H {n 97 Kt1kl-afn7a|/l Wqmi; 1ZX# F {+׼CkeoAn>]̻GW`$z� q"I.ʆ5f!F6=3Mv~$QG%P|W:)<Q=C_Xl`#GkCʭ)@ n<q@t- ̨I$!#fۖUn8R:V'ۨ#vǔ  \42{hkw\u�z%~UL $cr�rc._ 'ץbRe#Fv�zQ@Q@Q@Q@Q@Q@Q@Q@((((((() R㎾^KR۶ʥWxn?<gX]ON?yq"(y徊U]ct( ?rP6T@#MkWz<HY;x=z`P향潫C?hS[Fw۳W˨ږ2|yf$r1Xgiޕ~~YFwۼs@v٘{XwJ>tJ7򧶸X4r�?MzؔzGaZ=$WrBn>\L$2!Fm$dH2A'^MZnT,{0q{`=1Ӿ)`#b SÎ xap qTtF�{^,BXiKk2pG#j iAlgkj8tg 7߯\ס]+!0\.q{�}SVZCD+`@=8 W4pykm8#ھ♙at<g^y葝�=Ν$ -kI=1�U,Jy>^ͪjdYPbIv/H>PxF1`SU`=*Vh xZV g!˅=8_�WU]뀉&*ۜۥtpXNЌ&xO20B9ȖҀ<v#nGcW|<4W5J 6x g�+iȫِn0@Cucy;=;2=;tk,P? +Fė3�zq�?k6,gPY{j`T~� zs)KU3V5A8'׿jC/DcwUM|kgdi$ĢǓr~{fU8U1>i'#W{g] TU }wzWEn.bJ,y cWޮ$2#. uݲ<M09$�Ď:]_PM= UƧx}5߈$&'q^GSz�8RzavP oU^|On{OJj{h�+>@Lc(Hq8r{Nmca }8m3N]2_Cm!B@I&9�u@q#G908ӟ€-kگ(HXрU8A:׮|3AGv<+gq�=<!JM%\6UQ-Rȥ((((((((((((((()51 W'*1i&|cv׶nK2c__l#ѢS"yxx?O@Fe8#J$\ϧA57:ށ|$nT w!A'Lz]>'rH09 #޳O T?!9qP<+J11?sɯO5H/3p_F_׉k>{8q[,ax^U(e?#n Tq_mO:d9\9k|CêY"A|n;WCX`G_zBe]g۔k\ylF.>!V}*gM TW?+ާ'T˹rqN^ska'h gb =Zƺӯ7(boHH�SZ])x'Esz`="=;[eD iq�*捅1ᶀ<QӄYHUbp'<|͒=803^_}<,UI$^C@ϲZ>Dmmjd\#-@+;PP@̚@f@E@Iomw/ c}�Xi.QqH-wz~jSy}*̣0Se0QԊ�.b6=^NJN.,g`{Dh_RVC ~`�{Vׄ|UqT\1ۏ?@IGO1�my>H#ҴmUOlfAS0Q:JAl5VMu C4d2=0J6;of[BH>uBudCTJpTBn'}!k*fGL*ׁX�IǨGi̓-RALUC^?o9ZB\}am:+J�HEQ+~i;*/9WMAY:_wI>د<:^+�{s=9VvMā!#1G;q?<Px"1Y} &dj�ʻUG/L O^ƸWD&S: *[IPjAU8@}zqץwZ/Faӧa8 vFoz�nd �v{"۵z_e\.@ n ]{5}(NL}i�C~uꖚLD#Њ�4Kf&p&qB1cys!9;(�FڐC8?ʼ͍O2#twzN~Z~oLʩj=F=<6O<oj f{|FL�w8vѵ ')w:G(T){vѭL`_+Vq�QE�QE�QE�QE�QE�QE�QE(((((((kVf؊9=*կ7ـ2^�Xڹ28C=p{Pv3G<�7MӾyٗLbN3E_12˿zҹ{߉V6W݅ pG�gku)b)dcx9נys_.�Ekя}"=Ϩ8U_N.NO� #+RN?қlXO1Ћr PFnqIGڼdɉ$G'@Fpҵ&${+iaq𒲿5M1=S-Yf2m�[Ҁ<mH[2&FuY b c� ͺ#^Gpؐqߍqq>skU8#i-WPGM61]A,DKIګ} 9>ur'vAZWn=>+cښY$"]6Ic2�z6<;&|y~c/*0�=+{?!7S)p\I^:?u"m]Dp%L'VښĀf;DiϠ*�4oj,u AZk|,B�@=kirLLccffU^>f=E.Y .O%ѹ�X"1i̖n˔E,�0Pr@1Óڹ(XDoV2F?qm$~X*�q8^OsQ\\1,C�l�J�u}OByN)^C|j;K{׎jZޯu3wxKC\'p�Jز1~P)9Q?AAq"> 3zjK3Nw9? ' s*ђ8<i a݋,|wHzs(ġH!r=q}ݫ=񘈢]<*뷯SDm⾙ZeǕs3w !PDqGsX/nM p(J�/AmRcZ}߷v8@۞+SQooNJ1/R3^Z\l|,a0OX /P0 +v�(<:q d Rmq65Y#aulŽ^k4"fΌLw1l -!fyIN ."@]x9c zP%xi]ܭL/`>_EP>\wVf^?qՆ켿4L? +-xWKq ر8lP-m#bL{)`-4jzyd~$CoY!fBWz&sHM}||ʰ|?Z�|Wխ0-`-ݾb?gT:Cd9{G< @^06)1@6hN1 �?�?xUrpN�ȁVkL1jna"='eY`F:V{xݟdm< >lo`g#81ggEp5q@ EPEPEPEPEPEPEP(((((((>%߇俷mثs_jzt,# *?(;zgRBxWӁ\S-ԡm 8 8P0�NOw~𦣬 5II;m?ŷ޴i%~z8?u[Kkf@ @=�.?y4HGݎz{zt25%#J Ҁ>F7֗(ﮀNL_ x(@e9ex[a]Оkˮ߱Jn-xY[*1<~z�6XoW.@r1=;UdK;, 0&�>)4>T>"{c .Y]BPq@`?�a>YF6gO$cȯ<Լ C[7G|yt�0�=nI6KX}*(SҀ>W|amx9Ys>&1]8Q~kWkXGpFcGCVe׃࿐5QCgE B:\_R%s}hд 9\1$$k"Em*Ӷl/N;ݩS3ɾ@ªG&<רg#t8=vM)1c' F8ݐE{L2H\l~�qZpРbyqBt ώ{p*>ɼ7=Ω*1!<ˈѭ## c{+Ū,&56�*�f`7ξe?Z�K_ h7n63�0@P>}8Uo#gm.xQ̮n#Ó^ #V\�+8{j=N IO}=z}hq H�Dʣ,solYٶ^"9*opw1]0I� ;J6)csް5{Ew.p*8O3upFX�&7B2Gcq�lj՝WxZ|i6J1;cg׵pz~=ێ6@O��8 =_�$N;ܢ(=@IiHĤ۠o[x~l},nrUU=>PI~t0M&ܲpA펕 ܔH#%xUϾ?J`iG}v-t㢶k3C&zL7fkt"7 [HE0<kۆǶ ª@V>c)SΏ3*Y<:{{WуOL0Y##�VŰ4f(V7;# hJN{ ߗ ʭE9!M}xkL`huUq�?|><Y\p dr;q�zQ%`{* ׯ_KƂ8E�~U<Sau->/ݾYEܸj RxRheu Ab%(�(�(�(�(�(�((((((((TtHt ]EJقkvu[Xf\<@ # }P9gLyV!9Q+]uF)?*/d+u褷kgV\|v 돭zZ5 ; ��yKc#ނ<k0*aªX,qu۟VRx Xm^TYnxaWxÚ4)B&؁,6zs_Nʁz]ՇH�,�RW.|4&>a}jo|CP#*ƒcz;TΙy־do3]rH+)hݢ0t >^;t|'"\ѥ"9帊ܦyq#8KY4I_FJW+0#?ZsSoF,C; 8�}ecQ$�e[@,v@p�<aSGU^;p1*^N}!�5|NPuE`c-]]<ؠRfWN&;u++z'\(?�tU<WH#c GNGPa&wIcy$=(B 1~S* 29yY3W_ML!7?:nWzVĶ\@y͵d"2>`:2`_1J6 0ÏW9}/O˿cm7Fx|K2#W@ĀG#ڨ ޣ+(v1ěQǣ;3&VTeyoYI <A߈n-:̓I$pۜF1մi]E\ t�f<IH 2^�=0?» xnvln'wur`rEotrޕe8%y��GAֽ8ˍц6ʸc/]') ~�p>[ZB g#<g4Z,4hi1}8L]kjMiVKI&8!}yzP萬PVXQs�7I{žYg=}:}=+4ϱX74<=~Um�ztp~CQn<LK"`S�`O).;.*ugql}XVH㪞1H8Vo<jw�w;zWk>(;!+@DnG'cO^�4֭t%ŤתC鷡Obq_CxwW:LZ"Qe_Jz1J9o�'=@=Vmb&H($8`[J�rTH{HF+JW@+"c(ԥlN}�Xn+4vPy-ı66+uҀ7�(�(�(�(�(�((((((([ZD'8\ƿӥM3M{򱍤FL?*u7KP(<-7o~ߐ9w%F�=y1ӥ{7zf}y� 'ZmE 5 w?J)%5ʒFrlA=n=Q.0GEֵc/33H\{p?Y\ 1 m47kx䑝�З+^ljH~NofPX(d86@Nrw ~}o{�,9G;^-}omYRda٢v _Xy[!ed9a؎$ejYWX\r :rj+rnC eV6sWo<1j(Viڿr ;!m[=�p>"TČ H7nq\. qYPt&K]nt #;@{l oM)l:;;|p;W~E8V|""vn{CG rx z0'լŅȖc qxҦ 'ȯtXX%8EXn 1"-Z,!&IݙV6{ uFkT( #Z'^kJ�tx_V[b8 { m]�s\7;ՙ;s!^iIn.<j3100\gy\$`NO־}46<٧EA#qIubYnB,Ǵ0��TZ? RAlE@=Oa Wf0HH�׭b茱dmɞ0 ;4[~gX@ ?;o-$ٻ ªIIi�6ppt(ѥQ B~n}9'tSJ_!]q�<PԚ!Vcs8o>]OOľ-<7l'7)R:dW (--,,R`@WrY4L|cy|JmhWRkZ~x9b8 {tW?%$ż!�Z-B[ UѭDP�WvlqMfga?mƼ&jn'&(�+:ɪ71@=)GBTU%,e’1zPp|Tm+~? W~܀.1saxQo'ּR.f4`;#Ҁ<TԼeg!;m"`p?W#ۏڻ? �Iwa}w1� \&x@M6\cnںc/٢V$A*L4^B Hw x>^㱿y uQ6 Nm633Jif |EV8M69:EYOc@֗S?Ĝt#WRzWNwHe^x8ܞЏʺPKvvr(((((((((((5V=.NK)d`w+nUvqU�F!z�!`}b༓]I 5O2,J\^3ǢV;G#j(T"<KWQiMmC|ܕS#�W !@4ǃ=j@g& E�?vNשXkW:F[;�Nq@#"1D1SŢh1[ǹoOdNPB8�NqW#cX=?ˏׁ@1$(5 =2kt# /CWRY68(,&Y#9$w1Wj<Uw[S a`Fɗdv#jMEuYҵA]J0TF#@ DuţF2;?U-ƟyOgp'82s1]om#eY  zgo*O"Ks!o1Q3ʨ PxOvZ-p[!=faWX1Ϧ{T9dn"=W?cw؎?Jmx 1ZmQ͖s#6eI<ck]�0Bܹ`? hn^wF(Mt'⽛:AՌ \ >3 O ??J shɞ>PC9n kZpB4qD0.o$?kXkM=4=5w^0s(^#L¯\pNxl�.̘8rOHӧ$rZ ٭mqP8T2v @_i8NlտN $YAqVnG!"d2|/(|Yn$̇ #ӠǶ+ﴐK+v _Ykz|qUA'v~m̶28ʚBé@2�<z/j�?y[dHTc?w#fGKXV"죵Lmm\rrF8ßj�tK1]I#2|1 `A i y[t s^AYGe2munN_jJt4�dJTc/nY|B6.G]#481 u=r;f<Ru�3O#@\%ϔUR1n:w}y:c#iQxۦP^&ѼGyc+y_;NҽqNeYʹ�Vɕʯ �Wj~&Q?\d;T: �%Ii2Q@*O@ݒ=*uDu%_M5Z\imndSL ]X.Ryb'А[*[YI/GZC=߃ڀ:]ڶ1LFX:-i3$x9U!G,`g+5tl�<z:ÚFg$6[($|l �[+Yee]z0uOUK Ʈ"w(uRE㍯ (�(�(�(�(((((((y]ޮyn)@-]}b5'=ϵq mu"2%vCA㞤hl�aXzHU, %pǸP>oŨ*X"q�|IH/,mw+tf�29!#vMcZXKYۄ>�OqQCm-V(Zpv:q^kimvvc�Q۠ V# u!~rGlVȃ>ֹI<cbX$��?P/!DdtNP{Epgr9>¶-u<E#gSϧ@t^<xK�n< lQ^$<ӊ/6YryVCH=1@'r6eK N{wSc|/4۩ (IHؼOcZQKK'U&;!А8WZm;CM?eiUr"~ߐt'�g�YQVxy02I<N+Olm̸=^y'f~6Ù{nƤ][Oc<N&ڢ6L0hLj<QrJř-ʞѾMpV$yզCT�gAi>:�e� s:d%fOI �:m2*-$ݸzfͦR)dr~ˡ>\–M 0?P+/->[:lc?@s@C:s2HF'2� cئWݣ|9?3�w^; �jڻźm(.?@_GcxQco+>_qh~%܂{R(G eԁ^m9),cjǧ|~�/sh<'Ϩ/乱H.Y5q#j�bB ԂW<`�W~,]N"Idn8} {~I n^`\}b?#�#k?T3ͼۼK?2.r�p!Y }1;WٞE펠<�WrxE6܂7r av-4\ rz �׸9-#m'm! ?a\mZG܈ylݲܿ酯@�2f鐬8V`�'� Ǹu솂u= R19jx<5'Gb3GT$z9GyVkySvq=;v=۾oҘfeP\q��L,Hp<a{t8fVt6@v8;&|<߈]e_+n޾z-M5dr l08럠閹k)8iFqv:W�nm''#N�p9  yɯ"X'fE޳ `ҥU1@,Ig=PWuy'J v-pU�g]<};ռDQ〣rB$U gLY۾ﺎxcEqƊ6(Œ#xZ11; E"w!dc==IF?oF^E_q@;^&Xjd+0rTOLc+dv:tC|v3p I�R((((((((()ʈ] 2~<X7~$=ġb9e(:\]ghP6 :WKj78[{yN񟻼E?>ձ|V8�/=\m-m eYr v|>4-X}kkK+[Q9RGK t9L#rsқi~*V8D+:9cڮxK,Gng*rT6@Ab״Gcjkp@�>8/<+?s}k{ ?{3qpn4sf^H=vH|[v\æ[7�@ihz.JP`u0yV ||ul]Ŏqm8@" 8:~vڞ"yO�axG{b9eW>=>Lf''a`�Q_i\:J=I�y]A=;:fK9$"Pl}G<&{e'n:Ll9^V3~'U Vv =Eu: Ρ]!@x|PxS25ź\݆ʎW>gˆti Wۏ+4]J,xKn<}�Weujd6N�JC452[]iэKy0?&AQA:YKzOќ wKB"+#0WAWi2)T|r>tYPx&CQ]ke`70J'󇃯fЊ0VX~9Qǽ}3ʚ6i.0 Fr7Aoj�U.-ٍM"<R.G@=+Ѽ5o?YrA,ytR=;ja$*{c5ao6!GH?(p:G%.Ig8>Y隡&2Hj;-8W 8d_5.J~S#:w�n]Ω͏\s}hgRF$w<{q?tMj !#'tJRB$"AFlKk p*,ip(-vv=I.uGQ�[Z2zه?{Sns�#g�߀,QlW}9Q>&!Q<i=aB�zV:m 7) GLkߧއuuiW+^U~B/(�,t1�wڀ8_9 ;[bXt߈OޤͻLntO,7Oh [tL*ud|%Lm,Frqۦ1@,MIj%< ipxW^}Df@%եA#1m#3;Dԧmi,AU߷8}ωu<1 ̲ц8T'Pو-2JDASS@UMh'j4�\"]\p;$Gq#uQ|8|n30C1#whu/+vV;ˌe9ދQm򛀛:F?u<D>yk'oJo x^lB0<ax ǣڀ9r\q⋅ķ` #T^n_ٝ'P6P~cys;t]�QE�QE�QE�QE�(((((N& )GOں]Vt:k`Z-zW).|ߩ.Iepџ�PҾM1׮_77hx UprMwlTkHe)ҴxkUc\:|LA}"A۾;v2zrH([F�m`6@\nD�c&8C#Jq޹Lo\ۜ~a??IN$I#*?^ dzq#ؼUGk$..">T%X v6>Oz?P"~Wi[=vxi&`ynO r6u8e۵s мCXMiNyB=SFDŽ8-2U>库t{q~7~2GA �\u(<dyC.+(~-C 6T_q_�Wiv<@::�3nߥx ?-XFy�&!ŬyqדϯZ�&1<yN5=17#=Gt= 4H18P}MksNo�rAu�i{e"g2XL~q2%}ډ8}+C6[8G>j/`&~�W+쐩6y{g۟˥�z֑K*<UtR2;t mѬyJ 7_/sW =kbH,D;dgn+ZX;;c\n܃ 2p�x�zfAUG\6!ygP8�l^y.&‡?6Z&s|ux/#z*`9EqnX8m="zr}?e\C'nԀÂyWў"|%#]HP* |)%jp0u,jt۹V4n~|Cu5\ZD^.YsԎ kE,6AZ&[q,S߁֥!shh2nH9du9sҺO0)#>q1G fe'v2G(*bv=1?<gkm,�灎#;. 81[['3nF~~2Gw$Mq U>d>f'9�s^c֬M,n1w0{W۾nj�g�Q󋢟hj>;ĸhbN+뻻ăd@g�Tu?}QPm^:bB6 ! \ޭLm~p:�z51eߊf#`{㷯+ jeEM= tXPh0ϦjP;=z_)7[;Eo1uHʎcH�b!~;~(SVc?_u9 |Ա 8[NzbF$$@8GOzqweHRp/]�@5jzm opLF> ({WU'}ambS O#+ouB+D.�'zv X" H9F{:@/=yC�U>8kiJT؈۵OV r1ӎM\ *͒p�>Q? 8|Fx�\�Ƕ �xU� CNO=G+tw>\h˓vTc+ #:{F11`Wwz<?t'8,A'm'ȠrXYae*rӊz�&Ǘ\3s8��QE�QE�QE�QE(((w}gbKR%< |Cmdsqrvc *pNQ\c]kl[*+PwSS @PI`CiW|H죾ϙG ~^kɧilZc:-j×:#VJOJt? ^XkSTii5y#;c }Ћڻkh$m5060ہ^m]:, x:i&5߮c?0Gx>P{0+ϼG+}nKev,_CۊZ 1|p<~U_\j~WKR,HN=w;POmxz}*]]�xg?'8+;x{:O4RK{>}Ϙ |? v9Fr:WSNF]F<lK _ֳ/ڵj(iq=geG}|N0Lw׃ u/lw*Bst:戮c2*ߎ/ ?(Z?#�A? "xc(\gwV%~yH&ط̓#n=G�ZȲ�A{u&W]-N�15_| _7Kԛ ?]rL\,`8p@[_i7J~`< ÷A"<Ntq剭^, :x� ɷ.Ƭ)}-ig\?S}x<rp7/Ё*�ڧg$Bqg'^1]N�R0Sfܧ=NTXKR{`g۞�dN@1j_4[#p#;VeC%2Dx1;w\5 -^dݰ1@Q.q;GljbO){Ivg�;+Ot|h C>BR&�p-q[ZiyS}Ȥ!&�rF{my\ / H@8QqS^[Π<v6mV+/#wgjr[fpg59ȿƒS۵�wn̪Qln8<FV 1h dYגbI0rOZӨ/پΉ vtT2\!G8�zljPE,$.s܀YZ_qb3k`\cCˉ0N6[?EDc zP|+<VFCyWocpuk.r̼ A�ڟP zW ;d�t[[kۗ]H_\u@KiMֿyCI~?:4>ddAJ/5xmT#h�\b SD}PZ}kƩ…@0=*َ6]LW|M>NU^)G޸P=�Q@{xv?*E=5?ҸCl�^я~Y\$|qqco] I׊�~[ =.W#5[ox;H7` KQk){+߭<ka2vC)i'vtba/\qxnD pXz-{'nѐvWKOfOm՜E'E<� �`{cë-`}lh D2`$y@$:Lqͳc)WDhY�a|Omo-R8t[/}O�Z~ O' #QtFxA~+TSW\>qn>6i/{{k~ RA.Q 3x2i=͵pBG̹a}+5:1c!)6{p=~<)4G(OTwdhB=QkEPEPEPEP((|Cb$D3m ;|H{�X+zQxUoIvH ;|L�:ԩ%^OT?A�?k[w7=suA>;H][ű견VvMp¥#wn|o5|7FEPq�Hݶma߯oz7ۖt9{�+>"ϳ×7_ʃkC@aہ@^Mi.ogK61;b.sjO+A45 @F?߆+nc�@|FKvkQo}�%j4Ϟ̙,91Os) Av//"S4fTzpH*>zvG Bc+uߵ"M2 d5Gi7yF#jw`{jl+swǧoZ�e"mHr��.=3+c᷆|A9/eI_ IBz{f!!CF9�k52-;Ec%X[Wm|? Pշ| H 8^X$߽`?l< \!+{WظU׿mW/OI,_\*i\C'KC4ybie=f.n6#>iHC9Ÿʹi<' Ghڔߛ'ɐ2Yź't`e}~uܸhGl.t»|�fEGڢ~jKhmVޓ?BאX#݂}} lVoAGӁ�xR@֬坯c3>V]#Р2#)�m}R,bv6C@<P,5'yo*~ѷ8PaCkyu>V=cn;W1]KmoR찴*R0Nϗ9?²5bmvx7?|;%͸` : sPҚό/Ak*o$lM&;Ok?ԯ2PF̳.? <)[&8lT1D<oON:⽳SVmlђt}hGVulJ1 `SLs^]A_oMvbln[Ku+{K$g@g؃xf;�8^ |okV6txR {e#ЎVݭom�J9?@?yOk0BVe<lҽ}m�C%a 7*x|`$_&z€>1^9Ƕ16Kߥ}_kjL(S5(xL׋iW:d $aP:7ˏj0HFp=*FH(#qo€=r[Ej&R4|߇JmQY�tZ/Qz5ѭokm[[|if?uzt?@ ~ <]r8P'� V=׆t Z{٘Dob} 4g_UX].% !R1H<�+51>iF+ZxGw~OGY+Go*ǵqM.g~EEO�_\P~^- Ш?9? xgٵ]"+Qy?GJm?GQuhK�u�V^ MGU#0IҀ,j? tV??CͱM|s^9;>?h9�C^i?<WWDS^ mV.�ki=vɷ4:ƥ6q}{)*<�=u6:rmm,䟻.i4ŰROČfx<EX Odd$w�{y/!o>8jђ!+kM{{L(vO�6bQ,p!#<_J�x iiK+eF1끂�>U-vd@p9S^5|8xowpdt?nwAn9ӟ�rV^6.cSjdҶȤcFd `»Am:]*UԖ&m1 Cp^%͡gV N309RNrn{=<7^]>-FM$~�Bz�(�(�(�()ʽhv,4O'򹯞|# 3T_;]ٰ8m ^sޟAbNѴyMO[9KvLmI!3Ҁ=76V-fWK{vYK{o=*!7Hl!Y637a {%p[:u9_ hmN@t7`el˶OJ/d mn8@pZKjcA�} @? ZL.;vWxsP3ɸM #Zw$gS2X&ぽv1O>xn,Z|b+$r.Tv,瀵쫴9�9|!id ɣ7sdY텵۴HrDS|@o`7�~$i6}I81^6y` %b~3N\x !w R�ǽPoK*ܻȪ'ǡP$iUv6[881:׎$?棫{yݾqkVz;$�rOOO~5KOh>fXaA՝,{(|kC7>/'?iJ)x*;7?^>!̭J�cֹ<V'`~>߆(Z 3IڀfA[˥[9*>�3_<Tt4Vrzu=髨%eNq �5+HѮl5d\`qY\)YxtˏaQ+,ld8:g<q_:x[ R-Z -Fz{p(G~ %7ELJ7F}b'm4%֛s(NJqUI�fod i;P|;{Wm{IJq&Ҥl% R:ڼ. &D+>{ o`;•9g@xp:&ZJO":ɂW$PƣƼz+VjslI*wUڸ˒ޟ; �j7)K%^Pq/?@u�֨1FR,NϣsL Zm-dZBwoA?Y]2/h\mu 9*{mcGN�[a5Gp]Ol?�E? ^:H״>]uHM[adB߇o· 91fR�|ןZkh$\(�PKc4/ޡbܱJdsªd>bS~|4bL>f3?\h~ ylv4jH0crkϵJPK]6vs7Jpg@�זVa#�a5YE{� T'1NGU4۶Fa_⡊%X/B` q;bqZ<*nNN?š ~nct2y 8񌐢E1wЎN��m#+ ~@a01Gv+o ɦh^ .?&5w;WM$1<=+ گt8Mo-Q!zAצ8ϩ`(ҥcd&Ԍv9O?qrxoA{y&|Y8 ud /)ݸ?v4Ϡ!}6ݮ*��_M3\`Ǧ[=O֢[ZV=-Q8kE�P=w| c~ͣ|zxW;;Jnh�a7t7۱+aXe}=>mKPfo*VB[q`Of{$l:)=iSvWgKe2/.%@@k, �>͖o[-m*8?Z�xtz:W2AJG?J5o:.u K ɌO@짦>�mON:U\A^pߘ>8մ J+Ixw?²\G񾁮_"ƑF#p�r8y^=#J,#pZ3<qEx72֢iku< {4_t˫GĶ*۵9X�]s_kk77m)HO`55/qp/c:mtvpr=+|_y~GNr '⏇ U-5MJWoA8M/|= V:Z>d 0X}>ub7]p?BsZK[=3 !u\�֤f^SfXWI,E1h]FT`28 58mzc__ݽr,M\2c�VN=SöH6!bt*.EЁ@Q@Q@Q@(ljSi.Cm�~F S^w_+/r�Wp?2{qF \CS�-w;([MD֤E4ƈJ:P{{WxViSSqWU?D3 Ew$]}jeեqH^2؀x/9eݺ\G(`>b1_ a;߁%n]5T^D`)'<9/`t|eҶ18ܬ=UF_-Fe>rF> j[ボ~lW %ˍ{WRbG>ApߕSm7Oܞ?@^K`z],ؼi=2`/W)aqbFj|ddY%>8'8N+d.<Qs}Kp00N[P5zd__亟-|R89ج>۽yOW&{au\KqmE<�e>4k:4Nx[U#-(29?t;~wh ¼2[FH#l`z} ux_C+JfV++ 987wm qPC@ 'C)kL}3ؾb{�|ag|FZDFu) |w#|FվCqMhDžp3c(l �t^# =1~]�WC G:}ewEu7 ?;a1=@?+~50ҐHF;(bl�t5j1$q۰+tiv5pKzX!b0TN<tb\̓1.<lT׌j`YfW;O=1^U#MjH;owC t߈<1zW|Am4'w" xt"Tҽč<-#[T*^&sjA/E?LތLƘ&"Y^̩d c<tg1Ld�\6/:'Y}7VP]~\�JE5%˩lm'z= PJ+^IP n2~u^H jmc_ki-flK=2;Tv3mJ!I#` 9�WX7/(ެ[F rp03VmB̲�'P+I:2$*ٜ,h)Ӿ3nϠ?u!X3vqXvڃBa &HtxQW\S(ٔ~)<x ,5Qİc *b|aw;0FJfnLs}}v8a�zU) r(3Mam^7|n.��s8<+%ou'"X?@B=+䘼2>Kln>eb iAɪy)cۑ@AB_7N0fl�נ-H WmE혉8mμ2U=q@U gzA 3'_j սljn?$2F�:J"h0€8sN+rБ^7]cΠ}M{t59E_b3^b✆tBޡn(;;.?`Ezuλ#o"3ܐI^]w*'Airm%P!Sc3�~ j77uΝpF% z|a:z;׸ 9�W̾?u]:6WVQMo8OuzqnQcvo�ƣT ]0ɞq}<ǯ�?mR^ ӧchxRt9!6~\FyY=AVoĘwJiVeyʬV,}<Ki\B�x}ݫw H׻ #${'_¼LCw `[*qҟ&\GNv8q�{Vy%Qb;X#�s^Y |1yvo-ʶ?+88�,U{DKٞkz|ۤc-Ҁ64/@w~v22HTLd z=+/隅[\_'kem 1LRd5mjk71A<A�z*p$Wpꖬ$I�udz\wVq�Z(;H(9�ע(�(( oZ3F�TOJ(/ȏSM`?#Z 1�|Dvjo�c�SYHǖ �@"[v k�€/XAPx%Iy HIEdaF(GxΡῈҧO Ū3­1ǒUqpO5 x~`?1@i(촤V<y}.#Q4k41F6%Wsk  _}<;DDXd 7y>#Iy{2 ;9$uWQn-Of blQc%�| 2<"T^H^zzz<gכd 0ێ=먴]> !1j�U m]�?^ ׼/,48RyޞX wpsXwlt:;! 'Ҿm6z� ~XFooH͵o9vÐ1_jO0d7338�aP�JhZ@> ŸxP? <@XoU<`~ [?0/ooh^t/<i߼�gz�6$2-v5~QM-3er_�_6hÝ5eIqc _ <)& Gcd � XQF=:P gSW~xoO;8w?"p\}Ͳ(T�{>Ih/& �Ky>o½εWonw@948VpDq*񧰇j年PsݿVy'#Qh@ax{ODq~[�X2ŢJEʈmʔA(XulnL1{GL]1�kZPYb=`uKB}Ƿlqƾp%"!^kן]g}A邤:W\|!a֥,Q-?/%262xȷUv 8d@-ѣUv~Sχp<L�EW$fe>T5o |J{oja<c,u}PY%>"I]yB\H۰T+#{2G;}IP,�X2fQpt]3 �D5KHz1=�z{ו=y[<9hZ"m2qyo3vw^ֿfk  `q*Tgҹ$?"X)RA$^J.@^B[ssrET(�wj^{&3bi8O_B8残V󛫍X#}(<:}*h>ĭNN!Pk^9;St@p#`qzUc]y*?u#=v澍~ oOr)exH3LtD6qBq�kF`רx~s]0=]|_Qc�5}/6ƈV9ڌ �~Ǚu)��jDwU+: \ �k?z*0NT~]D%1 ("AP?_jAѳzSK@Q@Q@(((((((ZiDv/R@ D:(v:�0)KE�G�yK3RQ@`RE�QE�QE�QE�QE�QE�QE�&&(R_AKE�&-PEPEPFE�7bzʗjR@ F-��(�(�(�(�(��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/vignettes/translations.Rmd������������������������������������������������������������������0000644�0001762�0000144�00000007225�14642046757�017145� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- title: "Translations" output: rmarkdown::html_vignette description: > If your documentation is written in a language other than English, you can automatically translate the text generated by pkgdown by setting the `lang` field. If your language isn't currently supported, we'll show you how you can provide translations. vignette: > %\VignetteIndexEntry{Translations} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` If your documentation (`.Rd` and `.Rmd`) is written in a language other than English, declare it by setting setting `lang` to the [language code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) for your language: ``` yaml lang: fr ``` This will be used to set the language of the web page and to translate the English words that pkgdown generates on your site. Current available translations are: - `ca`: Catalan - `de`: German - `dk`: Danish - `es`: Spanish - `fr`: French - `ko`: Korean - `pt`: Portuguese - `tr`: Turkish - `zh_CN`: Chinese (simplified) As you can see, most language codes are two letters, but if a language has multiple variants, it gets a longer form which can be used to disambiguate the options. For example, Chinese can use one of two forms: simplified (used in China and Singapore) or traditional (used in Taiwan and Hong Kong). Another example would be providing specific French Canadian translations by using code `fr_CN`. ## Translations Translations are contributed by community members so if your language is not currently available, you could be the one to add it! To get started, first check the [pkgdown issues](https://github.com/r-lib/pkgdown/issues) to see if anyone has filed an existing issue. If so, the person who filed the issue might make for a great collaborator 😀. Next, install [potools](https://michaelchirico.github.io/potools/) and [usethis](https://usethis.r-lib.org): ```{r} #| eval: false install.packages(c("potools", "usethis")) ``` You'll then need to familiarise yourself with the basics of [translations with potools](https://michaelchirico.github.io/potools/articles/translators.html) and [creating pull requests](https://usethis.r-lib.org/articles/pr-functions.html) with usethis. If you don't already know it, you'll need to look up the ISO 639-1 abbreviation for [your language](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes). In the examples below, I'll pretend I'm providing translations for Zulu, which has code `zu`. Start by initialising a pull request: ```{r} #| eval: false usethis::pr_init("translation-zu") ``` Then create the translation file by running `potools::po_create("zu")`, open `po/R-zu.po`, and starting filling in the translations. If you have access to chatGPT or similar, you can try prepopulating the translations, with a prompt something like thii: > You are an R developer who is fluent in English and Zulu. You love to do careful, high quality translations in your spare time. Complete the following po file for the R pkgdown package (which creates websites for R packages) by supplying translations for Zulu. Use inclusive gender forms where possible. Then copy and paste the complete contents of the `.po` file . You can check your work by adding `lang: zu` to your `_pkgdown.yml` then running: ```{r} #| eval: false potools::po_compile() devtools::load_all() build_site("~/path/to/your/site") ``` Once you're happy with your work, make sure to compile the changes: ```{r} #| eval: false potools::po_compile() ``` Then commit your changes to Git and submit your pull request for review: ```{r} #| eval: false usethis::pr_push() ``` ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/vignettes/test/�����������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14672347612�014726� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/vignettes/test/pdf.Rmd����������������������������������������������������������������������0000644�0001762�0000144�00000000151�13634413343�016130� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- title: "PDF" output: pdf_document pkgdown: as_is: true extension: pdf --- # Heading Some text �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/vignettes/test/jss.bst����������������������������������������������������������������������0000644�0001762�0000144�00000100405�13632757251�016236� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������%% %% This is file `jss.bst', %% generated with the docstrip utility. %% %% The original source files were: %% %% merlin.mbs (with options: `ay,nat,nm-rvx,keyxyr,dt-beg,yr-par,note-yr,tit-qq,atit-u,trnum-it,vol-bf,volp-com,num-xser,pre-edn,isbn,issn,edpar,pp,ed,xedn,xand,etal-it,revdata,eprint,url,url-blk,doi,nfss') %% %% ** BibTeX style file for JSS publications (http://www.jstatsoft.org/) %% %% Copyright 1994-2011 Patrick W Daly %% License: GPL-2 | GPL-3 % =============================================================== % IMPORTANT NOTICE: % This bibliographic style (bst) file has been generated from one or % more master bibliographic style (mbs) files, listed above, provided % with kind permission of Patrick W Daly. % % This generated file can be redistributed and/or modified under the terms % of the General Public License (Version 2 or 3). % =============================================================== % Name and version information of the main mbs file: % \ProvidesFile{merlin.mbs}[2011/11/18 4.33 (PWD, AO, DPC)] % For use with BibTeX version 0.99a or later %------------------------------------------------------------------- % This bibliography style file is intended for texts in ENGLISH % This is an author-year citation style bibliography. As such, it is % non-standard LaTeX, and requires a special package file to function properly. % Such a package is natbib.sty by Patrick W. Daly % The form of the \bibitem entries is % \bibitem[Jones et al.(1990)]{key}... % \bibitem[Jones et al.(1990)Jones, Baker, and Smith]{key}... % The essential feature is that the label (the part in brackets) consists % of the author names, as they should appear in the citation, with the year % in parentheses following. There must be no space before the opening % parenthesis! % With natbib v5.3, a full list of authors may also follow the year. % In natbib.sty, it is possible to define the type of enclosures that is % really wanted (brackets or parentheses), but in either case, there must % be parentheses in the label. % The \cite command functions as follows: % \citet{key} ==>> Jones et al. (1990) % \citet*{key} ==>> Jones, Baker, and Smith (1990) % \citep{key} ==>> (Jones et al., 1990) % \citep*{key} ==>> (Jones, Baker, and Smith, 1990) % \citep[chap. 2]{key} ==>> (Jones et al., 1990, chap. 2) % \citep[e.g.][]{key} ==>> (e.g. Jones et al., 1990) % \citep[e.g.][p. 32]{key} ==>> (e.g. Jones et al., 1990, p. 32) % \citeauthor{key} ==>> Jones et al. % \citeauthor*{key} ==>> Jones, Baker, and Smith % \citeyear{key} ==>> 1990 %--------------------------------------------------------------------- ENTRY { address archive author booktitle chapter collaboration doi edition editor eid eprint howpublished institution isbn issn journal key month note number numpages organization pages publisher school series title type url volume year } {} { label extra.label sort.label short.list } INTEGERS { output.state before.all mid.sentence after.sentence after.block } FUNCTION {init.state.consts} { #0 'before.all := #1 'mid.sentence := #2 'after.sentence := #3 'after.block := } STRINGS { s t} FUNCTION {output.nonnull} { 's := output.state mid.sentence = { ", " * write$ } { output.state after.block = { add.period$ write$ newline$ "\newblock " write$ } { output.state before.all = 'write$ { add.period$ " " * write$ } if$ } if$ mid.sentence 'output.state := } if$ s } FUNCTION {output} { duplicate$ empty$ 'pop$ 'output.nonnull if$ } FUNCTION {output.check} { 't := duplicate$ empty$ { pop$ "empty " t * " in " * cite$ * warning$ } 'output.nonnull if$ } FUNCTION {fin.entry} { add.period$ write$ newline$ } FUNCTION {new.block} { output.state before.all = 'skip$ { after.block 'output.state := } if$ } FUNCTION {new.sentence} { output.state after.block = 'skip$ { output.state before.all = 'skip$ { after.sentence 'output.state := } if$ } if$ } FUNCTION {add.blank} { " " * before.all 'output.state := } FUNCTION {date.block} { new.block } FUNCTION {not} { { #0 } { #1 } if$ } FUNCTION {and} { 'skip$ { pop$ #0 } if$ } FUNCTION {or} { { pop$ #1 } 'skip$ if$ } FUNCTION {non.stop} { duplicate$ "}" * add.period$ #-1 #1 substring$ "." = } STRINGS {z} FUNCTION {remove.dots} { 'z := "" { z empty$ not } { z #1 #2 substring$ duplicate$ "\." = { z #3 global.max$ substring$ 'z := * } { pop$ z #1 #1 substring$ z #2 global.max$ substring$ 'z := duplicate$ "." = 'pop$ { * } if$ } if$ } while$ } FUNCTION {new.block.checkb} { empty$ swap$ empty$ and 'skip$ 'new.block if$ } FUNCTION {field.or.null} { duplicate$ empty$ { pop$ "" } 'skip$ if$ } FUNCTION {emphasize} { duplicate$ empty$ { pop$ "" } { "\emph{" swap$ * "}" * } if$ } FUNCTION {bolden} { duplicate$ empty$ { pop$ "" } { "\textbf{" swap$ * "}" * } if$ } FUNCTION {tie.or.space.prefix} { duplicate$ text.length$ #3 < { "~" } { " " } if$ swap$ } FUNCTION {capitalize} { "u" change.case$ "t" change.case$ } FUNCTION {space.word} { " " swap$ * " " * } % Here are the language-specific definitions for explicit words. % Each function has a name bbl.xxx where xxx is the English word. % The language selected here is ENGLISH FUNCTION {bbl.and} { "and"} FUNCTION {bbl.etal} { "et~al." } FUNCTION {bbl.editors} { "eds." } FUNCTION {bbl.editor} { "ed." } FUNCTION {bbl.edby} { "edited by" } FUNCTION {bbl.edition} { "edition" } FUNCTION {bbl.volume} { "volume" } FUNCTION {bbl.of} { "of" } FUNCTION {bbl.number} { "number" } FUNCTION {bbl.nr} { "no." } FUNCTION {bbl.in} { "in" } FUNCTION {bbl.pages} { "pp." } FUNCTION {bbl.page} { "p." } FUNCTION {bbl.eidpp} { "pages" } FUNCTION {bbl.chapter} { "chapter" } FUNCTION {bbl.techrep} { "Technical Report" } FUNCTION {bbl.mthesis} { "Master's thesis" } FUNCTION {bbl.phdthesis} { "Ph.D. thesis" } MACRO {jan} {"January"} MACRO {feb} {"February"} MACRO {mar} {"March"} MACRO {apr} {"April"} MACRO {may} {"May"} MACRO {jun} {"June"} MACRO {jul} {"July"} MACRO {aug} {"August"} MACRO {sep} {"September"} MACRO {oct} {"October"} MACRO {nov} {"November"} MACRO {dec} {"December"} MACRO {acmcs} {"ACM Computing Surveys"} MACRO {acta} {"Acta Informatica"} MACRO {cacm} {"Communications of the ACM"} MACRO {ibmjrd} {"IBM Journal of Research and Development"} MACRO {ibmsj} {"IBM Systems Journal"} MACRO {ieeese} {"IEEE Transactions on Software Engineering"} MACRO {ieeetc} {"IEEE Transactions on Computers"} MACRO {ieeetcad} {"IEEE Transactions on Computer-Aided Design of Integrated Circuits"} MACRO {ipl} {"Information Processing Letters"} MACRO {jacm} {"Journal of the ACM"} MACRO {jcss} {"Journal of Computer and System Sciences"} MACRO {scp} {"Science of Computer Programming"} MACRO {sicomp} {"SIAM Journal on Computing"} MACRO {tocs} {"ACM Transactions on Computer Systems"} MACRO {tods} {"ACM Transactions on Database Systems"} MACRO {tog} {"ACM Transactions on Graphics"} MACRO {toms} {"ACM Transactions on Mathematical Software"} MACRO {toois} {"ACM Transactions on Office Information Systems"} MACRO {toplas} {"ACM Transactions on Programming Languages and Systems"} MACRO {tcs} {"Theoretical Computer Science"} FUNCTION {bibinfo.check} { swap$ duplicate$ missing$ { pop$ pop$ "" } { duplicate$ empty$ { swap$ pop$ } { swap$ pop$ } if$ } if$ } FUNCTION {bibinfo.warn} { swap$ duplicate$ missing$ { swap$ "missing " swap$ * " in " * cite$ * warning$ pop$ "" } { duplicate$ empty$ { swap$ "empty " swap$ * " in " * cite$ * warning$ } { swap$ pop$ } if$ } if$ } FUNCTION {format.eprint} { eprint duplicate$ empty$ 'skip$ { "\eprint" archive empty$ 'skip$ { "[" * archive * "]" * } if$ "{" * swap$ * "}" * } if$ } FUNCTION {format.url} { url duplicate$ empty$ { pop$ "" } { "\urlprefix\url{" swap$ * "}" * } if$ } INTEGERS { nameptr namesleft numnames } STRINGS { bibinfo} FUNCTION {format.names} { 'bibinfo := duplicate$ empty$ 'skip$ { 's := "" 't := #1 'nameptr := s num.names$ 'numnames := numnames 'namesleft := { namesleft #0 > } { s nameptr "{vv~}{ll}{ jj}{ f{}}" format.name$ remove.dots bibinfo bibinfo.check 't := nameptr #1 > { namesleft #1 > { ", " * t * } { s nameptr "{ll}" format.name$ duplicate$ "others" = { 't := } { pop$ } if$ "," * t "others" = { " " * bbl.etal emphasize * } { " " * t * } if$ } if$ } 't if$ nameptr #1 + 'nameptr := namesleft #1 - 'namesleft := } while$ } if$ } FUNCTION {format.names.ed} { 'bibinfo := duplicate$ empty$ 'skip$ { 's := "" 't := #1 'nameptr := s num.names$ 'numnames := numnames 'namesleft := { namesleft #0 > } { s nameptr "{f{}~}{vv~}{ll}{ jj}" format.name$ remove.dots bibinfo bibinfo.check 't := nameptr #1 > { namesleft #1 > { ", " * t * } { s nameptr "{ll}" format.name$ duplicate$ "others" = { 't := } { pop$ } if$ "," * t "others" = { " " * bbl.etal emphasize * } { " " * t * } if$ } if$ } 't if$ nameptr #1 + 'nameptr := namesleft #1 - 'namesleft := } while$ } if$ } FUNCTION {format.key} { empty$ { key field.or.null } { "" } if$ } FUNCTION {format.authors} { author "author" format.names duplicate$ empty$ 'skip$ { collaboration "collaboration" bibinfo.check duplicate$ empty$ 'skip$ { " (" swap$ * ")" * } if$ * } if$ } FUNCTION {get.bbl.editor} { editor num.names$ #1 > 'bbl.editors 'bbl.editor if$ } FUNCTION {format.editors} { editor "editor" format.names duplicate$ empty$ 'skip$ { " " * get.bbl.editor "(" swap$ * ")" * * } if$ } FUNCTION {format.isbn} { isbn "isbn" bibinfo.check duplicate$ empty$ 'skip$ { new.block "ISBN " swap$ * } if$ } FUNCTION {format.issn} { issn "issn" bibinfo.check duplicate$ empty$ 'skip$ { new.block "ISSN " swap$ * } if$ } FUNCTION {format.doi} { doi empty$ { "" } { new.block "\doi{" doi * "}" * } if$ } FUNCTION {format.note} { note empty$ { "" } { note #1 #1 substring$ duplicate$ "{" = 'skip$ { output.state mid.sentence = { "l" } { "u" } if$ change.case$ } if$ note #2 global.max$ substring$ * "note" bibinfo.check } if$ } FUNCTION {format.title} { title "title" bibinfo.check duplicate$ empty$ 'skip$ { "\enquote{" swap$ * add.period$ "}" * } if$ } FUNCTION {format.full.names} {'s := "" 't := #1 'nameptr := s num.names$ 'numnames := numnames 'namesleft := { namesleft #0 > } { s nameptr "{vv~}{ll}" format.name$ 't := nameptr #1 > { namesleft #1 > { ", " * t * } { s nameptr "{ll}" format.name$ duplicate$ "others" = { 't := } { pop$ } if$ t "others" = { " " * bbl.etal emphasize * } { numnames #2 > { "," * } 'skip$ if$ bbl.and space.word * t * } if$ } if$ } 't if$ nameptr #1 + 'nameptr := namesleft #1 - 'namesleft := } while$ } FUNCTION {author.editor.key.full} { author empty$ { editor empty$ { key empty$ { cite$ #1 #3 substring$ } 'key if$ } { editor format.full.names } if$ } { author format.full.names } if$ } FUNCTION {author.key.full} { author empty$ { key empty$ { cite$ #1 #3 substring$ } 'key if$ } { author format.full.names } if$ } FUNCTION {editor.key.full} { editor empty$ { key empty$ { cite$ #1 #3 substring$ } 'key if$ } { editor format.full.names } if$ } FUNCTION {make.full.names} { type$ "book" = type$ "inbook" = or 'author.editor.key.full { type$ "proceedings" = 'editor.key.full 'author.key.full if$ } if$ } FUNCTION {output.bibitem} { newline$ "\bibitem[{" write$ label write$ ")" make.full.names duplicate$ short.list = { pop$ } { * } if$ "}]{" * write$ cite$ write$ "}" write$ newline$ "" before.all 'output.state := } FUNCTION {n.dashify} { 't := "" { t empty$ not } { t #1 #1 substring$ "-" = { t #1 #2 substring$ "--" = not { "--" * t #2 global.max$ substring$ 't := } { { t #1 #1 substring$ "-" = } { "-" * t #2 global.max$ substring$ 't := } while$ } if$ } { t #1 #1 substring$ * t #2 global.max$ substring$ 't := } if$ } while$ } FUNCTION {word.in} { bbl.in capitalize " " * } FUNCTION {format.date} { year "year" bibinfo.check duplicate$ empty$ { "empty year in " cite$ * "; set to ????" * warning$ pop$ "????" } 'skip$ if$ extra.label * before.all 'output.state := " (" swap$ * ")" * } FUNCTION {format.btitle} { title "title" bibinfo.check duplicate$ empty$ 'skip$ { emphasize } if$ } FUNCTION {either.or.check} { empty$ 'pop$ { "can't use both " swap$ * " fields in " * cite$ * warning$ } if$ } FUNCTION {format.bvolume} { volume empty$ { "" } { bbl.volume volume tie.or.space.prefix "volume" bibinfo.check * * series "series" bibinfo.check duplicate$ empty$ 'pop$ { swap$ bbl.of space.word * swap$ emphasize * } if$ "volume and number" number either.or.check } if$ } FUNCTION {format.number.series} { volume empty$ { number empty$ { series field.or.null } { series empty$ { number "number" bibinfo.check } { output.state mid.sentence = { bbl.number } { bbl.number capitalize } if$ number tie.or.space.prefix "number" bibinfo.check * * bbl.in space.word * series "series" bibinfo.check * } if$ } if$ } { "" } if$ } FUNCTION {format.edition} { edition duplicate$ empty$ 'skip$ { output.state mid.sentence = { "l" } { "t" } if$ change.case$ "edition" bibinfo.check " " * bbl.edition * } if$ } INTEGERS { multiresult } FUNCTION {multi.page.check} { 't := #0 'multiresult := { multiresult not t empty$ not and } { t #1 #1 substring$ duplicate$ "-" = swap$ duplicate$ "," = swap$ "+" = or or { #1 'multiresult := } { t #2 global.max$ substring$ 't := } if$ } while$ multiresult } FUNCTION {format.pages} { pages duplicate$ empty$ 'skip$ { duplicate$ multi.page.check { bbl.pages swap$ n.dashify } { bbl.page swap$ } if$ tie.or.space.prefix "pages" bibinfo.check * * } if$ } FUNCTION {format.journal.pages} { pages duplicate$ empty$ 'pop$ { swap$ duplicate$ empty$ { pop$ pop$ format.pages } { ", " * swap$ n.dashify "pages" bibinfo.check * } if$ } if$ } FUNCTION {format.journal.eid} { eid "eid" bibinfo.check duplicate$ empty$ 'pop$ { swap$ duplicate$ empty$ 'skip$ { ", " * } if$ swap$ * numpages empty$ 'skip$ { bbl.eidpp numpages tie.or.space.prefix "numpages" bibinfo.check * * " (" swap$ * ")" * * } if$ } if$ } FUNCTION {format.vol.num.pages} { volume field.or.null duplicate$ empty$ 'skip$ { "volume" bibinfo.check } if$ bolden number "number" bibinfo.check duplicate$ empty$ 'skip$ { swap$ duplicate$ empty$ { "there's a number but no volume in " cite$ * warning$ } 'skip$ if$ swap$ "(" swap$ * ")" * } if$ * eid empty$ { format.journal.pages } { format.journal.eid } if$ } FUNCTION {format.chapter.pages} { chapter empty$ 'format.pages { type empty$ { bbl.chapter } { type "l" change.case$ "type" bibinfo.check } if$ chapter tie.or.space.prefix "chapter" bibinfo.check * * pages empty$ 'skip$ { ", " * format.pages * } if$ } if$ } FUNCTION {format.booktitle} { booktitle "booktitle" bibinfo.check emphasize } FUNCTION {format.in.ed.booktitle} { format.booktitle duplicate$ empty$ 'skip$ { editor "editor" format.names.ed duplicate$ empty$ 'pop$ { " " * get.bbl.editor "(" swap$ * "), " * * swap$ * } if$ word.in swap$ * } if$ } FUNCTION {format.thesis.type} { type duplicate$ empty$ 'pop$ { swap$ pop$ "t" change.case$ "type" bibinfo.check } if$ } FUNCTION {format.tr.number} { number "number" bibinfo.check type duplicate$ empty$ { pop$ bbl.techrep } 'skip$ if$ "type" bibinfo.check swap$ duplicate$ empty$ { pop$ "t" change.case$ } { tie.or.space.prefix * * } if$ } FUNCTION {format.article.crossref} { word.in " \cite{" * crossref * "}" * } FUNCTION {format.book.crossref} { volume duplicate$ empty$ { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ pop$ word.in } { bbl.volume capitalize swap$ tie.or.space.prefix "volume" bibinfo.check * * bbl.of space.word * } if$ " \cite{" * crossref * "}" * } FUNCTION {format.incoll.inproc.crossref} { word.in " \cite{" * crossref * "}" * } FUNCTION {format.org.or.pub} { 't := "" address empty$ t empty$ and 'skip$ { t empty$ { address "address" bibinfo.check * } { t * address empty$ 'skip$ { ", " * address "address" bibinfo.check * } if$ } if$ } if$ } FUNCTION {format.publisher.address} { publisher "publisher" bibinfo.warn format.org.or.pub } FUNCTION {format.organization.address} { organization "organization" bibinfo.check format.org.or.pub } FUNCTION {article} { output.bibitem format.authors "author" output.check author format.key output format.date "year" output.check date.block format.title "title" output.check new.block crossref missing$ { journal "journal" bibinfo.check emphasize "journal" output.check format.vol.num.pages output } { format.article.crossref output.nonnull format.pages output } if$ format.issn output format.doi output new.block format.note output format.eprint output format.url output fin.entry } FUNCTION {book} { output.bibitem author empty$ { format.editors "author and editor" output.check editor format.key output } { format.authors output.nonnull crossref missing$ { "author and editor" editor either.or.check } 'skip$ if$ } if$ format.date "year" output.check date.block format.btitle "title" output.check crossref missing$ { format.bvolume output new.block format.number.series output format.edition output new.sentence format.publisher.address output } { new.block format.book.crossref output.nonnull } if$ format.isbn output format.doi output new.block format.note output format.eprint output format.url output fin.entry } FUNCTION {booklet} { output.bibitem format.authors output author format.key output format.date "year" output.check date.block format.title "title" output.check new.block howpublished "howpublished" bibinfo.check output address "address" bibinfo.check output format.isbn output format.doi output new.block format.note output format.eprint output format.url output fin.entry } FUNCTION {inbook} { output.bibitem author empty$ { format.editors "author and editor" output.check editor format.key output } { format.authors output.nonnull crossref missing$ { "author and editor" editor either.or.check } 'skip$ if$ } if$ format.date "year" output.check date.block format.btitle "title" output.check crossref missing$ { format.bvolume output format.chapter.pages "chapter and pages" output.check new.block format.number.series output format.edition output new.sentence format.publisher.address output } { format.chapter.pages "chapter and pages" output.check new.block format.book.crossref output.nonnull } if$ crossref missing$ { format.isbn output } 'skip$ if$ format.doi output new.block format.note output format.eprint output format.url output fin.entry } FUNCTION {incollection} { output.bibitem format.authors "author" output.check author format.key output format.date "year" output.check date.block format.title "title" output.check new.block crossref missing$ { format.in.ed.booktitle "booktitle" output.check format.bvolume output format.number.series output format.edition output format.chapter.pages output new.sentence format.publisher.address output format.isbn output } { format.incoll.inproc.crossref output.nonnull format.chapter.pages output } if$ format.doi output new.block format.note output format.eprint output format.url output fin.entry } FUNCTION {inproceedings} { output.bibitem format.authors "author" output.check author format.key output format.date "year" output.check date.block format.title "title" output.check new.block crossref missing$ { format.in.ed.booktitle "booktitle" output.check format.bvolume output format.number.series output format.pages output new.sentence publisher empty$ { format.organization.address output } { organization "organization" bibinfo.check output format.publisher.address output } if$ format.isbn output format.issn output } { format.incoll.inproc.crossref output.nonnull format.pages output } if$ format.doi output new.block format.note output format.eprint output format.url output fin.entry } FUNCTION {conference} { inproceedings } FUNCTION {manual} { output.bibitem format.authors output author format.key output format.date "year" output.check date.block format.btitle "title" output.check organization address new.block.checkb organization "organization" bibinfo.check output address "address" bibinfo.check output format.edition output format.doi output new.block format.note output format.eprint output format.url output fin.entry } FUNCTION {mastersthesis} { output.bibitem format.authors "author" output.check author format.key output format.date "year" output.check date.block format.btitle "title" output.check new.block bbl.mthesis format.thesis.type output.nonnull school "school" bibinfo.warn output address "address" bibinfo.check output format.doi output new.block format.note output format.eprint output format.url output fin.entry } FUNCTION {misc} { output.bibitem format.authors output author format.key output format.date "year" output.check date.block format.title output new.block howpublished "howpublished" bibinfo.check output format.doi output new.block format.note output format.eprint output format.url output fin.entry } FUNCTION {phdthesis} { output.bibitem format.authors "author" output.check author format.key output format.date "year" output.check date.block format.btitle "title" output.check new.block bbl.phdthesis format.thesis.type output.nonnull school "school" bibinfo.warn output address "address" bibinfo.check output format.doi output new.block format.note output format.eprint output format.url output fin.entry } FUNCTION {proceedings} { output.bibitem format.editors output editor format.key output format.date "year" output.check date.block format.btitle "title" output.check format.bvolume output format.number.series output new.sentence publisher empty$ { format.organization.address output } { organization "organization" bibinfo.check output format.publisher.address output } if$ format.isbn output format.issn output format.doi output new.block format.note output format.eprint output format.url output fin.entry } FUNCTION {techreport} { output.bibitem format.authors "author" output.check author format.key output format.date "year" output.check date.block format.title "title" output.check new.block format.tr.number emphasize output.nonnull institution "institution" bibinfo.warn output address "address" bibinfo.check output format.doi output new.block format.note output format.eprint output format.url output fin.entry } FUNCTION {unpublished} { output.bibitem format.authors "author" output.check author format.key output format.date "year" output.check date.block format.title "title" output.check format.doi output new.block format.note "note" output.check format.eprint output format.url output fin.entry } FUNCTION {default.type} { misc } READ FUNCTION {sortify} { purify$ "l" change.case$ } INTEGERS { len } FUNCTION {chop.word} { 's := 'len := s #1 len substring$ = { s len #1 + global.max$ substring$ } 's if$ } FUNCTION {format.lab.names} { 's := "" 't := s #1 "{vv~}{ll}" format.name$ s num.names$ duplicate$ #2 > { pop$ " " * bbl.etal emphasize * } { #2 < 'skip$ { s #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = { " " * bbl.etal emphasize * } { bbl.and space.word * s #2 "{vv~}{ll}" format.name$ * } if$ } if$ } if$ } FUNCTION {author.key.label} { author empty$ { key empty$ { cite$ #1 #3 substring$ } 'key if$ } { author format.lab.names } if$ } FUNCTION {author.editor.key.label} { author empty$ { editor empty$ { key empty$ { cite$ #1 #3 substring$ } 'key if$ } { editor format.lab.names } if$ } { author format.lab.names } if$ } FUNCTION {editor.key.label} { editor empty$ { key empty$ { cite$ #1 #3 substring$ } 'key if$ } { editor format.lab.names } if$ } FUNCTION {calc.short.authors} { type$ "book" = type$ "inbook" = or 'author.editor.key.label { type$ "proceedings" = 'editor.key.label 'author.key.label if$ } if$ 'short.list := } FUNCTION {calc.label} { calc.short.authors short.list "(" * year duplicate$ empty$ short.list key field.or.null = or { pop$ "" } 'skip$ if$ * 'label := } FUNCTION {sort.format.names} { 's := #1 'nameptr := "" s num.names$ 'numnames := numnames 'namesleft := { namesleft #0 > } { s nameptr "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" format.name$ 't := nameptr #1 > { " " * namesleft #1 = t "others" = and { "zzzzz" 't := } 'skip$ if$ t sortify * } { t sortify * } if$ nameptr #1 + 'nameptr := namesleft #1 - 'namesleft := } while$ } FUNCTION {sort.format.title} { 't := "A " #2 "An " #3 "The " #4 t chop.word chop.word chop.word sortify #1 global.max$ substring$ } FUNCTION {author.sort} { author empty$ { key empty$ { "to sort, need author or key in " cite$ * warning$ "" } { key sortify } if$ } { author sort.format.names } if$ } FUNCTION {author.editor.sort} { author empty$ { editor empty$ { key empty$ { "to sort, need author, editor, or key in " cite$ * warning$ "" } { key sortify } if$ } { editor sort.format.names } if$ } { author sort.format.names } if$ } FUNCTION {editor.sort} { editor empty$ { key empty$ { "to sort, need editor or key in " cite$ * warning$ "" } { key sortify } if$ } { editor sort.format.names } if$ } FUNCTION {presort} { calc.label label sortify " " * type$ "book" = type$ "inbook" = or 'author.editor.sort { type$ "proceedings" = 'editor.sort 'author.sort if$ } if$ #1 entry.max$ substring$ 'sort.label := sort.label * " " * title field.or.null sort.format.title * #1 entry.max$ substring$ 'sort.key$ := } ITERATE {presort} SORT STRINGS { last.label next.extra } INTEGERS { last.extra.num last.extra.num.extended last.extra.num.blank number.label } FUNCTION {initialize.extra.label.stuff} { #0 int.to.chr$ 'last.label := "" 'next.extra := #0 'last.extra.num := "a" chr.to.int$ #1 - 'last.extra.num.blank := last.extra.num.blank 'last.extra.num.extended := #0 'number.label := } FUNCTION {forward.pass} { last.label label = { last.extra.num #1 + 'last.extra.num := last.extra.num "z" chr.to.int$ > { "a" chr.to.int$ 'last.extra.num := last.extra.num.extended #1 + 'last.extra.num.extended := } 'skip$ if$ last.extra.num.extended last.extra.num.blank > { last.extra.num.extended int.to.chr$ last.extra.num int.to.chr$ * 'extra.label := } { last.extra.num int.to.chr$ 'extra.label := } if$ } { "a" chr.to.int$ 'last.extra.num := "" 'extra.label := label 'last.label := } if$ number.label #1 + 'number.label := } FUNCTION {reverse.pass} { next.extra "b" = { "a" 'extra.label := } 'skip$ if$ extra.label 'next.extra := extra.label duplicate$ empty$ 'skip$ { "{\natexlab{" swap$ * "}}" * } if$ 'extra.label := label extra.label * 'label := } EXECUTE {initialize.extra.label.stuff} ITERATE {forward.pass} REVERSE {reverse.pass} FUNCTION {bib.sort.order} { sort.label " " * year field.or.null sortify * " " * title field.or.null sort.format.title * #1 entry.max$ substring$ 'sort.key$ := } ITERATE {bib.sort.order} SORT FUNCTION {begin.bib} { preamble$ empty$ 'skip$ { preamble$ write$ newline$ } if$ "\begin{thebibliography}{" number.label int.to.str$ * "}" * write$ newline$ "\newcommand{\enquote}[1]{``#1''}" write$ newline$ "\providecommand{\natexlab}[1]{#1}" write$ newline$ "\providecommand{\url}[1]{\texttt{#1}}" write$ newline$ "\providecommand{\urlprefix}{URL }" write$ newline$ "\expandafter\ifx\csname urlstyle\endcsname\relax" write$ newline$ " \providecommand{\doi}[1]{doi:\discretionary{}{}{}#1}\else" write$ newline$ " \providecommand{\doi}{doi:\discretionary{}{}{}\begingroup \urlstyle{rm}\Url}\fi" write$ newline$ "\providecommand{\eprint}[2][]{\url{#2}}" write$ newline$ } EXECUTE {begin.bib} EXECUTE {init.state.consts} ITERATE {call.type$} FUNCTION {end.bib} { newline$ "\end{thebibliography}" write$ newline$ } EXECUTE {end.bib} %% End of customized bst file %% %% End of file `jss.bst'. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/vignettes/test/short.Rmd��������������������������������������������������������������������0000644�0001762�0000144�00000000121�14132553437�016516� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- title: "A short page" --- The footer should hug the bottom of the viewport. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/vignettes/test/widgets.Rmd������������������������������������������������������������������0000644�0001762�0000144�00000000543�14633374223�017035� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- title: "HTML widgets" --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ## Widgets Test spacing above widget. ```{r, echo=FALSE} path1 <- tempfile() writeLines(letters, path1) path2 <- tempfile() writeLines(letters[-(10:11)], path2) diffviewer::visual_diff(path1, path2) ``` Test spacing below widget. �������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/vignettes/test/jss.log����������������������������������������������������������������������0000644�0001762�0000144�00000076671�14632127733�016245� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is pdfTeX, Version 3.141592653-2.6-1.40.26 (TeX Live 2024) (preloaded format=pdflatex 2024.4.8) 11 JUN 2024 15:13 entering extended mode restricted \write18 enabled. %&-line parsing enabled. **/Users/hadleywickham/Documents/devtools/pkgdown/docs/dev/articles/test/jss.tex (/Users/hadleywickham/Documents/devtools/pkgdown/docs/dev/articles/test/jss.tex LaTeX2e <2023-11-01> patch level 1 L3 programming layer <2024-03-14> (./jss.cls Document Class: jss 2015/09/01 3.0 jss class by Achim Zeileis (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/base/article.cls Document Class: article 2023/05/17 v1.4n Standard LaTeX document class (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/base/size11.clo File: size11.clo 2023/05/17 v1.4n Standard LaTeX file (size option) ) \c@part=\count188 \c@section=\count189 \c@subsection=\count190 \c@subsubsection=\count191 \c@paragraph=\count192 \c@subparagraph=\count193 \c@figure=\count194 \c@table=\count195 \abovecaptionskip=\skip48 \belowcaptionskip=\skip49 \bibindent=\dimen140 ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/graphics/graphicx.sty Package: graphicx 2021/09/16 v1.2d Enhanced LaTeX Graphics (DPC,SPQR) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/graphics/keyval.sty Package: keyval 2022/05/29 v1.15 key=value parser (DPC) \KV@toks@=\toks17 ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/graphics/graphics.sty Package: graphics 2022/03/10 v1.4e Standard LaTeX Graphics (DPC,SPQR) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/graphics/trig.sty Package: trig 2021/08/11 v1.11 sin cos tan (DPC) ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/graphics-cfg/graphics.cfg File: graphics.cfg 2016/06/04 v1.11 sample graphics configuration ) Package graphics Info: Driver file: pdftex.def on input line 107. (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/graphics-def/pdftex.def File: pdftex.def 2022/09/22 v1.2b Graphics/color driver for pdftex )) \Gin@req@height=\dimen141 \Gin@req@width=\dimen142 ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/graphics/color.sty Package: color 2022/01/06 v1.3d Standard LaTeX Color (DPC) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/graphics-cfg/color.cfg File: color.cfg 2016/01/02 v1.6 sample color configuration ) Package color Info: Driver file: pdftex.def on input line 149. (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/graphics/mathcolor.ltx)) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/ae/ae.sty Package: ae 2001/02/12 1.3 Almost European Computer Modern (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/base/fontenc.sty Package: fontenc 2021/04/29 v2.0v Standard LaTeX package )) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/fancyvrb/fancyvrb.sty Package: fancyvrb 2024/01/20 4.5c verbatim text (tvz,hv) \FV@CodeLineNo=\count196 \FV@InFile=\read2 \FV@TabBox=\box51 \c@FancyVerbLine=\count197 \FV@StepNumber=\count198 \FV@OutFile=\write3 ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/base/fontenc.sty Package: fontenc 2021/04/29 v2.0v Standard LaTeX package LaTeX Font Info: Trying to load font information for T1+aer on input line 112. (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/ae/t1aer.fd File: t1aer.fd 1997/11/16 Font definitions for T1/aer. )) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/natbib/natbib.sty Package: natbib 2010/09/13 8.31b (PWD, AO) \bibhang=\skip50 \bibsep=\skip51 LaTeX Info: Redefining \cite on input line 694. \c@NAT@ctr=\count199 ) \footerskip=\skip52 (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/hyperref/hyperref.sty Package: hyperref 2024-01-20 v7.01h Hypertext links for LaTeX (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/iftex/iftex.sty Package: iftex 2022/02/03 v1.0f TeX engine tests ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/kvsetkeys/kvsetkeys.sty Package: kvsetkeys 2022-10-05 v1.19 Key value parser (HO) ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/kvdefinekeys/kvdefinekeys.sty Package: kvdefinekeys 2019-12-19 v1.6 Define keys (HO) ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pdfescape/pdfescape.sty Package: pdfescape 2019/12/09 v1.15 Implements pdfTeX's escape features (HO) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/ltxcmds/ltxcmds.sty Package: ltxcmds 2023-12-04 v1.26 LaTeX kernel commands for general use (HO) ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pdftexcmds/pdftexcmds.sty Package: pdftexcmds 2020-06-27 v0.33 Utility functions of pdfTeX for LuaTeX (HO) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/infwarerr/infwarerr.sty Package: infwarerr 2019/12/03 v1.5 Providing info/warning/error messages (HO) ) Package pdftexcmds Info: \pdf@primitive is available. Package pdftexcmds Info: \pdf@ifprimitive is available. Package pdftexcmds Info: \pdfdraftmode found. )) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/hycolor/hycolor.sty Package: hycolor 2020-01-27 v1.10 Color options for hyperref/bookmark (HO) ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/auxhook/auxhook.sty Package: auxhook 2019-12-17 v1.6 Hooks for auxiliary files (HO) ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/hyperref/nameref.sty Package: nameref 2023-11-26 v2.56 Cross-referencing by name of section (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/refcount/refcount.sty Package: refcount 2019/12/15 v3.6 Data extraction from label references (HO) ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/gettitlestring/gettitlestring.sty Package: gettitlestring 2019/12/15 v1.6 Cleanup title references (HO) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/kvoptions/kvoptions.sty Package: kvoptions 2022-06-15 v3.15 Key value format for package options (HO) )) \c@section@level=\count266 ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/etoolbox/etoolbox.sty Package: etoolbox 2020/10/05 v2.5k e-TeX tools for LaTeX (JAW) \etb@tempcnta=\count267 ) \@linkdim=\dimen143 \Hy@linkcounter=\count268 \Hy@pagecounter=\count269 (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/hyperref/pd1enc.def File: pd1enc.def 2024-01-20 v7.01h Hyperref: PDFDocEncoding definition (HO) Now handling font encoding PD1 ... ... no UTF-8 mapping file for font encoding PD1 ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/intcalc/intcalc.sty Package: intcalc 2019/12/15 v1.3 Expandable calculations with integers (HO) ) \Hy@SavedSpaceFactor=\count270 (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/hyperref/puenc.def File: puenc.def 2024-01-20 v7.01h Hyperref: PDF Unicode definition (HO) Now handling font encoding PU ... ... no UTF-8 mapping file for font encoding PU ) Package hyperref Info: Hyper figures OFF on input line 4179. Package hyperref Info: Link nesting OFF on input line 4184. Package hyperref Info: Hyper index ON on input line 4187. Package hyperref Info: Plain pages OFF on input line 4194. Package hyperref Info: Backreferencing OFF on input line 4199. Package hyperref Info: Implicit mode ON; LaTeX internals redefined. Package hyperref Info: Bookmarks ON on input line 4446. \c@Hy@tempcnt=\count271 (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/url/url.sty \Urlmuskip=\muskip16 Package: url 2013/09/16 ver 3.4 Verb mode for urls, etc. ) LaTeX Info: Redefining \url on input line 4784. \XeTeXLinkMargin=\dimen144 (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/bitset/bitset.sty Package: bitset 2019/12/09 v1.3 Handle bit-vector datatype (HO) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/bigintcalc/bigintcalc.sty Package: bigintcalc 2019/12/15 v1.5 Expandable calculations on big integers (HO) )) \Fld@menulength=\count272 \Field@Width=\dimen145 \Fld@charsize=\dimen146 Package hyperref Info: Hyper figures OFF on input line 6063. Package hyperref Info: Link nesting OFF on input line 6068. Package hyperref Info: Hyper index ON on input line 6071. Package hyperref Info: backreferencing OFF on input line 6078. Package hyperref Info: Link coloring OFF on input line 6083. Package hyperref Info: Link coloring with OCG OFF on input line 6088. Package hyperref Info: PDF/A mode OFF on input line 6093. (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/base/atbegshi-ltx.sty Package: atbegshi-ltx 2021/01/10 v1.0c Emulation of the original atbegshi package with kernel methods ) \Hy@abspage=\count273 \c@Item=\count274 \c@Hfootnote=\count275 ) Package hyperref Info: Driver (autodetected): hpdftex. (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/hyperref/hpdftex.def File: hpdftex.def 2024-01-20 v7.01h Hyperref driver for pdfTeX (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/base/atveryend-ltx.sty Package: atveryend-ltx 2020/08/19 v1.0a Emulation of the original atveryend package with kernel methods ) \Fld@listcount=\count276 \c@bookmark@seq@number=\count277 (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/rerunfilecheck/rerunfilecheck.sty Package: rerunfilecheck 2022-07-10 v1.10 Rerun checks for auxiliary files (HO) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/uniquecounter/uniquecounter.sty Package: uniquecounter 2019/12/15 v1.4 Provide unlimited unique counter (HO) ) Package uniquecounter Info: New unique counter `rerunfilecheck' on input line 285. ) \Hy@SectionHShift=\skip53 ) \preXLskip=\skip54 \preLskip=\skip55 \preMskip=\skip56 \preSskip=\skip57 \postMskip=\skip58 \postSskip=\skip59 Package hyperref Warning: Option `hyperindex' has already been used, (hyperref) setting the option has no effect on input line 466. Package hyperref Info: Option `colorlinks' set `true' on input line 466. Package hyperref Info: Option `linktocpage' set `true' on input line 466. Package hyperref Info: Option `plainpages' set `false' on input line 466. ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/orcidlink/orcidlink.sty Package: orcidlink 2023/12/30 v1.0.5 Linked ORCiD logo macro package (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/pgf/frontendlayer/tikz.sty (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/pgf/basiclayer/pgf.sty (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/pgf/utilities/pgfrcs.sty (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/utilities/pgfutil-common.tex \pgfutil@everybye=\toks18 \pgfutil@tempdima=\dimen147 \pgfutil@tempdimb=\dimen148 ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/utilities/pgfutil-latex.def \pgfutil@abb=\box52 ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/utilities/pgfrcs.code.tex (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/pgf.revision.tex) Package: pgfrcs 2023-01-15 v3.1.10 (3.1.10) )) Package: pgf 2023-01-15 v3.1.10 (3.1.10) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/pgf/basiclayer/pgfcore.sty (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/pgf/systemlayer/pgfsys.sty (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/systemlayer/pgfsys.code.tex Package: pgfsys 2023-01-15 v3.1.10 (3.1.10) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex \pgfkeys@pathtoks=\toks19 \pgfkeys@temptoks=\toks20 (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/utilities/pgfkeyslibraryfiltered.code.tex \pgfkeys@tmptoks=\toks21 )) \pgf@x=\dimen149 \pgf@y=\dimen150 \pgf@xa=\dimen151 \pgf@ya=\dimen152 \pgf@xb=\dimen153 \pgf@yb=\dimen154 \pgf@xc=\dimen155 \pgf@yc=\dimen156 \pgf@xd=\dimen157 \pgf@yd=\dimen158 \w@pgf@writea=\write4 \r@pgf@reada=\read3 \c@pgf@counta=\count278 \c@pgf@countb=\count279 \c@pgf@countc=\count280 \c@pgf@countd=\count281 \t@pgf@toka=\toks22 \t@pgf@tokb=\toks23 \t@pgf@tokc=\toks24 \pgf@sys@id@count=\count282 (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/systemlayer/pgf.cfg File: pgf.cfg 2023-01-15 v3.1.10 (3.1.10) ) Driver file for pgf: pgfsys-pdftex.def (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-pdftex.def File: pgfsys-pdftex.def 2023-01-15 v3.1.10 (3.1.10) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-pdf.def File: pgfsys-common-pdf.def 2023-01-15 v3.1.10 (3.1.10) ))) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/systemlayer/pgfsyssoftpath.code.tex File: pgfsyssoftpath.code.tex 2023-01-15 v3.1.10 (3.1.10) \pgfsyssoftpath@smallbuffer@items=\count283 \pgfsyssoftpath@bigbuffer@items=\count284 ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/systemlayer/pgfsysprotocol.code.tex File: pgfsysprotocol.code.tex 2023-01-15 v3.1.10 (3.1.10) )) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/xcolor/xcolor.sty Package: xcolor 2023/11/15 v3.01 LaTeX color extensions (UK) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/graphics-cfg/color.cfg File: color.cfg 2016/01/02 v1.6 sample color configuration ) Package xcolor Info: Driver file: pdftex.def on input line 274. LaTeX Info: Redefining \color on input line 758. (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/graphics/mathcolor.ltx) Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1350. Package xcolor Info: Model `hsb' substituted by `rgb' on input line 1354. Package xcolor Info: Model `RGB' extended on input line 1366. Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1368. Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1369. Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1370. Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1371. Package xcolor Info: Model `Gray' substituted by `gray' on input line 1372. Package xcolor Info: Model `wave' substituted by `hsb' on input line 1373. ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/basiclayer/pgfcore.code.tex Package: pgfcore 2023-01-15 v3.1.10 (3.1.10) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/math/pgfmath.code.tex (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/math/pgfmathutil.code.tex) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex \pgfmath@dimen=\dimen159 \pgfmath@count=\count285 \pgfmath@box=\box53 \pgfmath@toks=\toks25 \pgfmath@stack@operand=\toks26 \pgfmath@stack@operation=\toks27 ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.code.tex) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.basic.code.tex) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.trigonometric.code.tex) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.random.code.tex) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.comparison.code.tex) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.base.code.tex) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.round.code.tex) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.misc.code.tex) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.integerarithmetics.code.tex) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/math/pgfmathcalc.code.tex) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/math/pgfmathfloat.code.tex \c@pgfmathroundto@lastzeros=\count286 )) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/math/pgfint.code.tex) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepoints.code.tex File: pgfcorepoints.code.tex 2023-01-15 v3.1.10 (3.1.10) \pgf@picminx=\dimen160 \pgf@picmaxx=\dimen161 \pgf@picminy=\dimen162 \pgf@picmaxy=\dimen163 \pgf@pathminx=\dimen164 \pgf@pathmaxx=\dimen165 \pgf@pathminy=\dimen166 \pgf@pathmaxy=\dimen167 \pgf@xx=\dimen168 \pgf@xy=\dimen169 \pgf@yx=\dimen170 \pgf@yy=\dimen171 \pgf@zx=\dimen172 \pgf@zy=\dimen173 ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathconstruct.code.tex File: pgfcorepathconstruct.code.tex 2023-01-15 v3.1.10 (3.1.10) \pgf@path@lastx=\dimen174 \pgf@path@lasty=\dimen175 ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathusage.code.tex File: pgfcorepathusage.code.tex 2023-01-15 v3.1.10 (3.1.10) \pgf@shorten@end@additional=\dimen176 \pgf@shorten@start@additional=\dimen177 ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/basiclayer/pgfcorescopes.code.tex File: pgfcorescopes.code.tex 2023-01-15 v3.1.10 (3.1.10) \pgfpic=\box54 \pgf@hbox=\box55 \pgf@layerbox@main=\box56 \pgf@picture@serial@count=\count287 ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/basiclayer/pgfcoregraphicstate.code.tex File: pgfcoregraphicstate.code.tex 2023-01-15 v3.1.10 (3.1.10) \pgflinewidth=\dimen178 ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransformations.code.tex File: pgfcoretransformations.code.tex 2023-01-15 v3.1.10 (3.1.10) \pgf@pt@x=\dimen179 \pgf@pt@y=\dimen180 \pgf@pt@temp=\dimen181 ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/basiclayer/pgfcorequick.code.tex File: pgfcorequick.code.tex 2023-01-15 v3.1.10 (3.1.10) ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreobjects.code.tex File: pgfcoreobjects.code.tex 2023-01-15 v3.1.10 (3.1.10) ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathprocessing.code.tex File: pgfcorepathprocessing.code.tex 2023-01-15 v3.1.10 (3.1.10) ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/basiclayer/pgfcorearrows.code.tex File: pgfcorearrows.code.tex 2023-01-15 v3.1.10 (3.1.10) \pgfarrowsep=\dimen182 ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreshade.code.tex File: pgfcoreshade.code.tex 2023-01-15 v3.1.10 (3.1.10) \pgf@max=\dimen183 \pgf@sys@shading@range@num=\count288 \pgf@shadingcount=\count289 ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreimage.code.tex File: pgfcoreimage.code.tex 2023-01-15 v3.1.10 (3.1.10) ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreexternal.code.tex File: pgfcoreexternal.code.tex 2023-01-15 v3.1.10 (3.1.10) \pgfexternal@startupbox=\box57 ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/basiclayer/pgfcorelayers.code.tex File: pgfcorelayers.code.tex 2023-01-15 v3.1.10 (3.1.10) ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransparency.code.tex File: pgfcoretransparency.code.tex 2023-01-15 v3.1.10 (3.1.10) ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepatterns.code.tex File: pgfcorepatterns.code.tex 2023-01-15 v3.1.10 (3.1.10) ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/basiclayer/pgfcorerdf.code.tex File: pgfcorerdf.code.tex 2023-01-15 v3.1.10 (3.1.10) ))) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/modules/pgfmoduleshapes.code.tex File: pgfmoduleshapes.code.tex 2023-01-15 v3.1.10 (3.1.10) \pgfnodeparttextbox=\box58 ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/modules/pgfmoduleplot.code.tex File: pgfmoduleplot.code.tex 2023-01-15 v3.1.10 (3.1.10) ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/pgf/compatibility/pgfcomp-version-0-65.sty Package: pgfcomp-version-0-65 2023-01-15 v3.1.10 (3.1.10) \pgf@nodesepstart=\dimen184 \pgf@nodesepend=\dimen185 ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/pgf/compatibility/pgfcomp-version-1-18.sty Package: pgfcomp-version-1-18 2023-01-15 v3.1.10 (3.1.10) )) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/pgf/utilities/pgffor.sty (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/pgf/utilities/pgfkeys.sty (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex)) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/pgf/math/pgfmath.sty (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/math/pgfmath.code.tex)) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/utilities/pgffor.code.tex Package: pgffor 2023-01-15 v3.1.10 (3.1.10) \pgffor@iter=\dimen186 \pgffor@skip=\dimen187 \pgffor@stack=\toks28 \pgffor@toks=\toks29 )) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/frontendlayer/tikz/tikz.code.tex Package: tikz 2023-01-15 v3.1.10 (3.1.10) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/libraries/pgflibraryplothandlers.code.tex File: pgflibraryplothandlers.code.tex 2023-01-15 v3.1.10 (3.1.10) \pgf@plot@mark@count=\count290 \pgfplotmarksize=\dimen188 ) \tikz@lastx=\dimen189 \tikz@lasty=\dimen190 \tikz@lastxsaved=\dimen191 \tikz@lastysaved=\dimen192 \tikz@lastmovetox=\dimen193 \tikz@lastmovetoy=\dimen194 \tikzleveldistance=\dimen195 \tikzsiblingdistance=\dimen196 \tikz@figbox=\box59 \tikz@figbox@bg=\box60 \tikz@tempbox=\box61 \tikz@tempbox@bg=\box62 \tikztreelevel=\count291 \tikznumberofchildren=\count292 \tikznumberofcurrentchild=\count293 \tikz@fig@count=\count294 (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/modules/pgfmodulematrix.code.tex File: pgfmodulematrix.code.tex 2023-01-15 v3.1.10 (3.1.10) \pgfmatrixcurrentrow=\count295 \pgfmatrixcurrentcolumn=\count296 \pgf@matrix@numberofcolumns=\count297 ) \tikz@expandcount=\count298 (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarytopaths.code.tex File: tikzlibrarytopaths.code.tex 2023-01-15 v3.1.10 (3.1.10) ))) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysvg.path.code.tex File: tikzlibrarysvg.path.code.tex 2023-01-15 v3.1.10 (3.1.10) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/libraries/pgflibrarysvg.path.code.tex File: pgflibrarysvg.path.code.tex 2023-01-15 v3.1.10 (3.1.10) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/pgf/modules/pgfmoduleparser.code.tex File: pgfmoduleparser.code.tex 2023-01-15 v3.1.10 (3.1.10) \pgfparserdef@arg@count=\count299 ) \pgf@lib@svg@last@x=\dimen197 \pgf@lib@svg@last@y=\dimen198 \pgf@lib@svg@last@c@x=\dimen199 \pgf@lib@svg@last@c@y=\dimen256 \pgf@lib@svg@count=\count300 \pgf@lib@svg@max@num=\count301 )) \@curXheight=\skip60 ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/generic/thumbpdf/thumbpdf.sty Package: thumbpdf 2018/09/07 v3.17 Inclusion of thumbnails (HO) THUMBPDF: Compressed PDF objects of PDF 1.5 are not supported ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/lm/lmodern.sty Package: lmodern 2015/05/01 v1.6.1 Latin Modern Fonts LaTeX Font Info: Overwriting symbol font `operators' in version `normal' (Font) OT1/cmr/m/n --> OT1/lmr/m/n on input line 22. LaTeX Font Info: Overwriting symbol font `letters' in version `normal' (Font) OML/cmm/m/it --> OML/lmm/m/it on input line 23. LaTeX Font Info: Overwriting symbol font `symbols' in version `normal' (Font) OMS/cmsy/m/n --> OMS/lmsy/m/n on input line 24. LaTeX Font Info: Overwriting symbol font `largesymbols' in version `normal' (Font) OMX/cmex/m/n --> OMX/lmex/m/n on input line 25. LaTeX Font Info: Overwriting symbol font `operators' in version `bold' (Font) OT1/cmr/bx/n --> OT1/lmr/bx/n on input line 26. LaTeX Font Info: Overwriting symbol font `letters' in version `bold' (Font) OML/cmm/b/it --> OML/lmm/b/it on input line 27. LaTeX Font Info: Overwriting symbol font `symbols' in version `bold' (Font) OMS/cmsy/b/n --> OMS/lmsy/b/n on input line 28. LaTeX Font Info: Overwriting symbol font `largesymbols' in version `bold' (Font) OMX/cmex/m/n --> OMX/lmex/m/n on input line 29. LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `normal' (Font) OT1/cmr/bx/n --> OT1/lmr/bx/n on input line 31. LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `normal' (Font) OT1/cmss/m/n --> OT1/lmss/m/n on input line 32. LaTeX Font Info: Overwriting math alphabet `\mathit' in version `normal' (Font) OT1/cmr/m/it --> OT1/lmr/m/it on input line 33. LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `normal' (Font) OT1/cmtt/m/n --> OT1/lmtt/m/n on input line 34. LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `bold' (Font) OT1/cmr/bx/n --> OT1/lmr/bx/n on input line 35. LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `bold' (Font) OT1/cmss/bx/n --> OT1/lmss/bx/n on input line 36. LaTeX Font Info: Overwriting math alphabet `\mathit' in version `bold' (Font) OT1/cmr/bx/it --> OT1/lmr/bx/it on input line 37. LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `bold' (Font) OT1/cmtt/m/n --> OT1/lmtt/m/n on input line 38. ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/base/inputenc.sty Package: inputenc 2021/02/14 v1.3d Input encoding file \inpenc@prehook=\toks30 \inpenc@posthook=\toks31 ) LaTeX Font Info: Trying to load font information for T1+lmr on input line 52. (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/lm/t1lmr.fd File: t1lmr.fd 2015/05/01 v1.6.1 Font defs for Latin Modern ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def File: l3backend-pdftex.def 2024-03-14 L3 backend support: PDF output (pdfTeX) \l__color_backend_stack_int=\count302 \l__pdf_internal_box=\box63 ) (./jss.aux) \openout1 = `jss.aux'. LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 52. LaTeX Font Info: ... okay on input line 52. LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 52. LaTeX Font Info: ... okay on input line 52. LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 52. LaTeX Font Info: ... okay on input line 52. LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 52. LaTeX Font Info: ... okay on input line 52. LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 52. LaTeX Font Info: ... okay on input line 52. LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 52. LaTeX Font Info: ... okay on input line 52. LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 52. LaTeX Font Info: ... okay on input line 52. LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 52. LaTeX Font Info: ... okay on input line 52. LaTeX Font Info: Checking defaults for PU/pdf/m/n on input line 52. LaTeX Font Info: ... okay on input line 52. (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/context/base/mkii/supp-pdf.mkii [Loading MPS to PDF converter (version 2006.09.02).] \scratchcounter=\count303 \scratchdimen=\dimen257 \scratchbox=\box64 \nofMPsegments=\count304 \nofMParguments=\count305 \everyMPshowfont=\toks32 \MPscratchCnt=\count306 \MPscratchDim=\dimen258 \MPnumerator=\count307 \makeMPintoPDFobject=\count308 \everyMPtoPDFconversion=\toks33 ) (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/epstopdf-pkg/epstopdf-base.sty Package: epstopdf-base 2020-01-24 v2.11 Base part for package epstopdf (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/grfext/grfext.sty Package: grfext 2019/12/03 v1.3 Manage graphics extensions (HO) ) Package epstopdf-base Info: Redefining graphics rule for `.eps' on input line 485. Package grfext Info: Graphics extension search list: (grfext) [.pdf,.png,.jpg,.mps,.jpeg,.jbig2,.jb2,.PDF,.PNG,.JPG,.JPEG,.JBIG2,.JB2,.eps] (grfext) \AppendGraphicsExtensions on input line 504. (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/latexconfig/epstopdf-sys.cfg File: epstopdf-sys.cfg 2010/07/13 v1.3 Configuration of (r)epstopdf for TeX Live )) LaTeX Font Info: Trying to load font information for OT1+lmr on input line 52. (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/lm/ot1lmr.fd File: ot1lmr.fd 2015/05/01 v1.6.1 Font defs for Latin Modern ) LaTeX Font Info: Trying to load font information for OML+lmm on input line 52. (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/lm/omllmm.fd File: omllmm.fd 2015/05/01 v1.6.1 Font defs for Latin Modern ) LaTeX Font Info: Trying to load font information for OMS+lmsy on input line 52. (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/lm/omslmsy.fd File: omslmsy.fd 2015/05/01 v1.6.1 Font defs for Latin Modern ) LaTeX Font Info: Trying to load font information for OMX+lmex on input line 52. (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/lm/omxlmex.fd File: omxlmex.fd 2015/05/01 v1.6.1 Font defs for Latin Modern ) LaTeX Font Info: External font `lmex10' loaded for size (Font) <10.95> on input line 52. LaTeX Font Info: External font `lmex10' loaded for size (Font) <8> on input line 52. LaTeX Font Info: External font `lmex10' loaded for size (Font) <6> on input line 52. LaTeX Font Info: Trying to load font information for T1+lmss on input line 52. (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/lm/t1lmss.fd File: t1lmss.fd 2015/05/01 v1.6.1 Font defs for Latin Modern ) Package hyperref Info: Link coloring ON on input line 52. (./jss.out) (./jss.out) \@outlinefile=\write5 \openout5 = `jss.out'. Package xcolor Warning: Incompatible color definition on input line 58. Package xcolor Warning: Incompatible color definition on input line 58. LaTeX Font Info: Trying to load font information for T1+lmtt on input line 61. (/Users/hadleywickham/Library/TinyTeX/texmf-dist/tex/latex/lm/t1lmtt.fd File: t1lmtt.fd 2015/05/01 v1.6.1 Font defs for Latin Modern ) (./jss.bbl Package xcolor Warning: Incompatible color definition on input line 16. ) Package xcolor Warning: Incompatible color definition on input line 74. Package xcolor Warning: Incompatible color definition on input line 74. Underfull \hbox (badness 10000) in paragraph at lines 74--74 [] [1 {/Users/hadleywickham/Library/TinyTeX/texmf-var/fonts/map/pdftex/updmap/pdftex.map}{/Users/hadleywickham/Library/TinyTeX/texmf-dist/fonts/enc/dvips/lm/lm-ec.enc}] (./jss.aux) *********** LaTeX2e <2023-11-01> patch level 1 L3 programming layer <2024-03-14> *********** Package rerunfilecheck Info: File `jss.out' has not changed. (rerunfilecheck) Checksum: 5FF821BA1F3AA30244DA7AE0E9463E9F;118. ) Here is how much of TeX's memory you used: 20665 strings out of 476064 395066 string characters out of 5791905 1933493 words of memory out of 5000000 42409 multiletter control sequences out of 15000+600000 606305 words of font info for 62 fonts, out of 8000000 for 9000 14 hyphenation exceptions out of 8191 99i,9n,107p,456b,432s stack positions out of 10000i,1000n,20000p,200000b,200000s </Users/hadleywickham/Library/TinyTeX/texmf-dist/fonts/type1/public/lm/lmbx10.pfb></Users/hadleywickham/Library/TinyTeX/texmf-dist/fonts/type1/public/lm/lmbx12.pfb></Users/hadleywickham/Library/TinyTeX/texmf-dist/fonts/type1/public/lm/lmr10.pfb></Users/hadleywickham/Library/TinyTeX/texmf-dist/fonts/type1/public/lm/lmri10.pfb></Users/hadleywickham/Library/TinyTeX/texmf-dist/fonts/type1/public/lm/lmss10.pfb></Users/hadleywickham/Library/TinyTeX/texmf-dist/fonts/type1/public/lm/lmtt10.pfb></Users/hadleywickham/Library/TinyTeX/texmf-dist/fonts/type1/public/lm/lmtto10.pfb> Output written on jss.pdf (1 page, 160381 bytes). PDF statistics: 64 PDF objects out of 1000 (max. 8388607) 46 compressed objects within 1 object stream 5 named destinations out of 1000 (max. 500000) 21 words of extra memory for PDF output out of 10000 (max. 10000000) �����������������������������������������������������������������������pkgdown/vignettes/test/jss.cls����������������������������������������������������������������������0000644�0001762�0000144�00000036074�13632757251�016241� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������%% %% This is file `jss.cls', %% generated with the docstrip utility. %% %% The original source files were: %% %% jss.dtx (with options: `class') %% %% IMPORTANT NOTICE: %% %% For the copyright see the source file. %% %% Any modified versions of this file must be renamed %% with new filenames distinct from jss.cls. %% %% For distribution of the original source see the terms %% for copying and modification in the file jss.dtx. %% %% This generated file may be distributed as long as the %% original source files, as listed above, are part of the %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) \def\fileversion{3.0} \def\filename{jss} \def\filedate{2015/09/01} %% %% Package `jss' to use with LaTeX2e for JSS publications (http://www.jstatsoft.org/) %% License: GPL-2 | GPL-3 %% Copyright: (C) Achim Zeileis %% Please report errors to Achim.Zeileis@R-project.org %% \NeedsTeXFormat{LaTeX2e} \ProvidesClass{jss}[\filedate\space\fileversion\space jss class by Achim Zeileis] %% options \newif\if@article \newif\if@codesnippet \newif\if@bookreview \newif\if@softwarereview \newif\if@review \newif\if@shortnames \newif\if@nojss \newif\if@notitle \newif\if@noheadings \newif\if@nofooter \@articletrue \@codesnippetfalse \@bookreviewfalse \@softwarereviewfalse \@reviewfalse \@shortnamesfalse \@nojssfalse \@notitlefalse \@noheadingsfalse \@nofooterfalse \DeclareOption{article}{\@articletrue% \@codesnippetfalse \@bookreviewfalse \@softwarereviewfalse} \DeclareOption{codesnippet}{\@articlefalse% \@codesnippettrue \@bookreviewfalse \@softwarereviewfalse} \DeclareOption{bookreview}{\@articlefalse% \@codesnippetfalse \@bookreviewtrue \@softwarereviewfalse} \DeclareOption{softwarereview}{\@articlefalse% \@codesnippetfalse \@bookreviewfalse \@softwarereviewtrue} \DeclareOption{shortnames}{\@shortnamestrue} \DeclareOption{nojss}{\@nojsstrue} \DeclareOption{notitle}{\@notitletrue} \DeclareOption{noheadings}{\@noheadingstrue} \DeclareOption{nofooter}{\@nofootertrue} \ProcessOptions \LoadClass[11pt,a4paper,twoside]{article} %% required packages \RequirePackage{graphicx,color,ae,fancyvrb} \RequirePackage[T1]{fontenc} \IfFileExists{upquote.sty}{\RequirePackage{upquote}}{} %% bibliography \if@shortnames \usepackage[authoryear,round]{natbib} \else \usepackage[authoryear,round,longnamesfirst]{natbib} \fi \bibpunct{(}{)}{;}{a}{}{,} \bibliographystyle{jss} %% page layout \topmargin 0pt \textheight 46\baselineskip \advance\textheight by \topskip \oddsidemargin 0.1in \evensidemargin 0.15in \marginparwidth 1in \oddsidemargin 0.125in \evensidemargin 0.125in \marginparwidth 0.75in \textwidth 6.125in %% paragraphs \setlength{\parskip}{0.7ex plus0.1ex minus0.1ex} \setlength{\parindent}{0em} %% for all publications \newcommand{\Address}[1]{\def\@Address{#1}} \newcommand{\Plaintitle}[1]{\def\@Plaintitle{#1}} \newcommand{\Shorttitle}[1]{\def\@Shorttitle{#1}} \newcommand{\Plainauthor}[1]{\def\@Plainauthor{#1}} \newcommand{\Volume}[1]{\def\@Volume{#1}} \newcommand{\Year}[1]{\def\@Year{#1}} \newcommand{\Month}[1]{\def\@Month{#1}} \newcommand{\Issue}[1]{\def\@Issue{#1}} \newcommand{\Submitdate}[1]{\def\@Submitdate{#1}} %% for articles and code snippets \newcommand{\Acceptdate}[1]{\def\@Acceptdate{#1}} \newcommand{\Abstract}[1]{\def\@Abstract{#1}} \newcommand{\Keywords}[1]{\def\@Keywords{#1}} \newcommand{\Plainkeywords}[1]{\def\@Plainkeywords{#1}} %% for book and software reviews \newcommand{\Reviewer}[1]{\def\@Reviewer{#1}} \newcommand{\Booktitle}[1]{\def\@Booktitle{#1}} \newcommand{\Bookauthor}[1]{\def\@Bookauthor{#1}} \newcommand{\Publisher}[1]{\def\@Publisher{#1}} \newcommand{\Pubaddress}[1]{\def\@Pubaddress{#1}} \newcommand{\Pubyear}[1]{\def\@Pubyear{#1}} \newcommand{\ISBN}[1]{\def\@ISBN{#1}} \newcommand{\Pages}[1]{\def\@Pages{#1}} \newcommand{\Price}[1]{\def\@Price{#1}} \newcommand{\Plainreviewer}[1]{\def\@Plainreviewer{#1}} \newcommand{\Softwaretitle}[1]{\def\@Softwaretitle{#1}} \newcommand{\URL}[1]{\def\@URL{#1}} \newcommand{\DOI}[1]{\def\@DOI{#1}} %% for internal use \newcommand{\Seriesname}[1]{\def\@Seriesname{#1}} \newcommand{\Hypersubject}[1]{\def\@Hypersubject{#1}} \newcommand{\Hyperauthor}[1]{\def\@Hyperauthor{#1}} \newcommand{\Footername}[1]{\def\@Footername{#1}} \newcommand{\Firstdate}[1]{\def\@Firstdate{#1}} \newcommand{\Seconddate}[1]{\def\@Seconddate{#1}} \newcommand{\Reviewauthor}[1]{\def\@Reviewauthor{#1}} %% defaults \author{Firstname Lastname\\Affiliation} \title{Title} \Abstract{---!!!---an abstract is required---!!!---} \Plainauthor{\@author} \Volume{VV} \Year{YYYY} \Month{MMMMMM} \Issue{II} \Submitdate{yyyy-mm-dd} \Acceptdate{yyyy-mm-dd} \Address{ Firstname Lastname\\ Affiliation\\ Address, Country\\ E-mail: \email{name@address}\\ URL: \url{http://link/to/webpage/} } \Reviewer{Firstname Lastname\\Affiliation} \Plainreviewer{Firstname Lastname} \Booktitle{Book Title} \Bookauthor{Book Author} \Publisher{Publisher} \Pubaddress{Publisher's Address} \Pubyear{YYY} \ISBN{x-xxxxx-xxx-x} \Pages{xv + 123} \Price{USD 69.95 (P)} \URL{http://link/to/webpage/} \DOI{10.18637/jss.v000.i00} \if@article \Seriesname{Issue} \Hypersubject{Journal of Statistical Software} \Plaintitle{\@title} \Shorttitle{\@title} \Plainkeywords{\@Keywords} \fi \if@codesnippet \Seriesname{Code Snippet} \Hypersubject{Journal of Statistical Software -- Code Snippets} \Plaintitle{\@title} \Shorttitle{\@title} \Plainkeywords{\@Keywords} \fi \if@bookreview \Seriesname{Book Review} \Hypersubject{Journal of Statistical Software -- Book Reviews} \Plaintitle{\@Booktitle} \Shorttitle{\@Booktitle} \Reviewauthor{\@Bookauthor\\ \@Publisher, \@Pubaddress, \@Pubyear.\\ ISBN~\@ISBN. \@Pages~pp. \@Price.\\ \url{\@URL}} \Plainkeywords{} \@reviewtrue \fi \if@softwarereview \Seriesname{Software Review} \Hypersubject{Journal of Statistical Software -- Software Reviews} \Plaintitle{\@Softwaretitle} \Shorttitle{\@Softwaretitle} \Booktitle{\@Softwaretitle} \Reviewauthor{\@Publisher, \@Pubaddress. \@Price.\\ \url{\@URL}} \Plainkeywords{} \@reviewtrue \fi \if@review \Hyperauthor{\@Plainreviewer} \Keywords{} \Footername{Reviewer} \Firstdate{\textit{Published:} \@Submitdate} \Seconddate{} \else \Hyperauthor{\@Plainauthor} \Keywords{---!!!---at least one keyword is required---!!!---} \Footername{Affiliation} \Firstdate{\textit{Submitted:} \@Submitdate} \Seconddate{\textit{Accepted:} \@Acceptdate} \fi %% Sweave(-like) \DefineVerbatimEnvironment{Sinput}{Verbatim}{fontshape=sl} \DefineVerbatimEnvironment{Soutput}{Verbatim}{} \DefineVerbatimEnvironment{Scode}{Verbatim}{fontshape=sl} \newenvironment{Schunk}{}{} \DefineVerbatimEnvironment{Code}{Verbatim}{} \DefineVerbatimEnvironment{CodeInput}{Verbatim}{fontshape=sl} \DefineVerbatimEnvironment{CodeOutput}{Verbatim}{} \newenvironment{CodeChunk}{}{} \setkeys{Gin}{width=0.8\textwidth} %% footer \newlength{\footerskip} \setlength{\footerskip}{2.5\baselineskip plus 2ex minus 0.5ex} \newcommand{\makefooter}{% \vspace{\footerskip} \if@nojss \begin{samepage} \textbf{\large \@Footername: \nopagebreak}\\[.3\baselineskip] \nopagebreak \@Address \nopagebreak \end{samepage} \else \begin{samepage} \textbf{\large \@Footername: \nopagebreak}\\[.3\baselineskip] \nopagebreak \@Address \nopagebreak \vfill \hrule \nopagebreak \vspace{.1\baselineskip} {\fontfamily{pzc} \fontsize{13}{15} \selectfont Journal of Statistical Software} \hfill \url{http://www.jstatsoft.org/}\\ \nopagebreak published by the Foundation for Open Access Statistics \hfill \url{http://www.foastat.org/}\\[.3\baselineskip] \nopagebreak {\@Month{} \@Year, Volume~\@Volume, \@Seriesname~\@Issue} \hfill \@Firstdate\\ \nopagebreak {\href{https://doi.org/\@DOI}{\tt doi:\@DOI}} \hfill \@Seconddate \nopagebreak \vspace{.3\baselineskip} \hrule \end{samepage} \fi } \if@nofooter %% \AtEndDocument{\makefooter} \else \AtEndDocument{\makefooter} \fi %% required packages \RequirePackage{hyperref} %% new \maketitle \def\@myoddhead{ {\color{white} JSS}\\[-1.42cm] \hspace{-2em} \includegraphics[height=23mm,keepaspectratio]{jsslogo} \hfill \parbox[b][23mm]{118mm}{\hrule height 3pt \center{ {\fontfamily{pzc} \fontsize{28}{32} \selectfont Journal of Statistical Software} \vfill {\it \small \@Month{} \@Year, Volume~\@Volume, \@Seriesname~\@Issue.% \hfill \href{https://doi.org/\@DOI}{doi:\,\@DOI}}}\\[0.1cm] \hrule height 3pt}} \if@review \renewcommand{\maketitle}{ \if@nojss %% \@oddhead{\@myoddhead}\\[3\baselineskip] \else \@oddhead{\@myoddhead}\\[3\baselineskip] \fi {\large \noindent Reviewer: \@Reviewer \vspace{\baselineskip} \hrule \vspace{\baselineskip} \textbf{\@Booktitle} \begin{quotation} \noindent \@Reviewauthor \end{quotation} \vspace{0.7\baselineskip} \hrule \vspace{1.3\baselineskip} } \thispagestyle{empty} \if@nojss \markboth{\centerline{\@Shorttitle}}{\centerline{\@Hyperauthor}} \else \markboth{\centerline{\@Shorttitle}}{\centerline{\@Hypersubject}} \fi \pagestyle{myheadings} } \else \def\maketitle{ \if@nojss %% \@oddhead{\@myoddhead} \par \else \@oddhead{\@myoddhead} \par \fi \begingroup \def\thefootnote{\fnsymbol{footnote}} \def\@makefnmark{\hbox to 0pt{$^{\@thefnmark}$\hss}} \long\def\@makefntext##1{\parindent 1em\noindent \hbox to1.8em{\hss $\m@th ^{\@thefnmark}$}##1} \@maketitle \@thanks \endgroup \setcounter{footnote}{0} \if@noheadings %% \markboth{\centerline{\@Shorttitle}}{\centerline{\@Hypersubject}} \else \thispagestyle{empty} \if@nojss \markboth{\centerline{\@Shorttitle}}{\centerline{\@Hyperauthor}} \else \markboth{\centerline{\@Shorttitle}}{\centerline{\@Hypersubject}} \fi \pagestyle{myheadings} \fi \let\maketitle\relax \let\@maketitle\relax \gdef\@thanks{}\gdef\@author{}\gdef\@title{}\let\thanks\relax } \def\@maketitle{\vbox{\hsize\textwidth \linewidth\hsize \if@nojss %% \vskip 1in \else \vskip 1in \fi {\centering {\LARGE\bf \@title\par} \vskip 0.2in plus 1fil minus 0.1in { \def\and{\unskip\enspace{\rm and}\enspace}% \def\And{\end{tabular}\hss \egroup \hskip 1in plus 2fil \hbox to 0pt\bgroup\hss \begin{tabular}[t]{c}\large\bf\rule{\z@}{24pt}\ignorespaces}% \def\AND{\end{tabular}\hss\egroup \hfil\hfil\egroup \vskip 0.1in plus 1fil minus 0.05in \hbox to \linewidth\bgroup\rule{\z@}{10pt} \hfil\hfil \hbox to 0pt\bgroup\hss \begin{tabular}[t]{c}\large\bf\rule{\z@}{24pt}\ignorespaces} \hbox to \linewidth\bgroup\rule{\z@}{10pt} \hfil\hfil \hbox to 0pt\bgroup\hss \begin{tabular}[t]{c}\large\bf\rule{\z@}{24pt}\@author \end{tabular}\hss\egroup \hfil\hfil\egroup} \vskip 0.3in minus 0.1in \hrule \begin{abstract} \@Abstract \end{abstract}} \textit{Keywords}:~\@Keywords. \vskip 0.1in minus 0.05in \hrule \vskip 0.2in minus 0.1in }} \fi %% sections, subsections, and subsubsections \newlength{\preXLskip} \newlength{\preLskip} \newlength{\preMskip} \newlength{\preSskip} \newlength{\postMskip} \newlength{\postSskip} \setlength{\preXLskip}{1.8\baselineskip plus 0.5ex minus 0ex} \setlength{\preLskip}{1.5\baselineskip plus 0.3ex minus 0ex} \setlength{\preMskip}{1\baselineskip plus 0.2ex minus 0ex} \setlength{\preSskip}{.8\baselineskip plus 0.2ex minus 0ex} \setlength{\postMskip}{.5\baselineskip plus 0ex minus 0.1ex} \setlength{\postSskip}{.3\baselineskip plus 0ex minus 0.1ex} \newcommand{\jsssec}[2][default]{\vskip \preXLskip% \pdfbookmark[1]{#1}{Section.\thesection.#1}% \refstepcounter{section}% \centerline{\textbf{\Large \thesection. #2}} \nopagebreak \vskip \postMskip \nopagebreak} \newcommand{\jsssecnn}[1]{\vskip \preXLskip% \centerline{\textbf{\Large #1}} \nopagebreak \vskip \postMskip \nopagebreak} \newcommand{\jsssubsec}[2][default]{\vskip \preMskip% \pdfbookmark[2]{#1}{Subsection.\thesubsection.#1}% \refstepcounter{subsection}% \textbf{\large \thesubsection. #2} \nopagebreak \vskip \postSskip \nopagebreak} \newcommand{\jsssubsecnn}[1]{\vskip \preMskip% \textbf{\large #1} \nopagebreak \vskip \postSskip \nopagebreak} \newcommand{\jsssubsubsec}[2][default]{\vskip \preSskip% \pdfbookmark[3]{#1}{Subsubsection.\thesubsubsection.#1}% \refstepcounter{subsubsection}% {\large \textit{#2}} \nopagebreak \vskip \postSskip \nopagebreak} \newcommand{\jsssubsubsecnn}[1]{\vskip \preSskip% {\textit{\large #1}} \nopagebreak \vskip \postSskip \nopagebreak} \newcommand{\jsssimplesec}[2][default]{\vskip \preLskip% %% \pdfbookmark[1]{#1}{Section.\thesection.#1}% \refstepcounter{section}% \textbf{\large #1} \nopagebreak \vskip \postSskip \nopagebreak} \newcommand{\jsssimplesecnn}[1]{\vskip \preLskip% \textbf{\large #1} \nopagebreak \vskip \postSskip \nopagebreak} \if@review \renewcommand{\section}{\secdef \jsssimplesec \jsssimplesecnn} \renewcommand{\subsection}{\secdef \jsssimplesec \jsssimplesecnn} \renewcommand{\subsubsection}{\secdef \jsssimplesec \jsssimplesecnn} \else \renewcommand{\section}{\secdef \jsssec \jsssecnn} \renewcommand{\subsection}{\secdef \jsssubsec \jsssubsecnn} \renewcommand{\subsubsection}{\secdef \jsssubsubsec \jsssubsubsecnn} \fi %% colors \definecolor{Red}{rgb}{0.5,0,0} \definecolor{Blue}{rgb}{0,0,0.5} \if@review \hypersetup{% hyperindex = {true}, colorlinks = {true}, linktocpage = {true}, plainpages = {false}, linkcolor = {Blue}, citecolor = {Blue}, urlcolor = {Red}, pdfstartview = {Fit}, pdfpagemode = {None}, pdfview = {XYZ null null null} } \else \hypersetup{% hyperindex = {true}, colorlinks = {true}, linktocpage = {true}, plainpages = {false}, linkcolor = {Blue}, citecolor = {Blue}, urlcolor = {Red}, pdfstartview = {Fit}, pdfpagemode = {UseOutlines}, pdfview = {XYZ null null null} } \fi \if@nojss \AtBeginDocument{ \hypersetup{% pdfauthor = {\@Hyperauthor}, pdftitle = {\@Plaintitle}, pdfkeywords = {\@Plainkeywords} } } \else \AtBeginDocument{ \hypersetup{% pdfauthor = {\@Hyperauthor}, pdftitle = {\@Plaintitle}, pdfsubject = {\@Hypersubject}, pdfkeywords = {\@Plainkeywords} } } \fi \if@notitle %% \AtBeginDocument{\maketitle} \else \AtBeginDocument{\maketitle} \fi %% commands \newcommand\code{\bgroup\@makeother\_\@makeother\~\@makeother\$\@codex} \def\@codex#1{{\normalfont\ttfamily\hyphenchar\font=-1 #1}\egroup} %%\let\code=\texttt \let\proglang=\textsf \newcommand{\pkg}[1]{{\fontseries{b}\selectfont #1}} \newcommand{\email}[1]{\href{mailto:#1}{\normalfont\texttt{#1}}} \ifx\csname urlstyle\endcsname\relax \newcommand\@doi[1]{doi:\discretionary{}{}{}#1}\else \newcommand\@doi{doi:\discretionary{}{}{}\begingroup \urlstyle{tt}\Url}\fi \newcommand{\doi}[1]{\href{https://doi.org/#1}{\normalfont\texttt{\@doi{#1}}}} \newcommand{\E}{\mathsf{E}} \newcommand{\VAR}{\mathsf{VAR}} \newcommand{\COV}{\mathsf{COV}} \newcommand{\Prob}{\mathsf{P}} \endinput %% %% End of file `jss.cls'. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/vignettes/test/test.txt���������������������������������������������������������������������0000644�0001762�0000144�00000000010�13370400577�016427� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������a b c d ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/vignettes/test/bacon.jpg��������������������������������������������������������������������0000644�0001762�0000144�00000017523�13370400577�016514� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF�������C�    $.' ",#(7),01444'9=82<.342�C  2!!22222222222222222222222222222222222222222222222222��"����������������6�����!1A"Qaq#2BR4r���������������'��������!1AQ"2a#B� ��?��Zb;CY)mAȮr!u')n,+M˓N7=HGH?3t dܘcQT!.leͯ s>(X~QPN k0\~"_iN'+v '#ANWMF1̚u9%<75.lMq _f`zyX'ΏXs08d[I-'@76$ T]:)n?/XkCi9[ɪי˗{MbF%\ n(3#obkҩ7b * qӟ`7{%Ju&2]+HOJ|1/9H|cF|7jQ}HMS[b `jո"scFE8rg(s`sxdǶ#rW\1=, YQ"Wrce!=\re`.մo tF~. ymgF7-je(MѱFP�bWF{T} Xy>9~,Z_AƽYءǴ1%Yq-.6Mȭɿ]WhAȠ!]_P\S !<Ta�x1c5M2?y4* Չ-#|?p`͔pmu@VNGy1bx=/jMfJ;2Pz\b4sir.2;7߱I�3VA 9%Ӷ4wڟxxÓ!I"yQؤ٣ SoX=E\�l I1v\_<=w~,"Lb}c#-Bf28e"n0rZ�wl�pf|JCas;(n��7KcVٍ$//6;{ɐ2%ݠBNhkQw)0H$OhFdSJQV LhHcY@=a،{ e&O26q�|PL`\lN�6A2QJm- o2e-VѴfjk7'rNPwdx�Zv{^%Aj6@';Ȣe%�Q_}~^|K寬ı�V{tA۝WqG<W� 4U=I㬶6rGglnqdֱ!TOU"@$<:ؕ 6 ˕ATDʮEsqvJ vQq l 28C} okιP2rǴȌ& q+R|<-oUyƥб$#'#P"DC"Kda,OфdKX[Opc_!;_g'qcVF#'"Q}ٜvBrBӉUb(=*PwRׁ) {#|TFc&r-7RMDԖ(eFt(�d>ĥnzCs]gSw,-8 _HIͻ%i& (B*sl% 1BjX@D$)A!7?Abh?xpnQ8~"ЖnDkMf/UBi yGT6@CzzKMꖴЖ9ʜb7\q\N %L(7ߴ„`lt"(6,@|g*o2>[E]54=@ O ud(!:c0ՎSW8IPk&Ua Yӥ.<Qk5XDC96Wp%bI5qs<u]F@.NKp|p&Q�!:uvA(~ =ɿ9uEəFWKsI(aw7$~;1ml-qʮ 6A5e U^H9?qv)!@^vmw, عFḃNv^TwY?rq`$Qݑ}@2p>'F2l ׵~JyVodF.�11_~y`sEX#d;aya@w3P (ve b21 nT5CMpWsEIui`ǎ" X7@_hVACalIK)`)#]HlVԅض�I T%Igr5~4rqGA!2dja"=qܧ;is>@:Qk X.Ҽ vY&nqtaٙ M 8VtDlQGA FBi#j#:ed�IZ#̩b\'d\M %{>cR|d��KCBY{1(=²/J=z[ ט8G>W+=TFWۍQ-@}@=u�"Ws4D>a~ӣ!'|]3e {JL1<$QwVb|�wr/&y<'̓YH�Uo3,]wFh {ijy�g0)݉+mQ/Cc}0beo#Gf@@Ks #"SHJg?uLDٸĵڧ2s3W7k \F0rvz!C8G?xm7!aE7[UCǯ+ YnCd#ك/u|G]~j5bjX_1LdaHxnqo 7+Fk5elYqoQL#.^yԎ_4R*0婢>X3*Vs1n3�Hkox8SKƽo)LR0kX{'<A,MpY\#"Ï!__w*l8.|˩JK 湝TO#UsUA^҇ɏr,8"�2_<`sUiV@B܈\9UI[ 9|^?| /S4}FLxCv M0o3m##R?<YB4YQ<@v@/(6)|#1VCa +uᅫg  6щA,lJik91Fh.2p`E|$VNЂAF2 &zP ?cz+9.#;2%L+Y�k)_q}_;f{ƈMZyn{\4ÓhQQz@z[pݣLr55RnV-yL@@�}i} y�bŐ6@f+G*=sVht_hV[l0g1 p,s@ϝ\9Mwt، K$]$N2\ g2 vٽ0OOHw2T,]]4&Ʌ2׍ yU]OU$ɪǙղ�V gQ{E~*21U*׆O [>%rhi)EIY#3Qޠij,ؓQbC~`fMn>[-$ ش ׂF8K/S_Se('ryMPlōi | ,(!S|#\nBWIa杊B2 ᚜`GpDg܌A=�|xQlw%\3/˒0ҟry0VV@4&[Žm/rH ӷ{AG#>fbIf_f7*P^4Ŧ9�uHsc${?]V�Dk ȍQ%V${TC-Xz_Vgh\7'O1~҅E8WG|�xfZ$Ok-{^^?8{j vpG&63Ug"R{ Eq0׸G8[zh6wIoU0\ziiZ~F �a]BJxB R ׷5> й5N񻳳:s+SMTgfP܌F ,P=#v c>^GN`ݲ6zE.?7 'ddo_<7yM=46]�6bm;)7WJܤ"fɺ.i`I7V{7'q0#NluS?LYo�O0˨τ>Y%5 p d\l'/ܪ`D=bgɽi1(x6c$]i[ٕamC|?k<NەiY@+fw̬7[$q2Lfųib˪νˏ*N3B߈aС 5D`k17*J W1T7YSy+dԚO3iZ3wrQ`~6t(3m&+%~,�0'ul3e)M!l[7$<kix!wV3< @kSoSs'مaf?T:CKQ9$qxVj1gQفǕ??TO&}ڦVɝhKިHE�~社=yEsW+6<'ӗ":+SȹEPɌ023?* oyOQ{9pd0 jњ&j9FdrO`qNo`T4eR4 MYjGpNM;+;\&d5SY!?xQOyi*@* }oW +foޓ=8!8[RI<Lm/9qɌN&*D?Lff58Յץ1P,00Kԋ*;AdvzxF,~>_OVƹ6$!6*~AT{S+r).F2Diѿp-dʶbX7tfj|sSE:ؘNP�ɑǤy<5-q}ߑJ/Y$Jμow<cד0;QDiou$wK5>t]oͣ*"72AF zX"qccP~HS$G<̯dAdV2Q�G6>�3i-M3oPxOftɭ}Բ*n1BvMT>ϣ&UVk*Ȇ'�^,Lo":o,X9ȧ%PkD#> IjWrIӍh|zd$hmSJ`DRhUMbIM>e?,y%:*92Ry0|YRڧr`(=BKsEo<-X=}GWX(0<wz<H؉h;ceu_2 |[Pm n">HffHmJiV}cKCpڧ�cSDMJmC8\2$ ׷�0g޴)uUM�M(FôE}%WMؠI*5j:>P`رP})*@׉_4ڌb}jzf̛;}K'ڻx`ʎi~L-Y2Or紓?gɳӳoC Y۸0b-VmQ?8n P}}>9QQZpءނǴ7$H?N!W&˭}<375p0ce-"bߏh]Ḁ= [ʾX:u̔/i~)o"-4C ʼntۡe?Iec|E~RtVev/5';%rL:jjH&о UsG0ȔH6}7 jRBR9tiVHA;O"3i$QL"i0�^k"!0<r="Zd8'D Bk2Yv+\6=e"MuQkHddȼ F6#|xPKlw˩|zԀsɖ܀ƥꆒn O np67̡D= <Yt2 .0􋀵aKa~c:t8؞Z:P4kRd'N;�y?ɳܩP~Ү潄yIcp ьOcNeԑ̢\d$|� X=EY].Wd\ bHj+ӓpd-Wg7?XPaBC8Xp%*'X6:|IcX[>;"$hBU_S9m6LJ&חgofaiHdZ=:i[ ܚ\Nqh^=ِzT6xv'z~1 l|8ѩ<A%\8|$ >_5@�,Əd[F v~)}Zs2?[O*/LᇥIi:U@n}#6ݢɖ(yɈ깩,G7,w^=�}Ku q]cHjH<;uKǪpH4$ʮG 8mF$k yvL\ 0XB[{Ɲ^-p:H#l{̢̓Ŋ*E?[8{l?n wھT<I (Fͧ4|WL>;ɸ]W P>̇I9L,W*iO@8r)!pcY?'W(* ?x@.|E㺍&UMQIL_qw7/3i<OVcEV]X%OT2_E4{9OiGAl y�(\_�t5ğZԷ3'F5F_#SOx6%G'čX +qVṷS;N:b_)'~�pzw"'5H5{JLū5apcAxVh"ٵ y<aM&њSNҢ폾[!<ˢ$шW!C (ܖ:|lqq$Ok:vմ,)AI$z.xw&,j$n*la%H4d Pɗ);{J)ȼlI.%. +'1yIZrI-0EoGiԽv$!yղ�َ?EY'I$~._  xq[!eӎI$J)S7.3*5$fA1$8E91 G& aF:g'<[M"HM˛huuK{I$<Ñ}IQ�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/vignettes/test/long-toc.Rmd�����������������������������������������������������������������0000644�0001762�0000144�00000000621�14132370657�017107� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- title: "Long TOC" --- ```{r include = FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` This vignette tests has a very long TOC. You should be able to navigate to a heading near the bottom of the doc without having to scroll all the way down. ```{r, echo = FALSE} h2 <- paste0("## Heading ", t(outer(letters, 1:9, paste0))) knitr::asis_output(paste(h2, collapse = "\n\n")) ``` ���������������������������������������������������������������������������������������������������������������pkgdown/vignettes/test/jss.bib����������������������������������������������������������������������0000644�0001762�0000144�00000000412�13370400577�016172� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@article{JSSv059i10, author = {Hadley Wickham}, title = {Tidy Data}, journal = {Journal of Statistical Software, Articles}, volume = {59}, number = {10}, year = {2014}, issn = {1548-7660}, pages = {1--23}, doi = {10.18637/jss.v059.i10} } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/vignettes/test/jss.Rmd����������������������������������������������������������������������0000644�0001762�0000144�00000001335�13731761074�016170� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- author: - name: FirstName LastName affiliation: University/Company address: > First line Second line email: \email{name@company.com} url: https://rstudio.com - name: Second Author affiliation: Affiliation title: plain: "JSS article" formatted: "JSS article" short: "JSS article" pagetitle: "JSS article" abstract: > The abstract of the article. keywords: plain: [keywords, not capitalized, Java] formatted: [keywords, not capitalized, "\\proglang{Java}"] output: rticles::jss_article documentclass: jss classoption: nojss bibliography: jss.bib pkgdown: as_is: true extension: pdf --- # Introduction Some text and a reference [@JSSv059i10]. ```{r} 1 + 2 ``` ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/vignettes/test/quarto-features.qmd����������������������������������������������������������0000644�0001762�0000144�00000002002�14634573316�020552� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- title: quarto features knitr: opts_chunk: collapse: true comment: '#>' bibliography: jss.bib --- ## Citations * Citation: @JSSv059i10 ## Code annotations ```r library(tidyverse) library(palmerpenguins) penguins |> # <1> mutate( # <2> bill_ratio = bill_depth_mm / bill_length_mm, # <2> bill_area = bill_depth_mm * bill_length_mm # <2> ) # <2> ``` 1. Take `penguins`, and then, 2. add new columns for the bill ratio and bill area. ## Diagrams ```{mermaid} flowchart LR A[Hard edge] --> B(Round edge) B --> C{Decision} C --> D[Result one] C --> E[Result two] ``` ## HTML widgets ```{r, echo=FALSE} dir <- tempdir() path1 <- file.path(dir, "a.txt") writeLines(letters, path1) path2 <- file.path(dir, "b.txt") writeLines(letters[-(10:11)], path2) diffviewer::visual_diff(path1, path2) ``` ## Keyboard * Keyboard shortcut: {{< kbd Shift-Ctrl-P >}} ## References ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/vignettes/test/rendering.Rmd����������������������������������������������������������������0000644�0001762�0000144�00000005176�14633374223�017353� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- title: "Output Rendering" subtitle: "Subtitle is skipped from the TOC" author: "Author is skipped from the TOC" date: "Date is skipped from the TOC" --- ```{r} #| include: FALSE knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` This vignette tests pkgdown output rendering for several use cases. ## Footnotes Yay[^footnote] [^footnote]: Including **footnotes**! 😁 ## Figures ```{r} #| fig.alt: Test plot plot(1:10) ``` ## External files ```{r} x <- readLines("test.txt") x ``` ![bacon](bacon.jpg) ## Details tag <details> This should only be shown when required </details> <details> <summary>Multiple paragraphs</summary> First paragraph Second paragraph </details> <details> <summary>Some R code</summary> ```{r} 1 + 2 ``` </details> ## Tables | col 1 | col 2 | col 3 | col 4 | |:---------------|:-----------|:-------:|:---------:| | Brightness | Total brightness, total reflectance, spectral intensity | $$y = x^2$$ | test | ## Math $$f(x) = \dfrac{1}{\sqrt{2\pi\sigma^2}} e^{-\frac{(x-\mu^2)}{2\sigma^2}}$$ Inline equations: $y=x^2$ ## Code ### Line width ```{r} pkgdown:::ruler() cat(rep("x ", 100), sep = "") cat(rep("xy", 100), sep = "") ``` ### Should be highlighted Valid R code in `\preformatted{}`: ``` mean(a + 1) ``` R code in `R` block: ```R mean(a + 1) ``` R code in `r` block: ```R mean(a + 1) ``` Yaml ```yaml yaml: [a, 1] ``` ### Shouldn't be highlighted Non-R code in `\preformatted{}` ``` yaml: [a, b, c] ``` ### Crayon ```{r} cat(cli::col_red("This is red"), "\n") cat(cli::col_blue("This is blue\n"), "\n") message(cli::col_green("This is green")) warning(cli::style_bold("This is bold")) ``` Some text ```{r} #| error: TRUE stop(cli::style_italic("This is italic")) ``` Some more text ## Quoted text > Single-line quote about something miscellaneous. | Flush | 1 space indent | 2 space indent | 3 space indent ## This section is unnumbered {-} There should however be no bug here! ## Tabsets ### Tabset with pills {.tabset .tabset-pills} #### Tab 1 blablablabla ```r 1 + 1 ``` Should be "cool" heading below ##### cool Stuff #### Tab 2 blop ### Tabset without pills {.tabset} #### Tab 1 something nice ```{r} #| fig.alt: Another test plot plot(1:42) ``` #### Tab 2 {.active} This tab should be active ### Fading tabset {.tabset .tabset-fade} #### English Hello! #### French Bonjour! #### German Guten tag. ## Deep headings ### Heading 3 #### Heading 4 ##### Heading 5 ## Very long words This word should be broken across multiple lines on mobile, rather than making the page scroll horizontally: Ccccccccccccaaaaaaaaaaaaaaatttttttttttttttttssssssssssssssss ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/vignettes/quarto.qmd������������������������������������������������������������������������0000644�0001762�0000144�00000006625�14671042466�015774� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- title: quarto vignettes description: > Learn how quarto vignettes work with pkgdown, including currently supported features and known limitations. vignette: > %\VignetteIndexEntry{quarto vignettes} %\VignetteEngine{quarto::html} %\VignetteEncoding{UTF-8} knitr: opts_chunk: collapse: true comment: '#>' --- pkgdown effectively uses quarto only to generate HTML and then supplies its own CSS and JS. This means that when quarto introduces new features, pkgdown may lag behind in their support. If you're trying out something that doesn't work (and isn't mentioned explicitly below), please [file an issue](https://github.com/r-lib/pkgdown/issues) so we can look into it. ## Operation pkgdown turns your articles directory into a quarto project by temporarily adding a `_quarto.yml` to your articles. You can also add your own if you want to control options for all quarto articles. If you do so, and you have a mix of `.qmd` and `.Rmd` files, you'll need to include the following yaml so that RMarkdown can continue to handle the .Rmd files: ```yaml project: render: ['*.qmd'] ``` ### GitHub Actions The `setup-r-dependencies` action will [automatically](https://github.com/r-lib/actions/tree/v2-branch/setup-r-dependencies#usage) install Quarto in your GitHub Actions if a .qmd file is present in your repository (see the `install-quarto` parameter for more details). ## Limitations * Callouts are not currently supported (<https://github.com/quarto-dev/quarto-cli/issues/9963>). * pkgdown assumes that you're using [quarto vignette style](https://quarto-dev.github.io/quarto-r/articles/hello.html), or more generally an html format with [`minimal: true`](https://quarto.org/docs/output-formats/html-basics.html#minimal-html). Specifically, only HTML vignettes are currently supported. * You can't customise mermaid styles with quarto mermaid themes. If you want to change the colours, you'll need to provide your own custom CSS as shown in [the quarto docs](https://quarto.org/docs/authoring/diagrams.html#customizing-mermaid). * pkgdown will pass the `lang` setting on to quarto, but the set of available language is not perfectly matched. Learn more in <https://quarto.org/docs/authoring/language.html>, including how to supply your own translations. ## Supported features The following sections demonstrate a bunch of useful quarto features so that we can make sure that they work. ### Inline formatting * [Small caps]{.smallcaps} * Here is a footnote reference[^1] [^1]: And here is the footnote. ### Code ```{r} #| fig.alt: A plot of the numbers 1, 2, and 3 1 + 1 2 + 2 plot(1:3) ``` ### Figures ::: {#fig-puppies layout-ncol=2} ![A sketch of a pitbull puppy](pitbull.jpg){#fig-pitbull} ![A sketch of a sharpei puppy](shar-pei.jpg){#fig-shar-pei} Cute puppies ::: ### Equations $$ \frac{\partial \mathrm C}{ \partial \mathrm t } + \frac{1}{2}\sigma^{2} \mathrm S^{2} \frac{\partial^{2} \mathrm C}{\partial \mathrm C^2} + \mathrm r \mathrm S \frac{\partial \mathrm C}{\partial \mathrm S}\ = \mathrm r \mathrm C $$ {#eq-black-scholes} ### Cross references See @fig-puppies for two cute puppies. Black-Scholes (@eq-black-scholes) is a mathematical model that seeks to explain the behavior of financial derivatives, most commonly options. ## To do * [ ] Code annotations * [ ] Tabsets * [x] Citations * [x] Task/to do lists * [x] Figures * [x] Equations * [x] Cross-references * [x] Footnotes * [x] Callouts �����������������������������������������������������������������������������������������������������������pkgdown/vignettes/metadata.Rmd����������������������������������������������������������������������0000644�0001762�0000144�00000012355�14672347347�016206� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- title: "Metadata" description: > Customise metadata and social media cards for pkgdown websites. output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Metadata} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` Package authors can customize the metadata used by Twitter and the [Open Graph protocol][ogp] for rich social media cards. In addition to specifying an alternate description for the package and any individual articles, you may also choose the preview image shown and the style of the card used on Twitter. You can preview and validate the appearance of the social media cards with online tools: * [Google Rich Results Test][ogp-validator] * Drafting a tweet to yourself * Sending yourself a Slack message ## Necessary configuration Metadata can only be produced correctly if your pkgdown website URL is indicated in its configuration file. ```yaml url: https://example.com ``` ## Site-wide customization Metadata for the entire pkgdown website can be specified in the site's `_pkgdown.yml` configuration file in the `home` and `template: opengraph` sections: ```yaml home: title: An R package for pool-noodle discovery description: Discover and add pool-noodles to your growing collection. template: opengraph: image: src: man/figures/card.png alt: "Pool noodles configured to form the word poolnoodlr" twitter: creator: "@hadleywickham" site: "@rstudio" card: summary_large_image ``` The `home: title` and `home: description` fields override the `Title` and `Description` fields in the package `DESCRIPTION`. It's good practice to set these fields to make your package documentation easier to find via search, rather than sticking with the title and description needed by CRAN. The `template: opengraph` section allows you to further customize the social media card. * `image`: By default, pkgdown uses the package's logo for the card image (if one exists). Use `image` to specify an alternative image for the social media cards of pages in your pkgdown site. * `src`: A fully qualified URL to a media card image e.g. `src: https://avatars.githubusercontent.com/u/22618716?v=4`; or a relative path to an image in the rendered website e.g. `src: articles/test/image.jpg`; or a relative path to an image stored in `man/figures` in the package e.g. `src: man/figures/cards.png`. The `src` field is required if `image` is specified. * `alt`: Alternative text describing the image for screen readers and other situations where your social media card image cannot be displayed. * `twitter`: You can specify the Twitter accounts associated with your package and the [style of social media card][twitter-card] that Twitter will display. * `creator`: Typically, the Twitter handle of the author of the package or article. * `site`: The Twitter handle of the organization affiliated with the package author or sponsoring the package development. * If only one of either `creator` or `site` is included, the provided value will be used for both fields. * `card`: The [style of social media card][twitter-card] that Twitter will display. For pkgdown sites, the most relevant options are `summary_large_image`, featuring a large image over the page title and description, or `summary`, featuring a small square image inline and to the left of the page title and description. ## Article metadata Articles and vignettes rendered as articles by pkgdown can have individually customized metadata and social media cards. ```yaml title: "Introduction to poolnoodlr" description: "A brief introduction to pool noodles in R." author: "Mara Averick" opengraph: image: src: "https://example.com/pkg/batpig.png" twitter: card: summary creator: "@dataandme" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Introduction to poolnoodlr} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} ``` Use the `title`, `description`, and `author` fields to specify the title, description, and (optional) author of the vignette or article. * The `title` field is used as the title of your article in your pkgdown site and should always be included. * Both `title` and `description` are used by pkgdown for the page's social media card. If `description` is not included in the article's YAML front matter, then the name of the package is used instead. The `description` is also displayed on the articles index. - The `author` field is only used in the text of the vignette or article. How the author name is displayed depends on the `output` format. In articles, the `opengraph` section works in the same way as the site-wide `template: opengraph` settings, but is only applied to the article or vignette. This allows you to specify social media card preview images for individual articles, or to associate an article with a particular Twitter account. If not specified, the `opengraph` settings from the site-wide configuration are used. [ogp]: https://ogp.me/ [ogp-validator]: https://search.google.com/test/rich-results [twitter-card]: https://developer.x.com/en/docs/x-for-websites/cards/overview/abouts-cards �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/vignettes/accessibility.Rmd�����������������������������������������������������������������0000644�0001762�0000144�00000004214�14633374223�017236� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- title: "Accessibility" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Accessibility} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` pkgdown automates as many accessibility details as possible, so that your package website is readable by as many people as possible. This vignette describes the additional details that can't be automated away and you need to be aware of. ```{r setup} library(pkgdown) ``` ## Theming * If you adjust any colours from the default theme (including the syntax highlighting theme), you should double check that the contrast between the background and foreground doesn't make any text difficult to read. A good place to start is running a representative page of your site through <https://wave.webaim.org>. * The default colour of the development version label makes a slightly too low contrast against the pale grey background of the navbar. This colour comes from the bootstrap "danger" colour, so you can fix it by overriding that variable in your `_pkgdown.yml`: ```yaml template: bootstrap: 5 bslib: danger: "#A6081A" ``` * If you use custom navbar entries that only display an icon, make sure to also use the `aria-label` field to provide an accessible label that describes the icon. ```yaml cran: icon: fab fa-r-project href: https://cloud.r-project.org/package=pkgdown aria-label: View on CRAN ``` ## Images To make your site fully accessible, the place where you are likely to need to do the most work is adding alternative text to any images that you create. Unfortunately, there's currently no way to do this for plots you generate in examples, but you can and should add alternative text to plots in vignettes using the `fig.alt` chunk option: ````{verbatim} ```{r} #| fig.alt: > #| Histogram of time between eruptions for Old Faithful. #| It is a bimodal distribution with peaks at 50-55 and #| 80-90 minutes. hist(faithful$waiting) ``` ```` If you forget to add alt text to your vignettes, pkgdown will automatically remind you. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/vignettes/customise.Rmd���������������������������������������������������������������������0000644�0001762�0000144�00000052126�14671042466�016432� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- title: "Customise your site" output: rmarkdown::html_vignette description: > Learn how to change the look and feel of your pkgdown site. vignette: > %\VignetteIndexEntry{Customise your site} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` This vignette teaches you how to customise the style/design of your pkgdown site. We'll start by discussing two techniques that only require tweaks to your `_pkgdown.yml`: theming (colours and fonts) and layout (content of the navbar, sidebar, footer, ...). We'll then discuss how to add additional HTML and other files. Next, we'll discuss how to give multiple sites the same style using a package, then finish up with some workflow advice. In terms of your `_pkgdown.yml`, this vignette focusses on the most important fields nested under `template` and `navbar`. To learn more about customising other aspects of the site, see the documentation for the indiviudal functions like `build_reference()`, `build_articles()`, `build_home()`, `build_redirects()`, and `init_site()`. To learn about less important fields nested under `template`, see `build_site()`. ```{r setup} library(pkgdown) ``` ## Getting started Most theming features work only with Bootstrap 5, so first update your site by adding the following lines to your `_pkgdown.yml`: ``` yaml template: bootstrap: 5 ``` Overall, the site should look pretty similar, but you will notice a number of small improvements. Most importantly, the default font is much bigger, making it considerably easier to read. Upgrading to Bootstrap 5 has a low chance of breaking your site unless you were using your [own pkgdown templates](#template-packages) or custom CSS. ## Theming There are two ways to change the visual style of your site from `_pkgdown.yml`: using a pre-packaged bootswatch theme or customising theme variables with [bslib](https://rstudio.github.io/bslib/). The following sections show you how. Please note that pkgdown's default theme has been carefully optimised to be accessible, so if you make changes, make sure to also read `vignette("accessibility")` to learn about potential accessibility pitfalls. ### Light switch {#light-switch} You can provide a "light switch" to allow your users to switch between dark and light themes by setting the `light-switch` template option to true: ```yaml template: light-switch: true ``` This will add a `lightswitch` component to the navbar, which by default appears at the far right. This allows the user to select light mode, dark mode, or auto mode (which follows the system setting). The modes are applied using Bootstrap 5.3's [colours modes](https://getbootstrap.com/docs/5.3/customize/color-modes/) so are not separate themes, but a thin layer of colour customisation applied via CSS. ### Bootswatch themes The easiest way to change the entire appearance of your website is to use a [Bootswatch theme](https://bootswatch.com): ``` yaml template: bootstrap: 5 bootswatch: materia ``` (Themes are unlikely to work with the light switch, but you can try it and see.) Changing the bootswatch theme affects both the HTML (via the navbar, more on that below) and the CSS, so you'll need to re-build your complete site with `build_site()` to fully appreciate the changes. While you're experimenting, you can speed things up by just rebuilding the home page and the CSS by running `build_home_index()`; `init_site()` (and then refreshing the browser). Bootswatch templates with tall navbars (e.g. lux, pulse) also require that you set the `pkgdown-nav-height` bslib variable. Because Bootswatch themes are provided by the [bslib](https://rstudio.github.io/bslib/) R package, you can also nest the `bootswatch` field under the `bslib` field. ``` yaml template: bootstrap: 5 bslib: bootswatch: lux pkgdown-nav-height: 100px ``` You can find the correct height by running `$(".navbar").outerHeight()` in the [javascript console](https://firefox-source-docs.mozilla.org/devtools-user/web_console/index.html). ### bslib variables Instead of picking a complete theme, you can tweak fonts and colours individually using bslib variables. [bslib](https://rstudio.github.io/bslib/) is an R package that wraps sass, the tool that Boostrap uses to produce CSS from a special language called [scss](https://sass-lang.com). The primary advantage of scss over CSS is that it's more programmable, so you can have a few key bslib variables that affect appearance of many HTML elements. There are three key variables that affect the colour: - `bg` (background) determines the page background. - `fg` (foreground) determines the text colour. `bg` and `fg` are mixed to yield `gray-100`, `gray-200`, ..., `grey-900`, which are used to style other elements to match the overall colour scheme. - `primary` sets the link colour and the (translucent) hover colour in the navbar and sidebar. ``` yaml template: bootstrap: 5 bslib: bg: "#202123" fg: "#B8BCC2" primary: "#306cc9" ``` You can customise other components by setting more specific bslib variables, taking advantage of inheritance where possible. For example, `table-border-color` defaults to `border-color` which defaults to `gray-300`. If you want to change the colour of all borders, you can set `border-color` and if you just want to change the colour of table borders, you can set `table-border-color`. You can find a full list of variables in the [bslib docs](https://rstudio.github.io/bslib/articles/bs5-variables/index.html). If you're using the light switch, [many colours](https://getbootstrap.com/docs/5.3/customize/color-modes/#sass-variables) are available for customisation specifically for the dark theme. Theming with bslib is powered by `bslib::bs_theme()` and the `bslib` field is a direct translation of the arguments to that function. As a result, you can fully specify a bslib theme using the `template.bslib` field, making it easy to share YAML with the `output.html_document.theme` field [of an R Markdown document](https://rstudio.github.io/bslib/articles/theming/index.html). ``` yaml template: bslib: version: 5 bg: "#202123" fg: "#B8BCC2" primary: "#306cc9" ``` While iterating on colours and other variables you only need to rerun `init_site()` and refresh your browser to see the changes. ### Fonts You can also override the default fonts used for the majority of the text (`base_font`), for headings (`heading_font`) and for code (`code_font`). The easiest way is to supply the name of a [Google font](https://fonts.google.com) with the following syntax: ``` yaml template: bootstrap: 5 bslib: base_font: {google: "Roboto"} heading_font: {google: "Roboto Slab"} code_font: {google: "JetBrains Mono"} ``` If you want to use a non-Google font, you'll need to do a bit more work. There are two steps: you need to first configure the font with CSS and then use it in your `_pkgdown.yml`. There are two ways you might get the CSS: * As a block of CSS which you should put in `pkgdown/extra.scss` or `pkgdown/extra.css`. The CSS will look something like this: ```css @font-face { font-family: "proxima-nova"; src: local("Proxima Nova Regular"), local("ProximaNova-Regular"), url("https://example.com/ProximaNova-Regular.eot?#iefix") format("embedded-opentype"), url("https://example.com/fonts/proxima/ProximaNova-Regular.woff2") format("woff2"), url("https://example.com/fonts/proxima/ProximaNova-Regular.woff") format("woff"), url("https://example.com/fonts/proxima/ProximaNova-Regular.ttf") format("truetype"); font-weight: normal; font-style: normal; font-display: fallback; } ``` * As a link to a style file, which you'll need to add to the `<head>` using this syntax: ```yaml template: includes: in_header: <link rel="stylesheet" type="text/css" href="https://..." /> ``` Then in `_pkgdown.yml` you can use the name of the font you just specified: ```yaml template: bslib: base_font: proxima-nova ``` Depending on where the font is from (and if you purchased it), you may need to take additional steps to ensure that it can only be used from your site, and/or make sure that it can still be used when you're previewing locally. If you're having problems getting a custom font to work, looking for errors in the [browser developer console](https://developer.mozilla.org/en-US/docs/Glossary/Developer_Tools) is a good place to start. When iterating on fonts, you'll need to run `build_home_index(); init_site()` then refresh your browser to see the update. ### Syntax highlighting The colours used for syntax highlighting in code blocks are controlled by the `theme` setting: ``` yaml template: bootstrap: 5 theme: breeze-light ``` You can choose from any of the following options: `r paste0(pkgdown:::highlight_styles(), collapse = ", ")`. Bootswatch themes with a dark background (e.g. cyborg, darkly, solar) will need a dark syntax highlighting `theme`, e.g. `arrow-dark`: ``` yaml template: bootstrap: 5 bootswatch: cyborg theme: arrow-dark ``` If you're using the light switch, you will want to provide a `theme` and a `theme-dark`: ```yaml template: light-switch: true theme: gruvbox-light theme-dark: gruvbox-dark ``` The foreground and background colours used for inline code are controlled by `code-color` and `code-bg` bslib variables. If you want inline code to match code blocks, you'll need to override the variables yourself, e.g.: ``` yaml template: bootstrap: 5 theme: arrow-dark bslib: code-bg: "#2b2b2b" ``` ### Math rendering By default, pkgdown will render math using mathml. mathml is the official standard for rendering math on the web, and requires no additional javascript or css dependencies. However, browser support for complex math is not always that good, so if you are including complex equations in your documentation, you may want to switch to either [`katex`](https://katex.org) or [`mathjax`](https://www.mathjax.org) by using the `template.math-rendering` field: ```yaml template: math-rendering: katex ``` ### Navbar style The primary navbar colours are determined by HTML classes, not CSS, and can be customized using the `navbar` fields `bg` and `type` which control the background and foreground colours respectively. Typically `bg` will be one of `light`, `dark`, or `primary`: ``` yaml navbar: bg: primary ``` You generally don't need to set `bg` if you use a bootswatch theme, as pkgdown will pick the `bg` used on the [Bootswatch preview](https://bootswatch.com/). Similarly, you don't usually need to set `type` because bootstrap will guess it for you. If the guess is wrong, you can override with `type: light` or `type: dark` depending on whether the background colour is light (so you need dark text) or `type: dark` if the background is dark (so you need light text). Unfortunately, these are defined relative to the page background, so if you have a dark site you'll need to flip `light` and `dark` (a little experimentation should quickly determine what looks best). Because the navbar is styled with HTML, you'll need to `build_home_index(); init_site()` to see the effect of changing this parameter. ## Layout {#layout} You can customise the contents of the navbar, footer, using the `navbar` and `footer` fields. See `?build_home` for how to customise the sidebar on the homepage. They all use a similar structure that separately defines the overall `structure` and the individual `components`. ### Navbar {#navbar-heading} You can customise the navigation bar that appears at the top of the page with the `navbar` field. It's made up of two pieces: `structure`, which defines the overall layout, and `components`, which defines what each piece looks like. This organisation makes it easy to mix and match pkgdown defaults with your own customisations. This is the default structure: ``` yaml navbar: structure: left: [intro, reference, articles, tutorials, news] right: [search, github, lightswitch] ``` It makes use of the the following built-in components: - `intro`: "Get Started", which links to a vignette or article with the same name as the package[^dots]. - `reference`: if there are any `.Rd` files. - `articles`: if there are any vignettes or articles. - `tutorials`: if there any tutorials. - `news`: if `NEWS.md` exists. - `search`: the search box (see `?build_search` for more details). - `github`: a link to the source repository (with an icon), if it can be automatically determined from the `DESCRIPTION`. - `lightswitch`; a ["light switch"](#light-switch) to select light mode, dark mode, or auto mode. Note that customising `navbar` like this comes with a downside: if pkgdown later changes the defaults, you'll have to update your `_pkgdown.yml`. [^dots]: Note that dots (`.`) in the package name need to be replaced by hyphens (`-`) in the vignette filename to be recognized as the intro. That means for a package `foo.bar` the intro needs to be named `foo-bar.Rmd`. You can use the `structure` field to reorganise the navbar without changing the default contents: ``` yaml navbar: structure: left: [search] right: [reference, articles] ``` You can use `components` to override the default content. For example, this yaml provides a custom articles menu: ``` yaml navbar: components: articles: text: Articles menu: - text: Category A - text: Title A1 href: articles/a1.html - text: Title A2 href: articles/a2.html - text: ------- - text: "Category B" - text: Article B1 href: articles/b1.html ``` Components uses the same syntax as [RMarkdown menus](https://bookdown.org/yihui/rmarkdown/rmarkdown-site.html#site-navigation). The elements of `menu` can be: - Linked text (`text`, `href`, and an optional `target`). - A linked icon (`icon`, `aria-label`, `href`, and an optional `target`). You can find a list of available icons at [fontawesome](https://fontawesome.com/icons?d=gallery). Provide a text description of the icon in the `aria-label` field for screenreader users. - A heading (just `text`). - A separator (`text: ——–`). To add a new component to the navbar, you need to modify both `structure` and `components`. For example, the following yaml adds a new "twitter" component that appears to the left of the github icon. ``` yaml navbar: structure: right: [search, twitter, github, lightswitch] components: twitter: icon: fa-twitter href: http://twitter.com/hadleywickham aria-label: Twitter ``` Finally, you can add arbitrary HTML to three locations in the navbar: ```yaml template: includes: before_title: <!-- inserted before the package title in the header -> before_navbar: <!-- inserted before the navbar links --> after_navbar: <!-- inserted after the navbar links --> ``` These inclusions will appear on all screen sizes, and will not be collapsed into the the navbar drop down. You can also customise the colour scheme of the navbar by using the `type` and `bg` parameters. See above for details. ### Footer You can customise the footer with the `footer` field. It's made up of two pieces: `structure`, which defines the overall layout, and `components`, which defines what each piece looks like. This organisation makes it easy to mix and match the pkgdown defaults with your own customisations. This is the default structure: ``` yaml footer: structure: left: developed_by right: built_with ``` Which uses two of the three built-in components: - `developed_by`: a sentence describing the main authors of the package. (See `?build_home` if you want to tweak *which* authors appear in the footer.) - `built_with`: a sentence advertising pkgdown. - `package`: the name of the package. You can override these defaults with the `footer` field. The example below puts the author's information on the right along with a legal disclaimer, and puts the pkgdown link on the left. ``` yaml footer: structure: left: pkgdown right: [developed_by, legal] components: legal: Provided without **any warranty**. ``` Each side is pasted into a single string (separated by `" "`) and then converted from markdown to HTML. ## Additional HTML and files If you need to include additional HTML, you can add it in the following locations: ``` yaml template: includes: in_header: <!-- inserted at the end of the head --> before_body: <!-- inserted at the beginning of the body --> after_body: <!-- inserted at the end of the body --> before_title: <!-- inserted before the package title in the header -> before_navbar: <!-- inserted before the navbar links --> after_navbar: <!-- inserted after the navbar links --> ``` You can include additional files by putting them in the right place: - `pkgdown/extra.css` and `pkgdown/extra.js` will be copied to the rendered site and linked from `<head>` (after the pkgdown defaults). - `pkgdown/extra.scss` will be added to the scss ruleset used to generate the site CSS. - Any files in `pkgdown/assets` will be copied to the website root directory. - For expert users: template files in `pkgdown/templates` will override layout templates provided by pkgdown or [template packages](#template-packages). Use `init_site()` to update your rendered website after making changes to these files. ## Template packages {#template-packages} To share a pkgdown style across several packages, the best workflow is to create... a package! It can contain any of the following: - A configuration file in `inst/pkgdown/_pkgdown.yml`. This can be used to set (e.g.) author definitions, Bootstrap version and variables, the sidebar, footer, navbar, etc. - Templates in `inst/pkgdown/templates/` will override the default templates. - Assets in `inst/pkgdown/assets/` will be copied in to the destination directory. (Note these files are only copied; you'll need to reference them in your stylesheet or elsewhere in order for them to be actually used.) - `inst/pkgdown/extra.scss` will be added to the bslib ruleset. (Note that `extra.css` is not supported in templates.) The pkgdown defaults will be overriden by these template files, which are in turn overridden by package specific settings. Once you have created your template package `theverybest`, you need to set it as your site's theme: ``` yaml template: package: theverybest ``` You then also need to make sure it's available when your site is built. Typically, you won't want to publish this package to CRAN, but you will want to publish to GitHub. Once you've done that, and assuming you're using the [usethis workflow](https://usethis.r-lib.org/reference/use_pkgdown.html), add the following line to your `DESCRIPTION`: ```yaml Config/Needs/website: myorg/theverybest ``` This will ensure that the GitHub action will automatically install it from GitHub when building your pkgdown site. To get some sense of how a theming package works, you can look at: - [tidytemplate](https://tidytemplate.tidyverse.org/) used for tidyverse and tidymodels packages; - [quillt](https://pkgs.rstudio.com/quillt) used for R Markdown packages; - [rotemplate](https://github.com/ropensci-org/rotemplate) used for rOpenSci packages. But please note that these templates aren't suitable for use with your own package as they're all designed to give a common visual identity to a specific family of packages. ### Porting a template package If you are updating a template package that works with pkgdown 1.0.0, create directories `inst/pkgdown/BS5/templates` and `inst/pkgdown/BS5/assets` (if you don't have any templates/assets make sure to a add dummy file to ensure that git tracks them). The `templates` and `assets` directories directly under `inst/pkgdown` will be used by pkgdown 1.0.0 and by pkgdown 2.0.0 if `boostrap: 3`. The directories under `inst/pkgdown/BS5/` will be used for pkgdown 2.0.0 with `boostrap: 5`. This lets your package support both versions of Bootstrap and pkgdown. ## PR previews Lastly, it might be useful for you to get a preview of the website in internal pull requests. For that, you could use Netlify and GitHub Actions (or apply a similar logic to your toolset): - Create a new Netlify website (either from scratch by dragging and dropping a simple index.html, or by creating a site from a GitHub repository and then unlinking that repository); from the site settings get its ID to be saved as `NETLIFY_SITE_ID` in your repo secrets; from your account developer settings get a token to be saved as `NETLIFY_AUTH_TOKEN` in your repo secrets. - Starting from the standard pkgdown workflow `usethis::use_github_action("pkgdown")`, add some logic to build the site and deploy it to Netlify for pull requests from inside the repository, not pull requests from forks. [Example workflow](https://github.com/r-lib/pkgdown/blob/master/.github/workflows/pkgdown.yaml). ## Conclusion In this vignette we explained how to change the theming and layout of pkgdown websites. Further work to improve user experience will involve: - Working on the article (`?build_articles`) and reference indexes (`?build_reference`). - Writing a compelling README that explains why your package is so cool/useful/fun. - Improving the contents of the individual articles and reference topics 😉. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/NAMESPACE�����������������������������������������������������������������������������������0000644�0001762�0000144�00000007546�14645463761�013176� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Generated by roxygen2: do not edit by hand S3method("[",tag) S3method(as_data,"NULL") S3method(as_data,tag_arguments) S3method(as_data,tag_author) S3method(as_data,tag_description) S3method(as_data,tag_details) S3method(as_data,tag_format) S3method(as_data,tag_note) S3method(as_data,tag_references) S3method(as_data,tag_section) S3method(as_data,tag_seealso) S3method(as_data,tag_source) S3method(as_data,tag_usage) S3method(as_data,tag_value) S3method(as_example,COMMENT) S3method(as_example,RCODE) S3method(as_example,TEXT) S3method(as_example,VERB) S3method(as_example,tag) S3method(as_example,tag_dontrun) S3method(as_example,tag_dontshow) S3method(as_example,tag_donttest) S3method(as_example,tag_dots) S3method(as_example,tag_if) S3method(as_example,tag_ifelse) S3method(as_example,tag_ldots) S3method(as_example,tag_out) S3method(as_example,tag_testonly) S3method(as_html,"#ifdef") S3method(as_html,"#ifndef") S3method(as_html,COMMENT) S3method(as_html,LIST) S3method(as_html,RCODE) S3method(as_html,Rd) S3method(as_html,TEXT) S3method(as_html,USERMACRO) S3method(as_html,VERB) S3method(as_html,character) S3method(as_html,tag) S3method(as_html,tag_R) S3method(as_html,tag_S3method) S3method(as_html,tag_S4method) S3method(as_html,tag_Sexpr) S3method(as_html,tag_acronym) S3method(as_html,tag_bold) S3method(as_html,tag_cite) S3method(as_html,tag_code) S3method(as_html,tag_command) S3method(as_html,tag_cr) S3method(as_html,tag_dQuote) S3method(as_html,tag_deqn) S3method(as_html,tag_describe) S3method(as_html,tag_dfn) S3method(as_html,tag_dots) S3method(as_html,tag_email) S3method(as_html,tag_emph) S3method(as_html,tag_enc) S3method(as_html,tag_enumerate) S3method(as_html,tag_env) S3method(as_html,tag_eqn) S3method(as_html,tag_figure) S3method(as_html,tag_file) S3method(as_html,tag_href) S3method(as_html,tag_if) S3method(as_html,tag_ifelse) S3method(as_html,tag_item) S3method(as_html,tag_itemize) S3method(as_html,tag_kbd) S3method(as_html,tag_ldots) S3method(as_html,tag_link) S3method(as_html,tag_linkS4class) S3method(as_html,tag_method) S3method(as_html,tag_newcommand) S3method(as_html,tag_option) S3method(as_html,tag_out) S3method(as_html,tag_pkg) S3method(as_html,tag_preformatted) S3method(as_html,tag_renewcommand) S3method(as_html,tag_sQuote) S3method(as_html,tag_samp) S3method(as_html,tag_special) S3method(as_html,tag_strong) S3method(as_html,tag_subsection) S3method(as_html,tag_tab) S3method(as_html,tag_tabular) S3method(as_html,tag_url) S3method(as_html,tag_var) S3method(as_html,tag_verb) S3method(pkgdown_print,default) S3method(pkgdown_print,gt_tbl) S3method(pkgdown_print,htmlwidget) S3method(print,pkgdown_xml) S3method(print,print_yaml) S3method(print,tag) S3method(usage_code,"NULL") S3method(usage_code,COMMENT) S3method(usage_code,RCODE) S3method(usage_code,Rd) S3method(usage_code,TEXT) S3method(usage_code,VERB) S3method(usage_code,tag) S3method(usage_code,tag_S3method) S3method(usage_code,tag_S4method) S3method(usage_code,tag_dots) S3method(usage_code,tag_ldots) S3method(usage_code,tag_method) S3method(usage_code,tag_special) S3method(usage_code,tag_usage) export(as_pkgdown) export(autolink_html) export(build_article) export(build_articles) export(build_articles_index) export(build_favicons) export(build_home) export(build_home_index) export(build_news) export(build_redirects) export(build_reference) export(build_reference_index) export(build_search) export(build_site) export(build_site_github_pages) export(build_tutorials) export(check_pkgdown) export(clean_cache) export(clean_site) export(data_template) export(deploy_site_github) export(deploy_to_branch) export(fig_settings) export(in_pkgdown) export(init_site) export(pkgdown_print) export(pkgdown_sitrep) export(preview_page) export(preview_site) export(rd2html) export(render_page) export(template_articles) export(template_navbar) export(template_reference) import(fs) import(rlang) importFrom(utils,installed.packages) ����������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/LICENSE�������������������������������������������������������������������������������������0000644�0001762�0000144�00000000055�14633374223�012737� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������YEAR: 2023 COPYRIGHT HOLDER: pkgdown authors �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/NEWS.md�������������������������������������������������������������������������������������0000644�0001762�0000144�00000160265�14672347567�013060� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# pkgdown 2.1.1 * Added keyboard shortcut, `/`, to focus search bar (#2423) * The `BugReports` field can now be an email (@catalamarti, #2275). * New `clean_cache()` function removes the contents of the cache directory (#2718). * pkgdown now depends on R >= 4.0.0 (#2714) * Updated GitHub Actions advice and workflows around Quarto install (@tanho63, #2743) # pkgdown 2.1.0 ## Major changes * Added @olivroy and @salim-b as pkgdown authors in recognition of their contributions. * `build_articles()` and `build_article()` now support articles/vignettes written with quarto (version 1.5 and above). Combining the disparate quarto and pkgdown templating systems is a delicate art, so while I've done my best to make it work, there may be some rough edges. So please file an issue you encounter quarto features that don't work quite right. Learn more in `vignette("quarto")`(#2210). * New light switch makes it easy for users to switch between light and dark themes for the website (based on work in bslib by @gadenbuie). For now this behaviour is opt-in with `template.light-switch: true` but in the future we may turn it on automatically. See the customization vignette for details (#1696). * New `vignette("translations")` that discusses non-English sites including how to submit new translations (#2605). * New `vignette("accessibility")` describes what manual tasks you need to perform to make your site as accessible as possible (#2344). * New `template.math-rendering` allows you to control how math is rendered across your site. The default uses `mathml` which is low-dependency, but has the lowest fidelity. You can also use `mathjax`, the previous default, and `katex`, a faster alternative. (#1966). * All external assets (JS, CSS, fonts) are now directly included in the site instead of fetched from external CDN (@salim-b, #2249) * YAML validation has been substantially improved so you should get much clearer errors if you have made a mistake (#1927). Please file an issue if you find a case where the error message is not helpful. ## Lifecycle changes * `autolink_html()` was deprecated in pkgdown 1.6.0 and now warns every time you use it. `downlit::downlit_html_path()` should be used instead. * `build_site(document)` and `build_reference(document)` has been removed after being deprecated in pkgdown 1.4.0. `devel` should be used instead. * `preview_page()` has been deprecated (#2650). * Bootstrap 3 has been deprecated. It was superseded in December 2021, and now we're starting to more directly encourage folks to move away from it. ## Front end changes * When built on GitHub, source urls now use the name of the current upstream branch (rather than `HEAD`), which is more likely to generate correct links (#2597). * The search dropdown has been tweaked to look more like the other navbar menu items (#2338). * Improve HTML5 compliance (#2369): * No longer support IE9 or earlier * Strip trailing whitespace * Label `<nav>`s and improve navbar html. * Tweaked navbar display on mobile so that long titles in drop downs (e.g. article titles) are now wrapped, and the search input spans the full width (#2512). * The title for the "Reference" page is now "Package index" since this page might contain more than just function details (#2181). * Very wide words are now automatically broken across lines and hyphenated (when possible) when they'd otherwise create a horizontal scrollbar on mobile (#1888). * The mobile version of pkgdown sites no longer has a scrollburglar (a small amount of horizontal scroll) (#2179, @netique). * Anchors are displayed when they're the target of a link. * New translation for "Search site", the label applied to the search box for screenreaders. This was previously incorrectly labelled as "Toggle navigation" (#2320). * pkgdown no longer overrides the default selection colours. This improves accessibility for users who have set their own colours in their browser settings (#2139, @glin). * If you put a dropdown menu (e.g. articles) on the right hand side of the navbar, it will now be right aligned. This makes longer titles more likely to stay on the page (#2421). * BS5 templates no longer include empty link to logo when none exists (#2536). * Updated translations from @jplecavalier, @dieghernan, @krlmlr, @LDalby, @rich-iannone, @jmaspons, and @mine-cetinkaya-rundel (#2659). ## `_pkgdown.yaml` * Anywhere you can use `_pkgdown.yml`, you can now use `_pkgdown.yaml` (#2244). * Custom navbars that specify `icon` but not `aria-label` will now generate a message reminding you to provide one for to improve accessibility (#2533). * The `repo.source.url` field no longer requires a trailing slash (#2017). * The `template.bslib` item now also accepts a `bootswatch` key (@gadenbuie, #2483). * You can now choose where the search box is placed with the "search" navbar component. This has been documented for a very long time, but as far as I can tell, never worked (#2320). If you have made your own template with a custom `navbar`, you will need to remove the `<form>` with `role="search"` to avoid getting two search boxes. ## Minor improvements and bug fixes * pkgdown now uses httr2 instead of httr (#2600). * Mathjax now uses version 3.2.2. * The addin now runs `build_site()` instead of `build_site_external()`, which generally should be more reliable (#2252). * `<source>` tags now have their `srcref` attributes tweaked in the same way that the `src` attributes of `<img>` tags are (#2402). * `as.pkgdown()` will no longer prompt you to install a missing template package from CRAN, since these are almost always found in GitHub (#2076). * `build_articles()` now recognises a new `external-articles` top-level field that allows you to define articles that live in other packages (#2028). * `build_article()` no longer has a `data` argument. This is technically a breaking change, but I can't figure out why anyone would have ever used it. * `build_*()` (apart from `build_site()`) functions no longer default to previewing in interactive sessions since they now all emit specific links to newly generated files. * `build_article()` now translates the "Abstract" title if it's used. * `build_article()` now escapes html characters in the title (#2286). * `build_article()` no longer generates the wrong source link when you build your site outside of the root directory (#2172). * `build_articles()` now reports if you are missing alt-text for any images (#2357). * `build_articles()` now drops a section called "internal". This allows you to have articles that either aren't indexed at all or are included manually elsewhere in the navbar (#2205). * `build_home()` now correctly escapes special HTML characters in the bibtex citation (#2022). * `build_home()` no longer checks if the README is missing any images. This check is now performed in `build_site()`, after `build_articles()` so you can refer to images created by vignettes with warnings (#2194). * `build_home()` now includes the contents of `inst/AUTHORS` on the authors page (#2506). * `build_home_index()` now reports when rendering the home page (#2544). * `build_home_index()` now renders math if you use it in your home page (#2263). * `build_news()` now works if your package has been archived at some point (#2687). * `build_news()` only syntax highlights the page once, not twice, which prevents every block of R code getting a blank line at the start (#2630). ```R 1 + 1 ``` * `build_reference()` no longer displays `\dontshow{}` or `\testonly{}` blocks in examples. It will run the code in `\dontshow{}`; it won't run the code in `\testonly{}`(#2188). * `build_reference()` does a better job of parsing `\value{}` blocks (#2371). * `build_reference()` now generates the usage that users actually type for infix and replacement methods (#2303). * `build_reference()` now automatically translates `--`, `---`, ``` `` ```, and `''` to their unicode equivalents (#2530). * `build_reference()` now supports `\Sexpr[results=verbatim]` (@bastistician, #2510). * `build_reference()` adds anchors to arguments making it possible to link directly to an argument, if desired. A subtle visual treatment makes it easy to see which argument is targeted (#2228). * `build_reference()` now automatically renders any tables created by gt (#2326). * `build_reference()` matches usage for S3 and S4 methods to the style used by R 4.0.0 and later (#2187). * `build_reference_index()` now displays function lifecycle badges next to the function name (#2123). The badges are extracted only from the function description. You can now also use `has_lifecycle()` to select functions by their lifecycle status. * `build_redirects()` is now exported to make it easier to document (#2500). * `build_redirects()` now automatically adds redirects for topic aliases. This matches the behaviour of `?` and will help keep links stable in the long term (#1876). * `build_redirects()` now reports which redirects it is generating. * `build_site()` automatically runs `pkgdown_sitrep()` at the start of the process (#2380). * `build_sitemap()` no longer includes redirected pages (#2582). * `check_pkgdown()` and `pkgdown_sitrep()` have been unified so that they both report on the same problems. They now only differ in the style of their output: `pkgdown_sitrep()` reports whether each category is ok or not ok, while `check_pkgdown()` errors on the first issue (#2463). * `init_site()` will no longer automatically build favicons on CI systems (e.g. GHA). This is an expensive operation that uses an external service so it should only be run locally (#2553). * `init_site()` once again describes one copy per line, and now uses a better prefix when copying assets from pkgdown itself (#2445). * `pkgdown_sitrep()`/`check_pkgdown()` now check that you have up-to-date favicons if you have a package logo. * `template_reference()` and `template_article()` now only add backticks to function names if needed (#2561). * `vignette("search")` has been removed since BS3 is deprecated and all the BS5 docs are also included in `build_search()` (#2564). # pkgdown 2.0.9 * Fixes for regressions in 2.0.8: * Output links generated when building the site work once again (#2435). * pkgdown once again uses Bootstrap version specified in a template package (@gadenbuie, #2443). * Front-end improvements: * The skip link now becomes visible when focussed (#2138). Thanks to @glin for the styles! * The left and right footers no longer contain an extra empty paragraph tag and the footer gains additional padding-top to keep the whitespace constant (#2381). * Clipboard buttons report their action again ("Copied!") (#2462) * It is now easier to preview parts of the website locally interactively. `build_reference_index()` and friends will call `init_site()` automatically instead of erroring (@olivroy, #2329). * `build_article()` gains a new `new_process` argument which allows to build a vignette in the current process for debugging purposes. We've also improved the error messages and tracebacks if an article fails to build, hopefully also making debugging easier (#2438). * `build_article_index()` and `build_reference_index()` use an improved BS5 template that correctly wraps each section description in a `<div>`, rather than a `<p>`. This eliminates an empty pargraph tag that preceded each section description (#2352). * `build_home()` no longer errors when you have an empty `.md` file (#2309). It alos no longer renders Github issue and pull request templates (@hsloot, #2362) * `build_news()` now warns if it doesn't find any version headings, suggesting that that `NEWS.md` is structured incorrectly (#2213). * `build_readme()` now correctly tweaks links to markdown files that use an anchor, e.g. `foo.md#heading-name` (#2313). * `build_reference_index()` gives more informative errors if your `contents` field is malformed (#2323). * `check_pkgdown()` no longer errors if your intro vignette is an article is not listed in `_pkgdown.yml` (@olivroy #2150). * `data_template()` gives a more informative error if you've misspecified the navbar (#2312). # pkgdown 2.0.8 * pkgdown is now compatible with (and requires) bslib >= 0.5.1 (@gadenbuie, #2395), including a fix to BS5 navbar template to get `navbar.type: dark` to work with Bootstrap 5.3+ (@tanho63, #2388) * Now uses [cli](https://github.com/r-lib/cli) to provide interactive feedback. * Avoid unwanted linebreaks from parsing `DESCRIPTION` (@salim-b, #2247). * Translations * New Catalan translation (@jmaspons, #2333). * Citation sections are correctly translated (@eliocamp, #2410). * `build_article_index()` now sorts vignettes and non-vignette articles alphabetically by their filename (literally, their `basename()`), by default (@jennybc, #2253). * Deprecated `build_favicon()` was removed (`build_favicons()` remains). * `build_articles()` now sets RNG seed by default. Use `build_articles(seed = NULL)` for the old (unreproducible) behaviour. (@salim-b, #2354). * `build_articles()` will process `.qmd` articles with the quarto vignette builder (@rcannood, #2404). * `build_articles()` and `build_reference()` now set RNG seed for htmlwidgets IDs. This reduces noise in final HTML output, both for articles and examples that contain htmlwidgets (@salim-b, #2294, #2354). * `build_news()` correctly parses of github profiles and issues into links when present at the beginning of list items (@pearsonca, #2122) * `build_reference()` sets `seed` correctly; it was previously reset too early (@salim-b, #2355) * Rd -> html translation * `\cr` is now translated to `<br>` not `<br />` (#2400). * Correct usage for S3 methods with non-syntactic class names (#2384). * Preserve Markdown code blocks with class rmd from roxygen2 docs (@salim-b, #2298). * `build_reference_index()` no longer generates redundant entries when multiple explicit `@usage` tags are provided (@klmr, #2302) * `build_reference_index()` correctly handles topic names that conflict with selector functions (@dmurdoch, #2397). # pkgdown 2.0.7 * Fix topic match selection when there is an unmatched selection followed by a matched selection (@bundfussr, #2234) * Fix highlighting of nested not R code blocks (for instance, example of R Markdown code with chunks) (@idavydov, #2237). * Tweak German translation (@krlmlr, @mgirlich, @lhdjung, #2149, #2236) * Remove mention of (defunct) Twitter card validator, provide alternatives (@Bisaloo, #2185) * Fix `keywords` typo in `check_missing_topics()` message (@swsoyee, #2178). * Use jsdeliver CDN for bootstrap-toc (@GregorDeCillia, #2207). # pkgdown 2.0.6 * If you're using an RStudio daily, output file names are now clickable, previewing the generated HTML in the browser (#2157). * Getting started vignette no longer needs to be included in the articles index (#2150). * If there aren't any functions in the `\usage{}` block, then pkgdown will now shows all aliases on the reference index, rather than just the topic name (#1624). # pkgdown 2.0.5 * Correctly generate downlit link targets for topics that have a file name ending in `.` (#2128). * `build_articles()`: if build fails because the index doesn't include all articles, you're now told what articles are missing (@zkamvar, #2121). * `build_home()` now escapes angle brackets in author comments(#2127). * `build_home()` will automatically render and link `.github/SUPPORT.md` (@IndrajeetPatil, #2124). * `build_news()` once again fails to link `@username` at start of bullet. I had to reverted #2030 because of #2122. * `build_reference()`: restore accidentally nerfed `has_keyword()` and `has_concept()` reference selectors (#2126) and add tests. # pkgdown 2.0.4 * New `check_pkgdown()` provides a lightweight way to check that your `_pkgdown.yml` is valid without building the site (#2056). Invalid `_pkgdown.yml` now consistently generates errors both locally and on CI (#2055). * `build_article()` now supports inline markdown in the `title` (#2039). * `build_home()` no longer shows development status badges on the released version of the site (#2054). * `build_news()` support automated `@username` links in more places (#2030). * `build_reference()`: * You can once again exclude topics from the reference index with `-` (#2040). * Inline markdown in `title`s and `subtitle`s is now supported(#2039). * Package logos will be automatically stripped from the `.Rd` you don't end up with two on one page. (#2083). * `\figure{file}{alternative text}` with multiline alt text is now parsed correctly (#2080) * roxygen 7.2.0 output for generic code blocks (#2092, @jabenninghoff) is processed correctly. * Front end changes: * Automatically added links in code blocks are now styled less aggressively, so they occupy less visual weight on the page (#2007). * All article pages are given class `col-md-9` for consistency with other pages (#2045). * Fixed width HTML widgets are sized correctly (@dmurdoch, #2062). * Footnotes work with more contents, including code (@banfai, #2042). * Navbar components now accept `target` argument (#2089, @JSchoenbachler). * New syntax highlighting themes a11y-light, a11y-dark, monochrome-light, monochrome-dark, and solarized # pkgdown 2.0.3 * Fixes for R CMD check # pkgdown 2.0.2 * New Korean (`ko`) translation thanks to @mrchypark and @peremen (#1944). New Danish (`dk`) translation thanks to @LDalby. * `build_articles()` now adjusts the heading levels of vignettes/articles that use `<h1>` as section headings to ensure that there's one top-level heading (#2004). This ensures that there's one `<h1>`, the title, on each page, and makes the TOC in the sidebar work correctly. * `build_home_index()` no longer spuriously complains about missing images if you use plots in your `README.Rmd` (#1980, #1977). It no longer tweaks the `src` path for `<img>` tags with absolute paths (#1955). * `build_news()` once again works if `NEWS.md` uses `<h1>` headings (#1947). * `build_reference()` now correctly interprets `title: internal`: it removes the section from the reference index _and_ it doesn't list the topics in that section as missing (#1958). * `build_reference()` now gives a correct hint when the reference index YAML is not formatted correctly (e.g. empty item, or item such as "n" that needs to be escaped with quotes to not be interpreted as Boolean) (#1995). * `deploy_to_branch()` gains a `subdir` argument, allowing you to deploy the site to a subdirectory (@gadenbuie, #2001). * Front end changes: * The navbar gets a little more space after the version number, and aligns the baseline with rest of the navbar (#1989). * Long lines in code output once again scroll, rather than being wrapped. While this is different to what you'll see in the console, it's a better fit for web pages where the available code width varies based on the browser width (#1940). * scrollspy (which highlights the "active" heading in the sidebar) now computes the offset dynamically which makes it work better on sites with taller navbars (#1993). * Fixed js issues that occurred on pages without a table of contents (@gadenbuie, #1998). * When htmlwidgets with jQuery or Bootstrap dependencies are used in examples or articles, pkgdown's versions of jQuery and Boostrap will take precedence over the versions used by the htmlwidget (@gadenbuie, #1997). * pkgdown no longer includes bundled author metadata for Hadley Wickham, RStudio, or the RConsortium, since there are now ways to include this meta data in template packages, and special casing these three entities feels increasingly weird (#1952). # pkgdown 2.0.1 * Fix CRAN failures. * Reference sections are de-duplicated correctly (#1935). * Usage sections only generated for topics that have them; usage correctly displayed with BS3 (#1931) * Empty `\value{}` no longer errors (#1930). # pkgdown 2.0.0 ## New authors @maelle is now a pkgdown author in recognition of her significant and sustained contributions. She was the powerhouse behind many of the improvements in this release, particularly the switch to bootstrap 5, improvements to customisation, and implementation of local search. ## Bootstrap 5 * pkgdown can style your site with Bootstrap 5 (with help from @jayhesselberth, @apreshill, @cpsievert). Opt-in by setting `boostrap` version in your `_pkgdown.yml`: ```yaml template: bootstrap: 5 ``` * We reviewed site accessibility and made a number of small improvements: (#782, #1553): * Default font is larger and links are always underlined. * Heading anchors use `aria-hidden` to reduce noise for screenreader users. * Navbar dropdowns has improved `aria-labelledby`. * The default GitHub/GitLab links gain an `aria-label`; use for other icons is now supported, and encouraged in the docs. * Syntax highlighting uses a new more [accessible colour scheme](https://apreshill.github.io/rmda11y/arrow.html), designed by Alison Hill (#1536) * A skip link makes it easier to get directly to the page contents (#1827). * In-line footnotes mean you can read asides next to the text they refer to. * Articles support tabsets, [as in R Markdown](https://bookdown.org/yihui/rmarkdown-cookbook/html-tabs.html). (@JamesHWade, #1667). * Other minor styling improvements: * The active item in TOC is indicated with background colour, rather than a border. * If present, the package logo is shown on all pages near the header. * Section anchors now appear on the right (making them usable on mobile phones) (#1782). * The TOC is scrollable independently of the main content. This makes it more useful on long pages with many headings (#1610). * The sidebar is shown at the bottom of the page on narrow screens. * Function arguments and the reference index (#1822) use definition lists (`<dl>`) instead of tables. This gives more room for long argument names/lists of function and detailed descriptions, and displays better on mobile. * Links on the homepage no longer show the full url in the text. * The default navbar no longer includes a home icon - this took up precious horizontal space and wasn't very useful since there was already a link to the home page immediately to its left (#1383). ## Local search * pkgdown now supports local searching (i.e. searching without an external service), and is enabled by default for Bootstrap 5 sites since no set-up is needed (#1629, with help from @gustavdelius in #1655 and @dieghernan & @GregorDeCillia in #1770). * pkgdown builds a more exhaustive `sitemap.xml` even for websites built with Bootstrap 3. This might change Algolia results if you use Algolia for search (#1629). ## Customisation * New `vignette("customise")` documents all the ways you can customise your site, including the new options described below (#1573). * Sites can be easily themed with either bootswatch themes or by selectively overriding the `bslib` variables used to generate the CSS. pkgdown now uses scss for its own Bootstrap css tweaks, which means that you can customise more of the site from within `_pkgdown.yml`. * You can pick from a variety of built-in syntax highlighting themes (#1823). These control the colours (and background) of code in `<pre>` tags. * pkgdown can now translate all the text that it generates (#1446): this means that if you have a package where the docs are written in another language, you can match all the pkgdown UI to provide a seamless experience to non-English speakers. Activate the translations by setting the `lang` in `_pkgdown.yml`: ```yaml lang: fr ``` pkgdown includes translations for: * `es`, Spanish, thanks to @edgararuiz-zz, @dieghernan, @rivaquiroga. * `de`, German, thanks to @hfrick. * `fr`, French, thanks to @romainfrancois, @lionel-, @jplecavalier, and @maelle. * `pt`, Portuguese, thanks to @rich-iannone. * `tr`, Turkish, thanks to @mine-cetinkaya-rundel. * `zh_CN`, simplified Chinese, thanks to @yitao. If you're interested in adding translations for your language please file an issue and we'll help you get started. * Template packages can now provide `inst/pkgdown/_pkgdown.yml` which is used as a set of defaults for `_pkgdown.yml`. It can be used to (e.g.) provide author definitions, select Bootstrap version and define bslib variables, and customise the sidebar, footer, navbar, etc. (#1499). * New `includes` parameters `in-header`, `before-body`, and `after-body` make it easy to add arbitrary HTML to every page. Their content will be placed at the end of the `<head>` tag, right below the opening `<body>` tag, and before the closing tag `</body>` respectively (#1487). They match the bookdown options `in_header`, `before_body` and `after_body`. Additionally, you can use `before_title`, `before_navbar`, and `after_navbar` to add arbitrary HTML into the navbar/page header; they will appear to the left of the package name/version, and to the left and right of the navigation links respectively (#1882). * Authors configuration is more flexible (#1516). You can now: * Choose the roles used for filtering authors for the sidebar and footer. * Choose the text before authors in the footer. * Add text before and after the authors list in the sidebar. * Add text before and after the authors list of the authors page. * Sidebar specification is more flexible (#1443, #1488, #1502). You can now: * Change the order of sidebar elements. * Add custom sidebar sections (with Markdown/HTML `text`). * Add a table of contents to the home page. * Completely suppress the sidebar. * Provide your own HTML for the navbar. * Footer specification is more flexible (#1502). You can now: * Change the placement of elements on the left and right. * Add text to the left and right (or even remove/replace default text) * You can now exclude all default components from the navbar (#1517). * Expert users can now override layout templates provided by pkgdown or template packages by placing template files in `pkgdown/templates` (@gadenbuie, #1897). ## New features * pkgdown now supports redirects (#1259, @lorenzwalthert). The following yaml demonstrates the syntax, with old paths on the left and new paths/URLs on the right. ```yaml redirects: - ["articles/old-vignette-name.html", "articles/new-vignette-name.html"] - ["articles/another-old-vignette-name.html", "articles/new-vignette-name.html"] - ["articles/yet-another-old-vignette-name.html", "https://pkgdown.r-lib.org/dev"] ``` * Use HTML classes `pkgdown-devel` or `pkgdown-release` to declare that certain content should appear only on the devel or release site. Use the class `pkgdown-hide` for content that should only appear only on GitHub/CRAN (#1299). * New `pkgdown_sitrep()` function reports whether the site is set up correctly; in particularly it currently reports if auto-linking will work (#1478). ## Code * Styling for errors, warnings, and messages has been tweaked. Messages are now displayed the same way as output, and warnings and errors are bolded, not coloured. This is part of a suite of changes that aim to give package authors greater control over the appearance of messages, warnings, and errors. * Long lines in code output are now wrapped, rather than requiring scrolling. This better matches `rmarkdown::html_document()` and what you see in the console. * `build_reference()` now allows linking to topics from other packages (either function names e.g. `rlang::is_installed` or topic names e.g. `sass::font_face`). (#1664) * `build_reference()` now runs examples with `options(rlang_interactive = FALSE)` (ensuring non-interactive behaviour in functions that use `rlang::is_interactive()`), `options(cli.dynamic = FALSE)`, `Sys.setenv(RSTUDIO = NA)` and `Sys.setLocale("LC_COLLATE", "C")` (#1693). It also runs `pkgdown/pre-reference.R` before and `pkgdown/post-reference.R` after examples. These allow you to do any setup or teardown operations you might need (#1602). * A reference index section with `title: internal` is now silently dropped, allowing you to suppress warnings about topics that are not listed in the index (#1716). * Code blocks are now highlighted according to their declared language (e.g. `yaml`) if the documentation was built with roxygen2 7.1.2 or later (#1690, #1692). * New `pkgdown_print()` allows you to control how your objects are rendered in examples. It includes built-in handling for htmlwidgets and "browseable" HTML so pkgdown output now more closely resembles what you see in RStudio. Added extension points to make HTML widgets (and RGL in particular) work in rendered examples (@dmurdoch). * You can globally set the `width` of code output (in reference and articles) with ```yaml code: width: 50 ``` * Articles now render output styles created by cli/crayon (#1556). * When copy and pasting code blocks, lines containing output (e.g. `#>`) are automatically omitted (#1675). * Auto-linking improvements: * Links to inherited R6 methods now work correctly for both internal (#1173, @vandenman) and external (#1476) parent classes. * Linking no longer fails if a package contains duplicated Rd aliases. * Correctly link to reference pages when the `\name{}` entry doesn't match the file name (@dmurdoch, #1586; #1676). ## Articles * Article subtitle, author and date (specified in the YAML frontmatter) are now correctly omitted from the article table of contents in the sidebar (@maxheld83, #1428). * Support for `as_is: true` and non-default output formats for vignettes/ articles has been somewhat improved. Support is fundamentally limited due to the challenges of integrating HTML from output formats that pkgdown doesn't know about, but it should be a little more reliable and a little better documented (#1757, #1764). * `build_articles()` no longer fails if you have a directory underneath vignettes with a `.Rmd` extension (#1425). * `build_articles()` now correctly handles links to images in `man/figures` (which have the form `../man/figures`) (#1472). * `build_articles()` again sets the `theme` argument of the document format to `NULL` when `as_is: true` but lets users override this via the `theme` argument of the output format. * `build_articles()` and `build_home()` now warn if you have images that won't render on the website because they're in unsupported directories (#1810). Generally, it's only safe to refer to figures in `man/figures` and `vignettes`. * Articles stored in `vignettes/articles` are moved up one level so that they appear in `articles/` on the website. Previously, they would appear in `articles/articles`, so `build_redirects()` automatically adds redirects for any articles in the `vignettes/articles` directory (@gadenbuie #1911). ## HTML, CSS and JS * New `template` option `trailing_slash_redirect` that allows adding a script to redirect `your-package-url.com` to `your-package-url.com/` (#1439, @cderv, @apreshill). * External links now get the class `external-link`. This makes them easier to style with CSS (#881, #1491). * Duplicated section ids are now de-duplicated; this makes pkgdown work better with the documentation of R6 classes. * Updated CSS styles from pandoc to improve styling of reference lists (#1469). ## Deployment * `build_site_github_pages()` has been extracted out of `deploy_site_github()` to make it easier to decouple building and deployment, and so we can take advantage of standard deployment actions (#1756). * `deploy_to_branch()` now calls `git remote set-branches` with `--add` to avoid overwriting the existing `remote.{remote}.fetch` value (@kyleam, #1382). It also now cleans out the website directory by default; revert to previous behaviour with `clean = FALSE` (#1394). * `build_reference()` will error if envar `CI` is `true` and there are missing topics (@ThierryO, #1378). * You can override the `auto` development mode detected from the package version by setting env var `PKGDOWN_DEV_MODE` to `release` or `devel`. This is useful if your package uses a different convention to indicate development and release versions (#1081). ## Other minor improvements and bug fixes * `\special{}` tags with complex contents are rendered correctly (@klmr, #1744). * `\arguments{}` and `\value{}` do a better job of handling mingled items and text (#1479). The contents of `\value{}` are now shown immediately after `\arguments{}`. * The default "branch" for linking to the file sources is `HEAD`, which will work regardless of whether your default branch is called "main" or "master". * Non-ORCID comments in `Authors@R` are now more usable: if such comments exist, the sidebar gains a link to the authors page, where they are displayed (#1516). * Citations with and without text versions are better handled, and text citations are correctly escaped for HTML (@bastistician, #1507). * README badges in a single paragraph placed between `<!-- badges: end -->`and `<!-- badges: end -->` comments are again detected (#1603). * The 404 page (default or from `.github/404.md`) is no longer built in the development mode (see `?build_site`) as e.g. GitHub pages only uses the `404.html` in the site root (#1622). * All links on the 404 pages (navbar, scripts, CSS) are now absolute if there is an URL in the configuration file (#1622). * The version tooltip showed in the top navbar is now only set if you've explicitly set the `development.mode` in `_pkgdown.yml` (#1768). * All heading (e.g. headings on the reference index page, and the arguments heading on the reference pages) now get anchors (#1747). * Use `autolink_bare_uris` for Pandoc above version 2.0 (@marcosmolla, #1618). * pkgdown now recognizes GitLab URLs to the source repository and adds the corresponding icon to the navbar (#1493). It also supports [GitLab subgroups](https://docs.gitlab.com/ee/user/group/subgroups/) (@salim-b, #1532). * Links for GitHub Enterprise and GitLab Enterprise repositories are detected by assuming such host address begin with `github.` or `gitlab.` (@ijlyttle, #1452). * The rules drawn by the CLI (as for example, in `build_site()`) are protected against very narrow terminal windows (@maxheld83, #1435). * Google Site Verification (https://support.google.com/webmasters/answer/9008080?hl=en) can now be configured for pkgdown sites. * `build_rmarkdown_format` sets `html_document(anchor_sections = FALSE)` to avoid needless dependencies (@atusy, #1426). * Jira issues in NEWS can be automatically linked by setting your project name (s) with `repo: jira_projects: [...]` and specifying a custom issue URL with `repo: url: issue: ...` in `_pkgdown.yml` (@jonkeane, #1466). * `build_home()` always creates citation information for the authors page, using metadata from `DESCRIPTION` when there is no `inst/CITATION` file, and links to this from the sidebar (#1904). * `build_news()` no longer breaks with URLs containing numeric fragments (@krassowski, #1456), recognises more styles of release heading (#1437), and generate stable IDs using a the combination of the heading slug and package number. (@Bisaloo, #1015) # pkgdown 1.6.1 * The article index (used for autolinking vignettes across packages) once again works (#1401). # pkgdown 1.6.0 ## Major changes * pkgdown now uses the new [downlit](https://downlit.r-lib.org/) package for all syntax highlighting and autolinking (in both reference topics and vignettes). There should be very little change in behaviour because the code in downlit was extracted from pkgdown, but this makes it easier to use pkgdown's nice linking/highlighting in more places (#1234). * pkgdown now uses the `ragg::agg_png()` device to generate example figures. This should be a little faster and produce higher quality output. Learn more at <https://ragg.r-lib.org> (#1320). ## Minor improvements and bug fixes ### Rd translation * `\special{}` support inside `\usage{}` added to allow non-standard R usage syntax (@klmr, #1345). * `#ifdef` and `#ifndef` are now supported; the "current" OS is hard coded to "unix" to ensure reproducible output regardless of where you build the website (#1384). * Nested `\subsection{}`s now generate appropriate heading levels (h3, h4, h5 etc) (#1377), and get anchor links (#1389). * `\preformatted{}` no longer double escapes its contents (#1311). ### Articles and vignettes * `build_articles()` no longer sets the `theme` argument of the document format to `NULL` when `as_is: true`. This should allow it to work with a wider range of output formats including `bookdown::html_vignette2()` and friends (@GegznaV, #955, #1352). * When `build_article()` fails, it gives the complete failure message (#1379). * Markdown header attributes are now processed in all markdown files (@jonkeane, #1343) ### Auto-linking and syntax highlighting * The branch used for source linking can be configured by setting `repo: branch: branch_name` in `_pkgdown.yml` (@jonkeane, #1355): ```yaml repo: branch: main ``` * `autolink_html()` is (soft) deprecated. Please use `downlit::downlit_html_path()` instead. * Highlighting of empty expressions works once more (#1310). * New `deploy$install_metadata` option in `_pkgdown.yml`. Setting it to `true` will store site metadata in the package itself, allowing offline access for packages that to autolink to the package's website (@mstr3336, #1336). ### Other * You can now control the background colour of plots with the `figures.bg` option (it is transparent by default, and given a white background by css). See `?build_reference` for an example. * HTML is automatically stripped from the page title (#1318). * Suppressing CRAN dates in news file now actually works. * All HTTP requests are now retried upon failure (@jameslamb, #1305). * Setting `clean = TRUE` in `deploy_site_github()` removes old files from the deployed site before building a new one (#1297). # pkgdown 1.5.1 * Syntax highlighting works on Windows once more (#1282). * pkgdown no longer fails if your `.Rd` files have duplicated `\aliases` as were produced by an older version of roxygen2 (#1290). * Rendering empty `.md` file now returns empty string (#1285). * `build_articles_index()` is now exported to rapidly rebuild the index (#1281) * `deploy_site_github()` now accepts a `host` argument to specify alternate hosts (e.g., Github enterprise) (@dimagor, #1165) and once again works as intended on Travis-CI (@jimhester, #1276). # pkgdown 1.5.0 ## New features * The articles index page and navbar have been overhauled. There are two major new features in this release: * The articles index page now displays article `description`s, taken from YAML metadata belonging to each article. This lets you provide more context about each article and describe why one might want to read it (#1227). * The articles navbar is now also controlled by the `articles` section in `_pkgdown.yml`. The ordering of the sections, and articles within them, control the order of the articles in the navbar, and you can use the new `navbar` field to control whether or not each section appears in the navbar (#1101, #1146). * The reference index now has two levels of heading hierarchy: `title` and `subtitle` (#327). * Tables of contents in sidebars now use [bootstrap-toc](https://afeld.github.io/bootstrap-toc/); this considerably improves navigation for long articles and reference pages. * You can now control the links to source files (in reference pages and articles) and issues and users (in the NEWS) with new `repo$url` config option (#1238). This makes it easier to use pkgdown with GitHub enterprise, packages in subdirectories, and other source hosts (like bitbucket). ```yaml repo: url: home: https://github.com/r-lib/pkgdown/ source: https://github.com/r-lib/pkgdown/blob/main/ issue: https://github.com/r-lib/pkgdown/issues/ user: https://github.com/ ``` The individual components (e.g. path, issue number, username) are pasted on the end of these urls so they should have trailing `/`s. You don't need to set these links for GitLab, as pkgdown now detects GitLab urls automatically (since they use the same structure as GitHub) (#1045). * There's much richer control over Open Graph and Twitter metadata for the whole site and for individual articles. See new `vignette("metadata")` for details (@gadenbuie, #936). * New `deploy_to_branch()` function to build and deploy a site to a branch, defaulting to `gh-pages` for use with GitHub Pages. This is used in our recommended GitHub action workflow for automatically building and deploying pkgdown sites for packages on GitHub (@jimhester, #1221). * Updated JS libraries: jquery 3.3.1 -> 3.4.1; bootswatch 3.3.7 -> 3.4.0; bootstrap 3.3.7 -> bootstrap 3.4.1; docsearch 2.6.1 -> 2.6.3; fontawesome 5.11.1 -> 5.12.1; headroom.js 0.9.44 -> 0.11.0; clipboard.js 2.0.4 -> 2.0.6 (@jayhesselberth). ## Auto-linking improvements * Examples and Rmd now use exactly the same syntax highlighting strategy. * In examples and Rmd, calls of the form `current_package::foo` now get a local link (#1262). * `\preformatted{}` blocks are now highlighted and linked if they parse as R code (#1180). * `library(pkgdown)` is now automatically linked to the reference index for "pkgdown" not the documentation for `library()` (#1161). * `help("topic")` is now automatically linked to the documentation for "topic", not to the documentation for `help()` (#1210) ## Minor improvements and bug fixes ### Articles * `build_home()` no longer uses (unrendered) `README.Rmd` or `index.Rmd` if corresponding `.md` files are not found. * `build_article()` failures now print more information to help you debug the problem (#952). * The name of the vignette mapped to the "Get started" entry in the navbar is now more flexible. You can use an article (e.g `articles/{pkgname}`) and if your package has a `.` in its name you can replace it with `-` to generate a valid article name (e.g. the get started vignette for `pack.down` would be `pack-down`) (#1166). ### Deployment * `deploy_to_branch()` now correctly captures the commit SHA on GitHub Actions (@coatless, #1252). * `deploy_to_branch(github_pages = TRUE)` generates a `.nojekyll` to prevent jekyll ever executing (#1242). * `CNAME` is no longer generated by `init_site()`, but is instead conditionally by `deploy_to_branch()` when `github_pages = TRUE`. This is a better a fit because the `CNAME` file is only needed by GitHub pages (#969). * `deploy_site_github()` argument `repo_slug` has been deprecated and is no longer needed or used. (@jimhester, #1221) ### News See additional details in `?build_news`: * You can optionally suppress the CRAN release dates added to the news page (#1118). * Multi-page news style gets a better yaml specification (the old style will continue to work so no need to change existing YAML). ### Reference * A topic named `index` will not longer clobber the reference index (#1110). * Topic names/aliases on reference index are now escaped (#1216). * `build_reference()` gives better warnings if your `_pkgdown.yml` is constructed incorrectly (#1025). * New `has_keyword()` topic selector for `reference`. `has_keyword("datasets")` is particularly useful for selecting all data documentation (#760). * New `lacks_concepts()` can select topics that do not contain any of a number of specified concepts. (@mikldk, #1232) ### Home, authors, and citation * pkgdown now escapes html and linkifies links in comments in author info from DESCRIPTION (@maelle, #1204) * pkgdown now uses the ORCiD logo included in Font Awesome 5.11 instead of querying it from members.orcid.org (@bisaloo, #1153) * badges are now extracted from everything between `<!--badges: start-->` and `<!--badges: end-->`. They used to be extracted only if they were direct children of the first `<p>` after `<!--badges: start-->`. * `build_home()` now looks for `pkgdown/index.md` in addition to the top-level `index` or `README` files (@nteetor, #1031) ### Navbar * pkgdown now formats the package version displayed in the navbar the same way as it has been specified in the DESCRIPTION file. In particular, version separators (e.g. `.` and `-`) are preserved. (#1170, @kevinushey) * add support for navbar submenus: you can create submenus following the convention established in [rstudio/rmarkdown#721](https://github.com/rstudio/rmarkdown/issues/721) (@ijlyttle, @wendtke, #1213) ### Other * Updated JS libraries: jquery 3.3.1 -> 3.4.1; bootswatch 3.3.7 -> 3.4.0; bootstrap 3.3.7 -> bootstrap 3.4.1; docsearch 2.6.1 -> 2.6.3 (@jayhesselberth). * Markdown conversion now explicitly allows markdown inside of HTML blocks; this was previously accidentally disabled (#1220). * A timestamp for the last site build is reported in `pkgdown.yml` (#1122). # pkgdown 1.4.1 * Don't install test package in user library (fixes CRAN failure). # pkgdown 1.4.0 ## New features * build citation as specified by the `textVersion` argument of `citEntry` in the `CITATION` file (#1096, @yiluheihei) * `build_site()`, `build_reference()` and `build_home()` gain a parameter `devel` which controls whether you're in deployment or development mode. It generalises and replaces (with deprecation) the existing `document` argument. Development mode is optimised for rapid iteration and is the default for `build_reference()`. It uses `pkgload::load_all()` to load code directly from disk in order. Deployment mode is slower, but guarantees correct results, and is the default for `build_site()`. It installs the package into a temporary library, and runs examples/articles in a new process. * `build_reference()` no longer runs `devtools::document()` (#1079) and `build_home()` no longer re-builds `README.Rmd` or `index.Rmd`. This makes the scope of responsibility of pkgdown more clear: it now only creates/modifies files in `doc/`. * `build_home()` now strips quotes from `Title` and `Description` fields when generating page metadata. Additionally, you can now override the defaults via the `title` and `description` fields in the `home` section of `_pkgdown.yml` (#957, @maelle). * `vignette("linking")` describes how pkgdown's automatic linking works, and how to ensure that cross-package links point to the right place. ## Bug fixes and minor improvements ### Rd translation * `\examples{}` rendering has been completely overhauled so it now first converts the entire mixed Rd-R block to R prior, and then evaluates the whole thing. This considerably improves the fidelity of the translation at a small cost of no longer being able to remove `\donttest{}` and friends (#1087). * `\item{}`s in `\describe{}` containing whitespace are translated correctly (#1117). * `\dots` and `\ldots` are translated to `...` instead of the ellipsis, since they're often found in code (#1114). * `\tabular{}` translation handles code better (@mitchelloharawild, #978). * `\subsection{}` contents are now treated as paragraphs, not inline text (#991). * `\preformatted{}` blocks preserve important whitespace (#951). ### Front end * Links to online documentation for functions in code chunks are no longer displayed when printing (#1135, @bisaloo). * Updated fontawesome to v5.7.1. fontawesome 5 [deprecated the `fa` prefix](https://fontawesome.com/how-to-use/on-the-web/setup/upgrading-from-version-4#changes). If you have used custom icons in your navbar, you'll should update them from (e.g.) `fa fa-home` to `fas fa-home`. Brands now have a separate prefix so `fa fa-github` becomes `fab fa-github` (#953). * The navbar is now automatically hidden with [headroom.js](https://wicky.nillia.ms/headroom.js/). * The sticky behaviour of the navbar is now implemented in pure CSS instead of relying a the 3rd party javascript library (#1016, @bisaloo) * Favicons are now automatically built from a package logo (#949). ### Linking * Infix operators (e.g., `%in%` and `%*%`) are now linked to their documentation (#1082). * Function names can now be included in headers without spurious auto-linking (#948). * Links to external documentation now point to [rdrr.io](https://rdrr.io) (#998). ### Other * News page recognises more version specifications (including the "(development version)" now used by usethis) (#980). * Subdirectories are supported for assets (#939, @ijlyttle). * A default 404 page (`404.html`) is built, unless a custom `.github/404.md` is provided (#947). * `build_article()` now uses the raw vignette title as page `<title>` and `og:title` (@maelle, #1037). * `build_home()` now looks for license files spelled either as LICENSE or LICENCE (#972). * `build_home()` can find badges in paragraph coming after the comment `<!-- badges: start -->` (#670, @gaborcsardi, @maelle). * `build_home()` will add a community section to the sidebar if there is either a code of conduct (`.github/CODE_OF_CONDUCT.md`) or a contributing guide (`.github/CONTRIBUTING.md`) (#1044, @maelle). * `build_reference()` gains a `topics` argument which allows you to re-build only specified topics. * `build_site(new_process = TRUE)` gains a timeout, `options(pkgdown.timeout = 10)`, that can be used to prevent stalled builds. * `deploy_site_github(install = FALSE)` makes it possible to opt out of installation. * `dev_mode()` now recognises `0.1.9000` as a development version of a package (this is an emerging standard we use for packages with backward incompatible changes) (#1101). # pkgdown 1.3.0 * Restore accidentally deleted `build_logo()` function so that logos are once more copied to the website. * Fix to `pkgdown.css` so page header has correct amount of top margin. * `content-home.html` template is no longer used when the homepage is an `.Rmd` (Reverts #834. Fixes #927, #929) * `deploy_site_github()` now passes parameters to `build_site()` (@noamross, #922), and the documentation gives slightly better advice. * Correct off-by-one error in navbar highlighting javascript; now no navbar is highlighted if none match the current path (#911). * Tweaking of HTML table classes was fixed (@yonicd, #912) * Restore accidentally removed `docsearch.css` file. # pkgdown 1.2.0 ## New features * `deploy_site_github()` can be used from continuous integration systems (like travis) to automatically deploy your package website to GitHub Pages. See documentation for how to set up details (@jimhester). * `build_favicon()` creates high resolution favicons from the package logo, and saves them in `pkgdown/`. They are created using the <https://realfavicongenerator.net/> API, and are better suited for modern web usage (e.g. retina display screens, desktop shortcuts, etc.). This also removes the dependency on the magick package, making automated deployment a little easier (@bisaloo, #883). * Users with limited internet connectivity can explicitly disable internet usage by pkgdown by setting `options(pkgdown.internet = FALSE)` (#774, #877). ## Improvements to Rd translation * `rd2html()` is now exported to facilitate creation of translation reprexes. * `\Sexpr{}` conversion supports multiple arguments, eliminating `x must be a string or a R connection` errors when using `\doi{}` (#738). * `\tabular{}` conversion better handles empty cells (#780). * `\usage{}` now supports qualified functions eliminating `Error in fun_info(x) : Unknown call: ::` errors (#795). * Invalid tags now generate more informative errors (@BarkleyBG, #771, #891) ## Front end * The default footer now displays the version of pkgdown used to build the site (#876). * All third party resources are now fetched from a single CDN and are give a SRI hash (@bisaloo, #893). * The navbar version now has class "version" so you can more easily control its display (#680). * The default css has been tweaked to ensure that icons are visible on all browsers (#852). ## Bug fixes and minor improvements ### Home page * Can now build sites for older packages that don't have a `Authors@R` field (#727). * Remote urls ending in `.md` are no longer tweaked to end in `.html` (#763). * Bug report link is only shown if there's a "BugReports" field (#855). * `content-home.html` template is now used when the homepage is an `.Rmd` (@goldingn, #787). * A link to the source `inst/CITATION` was added to the authors page (#714). ### News * Uses stricter regular expression when linking to GitHub authors (#902). ### Reference * Unexported functions and test helpers are no longer loaded (#789). * Selectors that do not match topics now generate a warning. If none of the specified selectors have a match, no topics are selected (#728). ### Articles * The display depth of vignette tables of contents can be configured by setting `toc: depth` in `_pkgdown.yml` (#821): ```yaml toc: depth: 2 ``` ### Overall site * `init_site()` now creates a CNAME file if one doesn't already exist and the site's metadata includes a `url` field. * `build_site()` loses vestigal `mathjax` parameter. This didn't appear to do anything and no one could remember why it existed (#785). * `build_site()` now uses colours even if `new_process = TRUE` (@jimhester). # pkgdown 1.1.0 ## New features * `build_reference()` and `build_site()` get new `document` argument. When `TRUE`, the default, will automatically run `devtools::document()` to ensure that your documentation is up to date. * `build_site()` gains a `new_process` argument, which defaults to `TRUE`. This will run pkgdown in a separate process, and is recommended practice because it improves reproducibility (#647). * Improved display for icons: icons must be 30px and stored in top-level `icons/` directory. They are embedded in a separate column of reference index table, instead of being inside a comment (!) (#607). ## Front end * Added a keyboard shortcut for searching. Press `shift` + `/` (`?`) to move focus to the search bar (#642). * The Algolia logo is correctly shown in the search results (#673). * Navbar active tab highlighting uses a superior approach (suggested by @jcheng5) which should mean that the active page is correctly highlighted in all scenarios (#660). * `pkgdown.js` is better isolated so it should still work even if you load html widgets that import a different version of jquery (#655). ## Improvements to Rd translation * `vignette()` calls that don't link to existing vignettes silently fail to link instead of generating an uninformative error messages (#652). Automatic linking works for re-exported objects that are not functions (@gaborcsardi, #666). * Empty `\section{}`s are ignored (#656). Previously, empty sections caused error `Error in rep(TRUE, length(x) - 1)`. * `\Sexpr{}` supports `results=text`, `results=Rd` and `results=hide` (#651). * `\tabular{}` no longer requires a terminal `\cr` (#664, #645). ## Minor bug fixes and improvements * Add `inst/pkgdown.yml` as a possible site configuration file so that packages on CRAN can be built without needing the development version (#662). * Default navbar template now uses site title, not package name (the package name is the default title, so this will not affect most sites) (#654). * You can suppress indexing by search engines by setting `noindex: true` `pkgdown.yml` (#686) ```yaml template: params: noindex: true ``` * `build_article()` sets `IN_PKGDOWN` env var so `in_pkgdown()` works (#650). * `build_home()`: CITATION files with non-UTF-8 encodings (latin1) work correctly, instead of generating an error. For non-UTF-8 locales, ensure you have e.g. `Encoding: latin1` in your `DESCRIPTION`; but best practice is to re-enode your CITATION file to UTF-8 (#689). * `build_home()`: Markdown files (e.g., `CODE_OF_CONDUCT.md`) stored in `.github/` are copied and linked correctly (#682). * `build_news()`: Multi-page changelogs (generated from `NEWS.md` with `news: one_page: false` in `_pkgdown.yml`) are rendered correctly. * `build_reference()`: reference index shows infix functions (like `%+%`) as `` `%+%` ``, not `` `%+%`() `` on (#659). # pkgdown 1.0.0 * Major refactoring of path handling. `build_` functions no longer take `path` or `depth` arguments. Instead, set the `destination` directory at the top level of `pkgdown.yml`. * Similarly, `build_news()` no longer takes a `one_page` argument; this should now be specified in the `_pkgdown.yml` instead. See the documentation for an example. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/���������������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14672347611�012713� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/������������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14633374223�013325� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/de/���������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14610517574�013720� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/de/LC_MESSAGES/���������������������������������������������������������������������0000755�0001762�0000144�00000000000�14634573316�015507� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/de/LC_MESSAGES/R-pkgdown.mo���������������������������������������������������������0000644�0001762�0000144�00000007360�14634573316�017722� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������D������<��a���\������������� ����� ����� ������������������ �����(�����=�����P�� ���a�����k�� ���t�����~�� �����2���������� ���������� ����� ����� ����� �������� �����)�� ���0�� ���=�����I�����`�����h�����n����������������� ���������� ����� ��������������� ����� ����������,��������>�����O�����V�����^�����p�� ������������������������� ����� ��������������� ����� ������������� ����� �� ��� �����$ �����- �� ���< ��;��G ����� ����� �� ��� �� ��� ����� ����� �� ��� ����� ����� ����� �����! �����5 �� ���H �����T �� ���e ��;���o ����� �� ��� ����� ����� ����� ����� ����� �� ��� �����' �����. �����C �����R �����i �����p �����v ����� �� ��� ����� ����� ����� �� ��� ����� ����� ����� �� ���+ �� ���6 �� ���B ��/���M �����} ����� ����� ����� ����� ����� ����� �� ��� �� ���������� ��������&�����5�����>�����Q�� ���b�����p������� ����� ����� ����������������������=���9�������8���"���.���C���)���&���;���������� ���5�������6��������� ������������������������������4����������������������������!�������2�����������%�������>���$��� ������*���D���<������ ���-���?���/���(������@����������+���0������B��������������7������������������������,��������������3���#�������'���:���������A���1��������� ������ ���������������������Abstract�All functions�All vignettes�Arguments�Articles�Author�Authors�Authors and Citation�Browse source code�CRAN release: %s�Changelog�Citation�Citing %s�Code of conduct�Community�Content not found. Please use links in the navbar.�Contributing guide�Description�Details�Dev Status�Dev status�Developed by�Developers�Examples�Format�Full license�Get started�In-development version�License�Links�More about authors...�More articles...�News�Note�On this page�Page not found (404)�Reference�References�Released version�Releases�Report a bug�Search for�See also�Site built with <a href="%s">pkgdown</a> %s.�Skip to contents�Source�Source:�Table of contents�Toggle navigation�Tutorials�Unreleased version�Usage�Value�Version�Version %s�View on %s�author�compiler�contractor�contributor�copyright holder�data contributor�funder�maintainer�reviewer�thesis advisor�translator�Project-Id-Version: pkgdown 1.9000.9000.9000 Report-Msgid-Bugs-To: PO-Revision-Date: 2021-10-28 08:02-0500 Last-Translator: Automatically generated Language-Team: none Language: de MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); �Kurzzusammenfassung�Alle Funktionen�Alle Artikel�Argumente�Artikel�Autor:in�Autor:innen�Autor:innen und Zitation�Quellcode ansehen�CRAN-Veröffentlichung: %s�Änderungsprotokoll�Zitationsvorschlag�%s zitieren�Verhaltensregeln�Community�Inhalt nicht gefunden. Bitte die Navigationleiste benutzen.�Leitfaden zum Mitwirken�Beschreibung�Details�Entwicklungsstatus�Entwicklungsstatus�Entwickelt von�Entwicker:innen�Beispiele�Format�Vollständige Lizenz�Erste Schritte�Version in Entwicklung�Lizenz�Links�Mehr zu den Autor:innen�Mehr Artikel ...�Neuigkeiten�Notiz�Auf dieser Seite�Seite nicht gefunden (404)�Verzeichnis�Literaturverzeichnis�Veröffentlichte Version�Veröffentlichungen�Bug melden�Suchen nach�Siehe auch�Seite erstellt mit <a href="%s">pkgdown</a> %s.�Direkt zum Inhalt springen�Quelle�Quelle:�Inhaltsverzeichnis�Navigation ein-/ausschalten�Tutorien�Unveröffentlichte Version�Verwendung�Rückgabewert�Version�Version %s�Auf %s ansehen�Autor:in�Zusammensteller:in�Auftragnehmer:in�Beitragende:r�Urheberrechtsinhaber:in�Datenbeitragende:r�Sponsor:in�Maintainer:in�Gutachter:in�Betreuer:in der Abschlussarbeit�Übersetzer:in���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/dk/���������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14633374223�013723� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/dk/LC_MESSAGES/���������������������������������������������������������������������0000755�0001762�0000144�00000000000�14641252443�015506� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/dk/LC_MESSAGES/R-pkgdown.mo���������������������������������������������������������0000644�0001762�0000144�00000007726�14641252443�017727� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������P��������k�������������������������� ����� ����� �������������(�����/�����7�����L�����Q�����d�� ���u������� ���������� �����2��������������� ���������� ��� �� ����� ���!�� ���.�����9�����B�� ���I�� ���V�� ���b�����o������������ ������������������������������ ����� ���������� ��� �� ��� ����� �����. �� ���7 �� ���D �����O ��,���X ����� ����� ����� ����� ����� �� ��� ����� ����� ����� ����� �� ��� �� ��� ����� ����� �� ��� �� ���+ �����7 �����H �� ���Y �� ���d �����q �� ���x ����� ����� �� ��� ����� �� ��� ����� ����� �� ��� ����� ����� ����� �� ��� ����� �� ��� �� ��� �����+ �����B �� ���G �����T �� ���g �� ���t �� ���~ ����� �� ��� ��1��� ����� ����� �� ��� ����� ����� ����� �� ���* �� ���6 �� ���@ �����J �� ���Q �� ���] �� ���g �����r ����� ����� �� ��� ����� ����� ����� ����� ����� ����� �� ��� ����� �� ��� �� ��������"�� ���2�����=�����P�����U��,���^��������������������������� ������������������������� ����� ����� ���#�����-�� ���6�� ���B�����N�����e�����u�� ���}������� ����� ���������� ���������� �����������3�����������1���8���N������6���B�������A����������� ��������������=�������������I���'���@���;������C���"���,��� ���#�������G���������� ��� ����������)���.���?���%���P���!���$�������4���H������������������+����������L������(����������������/������&������������������E������M���0���������*��� ���<���O���J���7���D��������������>���9����������-�������������F������2������:���������������5���K��� ����# Default %s method�Abstract�Additional details�All functions�All vignettes�Arguments�Articles�Author�Authors�Authors and Citation�Auto�Browse source code�CRAN release: %s�Changelog�Citation�Citing %s�Code of conduct�Community�Content not found. Please use links in the navbar.�Contributing guide�Dark�Description�Details�Dev Status�Dev status�Developed by�Developers�Examples�Format�Full license�Get started�Getting help�In-development version�License�Light�Light switch�Links�More about authors...�More articles...�News�Note�On this page�Package index�Page not found (404)�Reference�References�Released version�Releases�Report a bug�Search for�See also�Site built with <a href="%s">pkgdown</a> %s.�Skip to contents�Source�Source:�Table of contents�Toggle navigation�Tutorials�Unreleased version�Usage�Value�Version�Version %s�View on %s�author�compiler�contractor�contributor�copyright holder�data contributor�deprecated�experimental�funder�maintainer�reviewer�stable�superseded�thesis advisor�translator�Project-Id-Version: pkgdown 2.0.1.9000 PO-Revision-Date: 2021-12-20 18:48+0100 Last-Translator: Automatically generated Language-Team: none Language: dk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit �# Standard %s metode�Sammenfatning�Yderligere detaljer�Alle funktioner�Alle vignetter�Argumenter�Artikler�Forfatter�Forfattere�Forfattere og citation�Auto�Se kildekode�CRAN udgivelse: %s�Ændringslog�Reference�Citér %s�Etisk regelsæt�Fællesskab�Indhold ikke fundet. Brug venligst links i menuen�Guide til bidragsydere�Mørk�Beskrivelse�Detaljer�Udviklingsstatus�Udviklingsstatus�Udviklet af�Udviklere�Eksempler�Format�Fuld licens�Kom igang�Få hjælp�Version under udvikling�Licens�Lys�Lyskontakt�Links�Mere om forfatterene�Flere artikler...�Nyheder�Note�På denne side�Pakke indeks�Side ikke fundet (404)�Reference�Referencer�Udgivet version�Udgivelser�Rapportér en fejl�Søg�Se også�Side bygget med <a href="%s">pkgdown</a> %s.�Spring til indhold�Kilde�Kilde:�Indholdsfortegnelse�Slå navigation til og fra�Vejledning�Ikke-udgivet version�Brug�Værdi�Version�Version %s�Se på %s�forfatter�compiler�leverandør�Bidragsyder�Indehaver af ophavsret�dataleverandør�udfaset�eksperimentel�bevilgingsgiver�maintainer�bedømmer�stabil�erstattet�vejleder�oversætter�������������������������������������������pkgdown/inst/po/tr/���������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14140760567�013755� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/tr/LC_MESSAGES/���������������������������������������������������������������������0000755�0001762�0000144�00000000000�14641277402�015537� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/tr/LC_MESSAGES/R-pkgdown.mo���������������������������������������������������������0000644�0001762�0000144�00000010525�14641277402�017747� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������S��������q���L����������������,�����@�����I�� ���\�� ���j�� ���x������������������������������������� ���������� ���������� �����2��������B�����U�� ���Z�����f�� ���n�� ���y�� ����� ��������������� ����� ����� �������������������� �������� ����� ����� �����1 �����6 �� ���; �� ���H �����V �� ���k �� ���u ����� ����� �� ��� �� ��� �� ��� ����� ��,��� ����� ����� ����� ����� �����$ �����6 �� ���H �����R �����e �����k �����q �� ���y �� ��� ����� ����� �� ��� �� ��� ����� ����� �� ��� �� ��� ����� �� ��� ����� ����� �� ��� ����� �� ���, ��;��7 �����s ����� ����� �� ��� ����� ����� �� ��� �� ��� ����� ����� ����� ����� ����� �����2 �����D �����] �����f �����} �� ��� ��U��� ����� ����� �� �������������'�����=�� ���S�����_�� ���o�����y�� ���������������"��������������� ����� �����&�������� ����������'�� ���+�� ���6�����C�����\�� ���e�����q�� ����� ��������������� �����8������������������ ������� ��������&�� ���:�����H�� ���a�����k�����r�� ���z�� ���������� ����� ����� ������������������������������� ����� ��������'�� ���-�����:�� ���K�����*���@�������������E��� ���(��������������$���+��� ���K���O���N���������������������F���"�����������������B���#���L�����������������1���4���8����������?������Q���S������/�������%���!������������� ���������2�����������G��� ���I������<���)��� �����������3���J���������������5���H������������������'���R������0���M������:�������,���=�������9��������������-�������6���;���7���A������D������� ���&���.���C�������P������������>����# %s method for class '%s'�# Default %s method�Abstract�Additional details�All functions�All vignettes�Arguments�Articles�Author�Authors�Authors and Citation�Auto�Browse source code�CRAN release: %s�Changelog�Citation�Citing %s�Code of conduct�Community�Content not found. Please use links in the navbar.�Contributing guide�Dark�Description�Details�Dev Status�Dev status�Developed by�Developers�Examples�Format�Full license�Get started�Getting help�In-development version�License�Light�Light switch�Links�More about authors...�More articles...�News�Note�On this page�Package index�Page not found (404)�Reference�References�Released version�Releases�Report a bug�Search for�Search site�See also�Site built with <a href="%s">pkgdown</a> %s.�Site navigation�Skip to contents�Source�Source:�Table of contents�Toggle navigation�Tutorials�Unreleased version�Usage�Value�Version�Version %s�View on %s�author�compiler�contractor�contributor�copyright holder�data contributor�deprecated�experimental�funder�maintainer�reviewer�stable�superseded�thesis advisor�translator�Project-Id-Version: pkgdown 1.9000.9000.9000 Report-Msgid-Bugs-To: PO-Revision-Date: 2021-10-28 08:02-0500 Last-Translator: Automatically generated Language-Team: none Language: tr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); �# %s için %s metodu�# Varsayılan %s metodu�Özet�Ek detaylar�Bütün fonksiyonlar�Bütün makaleler�Argümanlar�Makaleler�Yazar�Yazarlar�Yazarlar ve Alıntı�Otomatik�Kaynak koduna göz at�CRAN yayını: %s�Değişiklik günlüğü�Alıntı�%s'ı kaynak gösterme�Davranış kuralları�Komünite�İçerik bulunamıyor. Lütfen yukarıdaki gezinme çubuğundaki bağları kullanın.�Katkıda bulunma rehberi�Açık�Açıklama�Detaylar�Geliştirme statüsü�Geliştirme statüsü�Geliştiren�Geliştiriciler�Örnekler�Format�Tam lisans�Başla�Yardım�Geliştirme aşamasındaki sürüm�Lisans�Koyu�Koyu/açık�Bağlantılar�Yazarlar hakkında daha fazla bilgi...�Diğer makaleler...�Haberler�Not�Bu sayfada�Paket dizini�Sayfa bulunamıyor (404)�Referans�Referanslar�Yayımlanan sürüm�Yayınlar�Hata bildir�Ara�Ara�Ayrıca bak�Site <a href="%s">pkgdown</a> %s ile geliştirilmiştir.�Site navigasyonu�İçeriğe atla�Kaynak�Kaynak:�İçindekiler�Gezinmeyi aç/kapat�Öğreticiler�Yayınlanmamış sürüm�Kullanım�Değer�Sürüm�Sürüm %s�%s'da gör�yazar�derleyici�yüklenici�katılımcı�telif hakkı sahibi�veri katılımcısı�artık kullanılmayan�deneysel�fon sağlayıcı�bakımcı�eleştirmen�sabit�yerine gelen�tez danışmanı�çevirmen����������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/fr/���������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14137761366�013743� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/fr/LC_MESSAGES/���������������������������������������������������������������������0000755�0001762�0000144�00000000000�14641277402�015521� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/fr/LC_MESSAGES/R-pkgdown.mo���������������������������������������������������������0000644�0001762�0000144�00000010737�14641277402�017736� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������S��������q���L����������������,�����@�����I�� ���\�� ���j�� ���x������������������������������������� ���������� ���������� �����2��������B�����U�� ���Z�����f�� ���n�� ���y�� ����� ��������������� ����� ����� �������������������� �������� ����� ����� �����1 �����6 �� ���; �� ���H �����V �� ���k �� ���u ����� ����� �� ��� �� ��� �� ��� ����� ��,��� ����� ����� ����� ����� �����$ �����6 �� ���H �����R �����e �����k �����q �� ���y �� ��� ����� ����� �� ��� �� ��� ����� ����� �� ��� �� ��� ����� �� ��� ����� ����� �� ��� ����� �� ���, ��2��7 �����j ����� ����� ����� ����� ����� �� ��� ����� ����� ����� ����� �� ���4 �����@ �����X �� ���j �����v ����� ����� �� ��� ��J��� ����� ������� ��� ����������"�����;�����T�����d�����x������������ ������������������������� ���������� ���������� ���)�����5�����:�����I�����\�� ���s�� �������������������� ���������������-��������"�����9�����K�����R�����[�����o�� ���������� ��������������� ����� ����� ������������������ ����������<�� ���\�����f�����u������� ���������� ������������������*���@�������������E��� ���(��������������$���+��� ���K���O���N���������������������F���"�����������������B���#���L�����������������1���4���8����������?������Q���S������/�������%���!������������� ���������2�����������G��� ���I������<���)��� �����������3���J���������������5���H������������������'���R������0���M������:�������,���=�������9��������������-�������6���;���7���A������D������� ���&���.���C�������P������������>����# %s method for class '%s'�# Default %s method�Abstract�Additional details�All functions�All vignettes�Arguments�Articles�Author�Authors�Authors and Citation�Auto�Browse source code�CRAN release: %s�Changelog�Citation�Citing %s�Code of conduct�Community�Content not found. Please use links in the navbar.�Contributing guide�Dark�Description�Details�Dev Status�Dev status�Developed by�Developers�Examples�Format�Full license�Get started�Getting help�In-development version�License�Light�Light switch�Links�More about authors...�More articles...�News�Note�On this page�Package index�Page not found (404)�Reference�References�Released version�Releases�Report a bug�Search for�Search site�See also�Site built with <a href="%s">pkgdown</a> %s.�Site navigation�Skip to contents�Source�Source:�Table of contents�Toggle navigation�Tutorials�Unreleased version�Usage�Value�Version�Version %s�View on %s�author�compiler�contractor�contributor�copyright holder�data contributor�deprecated�experimental�funder�maintainer�reviewer�stable�superseded�thesis advisor�translator�Project-Id-Version: pkgdown 2.0.9.9000 Report-Msgid-Bugs-To: PO-Revision-Date: 2024-06-15 20:28-0400 Last-Translator: J.P. Le Cavalier <jplecavalier@me.com> Language-Team: fr Language: fr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Generator: potools 0.2.2 �# Méthode %s pour la classe %s�# Méthode %s par défaut�Résumé�Détails supplémentaires�Toutes les fonctions�Tous les articles�Arguments�Articles�Auteur�Auteur·rice·s�Auteur·rice·s et Citation�Automatique�Naviguer le code source�Version CRAN : %s�Changements�Citation�Citer %s�Code de conduite�Communauté�Contenu introuvable. Merci d'utiliser les liens de la barre de navigation.�Guide de contribution�Sombre�Description�Détails�Statut de développement�Statut de développement�Développé par�Développeur·se·s�Exemples�Format�Licence complète�Prise en main�Obtenir de l'aide�Version en développement�Licence�Clair�Interrupteur�Liens�À propos des auteur·rice·s...�Plus d'articles...�Nouveautés�Note�Sur cette page�Index du paquetage�Page introuvable (404)�Référence�Références�Dernière version publiée�Versions�Signaler un bogue�Rechercher�Rechercher sur le site�Voir également�Site créé avec <a href="%s">pkgdown</a> %s.�Navigation sur le site�Passer au contenu�Source�Source :�Table des matières�Activer la navigation�Tutoriels�Version inédite�Utilisation�Valeur de retour�Version�Version %s�Voir sur %s�auteur·rice�compilateur·rice�fournisseur·se�contributeur·rice�titulaire des droits d'auteur�contributeur·rice des données�obsolète�expérimentale�fondateur·rice�mainteneur·se�réviseur·se�stable�remplacée�directeur·rice de thèse�traducteur·rice����������������������������������pkgdown/inst/po/kr/���������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14633374223�013741� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/kr/LC_MESSAGES/���������������������������������������������������������������������0000755�0001762�0000144�00000000000�14633374223�015526� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/kr/LC_MESSAGES/R-pkgdown.mo���������������������������������������������������������0000644�0001762�0000144�00000007264�14633374223�017744� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������E������D��a���l������������������ ��� �� ��������%�����.�����5�����=�����R�����e�� ���v������� ���������� �����2���������� ���������� ����� ����� ����� ���*�����5�����>�� ���E�����R�� ���e�����q�������������������������������� ���������� ����� ��������������� ����� ���%�����0��,���9�����f�����w�����~������������ ������������������������� ����� ��������������� ��� �� ��� ����� �����) �����: �� ���A �����L �����U �� ���d ��(��o ����� ����� ��!��� ����� ����� ����� �� ���� ����� ����� �����/ �� ���? �����L �����S �� ���c �� ���p ��Z���} ����� ����� �� ��� �� ��� �� ��� �� ��� �� ���$ �� ���1 �����> �����E �����Y �� ���m �� ���z �� ��� ����� ����� �� ��� ����� ����� ����� ��*��� ����� ����� �� ��� �����$ �� ���+ �����9 �� ���@ ��G���K ����� �� ��� �� ��� ����� ����� �� ��� ����� �� ��������������� ��������&�����8�� ���?�� ���I�� ���S�� ���]�����j�����~�� ����� ���������� ������������ ���:���>���9���#������D���*���'���<�������������/�������7��� ������ ������������������������������5����������������������������"�������3�����������&�������?���%��� ������+���E���=������ ���.���@���0���)������A����������,���1������C�����������!���8�����������������6������-��������������4���$�������(���;���������B���2��������� ����������������������������# %s method for %s�Abstract�All vignettes�Arguments�Articles�Author�Authors�Authors and Citation�Browse source code�CRAN release: %s�Changelog�Citation�Citing %s�Code of conduct�Community�Content not found. Please use links in the navbar.�Contributing guide�Description�Details�Dev Status�Dev status�Developed by�Developers�Examples�Format�Full license�Function reference�Get started�In-development version�License�Links�More about authors...�More articles...�News�Note�On this page�Page not found (404)�Reference�References�Released version�Releases�Report a bug�Search for�See also�Site built with <a href="%s">pkgdown</a> %s.�Skip to contents�Source�Source:�Table of contents�Toggle navigation�Tutorials�Unreleased version�Usage�Value�Version�Version %s�View on %s�author�compiler�contractor�contributor�copyright holder�data contributor�funder�maintainer�reviewer�thesis advisor�translator�Project-Id-Version: pkgdown 1.9000.9000.9000 POT-Creation-Date: 2021-11-26 15:57-0600 PO-Revision-Date: 2021-11-26 15:57-0600 Last-Translator: Automatically generated Language-Team: @mrchypark Language: kr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit �# %s 타입인 %s의 메소드�초록�전체 사용설명서(비네트)�인수�관련 글 목록�저자�저자들�저자와 인용�소스코드 확인�CRAN 배포: %s�변경사항�인용�%s 인용하기�행동강령�커뮤니티�콘텐츠를 찾을 수 없습니다. 네비게이션 바의 링크를 이용해주세요.�기여 가이드�설명�세부사항�개발 상태�개발 상태�개발자:�개발자들�예시코드�양식�전체 라이선스�함수 레퍼런스�시작하기�개발 버전�라이선스�링크�저자에 대한 부분은...�더 보기...�뉴스�노트�목차�페이지를 찾을 수 없습니다 (404)�참조�참조�배포 버전�배포�버그 신고�검색�더 보기�현재 사이트는 <a href="%s">pkgdown</a> %s 로 만들었습니다.�콘텐츠로 바로가기�소스코드�소스코드:�목차�네비게이션바 열기�튜토리얼�배포전 버전�사용법�값�버전�버전 %s�(%s)에서 보기�저자�편집자�계약자�기여자�저작권자�데이터 기여자�자금 제공자�관리자�리뷰어�고문�번역자���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/es/���������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14137761366�013743� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/es/LC_MESSAGES/���������������������������������������������������������������������0000755�0001762�0000144�00000000000�14641277402�015521� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/es/LC_MESSAGES/R-pkgdown.mo���������������������������������������������������������0000644�0001762�0000144�00000010426�14641277402�017731� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������P��������k�������������������������� ����� ����� �������������(�����/�����7�����L�����Q�����d�� ���u������� ���������� �����2��������������� ���������� ��� �� ����� ���!�� ���.�����9�����B�� ���I�� ���V�� ���b�����o������������ ������������������������������ ����� ���������� ��� �� ��� ����� �����. �� ���7 �� ���D �����O ��,���X ����� ����� ����� ����� ����� �� ��� ����� ����� ����� ����� �� ��� �� ��� ����� ����� �� ��� �� ���+ �����7 �����H �� ���Y �� ���d �����q �� ���x ����� ����� �� ��� ����� �� ��� ���� �����? �����X �����` �����u ����� �� ��� �� ��� ����� ����� ����� ����� ����� ����� ������ ����� ����� �����( �� ���< ��R���F ����� ����� �� ��� ����� ����� ����� ����� ����� ����������#�����+�����=�����L�����\�����s�����|���������������������������������������������������� ���"�����.�� ���A�����N�����f�� ���m��-���z��������������������������� ������������������������ �� ���)�� ���5�����?�� ���G�� ���T�� ���`�� ���n������������ ���������� ����� ���������� ���������� ��� ��������3�����������1���8���N������6���B�������A����������� ��������������=�������������I���'���@���;������C���"���,��� ���#�������G���������� ��� ����������)���.���?���%���P���!���$�������4���H������������������+����������L������(����������������/������&������������������E������M���0���������*��� ���<���O���J���7���D��������������>���9����������-�������������F������2������:���������������5���K��� ����# Default %s method�Abstract�Additional details�All functions�All vignettes�Arguments�Articles�Author�Authors�Authors and Citation�Auto�Browse source code�CRAN release: %s�Changelog�Citation�Citing %s�Code of conduct�Community�Content not found. Please use links in the navbar.�Contributing guide�Dark�Description�Details�Dev Status�Dev status�Developed by�Developers�Examples�Format�Full license�Get started�Getting help�In-development version�License�Light�Light switch�Links�More about authors...�More articles...�News�Note�On this page�Package index�Page not found (404)�Reference�References�Released version�Releases�Report a bug�Search for�See also�Site built with <a href="%s">pkgdown</a> %s.�Skip to contents�Source�Source:�Table of contents�Toggle navigation�Tutorials�Unreleased version�Usage�Value�Version�Version %s�View on %s�author�compiler�contractor�contributor�copyright holder�data contributor�deprecated�experimental�funder�maintainer�reviewer�stable�superseded�thesis advisor�translator�Project-Id-Version: pkgdown 2.0.9.9000 Report-Msgid-Bugs-To: PO-Revision-Date: 2024-06-17 07:31+0000 Last-Translator: @dieghernan Language-Team: es Language: es MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=n != 1; X-Loco-Source-Locale: es_ES X-Generator: Loco https://localise.biz/ X-Loco-Parser: loco_parse_po �# Método %s por defecto�Resumen�Detalles adicionales�Todas las funciones�Todos los artículos�Argumentos�Artículos�Autor-a�Autores�Autores y Citas�Auto�Ir al código fuente�Versión CRAN: %s�Registro de cambios�Cita�Cómo citar %s�Código de conducta�Comunidad�Contenido no encontrado. Por favor utilice los enlaces de la barra de navegación.�Guía para colaboradores�Oscuro�Descripción�Detalles�Estado de Desarrollo�Estado de desarrollo�Desarrollado por�Desarrolladores�Ejemplos�Formato�Licencia completa�Primeros pasos�Ayuda y soporte�Versión en desarrollo�Licencia�Claro�Interruptor de color�Enlaces�Más sobre los autores...�Más artículos...�Noticias�Nota�En esta página�Índice del paquete�Página no encontrada (404)�Índice�Referencias�Versión publicada�Lanzamientos�Informar de un problema�Buscar�Ver también�Sitio creado con <a href="%s">pkgdown</a> %s.�Ir al contenido�Fuente�Código:�Índice de contenidos�Cambiar la navegación�Tutoriales�Versión no publicada�Uso�Valor�Versión�Versión %s�Ver en %s�autor-a�compilador-a�contratista�colaborador-a�titular de los derechos de autor�colaborador-a de datos�obsoleta�experimental�patrocinador-a�mantenedor-a�revisor-a�estable�reemplazada�director-a de tesis�traductor-a�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/ca/���������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14633374223�013710� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/ca/LC_MESSAGES/���������������������������������������������������������������������0000755�0001762�0000144�00000000000�14641277402�015475� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/ca/LC_MESSAGES/R-pkgdown.mo���������������������������������������������������������0000644�0001762�0000144�00000010616�14641277402�017706� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������S��������q���L����������������,�����@�����I�� ���\�� ���j�� ���x������������������������������������� ���������� ���������� �����2��������B�����U�� ���Z�����f�� ���n�� ���y�� ����� ��������������� ����� ����� �������������������� �������� ����� ����� �����1 �����6 �� ���; �� ���H �����V �� ���k �� ���u ����� ����� �� ��� �� ��� �� ��� ����� ��,��� ����� ����� ����� ����� �����$ �����6 �� ���H �����R �����e �����k �����q �� ���y �� ��� ����� ����� �� ��� �� ��� ����� ����� �� ��� �� ��� ����� �� ��� ����� ����� �� ��� ����� �� ���, ��M��7 ��#��� ����� ����� ����� ����� ����� �� ��� ����� ����� ����� �����$ �� ���6 �����A �����V �����k �����~ �� ��� ����� �� ��� ��J��� ����� ����� �� �������������$�����=�����V�����g�����w��������������������������� ��������������� �������������������*�����3�����8�����K�����]�� ���}�� ������������������������� ����� �����0�������������*�����?�����D�����J�����^�����t���������������������� ����� ���������� ����� �����������������������'�� ���0�� ���=�� ���I�����T�����\�� ���d�����q�� ��������*���@�������������E��� ���(��������������$���+��� ���K���O���N���������������������F���"�����������������B���#���L�����������������1���4���8����������?������Q���S������/�������%���!������������� ���������2�����������G��� ���I������<���)��� �����������3���J���������������5���H������������������'���R������0���M������:�������,���=�������9��������������-�������6���;���7���A������D������� ���&���.���C�������P������������>����# %s method for class '%s'�# Default %s method�Abstract�Additional details�All functions�All vignettes�Arguments�Articles�Author�Authors�Authors and Citation�Auto�Browse source code�CRAN release: %s�Changelog�Citation�Citing %s�Code of conduct�Community�Content not found. Please use links in the navbar.�Contributing guide�Dark�Description�Details�Dev Status�Dev status�Developed by�Developers�Examples�Format�Full license�Get started�Getting help�In-development version�License�Light�Light switch�Links�More about authors...�More articles...�News�Note�On this page�Package index�Page not found (404)�Reference�References�Released version�Releases�Report a bug�Search for�Search site�See also�Site built with <a href="%s">pkgdown</a> %s.�Site navigation�Skip to contents�Source�Source:�Table of contents�Toggle navigation�Tutorials�Unreleased version�Usage�Value�Version�Version %s�View on %s�author�compiler�contractor�contributor�copyright holder�data contributor�deprecated�experimental�funder�maintainer�reviewer�stable�superseded�thesis advisor�translator�Project-Id-Version: pkgdown 2.0.6.9000 PO-Revision-Date: 2024-06-16 09:24+0200 Last-Translator: Joan Maspons <joanmaspons@gmail.com> Language: ca MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=n != 1; X-Generator: Lokalize 24.05.0 Language-Team: Catalan <> �# Mètode %s per a la classe «%s»�# Mètode %s per defecte�Resum�Detalls addicionals�Totes les funcions�Totes les vinyetes�Paràmetres�Articles�Autor�Autors�Autors i citació�Automàtic�Navega pel codi font�Versió del CRAN: %s�Registre de canvis�Citació�Citant %s�Codi de conducta�Comunitat�No s'ha trobat el contingut. Useu els enllaços de la barra de navegació.�Guia per contribuir�Fosc�Descripció�Detalls�Estat de desenvolupament�Estat de desenvolupament�Desenvolupat per�Desenvolupadors�Exemples�Format�Llicència completa�Comenceu�Obtenció d'ajuda�Versió en desenvolupament�Llicència�Clar�Interruptor de color�Enllaços�Més sobre els autors...�Més articles...�Novetats�Nota�En aquesta pàgina�Índex del paquet�No s'ha trobat la pàgina (404)�Referència�Referències�Versió publicada�Versions�Informa d'un error�Cerca�Cerca al lloc�Vegeu també�Lloc construït amb <a href="%s">pkgdown</a> %s.�Navegació del lloc�Salta als continguts�Font�Font:�Taula de continguts�Commuta la navegació�Guies d'aprenentatge�Versió no publicada�Ús�Valor�Versió�Versió %s�Mostra a %s�autor�compilador�contractista�col·laborador�titular dels drets d'autor�col·laborador de dades�obsoleta�experimental�finançador�mantenidor�revisor�estable�reemplaçada�supervisor de tesi�traductor�������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/pt/���������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14633374223�013750� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/pt/LC_MESSAGES/���������������������������������������������������������������������0000755�0001762�0000144�00000000000�14634573316�015542� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/pt/LC_MESSAGES/R-pkgdown.mo���������������������������������������������������������0000644�0001762�0000144�00000006552�14634573316�017757� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������?��������Y��� ������p�����q�� ���z��������������������������� ����� ���������� �����2��������!�� ���4�����@�� ���H�� ���S�� ���^�� ���k�����v������� ����� ���������������������������������������� ���������� ����� ���!�����,�����=�� ���F�� ���S�����^��,���g��������������������������� �������������������� ����� ������������� �� ���)�� ���4�����@�����Q�����b�� ���i�����t�����}�� ����� ������� �� ��� ����� ����� ����� ����� ����� �� ��� �� ��� �����% �� ���8 ��:���C �����~ �� ��� ����� ����� ����� ����� ����� ����� ����� ����� �����" �����3 �����N �����W �����] �����s ����� ����� �� ��� ����� �� ��� �� ��� ����� �� ��� ����� ����� �� ��� ��,��� �����H �����` �����f �����m �����u �� ��� ����� ����� ����� �� ��� �� ��� ����� �� ��� �� ��� �� ��� ����� ����� �� ���/ �� ���; �����F �����N �����a ����������������������������!���(�������;����������:�����������2��������������/���9�������<������ �������-���3���.����������������������6���'��� ������%������������������0���4�����������������������������������������������&�����������=������ ���#���5���$������?���,��������� �������*���+���8���)���"�������1���7��� ������>��� �������Abstract�Arguments�Articles�Author�Authors�Browse source code�CRAN release: %s�Changelog�Citing %s�Code of conduct�Community�Content not found. Please use links in the navbar.�Contributing guide�Description�Details�Dev Status�Dev status�Developed by�Developers�Examples�Format�Full license�Get started�In-development version�License�Links�More about authors...�More articles...�News�Note�On this page�Page not found (404)�Reference�References�Released version�Releases�Report a bug�Search for�See also�Site built with <a href="%s">pkgdown</a> %s.�Skip to contents�Source�Source:�Table of contents�Toggle navigation�Tutorials�Unreleased version�Value�Version�Version %s�View on %s�author�compiler�contractor�contributor�copyright holder�data contributor�funder�maintainer�reviewer�thesis advisor�translator�Project-Id-Version: pkgdown 1.9000.9000.9000 PO-Revision-Date: 2021-11-12 15:18-0500 Last-Translator: Language-Team: Language: pt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Generator: Poedit 3.0 Plural-Forms: nplurals=2; plural=(n > 1); �Resumo�Argumentos�Artigos�Autor�Autores�Navegue pelo código-fonte�Lançamento CRAN: %s�Changelog�Citando %s�Código de conduta�Comunidade�Conteúdo não encontrado. Por favor, use links na navbar.�Guia de contribuição�Descrição�Detalhes�Estado de Desenvolvimento�Status de desenvolvimento�Desenvolvido por�Desenvolvedores�Exemplos�Formato�Licença completa�Primeiros passos�Versão em desenvolvimento�Licença�Links�Mais sobre autores...�Mais artigos...�Notícia�Nota�Nesta página�Página não encontrada (404)�Referência�Referências�Versão lançada�Lançamentos�Reportar um erro�Procurar�Veja também�Site criado com <a href="%s">pkgdown</a> %s.�Avance para o conteúdo�Fonte�Fonte:�Índice�Alternar de navegação�Tutoriais�Versão não lançada�Valor�Versão�Versão %s�Veja no %s�autor�compilador�contratante�contribuinte�titular dos direitos autorais�contribuidor de dados�financiador�mantenedor�revisor�orientador de tese�tradutor�������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/zh_CN/������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14140323600�014310� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/zh_CN/LC_MESSAGES/������������������������������������������������������������������0000755�0001762�0000144�00000000000�14634573316�016120� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/zh_CN/LC_MESSAGES/R-pkgdown.mo������������������������������������������������������0000644�0001762�0000144�00000006303�14634573316�020327� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������?��������Y��� ������p�����q�� ���z��������������������������� ����� ���������� �����2��������!�� ���4�����@�� ���H�� ���S�� ���^�� ���k�����v������� ����� ���������������������������������������� ���������� ����� ���!�����,�����=�� ���F�� ���S�����^��,���g��������������������������� �������������������� ����� ������������� �� ���)�� ���4�����@�����Q�����b�� ���i�����t�����}�� ������������ ����� ����� ����� ����� ����� ����� �� ��� �� ��� �� ��� ����� ��<��� �� ���\ �����i �����p �� ���w �� ��� �� ��� �� ��� ����� ����� ����� �� ��� ����� ����� ����� ����� ����� ����� ����� �� ���% �����/ �����H �� ���O �����\ �� ���o �� ���| ����� �� ��� ��2��� �� ��� ����� �� ��� ����� ����� ����� ����� �����+ �����/ �����6 �����= �����F �� ���M �� ���W �� ���d �����n �����~ �� ��� �� ��� �� ��� �� ��� �� ��� ����������������������������!���(�������;����������:�����������2��������������/���9�������<������ �������-���3���.����������������������6���'��� ������%������������������0���4�����������������������������������������������&�����������=������ ���#���5���$������?���,��������� �������*���+���8���)���"�������1���7��� ������>��� �������Abstract�Arguments�Articles�Author�Authors�Browse source code�CRAN release: %s�Changelog�Citing %s�Code of conduct�Community�Content not found. Please use links in the navbar.�Contributing guide�Description�Details�Dev Status�Dev status�Developed by�Developers�Examples�Format�Full license�Get started�In-development version�License�Links�More about authors...�More articles...�News�Note�On this page�Page not found (404)�Reference�References�Released version�Releases�Report a bug�Search for�See also�Site built with <a href="%s">pkgdown</a> %s.�Skip to contents�Source�Source:�Table of contents�Toggle navigation�Tutorials�Unreleased version�Value�Version�Version %s�View on %s�author�compiler�contractor�contributor�copyright holder�data contributor�funder�maintainer�reviewer�thesis advisor�translator�Project-Id-Version: pkgdown 1.9000.9000.9000 Report-Msgid-Bugs-To: PO-Revision-Date: 2021-10-28 08:02-0500 Last-Translator: Automatically generated Language-Team: none Language: zh_CN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit �摘要�参数�文章�作者�作者�浏览源代码�CRAN发布版本:%s�更改日志�引用 %s�行为准则�社区�请求的页面未找到。请使用导航栏内的链接。�开发指南�概述�细节�开发状态�开发状态�开发者:�开发者�范例�格式�许可全部条款�入门简介�开发中的版本�许可�链接�关于作者…�更多文章…�新闻�注释�该页面�页面未找到(404)�参考�参考文献�已发布的版本�发布版本�缺陷报告�搜索�相关话题�该网站由 <a href="%s">pkgdown</a> %s 构建。�跳到正文�参考文献出处�来源:�目录�切换导航栏�教程�未发布的版本�值�版本�%s 版�访问%s�作者�编译者�合同员工�合作者�版权所有者�数据提供者�赞助者�维护者�审核者�论文导师�翻译者������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/ko/���������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14633374223�013736� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/ko/LC_MESSAGES/���������������������������������������������������������������������0000755�0001762�0000144�00000000000�14634573316�015530� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/po/ko/LC_MESSAGES/R-pkgdown.mo���������������������������������������������������������0000644�0001762�0000144�00000007034�14634573316�017741� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������C������4��Y���L������������� ����� ����������������������������������� ���#�����-�� ���6�����@�� ���P��2���Z������� ���������� ����� ����� ����� ��������������� ����� �������� �����"�����*�����0�����F�����W�����\�� ���a�����n�� ����� ��������������� ����� ����������,������������������������ �����2�� ���D�����N�����a�����g�����m�� ���u�� ��������������� ����� �������������������� ��������������� ����� �� ����� ��!��� �����= �����D �����V �� ���] �����g �����x ����� �� ��� ����� ����� �� ��� �� ��� ��[��� �����7 �����H �� ���O �� ���\ �� ���j �� ���x �� ��� �� ��� ����� ����� �� ��� �� ��� �� ��� ����� ����� �� ��� ����� ����� �����" ��*���) �����T �����[ �� ���b �� ���p �� ���z ����� �� ��� ��\��� ����� �� ��� �� ��� �����, �����3 �� ���M �����Z �� ���k �����u �����y �� ��� ����� ����� �� ��� �� ��� �� ��� �� ��� ����� ����� �� ��� �� ��� �� ����� �����������"��������������������$���+�������?��� �������>�������0���6��������������2���=�������@������������� ������1����������7�����������:���*��� ������(������������������3���8��� ���������������������� ������!�����������4���)�����������A���������&���9���'������C���/���������#�������-���.���<���,���%�������5���;���������B��� �������Abstract�All vignettes�Arguments�Articles�Author�Authors�Authors and Citation�Browse source code�CRAN release: %s�Changelog�Citation�Citing %s�Code of conduct�Community�Content not found. Please use links in the navbar.�Contributing guide�Description�Details�Dev Status�Dev status�Developed by�Developers�Examples�Format�Full license�Get started�In-development version�License�Links�More about authors...�More articles...�News�Note�On this page�Page not found (404)�Reference�References�Released version�Releases�Report a bug�Search for�See also�Site built with <a href="%s">pkgdown</a> %s.�Skip to contents�Source�Source:�Table of contents�Toggle navigation�Tutorials�Unreleased version�Usage�Value�Version�Version %s�View on %s�author�compiler�contractor�contributor�copyright holder�data contributor�funder�maintainer�reviewer�thesis advisor�translator�Project-Id-Version: pkgdown 1.9000.9000.9000 PO-Revision-Date: 2021-11-26 15:57-0600 Last-Translator: Chanyub Park <mrchypark@gmail.com> Language-Team: @mrchypark Language: ko MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit �초록�전체 사용설명서(비네트)�인수�관련 글 목록�저자�저자들�저자와 인용�소스코드 보기�CRAN 배포: %s�변경 사항�인용�%s 인용하기�행동강령�커뮤니티�콘텐츠를 찾을 수 없습니다. 네비게이션 바의 링크를 이용해 주세요.�기여 가이드�설명�세부사항�개발 상태�개발 상태�개발자:�개발자들�예시 코드�양식�전체 라이선스�시작하기�개발 버전�라이선스�링크�저자에 대한 부분은...�더 보기...�뉴스�노트�목차�페이지를 찾을 수 없습니다 (404)�참조�참조�배포 버전�릴리즈�버그 신고�검색�더 보기�현재 사이트는 다음 패키지로 생성하였습니다. - <a href="%s">pkgdown</a> %s�콘텐츠로 바로가기�소스코드�소스코드:�목차�네비게이션바 열기�튜토리얼�배포전 버전�사용법�값�버전�버전 %s�%s에서 보기�저자�편집자�계약자�기여자�저작권자�데이터 기여자�자금 제공자�관리자�리뷰어�지도교수�번역자�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/doc/�����������������������������������������������������������������������������������0000755�0001762�0000144�00000000000�14672347611�013460� 5����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/doc/how-to-update-released-site.Rmd����������������������������������������������������0000644�0001762�0000144�00000025264�14671042554�021353� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- title: "How to update a released site" output: rmarkdown::html_vignette description: > A guide to updating the "released" version of your pkgdown site without having to release a new version of your package. vignette: > %\VignetteIndexEntry{How to update a released site} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", eval = FALSE, purl = FALSE ) ``` This vignette shows you how to update the released version of your site to match the dev version of the site, so the first step is to ensure that the dev site looks the way that you want it. This site assumes that you're using a recent version of our recommended [pkgdown action](https://github.com/r-lib/actions/blob/HEAD/examples/pkgdown.yaml). If your workflow does not contain `workflow_dispatch`, you will need to update `.github/actions/pkgdown.yaml` by running `use_github_action("pkgdown")`. ## Process If you're up to speed with the basic idea and just want some code to follow, here it is. Otherwise, read more below. ### Setup First, make sure you're in the `main` branch, and you have the latest version: ```{r} gert::git_branch_checkout("main") gert::git_pull() ``` Next figure out the released version that you're updating: ```{r} ver <- desc::desc_get_version()[1, 1:3] ``` You will use this to create and checkout the branch that you'll work in: ```{r} gert::git_branch_create(paste0("pkgdown-v", ver), paste0("v", ver)) ``` ### Backport changes Now you need to backport changes from the dev site into this branch. Run this R code to generate the git code to pull changes for the most common locations: ```{r} files <- c( # overall site config "_pkgdown.yml", # the workflow that builds the site ".github/workflows/pkgdown.yaml", # readme and vignettes "README.md", "vignettes", # logo and favicon "man/figures/", "pkgdown/", # Author metadata and Config/Needs/Website "DESCRIPTION" ) glue::glue("git checkout v{ver} -- {files}") ``` If you backport `DESCRIPTION`, you'll also need undo the change to the `Version`: ```{r} desc::desc_set_version(ver) ``` Now build the site locally and check that it looks as expected: ```{r} pkgdown::build_site() ``` ### Publish Now you need to publish the site. First push your branch to GitHub: ```{r} usethis:::git_push_first() ``` Then trigger the pkgdown workflow: 1. Go to your package's GHA page, e.g. with `usethis::browse_github_actions())`. 2. Select the pkgdown workflow. 3. Click *Run workflow* and select the branch you just pushed. If there's no dropdown menu for this, that means your pkgdown workflow config is not current. ## Context Before we talk about **how** to update a released site, we first establish **why** you might need to do this. What is a released site? What other kind of pkgdown site could you have? Why does updating a released site take special effort? ### Automatic development mode Every pkgdown site has a so-called [*development mode*](https://pkgdown.r-lib.org/reference/build_site.html#development-mode), which can be specified via the `development` field in `_pkgdown.yml`. If unspecified, the default is `mode: release`, which results in a single pkgdown site. Despite the name, this single site reflects "the current package state", which could be either a released state or a development state. For packages with a substantial user base, it is recommended instead to specify `mode: auto` like so: ``` yaml development: mode: auto ``` This directs pkgdown to "generate different sites for the development and released versions of your package." The readr package demonstrates what happens in automatic development mode: [readr.tidyverse.org](https://readr.tidyverse.org) documents the released version, i.e. what `install.packages()` will deliver.\ [readr.tidyverse.org/dev/](https://readr.tidyverse.org/dev/) documents the dev version, i.e. what you'd get by installing from GitHub. In this mode, `pkgdown::build_site()`, consults DESCRIPTION to learn the package's version number. For a development version number, the rendered site is written to `docs/dev/`. For a released version number, the site is written to `docs/`. (There are also other signals to alert users that they are reading documentation for a dev version vs. a released version.) Automatic development mode is recommended for packages with a broad user base because it maximizes the chance that a user will read web-based documentation which reflects the package version that is locally installed. ### Publishing Now that we've established the meaning of a released (vs dev) site, we have to consider how the site is built (i.e. how the HTML is generated) and deployed (i.e. how the HTML is published to a website so people can see it.). We recommend `usethis::use_pkgdown_github_pages()` to do basic pkgdown setup and configure a GitHub Actions (GHA) workflow to automatically render and publish the site to GitHub Pages. This function is basically a shortcut for calling the following functions individually: * `use_pkgdown()` * `use_github_pages()` * `use_github_action("pkgdown")` It then adds the pkgdown site's URL to `_pkgdown.yml`, the `URL` field of DESCRIPTION, and the GitHub repo. As a result, the publishing cadence of many pkgdown sites is governed by the workflow maintained at [`r-lib/actions/examples/pkgdown.yaml`](https://github.com/r-lib/actions/blob/v2/examples/pkgdown.yaml). (Do not confuse `_pkgdown.yml`, which gives instructions to the pkgdown package, with `.github/workflows/pkgdown.yaml`, which gives instructions to GHA.) Here are some of the most important bits of the GHA workflow config: ``` yaml on: push: branches: [main, master] pull_request: branches: [main, master] release: types: [published] workflow_dispatch: <snip, snip> - name: Build site run: Rscript -e 'pkgdown::build_site_github_pages(...)' - name: Deploy to GitHub pages 🚀 if: github.event_name != 'pull_request' uses: JamesIves/github-pages-deploy-action@4.1.4 <snip, snip> ``` Altogether this means that we: * Build and deploy for pushes to `main`. * Build, but don't deploy, for pull requests against `main`. This reveals any pkgdown errors, but ensures the live site isn't updated until the pull request is merged (because the code is pushed to `main`). * Build and deploy when we publish a GitHub release. By convention, we assume that a GitHub release coincides with a CRAN release. So this is the **primary mechanism for building the released pkgdown site**. `pkgdown::build_site_github_pages()` consults the version in DESCRIPTION to detect whether it's building from a released version or a dev version. That determines the `dest_dir`, e.g. `docs/` for released and `docs/dev/` for dev. For a package in automatic development mode, this means that almost all of your pushes trigger an update to the dev site. The released site is only updated when you push a state with a non-development version number or when you publish a GitHub release. So how do you tweak things about the released site *in between* releases? That brings us to `workflow_dispatch:`. (Yes that dangling colon is correct.) The inclusion of `workflow_dispatch` as a trigger means the pkgdown workflow can be [run on demand](https://docs.github.com/en/actions/using-workflows/manually-running-a-workflow), most importantly from the browser. ## Construct a branch for the update The overall goal is to create a branch that combines some features of the released website (e.g. the released version) and the development version (e.g. improvements to your `_pkgdown.yml`). The easiest way is to start your branch using the latest release tag, then bring in selected changes or files from the development version. For example, if readr's latest release is 2.1.1: ``` git checkout -b update-pkgdown-2-1-1 v2.1.1 ``` And here is the general pattern: ``` git checkout -b NEW-BRANCH-NAME NAME-OF-RELEASE-TAG ``` Now you should port innovations from the development site that you want to apply to your released site. Files you must update: - `.github/workflows/pkgdown.yaml` - `_pkgdown.yml` - `Config/Needs/website` field of DESCRIPTION (And, probably, only this field! In particular, do not mess with the version number.) Other likely candidates: - `README.Rmd` + `README.md`, e.g., if you've updated badges. - Any documentation fixes that **apply to the released version**. This is the only reason to touch anything below `R/` and even then it should only affect roxygen comments. Don't forget to `document()` if you do this! - Any new vignettes or articles that apply to the released version. Here are some tips on backporting specific changes into this branch. If you are lucky, there are specific commits in your default branch that contain all the necessary changes. In that case, we can cherry pick such a commit by its SHA: ``` git cherry-pick SHA ``` If that doesn't cover everything for each file you want to update, identify a Git reference (meaning: a SHA, tag, or branch) where the file is in the desired state. Checkout that specific file path from that specific ref: ``` git checkout main -- path/to/the/file ``` For example, readr recently gained a new vignette that applies to the released version of readr, i.e. it does not document any dev-only features or functions. We can bring that into the current branch with: ``` git checkout main -- vignettes/column-types.Rmd ``` Commit and push this new branch to GitHub. `usethis::pr_push()` can be handy for this. Just don't bother opening a pull request (the branch will still be pushed). Now we will use the `workflow_dispatch` GHA trigger: 1. Go to the Actions page of your repo, maybe via `usethis::browse_github_actions()`. 1. Click on the `pkgdown` workflow. 1. Click the "Run workflow". 1. In the "Use workflow from" dropdown menu, select the branch you've just made and pushed, then click "Run workflow". This should kick off a pkgdown build-and-deploy and, specifically, it should cause updates to the **released** site. You can keep this branch around for a while, in case you didn't get everything right the first time or if more things crop up that you'd like backport to the released site, before your next CRAN release. ## Problem-solving Another great problem solving technique is to get a bunch of other people's `_pkgdown.yml` files in front of your eyeballs. There are two ways to do this: [GitHub search](https://github.com/search?q=path%3A%22_pkgdown.yml%22+AND+%28org%3Atidyverse+OR+org%3Ar-lib%29&type=code) or [Michael Chirico's `r-ci-samples` repo](https://github.com/MichaelChirico/r-ci-samples/tree/master/pkgdown). For any given `_pkgdown.yml` file, remember that its History and Blame can be helpful for seeing how it has evolved over time. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pkgdown/inst/doc/linking.Rmd������������������������������������������������������������������������0000644�0001762�0000144�00000005761�14671042466�015567� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- title: "Auto-linking" output: rmarkdown::html_vignette description: > Learn how pkgdown's automatic linking works, and how you can customise it. vignette: > %\VignetteIndexEntry{Auto-linking} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ## Within a package pkgdown will automatically link to documentation and articles wherever it's possible to do unambiguously. This includes: * Bare function calls, like `build_site()`. * Calls to `?`, like `?build_site` or `package?pkgdown`. * Calls to `help()`, like `help("pkgdown")`. * Calls to `vignette()`, like `vignette("pkgdown")`. ## Across packages Linking to documentation in another package is straightforward. Just adapt the call in the usual way: * `purrr::map()`, `MASS::addterm()`. * `?purrr::map`, `?MASS::addterm`. * `vignette("other-langs", package = "purrr")`, `vignette("longintro", package = "rpart")` * `{purrr}` If pkgdown can find a pkgdown site for the remote package, it will link to it; otherwise, it will link to <https://rdrr.io/> for documentation and CRAN for vignettes. In order for a pkgdown site to be findable, it needs to be listed in two places: * In the `URL` field in the `DESCRIPTION`, as in [dplyr](https://github.com/tidyverse/dplyr/blob/85faf79c1fd74f4b4f95319e5be6a124a8075502/DESCRIPTION#L15): ``` URL: https://dplyr.tidyverse.org, https://github.com/tidyverse/dplyr ``` * In the `url` field in `_pkgdown.yml`, as in [dplyr](https://github.com/tidyverse/dplyr/blob/master/_pkgdown.yml#L1) ```yaml url: https://dplyr.tidyverse.org ``` When this field is defined, pkgdown generates a public facing [`pkgdown.yml` file](https://dplyr.tidyverse.org/pkgdown.yml) that provides metadata about the site: ```yaml pandoc: '2.2' pkgdown: 1.3.0 pkgdown_sha: ~ articles: compatibility: compatibility.html dplyr: dplyr.html dplyr_0.8.0: future/dplyr_0.8.0.html dplyr_0.8.0_new_hybrid: future/dplyr_0.8.0_new_hybrid.html programming: programming.html two-table: two-table.html window-functions: window-functions.html urls: reference: https://dplyr.tidyverse.org/reference article: https://dplyr.tidyverse.org/articles ``` Now, when you build a pkgdown site for a package that links to the dplyr documentation (e.g., `dplyr::mutate()`), pkgdown looks first in dplyr's `DESCRIPTION` to find its website, then it looks for `pkgdown.yml`, and uses the metadata to generate the correct links. To allow your package to be linked by other locally installed packages, even if your website is not reachable at build time, the following option needs to be set in `_pkgdown.yml`: ```yaml deploy: install_metadata: true ``` This allows locally installed packages to access package index metadata from the locally installed copy, which may be useful if your website require auth, or you build behind a firewall. ���������������pkgdown/inst/doc/linking.html�����������������������������������������������������������������������0000644�0001762�0000144�00000034102�14672347607�016006� 0����������������������������������������������������������������������������������������������������ustar �ligges��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="generator" content="pandoc" /> <meta http-equiv="X-UA-Compatible" content="IE=EDGE" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>Auto-linking

    Auto-linking

    Within a package

    pkgdown will automatically link to documentation and articles wherever it’s possible to do unambiguously. This includes:

    • Bare function calls, like build_site().
    • Calls to ?, like ?build_site or package?pkgdown.
    • Calls to help(), like help("pkgdown").
    • Calls to vignette(), like vignette("pkgdown").

    Across packages

    Linking to documentation in another package is straightforward. Just adapt the call in the usual way:

    • purrr::map(), MASS::addterm().
    • ?purrr::map, ?MASS::addterm.
    • vignette("other-langs", package = "purrr"), vignette("longintro", package = "rpart")
    • {purrr}

    If pkgdown can find a pkgdown site for the remote package, it will link to it; otherwise, it will link to https://rdrr.io/ for documentation and CRAN for vignettes. In order for a pkgdown site to be findable, it needs to be listed in two places:

    • In the URL field in the DESCRIPTION, as in dplyr:

      URL: https://dplyr.tidyverse.org, https://github.com/tidyverse/dplyr
    • In the url field in _pkgdown.yml, as in dplyr

      url: https://dplyr.tidyverse.org

      When this field is defined, pkgdown generates a public facing pkgdown.yml file that provides metadata about the site:

      pandoc: '2.2'
      pkgdown: 1.3.0
      pkgdown_sha: ~
      articles:
        compatibility: compatibility.html
        dplyr: dplyr.html
        dplyr_0.8.0: future/dplyr_0.8.0.html
        dplyr_0.8.0_new_hybrid: future/dplyr_0.8.0_new_hybrid.html
        programming: programming.html
        two-table: two-table.html
        window-functions: window-functions.html
      urls:
        reference: https://dplyr.tidyverse.org/reference
        article: https://dplyr.tidyverse.org/articles

    Now, when you build a pkgdown site for a package that links to the dplyr documentation (e.g., dplyr::mutate()), pkgdown looks first in dplyr’s DESCRIPTION to find its website, then it looks for pkgdown.yml, and uses the metadata to generate the correct links.

    To allow your package to be linked by other locally installed packages, even if your website is not reachable at build time, the following option needs to be set in _pkgdown.yml:

    deploy:
      install_metadata: true

    This allows locally installed packages to access package index metadata from the locally installed copy, which may be useful if your website require auth, or you build behind a firewall.

    pkgdown/inst/doc/metadata.html0000644000176200001440000004362114672347607016141 0ustar liggesusers Metadata

    Metadata

    Package authors can customize the metadata used by Twitter and the Open Graph protocol for rich social media cards. In addition to specifying an alternate description for the package and any individual articles, you may also choose the preview image shown and the style of the card used on Twitter.

    You can preview and validate the appearance of the social media cards with online tools:

    Necessary configuration

    Metadata can only be produced correctly if your pkgdown website URL is indicated in its configuration file.

    url: https://example.com

    Site-wide customization

    Metadata for the entire pkgdown website can be specified in the site’s _pkgdown.yml configuration file in the home and template: opengraph sections:

    home:
      title: An R package for pool-noodle discovery
      description: Discover and add pool-noodles to your growing collection.
    
    template:
      opengraph:
        image:
          src: man/figures/card.png
          alt: "Pool noodles configured to form the word poolnoodlr"
        twitter:
          creator: "@hadleywickham"
          site: "@rstudio"
          card: summary_large_image

    The home: title and home: description fields override the Title and Description fields in the package DESCRIPTION. It’s good practice to set these fields to make your package documentation easier to find via search, rather than sticking with the title and description needed by CRAN.

    The template: opengraph section allows you to further customize the social media card.

    • image: By default, pkgdown uses the package’s logo for the card image (if one exists). Use image to specify an alternative image for the social media cards of pages in your pkgdown site.

      • src: A fully qualified URL to a media card image e.g. src: https://avatars.githubusercontent.com/u/22618716?v=4; or a relative path to an image in the rendered website e.g. src: articles/test/image.jpg; or a relative path to an image stored in man/figures in the package e.g. src: man/figures/cards.png. The src field is required if image is specified.

      • alt: Alternative text describing the image for screen readers and other situations where your social media card image cannot be displayed.

    • twitter: You can specify the Twitter accounts associated with your package and the style of social media card that Twitter will display.

      • creator: Typically, the Twitter handle of the author of the package or article.

      • site: The Twitter handle of the organization affiliated with the package author or sponsoring the package development.

      • If only one of either creator or site is included, the provided value will be used for both fields.

      • card: The style of social media card that Twitter will display. For pkgdown sites, the most relevant options are summary_large_image, featuring a large image over the page title and description, or summary, featuring a small square image inline and to the left of the page title and description.

    Article metadata

    Articles and vignettes rendered as articles by pkgdown can have individually customized metadata and social media cards.

    title: "Introduction to poolnoodlr"
    description: "A brief introduction to pool noodles in R."
    author: "Mara Averick"
    opengraph:
      image:
        src: "https://example.com/pkg/batpig.png"
      twitter:
        card: summary
        creator: "@dataandme"
    output: rmarkdown::html_vignette
    vignette: >
      %\VignetteIndexEntry{Introduction to poolnoodlr}
      %\VignetteEngine{knitr::rmarkdown}
      %\VignetteEncoding{UTF-8}

    Use the title, description, and author fields to specify the title, description, and (optional) author of the vignette or article.

    • The title field is used as the title of your article in your pkgdown site and should always be included.

    • Both title and description are used by pkgdown for the page’s social media card. If description is not included in the article’s YAML front matter, then the name of the package is used instead. The description is also displayed on the articles index.

    • The author field is only used in the text of the vignette or article. How the author name is displayed depends on the output format.

    In articles, the opengraph section works in the same way as the site-wide template: opengraph settings, but is only applied to the article or vignette. This allows you to specify social media card preview images for individual articles, or to associate an article with a particular Twitter account. If not specified, the opengraph settings from the site-wide configuration are used.

    pkgdown/inst/doc/pkgdown.html0000644000176200001440000005235514672347607016036 0ustar liggesusers Introduction to pkgdown

    Introduction to pkgdown

    The goal of pkgdown is to make it easy to make an elegant and useful package website with a minimum of work. You can get a basic website up and running in just a couple of minutes. If you’re using GitHub, we recommend setting up pkgdown and GitHub actions to automatically build and publish your site:

    # Run this once to publish your site regularly
    usethis::use_pkgdown_github_pages()

    If you are not using GitHub, you will have to run pkgdown::build_site() manually everytime you want to update the site.

    # Run once
    # Remove docs/ from gitignore to ensure it is checked into git.
    usethis::use_pkgdown()
    # Run everytime you want to update your site
    pkgdown::build_site()

    While you’ll get a decent website without any additional work, if you want a website that really pops, you’ll need to read the rest of this vignette. It starts by showing you how to configure pkgdown with a _pkgdown.yml. You’ll learn about the main components of the site (the home page, reference, articles, and news), and then how to publish and promote your site.

    Metadata

    You can override pkgdown’s defaults with a YAML file called _pkgdown.yml1. The most important field is url, which gives the final location of the site:

    url: https://pkgdown.r-lib.org

    url is used throughout the site to generate absolute urls where they are needed. url is also part of what enables auto-links to your help topics or vignettes from sites external to your package, such as from other pkgdown sites or from Quarto websites. See vignette("linking") for more.

    Another important option is template, which allows you to control the overall appearance of your site:

    template:
      bootstrap: 5
      bootswatch: cerulean

    You can learn more about controlling the appearance of your site in vignette("customise").

    Accessibility

    pkgdown’s defaults work to ensure that your site is accessible to as many people as possible. But there are some accessibilty issues that only a human can solve, so make sure to also read vignette("accessibility") to learn about them.

    Home page

    The contents of the home page are automatically generated from index.md or README.md. pkgdown tries to put them in order, so it’s possible to have a different display on GitHub and pkgdown by providing both files. The homepage also includes a sidebar full of useful links (see ?build_home for how these are generated and how you can customise them).

    Reference

    pkgdown creates a function reference in reference/ that includes one page for each .Rd help topic in man/. The translation of individual help topics from Rd to HTML is generally straightforward, but there are a couple of things you should bear in mind:

    • pkgdown does its best to autolink all references to help topics and articles described in vignette("linking").

    • pkgdown executes all examples, inserting the rendered results in the generated HTML files.

    By default, pkgdown generates a reference index that is just an alphabetically-ordered list of functions. The index is much more useful with human curation because functions can be grouped and described in categories. To override the default, provide a reference field in _pkgdown.yml.

    Each entry in reference can take one of three forms:

    • A title, defined by title and optional desc (description) fields.
    • A subtitle, defined by subtitle and optional desc (description) fields.
    • A list of topics defined by a contents field.
    reference:
    - title: "Connecting to Spark"
      desc: >
        Functions for installing Spark components and managing
        connections to Spark
      contents: 
      - spark_config
      - spark_connect
      - spark_disconnect
      - spark_install
      - spark_log
    - title: "Reading and Writing Data"
      desc: "Functions for reading and writing Spark DataFrames."
      contents:
      - starts_with("spark_read")
      - starts_with("spark_write")
      - matches("saveload")

    Note the use of starts_with() to select all functions with a common prefix. You can also use ends_with() and matches(). See complete details in ?build_reference, including other topic matching helper functions.

    While iterating on the reference index you might want to run pkgdown::build_reference_index(). It just re-builds the index page, making it faster to quickly change _pkgdown.yml and see how it affects your site.

    Articles

    pkgdown will automatically build all vignettes found in vignettes/, translating them to HTML files in articles/. It is recommended to name your intro article with your package name to generate a “Get Started” page automatically.

    Due to the way that pkgdown has to integrate R Markdown generated HTML with its own HTML, relatively little control is available over the output format. You can see the details in ?build_articles.

    If you want to include an article on the website but not in the package (e.g., because it’s large), you can use usethis::use_article() to set it up.

    News

    If NEWS.md is present, it will be rendered into a single-page changelog based on markdown level headings. pkgdown assumes your NEWS.md is formatted using level one headings (#) to specify package name and version number, and level two headings (##) to provide topical organization for each release.

    # pkgdown 1.1.0
    
    ## Bug Fixes
    
    * Lots of them
    
    # pkgdown 1.0.0
    
    * This is the first release of pkgdown.

    See more suggestions for writing news bullets in the tidyverse style guide.

    See ?build_news for more customisation options including how to:

    • Create one page for each major version and related minor versions.
    • Add release announcements to the news navbar drop-down.

    Publishing

    If you use GitHub, the easiest way to build and publish your site is via GitHub actions. Using GitHub actions automatically builds and publishes the site every time you make a change. The easiest way to set this up is to run usethis::use_pkgdown_github_pages(), and if you need to customize the action, see README.md r-lib/actions.

    Promoting

    Once your finalized site is built and published on the web, you should publicize its URL in a few places:

    1. The URL field of your package DESCRIPTION, alongside a link to its source:

      URL: https://pkgdown.r-lib.org, https://github.com/r-lib/pkgdown

      (usethis::use_pkgdown_github_pages() does this for you.)

    2. Your repository description on GitHub.

      (usethis::use_pkgdown_github_pages() does this for you.)

    3. On social media (make sure to include #rstats).


    1. You can also put it in pkgdown/_pkgdown.yml if you want to keep the package root clutter-free, or in inst/_pkgdown.yml if you want to make it available when your package is installed. You can also use .yaml as the extension if desired.↩︎

    pkgdown/inst/doc/how-to-update-released-site.R0000644000176200001440000000025714672347606021034 0ustar liggesusers## ----include = FALSE---------------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>", eval = FALSE, purl = FALSE ) pkgdown/inst/doc/pkgdown.R0000644000176200001440000000066114672347607015264 0ustar liggesusers## ----eval = FALSE------------------------------------------------------------- # # Run this once to publish your site regularly # usethis::use_pkgdown_github_pages() ## ----eval = FALSE------------------------------------------------------------- # # Run once # # Remove docs/ from gitignore to ensure it is checked into git. # usethis::use_pkgdown() # # Run everytime you want to update your site # pkgdown::build_site() pkgdown/inst/doc/pkgdown.Rmd0000644000176200001440000001617014671042466015601 0ustar liggesusers--- title: "Introduction to pkgdown" description: > Learn how to get started with the basics of pkgdown. output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Introduction to pkgdown} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- The goal of pkgdown is to make it easy to make an elegant and useful package website with a minimum of work. You can get a basic website up and running in just a couple of minutes. If you're using GitHub, we recommend setting up pkgdown and GitHub actions to automatically build and publish your site: ```{r, eval = FALSE} # Run this once to publish your site regularly usethis::use_pkgdown_github_pages() ``` If you are not using GitHub, you will have to run `pkgdown::build_site()` manually everytime you want to update the site. ```{r, eval = FALSE} # Run once # Remove docs/ from gitignore to ensure it is checked into git. usethis::use_pkgdown() # Run everytime you want to update your site pkgdown::build_site() ``` While you'll get a decent website without any additional work, if you want a website that really pops, you'll need to read the rest of this vignette. It starts by showing you how to configure pkgdown with a `_pkgdown.yml`. You'll learn about the main components of the site (the home page, reference, articles, and news), and then how to publish and promote your site. ## Metadata You can override pkgdown's defaults with a YAML file called `_pkgdown.yml`[^1]. The most important field is `url`, which gives the final location of the site: [^1]: You can also put it in `pkgdown/_pkgdown.yml` if you want to keep the package root clutter-free, or in `inst/_pkgdown.yml` if you want to make it available when your package is installed. You can also use `.yaml` as the extension if desired. ``` yaml url: https://pkgdown.r-lib.org ``` `url` is used throughout the site to generate absolute urls where they are needed. `url` is also part of what enables auto-links to your help topics or vignettes from sites external to your package, such as from other pkgdown sites or from Quarto websites. See `vignette("linking")` for more. Another important option is `template`, which allows you to control the overall appearance of your site: ``` yaml template: bootstrap: 5 bootswatch: cerulean ``` You can learn more about controlling the appearance of your site in `vignette("customise")`. ## Accessibility pkgdown's defaults work to ensure that your site is accessible to as many people as possible. But there are some accessibilty issues that only a human can solve, so make sure to also read `vignette("accessibility")` to learn about them. ## Home page The contents of the home page are automatically generated from `index.md` or `README.md`. pkgdown tries to put them in order, so it's possible to have a different display on GitHub and pkgdown by providing both files. The homepage also includes a sidebar full of useful links (see `?build_home` for how these are generated and how you can customise them). ## Reference pkgdown creates a function reference in `reference/` that includes one page for each `.Rd` help topic in `man/`. The translation of individual help topics from Rd to HTML is generally straightforward, but there are a couple of things you should bear in mind: - pkgdown does its best to autolink all references to help topics and articles described in `vignette("linking")`. - pkgdown executes all examples, inserting the rendered results in the generated HTML files. By default, pkgdown generates a reference index that is just an alphabetically-ordered list of functions. The index is much more useful with human curation because functions can be grouped and described in categories. To override the default, provide a `reference` field in `_pkgdown.yml`. Each entry in `reference` can take one of three forms: - A title, defined by `title` and optional `desc` (description) fields. - A subtitle, defined by `subtitle` and optional `desc` (description) fields. - A list of topics defined by a `contents` field. ``` yaml reference: - title: "Connecting to Spark" desc: > Functions for installing Spark components and managing connections to Spark contents: - spark_config - spark_connect - spark_disconnect - spark_install - spark_log - title: "Reading and Writing Data" desc: "Functions for reading and writing Spark DataFrames." contents: - starts_with("spark_read") - starts_with("spark_write") - matches("saveload") ``` Note the use of `starts_with()` to select all functions with a common prefix. You can also use `ends_with()` and `matches()`. See complete details in `?build_reference`, including other topic matching helper functions. While iterating on the reference index you might want to run `pkgdown::build_reference_index()`. It just re-builds the index page, making it faster to quickly change `_pkgdown.yml` and see how it affects your site. ## Articles pkgdown will automatically build all vignettes found in `vignettes/`, translating them to HTML files in `articles/`. It is recommended to name your intro article with your package name to generate a "Get Started" page automatically. Due to the way that pkgdown has to integrate R Markdown generated HTML with its own HTML, relatively little control is available over the output format. You can see the details in `?build_articles`. If you want to include an [article](https://r-pkgs.org/website.html#non-vignette-articles) on the website but not in the package (e.g., because it's large), you can use `usethis::use_article()` to set it up. ## News If `NEWS.md` is present, it will be rendered into a single-page changelog based on markdown level headings. pkgdown assumes your `NEWS.md` is formatted using level one headings (`#`) to specify package name and version number, and level two headings (`##`) to provide topical organization for each release. ``` markdown # pkgdown 1.1.0 ## Bug Fixes * Lots of them # pkgdown 1.0.0 * This is the first release of pkgdown. ``` See more suggestions for writing news bullets in the [tidyverse style guide](https://style.tidyverse.org/news.html). See `?build_news` for more customisation options including how to: - Create one page for each major version and related minor versions. - Add release announcements to the news navbar drop-down. ## Publishing If you use GitHub, the easiest way to build and publish your site is via GitHub actions. Using GitHub actions automatically builds and publishes the site every time you make a change. The easiest way to set this up is to run `usethis::use_pkgdown_github_pages()`, and if you need to customize the action, see [README.md r-lib/actions](https://github.com/r-lib/actions/tree/v2-branch/examples#build-pkgdown-site). ## Promoting Once your finalized site is built and published on the web, you should publicize its URL in a few places: 1. The `URL` field of your package `DESCRIPTION`, alongside a link to its source: URL: https://pkgdown.r-lib.org, https://github.com/r-lib/pkgdown (`usethis::use_pkgdown_github_pages()` does this for you.) 2. Your repository description on GitHub. (`usethis::use_pkgdown_github_pages()` does this for you.) 3. On social media (make sure to include `#rstats`). pkgdown/inst/doc/linking.R0000644000176200001440000000021714672347606015242 0ustar liggesusers## ----include = FALSE---------------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) pkgdown/inst/doc/accessibility.html0000644000176200001440000003036114672347605017203 0ustar liggesusers Accessibility

    Accessibility

    pkgdown automates as many accessibility details as possible, so that your package website is readable by as many people as possible. This vignette describes the additional details that can’t be automated away and you need to be aware of.

    library(pkgdown)

    Theming

    • If you adjust any colours from the default theme (including the syntax highlighting theme), you should double check that the contrast between the background and foreground doesn’t make any text difficult to read. A good place to start is running a representative page of your site through https://wave.webaim.org.

    • The default colour of the development version label makes a slightly too low contrast against the pale grey background of the navbar. This colour comes from the bootstrap “danger” colour, so you can fix it by overriding that variable in your _pkgdown.yml:

      template:
        bootstrap: 5
        bslib:
          danger: "#A6081A"
    • If you use custom navbar entries that only display an icon, make sure to also use the aria-label field to provide an accessible label that describes the icon.

      cran:
        icon: fab fa-r-project
        href: https://cloud.r-project.org/package=pkgdown
        aria-label: View on CRAN

    Images

    To make your site fully accessible, the place where you are likely to need to do the most work is adding alternative text to any images that you create. Unfortunately, there’s currently no way to do this for plots you generate in examples, but you can and should add alternative text to plots in vignettes using the fig.alt chunk option:

    ```{r}
    #| fig.alt: >
    #|   Histogram of time between eruptions for Old Faithful. 
    #|   It is a bimodal distribution with peaks at 50-55 and 
    #|   80-90 minutes.
    hist(faithful$waiting)
    ```

    If you forget to add alt text to your vignettes, pkgdown will automatically remind you.

    pkgdown/inst/doc/how-to-update-released-site.html0000644000176200001440000006451014672347606021601 0ustar liggesusers How to update a released site

    How to update a released site

    This vignette shows you how to update the released version of your site to match the dev version of the site, so the first step is to ensure that the dev site looks the way that you want it.

    This site assumes that you’re using a recent version of our recommended pkgdown action. If your workflow does not contain workflow_dispatch, you will need to update .github/actions/pkgdown.yaml by running use_github_action("pkgdown").

    Process

    If you’re up to speed with the basic idea and just want some code to follow, here it is. Otherwise, read more below.

    Setup

    First, make sure you’re in the main branch, and you have the latest version:

    gert::git_branch_checkout("main")
    gert::git_pull()

    Next figure out the released version that you’re updating:

    ver <- desc::desc_get_version()[1, 1:3]

    You will use this to create and checkout the branch that you’ll work in:

    gert::git_branch_create(paste0("pkgdown-v", ver), paste0("v", ver))

    Backport changes

    Now you need to backport changes from the dev site into this branch. Run this R code to generate the git code to pull changes for the most common locations:

    files <- c(
      # overall site config
      "_pkgdown.yml",
      # the workflow that builds the site
      ".github/workflows/pkgdown.yaml",
      # readme and vignettes
      "README.md", "vignettes",
      # logo and favicon
      "man/figures/", "pkgdown/",
      # Author metadata and Config/Needs/Website
      "DESCRIPTION"
    )
    
    glue::glue("git checkout v{ver} -- {files}")

    If you backport DESCRIPTION, you’ll also need undo the change to the Version:

    desc::desc_set_version(ver)

    Now build the site locally and check that it looks as expected:

    pkgdown::build_site()

    Publish

    Now you need to publish the site. First push your branch to GitHub:

    usethis:::git_push_first()

    Then trigger the pkgdown workflow:

    1. Go to your package’s GHA page, e.g. with usethis::browse_github_actions()).
    2. Select the pkgdown workflow.
    3. Click Run workflow and select the branch you just pushed.

    If there’s no dropdown menu for this, that means your pkgdown workflow config is not current.

    Context

    Before we talk about how to update a released site, we first establish why you might need to do this. What is a released site? What other kind of pkgdown site could you have? Why does updating a released site take special effort?

    Automatic development mode

    Every pkgdown site has a so-called development mode, which can be specified via the development field in _pkgdown.yml. If unspecified, the default is mode: release, which results in a single pkgdown site. Despite the name, this single site reflects “the current package state”, which could be either a released state or a development state.

    For packages with a substantial user base, it is recommended instead to specify mode: auto like so:

    development:
      mode: auto

    This directs pkgdown to “generate different sites for the development and released versions of your package.”

    The readr package demonstrates what happens in automatic development mode:

    readr.tidyverse.org documents the released version, i.e. what install.packages() will deliver.
    readr.tidyverse.org/dev/ documents the dev version, i.e. what you’d get by installing from GitHub.

    In this mode, pkgdown::build_site(), consults DESCRIPTION to learn the package’s version number. For a development version number, the rendered site is written to docs/dev/. For a released version number, the site is written to docs/. (There are also other signals to alert users that they are reading documentation for a dev version vs. a released version.)

    Automatic development mode is recommended for packages with a broad user base because it maximizes the chance that a user will read web-based documentation which reflects the package version that is locally installed.

    Publishing

    Now that we’ve established the meaning of a released (vs dev) site, we have to consider how the site is built (i.e. how the HTML is generated) and deployed (i.e. how the HTML is published to a website so people can see it.).

    We recommend usethis::use_pkgdown_github_pages() to do basic pkgdown setup and configure a GitHub Actions (GHA) workflow to automatically render and publish the site to GitHub Pages. This function is basically a shortcut for calling the following functions individually:

    • use_pkgdown()
    • use_github_pages()
    • use_github_action("pkgdown")

    It then adds the pkgdown site’s URL to _pkgdown.yml, the URL field of DESCRIPTION, and the GitHub repo.

    As a result, the publishing cadence of many pkgdown sites is governed by the workflow maintained at r-lib/actions/examples/pkgdown.yaml. (Do not confuse _pkgdown.yml, which gives instructions to the pkgdown package, with .github/workflows/pkgdown.yaml, which gives instructions to GHA.)

    Here are some of the most important bits of the GHA workflow config:

    on:
      push:
        branches: [main, master]
      pull_request:
        branches: [main, master]
      release:
        types: [published]
      workflow_dispatch:
    
    <snip, snip>
    
          - name: Build site
            run: Rscript -e 'pkgdown::build_site_github_pages(...)'
    
          - name: Deploy to GitHub pages 🚀
            if: github.event_name != 'pull_request'
            uses: JamesIves/github-pages-deploy-action@4.1.4
    
            <snip, snip>

    Altogether this means that we:

    • Build and deploy for pushes to main.

    • Build, but don’t deploy, for pull requests against main. This reveals any pkgdown errors, but ensures the live site isn’t updated until the pull request is merged (because the code is pushed to main).

    • Build and deploy when we publish a GitHub release. By convention, we assume that a GitHub release coincides with a CRAN release. So this is the primary mechanism for building the released pkgdown site.

    pkgdown::build_site_github_pages() consults the version in DESCRIPTION to detect whether it’s building from a released version or a dev version. That determines the dest_dir, e.g. docs/ for released and docs/dev/ for dev. For a package in automatic development mode, this means that almost all of your pushes trigger an update to the dev site. The released site is only updated when you push a state with a non-development version number or when you publish a GitHub release.

    So how do you tweak things about the released site in between releases?

    That brings us to workflow_dispatch:. (Yes that dangling colon is correct.)

    The inclusion of workflow_dispatch as a trigger means the pkgdown workflow can be run on demand, most importantly from the browser.

    Construct a branch for the update

    The overall goal is to create a branch that combines some features of the released website (e.g. the released version) and the development version (e.g. improvements to your _pkgdown.yml). The easiest way is to start your branch using the latest release tag, then bring in selected changes or files from the development version.

    For example, if readr’s latest release is 2.1.1:

    git checkout -b update-pkgdown-2-1-1 v2.1.1

    And here is the general pattern:

    git checkout -b NEW-BRANCH-NAME NAME-OF-RELEASE-TAG

    Now you should port innovations from the development site that you want to apply to your released site.

    Files you must update:

    • .github/workflows/pkgdown.yaml
    • _pkgdown.yml
    • Config/Needs/website field of DESCRIPTION (And, probably, only this field! In particular, do not mess with the version number.)

    Other likely candidates:

    • README.Rmd + README.md, e.g., if you’ve updated badges.
    • Any documentation fixes that apply to the released version. This is the only reason to touch anything below R/ and even then it should only affect roxygen comments. Don’t forget to document() if you do this!
    • Any new vignettes or articles that apply to the released version.

    Here are some tips on backporting specific changes into this branch. If you are lucky, there are specific commits in your default branch that contain all the necessary changes. In that case, we can cherry pick such a commit by its SHA:

    git cherry-pick SHA

    If that doesn’t cover everything for each file you want to update, identify a Git reference (meaning: a SHA, tag, or branch) where the file is in the desired state. Checkout that specific file path from that specific ref:

    git checkout main -- path/to/the/file

    For example, readr recently gained a new vignette that applies to the released version of readr, i.e. it does not document any dev-only features or functions. We can bring that into the current branch with:

    git checkout main -- vignettes/column-types.Rmd

    Commit and push this new branch to GitHub. usethis::pr_push() can be handy for this. Just don’t bother opening a pull request (the branch will still be pushed).

    Now we will use the workflow_dispatch GHA trigger:

    1. Go to the Actions page of your repo, maybe via usethis::browse_github_actions().
    2. Click on the pkgdown workflow.
    3. Click the “Run workflow”.
    4. In the “Use workflow from” dropdown menu, select the branch you’ve just made and pushed, then click “Run workflow”.

    This should kick off a pkgdown build-and-deploy and, specifically, it should cause updates to the released site.

    You can keep this branch around for a while, in case you didn’t get everything right the first time or if more things crop up that you’d like backport to the released site, before your next CRAN release.

    Problem-solving

    Another great problem solving technique is to get a bunch of other people’s _pkgdown.yml files in front of your eyeballs. There are two ways to do this: GitHub search or Michael Chirico’s r-ci-samples repo. For any given _pkgdown.yml file, remember that its History and Blame can be helpful for seeing how it has evolved over time.

    pkgdown/inst/doc/translations.Rmd0000644000176200001440000000722514642046757016657 0ustar liggesusers--- title: "Translations" output: rmarkdown::html_vignette description: > If your documentation is written in a language other than English, you can automatically translate the text generated by pkgdown by setting the `lang` field. If your language isn't currently supported, we'll show you how you can provide translations. vignette: > %\VignetteIndexEntry{Translations} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` If your documentation (`.Rd` and `.Rmd`) is written in a language other than English, declare it by setting setting `lang` to the [language code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) for your language: ``` yaml lang: fr ``` This will be used to set the language of the web page and to translate the English words that pkgdown generates on your site. Current available translations are: - `ca`: Catalan - `de`: German - `dk`: Danish - `es`: Spanish - `fr`: French - `ko`: Korean - `pt`: Portuguese - `tr`: Turkish - `zh_CN`: Chinese (simplified) As you can see, most language codes are two letters, but if a language has multiple variants, it gets a longer form which can be used to disambiguate the options. For example, Chinese can use one of two forms: simplified (used in China and Singapore) or traditional (used in Taiwan and Hong Kong). Another example would be providing specific French Canadian translations by using code `fr_CN`. ## Translations Translations are contributed by community members so if your language is not currently available, you could be the one to add it! To get started, first check the [pkgdown issues](https://github.com/r-lib/pkgdown/issues) to see if anyone has filed an existing issue. If so, the person who filed the issue might make for a great collaborator 😀. Next, install [potools](https://michaelchirico.github.io/potools/) and [usethis](https://usethis.r-lib.org): ```{r} #| eval: false install.packages(c("potools", "usethis")) ``` You'll then need to familiarise yourself with the basics of [translations with potools](https://michaelchirico.github.io/potools/articles/translators.html) and [creating pull requests](https://usethis.r-lib.org/articles/pr-functions.html) with usethis. If you don't already know it, you'll need to look up the ISO 639-1 abbreviation for [your language](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes). In the examples below, I'll pretend I'm providing translations for Zulu, which has code `zu`. Start by initialising a pull request: ```{r} #| eval: false usethis::pr_init("translation-zu") ``` Then create the translation file by running `potools::po_create("zu")`, open `po/R-zu.po`, and starting filling in the translations. If you have access to chatGPT or similar, you can try prepopulating the translations, with a prompt something like thii: > You are an R developer who is fluent in English and Zulu. You love to do careful, high quality translations in your spare time. Complete the following po file for the R pkgdown package (which creates websites for R packages) by supplying translations for Zulu. Use inclusive gender forms where possible. Then copy and paste the complete contents of the `.po` file . You can check your work by adding `lang: zu` to your `_pkgdown.yml` then running: ```{r} #| eval: false potools::po_compile() devtools::load_all() build_site("~/path/to/your/site") ``` Once you're happy with your work, make sure to compile the changes: ```{r} #| eval: false potools::po_compile() ``` Then commit your changes to Git and submit your pull request for review: ```{r} #| eval: false usethis::pr_push() ``` pkgdown/inst/doc/customise.html0000644000176200001440000015750614672347606016403 0ustar liggesusers Customise your site

    Customise your site

    This vignette teaches you how to customise the style/design of your pkgdown site. We’ll start by discussing two techniques that only require tweaks to your _pkgdown.yml: theming (colours and fonts) and layout (content of the navbar, sidebar, footer, …). We’ll then discuss how to add additional HTML and other files. Next, we’ll discuss how to give multiple sites the same style using a package, then finish up with some workflow advice.

    In terms of your _pkgdown.yml, this vignette focusses on the most important fields nested under template and navbar. To learn more about customising other aspects of the site, see the documentation for the indiviudal functions like build_reference(), build_articles(), build_home(), build_redirects(), and init_site(). To learn about less important fields nested under template, see build_site().

    library(pkgdown)

    Getting started

    Most theming features work only with Bootstrap 5, so first update your site by adding the following lines to your _pkgdown.yml:

    template:
      bootstrap: 5

    Overall, the site should look pretty similar, but you will notice a number of small improvements. Most importantly, the default font is much bigger, making it considerably easier to read. Upgrading to Bootstrap 5 has a low chance of breaking your site unless you were using your own pkgdown templates or custom CSS.

    Theming

    There are two ways to change the visual style of your site from _pkgdown.yml: using a pre-packaged bootswatch theme or customising theme variables with bslib. The following sections show you how.

    Please note that pkgdown’s default theme has been carefully optimised to be accessible, so if you make changes, make sure to also read vignette("accessibility") to learn about potential accessibility pitfalls.

    Light switch

    You can provide a “light switch” to allow your users to switch between dark and light themes by setting the light-switch template option to true:

    template:
      light-switch: true

    This will add a lightswitch component to the navbar, which by default appears at the far right. This allows the user to select light mode, dark mode, or auto mode (which follows the system setting). The modes are applied using Bootstrap 5.3’s colours modes so are not separate themes, but a thin layer of colour customisation applied via CSS.

    Bootswatch themes

    The easiest way to change the entire appearance of your website is to use a Bootswatch theme:

    template:
      bootstrap: 5
      bootswatch: materia

    (Themes are unlikely to work with the light switch, but you can try it and see.)

    Changing the bootswatch theme affects both the HTML (via the navbar, more on that below) and the CSS, so you’ll need to re-build your complete site with build_site() to fully appreciate the changes. While you’re experimenting, you can speed things up by just rebuilding the home page and the CSS by running build_home_index(); init_site() (and then refreshing the browser).

    Bootswatch templates with tall navbars (e.g. lux, pulse) also require that you set the pkgdown-nav-height bslib variable. Because Bootswatch themes are provided by the bslib R package, you can also nest the bootswatch field under the bslib field.

    template:
      bootstrap: 5
      bslib:
        bootswatch: lux
        pkgdown-nav-height: 100px

    You can find the correct height by running $(".navbar").outerHeight() in the javascript console.

    bslib variables

    Instead of picking a complete theme, you can tweak fonts and colours individually using bslib variables. bslib is an R package that wraps sass, the tool that Boostrap uses to produce CSS from a special language called scss. The primary advantage of scss over CSS is that it’s more programmable, so you can have a few key bslib variables that affect appearance of many HTML elements.

    There are three key variables that affect the colour:

    • bg (background) determines the page background.
    • fg (foreground) determines the text colour. bg and fg are mixed to yield gray-100, gray-200, …, grey-900, which are used to style other elements to match the overall colour scheme.
    • primary sets the link colour and the (translucent) hover colour in the navbar and sidebar.
    template:
      bootstrap: 5
      bslib:
        bg: "#202123"
        fg: "#B8BCC2"
        primary: "#306cc9"

    You can customise other components by setting more specific bslib variables, taking advantage of inheritance where possible. For example, table-border-color defaults to border-color which defaults to gray-300. If you want to change the colour of all borders, you can set border-color and if you just want to change the colour of table borders, you can set table-border-color. You can find a full list of variables in the bslib docs.

    If you’re using the light switch, many colours are available for customisation specifically for the dark theme.

    Theming with bslib is powered by bslib::bs_theme() and the bslib field is a direct translation of the arguments to that function. As a result, you can fully specify a bslib theme using the template.bslib field, making it easy to share YAML with the output.html_document.theme field of an R Markdown document.

    template:
      bslib:
        version: 5
        bg: "#202123"
        fg: "#B8BCC2"
        primary: "#306cc9"

    While iterating on colours and other variables you only need to rerun init_site() and refresh your browser to see the changes.

    Fonts

    You can also override the default fonts used for the majority of the text (base_font), for headings (heading_font) and for code (code_font). The easiest way is to supply the name of a Google font with the following syntax:

    template:
      bootstrap: 5
      bslib:
        base_font: {google: "Roboto"}
        heading_font: {google: "Roboto Slab"}
        code_font: {google: "JetBrains Mono"}

    If you want to use a non-Google font, you’ll need to do a bit more work. There are two steps: you need to first configure the font with CSS and then use it in your _pkgdown.yml. There are two ways you might get the CSS:

    • As a block of CSS which you should put in pkgdown/extra.scss or pkgdown/extra.css. The CSS will look something like this:

      @font-face {
        font-family: "proxima-nova";
        src: 
          local("Proxima Nova Regular"), 
          local("ProximaNova-Regular"),
          url("https://example.com/ProximaNova-Regular.eot?#iefix") format("embedded-opentype"),
          url("https://example.com/fonts/proxima/ProximaNova-Regular.woff2") format("woff2"),
          url("https://example.com/fonts/proxima/ProximaNova-Regular.woff") format("woff"),
          url("https://example.com/fonts/proxima/ProximaNova-Regular.ttf") format("truetype");
        font-weight: normal;
        font-style: normal;
        font-display: fallback;
      }
    • As a link to a style file, which you’ll need to add to the <head> using this syntax:

      template:
      includes:
        in_header: <link rel="stylesheet" type="text/css" href="https://..." />

    Then in _pkgdown.yml you can use the name of the font you just specified:

    template:
      bslib:
        base_font: proxima-nova

    Depending on where the font is from (and if you purchased it), you may need to take additional steps to ensure that it can only be used from your site, and/or make sure that it can still be used when you’re previewing locally. If you’re having problems getting a custom font to work, looking for errors in the browser developer console is a good place to start.

    When iterating on fonts, you’ll need to run build_home_index(); init_site() then refresh your browser to see the update.

    Syntax highlighting

    The colours used for syntax highlighting in code blocks are controlled by the theme setting:

    template:
      bootstrap: 5
      theme: breeze-light

    You can choose from any of the following options: a11y-dark, a11y-light, arrow-dark, arrow-light, atom-one-dark, atom-one-light, ayu-dark, ayu-light, ayu-mirage, breeze-dark, breeze-light, breezedark, dracula, espresso, github-dark, github-light, gruvbox-dark, gruvbox-light, haddock, kate, monochrome-dark, monochrome-light, monochrome, monokai, nord, oblivion, printing, pygments, radical, solarized-dark, solarized-light, solarized, tango, vim-dark, zenburn.

    Bootswatch themes with a dark background (e.g. cyborg, darkly, solar) will need a dark syntax highlighting theme, e.g. arrow-dark:

    template:
      bootstrap: 5
      bootswatch: cyborg
      theme: arrow-dark

    If you’re using the light switch, you will want to provide a theme and a theme-dark:

    template:
      light-switch: true
      theme: gruvbox-light
      theme-dark: gruvbox-dark

    The foreground and background colours used for inline code are controlled by code-color and code-bg bslib variables. If you want inline code to match code blocks, you’ll need to override the variables yourself, e.g.:

    template: 
      bootstrap: 5
      theme: arrow-dark  
      bslib:
        code-bg: "#2b2b2b"

    Math rendering

    By default, pkgdown will render math using mathml. mathml is the official standard for rendering math on the web, and requires no additional javascript or css dependencies. However, browser support for complex math is not always that good, so if you are including complex equations in your documentation, you may want to switch to either katex or mathjax by using the template.math-rendering field:

    template:
      math-rendering: katex

    Layout

    You can customise the contents of the navbar, footer, using the navbar and footer fields. See ?build_home for how to customise the sidebar on the homepage. They all use a similar structure that separately defines the overall structure and the individual components.

    Additional HTML and files

    If you need to include additional HTML, you can add it in the following locations:

    template:
      includes:
        in_header: <!-- inserted at the end of the head -->
        before_body: <!-- inserted at the beginning of the body -->
        after_body: <!-- inserted at the end of the body -->
        before_title: <!-- inserted before the package title in the header ->
        before_navbar: <!-- inserted before the navbar links -->
        after_navbar: <!-- inserted after the navbar links -->

    You can include additional files by putting them in the right place:

    • pkgdown/extra.css and pkgdown/extra.js will be copied to the rendered site and linked from <head> (after the pkgdown defaults).

    • pkgdown/extra.scss will be added to the scss ruleset used to generate the site CSS.

    • Any files in pkgdown/assets will be copied to the website root directory.

    • For expert users: template files in pkgdown/templates will override layout templates provided by pkgdown or template packages.

    Use init_site() to update your rendered website after making changes to these files.

    Template packages

    To share a pkgdown style across several packages, the best workflow is to create… a package! It can contain any of the following:

    • A configuration file in inst/pkgdown/_pkgdown.yml. This can be used to set (e.g.) author definitions, Bootstrap version and variables, the sidebar, footer, navbar, etc.
    • Templates in inst/pkgdown/templates/ will override the default templates.
    • Assets in inst/pkgdown/assets/ will be copied in to the destination directory. (Note these files are only copied; you’ll need to reference them in your stylesheet or elsewhere in order for them to be actually used.)
    • inst/pkgdown/extra.scss will be added to the bslib ruleset. (Note that extra.css is not supported in templates.)

    The pkgdown defaults will be overriden by these template files, which are in turn overridden by package specific settings.

    Once you have created your template package theverybest, you need to set it as your site’s theme:

    template:
      package: theverybest

    You then also need to make sure it’s available when your site is built. Typically, you won’t want to publish this package to CRAN, but you will want to publish to GitHub. Once you’ve done that, and assuming you’re using the usethis workflow, add the following line to your DESCRIPTION:

    Config/Needs/website: myorg/theverybest

    This will ensure that the GitHub action will automatically install it from GitHub when building your pkgdown site.

    To get some sense of how a theming package works, you can look at:

    But please note that these templates aren’t suitable for use with your own package as they’re all designed to give a common visual identity to a specific family of packages.

    Porting a template package

    If you are updating a template package that works with pkgdown 1.0.0, create directories inst/pkgdown/BS5/templates and inst/pkgdown/BS5/assets (if you don’t have any templates/assets make sure to a add dummy file to ensure that git tracks them). The templates and assets directories directly under inst/pkgdown will be used by pkgdown 1.0.0 and by pkgdown 2.0.0 if boostrap: 3. The directories under inst/pkgdown/BS5/ will be used for pkgdown 2.0.0 with boostrap: 5. This lets your package support both versions of Bootstrap and pkgdown.

    PR previews

    Lastly, it might be useful for you to get a preview of the website in internal pull requests. For that, you could use Netlify and GitHub Actions (or apply a similar logic to your toolset):

    • Create a new Netlify website (either from scratch by dragging and dropping a simple index.html, or by creating a site from a GitHub repository and then unlinking that repository); from the site settings get its ID to be saved as NETLIFY_SITE_ID in your repo secrets; from your account developer settings get a token to be saved as NETLIFY_AUTH_TOKEN in your repo secrets.
    • Starting from the standard pkgdown workflow usethis::use_github_action("pkgdown"), add some logic to build the site and deploy it to Netlify for pull requests from inside the repository, not pull requests from forks. Example workflow.

    Conclusion

    In this vignette we explained how to change the theming and layout of pkgdown websites. Further work to improve user experience will involve:

    • Working on the article (?build_articles) and reference indexes (?build_reference).
    • Writing a compelling README that explains why your package is so cool/useful/fun.
    • Improving the contents of the individual articles and reference topics 😉.

    1. Note that dots (.) in the package name need to be replaced by hyphens (-) in the vignette filename to be recognized as the intro. That means for a package foo.bar the intro needs to be named foo-bar.Rmd.↩︎

    pkgdown/inst/doc/customise.R0000644000176200001440000000036214672347605015622 0ustar liggesusers## ----include = FALSE---------------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ## ----setup-------------------------------------------------------------------- library(pkgdown) pkgdown/inst/doc/quarto.R0000644000176200001440000000022714672347611015117 0ustar liggesusers## ----------------------------------------------------------------------------- #| fig.alt: A plot of the numbers 1, 2, and 3 1 + 1 2 + 2 plot(1:3) pkgdown/inst/doc/quarto.html0000644000176200001440000064332014672347611015671 0ustar liggesusers quarto vignettes

    quarto vignettes

    pkgdown effectively uses quarto only to generate HTML and then supplies its own CSS and JS. This means that when quarto introduces new features, pkgdown may lag behind in their support. If you’re trying out something that doesn’t work (and isn’t mentioned explicitly below), please file an issue so we can look into it.

    Operation

    pkgdown turns your articles directory into a quarto project by temporarily adding a _quarto.yml to your articles. You can also add your own if you want to control options for all quarto articles. If you do so, and you have a mix of .qmd and .Rmd files, you’ll need to include the following yaml so that RMarkdown can continue to handle the .Rmd files:

    project:
      render: ['*.qmd']

    GitHub Actions

    The setup-r-dependencies action will automatically install Quarto in your GitHub Actions if a .qmd file is present in your repository (see the install-quarto parameter for more details).

    Limitations

    Supported features

    The following sections demonstrate a bunch of useful quarto features so that we can make sure that they work.

    Inline formatting

    • Small caps

    • Here is a footnote reference1

    Code

    1 + 1
    #> [1] 2
    2 + 2
    #> [1] 4
    
    plot(1:3)

    A plot of the numbers 1, 2, and 3

    Figures

    (a) A sketch of a pitbull puppy
    (b) A sketch of a sharpei puppy
    Figure 1: Cute puppies

    Equations

    $$ \frac{\partial \mathrm C}{ \partial \mathrm t } + \frac{1}{2}\sigma^{2} \mathrm S^{2} \frac{\partial^{2} \mathrm C}{\partial \mathrm C^2} + \mathrm r \mathrm S \frac{\partial \mathrm C}{\partial \mathrm S}\ = \mathrm r \mathrm C \qquad(1)$$

    Cross references

    See Figure 1 for two cute puppies.

    Black-Scholes (Equation 1) is a mathematical model that seeks to explain the behavior of financial derivatives, most commonly options.

    To do


    1. And here is the footnote.↩︎

    pkgdown/inst/doc/translations.html0000644000176200001440000003235014672347610017071 0ustar liggesusers Translations

    Translations

    If your documentation (.Rd and .Rmd) is written in a language other than English, declare it by setting setting lang to the language code for your language:

    lang: fr

    This will be used to set the language of the web page and to translate the English words that pkgdown generates on your site. Current available translations are:

    • ca: Catalan
    • de: German
    • dk: Danish
    • es: Spanish
    • fr: French
    • ko: Korean
    • pt: Portuguese
    • tr: Turkish
    • zh_CN: Chinese (simplified)

    As you can see, most language codes are two letters, but if a language has multiple variants, it gets a longer form which can be used to disambiguate the options. For example, Chinese can use one of two forms: simplified (used in China and Singapore) or traditional (used in Taiwan and Hong Kong). Another example would be providing specific French Canadian translations by using code fr_CN.

    Translations

    Translations are contributed by community members so if your language is not currently available, you could be the one to add it!

    To get started, first check the pkgdown issues to see if anyone has filed an existing issue. If so, the person who filed the issue might make for a great collaborator 😀.

    Next, install potools and usethis:

    install.packages(c("potools", "usethis"))

    You’ll then need to familiarise yourself with the basics of translations with potools and creating pull requests with usethis.

    If you don’t already know it, you’ll need to look up the ISO 639-1 abbreviation for your language. In the examples below, I’ll pretend I’m providing translations for Zulu, which has code zu.

    Start by initialising a pull request:

    usethis::pr_init("translation-zu")

    Then create the translation file by running potools::po_create("zu"), open po/R-zu.po, and starting filling in the translations.

    If you have access to chatGPT or similar, you can try prepopulating the translations, with a prompt something like thii:

    You are an R developer who is fluent in English and Zulu. You love to do careful, high quality translations in your spare time. Complete the following po file for the R pkgdown package (which creates websites for R packages) by supplying translations for Zulu. Use inclusive gender forms where possible.

    Then copy and paste the complete contents of the .po file .

    You can check your work by adding lang: zu to your _pkgdown.yml then running:

    potools::po_compile()
    devtools::load_all()
    build_site("~/path/to/your/site")

    Once you’re happy with your work, make sure to compile the changes:

    potools::po_compile()

    Then commit your changes to Git and submit your pull request for review:

    usethis::pr_push()
    pkgdown/inst/doc/translations.R0000644000176200001440000000140114672347607016325 0ustar liggesusers## ----include = FALSE---------------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ## ----------------------------------------------------------------------------- # install.packages(c("potools", "usethis")) ## ----------------------------------------------------------------------------- # usethis::pr_init("translation-zu") ## ----------------------------------------------------------------------------- # potools::po_compile() # devtools::load_all() # build_site("~/path/to/your/site") ## ----------------------------------------------------------------------------- # potools::po_compile() ## ----------------------------------------------------------------------------- # usethis::pr_push() pkgdown/inst/doc/accessibility.R0000644000176200001440000000036214672347605016436 0ustar liggesusers## ----include = FALSE---------------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ## ----setup-------------------------------------------------------------------- library(pkgdown) pkgdown/inst/doc/quarto.qmd0000644000176200001440000000662514671042466015506 0ustar liggesusers--- title: quarto vignettes description: > Learn how quarto vignettes work with pkgdown, including currently supported features and known limitations. vignette: > %\VignetteIndexEntry{quarto vignettes} %\VignetteEngine{quarto::html} %\VignetteEncoding{UTF-8} knitr: opts_chunk: collapse: true comment: '#>' --- pkgdown effectively uses quarto only to generate HTML and then supplies its own CSS and JS. This means that when quarto introduces new features, pkgdown may lag behind in their support. If you're trying out something that doesn't work (and isn't mentioned explicitly below), please [file an issue](https://github.com/r-lib/pkgdown/issues) so we can look into it. ## Operation pkgdown turns your articles directory into a quarto project by temporarily adding a `_quarto.yml` to your articles. You can also add your own if you want to control options for all quarto articles. If you do so, and you have a mix of `.qmd` and `.Rmd` files, you'll need to include the following yaml so that RMarkdown can continue to handle the .Rmd files: ```yaml project: render: ['*.qmd'] ``` ### GitHub Actions The `setup-r-dependencies` action will [automatically](https://github.com/r-lib/actions/tree/v2-branch/setup-r-dependencies#usage) install Quarto in your GitHub Actions if a .qmd file is present in your repository (see the `install-quarto` parameter for more details). ## Limitations * Callouts are not currently supported (). * pkgdown assumes that you're using [quarto vignette style](https://quarto-dev.github.io/quarto-r/articles/hello.html), or more generally an html format with [`minimal: true`](https://quarto.org/docs/output-formats/html-basics.html#minimal-html). Specifically, only HTML vignettes are currently supported. * You can't customise mermaid styles with quarto mermaid themes. If you want to change the colours, you'll need to provide your own custom CSS as shown in [the quarto docs](https://quarto.org/docs/authoring/diagrams.html#customizing-mermaid). * pkgdown will pass the `lang` setting on to quarto, but the set of available language is not perfectly matched. Learn more in , including how to supply your own translations. ## Supported features The following sections demonstrate a bunch of useful quarto features so that we can make sure that they work. ### Inline formatting * [Small caps]{.smallcaps} * Here is a footnote reference[^1] [^1]: And here is the footnote. ### Code ```{r} #| fig.alt: A plot of the numbers 1, 2, and 3 1 + 1 2 + 2 plot(1:3) ``` ### Figures ::: {#fig-puppies layout-ncol=2} ![A sketch of a pitbull puppy](pitbull.jpg){#fig-pitbull} ![A sketch of a sharpei puppy](shar-pei.jpg){#fig-shar-pei} Cute puppies ::: ### Equations $$ \frac{\partial \mathrm C}{ \partial \mathrm t } + \frac{1}{2}\sigma^{2} \mathrm S^{2} \frac{\partial^{2} \mathrm C}{\partial \mathrm C^2} + \mathrm r \mathrm S \frac{\partial \mathrm C}{\partial \mathrm S}\ = \mathrm r \mathrm C $$ {#eq-black-scholes} ### Cross references See @fig-puppies for two cute puppies. Black-Scholes (@eq-black-scholes) is a mathematical model that seeks to explain the behavior of financial derivatives, most commonly options. ## To do * [ ] Code annotations * [ ] Tabsets * [x] Citations * [x] Task/to do lists * [x] Figures * [x] Equations * [x] Cross-references * [x] Footnotes * [x] Callouts pkgdown/inst/doc/metadata.Rmd0000644000176200001440000001235514672347347015720 0ustar liggesusers--- title: "Metadata" description: > Customise metadata and social media cards for pkgdown websites. output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Metadata} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` Package authors can customize the metadata used by Twitter and the [Open Graph protocol][ogp] for rich social media cards. In addition to specifying an alternate description for the package and any individual articles, you may also choose the preview image shown and the style of the card used on Twitter. You can preview and validate the appearance of the social media cards with online tools: * [Google Rich Results Test][ogp-validator] * Drafting a tweet to yourself * Sending yourself a Slack message ## Necessary configuration Metadata can only be produced correctly if your pkgdown website URL is indicated in its configuration file. ```yaml url: https://example.com ``` ## Site-wide customization Metadata for the entire pkgdown website can be specified in the site's `_pkgdown.yml` configuration file in the `home` and `template: opengraph` sections: ```yaml home: title: An R package for pool-noodle discovery description: Discover and add pool-noodles to your growing collection. template: opengraph: image: src: man/figures/card.png alt: "Pool noodles configured to form the word poolnoodlr" twitter: creator: "@hadleywickham" site: "@rstudio" card: summary_large_image ``` The `home: title` and `home: description` fields override the `Title` and `Description` fields in the package `DESCRIPTION`. It's good practice to set these fields to make your package documentation easier to find via search, rather than sticking with the title and description needed by CRAN. The `template: opengraph` section allows you to further customize the social media card. * `image`: By default, pkgdown uses the package's logo for the card image (if one exists). Use `image` to specify an alternative image for the social media cards of pages in your pkgdown site. * `src`: A fully qualified URL to a media card image e.g. `src: https://avatars.githubusercontent.com/u/22618716?v=4`; or a relative path to an image in the rendered website e.g. `src: articles/test/image.jpg`; or a relative path to an image stored in `man/figures` in the package e.g. `src: man/figures/cards.png`. The `src` field is required if `image` is specified. * `alt`: Alternative text describing the image for screen readers and other situations where your social media card image cannot be displayed. * `twitter`: You can specify the Twitter accounts associated with your package and the [style of social media card][twitter-card] that Twitter will display. * `creator`: Typically, the Twitter handle of the author of the package or article. * `site`: The Twitter handle of the organization affiliated with the package author or sponsoring the package development. * If only one of either `creator` or `site` is included, the provided value will be used for both fields. * `card`: The [style of social media card][twitter-card] that Twitter will display. For pkgdown sites, the most relevant options are `summary_large_image`, featuring a large image over the page title and description, or `summary`, featuring a small square image inline and to the left of the page title and description. ## Article metadata Articles and vignettes rendered as articles by pkgdown can have individually customized metadata and social media cards. ```yaml title: "Introduction to poolnoodlr" description: "A brief introduction to pool noodles in R." author: "Mara Averick" opengraph: image: src: "https://example.com/pkg/batpig.png" twitter: card: summary creator: "@dataandme" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Introduction to poolnoodlr} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} ``` Use the `title`, `description`, and `author` fields to specify the title, description, and (optional) author of the vignette or article. * The `title` field is used as the title of your article in your pkgdown site and should always be included. * Both `title` and `description` are used by pkgdown for the page's social media card. If `description` is not included in the article's YAML front matter, then the name of the package is used instead. The `description` is also displayed on the articles index. - The `author` field is only used in the text of the vignette or article. How the author name is displayed depends on the `output` format. In articles, the `opengraph` section works in the same way as the site-wide `template: opengraph` settings, but is only applied to the article or vignette. This allows you to specify social media card preview images for individual articles, or to associate an article with a particular Twitter account. If not specified, the `opengraph` settings from the site-wide configuration are used. [ogp]: https://ogp.me/ [ogp-validator]: https://search.google.com/test/rich-results [twitter-card]: https://developer.x.com/en/docs/x-for-websites/cards/overview/abouts-cards pkgdown/inst/doc/accessibility.Rmd0000644000176200001440000000421414633374223016750 0ustar liggesusers--- title: "Accessibility" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Accessibility} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` pkgdown automates as many accessibility details as possible, so that your package website is readable by as many people as possible. This vignette describes the additional details that can't be automated away and you need to be aware of. ```{r setup} library(pkgdown) ``` ## Theming * If you adjust any colours from the default theme (including the syntax highlighting theme), you should double check that the contrast between the background and foreground doesn't make any text difficult to read. A good place to start is running a representative page of your site through . * The default colour of the development version label makes a slightly too low contrast against the pale grey background of the navbar. This colour comes from the bootstrap "danger" colour, so you can fix it by overriding that variable in your `_pkgdown.yml`: ```yaml template: bootstrap: 5 bslib: danger: "#A6081A" ``` * If you use custom navbar entries that only display an icon, make sure to also use the `aria-label` field to provide an accessible label that describes the icon. ```yaml cran: icon: fab fa-r-project href: https://cloud.r-project.org/package=pkgdown aria-label: View on CRAN ``` ## Images To make your site fully accessible, the place where you are likely to need to do the most work is adding alternative text to any images that you create. Unfortunately, there's currently no way to do this for plots you generate in examples, but you can and should add alternative text to plots in vignettes using the `fig.alt` chunk option: ````{verbatim} ```{r} #| fig.alt: > #| Histogram of time between eruptions for Old Faithful. #| It is a bimodal distribution with peaks at 50-55 and #| 80-90 minutes. hist(faithful$waiting) ``` ```` If you forget to add alt text to your vignettes, pkgdown will automatically remind you. pkgdown/inst/doc/customise.Rmd0000644000176200001440000005212614671042466016144 0ustar liggesusers--- title: "Customise your site" output: rmarkdown::html_vignette description: > Learn how to change the look and feel of your pkgdown site. vignette: > %\VignetteIndexEntry{Customise your site} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` This vignette teaches you how to customise the style/design of your pkgdown site. We'll start by discussing two techniques that only require tweaks to your `_pkgdown.yml`: theming (colours and fonts) and layout (content of the navbar, sidebar, footer, ...). We'll then discuss how to add additional HTML and other files. Next, we'll discuss how to give multiple sites the same style using a package, then finish up with some workflow advice. In terms of your `_pkgdown.yml`, this vignette focusses on the most important fields nested under `template` and `navbar`. To learn more about customising other aspects of the site, see the documentation for the indiviudal functions like `build_reference()`, `build_articles()`, `build_home()`, `build_redirects()`, and `init_site()`. To learn about less important fields nested under `template`, see `build_site()`. ```{r setup} library(pkgdown) ``` ## Getting started Most theming features work only with Bootstrap 5, so first update your site by adding the following lines to your `_pkgdown.yml`: ``` yaml template: bootstrap: 5 ``` Overall, the site should look pretty similar, but you will notice a number of small improvements. Most importantly, the default font is much bigger, making it considerably easier to read. Upgrading to Bootstrap 5 has a low chance of breaking your site unless you were using your [own pkgdown templates](#template-packages) or custom CSS. ## Theming There are two ways to change the visual style of your site from `_pkgdown.yml`: using a pre-packaged bootswatch theme or customising theme variables with [bslib](https://rstudio.github.io/bslib/). The following sections show you how. Please note that pkgdown's default theme has been carefully optimised to be accessible, so if you make changes, make sure to also read `vignette("accessibility")` to learn about potential accessibility pitfalls. ### Light switch {#light-switch} You can provide a "light switch" to allow your users to switch between dark and light themes by setting the `light-switch` template option to true: ```yaml template: light-switch: true ``` This will add a `lightswitch` component to the navbar, which by default appears at the far right. This allows the user to select light mode, dark mode, or auto mode (which follows the system setting). The modes are applied using Bootstrap 5.3's [colours modes](https://getbootstrap.com/docs/5.3/customize/color-modes/) so are not separate themes, but a thin layer of colour customisation applied via CSS. ### Bootswatch themes The easiest way to change the entire appearance of your website is to use a [Bootswatch theme](https://bootswatch.com): ``` yaml template: bootstrap: 5 bootswatch: materia ``` (Themes are unlikely to work with the light switch, but you can try it and see.) Changing the bootswatch theme affects both the HTML (via the navbar, more on that below) and the CSS, so you'll need to re-build your complete site with `build_site()` to fully appreciate the changes. While you're experimenting, you can speed things up by just rebuilding the home page and the CSS by running `build_home_index()`; `init_site()` (and then refreshing the browser). Bootswatch templates with tall navbars (e.g. lux, pulse) also require that you set the `pkgdown-nav-height` bslib variable. Because Bootswatch themes are provided by the [bslib](https://rstudio.github.io/bslib/) R package, you can also nest the `bootswatch` field under the `bslib` field. ``` yaml template: bootstrap: 5 bslib: bootswatch: lux pkgdown-nav-height: 100px ``` You can find the correct height by running `$(".navbar").outerHeight()` in the [javascript console](https://firefox-source-docs.mozilla.org/devtools-user/web_console/index.html). ### bslib variables Instead of picking a complete theme, you can tweak fonts and colours individually using bslib variables. [bslib](https://rstudio.github.io/bslib/) is an R package that wraps sass, the tool that Boostrap uses to produce CSS from a special language called [scss](https://sass-lang.com). The primary advantage of scss over CSS is that it's more programmable, so you can have a few key bslib variables that affect appearance of many HTML elements. There are three key variables that affect the colour: - `bg` (background) determines the page background. - `fg` (foreground) determines the text colour. `bg` and `fg` are mixed to yield `gray-100`, `gray-200`, ..., `grey-900`, which are used to style other elements to match the overall colour scheme. - `primary` sets the link colour and the (translucent) hover colour in the navbar and sidebar. ``` yaml template: bootstrap: 5 bslib: bg: "#202123" fg: "#B8BCC2" primary: "#306cc9" ``` You can customise other components by setting more specific bslib variables, taking advantage of inheritance where possible. For example, `table-border-color` defaults to `border-color` which defaults to `gray-300`. If you want to change the colour of all borders, you can set `border-color` and if you just want to change the colour of table borders, you can set `table-border-color`. You can find a full list of variables in the [bslib docs](https://rstudio.github.io/bslib/articles/bs5-variables/index.html). If you're using the light switch, [many colours](https://getbootstrap.com/docs/5.3/customize/color-modes/#sass-variables) are available for customisation specifically for the dark theme. Theming with bslib is powered by `bslib::bs_theme()` and the `bslib` field is a direct translation of the arguments to that function. As a result, you can fully specify a bslib theme using the `template.bslib` field, making it easy to share YAML with the `output.html_document.theme` field [of an R Markdown document](https://rstudio.github.io/bslib/articles/theming/index.html). ``` yaml template: bslib: version: 5 bg: "#202123" fg: "#B8BCC2" primary: "#306cc9" ``` While iterating on colours and other variables you only need to rerun `init_site()` and refresh your browser to see the changes. ### Fonts You can also override the default fonts used for the majority of the text (`base_font`), for headings (`heading_font`) and for code (`code_font`). The easiest way is to supply the name of a [Google font](https://fonts.google.com) with the following syntax: ``` yaml template: bootstrap: 5 bslib: base_font: {google: "Roboto"} heading_font: {google: "Roboto Slab"} code_font: {google: "JetBrains Mono"} ``` If you want to use a non-Google font, you'll need to do a bit more work. There are two steps: you need to first configure the font with CSS and then use it in your `_pkgdown.yml`. There are two ways you might get the CSS: * As a block of CSS which you should put in `pkgdown/extra.scss` or `pkgdown/extra.css`. The CSS will look something like this: ```css @font-face { font-family: "proxima-nova"; src: local("Proxima Nova Regular"), local("ProximaNova-Regular"), url("https://example.com/ProximaNova-Regular.eot?#iefix") format("embedded-opentype"), url("https://example.com/fonts/proxima/ProximaNova-Regular.woff2") format("woff2"), url("https://example.com/fonts/proxima/ProximaNova-Regular.woff") format("woff"), url("https://example.com/fonts/proxima/ProximaNova-Regular.ttf") format("truetype"); font-weight: normal; font-style: normal; font-display: fallback; } ``` * As a link to a style file, which you'll need to add to the `` using this syntax: ```yaml template: includes: in_header: ``` Then in `_pkgdown.yml` you can use the name of the font you just specified: ```yaml template: bslib: base_font: proxima-nova ``` Depending on where the font is from (and if you purchased it), you may need to take additional steps to ensure that it can only be used from your site, and/or make sure that it can still be used when you're previewing locally. If you're having problems getting a custom font to work, looking for errors in the [browser developer console](https://developer.mozilla.org/en-US/docs/Glossary/Developer_Tools) is a good place to start. When iterating on fonts, you'll need to run `build_home_index(); init_site()` then refresh your browser to see the update. ### Syntax highlighting The colours used for syntax highlighting in code blocks are controlled by the `theme` setting: ``` yaml template: bootstrap: 5 theme: breeze-light ``` You can choose from any of the following options: `r paste0(pkgdown:::highlight_styles(), collapse = ", ")`. Bootswatch themes with a dark background (e.g. cyborg, darkly, solar) will need a dark syntax highlighting `theme`, e.g. `arrow-dark`: ``` yaml template: bootstrap: 5 bootswatch: cyborg theme: arrow-dark ``` If you're using the light switch, you will want to provide a `theme` and a `theme-dark`: ```yaml template: light-switch: true theme: gruvbox-light theme-dark: gruvbox-dark ``` The foreground and background colours used for inline code are controlled by `code-color` and `code-bg` bslib variables. If you want inline code to match code blocks, you'll need to override the variables yourself, e.g.: ``` yaml template: bootstrap: 5 theme: arrow-dark bslib: code-bg: "#2b2b2b" ``` ### Math rendering By default, pkgdown will render math using mathml. mathml is the official standard for rendering math on the web, and requires no additional javascript or css dependencies. However, browser support for complex math is not always that good, so if you are including complex equations in your documentation, you may want to switch to either [`katex`](https://katex.org) or [`mathjax`](https://www.mathjax.org) by using the `template.math-rendering` field: ```yaml template: math-rendering: katex ``` ### Navbar style The primary navbar colours are determined by HTML classes, not CSS, and can be customized using the `navbar` fields `bg` and `type` which control the background and foreground colours respectively. Typically `bg` will be one of `light`, `dark`, or `primary`: ``` yaml navbar: bg: primary ``` You generally don't need to set `bg` if you use a bootswatch theme, as pkgdown will pick the `bg` used on the [Bootswatch preview](https://bootswatch.com/). Similarly, you don't usually need to set `type` because bootstrap will guess it for you. If the guess is wrong, you can override with `type: light` or `type: dark` depending on whether the background colour is light (so you need dark text) or `type: dark` if the background is dark (so you need light text). Unfortunately, these are defined relative to the page background, so if you have a dark site you'll need to flip `light` and `dark` (a little experimentation should quickly determine what looks best). Because the navbar is styled with HTML, you'll need to `build_home_index(); init_site()` to see the effect of changing this parameter. ## Layout {#layout} You can customise the contents of the navbar, footer, using the `navbar` and `footer` fields. See `?build_home` for how to customise the sidebar on the homepage. They all use a similar structure that separately defines the overall `structure` and the individual `components`. ### Navbar {#navbar-heading} You can customise the navigation bar that appears at the top of the page with the `navbar` field. It's made up of two pieces: `structure`, which defines the overall layout, and `components`, which defines what each piece looks like. This organisation makes it easy to mix and match pkgdown defaults with your own customisations. This is the default structure: ``` yaml navbar: structure: left: [intro, reference, articles, tutorials, news] right: [search, github, lightswitch] ``` It makes use of the the following built-in components: - `intro`: "Get Started", which links to a vignette or article with the same name as the package[^dots]. - `reference`: if there are any `.Rd` files. - `articles`: if there are any vignettes or articles. - `tutorials`: if there any tutorials. - `news`: if `NEWS.md` exists. - `search`: the search box (see `?build_search` for more details). - `github`: a link to the source repository (with an icon), if it can be automatically determined from the `DESCRIPTION`. - `lightswitch`; a ["light switch"](#light-switch) to select light mode, dark mode, or auto mode. Note that customising `navbar` like this comes with a downside: if pkgdown later changes the defaults, you'll have to update your `_pkgdown.yml`. [^dots]: Note that dots (`.`) in the package name need to be replaced by hyphens (`-`) in the vignette filename to be recognized as the intro. That means for a package `foo.bar` the intro needs to be named `foo-bar.Rmd`. You can use the `structure` field to reorganise the navbar without changing the default contents: ``` yaml navbar: structure: left: [search] right: [reference, articles] ``` You can use `components` to override the default content. For example, this yaml provides a custom articles menu: ``` yaml navbar: components: articles: text: Articles menu: - text: Category A - text: Title A1 href: articles/a1.html - text: Title A2 href: articles/a2.html - text: ------- - text: "Category B" - text: Article B1 href: articles/b1.html ``` Components uses the same syntax as [RMarkdown menus](https://bookdown.org/yihui/rmarkdown/rmarkdown-site.html#site-navigation). The elements of `menu` can be: - Linked text (`text`, `href`, and an optional `target`). - A linked icon (`icon`, `aria-label`, `href`, and an optional `target`). You can find a list of available icons at [fontawesome](https://fontawesome.com/icons?d=gallery). Provide a text description of the icon in the `aria-label` field for screenreader users. - A heading (just `text`). - A separator (`text: ——–`). To add a new component to the navbar, you need to modify both `structure` and `components`. For example, the following yaml adds a new "twitter" component that appears to the left of the github icon. ``` yaml navbar: structure: right: [search, twitter, github, lightswitch] components: twitter: icon: fa-twitter href: http://twitter.com/hadleywickham aria-label: Twitter ``` Finally, you can add arbitrary HTML to three locations in the navbar: ```yaml template: includes: before_title: after_navbar: ``` These inclusions will appear on all screen sizes, and will not be collapsed into the the navbar drop down. You can also customise the colour scheme of the navbar by using the `type` and `bg` parameters. See above for details. ### Footer You can customise the footer with the `footer` field. It's made up of two pieces: `structure`, which defines the overall layout, and `components`, which defines what each piece looks like. This organisation makes it easy to mix and match the pkgdown defaults with your own customisations. This is the default structure: ``` yaml footer: structure: left: developed_by right: built_with ``` Which uses two of the three built-in components: - `developed_by`: a sentence describing the main authors of the package. (See `?build_home` if you want to tweak *which* authors appear in the footer.) - `built_with`: a sentence advertising pkgdown. - `package`: the name of the package. You can override these defaults with the `footer` field. The example below puts the author's information on the right along with a legal disclaimer, and puts the pkgdown link on the left. ``` yaml footer: structure: left: pkgdown right: [developed_by, legal] components: legal: Provided without **any warranty**. ``` Each side is pasted into a single string (separated by `" "`) and then converted from markdown to HTML. ## Additional HTML and files If you need to include additional HTML, you can add it in the following locations: ``` yaml template: includes: in_header: before_body: after_body: before_title: after_navbar: ``` You can include additional files by putting them in the right place: - `pkgdown/extra.css` and `pkgdown/extra.js` will be copied to the rendered site and linked from `` (after the pkgdown defaults). - `pkgdown/extra.scss` will be added to the scss ruleset used to generate the site CSS. - Any files in `pkgdown/assets` will be copied to the website root directory. - For expert users: template files in `pkgdown/templates` will override layout templates provided by pkgdown or [template packages](#template-packages). Use `init_site()` to update your rendered website after making changes to these files. ## Template packages {#template-packages} To share a pkgdown style across several packages, the best workflow is to create... a package! It can contain any of the following: - A configuration file in `inst/pkgdown/_pkgdown.yml`. This can be used to set (e.g.) author definitions, Bootstrap version and variables, the sidebar, footer, navbar, etc. - Templates in `inst/pkgdown/templates/` will override the default templates. - Assets in `inst/pkgdown/assets/` will be copied in to the destination directory. (Note these files are only copied; you'll need to reference them in your stylesheet or elsewhere in order for them to be actually used.) - `inst/pkgdown/extra.scss` will be added to the bslib ruleset. (Note that `extra.css` is not supported in templates.) The pkgdown defaults will be overriden by these template files, which are in turn overridden by package specific settings. Once you have created your template package `theverybest`, you need to set it as your site's theme: ``` yaml template: package: theverybest ``` You then also need to make sure it's available when your site is built. Typically, you won't want to publish this package to CRAN, but you will want to publish to GitHub. Once you've done that, and assuming you're using the [usethis workflow](https://usethis.r-lib.org/reference/use_pkgdown.html), add the following line to your `DESCRIPTION`: ```yaml Config/Needs/website: myorg/theverybest ``` This will ensure that the GitHub action will automatically install it from GitHub when building your pkgdown site. To get some sense of how a theming package works, you can look at: - [tidytemplate](https://tidytemplate.tidyverse.org/) used for tidyverse and tidymodels packages; - [quillt](https://pkgs.rstudio.com/quillt) used for R Markdown packages; - [rotemplate](https://github.com/ropensci-org/rotemplate) used for rOpenSci packages. But please note that these templates aren't suitable for use with your own package as they're all designed to give a common visual identity to a specific family of packages. ### Porting a template package If you are updating a template package that works with pkgdown 1.0.0, create directories `inst/pkgdown/BS5/templates` and `inst/pkgdown/BS5/assets` (if you don't have any templates/assets make sure to a add dummy file to ensure that git tracks them). The `templates` and `assets` directories directly under `inst/pkgdown` will be used by pkgdown 1.0.0 and by pkgdown 2.0.0 if `boostrap: 3`. The directories under `inst/pkgdown/BS5/` will be used for pkgdown 2.0.0 with `boostrap: 5`. This lets your package support both versions of Bootstrap and pkgdown. ## PR previews Lastly, it might be useful for you to get a preview of the website in internal pull requests. For that, you could use Netlify and GitHub Actions (or apply a similar logic to your toolset): - Create a new Netlify website (either from scratch by dragging and dropping a simple index.html, or by creating a site from a GitHub repository and then unlinking that repository); from the site settings get its ID to be saved as `NETLIFY_SITE_ID` in your repo secrets; from your account developer settings get a token to be saved as `NETLIFY_AUTH_TOKEN` in your repo secrets. - Starting from the standard pkgdown workflow `usethis::use_github_action("pkgdown")`, add some logic to build the site and deploy it to Netlify for pull requests from inside the repository, not pull requests from forks. [Example workflow](https://github.com/r-lib/pkgdown/blob/master/.github/workflows/pkgdown.yaml). ## Conclusion In this vignette we explained how to change the theming and layout of pkgdown websites. Further work to improve user experience will involve: - Working on the article (`?build_articles`) and reference indexes (`?build_reference`). - Writing a compelling README that explains why your package is so cool/useful/fun. - Improving the contents of the individual articles and reference topics 😉. pkgdown/inst/doc/metadata.R0000644000176200001440000000021714672347607015370 0ustar liggesusers## ----include = FALSE---------------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) pkgdown/inst/rstudio/0000755000176200001440000000000014633374223014400 5ustar liggesuserspkgdown/inst/rstudio/addins.dcf0000644000176200001440000000015314633374223016317 0ustar liggesusersName: Build full site Description: Build website for current package Binding: build_site Interactive: true pkgdown/inst/BS3/0000755000176200001440000000000014672347600013300 5ustar liggesuserspkgdown/inst/BS3/assets/0000755000176200001440000000000014612453757014607 5ustar liggesuserspkgdown/inst/BS3/assets/pkgdown.js0000644000176200001440000000626014134110164016577 0ustar liggesusers/* http://gregfranko.com/blog/jquery-best-practices/ */ (function($) { $(function() { $('.navbar-fixed-top').headroom(); $('body').css('padding-top', $('.navbar').height() + 10); $(window).resize(function(){ $('body').css('padding-top', $('.navbar').height() + 10); }); $('[data-toggle="tooltip"]').tooltip(); var cur_path = paths(location.pathname); var links = $("#navbar ul li a"); var max_length = -1; var pos = -1; for (var i = 0; i < links.length; i++) { if (links[i].getAttribute("href") === "#") continue; // Ignore external links if (links[i].host !== location.host) continue; var nav_path = paths(links[i].pathname); var length = prefix_length(nav_path, cur_path); if (length > max_length) { max_length = length; pos = i; } } // Add class to parent
  • , and enclosing
  • if in dropdown if (pos >= 0) { var menu_anchor = $(links[pos]); menu_anchor.parent().addClass("active"); menu_anchor.closest("li.dropdown").addClass("active"); } }); function paths(pathname) { var pieces = pathname.split("/"); pieces.shift(); // always starts with / var end = pieces[pieces.length - 1]; if (end === "index.html" || end === "") pieces.pop(); return(pieces); } // Returns -1 if not found function prefix_length(needle, haystack) { if (needle.length > haystack.length) return(-1); // Special case for length-0 haystack, since for loop won't run if (haystack.length === 0) { return(needle.length === 0 ? 0 : -1); } for (var i = 0; i < haystack.length; i++) { if (needle[i] != haystack[i]) return(i); } return(haystack.length); } /* Clipboard --------------------------*/ function changeTooltipMessage(element, msg) { var tooltipOriginalTitle=element.getAttribute('data-original-title'); element.setAttribute('data-original-title', msg); $(element).tooltip('show'); element.setAttribute('data-original-title', tooltipOriginalTitle); } if(ClipboardJS.isSupported()) { $(document).ready(function() { var copyButton = ""; $("div.sourceCode").addClass("hasCopyButton"); // Insert copy buttons: $(copyButton).prependTo(".hasCopyButton"); // Initialize tooltips: $('.btn-copy-ex').tooltip({container: 'body'}); // Initialize clipboard: var clipboardBtnCopies = new ClipboardJS('[data-clipboard-copy]', { text: function(trigger) { return trigger.parentNode.textContent.replace(/\n#>[^\n]*/g, ""); } }); clipboardBtnCopies.on('success', function(e) { changeTooltipMessage(e.trigger, 'Copied!'); e.clearSelection(); }); clipboardBtnCopies.on('error', function() { changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); }); }); } })(window.jQuery || window.$) pkgdown/inst/BS3/assets/docsearch.js0000644000176200001440000000374214134110164017063 0ustar liggesusers$(function() { // register a handler to move the focus to the search bar // upon pressing shift + "/" (i.e. "?") $(document).on('keydown', function(e) { if (e.shiftKey && e.keyCode == 191) { e.preventDefault(); $("#search-input").focus(); } }); $(document).ready(function() { // do keyword highlighting /* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */ var mark = function() { var referrer = document.URL ; var paramKey = "q" ; if (referrer.indexOf("?") !== -1) { var qs = referrer.substr(referrer.indexOf('?') + 1); var qs_noanchor = qs.split('#')[0]; var qsa = qs_noanchor.split('&'); var keyword = ""; for (var i = 0; i < qsa.length; i++) { var currentParam = qsa[i].split('='); if (currentParam.length !== 2) { continue; } if (currentParam[0] == paramKey) { keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20")); } } if (keyword !== "") { $(".contents").unmark({ done: function() { $(".contents").mark(keyword); } }); } } }; mark(); }); }); /* Search term highlighting ------------------------------*/ function matchedWords(hit) { var words = []; var hierarchy = hit._highlightResult.hierarchy; // loop to fetch from lvl0, lvl1, etc. for (var idx in hierarchy) { words = words.concat(hierarchy[idx].matchedWords); } var content = hit._highlightResult.content; if (content) { words = words.concat(content.matchedWords); } // return unique words var words_uniq = [...new Set(words)]; return words_uniq; } function updateHitURL(hit) { var words = matchedWords(hit); var url = ""; if (hit.anchor) { url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor; } else { url = hit.url + '?q=' + escape(words.join(" ")); } return url; } pkgdown/inst/BS3/assets/pkgdown.css0000644000176200001440000001621414612453757016776 0ustar liggesusers/* Sticky footer */ /** * Basic idea: https://philipwalton.github.io/solved-by-flexbox/demos/sticky-footer/ * Details: https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/site.css * * .Site -> body > .container * .Site-content -> body > .container .row * .footer -> footer * * Key idea seems to be to ensure that .container and __all its parents__ * have height set to 100% * */ html, body { height: 100%; } body { position: relative; } body > .container { display: flex; height: 100%; flex-direction: column; } body > .container .row { flex: 1 0 auto; } footer { margin-top: 45px; padding: 35px 0 36px; border-top: 1px solid #e5e5e5; color: #666; display: flex; flex-shrink: 0; } footer p { margin-bottom: 0; } footer div { flex: 1; } footer .pkgdown { text-align: right; } footer p { margin-bottom: 0; } img.icon { float: right; } /* Ensure in-page images don't run outside their container */ .contents img { max-width: 100%; height: auto; } /* Fix bug in bootstrap (only seen in firefox) */ summary { display: list-item; } /* Typographic tweaking ---------------------------------*/ .contents .page-header { margin-top: calc(-60px + 1em); } dd { margin-left: 3em; } /* Section anchors ---------------------------------*/ a.anchor { display: none; margin-left: 5px; width: 20px; height: 20px; background-image: url(./link.svg); background-repeat: no-repeat; background-size: 20px 20px; background-position: center center; } h1:hover .anchor, h2:hover .anchor, h3:hover .anchor, h4:hover .anchor, h5:hover .anchor, h6:hover .anchor { display: inline-block; } /* Fixes for fixed navbar --------------------------*/ .contents h1, .contents h2, .contents h3, .contents h4 { padding-top: 60px; margin-top: -40px; } /* Navbar submenu --------------------------*/ .dropdown-submenu { position: relative; } .dropdown-submenu>.dropdown-menu { top: 0; left: 100%; margin-top: -6px; margin-left: -1px; border-radius: 0 6px 6px 6px; } .dropdown-submenu:hover>.dropdown-menu { display: block; } .dropdown-submenu>a:after { display: block; content: " "; float: right; width: 0; height: 0; border-color: transparent; border-style: solid; border-width: 5px 0 5px 5px; border-left-color: #cccccc; margin-top: 5px; margin-right: -10px; } .dropdown-submenu:hover>a:after { border-left-color: #ffffff; } .dropdown-submenu.pull-left { float: none; } .dropdown-submenu.pull-left>.dropdown-menu { left: -100%; margin-left: 10px; border-radius: 6px 0 6px 6px; } /* Sidebar --------------------------*/ #pkgdown-sidebar { margin-top: 30px; position: -webkit-sticky; position: sticky; top: 70px; } #pkgdown-sidebar h2 { font-size: 1.5em; margin-top: 1em; } #pkgdown-sidebar h2:first-child { margin-top: 0; } #pkgdown-sidebar .list-unstyled li { margin-bottom: 0.5em; } /* bootstrap-toc tweaks ------------------------------------------------------*/ /* All levels of nav */ nav[data-toggle='toc'] .nav > li > a { padding: 4px 20px 4px 6px; font-size: 1.5rem; font-weight: 400; color: inherit; } nav[data-toggle='toc'] .nav > li > a:hover, nav[data-toggle='toc'] .nav > li > a:focus { padding-left: 5px; color: inherit; border-left: 1px solid #878787; } nav[data-toggle='toc'] .nav > .active > a, nav[data-toggle='toc'] .nav > .active:hover > a, nav[data-toggle='toc'] .nav > .active:focus > a { padding-left: 5px; font-size: 1.5rem; font-weight: 400; color: inherit; border-left: 2px solid #878787; } /* Nav: second level (shown on .active) */ nav[data-toggle='toc'] .nav .nav { display: none; /* Hide by default, but at >768px, show it */ padding-bottom: 10px; } nav[data-toggle='toc'] .nav .nav > li > a { padding-left: 16px; font-size: 1.35rem; } nav[data-toggle='toc'] .nav .nav > li > a:hover, nav[data-toggle='toc'] .nav .nav > li > a:focus { padding-left: 15px; } nav[data-toggle='toc'] .nav .nav > .active > a, nav[data-toggle='toc'] .nav .nav > .active:hover > a, nav[data-toggle='toc'] .nav .nav > .active:focus > a { padding-left: 15px; font-weight: 500; font-size: 1.35rem; } /* orcid ------------------------------------------------------------------- */ .orcid { font-size: 16px; color: #A6CE39; /* margins are required by official ORCID trademark and display guidelines */ margin-left:4px; margin-right:4px; vertical-align: middle; } /* Reference index & topics ----------------------------------------------- */ .ref-index th {font-weight: normal;} .ref-index td {vertical-align: top; min-width: 100px} .ref-index .icon {width: 40px;} .ref-index .alias {width: 40%;} .ref-index-icons .alias {width: calc(40% - 40px);} .ref-index .title {width: 60%;} .ref-arguments th {text-align: right; padding-right: 10px;} .ref-arguments th, .ref-arguments td {vertical-align: top; min-width: 100px} .ref-arguments .name {width: 20%;} .ref-arguments .desc {width: 80%;} /* Nice scrolling for wide elements --------------------------------------- */ table { display: block; overflow: auto; } /* Syntax highlighting ---------------------------------------------------- */ pre, code, pre code { background-color: #f8f8f8; color: #333; } pre, pre code { white-space: pre-wrap; word-break: break-all; overflow-wrap: break-word; } pre { border: 1px solid #eee; } pre .img, pre .r-plt { margin: 5px 0; } pre .img img, pre .r-plt img { background-color: #fff; } code a, pre a { color: #375f84; } a.sourceLine:hover { text-decoration: none; } .fl {color: #1514b5;} .fu {color: #000000;} /* function */ .ch,.st {color: #036a07;} /* string */ .kw {color: #264D66;} /* keyword */ .co {color: #888888;} /* comment */ .error {font-weight: bolder;} .warning {font-weight: bolder;} /* Clipboard --------------------------*/ .hasCopyButton { position: relative; } .btn-copy-ex { position: absolute; right: 0; top: 0; visibility: hidden; } .hasCopyButton:hover button.btn-copy-ex { visibility: visible; } /* headroom.js ------------------------ */ .headroom { will-change: transform; transition: transform 200ms linear; } .headroom--pinned { transform: translateY(0%); } .headroom--unpinned { transform: translateY(-100%); } /* mark.js ----------------------------*/ mark { background-color: rgba(255, 255, 51, 0.5); border-bottom: 2px solid rgba(255, 153, 51, 0.3); padding: 1px; } /* vertical spacing after htmlwidgets */ .html-widget { margin-bottom: 10px; } /* fontawesome ------------------------ */ .fab { font-family: "Font Awesome 5 Brands" !important; } /* don't display links in code chunks when printing */ /* source: https://stackoverflow.com/a/10781533 */ @media print { code a:link:after, code a:visited:after { content: ""; } } /* Section anchors --------------------------------- Added in pandoc 2.11: https://github.com/jgm/pandoc-templates/commit/9904bf71 */ div.csl-bib-body { } div.csl-entry { clear: both; } .hanging-indent div.csl-entry { margin-left:2em; text-indent:-2em; } div.csl-left-margin { min-width:2em; float:left; } div.csl-right-inline { margin-left:2em; padding-left:1em; } div.csl-indent { margin-left: 2em; } pkgdown/inst/BS3/assets/link.svg0000644000176200001440000000145214134110164016244 0ustar liggesusers pkgdown/inst/BS3/assets/bootstrap-toc.css0000644000176200001440000000346314134110164020104 0ustar liggesusers/*! * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) * Copyright 2015 Aidan Feldman * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ /* modified from https://github.com/twbs/bootstrap/blob/94b4076dd2efba9af71f0b18d4ee4b163aa9e0dd/docs/assets/css/src/docs.css#L548-L601 */ /* All levels of nav */ nav[data-toggle='toc'] .nav > li > a { display: block; padding: 4px 20px; font-size: 13px; font-weight: 500; color: #767676; } nav[data-toggle='toc'] .nav > li > a:hover, nav[data-toggle='toc'] .nav > li > a:focus { padding-left: 19px; color: #563d7c; text-decoration: none; background-color: transparent; border-left: 1px solid #563d7c; } nav[data-toggle='toc'] .nav > .active > a, nav[data-toggle='toc'] .nav > .active:hover > a, nav[data-toggle='toc'] .nav > .active:focus > a { padding-left: 18px; font-weight: bold; color: #563d7c; background-color: transparent; border-left: 2px solid #563d7c; } /* Nav: second level (shown on .active) */ nav[data-toggle='toc'] .nav .nav { display: none; /* Hide by default, but at >768px, show it */ padding-bottom: 10px; } nav[data-toggle='toc'] .nav .nav > li > a { padding-top: 1px; padding-bottom: 1px; padding-left: 30px; font-size: 12px; font-weight: normal; } nav[data-toggle='toc'] .nav .nav > li > a:hover, nav[data-toggle='toc'] .nav .nav > li > a:focus { padding-left: 29px; } nav[data-toggle='toc'] .nav .nav > .active > a, nav[data-toggle='toc'] .nav .nav > .active:hover > a, nav[data-toggle='toc'] .nav .nav > .active:focus > a { padding-left: 28px; font-weight: 500; } /* from https://github.com/twbs/bootstrap/blob/e38f066d8c203c3e032da0ff23cd2d6098ee2dd6/docs/assets/css/src/docs.css#L631-L634 */ nav[data-toggle='toc'] .nav > .active > ul { display: block; } pkgdown/inst/BS3/assets/docsearch.css0000644000176200001440000002675614134110164017251 0ustar liggesusers/* Docsearch -------------------------------------------------------------- */ /* Source: https://github.com/algolia/docsearch/ License: MIT */ .algolia-autocomplete { display: block; -webkit-box-flex: 1; -ms-flex: 1; flex: 1 } .algolia-autocomplete .ds-dropdown-menu { width: 100%; min-width: none; max-width: none; padding: .75rem 0; background-color: #fff; background-clip: padding-box; border: 1px solid rgba(0, 0, 0, .1); box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .175); } @media (min-width:768px) { .algolia-autocomplete .ds-dropdown-menu { width: 175% } } .algolia-autocomplete .ds-dropdown-menu::before { display: none } .algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-] { padding: 0; background-color: rgb(255,255,255); border: 0; max-height: 80vh; } .algolia-autocomplete .ds-dropdown-menu .ds-suggestions { margin-top: 0 } .algolia-autocomplete .algolia-docsearch-suggestion { padding: 0; overflow: visible } .algolia-autocomplete .algolia-docsearch-suggestion--category-header { padding: .125rem 1rem; margin-top: 0; font-size: 1.3em; font-weight: 500; color: #00008B; border-bottom: 0 } .algolia-autocomplete .algolia-docsearch-suggestion--wrapper { float: none; padding-top: 0 } .algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column { float: none; width: auto; padding: 0; text-align: left } .algolia-autocomplete .algolia-docsearch-suggestion--content { float: none; width: auto; padding: 0 } .algolia-autocomplete .algolia-docsearch-suggestion--content::before { display: none } .algolia-autocomplete .ds-suggestion:not(:first-child) .algolia-docsearch-suggestion--category-header { padding-top: .75rem; margin-top: .75rem; border-top: 1px solid rgba(0, 0, 0, .1) } .algolia-autocomplete .ds-suggestion .algolia-docsearch-suggestion--subcategory-column { display: block; padding: .1rem 1rem; margin-bottom: 0.1; font-size: 1.0em; font-weight: 400 /* display: none */ } .algolia-autocomplete .algolia-docsearch-suggestion--title { display: block; padding: .25rem 1rem; margin-bottom: 0; font-size: 0.9em; font-weight: 400 } .algolia-autocomplete .algolia-docsearch-suggestion--text { padding: 0 1rem .5rem; margin-top: -.25rem; font-size: 0.8em; font-weight: 400; line-height: 1.25 } .algolia-autocomplete .algolia-docsearch-footer { width: 110px; height: 20px; z-index: 3; margin-top: 10.66667px; float: right; font-size: 0; line-height: 0; } .algolia-autocomplete .algolia-docsearch-footer--logo { background-image: url("data:image/svg+xml;utf8,"); background-repeat: no-repeat; background-position: 50%; background-size: 100%; overflow: hidden; text-indent: -9000px; width: 100%; height: 100%; display: block; transform: translate(-8px); } .algolia-autocomplete .algolia-docsearch-suggestion--highlight { color: #FF8C00; background: rgba(232, 189, 54, 0.1) } .algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight { box-shadow: inset 0 -2px 0 0 rgba(105, 105, 105, .5) } .algolia-autocomplete .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content { background-color: rgba(192, 192, 192, .15) } pkgdown/inst/BS3/assets/bootstrap-toc.js0000644000176200001440000001123414134110164017723 0ustar liggesusers/*! * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) * Copyright 2015 Aidan Feldman * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ (function() { 'use strict'; window.Toc = { helpers: { // return all matching elements in the set, or their descendants findOrFilter: function($el, selector) { // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/ // http://stackoverflow.com/a/12731439/358804 var $descendants = $el.find(selector); return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])'); }, generateUniqueIdBase: function(el) { var text = $(el).text(); var anchor = text.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g, '-'); return anchor || el.tagName.toLowerCase(); }, generateUniqueId: function(el) { var anchorBase = this.generateUniqueIdBase(el); for (var i = 0; ; i++) { var anchor = anchorBase; if (i > 0) { // add suffix anchor += '-' + i; } // check if ID already exists if (!document.getElementById(anchor)) { return anchor; } } }, generateAnchor: function(el) { if (el.id) { return el.id; } else { var anchor = this.generateUniqueId(el); el.id = anchor; return anchor; } }, createNavList: function() { return $(''); }, createChildNavList: function($parent) { var $childList = this.createNavList(); $parent.append($childList); return $childList; }, generateNavEl: function(anchor, text) { var $a = $(''); $a.attr('href', '#' + anchor); $a.text(text); var $li = $('
  • '); $li.append($a); return $li; }, generateNavItem: function(headingEl) { var anchor = this.generateAnchor(headingEl); var $heading = $(headingEl); var text = $heading.data('toc-text') || $heading.text(); return this.generateNavEl(anchor, text); }, // Find the first heading level (`

    `, then `

    `, etc.) that has more than one element. Defaults to 1 (for `

    `). getTopLevel: function($scope) { for (var i = 1; i <= 6; i++) { var $headings = this.findOrFilter($scope, 'h' + i); if ($headings.length > 1) { return i; } } return 1; }, // returns the elements for the top level, and the next below it getHeadings: function($scope, topLevel) { var topSelector = 'h' + topLevel; var secondaryLevel = topLevel + 1; var secondarySelector = 'h' + secondaryLevel; return this.findOrFilter($scope, topSelector + ',' + secondarySelector); }, getNavLevel: function(el) { return parseInt(el.tagName.charAt(1), 10); }, populateNav: function($topContext, topLevel, $headings) { var $context = $topContext; var $prevNav; var helpers = this; $headings.each(function(i, el) { var $newNav = helpers.generateNavItem(el); var navLevel = helpers.getNavLevel(el); // determine the proper $context if (navLevel === topLevel) { // use top level $context = $topContext; } else if ($prevNav && $context === $topContext) { // create a new level of the tree and switch to it $context = helpers.createChildNavList($prevNav); } // else use the current $context $context.append($newNav); $prevNav = $newNav; }); }, parseOps: function(arg) { var opts; if (arg.jquery) { opts = { $nav: arg }; } else { opts = arg; } opts.$scope = opts.$scope || $(document.body); return opts; } }, // accepts a jQuery object, or an options object init: function(opts) { opts = this.helpers.parseOps(opts); // ensure that the data attribute is in place for styling opts.$nav.attr('data-toggle', 'toc'); var $topContext = this.helpers.createChildNavList(opts.$nav); var topLevel = this.helpers.getTopLevel(opts.$scope); var $headings = this.helpers.getHeadings(opts.$scope, topLevel); this.helpers.populateNav($topContext, topLevel, $headings); } }; $(function() { $('nav[data-toggle="toc"]').each(function(i, el) { var $nav = $(el); Toc.init($nav); }); }); })(); pkgdown/inst/BS3/templates/0000755000176200001440000000000014633374223015274 5ustar liggesuserspkgdown/inst/BS3/templates/content-news.html0000644000176200001440000000071414134110164020574 0ustar liggesusers
    {{#contents}} {{{html}}} {{/contents}}
    pkgdown/inst/BS3/templates/config-docsearch.json0000644000176200001440000000366214134110164021360 0ustar liggesusers{ "index_name": "{{index}}", "start_urls": [ { "url": "{{url}}/index.html", "selectors_key": "homepage", "tags": [ "homepage" ] }, { "url": "{{url}}/reference", "selectors_key": "reference", "tags": [ "reference" ] }, { "url": "{{url}}/articles", "selectors_key": "articles", "tags": [ "articles" ] } ], "stop_urls": [ "/reference/$", "/reference/index.html", "/articles/$", "/articles/index.html" ], "sitemap_urls": [ "{{url}}/sitemap.xml" ], "selectors": { "homepage": { "lvl0": { "selector": ".contents h1", "default_value": "{{package}} Home page" }, "lvl1": { "selector": ".contents h2" }, "lvl2": { "selector": ".contents h3", "default_value": "Context" }, "lvl3": ".ref-arguments td, .ref-description", "text": ".contents p, .contents li, .contents .pre" }, "reference": { "lvl0": { "selector": ".contents h1" }, "lvl1": { "selector": ".contents .name", "default_value": "Argument" }, "lvl2": { "selector": ".ref-arguments th", "default_value": "Description" }, "lvl3": ".ref-arguments td, .ref-description", "text": ".contents p, .contents li" }, "articles": { "lvl0": { "selector": ".contents h1" }, "lvl1": { "selector": ".contents .name" }, "lvl2": { "selector": ".contents h2, .contents h3", "default_value": "Context" }, "text": ".contents p, .contents li" } }, "selectors_exclude": [ ".dont-index" ], "min_indexed_level": 2, "custom_settings": { "separatorsToIndex": "_", "attributesToRetrieve": [ "hierarchy", "content", "anchor", "url", "url_without_anchor" ] } } pkgdown/inst/BS3/templates/content-article-index.html0000644000176200001440000000067214633374223022367 0ustar liggesusers
    {{#sections}}

    {{{title}}}

    {{{desc}}}

    {{#contents}}
    {{title}}
    {{{description}}} {{/contents}}
    {{/sections}}
    pkgdown/inst/BS3/templates/content-home.html0000644000176200001440000000031214134110164020542 0ustar liggesusers
    {{{index}}}
    pkgdown/inst/BS3/templates/docsearch.html0000644000176200001440000000115214134110164020100 0ustar liggesusers{{#yaml}}{{#docsearch}} {{/docsearch}}{{/yaml}} pkgdown/inst/BS3/templates/content-article.html0000644000176200001440000000263514134110164021247 0ustar liggesusers{{^as_is}}$for(header-includes)$ $header-includes$ $endfor${{/as_is}}
    $for(include-before)$ $include-before$ $endfor$ $if(abstract)$

    Abstract

    $abstract$
    $endif$ $body$
    $for(include-after)$ $include-after$ $endfor$ pkgdown/inst/BS3/templates/content-title-body.html0000644000176200001440000000051614134110164021674 0ustar liggesusers
    {{{body}}}
    pkgdown/inst/BS3/templates/content-tutorial-index.html0000644000176200001440000000036414134110164022571 0ustar liggesusers
    pkgdown/inst/BS3/templates/content-reference-topic.html0000644000176200001440000000165314633374223022711 0ustar liggesusers
    {{#description}} {{#contents}} {{{.}}} {{/contents}} {{/description}}
    {{#usage}}
    {{#contents}} {{{.}}} {{/contents}}
    {{/usage}} {{#sections}}

    {{{title}}}

    {{#contents}} {{{.}}} {{/contents}}
    {{/sections}} {{#examples}}

    Examples

    {{{.}}}
    {{/examples}}
    pkgdown/inst/BS3/templates/after-body.html0000644000176200001440000000005314136064064020211 0ustar liggesusers{{#includes}}{{{after_body}}}{{/includes}} pkgdown/inst/BS3/templates/before-body.html0000644000176200001440000000005414136064064020353 0ustar liggesusers{{#includes}}{{{before_body}}}{{/includes}} pkgdown/inst/BS3/templates/content-news-index.html0000644000176200001440000000040214134110164021673 0ustar liggesusers
    pkgdown/inst/BS3/templates/content-tutorial.html0000644000176200001440000000040614134110164021461 0ustar liggesusers
    pkgdown/inst/BS3/templates/header.html0000644000176200001440000000000014134110164017364 0ustar liggesuserspkgdown/inst/BS3/templates/content-citation-authors.html0000644000176200001440000000143414633374223023131 0ustar liggesusers
    {{{before}}}
      {{#authors}}
    • {{{name}}}. {{{roles}}}. {{{orcid}}} {{#comment}}
      {{{.}}}{{/comment}}

    • {{/authors}}
    {{{after}}}

    {{#translate}}{{citation}}{{/translate}}

    {{#source}}{{{.}}}{{/source}}
    {{#citations}} {{{html}}}
    {{bibtex}}
    {{/citations}}
    pkgdown/inst/BS3/templates/layout.html0000644000176200001440000000074214137761366017511 0ustar liggesusers {{{ head }}} {{{ in-header }}} {{{ before-body }}}
    {{{ navbar }}} {{{ header }}}
    {{{ content }}}
    {{{ footer }}}
    {{{ docsearch }}} {{{ after-body }}} pkgdown/inst/BS3/templates/in-header.html0000644000176200001440000000005214136064064020010 0ustar liggesusers{{#includes}}{{{in_header}}}{{/includes}} pkgdown/inst/BS3/templates/content-reference-index.html0000644000176200001440000000276114633374223022703 0ustar liggesusers
    {{#has_icons}}{{/has_icons}} {{#rows}} {{#title}}{{/title}} {{#subtitle}}{{/subtitle}} {{#topics}} {{#has_icons}}{{/has_icons}} {{/topics}} {{/rows}}

    {{{title}}}

    {{{desc}}}

    {{{subtitle}}}

    {{{desc}}}

    {{#icon}}{{/icon}}

    {{#aliases}}{{{.}}} {{/aliases}}

    {{{title}}}

    pkgdown/inst/BS3/templates/footer.html0000644000176200001440000000023514134110164017444 0ustar liggesusers{{#footer}}

    {{#right}}{{{.}}}{{/right}}

    {{/footer}} pkgdown/inst/BS3/templates/navbar.html0000644000176200001440000000306114134110164017417 0ustar liggesusers{{#navbar}} {{/navbar}} pkgdown/inst/BS3/templates/layout-redirect.html0000644000176200001440000000026514633374223021301 0ustar liggesusers pkgdown/inst/BS3/templates/head.html0000644000176200001440000001425114633374223017066 0ustar liggesusers {{{pagetitle}}} • {{#site}}{{title}}{{/site}} {{#has_favicons}} {{/has_favicons}} {{#yaml}} {{#bootswatch}}{{/bootswatch}} {{^bootswatch}}{{/bootswatch}} {{/yaml}} {{#yaml}}{{#docsearch}} {{/docsearch}}{{/yaml}} {{#extra}} {{#css}}{{/css}} {{#js}}{{/js}} {{/extra}} {{#opengraph}} {{#description}} {{/description}} {{#image}} {{#alt}} {{/alt}} {{/image}} {{#twitter}} {{#card}} {{/card}} {{^card}} {{/card}} {{#creator}} {{/creator}} {{#site}} {{/site}} {{/twitter}} {{/opengraph}} {{#yaml}}{{#noindex}}{{/noindex}}{{/yaml}} {{#development}}{{#in_dev}}{{/in_dev}}{{/development}} {{#yaml}}{{#google_site_verification}} {{/google_site_verification}}{{/yaml}} {{#yaml}}{{#ganalytics}} {{/ganalytics}}{{/yaml}} {{#has_trailingslash}} {{/has_trailingslash}} {{#has_deps}} {{{dependencies}}} {{/has_deps}} pkgdown/inst/BS5/0000755000176200001440000000000014672347600013302 5ustar liggesuserspkgdown/inst/BS5/assets/0000755000176200001440000000000014671042466014605 5ustar liggesuserspkgdown/inst/BS5/assets/pkgdown.js0000644000176200001440000001115414671042466016616 0ustar liggesusers/* http://gregfranko.com/blog/jquery-best-practices/ */ (function($) { $(function() { $('nav.navbar').headroom(); Toc.init({ $nav: $("#toc"), $scope: $("main h2, main h3, main h4, main h5, main h6") }); if ($('#toc').length) { $('body').scrollspy({ target: '#toc', offset: $("nav.navbar").outerHeight() + 1 }); } // Activate popovers $('[data-bs-toggle="popover"]').popover({ container: 'body', html: true, trigger: 'focus', placement: "top", sanitize: false, }); $('[data-bs-toggle="tooltip"]').tooltip(); /* Clipboard --------------------------*/ function changeTooltipMessage(element, msg) { var tooltipOriginalTitle=element.getAttribute('data-bs-original-title'); element.setAttribute('data-bs-original-title', msg); $(element).tooltip('show'); element.setAttribute('data-bs-original-title', tooltipOriginalTitle); } if(ClipboardJS.isSupported()) { $(document).ready(function() { var copyButton = ""; $("div.sourceCode").addClass("hasCopyButton"); // Insert copy buttons: $(copyButton).prependTo(".hasCopyButton"); // Initialize tooltips: $('.btn-copy-ex').tooltip({container: 'body'}); // Initialize clipboard: var clipboard = new ClipboardJS('[data-clipboard-copy]', { text: function(trigger) { return trigger.parentNode.textContent.replace(/\n#>[^\n]*/g, ""); } }); clipboard.on('success', function(e) { changeTooltipMessage(e.trigger, 'Copied!'); e.clearSelection(); }); clipboard.on('error', function(e) { changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); }); }); } /* Search marking --------------------------*/ var url = new URL(window.location.href); var toMark = url.searchParams.get("q"); var mark = new Mark("main#main"); if (toMark) { mark.mark(toMark, { accuracy: { value: "complementary", limiters: [",", ".", ":", "/"], } }); } /* Search --------------------------*/ /* Adapted from https://github.com/rstudio/bookdown/blob/2d692ba4b61f1e466c92e78fd712b0ab08c11d31/inst/resources/bs4_book/bs4_book.js#L25 */ // Initialise search index on focus var fuse; $("#search-input").focus(async function(e) { if (fuse) { return; } $(e.target).addClass("loading"); var response = await fetch($("#search-input").data("search-index")); var data = await response.json(); var options = { keys: ["what", "text", "code"], ignoreLocation: true, threshold: 0.1, includeMatches: true, includeScore: true, }; fuse = new Fuse(data, options); $(e.target).removeClass("loading"); }); // Use algolia autocomplete var options = { autoselect: true, debug: true, hint: false, minLength: 2, }; var q; async function searchFuse(query, callback) { await fuse; var items; if (!fuse) { items = []; } else { q = query; var results = fuse.search(query, { limit: 20 }); items = results .filter((x) => x.score <= 0.75) .map((x) => x.item); if (items.length === 0) { items = [{dir:"Sorry 😿",previous_headings:"",title:"No results found.",what:"No results found.",path:window.location.href}]; } } callback(items); } $("#search-input").autocomplete(options, [ { name: "content", source: searchFuse, templates: { suggestion: (s) => { if (s.title == s.what) { return `${s.dir} >
    ${s.title}
    `; } else if (s.previous_headings == "") { return `${s.dir} >
    ${s.title}
    > ${s.what}`; } else { return `${s.dir} >
    ${s.title}
    > ${s.previous_headings} > ${s.what}`; } }, }, }, ]).on('autocomplete:selected', function(event, s) { window.location.href = s.path + "?q=" + q + "#" + s.id; }); }); })(window.jQuery || window.$) document.addEventListener('keydown', function(event) { // Check if the pressed key is '/' if (event.key === '/') { event.preventDefault(); // Prevent any default action associated with the '/' key document.getElementById('search-input').focus(); // Set focus to the search input } }); pkgdown/inst/BS5/assets/link.svg0000644000176200001440000000145214134110164016246 0ustar liggesusers pkgdown/inst/BS5/assets/lightswitch.js0000644000176200001440000000471114633374223017474 0ustar liggesusers /*! * Color mode toggler for Bootstrap's docs (https://getbootstrap.com/) * Copyright 2011-2023 The Bootstrap Authors * Licensed under the Creative Commons Attribution 3.0 Unported License. * Updates for {pkgdown} by the {bslib} authors, also licensed under CC-BY-3.0. */ const getStoredTheme = () => localStorage.getItem('theme') const setStoredTheme = theme => localStorage.setItem('theme', theme) const getPreferredTheme = () => { const storedTheme = getStoredTheme() if (storedTheme) { return storedTheme } return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light' } const setTheme = theme => { if (theme === 'auto') { document.documentElement.setAttribute('data-bs-theme', (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')) } else { document.documentElement.setAttribute('data-bs-theme', theme) } } function bsSetupThemeToggle () { 'use strict' const showActiveTheme = (theme, focus = false) => { var activeLabel, activeIcon; document.querySelectorAll('[data-bs-theme-value]').forEach(element => { const buttonTheme = element.getAttribute('data-bs-theme-value') const isActive = buttonTheme == theme element.classList.toggle('active', isActive) element.setAttribute('aria-pressed', isActive) if (isActive) { activeLabel = element.textContent; activeIcon = element.querySelector('span').classList.value; } }) const themeSwitcher = document.querySelector('#dropdown-lightswitch') if (!themeSwitcher) { return } themeSwitcher.setAttribute('aria-label', activeLabel) themeSwitcher.querySelector('span').classList.value = activeIcon; if (focus) { themeSwitcher.focus() } } window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { const storedTheme = getStoredTheme() if (storedTheme !== 'light' && storedTheme !== 'dark') { setTheme(getPreferredTheme()) } }) window.addEventListener('DOMContentLoaded', () => { showActiveTheme(getPreferredTheme()) document .querySelectorAll('[data-bs-theme-value]') .forEach(toggle => { toggle.addEventListener('click', () => { const theme = toggle.getAttribute('data-bs-theme-value') setTheme(theme) setStoredTheme(theme) showActiveTheme(theme, true) }) }) }) } setTheme(getPreferredTheme()); bsSetupThemeToggle(); pkgdown/inst/BS5/assets/katex-auto.js0000644000176200001440000000115114633374223017220 0ustar liggesusers// https://github.com/jgm/pandoc/blob/29fa97ab96b8e2d62d48326e1b949a71dc41f47a/src/Text/Pandoc/Writers/HTML.hs#L332-L345 document.addEventListener("DOMContentLoaded", function () { var mathElements = document.getElementsByClassName("math"); var macros = []; for (var i = 0; i < mathElements.length; i++) { var texText = mathElements[i].firstChild; if (mathElements[i].tagName == "SPAN") { katex.render(texText.data, mathElements[i], { displayMode: mathElements[i].classList.contains("display"), throwOnError: false, macros: macros, fleqn: false }); }}}); pkgdown/inst/BS5/assets/pkgdown.scss0000644000176200001440000004137414634573316017166 0ustar liggesusers/* control page width ====================================================== */ .row > main { // Ensure contents never become unreadably wide max-width: 50rem; // And that we can break and hypenate very long words overflow-wrap: break-word; hyphens: auto; } // Put extra space between content and navbar @include media-breakpoint-only(xl) { .container .row { justify-content: space-evenly; } } // Boost font size and give big (but not infinite) margin on sidebar @include media-breakpoint-up(xxl) { body { font-size: 18px } .col-md-3 { margin-left: 5rem; } } /* navbar =================================================================== */ $pkgdown-navbar-bg: null !default; $pkgdown-navbar-bg-dark: null !default; // BS navbars appears to be designed with the idea that you have a coloured // navbar that looks the same in both light and dark mode. We prefer a mildly // coloured navbar that's just different enough from the body to stand out. // // Relies on CSS fallback rules .navbar { background: RGBA(var(--bs-body-color-rgb), 0.1); background: color-mix(in oklab, color-mix(in oklab, var(--bs-body-bg) 95%, var(--bs-primary)) 95%, var(--bs-body-color)); background: $pkgdown-navbar-bg; // Harmonize alignment of navbar elements (search field vs. rest) line-height: initial; } [data-bs-theme="dark"] .navbar { background: $pkgdown-navbar-bg-dark; } // make both the active nav and the hovered nav more clear by mixing the // background colour with the body and primary colours respectively .nav-item .nav-link { @include border-radius($border-radius); } .nav-item.active .nav-link { background: RGBA(var(--bs-body-color-rgb), 0.1); } .nav-item .nav-link:hover { background: RGBA(var(--bs-primary-rgb), 0.1); } // Align baselines of package name, version, and nav items .navbar > .container { align-items: baseline; -webkit-align-items: baseline; } // Make search a little narrower than the default input[type="search"] { width: 12rem; } [aria-labelledby=dropdown-lightswitch] span.fa { opacity: 0.5; } // When navbar is a dropdown: @include media-breakpoint-down(lg) { // Make search and sub-menus span full width .algolia-autocomplete, input[type="search"], #navbar .dropdown-menu { width: 100%; } // Allow text to wrap #navbar .dropdown-item { white-space: normal; } // Add a little margin input[type="search"] { margin: 0.25rem 0; } } /* headroom.js -------------------------------------------------------------- */ .headroom { will-change: transform; transition: transform 400ms ease; } .headroom--pinned { transform: translateY(0%); } .headroom--unpinned { transform: translateY(-100%); } // Need to adjust body components down by height of navbar so it // doesn't overlap them when visible $pkgdown-nav-height: 56px !default; .row > main, .row > aside { margin-top: $pkgdown-nav-height; } html, body { scroll-padding: $pkgdown-nav-height } // Make scrollable, sticky TOC @include media-breakpoint-up(sm) { #toc { position: sticky; top: $pkgdown-nav-height; max-height: calc(100vh - #{$pkgdown-nav-height} - 1rem); overflow-y: auto; } } /* sidebar ================================================================== */ aside { h2 { margin-top: 1.5rem; font-size: $font-size-lg; } .roles { color: RGBA(var(--bs-body-color-rgb), 0.8); } .list-unstyled li { margin-bottom: 0.5rem; } .dev-status .list-unstyled li { margin-bottom: 0.1rem; } } // Add some visual distinction between content and "sidebar" on mobile @include media-breakpoint-down(md) { // Additional specificity needed to override bootstrap width on .row > * .row > aside { margin: 0.5rem; width: calc(100vw - 1rem); background-color: RGBA(var(--bs-body-color-rgb), 0.1); border-color: var(--bs-border-color); @include border-radius($border-radius); h2:first-child { margin-top: 1rem; } } } /* table of contents -------------------------------------------------------- */ // needed for scrollspy body {position: relative;} #toc > .nav { margin-bottom: 1rem; a.nav-link { color: inherit; padding: 0.25rem 0.5rem; margin-bottom: 2px; @include border-radius($border-radius); &:hover, &:focus { background-color: RGBA(var(--bs-primary-rgb), 0.1); } &.active { background-color: RGBA(var(--bs-body-color-rgb), 0.1); } } // Nested headings are indented .nav a.nav-link { margin-left: 0.5rem; } // Only show second level if active. // Requires !important because that's how BS5 sets display: flex .nav { display: none !important; } a.active + .nav { display: flex !important; } } /* footer ================================================================== */ $pkgdown-footer-color: RGBA(var(--bs-body-color-rgb), 0.8) !default; $pkgdown-footer-bg: transparent !default; $pkgdown-footer-border-color: $border-color !default; $pkgdown-footer-border-width: $border-width !default; footer { margin: 1rem 0 1rem 0; padding-top: 1rem; font-size: .875em; border-top: $pkgdown-footer-border-width solid $pkgdown-footer-border-color; background: $pkgdown-footer-bg; color: $pkgdown-footer-color; display: flex; column-gap: 1rem; } @include media-breakpoint-down(sm) { footer {flex-direction: column;} } @include media-breakpoint-up(sm) { footer .pkgdown-footer-right { text-align: right;} } footer div { flex: 1 1 auto; } // "Sticky" footer - i.e. the footer always hugs the bottom of the viewport // even for short pages. // // Basic idea: https://philipwalton.github.io/solved-by-flexbox/demos/sticky-footer/ // Details: https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/site.css // Need .container and __all parents__ have height set to 100% html, body { height: 100%; } body > .container { min-height: 100%; display: flex; flex-direction: column; } body > .container .row { flex: 1 0 auto; } /* General typography ======================================================= */ // Ensure in-page images don't run outside their container main img { max-width: 100%; height: auto; } main table { display: block; overflow: auto; } // avoid flash of invisible text + flash of unstyled text body { font-display: fallback; } // page header .page-header { border-bottom: 1px solid var(--bs-border-color); padding-bottom: 0.5rem; margin-bottom: 0.5rem; margin-top: 1.5rem; } // spacing tweaks // Use an indent for defintions rather than horitzonal space dl {margin-bottom: 0;} dd {padding-left: 1.5rem; margin-bottom: 0.25rem} // Use margins rather than size to distinguish headings h2, .h2 { font-size: 1.75rem; margin-top: 1.5rem;} h3, .h3 { font-size: 1.25rem; margin-top: 1rem; font-weight: bold;} h4, .h4 { font-size: 1.1rem; font-weight: bold;} h5, .h5 { font-size: 1rem; font-weight: bold;} summary { margin-bottom: 0.5rem; } details { margin-bottom: 1rem; } .html-widget { margin-bottom: 1rem; } // Section anchors a.anchor { display: none; // style like a footnote margin-left: 2px; vertical-align: top; width: Min(0.9em, 20px); height: Min(0.9em, 20px); background-image: url(../../link.svg); background-repeat: no-repeat; background-size: Min(0.9em, 20px) Min(0.9em, 20px); background-position: center center; } h2, h3, h4, h5, h6, dt { &:hover .anchor, &:target .anchor {display: inline-block;} } // Give targetted arguments some visual distinction dt:target, dt:target + dd { border-left: 0.25rem solid var(--bs-primary); margin-left: -0.75rem; } dt:target { padding-left: 0.5rem; } dt:target + dd { padding-left: 2rem; } // orcid badge .orcid { color: #A6CE39; margin-right: 4px; } // activate font awesome .fab { font-family: "Font Awesome 5 Brands" !important; } // package logo img.logo { float: right; width: 100px; margin-left: 30px; } .template-home img.logo { width: 120px; } @include media-breakpoint-down(sm) { img.logo {width: 80px;} } // line up h1 border-bottom with corner of hexagon // values determined empirically @include media-breakpoint-up(sm) { .page-header {min-height: 88px} .template-home .page-header {min-height: 104px} } // line-block produced by pandoc needs margin-bottom since it doesn't // contain other tags .line-block { margin-bottom: 1rem; } // Override bootstrap defaults that make sense in page bodies, but not on // the reference index .template-reference-index { dt {font-weight: normal;} // Don't allow breaking within a function name code {word-wrap: normal;} } .icon { float: right; img {width: 40px;} } // Ensure skip link is visible if focussed a[href='#main'] { position: absolute; margin: 4px; padding: 0.75rem; background-color: var(--bs-body-bg); text-decoration: none; z-index: 2000; } .lifecycle { color: var(--bs-secondary-color); background-color: var(--bs-secondary-bg); // backup just in case we don't know the name border-radius: 5px; } .lifecycle-stable { background-color: rgb(16, 128, 1); color: var(--bs-white);} .lifecycle-superseded { background-color: rgb(7, 64, 128); color: var(--bs-white);} .lifecycle-experimental, .lifecycle-deprecated { background-color: rgb(253, 128, 8); color: var(--bs-black);} /* Footnotes ---------------------------------------------------------------- */ a.footnote-ref { cursor: pointer; } // use "Min" to trigger computation in css, not sass .popover { width: Min(100vw, 32rem); font-size: 0.9rem; box-shadow: 4px 4px 8px RGBA(var(--bs-body-color-rgb), 0.3); } .popover-body { padding: 0.75rem; } .popover-body p:last-child { margin-bottom: 0; } /* tabsets ------------------------------------------------------------------ */ .tab-content { padding: 1rem; } .tabset-pills .tab-content { border: solid 1px #e5e5e5; } // Make tab height consistent // https://observablehq.com/@rkaravia/css-trick-tabs-with-consistent-height .tab-content { display: flex; } .tab-content > .tab-pane { display: block; /* undo "display: none;" */ visibility: hidden; margin-right: -100%; width: 100%; } .tab-content > .active { visibility: visible; } /* bibliography styling ----------------------------------------------------- */ // Added in pandoc 2.11: https://github.com/jgm/pandoc-templates/commit/9904bf71 div.csl-bib-body { } div.csl-entry { clear: both; } .hanging-indent div.csl-entry { margin-left:2em; text-indent:-2em; } div.csl-left-margin { min-width:2em; float:left; } div.csl-right-inline { margin-left:2em; padding-left:1em; } div.csl-indent { margin-left: 2em; } /* code ===================================================================== */ pre, pre code { // override bootstrap deafult that causes problems in old safari + IE // https://github.com/rstudio/shiny/issues/2233 word-wrap: normal; } // Default dark mode styling does not look good for code [data-bs-theme="dark"] { pre, code { background-color: RGBA(var(--bs-body-color-rgb), 0.1); } // don't double apply transparency pre code { background: transparent; } } code { // break long functions into multiple lines overflow-wrap: break-word; } // copy button .hasCopyButton { position: relative; } .btn-copy-ex { position: absolute; right: 5px; top: 5px; visibility: hidden; } .hasCopyButton:hover button.btn-copy-ex { visibility: visible; } // Ensure there's enough space for the copy button pre { padding: 0.75rem; } // Spacing tweaks for gt table pre div.gt-table { white-space: normal; margin-top: 1rem; } // "Pop" code out of page margins on small screens to give a little more room @include media-breakpoint-down(sm) { // div.section div.sourceCode pre // prevents matching
     inside (e.g.) a 
  • div > div > pre { margin-left: calc(var(--bs-gutter-x) * -.5); margin-right: calc(var(--bs-gutter-x) * -.5); border-radius: 0; padding-left: 1rem; padding-right: 1rem; } .btn-copy-ex { right: calc(var(--bs-gutter-x) * -.5 + 5px); } } code a:any-link { color: inherit; text-decoration-color: RGBA(var(--bs-body-color-rgb), 0.6); } pre code { padding: 0; background: transparent; .error, .warning {font-weight: bolder;} } pre .img, pre .r-plt { img { margin: 5px 0; background-color: #fff; } } // low-tech plot softening in dark mode [data-bs-theme="dark"] pre img { opacity: 0.66; transition: opacity 250ms ease-in-out; &:hover, &:focus, &:active {opacity: 1;} } /* don't display links in code chunks when printing */ /* source: https://stackoverflow.com/a/10781533 */ @media print { code a:link:after, code a:visited:after { content: ""; } } a.sourceLine:hover { text-decoration: none; } /* search =================================================================== */ mark { background: linear-gradient(-100deg, RGBA(var(--bs-info-rgb), 0.2), RGBA(var(--bs-info-rgb), 0.7) 95%, RGBA(var(--bs-info-rgb), 0.1) ) } // Mimic the style of the navbar dropdowns .algolia-autocomplete .aa-dropdown-menu { margin-top: 0.5rem; padding: 0.5rem 0.25rem; width: MAX(100%, 20rem); // force computation in css, not sass max-height: 50vh; overflow-y: auto; background-color: var(--bs-body-bg); border: var(--bs-border-width) solid var(--bs-border-color); @include border-radius($border-radius); .aa-suggestion { cursor: pointer; font-size: 1rem; padding: 0.5rem 0.25rem; line-height: 1.3; &:hover { background-color: var(--bs-tertiary-bg); color: var(--bs-body-color); } .search-details { text-decoration: underline; display: inline; // algolia makes it a div } } } /* Quarto specific =========================================================== */ // Selectively copied from https://github.com/quarto-dev/quarto-cli/blob/main/src/resources/formats/html/_quarto-rules.scss#L110 span.smallcaps {font-variant: small-caps;} // task-list -------------------------------------------------------------- ul.task-list{list-style: none;} ul.task-list li input[type="checkbox"] { width: 0.8em; margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */ vertical-align: middle; } // Figure and layout -------------------------------------------------------- figure.figure { display: block; } .quarto-layout-panel { margin-bottom: 1em; } .quarto-layout-panel > figure { width: 100%; } .quarto-layout-panel > figure > figcaption, .quarto-layout-panel > .panel-caption { margin-top: 10pt; } .quarto-layout-panel > .table-caption { margin-top: 0px; } .table-caption p { margin-bottom: 0.5em; } .quarto-layout-row { display: flex; flex-direction: row; align-items: flex-start; } .quarto-layout-valign-top { align-items: flex-start; } .quarto-layout-valign-bottom { align-items: flex-end; } .quarto-layout-valign-center { align-items: center; } .quarto-layout-cell { position: relative; margin-right: 20px; } .quarto-layout-cell:last-child { margin-right: 0; } .quarto-layout-cell figure, .quarto-layout-cell > p { margin: 0.2em; } .quarto-layout-cell img { max-width: 100%; } .quarto-layout-cell .html-widget { width: 100% !important; } .quarto-layout-cell div figure p { margin: 0; } .quarto-layout-cell figure { display: block; margin-inline-start: 0; margin-inline-end: 0; } .quarto-layout-cell table { display: inline-table; } .quarto-layout-cell-subref figcaption, figure .quarto-layout-row figure figcaption { text-align: center; font-style: italic; } .quarto-figure { position: relative; margin-bottom: 1em; } .quarto-figure > figure { width: 100%; margin-bottom: 0; } .quarto-figure-left > figure > p, .quarto-figure-left > figure > div /* for mermaid and dot diagrams */ { text-align: left; } .quarto-figure-center > figure > p, .quarto-figure-center > figure > div /* for mermaid and dot diagrams */ { text-align: center; } .quarto-figure-right > figure > p, .quarto-figure-right > figure > div /* for mermaid and dot diagrams */ { text-align: right; } .quarto-figure > figure > div.cell-annotation, .quarto-figure > figure > div code { text-align: left; /* override align center for code blocks */ } figure > p:empty { display: none; } figure > p:first-child { margin-top: 0; margin-bottom: 0; } figure > figcaption.quarto-float-caption-bottom { margin-bottom: 0.5em; } figure > figcaption.quarto-float-caption-top { margin-top: 0.5em; } // mermaid --------------------------------------------------------- :root { --mermaid-bg-color: transparent; --mermaid-edge-color: var(--bs-secondary); --mermaid-fg-color: var(--bs-body-color); --mermaid-fg-color--lighter: RGBA(var(--bs-body-color-rgb), 0.9); --mermaid-fg-color--lightest: RGBA(var(--bs-body-color-rgb), 0.8); --mermaid-font-family: var(--bs-body-font-family); --mermaid-label-bg-color: var(--bs-primary); --mermaid-label-fg-color: var(--bs-body-color); --mermaid-node-bg-color: RGBA(var(--bs-primary-rgb), 0.1); --mermaid-node-fg-color: var(--bs-primary); } pkgdown/inst/BS5/templates/0000755000176200001440000000000014634573316015303 5ustar liggesuserspkgdown/inst/BS5/templates/content-news.html0000644000176200001440000000075714633374223020621 0ustar liggesusers
    {{#contents}} {{{html}}} {{/contents}}
    pkgdown/inst/BS5/templates/config-docsearch.json0000644000176200001440000000354214633374223021373 0ustar liggesusers{ "index_name": "{{index}}", "start_urls": [ { "url": "{{url}}/index.html", "selectors_key": "homepage", "tags": [ "homepage" ] }, { "url": "{{url}}/reference", "selectors_key": "reference", "tags": [ "reference" ] }, { "url": "{{url}}/articles", "selectors_key": "articles", "tags": [ "articles" ] } ], "stop_urls": [ "/reference/$", "/reference/index.html", "/articles/$", "/articles/index.html" ], "sitemap_urls": [ "{{url}}/sitemap.xml" ], "selectors": { "homepage": { "lvl0": { "selector": "main h1", "default_value": "{{package}} Home page" }, "lvl1": { "selector": "main h2" }, "lvl2": { "selector": "main h3", "default_value": "Context" }, "lvl3": ".ref-arguments td, .ref-description", "text": "main p, main li, main .pre" }, "reference": { "lvl0": { "selector": "main h1" }, "lvl1": { "selector": "main .name", "default_value": "Argument" }, "lvl2": { "selector": ".ref-arguments th", "default_value": "Description" }, "lvl3": ".ref-arguments td, .ref-description", "text": "main p, main li" }, "articles": { "lvl0": { "selector": "main h1" }, "lvl1": { "selector": "main .name" }, "lvl2": { "selector": "main h2, main h3", "default_value": "Context" }, "text": "main p, main li" } }, "selectors_exclude": [ ".dont-index" ], "min_indexed_level": 2, "custom_settings": { "separatorsToIndex": "_", "attributesToRetrieve": [ "hierarchy", "content", "anchor", "url", "url_without_anchor" ] } } pkgdown/inst/BS5/templates/content-article-index.html0000644000176200001440000000130014633374223022356 0ustar liggesusers
    {{#sections}}

    {{{title}}}

    {{{desc}}}
    {{#contents}}
    {{title}}
    {{{description}}} {{/contents}}
    {{/sections}}
    pkgdown/inst/BS5/templates/content-home.html0000644000176200001440000000023414633374223020563 0ustar liggesusers
    {{{index}}}
    pkgdown/inst/BS5/templates/content-article.html0000644000176200001440000000271614634573316021272 0ustar liggesusers{{^as_is}}$for(header-includes)$ $header-includes$ $endfor${{/as_is}}
    $for(include-before)$ $include-before$ $endfor$ $if(abstract)$

    {{#translate}}{{abstract}}{{/translate}}

    $abstract$
    $endif$ $body$
    {{#toc}} {{/toc}}
    $for(include-after)$ $include-after$ $endfor$ pkgdown/inst/BS5/templates/content-title-body.html0000644000176200001440000000073114633374223021711 0ustar liggesusers
    {{{body}}}
    pkgdown/inst/BS5/templates/content-tutorial-index.html0000644000176200001440000000076514633374223022614 0ustar liggesusers
    pkgdown/inst/BS5/templates/content-reference-topic.html0000644000176200001440000000221614633374223022707 0ustar liggesusers
    {{#description}} {{#contents}} {{{.}}} {{/contents}} {{/description}}
    {{#usage}}

    {{{title}}}

    {{#contents}} {{{.}}} {{/contents}}
    {{/usage}} {{#sections}}

    {{{title}}}

    {{#contents}} {{{.}}} {{/contents}}
    {{/sections}} {{#examples}}

    {{#translate}}{{examples}}{{/translate}}

    {{{.}}}
    {{/examples}}
    pkgdown/inst/BS5/templates/after-body.html0000644000176200001440000000005314136064064020213 0ustar liggesusers{{#includes}}{{{after_body}}}{{/includes}} pkgdown/inst/BS5/templates/before-body.html0000644000176200001440000000005414136064064020355 0ustar liggesusers{{#includes}}{{{before_body}}}{{/includes}} pkgdown/inst/BS5/templates/content-authors.html0000644000176200001440000000127514633374223021326 0ustar liggesusers
    {{{before}}}
      {{#authors}}
    • {{{name}}}. {{{roles}}}. {{{orcid}}} {{#comment}}
      {{{.}}}{{/comment}}

    • {{/authors}}
    {{{after}}}
    pkgdown/inst/BS5/templates/content-news-index.html0000644000176200001440000000103714633374223021716 0ustar liggesusers
    pkgdown/inst/BS5/templates/content-quarto.html0000644000176200001440000000176314634573316021163 0ustar liggesusers
    {{#abstract}}

    {{#translate}}{{abstract}}{{/translate}}

    {{{.}}}
    {{/abstract}} {{#includes}}{{{before}}}{{/includes}} {{{body}}} {{#includes}}{{{after}}}{{/includes}}
    {{#toc}} {{/toc}}
    pkgdown/inst/BS5/templates/content-tutorial.html0000644000176200001440000000071414633374223021501 0ustar liggesusers
  • pkgdown/inst/BS5/templates/header.html0000644000176200001440000000000014134110164017366 0ustar liggesuserspkgdown/inst/BS5/templates/content-citation-authors.html0000644000176200001440000000227614633374223023140 0ustar liggesusers

    {{#translate}}{{authors}}{{/translate}}

    {{{before}}}
      {{#authors}}
    • {{{name}}}. {{{roles}}}. {{{orcid}}} {{#comment}}
      {{{.}}}{{/comment}}

    • {{/authors}}
    {{{after}}}

    {{#translate}}{{citation}}{{/translate}}

    {{#source}}{{{.}}}{{/source}}

    {{#citations}} {{{html}}}
    {{bibtex}}
    {{/citations}}
    {{#inst}}

    {{#translate}}{{author_details}}{{/translate}}

    {{.}}
    {{/inst}}
    pkgdown/inst/BS5/templates/layout.html0000644000176200001440000000073714633374223017510 0ustar liggesusers {{{ head }}} {{{ in-header }}} {{#translate}}{{skip}}{{/translate}} {{{ before-body }}} {{{ navbar }}}
    {{{ content }}}
    {{{ footer }}}
    {{{ docsearch }}} {{{ after-body }}} pkgdown/inst/BS5/templates/in-header.html0000644000176200001440000000005214136064064020012 0ustar liggesusers{{#includes}}{{{in_header}}}{{/includes}} pkgdown/inst/BS5/templates/content-reference-index.html0000644000176200001440000000202614633374223022677 0ustar liggesusers
    {{#rows}}
    {{#title}}

    {{{.}}}

    {{/title}} {{#subtitle}}

    {{{.}}}

    {{/subtitle}} {{#desc}}
    {{{desc}}}
    {{/desc}} {{#topics}}
    {{#has_icons}}{{#icon}}{{/icon}}{{/has_icons}} {{#aliases}}{{{.}}} {{/aliases}} {{#lifecycle}}{{.}}{{/lifecycle}}
    {{{title}}}
    {{/topics}}
    {{/rows}}
    pkgdown/inst/BS5/templates/footer.html0000644000176200001440000000024614633374223017464 0ustar liggesusers{{#footer}} {{/footer}} pkgdown/inst/BS5/templates/navbar.html0000644000176200001440000000236114633374223017437 0ustar liggesusers{{#navbar}} {{/navbar}} pkgdown/inst/BS5/templates/layout-redirect.html0000644000176200001440000000026514633374223021303 0ustar liggesusers pkgdown/inst/BS5/templates/head.html0000644000176200001440000000622514634573316017077 0ustar liggesusers {{{pagetitle}}} • {{#site}}{{title}}{{/site}} {{#has_favicons}} {{/has_favicons}} {{#lightswitch}}{{/lightswitch}} {{#uses_katex}}{{/uses_katex}} {{{headdeps}}} {{#includes}}{{{head}}}{{/includes}} {{#extra}} {{#css}}{{/css}} {{#js}}{{/js}} {{/extra}} {{#opengraph}} {{#description}} {{/description}} {{#image}} {{#alt}}{{/alt}} {{/image}} {{#twitter}} {{#card}}{{/card}} {{#creator}}{{/creator}} {{#site}}{{/site}} {{/twitter}} {{/opengraph}} {{#yaml}}{{#noindex}}{{/noindex}}{{/yaml}} {{#development}}{{#in_dev}}{{/in_dev}}{{/development}} {{#yaml}}{{#google_site_verification}} {{/google_site_verification}}{{/yaml}} {{#yaml}}{{#ganalytics}} {{/ganalytics}}{{/yaml}} {{#has_trailingslash}} {{/has_trailingslash}} {{#has_deps}} {{{dependencies}}} {{/has_deps}} pkgdown/inst/quarto/0000755000176200001440000000000014634573316014227 5ustar liggesuserspkgdown/inst/quarto/template.html0000644000176200001440000000164414634573316016735 0ustar liggesusers $pagetitle$ $for(css)$ $endfor$ $for(header-includes)$ $header-includes$ $endfor$
    $for(include-before)$ $include-before$ $endfor$
    $if(title)$

    $title$

    $endif$ $if(subtitle)$

    $subtitle$

    $endif$ $for(author)$

    $author$

    $endfor$ $if(date)$

    $date$

    $endif$ $if(abstract)$
    $abstract$
    $endif$
    $body$
    $for(include-after)$ $include-after$ $endfor$
    pkgdown/inst/highlight-styles/0000755000176200001440000000000014633374223016177 5ustar liggesuserspkgdown/inst/highlight-styles/radical.scss0000644000176200001440000000356414633374223020503 0ustar liggesuserspre code /* Normal */ {color:#7c9c9e} pre code span.al /* Alert */ {color:#ff427b; background-color:#2f183b; font-weight: bold} pre code span.an /* Annotation */ {color:#fda8bc} pre code span.at /* Attribute */ {color:#5af5f0} pre code span.bn /* BaseN */ {color:#f834bb} pre code span.bu /* BuiltIn */ {color:#999ee1} pre code span.cf /* ControlFlow */ {color:#d5358f; font-weight: bold} pre code span.ch /* Char */ {color:#dff959} pre code span.cn /* Constant */ {color:#fa61b8; font-weight: bold} pre code span.co /* Comment */ {color:#45898c; font-style: italic} pre code span.cv /* CommentVar */ {color:#a8c0c2} pre code span.do /* Documentation */ {color:#75b7bb} pre code span.dt /* DataType */ {color:#ff85a1} pre code span.dv /* DecVal */ {color:#fa61b8} pre code span.er /* Error */ {color:#ff427b; font-weight: bold; font-style: italic; text-decoration: underline} pre code span.ex /* Extension */ {color:#a8ffdb; font-weight: bold} pre code span.fl /* Float */ {color:#f834bb} pre code span.fu /* Function */ {color:#a9fef7} pre code span.im /* Import */ {color:#a9fef7} pre code span.in /* Information */ {color:#ffd000} pre code span.kw /* Keyword */ {color:#d5358f; font-weight: bold} pre code span.op /* Operator */ {color:#d5358f} pre code span.ot /* Others */ {color:#5effbd} pre code span.pp /* Preprocessor */ {color:#d5358f} pre code span.re /* RegionMarker */ {color:#baf7fc; background-color:#242560} pre code span.sc /* SpecialChar */ {color:#c3f920} pre code span.ss /* SpecialString */ {color:#ff96aa} pre code span.st /* String */ {color:#a9fef7} pre code span.va /* Variable */ {color:#c7e3ee} pre code span.vs /* VerbatimString */ {color:#a8ffdb} pre code span.wa /* Warning */ {color:#ff427b} pkgdown/inst/highlight-styles/arrow-light.scss0000644000176200001440000000322714633374223021337 0ustar liggesuserspre {background-color: #f1f3f5;} pre code /* Normal */ {color:#003B4F} pre code span.al /* Alert */ {color:#AD0000} pre code span.an /* Annotation */ {color:#5E5E5E} pre code span.at /* Attribute */ {color:#657422} pre code span.bn /* BaseN */ {color:#AD0000} pre code span.bu /* BuiltIn */ {} pre code span.cf /* ControlFlow */ {color:#003B4F} pre code span.ch /* Char */ {color:#20794D} pre code span.cn /* Constant */ {color:#8f5902} pre code span.co /* Comment */ {color:#5E5E5E} pre code span.cv /* CommentVar */ {color:#5E5E5E; font-style: italic} pre code span.do /* Documentation */ {color:#5E5E5E; font-style: italic} pre code span.dt /* DataType */ {color:#AD0000} pre code span.dv /* DecVal */ {color:#AD0000} pre code span.er /* Error */ {color:#AD0000} pre code span.ex /* Extension */ {} pre code span.fl /* Float */ {color:#AD0000} pre code span.fu /* Function */ {color:#4758AB} pre code span.im /* Import */ {color:#00769E} pre code span.in /* Information */ {color:#5E5E5E} pre code span.kw /* Keyword */ {color:#003B4F} pre code span.op /* Operator */ {color:#5E5E5E} pre code span.ot /* Other */ {color:#003B4F} pre code span.pp /* Preprocessor */ {color:#AD0000} pre code span.sc /* SpecialChar */ {color:#5E5E5E} pre code span.ss /* SpecialString */ {color:#20794D} pre code span.st /* String */ {color:#20794D} pre code span.va /* Variable */ {color:#111111} pre code span.vs /* VerbatimString */ {color:#20794D} pre code span.wa /* Warning */ {color:#5E5E5E; font-style: italic} pkgdown/inst/highlight-styles/a11y-light.scss0000644000176200001440000000321214633374223020752 0ustar liggesuserspre {background-color: #fefefe;} pre code /* Normal */ {color:#545454} pre code span.al /* Alert */ {color:#7928a1} pre code span.an /* Annotation */ {color:#696969} pre code span.at /* Attribute */ {color:#aa5d00} pre code span.bn /* BaseN */ {color:#7928a1} pre code span.bu /* BuiltIn */ {} pre code span.cf /* ControlFlow */ {color:#d91e18} pre code span.ch /* Char */ {color:#008000} pre code span.cn /* Constant */ {color:#d91e18} pre code span.co /* Comment */ {color:#696969} pre code span.cv /* CommentVar */ {color:#696969; font-style: italic} pre code span.do /* Documentation */ {color:#696969; font-style: italic} pre code span.dt /* DataType */ {color:#7928a1} pre code span.dv /* DecVal */ {color:#7928a1} pre code span.er /* Error */ {color:#7928a1} pre code span.ex /* Extension */ {} pre code span.fl /* Float */ {color:#aa5d00} pre code span.fu /* Function */ {color:#06287e} pre code span.im /* Import */ {} pre code span.in /* Information */ {color:#696969} pre code span.kw /* Keyword */ {color:#d91e18} pre code span.op /* Operator */ {color:#007faa} pre code span.ot /* Other */ {color:#d91e18} pre code span.pp /* Preprocessor */ {color:#7928a1} pre code span.sc /* SpecialChar */ {color:#007faa} pre code span.ss /* SpecialString */ {color:#008000} pre code span.st /* String */ {color:#008000} pre code span.va /* Variable */ {color:#aa5d00} pre code span.vs /* VerbatimString */ {color:#008000} pre code span.wa /* Warning */ {color:#696969; font-style: italic} pkgdown/inst/highlight-styles/monochrome-light.scss0000644000176200001440000000346314633374223022355 0ustar liggesuserspre {background-color: #ffffff; color: #000000;} pre code /* Normal */ {color:#000000} pre code span.al /* Alert */ {color:#000000} pre code span.an /* Annotation */ {color:#000000; font-style: italic} pre code span.at /* Attribute */ {color:#000000} pre code span.bn /* BaseN */ {color:#000000} pre code span.bu /* BuiltIn */ {color:#000000} pre code span.cf /* ControlFlow */ {color:#000000} pre code span.ch /* Char */ {color:#000000} pre code span.cn /* Constant */ {color:#000000} pre code span.co /* Comment */ {color:#000000; font-style: italic} pre code span.cv /* CommentVar */ {color:#000000; font-style: italic} pre code span.do /* Documentation */ {color:#000000; font-style: italic} pre code span.dt /* DataType */ {color:#000000} pre code span.dv /* DecVal */ {color:#000000} pre code span.er /* Error */ {color:#000000} pre code span.ex /* Extension */ {color:#000000} pre code span.fl /* Float */ {color:#000000} pre code span.fu /* Function */ {color:#000000} pre code span.im /* Import */ {color:#000000} pre code span.in /* Information */ {color:#000000; font-style: italic} pre code span.kw /* Keyword */ {color:#000000} pre code span.op /* Operator */ {color:#000000} pre code span.ot /* Other */ {color:#000000} pre code span.pp /* Preprocessor */ {color:#000000} pre code span.re /* RegionMarker */ {color:#000000} pre code span.sc /* SpecialChar */ {color:#000000} pre code span.ss /* SpecialString */ {color:#000000} pre code span.st /* String */ {color:#000000} pre code span.va /* Variable */ {color:#000000} pre code span.vs /* VerbatimString */ {color:#000000} pre code span.wa /* Warning */ {color:#000000; font-style: italic} pkgdown/inst/highlight-styles/ayu-light.scss0000644000176200001440000000353314246155422021001 0ustar liggesuserspre {background-color: #fafafa;} pre code /* Normal */ {color:#575f66} pre code span.al /* Alert */ {color:#f51818; background-color:#faefef; font-weight: bold} pre code span.an /* Annotation */ {color:#e6ba7e} pre code span.at /* Attribute */ {color:#399ee6} pre code span.bn /* BaseN */ {color:#ff9940} pre code span.bu /* BuiltIn */ {color:#4cbf99} pre code span.cf /* ControlFlow */ {color:#fa8d3e; font-weight: bold} pre code span.ch /* Char */ {color:#4cbf99} pre code span.cn /* Constant */ {color:#a37acc} pre code span.co /* Comment */ {color:#607880; font-style: italic} pre code span.cv /* CommentVar */ {color:#a37acc} pre code span.do /* Documentation */ {color:#607880} pre code span.dt /* DataType */ {color:#fa8d3e} pre code span.dv /* DecVal */ {color:#ff9940} pre code span.er /* Error */ {color:#f51818; text-decoration: underline} pre code span.ex /* Extension */ {color:#399ee6; font-weight: bold} pre code span.fl /* Float */ {color:#ff9940} pre code span.fu /* Function */ {color:#f2ae49} pre code span.im /* Import */ {color:#86b300} pre code span.in /* Information */ {color:#ff9940} pre code span.kw /* Keyword */ {color:#fa8d3e; font-weight: bold} pre code span.op /* Operator */ {color:#ed9366} pre code span.ot /* Others */ {color:#55b4d4} pre code span.pp /* Preprocessor */ {color:#f07171} pre code span.re /* RegionMarker */ {color:#399ee6; background-color:#ddecf3} pre code span.sc /* SpecialChar */ {color:#4cbf99} pre code span.ss /* SpecialString */ {color:#4cbf99} pre code span.st /* String */ {color:#86b300} pre code span.va /* Variable */ {color:#55b4d4} pre code span.vs /* VerbatimString */ {color:#86b300} pre code span.wa /* Warning */ {color:#f07171} pkgdown/inst/highlight-styles/haddock.scss0000644000176200001440000000233314245770621020473 0ustar liggesuserspre code span.al /* Alert */ {color:#ff0000} pre code span.an /* Annotation */ {color:#008000} pre code span.at /* Attribute */ {} pre code span.bu /* BuiltIn */ {} pre code span.cf /* ControlFlow */ {color:#0000ff} pre code span.ch /* Char */ {color:#008080} pre code span.cn /* Constant */ {} pre code span.co /* Comment */ {color:#008000} pre code span.cv /* CommentVar */ {color:#008000} pre code span.do /* Documentation */ {color:#008000} pre code span.er /* Error */ {color:#ff0000; font-weight: bold} pre code span.ex /* Extension */ {} pre code span.im /* Import */ {} pre code span.in /* Information */ {color:#008000} pre code span.kw /* Keyword */ {color:#0000ff} pre code span.op /* Operator */ {} pre code span.ot /* Other */ {color:#ff4000} pre code span.pp /* Preprocessor */ {color:#ff4000} pre code span.sc /* SpecialChar */ {color:#008080} pre code span.ss /* SpecialString */ {color:#008080} pre code span.st /* String */ {color:#008080} pre code span.va /* Variable */ {} pre code span.vs /* VerbatimString */ {color:#008080} pre code span.wa /* Warning */ {color:#008000; font-weight: bold} pkgdown/inst/highlight-styles/breeze-dark.scss0000644000176200001440000000353214246155422021270 0ustar liggesuserspre {background-color: #232629;} pre code /* Normal */ {color:#cfcfc2} pre code span.al /* Alert */ {color:#95da4c; background-color:#4d1f24; font-weight: bold} pre code span.an /* Annotation */ {color:#3f8058} pre code span.at /* Attribute */ {color:#2980b9} pre code span.bn /* BaseN */ {color:#f67400} pre code span.bu /* BuiltIn */ {color:#7f8c8d} pre code span.cf /* ControlFlow */ {color:#fdbc4b; font-weight: bold} pre code span.ch /* Char */ {color:#3daee9} pre code span.cn /* Constant */ {color:#27aeae; font-weight: bold} pre code span.co /* Comment */ {color:#7a7c7d} pre code span.cv /* CommentVar */ {color:#7f8c8d} pre code span.do /* Documentation */ {color:#a43340} pre code span.dt /* DataType */ {color:#2980b9} pre code span.dv /* DecVal */ {color:#f67400} pre code span.er /* Error */ {color:#da4453; text-decoration: underline} pre code span.ex /* Extension */ {color:#0099ff; font-weight: bold} pre code span.fl /* Float */ {color:#f67400} pre code span.fu /* Function */ {color:#8e44ad} pre code span.im /* Import */ {color:#27ae60} pre code span.in /* Information */ {color:#c45b00} pre code span.kw /* Keyword */ {color:#cfcfc2; font-weight: bold} pre code span.op /* Operator */ {color:#3f8058} pre code span.ot /* Others */ {color:#27ae60} pre code span.pp /* Preprocessor */ {color:#27ae60} pre code span.re /* RegionMarker */ {color:#2980b9; background-color:#153042} pre code span.sc /* SpecialChar */ {color:#3daee9} pre code span.ss /* SpecialString */ {color:#da4453} pre code span.st /* String */ {color:#f44f4f} pre code span.va /* Variable */ {color:#27aeae} pre code span.vs /* VerbatimString */ {color:#da4453} pre code span.wa /* Warning */ {color:#da4453} pkgdown/inst/highlight-styles/printing.scss0000644000176200001440000000350714246155422020731 0ustar liggesuserspre {background-color: #ffffff;} pre code /* Normal */ {color:#000000} pre code span.al /* Alert */ {color:#bf0303; background-color:#f7e6e6; font-weight: bold} pre code span.an /* Annotation */ {color:#ca60ca} pre code span.at /* Attribute */ {color:#0057ae} pre code span.bn /* BaseN */ {color:#b08000} pre code span.bu /* BuiltIn */ {color:#644a9b} pre code span.cf /* ControlFlow */ {color:#000000; font-weight: bold} pre code span.ch /* Char */ {color:#924c9d} pre code span.cn /* Constant */ {color:#aa5500} pre code span.co /* Comment */ {color:#898887} pre code span.cv /* CommentVar */ {color:#0095ff} pre code span.do /* Documentation */ {color:#607880} pre code span.dt /* DataType */ {color:#0057ae} pre code span.dv /* DecVal */ {color:#b08000} pre code span.er /* Error */ {color:#bf0303; text-decoration: underline} pre code span.ex /* Extension */ {color:#0095ff; font-weight: bold} pre code span.fl /* Float */ {color:#b08000} pre code span.fu /* Function */ {color:#644a9b} pre code span.im /* Import */ {color:#644a9b} pre code span.in /* Information */ {color:#b08000} pre code span.kw /* Keyword */ {color:#000000; font-weight: bold} pre code span.op /* Operator */ {color:#000000} pre code span.ot /* Others */ {color:#006e28} pre code span.pp /* Preprocessor */ {color:#006e28} pre code span.re /* RegionMarker */ {color:#0057ae; background-color:#e0e9f8} pre code span.sc /* SpecialChar */ {color:#ff5500} pre code span.ss /* SpecialString */ {color:#ff5500} pre code span.st /* String */ {color:#bf0303} pre code span.va /* Variable */ {color:#0057ae} pre code span.vs /* VerbatimString */ {color:#bf0303} pre code span.wa /* Warning */ {color:#bf0303} pkgdown/inst/highlight-styles/ayu-mirage.scss0000644000176200001440000000353314633374223021140 0ustar liggesuserspre {background-color: #1f2430;} pre code /* Normal */ {color:#cbccc6} pre code span.al /* Alert */ {color:#ff3333; background-color:#332430; font-weight: bold} pre code span.an /* Annotation */ {color:#ffe6b3} pre code span.at /* Attribute */ {color:#73d0ff} pre code span.bn /* BaseN */ {color:#ffcc66} pre code span.bu /* BuiltIn */ {color:#95e6cb} pre code span.cf /* ControlFlow */ {color:#ffa759; font-weight: bold} pre code span.ch /* Char */ {color:#95e6cb} pre code span.cn /* Constant */ {color:#d4bfff} pre code span.co /* Comment */ {color:#5c6773; font-style: italic} pre code span.cv /* CommentVar */ {color:#d4bfff} pre code span.do /* Documentation */ {color:#5c6773} pre code span.dt /* DataType */ {color:#ffa759} pre code span.dv /* DecVal */ {color:#ffcc66} pre code span.er /* Error */ {color:#ff3333; text-decoration: underline} pre code span.ex /* Extension */ {color:#73d0ff; font-weight: bold} pre code span.fl /* Float */ {color:#ffcc66} pre code span.fu /* Function */ {color:#ffd580} pre code span.im /* Import */ {color:#bae67e} pre code span.in /* Information */ {color:#ffcc66} pre code span.kw /* Keyword */ {color:#ffa759; font-weight: bold} pre code span.op /* Operator */ {color:#f29e74} pre code span.ot /* Other */ {color:#5ccfe6} pre code span.pp /* Preprocessor */ {color:#f28779} pre code span.re /* RegionMarker */ {color:#73d0ff; background-color:#2a4254} pre code span.sc /* SpecialChar */ {color:#95e6cb} pre code span.ss /* SpecialString */ {color:#95e6cb} pre code span.st /* String */ {color:#bae67e} pre code span.va /* Variable */ {color:#5ccfe6} pre code span.vs /* VerbatimString */ {color:#bae67e} pre code span.wa /* Warning */ {color:#f28779} pkgdown/inst/highlight-styles/zenburn.scss0000644000176200001440000000320014246155422020550 0ustar liggesuserspre {background-color: #303030; color: #cccccc;} pre code span.al /* Alert */ {color:#ffcfaf} pre code span.an /* Annotation */ {color:#7f9f7f; font-weight: bold} pre code span.at /* Attribute */ {} pre code span.bn /* BaseN */ {color:#dca3a3} pre code span.bu /* BuiltIn */ {} pre code span.cf /* ControlFlow */ {color:#f0dfaf} pre code span.ch /* Char */ {color:#dca3a3} pre code span.cn /* Constant */ {color:#dca3a3; font-weight: bold} pre code span.co /* Comment */ {color:#7f9f7f} pre code span.cv /* CommentVar */ {color:#7f9f7f; font-weight: bold} pre code span.do /* Documentation */ {color:#7f9f7f} pre code span.dt /* DataType */ {color:#dfdfbf} pre code span.dv /* DecVal */ {color:#dcdccc} pre code span.er /* Error */ {color:#c3bf9f} pre code span.ex /* Extension */ {} pre code span.fl /* Float */ {color:#c0bed1} pre code span.fu /* Function */ {color:#efef8f} pre code span.im /* Import */ {} pre code span.in /* Information */ {color:#7f9f7f; font-weight: bold} pre code span.kw /* Keyword */ {color:#f0dfaf} pre code span.op /* Operator */ {color:#f0efd0} pre code span.ot /* Other */ {color:#efef8f} pre code span.pp /* Preprocessor */ {color:#ffcfaf; font-weight: bold} pre code span.sc /* SpecialChar */ {color:#dca3a3} pre code span.ss /* SpecialString */ {color:#cc9393} pre code span.st /* String */ {color:#cc9393} pre code span.va /* Variable */ {} pre code span.vs /* VerbatimString */ {color:#cc9393} pre code span.wa /* Warning */ {color:#7f9f7f; font-weight: bold} pkgdown/inst/highlight-styles/tango.scss0000644000176200001440000000344614246155422020211 0ustar liggesuserspre {background-color: #f8f8f8;} pre code span.al /* Alert */ {color:#ef2929} pre code span.an /* Annotation */ {color:#8f5902; font-weight: bold; font-style: italic} pre code span.at /* Attribute */ {color:#c4a000} pre code span.bn /* BaseN */ {color:#0000cf} pre code span.cf /* ControlFlow */ {color:#204a87; font-weight: bold} pre code span.ch /* Char */ {color:#4e9a06} pre code span.cn /* Constant */ {color:#000000} pre code span.co /* Comment */ {color:#8f5902; font-style: italic} pre code span.cv /* CommentVar */ {color:#8f5902; font-weight: bold; font-style: italic} pre code span.do /* Documentation */ {color:#8f5902; font-weight: bold; font-style: italic} pre code span.dt /* DataType */ {color:#204a87} pre code span.dv /* DecVal */ {color:#0000cf} pre code span.er /* Error */ {color:#a40000; font-weight: bold} pre code span.ex /* Extension */ {} pre code span.fl /* Float */ {color:#0000cf} pre code span.fu /* Function */ {color:#000000} pre code span.im /* Import */ {} pre code span.in /* Information */ {color:#8f5902; font-weight: bold; font-style: italic} pre code span.kw /* Keyword */ {color:#204a87; font-weight: bold} pre code span.op /* Operator */ {color:#ce5c00; font-weight: bold} pre code span.ot /* Other */ {color:#8f5902} pre code span.pp /* Preprocessor */ {color:#8f5902; font-style: italic} pre code span.sc /* SpecialChar */ {color:#000000} pre code span.ss /* SpecialString */ {color:#4e9a06} pre code span.st /* String */ {color:#4e9a06} pre code span.va /* Variable */ {color:#000000} pre code span.vs /* VerbatimString */ {color:#4e9a06} pre code span.wa /* Warning */ {color:#8f5902; font-weight: bold; font-style: italic} pkgdown/inst/highlight-styles/gruvbox-light.scss0000644000176200001440000000361614246155422021701 0ustar liggesuserspre {background-color: #fbf1c7;} pre code /* Normal */ {color:#3c3836} pre code span.al /* Alert */ {color:#282828; background-color:#cc241d; font-weight: bold} pre code span.an /* Annotation */ {color:#98971a} pre code span.at /* Attribute */ {color:#d79921} pre code span.bn /* BaseN */ {color:#f67400} pre code span.bu /* BuiltIn */ {color:#d65d0e} pre code span.cf /* ControlFlow */ {color:#cc241d; font-weight: bold} pre code span.ch /* Char */ {color:#b16286} pre code span.cn /* Constant */ {color:#b16286; font-weight: bold} pre code span.co /* Comment */ {color:#928374} pre code span.cv /* CommentVar */ {color:#928374} pre code span.do /* Documentation */ {color:#98971a} pre code span.dt /* DataType */ {color:#d79921} pre code span.dv /* DecVal */ {color:#f67400} pre code span.er /* Error */ {color:#cc241d; text-decoration: underline} pre code span.ex /* Extension */ {color:#689d6a; font-weight: bold} pre code span.fl /* Float */ {color:#f67400} pre code span.fu /* Function */ {color:#689d6a} pre code span.im /* Import */ {color:#689d6a} pre code span.in /* Information */ {color:#282828; background-color:#83a598} pre code span.kw /* Keyword */ {color:#3c3836; font-weight: bold} pre code span.op /* Operator */ {color:#3c3836} pre code span.ot /* Others */ {color:#689d6a} pre code span.pp /* Preprocessor */ {color:#d65d0e} pre code span.re /* RegionMarker */ {color:#928374; background-color:#f9f5d7} pre code span.sc /* SpecialChar */ {color:#b16286} pre code span.ss /* SpecialString */ {color:#98971a} pre code span.st /* String */ {color:#98971a} pre code span.va /* Variable */ {color:#458588} pre code span.vs /* VerbatimString */ {color:#98971a} pre code span.wa /* Warning */ {color:#282828; background-color:#fabd2f} pkgdown/inst/highlight-styles/monokai.scss0000644000176200001440000000340114633374223020527 0ustar liggesuserspre {background-color: #2e3440;} pre code /* Normal */ {color:#f8f8f2} pre code span.al /* Alert */ {color:#ff5555; font-weight: bold} pre code span.an /* Annotation */ {color:#75715e} pre code span.at /* Attribute */ {color:#f92672} pre code span.bn /* BaseN */ {color:#ae81ff} pre code span.bu /* BuiltIn */ {color:#66D9EF} pre code span.cf /* ControlFlow */ {color:#f92672} pre code span.ch /* Char */ {color:#e6db74} pre code span.cn /* Constant */ {color:#ae81ff} pre code span.co /* Comment */ {color:#75715e} pre code span.cv /* CommentVar */ {color:#75715e} pre code span.do /* Documentation */ {color:#75715e} pre code span.dt /* DataType */ {color:#66d9ef; font-style: italic} pre code span.dv /* DecVal */ {color:#ae81ff} pre code span.er /* Error */ {color:#ff5555; text-decoration: underline} pre code span.ex /* Extension */ {color:#a6e22e; font-weight: bold} pre code span.fl /* Float */ {color:#ae81ff} pre code span.fu /* Function */ {color:#a6e22e} pre code span.im /* Import */ {color:#f92672} pre code span.in /* Information */ {color:#f1fa8c} pre code span.kw /* Keyword */ {color:#f92672} pre code span.op /* Operator */ {color:#f8f8f2} pre code span.ot /* Others */ {color:#a6e22e} pre code span.pp /* Preprocessor */ {color:#f92672} pre code span.re /* RegionMarker */ {color:#75715e} pre code span.sc /* SpecialChar */ {color:#ae81ff} pre code span.ss /* SpecialString */ {color:#e6db74} pre code span.st /* String */ {color:#e6db74} pre code span.va /* Variable */ {color:#f8f8f2} pre code span.vs /* VerbatimString */ {color:#e6db74} pre code span.wa /* Warning */ {color:#ff5555} pkgdown/inst/highlight-styles/monochrome.scss0000644000176200001440000000127314245770621021246 0ustar liggesuserspre code span.al /* Alert */ {font-weight: bold} pre code span.an /* Annotation */ {font-style: italic} pre code span.cf /* ControlFlow */ {font-weight: bold} pre code span.co /* Comment */ {font-style: italic} pre code span.cv /* CommentVar */ {font-style: italic} pre code span.do /* Documentation */ {font-style: italic} pre code span.dt /* DataType */ {text-decoration: underline} pre code span.er /* Error */ {font-weight: bold} pre code span.in /* Information */ {font-style: italic} pre code span.kw /* Keyword */ {font-weight: bold} pre code span.pp /* Preprocessor */ {font-weight: bold} pre code span.wa /* Warning */ {font-style: italic} pkgdown/inst/highlight-styles/breezedark.scss0000644000176200001440000000355214246155422021215 0ustar liggesuserspre {background-color: #232629; color: #cfcfc2;} pre code /* Normal */ {color:#cfcfc2} pre code span.al /* Alert */ {color:#95da4c; background-color:#4d1f24; font-weight: bold} pre code span.an /* Annotation */ {color:#3f8058} pre code span.at /* Attribute */ {color:#2980b9} pre code span.bn /* BaseN */ {color:#f67400} pre code span.bu /* BuiltIn */ {color:#7f8c8d} pre code span.cf /* ControlFlow */ {color:#fdbc4b; font-weight: bold} pre code span.ch /* Char */ {color:#3daee9} pre code span.cn /* Constant */ {color:#27aeae; font-weight: bold} pre code span.co /* Comment */ {color:#7a7c7d} pre code span.cv /* CommentVar */ {color:#7f8c8d} pre code span.do /* Documentation */ {color:#a43340} pre code span.dt /* DataType */ {color:#2980b9} pre code span.dv /* DecVal */ {color:#f67400} pre code span.er /* Error */ {color:#da4453; text-decoration: underline} pre code span.ex /* Extension */ {color:#0099ff; font-weight: bold} pre code span.fl /* Float */ {color:#f67400} pre code span.fu /* Function */ {color:#8e44ad} pre code span.im /* Import */ {color:#27ae60} pre code span.in /* Information */ {color:#c45b00} pre code span.kw /* Keyword */ {color:#cfcfc2; font-weight: bold} pre code span.op /* Operator */ {color:#cfcfc2} pre code span.ot /* Other */ {color:#27ae60} pre code span.pp /* Preprocessor */ {color:#27ae60} pre code span.re /* RegionMarker */ {color:#2980b9; background-color:#153042} pre code span.sc /* SpecialChar */ {color:#3daee9} pre code span.ss /* SpecialString */ {color:#da4453} pre code span.st /* String */ {color:#f44f4f} pre code span.va /* Variable */ {color:#27aeae} pre code span.vs /* VerbatimString */ {color:#da4453} pre code span.wa /* Warning */ {color:#da4453} pkgdown/inst/highlight-styles/pygments.scss0000644000176200001440000000340714245770621020747 0ustar liggesuserspre code span.al /* Alert */ {color:#ff0000; font-weight: bold} pre code span.an /* Annotation */ {color:#60a0b0; font-weight: bold; font-style: italic} pre code span.at /* Attribute */ {color:#7d9029} pre code span.bn /* BaseN */ {color:#40a070} pre code span.bu /* BuiltIn */ {} pre code span.cf /* ControlFlow */ {color:#007020; font-weight: bold} pre code span.ch /* Char */ {color:#4070a0} pre code span.cn /* Constant */ {color:#880000} pre code span.co /* Comment */ {color:#60a0b0; font-style: italic} pre code span.cv /* CommentVar */ {color:#60a0b0; font-weight: bold; font-style: italic} pre code span.do /* Documentation */ {color:#ba2121; font-style: italic} pre code span.dt /* DataType */ {color:#902000} pre code span.dv /* DecVal */ {color:#40a070} pre code span.er /* Error */ {color:#ff0000; font-weight: bold} pre code span.ex /* Extension */ {} pre code span.fl /* Float */ {color:#40a070} pre code span.fu /* Function */ {color:#06287e} pre code span.im /* Import */ {} pre code span.in /* Information */ {color:#60a0b0; font-weight: bold; font-style: italic} pre code span.kw /* Keyword */ {color:#007020; font-weight: bold} pre code span.op /* Operator */ {color:#666666} pre code span.ot /* Other */ {color:#007020} pre code span.pp /* Preprocessor */ {color:#bc7a00} pre code span.sc /* SpecialChar */ {color:#4070a0} pre code span.ss /* SpecialString */ {color:#bb6688} pre code span.st /* String */ {color:#4070a0} pre code span.va /* Variable */ {color:#19177c} pre code span.vs /* VerbatimString */ {color:#4070a0} pre code span.wa /* Warning */ {color:#60a0b0; font-weight: bold; font-style: italic} pkgdown/inst/highlight-styles/espresso.scss0000644000176200001440000000320114246155422020731 0ustar liggesuserspre {background-color: #2a211c; color: #bdae9d;} pre code span.al /* Alert */ {color:#ffff00} pre code span.an /* Annotation */ {color:#0066ff; font-weight: bold; font-style: italic} pre code span.at /* Attribute */ {} pre code span.bn /* BaseN */ {color:#44aa43} pre code span.bu /* BuiltIn */ {} pre code span.cf /* ControlFlow */ {color:#43a8ed; font-weight: bold} pre code span.ch /* Char */ {color:#049b0a} pre code span.cn /* Constant */ {} pre code span.co /* Comment */ {color:#0066ff; font-weight: bold; font-style: italic} pre code span.do /* Documentation */ {color:#0066ff; font-style: italic} pre code span.dt /* DataType */ {text-decoration: underline} pre code span.dv /* DecVal */ {color:#44aa43} pre code span.er /* Error */ {color:#ffff00; font-weight: bold} pre code span.ex /* Extension */ {} pre code span.fl /* Float */ {color:#44aa43} pre code span.fu /* Function */ {color:#ff9358; font-weight: bold} pre code span.im /* Import */ {} pre code span.in /* Information */ {color:#0066ff; font-weight: bold; font-style: italic} pre code span.kw /* Keyword */ {color:#43a8ed; font-weight: bold} pre code span.op /* Operator */ {} pre code span.pp /* Preprocessor */ {font-weight: bold} pre code span.sc /* SpecialChar */ {color:#049b0a} pre code span.ss /* SpecialString */ {color:#049b0a} pre code span.st /* String */ {color:#049b0a} pre code span.va /* Variable */ {} pre code span.vs /* VerbatimString */ {color:#049b0a} pre code span.wa /* Warning */ {color:#ffff00; font-weight: bold} pkgdown/inst/highlight-styles/github-light.scss0000644000176200001440000000335514246155422021467 0ustar liggesuserspre {background-color: #ffffff;} pre code /* Normal */ {color:#24292e} pre code span.al /* Alert */ {color:#ff5555; font-weight: bold} pre code span.an /* Annotation */ {color:#6a737d} pre code span.at /* Attribute */ {color:#d73a49} pre code span.bn /* BaseN */ {color:#005cc5} pre code span.bu /* BuiltIn */ {color:#d73a49} pre code span.cf /* ControlFlow */ {color:#d73a49} pre code span.ch /* Char */ {color:#032f62} pre code span.cn /* Constant */ {color:#005cc5} pre code span.co /* Comment */ {color:#6a737d} pre code span.cv /* CommentVar */ {color:#6a737d} pre code span.do /* Documentation */ {color:#6a737d} pre code span.dt /* DataType */ {color:#d73a49} pre code span.dv /* DecVal */ {color:#005cc5} pre code span.er /* Error */ {color:#ff5555; text-decoration: underline} pre code span.ex /* Extension */ {color:#d73a49; font-weight: bold} pre code span.fl /* Float */ {color:#005cc5} pre code span.fu /* Function */ {color:#6f42c1} pre code span.im /* Import */ {color:#032f62} pre code span.in /* Information */ {color:#6a737d} pre code span.kw /* Keyword */ {color:#d73a49} pre code span.op /* Operator */ {color:#24292e} pre code span.ot /* Others */ {color:#6f42c1} pre code span.pp /* Preprocessor */ {color:#d73a49} pre code span.re /* RegionMarker */ {color:#6a737d} pre code span.sc /* SpecialChar */ {color:#005cc5} pre code span.ss /* SpecialString */ {color:#032f62} pre code span.st /* String */ {color:#032f62} pre code span.va /* Variable */ {color:#e36209} pre code span.vs /* VerbatimString */ {color:#032f62} pre code span.wa /* Warning */ {color:#ff5555} pkgdown/inst/highlight-styles/oblivion.scss0000644000176200001440000000355514246155422020723 0ustar liggesuserspre {background-color: #201f1f;} pre code /* Normal */ {color:#d3d7c1} pre code span.al /* Alert */ {color:#e85848; background-color:#451e1a; font-weight: bold} pre code span.an /* Annotation */ {color:#ad7fa8} pre code span.at /* Attribute */ {color:#ad7fa8} pre code span.bn /* BaseN */ {color:#edd400} pre code span.bu /* BuiltIn */ {color:#729fcf} pre code span.cf /* ControlFlow */ {color:#ffffff; font-weight: bold} pre code span.ch /* Char */ {color:#ce5c00} pre code span.cn /* Constant */ {color:#edd400; font-weight: bold} pre code span.co /* Comment */ {color:#30a100} pre code span.cv /* CommentVar */ {color:#ad7fa8} pre code span.do /* Documentation */ {color:#4e9a06} pre code span.dt /* DataType */ {color:#508ed8} pre code span.dv /* DecVal */ {color:#edd400} pre code span.er /* Error */ {color:#e85848; text-decoration: underline} pre code span.ex /* Extension */ {color:#508ed8; font-weight: bold} pre code span.fl /* Float */ {color:#ce5c00} pre code span.fu /* Function */ {color:#729fcf; font-weight: bold} pre code span.im /* Import */ {color:#ad7fa8} pre code span.in /* Information */ {color:#c0a25f} pre code span.kw /* Keyword */ {color:#ffffff; font-weight: bold} pre code span.op /* Operator */ {color:#eeeeec} pre code span.ot /* Others */ {color:#edd400} pre code span.pp /* Preprocessor */ {color:#ad7fa8} pre code span.re /* RegionMarker */ {color:#508ed8; background-color:#1c2c3f} pre code span.sc /* SpecialChar */ {color:#ce5c00} pre code span.ss /* SpecialString */ {color:#fce94f} pre code span.st /* String */ {color:#edd400} pre code span.va /* Variable */ {color:#ce5c00} pre code span.vs /* VerbatimString */ {color:#c4a000} pre code span.wa /* Warning */ {color:#e85848} pkgdown/inst/highlight-styles/monochrome-dark.scss0000644000176200001440000000346314633374223022167 0ustar liggesuserspre {background-color: #000000; color: #FFFFFF;} pre code /* Normal */ {color:#FFFFFF} pre code span.al /* Alert */ {color:#FFFFFF} pre code span.an /* Annotation */ {color:#FFFFFF; font-style: italic} pre code span.at /* Attribute */ {color:#FFFFFF} pre code span.bn /* BaseN */ {color:#FFFFFF} pre code span.bu /* BuiltIn */ {color:#FFFFFF} pre code span.cf /* ControlFlow */ {color:#FFFFFF} pre code span.ch /* Char */ {color:#FFFFFF} pre code span.cn /* Constant */ {color:#FFFFFF} pre code span.co /* Comment */ {color:#FFFFFF; font-style: italic} pre code span.cv /* CommentVar */ {color:#FFFFFF; font-style: italic} pre code span.do /* Documentation */ {color:#FFFFFF; font-style: italic} pre code span.dt /* DataType */ {color:#FFFFFF} pre code span.dv /* DecVal */ {color:#FFFFFF} pre code span.er /* Error */ {color:#FFFFFF} pre code span.ex /* Extension */ {color:#FFFFFF} pre code span.fl /* Float */ {color:#FFFFFF} pre code span.fu /* Function */ {color:#FFFFFF} pre code span.im /* Import */ {color:#FFFFFF} pre code span.in /* Information */ {color:#FFFFFF; font-style: italic} pre code span.kw /* Keyword */ {color:#FFFFFF} pre code span.op /* Operator */ {color:#FFFFFF} pre code span.ot /* Other */ {color:#FFFFFF} pre code span.pp /* Preprocessor */ {color:#FFFFFF} pre code span.re /* RegionMarker */ {color:#FFFFFF} pre code span.sc /* SpecialChar */ {color:#FFFFFF} pre code span.ss /* SpecialString */ {color:#FFFFFF} pre code span.st /* String */ {color:#FFFFFF} pre code span.va /* Variable */ {color:#FFFFFF} pre code span.vs /* VerbatimString */ {color:#FFFFFF} pre code span.wa /* Warning */ {color:#FFFFFF; font-style: italic} pkgdown/inst/highlight-styles/breeze-light.scss0000644000176200001440000000353214246155422021456 0ustar liggesuserspre {background-color: #ffffff;} pre code /* Normal */ {color:#1f1c1b} pre code span.al /* Alert */ {color:#bf0303; background-color:#f7e6e6; font-weight: bold} pre code span.an /* Annotation */ {color:#ca60ca} pre code span.at /* Attribute */ {color:#0057ae} pre code span.bn /* BaseN */ {color:#b08000} pre code span.bu /* BuiltIn */ {color:#644a9b; font-weight: bold} pre code span.cf /* ControlFlow */ {color:#1f1c1b; font-weight: bold} pre code span.ch /* Char */ {color:#924c9d} pre code span.cn /* Constant */ {color:#aa5500} pre code span.co /* Comment */ {color:#898887} pre code span.cv /* CommentVar */ {color:#0095ff} pre code span.do /* Documentation */ {color:#607880} pre code span.dt /* DataType */ {color:#0057ae} pre code span.dv /* DecVal */ {color:#b08000} pre code span.er /* Error */ {color:#bf0303; text-decoration: underline} pre code span.ex /* Extension */ {color:#0095ff; font-weight: bold} pre code span.fl /* Float */ {color:#b08000} pre code span.fu /* Function */ {color:#644a9b} pre code span.im /* Import */ {color:#ff5500} pre code span.in /* Information */ {color:#b08000} pre code span.kw /* Keyword */ {color:#1f1c1b; font-weight: bold} pre code span.op /* Operator */ {color:#ca60ca} pre code span.ot /* Others */ {color:#006e28} pre code span.pp /* Preprocessor */ {color:#006e28} pre code span.re /* RegionMarker */ {color:#0057ae; background-color:#e0e9f8} pre code span.sc /* SpecialChar */ {color:#3daee9} pre code span.ss /* SpecialString */ {color:#ff5500} pre code span.st /* String */ {color:#bf0303} pre code span.va /* Variable */ {color:#0057ae} pre code span.vs /* VerbatimString */ {color:#bf0303} pre code span.wa /* Warning */ {color:#bf0303} pkgdown/inst/highlight-styles/a11y-dark.scss0000644000176200001440000000321214633374223020564 0ustar liggesuserspre {background-color: #2b2b2b;} pre code /* Normal */ {color:#f8f8f2} pre code span.al /* Alert */ {color:#dcc6e0} pre code span.an /* Annotation */ {color:#d4d0ab} pre code span.at /* Attribute */ {color:#ffd700} pre code span.bn /* BaseN */ {color:#dcc6e0} pre code span.bu /* BuiltIn */ {} pre code span.cf /* ControlFlow */ {color:#ffa07a} pre code span.ch /* Char */ {color:#abe338} pre code span.cn /* Constant */ {color:#ffa07a} pre code span.co /* Comment */ {color:#d4d0ab} pre code span.cv /* CommentVar */ {color:#d4d0ab; font-style: italic} pre code span.do /* Documentation */ {color:#d4d0ab; font-style: italic} pre code span.dt /* DataType */ {color:#dcc6e0} pre code span.dv /* DecVal */ {color:#dcc6e0} pre code span.er /* Error */ {color:#dcc6e0} pre code span.ex /* Extension */ {} pre code span.fl /* Float */ {color:#f5ab35} pre code span.fu /* Function */ {color:#ffd700} pre code span.im /* Import */ {} pre code span.in /* Information */ {color:#d4d0ab} pre code span.kw /* Keyword */ {color:#ffa07a} pre code span.op /* Operator */ {color:#00e0e0} pre code span.ot /* Other */ {color:#ffa07a} pre code span.pp /* Preprocessor */ {color:#dcc6e0} pre code span.sc /* SpecialChar */ {color:#00e0e0} pre code span.ss /* SpecialString */ {color:#abe338} pre code span.st /* String */ {color:#abe338} pre code span.va /* Variable */ {color:#f5ab35} pre code span.vs /* VerbatimString */ {color:#abe338} pre code span.wa /* Warning */ {color:#d4d0ab; font-style: italic} pkgdown/inst/highlight-styles/solarized.scss0000644000176200001440000000354714633374223021101 0ustar liggesuserspre {background-color: #fdf6e3;} pre code /* Normal */ {color:#657b83} pre code span.al /* Alert */ {color:#d33682; font-weight: bold} pre code span.an /* Annotation */ {color:#268bd2} pre code span.at /* Attribute */ {color:#268bd2} pre code span.bn /* BaseN */ {color:#2aa198} pre code span.bu /* BuiltIn */ {color:#cb4b16} pre code span.cf /* ControlFlow */ {color:#859900; font-weight: bold} pre code span.ch /* Char */ {color:#2aa198} pre code span.cn /* Constant */ {color:#2aa198; font-weight: bold} pre code span.co /* Comment */ {color:#93a1a1; font-style: italic} pre code span.cv /* CommentVar */ {color:#2aa198} pre code span.do /* Documentation */ {color:#dc322f} pre code span.dt /* DataType */ {color:#b58900; font-weight: bold} pre code span.dv /* DecVal */ {color:#2aa198} pre code span.er /* Error */ {color:#dc322f; text-decoration: underline} pre code span.ex /* Extension */ {color:#268bd2; font-weight: bold} pre code span.fl /* Float */ {color:#2aa198} pre code span.fu /* Function */ {color:#268bd2} pre code span.im /* Import */ {color:#2aa198} pre code span.in /* Information */ {color:#b58900} pre code span.kw /* Keyword */ {color:#859900; font-weight: bold} pre code span.op /* Operator */ {color:#859900} pre code span.ot /* Others */ {color:#859900} pre code span.pp /* Preprocessor */ {color:#cb4b16} pre code span.re /* RegionMarker */ {color:#268bd2; background-color:#eee8d5} pre code span.sc /* SpecialChar */ {color:#dc322f} pre code span.ss /* SpecialString */ {color:#dc322f} pre code span.st /* String */ {color:#2aa198} pre code span.va /* Variable */ {color:#268bd2} pre code span.vs /* VerbatimString */ {color:#2aa198} pre code span.wa /* Warning */ {color:#cb4b16} pkgdown/inst/highlight-styles/dracula.scss0000644000176200001440000000340114246155422020503 0ustar liggesuserspre {background-color: #282a36;} pre code /* Normal */ {color:#f8f8f2} pre code span.al /* Alert */ {color:#ff5555; font-weight: bold} pre code span.an /* Annotation */ {color:#ff79c6} pre code span.at /* Attribute */ {color:#ff79c6} pre code span.bn /* BaseN */ {color:#bd93f9} pre code span.bu /* BuiltIn */ {color:#8be9fd} pre code span.cf /* ControlFlow */ {color:#ff79c6} pre code span.ch /* Char */ {color:#f1fa8c} pre code span.cn /* Constant */ {color:#bd93f9; font-weight: bold} pre code span.co /* Comment */ {color:#6272a4} pre code span.cv /* CommentVar */ {color:#8be9fd} pre code span.do /* Documentation */ {color:#ffb86c} pre code span.dt /* DataType */ {color:#8be9fd; font-style: italic} pre code span.dv /* DecVal */ {color:#bd93f9} pre code span.er /* Error */ {color:#ff5555; text-decoration: underline} pre code span.ex /* Extension */ {color:#8be9fd} pre code span.fl /* Float */ {color:#bd93f9} pre code span.fu /* Function */ {color:#50fa7b} pre code span.im /* Import */ {color:#ff79c6} pre code span.in /* Information */ {color:#f1fa8c} pre code span.kw /* Keyword */ {color:#ff79c6} pre code span.op /* Operator */ {color:#f8f8f2} pre code span.ot /* Others */ {color:#50fa7b} pre code span.pp /* Preprocessor */ {color:#ff79c6} pre code span.re /* RegionMarker */ {color:#8be9fd} pre code span.sc /* SpecialChar */ {color:#ff79c6} pre code span.ss /* SpecialString */ {color:#f1fa8c} pre code span.st /* String */ {color:#f1fa8c} pre code span.va /* Variable */ {color:#8be9fd} pre code span.vs /* VerbatimString */ {color:#f1fa8c} pre code span.wa /* Warning */ {color:#ff5555} pkgdown/inst/highlight-styles/gruvbox-dark.scss0000644000176200001440000000361614246155422021513 0ustar liggesuserspre {background-color: #282828;} pre code /* Normal */ {color:#ebdbb2} pre code span.al /* Alert */ {color:#282828; background-color:#cc241d; font-weight: bold} pre code span.an /* Annotation */ {color:#98971a} pre code span.at /* Attribute */ {color:#d79921} pre code span.bn /* BaseN */ {color:#f67400} pre code span.bu /* BuiltIn */ {color:#d65d0e} pre code span.cf /* ControlFlow */ {color:#cc241d; font-weight: bold} pre code span.ch /* Char */ {color:#b16286} pre code span.cn /* Constant */ {color:#b16286; font-weight: bold} pre code span.co /* Comment */ {color:#928374} pre code span.cv /* CommentVar */ {color:#928374} pre code span.do /* Documentation */ {color:#98971a} pre code span.dt /* DataType */ {color:#d79921} pre code span.dv /* DecVal */ {color:#f67400} pre code span.er /* Error */ {color:#cc241d; text-decoration: underline} pre code span.ex /* Extension */ {color:#689d6a; font-weight: bold} pre code span.fl /* Float */ {color:#f67400} pre code span.fu /* Function */ {color:#689d6a} pre code span.im /* Import */ {color:#689d6a} pre code span.in /* Information */ {color:#282828; background-color:#83a598} pre code span.kw /* Keyword */ {color:#ebdbb2; font-weight: bold} pre code span.op /* Operator */ {color:#ebdbb2} pre code span.ot /* Others */ {color:#689d6a} pre code span.pp /* Preprocessor */ {color:#d65d0e} pre code span.re /* RegionMarker */ {color:#928374; background-color:#1d2021} pre code span.sc /* SpecialChar */ {color:#b16286} pre code span.ss /* SpecialString */ {color:#98971a} pre code span.st /* String */ {color:#98971a} pre code span.va /* Variable */ {color:#458588} pre code span.vs /* VerbatimString */ {color:#98971a} pre code span.wa /* Warning */ {color:#282828; background-color:#fabd2f} pkgdown/inst/highlight-styles/vim-dark.scss0000644000176200001440000000355514246155422020614 0ustar liggesuserspre {background-color: #000000;} pre code /* Normal */ {color:#b2b2b2} pre code span.al /* Alert */ {color:#ff0000; background-color:#3f0000; font-weight: bold} pre code span.an /* Annotation */ {color:#ff00ff} pre code span.at /* Attribute */ {color:#ffffaf} pre code span.bn /* BaseN */ {color:#ff8b8b} pre code span.bu /* BuiltIn */ {color:#87ffaf; font-weight: bold} pre code span.cf /* ControlFlow */ {color:#ffff54; font-weight: bold} pre code span.ch /* Char */ {color:#ff5454} pre code span.cn /* Constant */ {color:#af7f00; font-weight: bold} pre code span.co /* Comment */ {color:#54ffff} pre code span.cv /* CommentVar */ {color:#0095ff} pre code span.do /* Documentation */ {color:#e0ffff} pre code span.dt /* DataType */ {color:#ffff54} pre code span.dv /* DecVal */ {color:#ff8b8b} pre code span.er /* Error */ {color:#ff5500; text-decoration: underline} pre code span.ex /* Extension */ {color:#0095ff; font-weight: bold} pre code span.fl /* Float */ {color:#ff8b8b} pre code span.fu /* Function */ {color:#cd00cd} pre code span.im /* Import */ {color:#ff54ff} pre code span.in /* Information */ {color:#ffaa00} pre code span.kw /* Keyword */ {color:#5fd7ff; font-weight: bold} pre code span.op /* Operator */ {color:#b2b2b2} pre code span.ot /* Others */ {color:#54ff54} pre code span.pp /* Preprocessor */ {color:#87ffaf} pre code span.re /* RegionMarker */ {color:#0095ff; background-color:#22226d} pre code span.sc /* SpecialChar */ {color:#0095ff} pre code span.ss /* SpecialString */ {color:#ff5500} pre code span.st /* String */ {color:#ff54ff} pre code span.va /* Variable */ {color:#06989a} pre code span.vs /* VerbatimString */ {color:#ff54ff} pre code span.wa /* Warning */ {color:#ff0000} pkgdown/inst/highlight-styles/kate.scss0000644000176200001440000000355214246155422020023 0ustar liggesuserspre {background-color: #ffffff; color: #1f1c1b;} pre code /* Normal */ {color:#1f1c1b} pre code span.al /* Alert */ {color:#bf0303; background-color:#f7e6e6; font-weight: bold} pre code span.an /* Annotation */ {color:#ca60ca} pre code span.at /* Attribute */ {color:#0057ae} pre code span.bn /* BaseN */ {color:#b08000} pre code span.bu /* BuiltIn */ {color:#644a9b; font-weight: bold} pre code span.cf /* ControlFlow */ {color:#1f1c1b; font-weight: bold} pre code span.ch /* Char */ {color:#924c9d} pre code span.cn /* Constant */ {color:#aa5500} pre code span.co /* Comment */ {color:#898887} pre code span.cv /* CommentVar */ {color:#0095ff} pre code span.do /* Documentation */ {color:#607880} pre code span.dt /* DataType */ {color:#0057ae} pre code span.dv /* DecVal */ {color:#b08000} pre code span.er /* Error */ {color:#bf0303; text-decoration: underline} pre code span.ex /* Extension */ {color:#0095ff; font-weight: bold} pre code span.fl /* Float */ {color:#b08000} pre code span.fu /* Function */ {color:#644a9b} pre code span.im /* Import */ {color:#ff5500} pre code span.in /* Information */ {color:#b08000} pre code span.kw /* Keyword */ {color:#1f1c1b; font-weight: bold} pre code span.op /* Operator */ {color:#1f1c1b} pre code span.ot /* Other */ {color:#006e28} pre code span.pp /* Preprocessor */ {color:#006e28} pre code span.re /* RegionMarker */ {color:#0057ae; background-color:#e0e9f8} pre code span.sc /* SpecialChar */ {color:#3daee9} pre code span.ss /* SpecialString */ {color:#ff5500} pre code span.st /* String */ {color:#bf0303} pre code span.va /* Variable */ {color:#0057ae} pre code span.vs /* VerbatimString */ {color:#bf0303} pre code span.wa /* Warning */ {color:#bf0303} pkgdown/inst/highlight-styles/nord.scss0000644000176200001440000000355614246155422020045 0ustar liggesuserspre {background-color: #2e3440;} pre code /* Normal */ {color:#d8dee9} pre code span.al /* Alert */ {color:#bf616a; background-color:#3b4252; font-weight: bold} pre code span.an /* Annotation */ {color:#d08770} pre code span.at /* Attribute */ {color:#8fbcbb} pre code span.bn /* BaseN */ {color:#b48ead} pre code span.bu /* BuiltIn */ {color:#88c0d0; font-style: italic} pre code span.cf /* ControlFlow */ {color:#81a1c1; font-weight: bold} pre code span.ch /* Char */ {color:#ebcb8b} pre code span.cn /* Constant */ {color:#eceff4; font-weight: bold} pre code span.co /* Comment */ {color:#616e88} pre code span.cv /* CommentVar */ {color:#e5e9f0} pre code span.do /* Documentation */ {color:#5e81ac} pre code span.dt /* DataType */ {color:#81a1c1} pre code span.dv /* DecVal */ {color:#b48ead} pre code span.er /* Error */ {color:#bf616a; text-decoration: underline} pre code span.ex /* Extension */ {color:#8fbcbb; font-weight: bold} pre code span.fl /* Float */ {color:#b48ead} pre code span.fu /* Function */ {color:#88c0d0} pre code span.im /* Import */ {color:#a3be8c} pre code span.in /* Information */ {color:#ebcb8b} pre code span.kw /* Keyword */ {color:#81a1c1; font-weight: bold} pre code span.op /* Operator */ {color:#81a1c1} pre code span.ot /* Others */ {color:#8fbcbb} pre code span.pp /* Preprocessor */ {color:#5e81ac} pre code span.re /* RegionMarker */ {color:#88c0d0; background-color:#3b4252} pre code span.sc /* SpecialChar */ {color:#ebcb8b} pre code span.ss /* SpecialString */ {color:#d08770} pre code span.st /* String */ {color:#a3be8c} pre code span.va /* Variable */ {color:#5e81ac} pre code span.vs /* VerbatimString */ {color:#a3be8c} pre code span.wa /* Warning */ {color:#bf616a} pkgdown/inst/highlight-styles/github-dark.scss0000644000176200001440000000335514246155422021301 0ustar liggesuserspre {background-color: #24292e;} pre code /* Normal */ {color:#e1e4e8} pre code span.al /* Alert */ {color:#ff5555; font-weight: bold} pre code span.an /* Annotation */ {color:#6a737d} pre code span.at /* Attribute */ {color:#f97583} pre code span.bn /* BaseN */ {color:#79b8ff} pre code span.bu /* BuiltIn */ {color:#f97583} pre code span.cf /* ControlFlow */ {color:#f97583} pre code span.ch /* Char */ {color:#9ecbff} pre code span.cn /* Constant */ {color:#79b8ff} pre code span.co /* Comment */ {color:#6a737d} pre code span.cv /* CommentVar */ {color:#6a737d} pre code span.do /* Documentation */ {color:#6a737d} pre code span.dt /* DataType */ {color:#f97583} pre code span.dv /* DecVal */ {color:#79b8ff} pre code span.er /* Error */ {color:#ff5555; text-decoration: underline} pre code span.ex /* Extension */ {color:#f97583; font-weight: bold} pre code span.fl /* Float */ {color:#79b8ff} pre code span.fu /* Function */ {color:#b392f0} pre code span.im /* Import */ {color:#9ecbff} pre code span.in /* Information */ {color:#6a737d} pre code span.kw /* Keyword */ {color:#f97583} pre code span.op /* Operator */ {color:#e1e4e8} pre code span.ot /* Others */ {color:#b392f0} pre code span.pp /* Preprocessor */ {color:#f97583} pre code span.re /* RegionMarker */ {color:#6a737d} pre code span.sc /* SpecialChar */ {color:#79b8ff} pre code span.ss /* SpecialString */ {color:#9ecbff} pre code span.st /* String */ {color:#9ecbff} pre code span.va /* Variable */ {color:#ffab70} pre code span.vs /* VerbatimString */ {color:#9ecbff} pre code span.wa /* Warning */ {color:#ff5555} pkgdown/inst/highlight-styles/atom-one-light.scss0000644000176200001440000000345014245770621021723 0ustar liggesuserspre code /* Normal */ {color:#383a42} pre code span.al /* Alert */ {color:#95da4c; background-color:#4d1f24; font-weight: bold} pre code span.an /* Annotation */ {color:#50a14f} pre code span.at /* Attribute */ {color:#a626a4} pre code span.bn /* BaseN */ {color:#986801} pre code span.bu /* BuiltIn */ {color:#a626a4} pre code span.cf /* ControlFlow */ {color:#a626a4} pre code span.ch /* Char */ {color:#50a14f} pre code span.cn /* Constant */ {color:#986801} pre code span.co /* Comment */ {color:#a0a1a7; font-style: italic} pre code span.cv /* CommentVar */ {color:#e45649; font-style: italic} pre code span.do /* Documentation */ {color:#e45649} pre code span.dt /* DataType */ {color:#a626a4} pre code span.dv /* DecVal */ {color:#986801} pre code span.er /* Error */ {color:#f44747; text-decoration: underline} pre code span.ex /* Extension */ {color:#4078f2; font-weight: bold} pre code span.fl /* Float */ {color:#986801} pre code span.fu /* Function */ {color:#4078f2} pre code span.im /* Import */ {color:#50a14f} pre code span.in /* Information */ {color:#c45b00} pre code span.kw /* Keyword */ {color:#a626a4} pre code span.op /* Operator */ {color:#a626a4} pre code span.ot /* Others */ {color:#27ae60} pre code span.pp /* Preprocessor */ {color:#a626a4} pre code span.re /* RegionMarker */ {color:#2980b9; background-color:#153042} pre code span.sc /* SpecialChar */ {color:#0184bc} pre code span.ss /* SpecialString */ {color:#da4453} pre code span.st /* String */ {color:#50a14f} pre code span.va /* Variable */ {color:#e45649} pre code span.vs /* VerbatimString */ {color:#da4453} pre code span.wa /* Warning */ {color:#da4453} pkgdown/inst/highlight-styles/ayu-dark.scss0000644000176200001440000000353314246155422020613 0ustar liggesuserspre {background-color: #0a0e14;} pre code /* Normal */ {color:#b3b1ad} pre code span.al /* Alert */ {color:#ff3333; background-color:#2a0f15; font-weight: bold} pre code span.an /* Annotation */ {color:#e6b673} pre code span.at /* Attribute */ {color:#59c2ff} pre code span.bn /* BaseN */ {color:#e6b450} pre code span.bu /* BuiltIn */ {color:#95e6cb} pre code span.cf /* ControlFlow */ {color:#ff8f40; font-weight: bold} pre code span.ch /* Char */ {color:#95e6cb} pre code span.cn /* Constant */ {color:#ffee99} pre code span.co /* Comment */ {color:#626a73; font-style: italic} pre code span.cv /* CommentVar */ {color:#ffee99} pre code span.do /* Documentation */ {color:#626a73} pre code span.dt /* DataType */ {color:#ff8f40} pre code span.dv /* DecVal */ {color:#e6b450} pre code span.er /* Error */ {color:#ff3333; text-decoration: underline} pre code span.ex /* Extension */ {color:#59c2ff; font-weight: bold} pre code span.fl /* Float */ {color:#e6b450} pre code span.fu /* Function */ {color:#ffb454} pre code span.im /* Import */ {color:#c2d94c} pre code span.in /* Information */ {color:#e6b450} pre code span.kw /* Keyword */ {color:#ff8f40; font-weight: bold} pre code span.op /* Operator */ {color:#f29668} pre code span.ot /* Others */ {color:#39bae6} pre code span.pp /* Preprocessor */ {color:#f07178} pre code span.re /* RegionMarker */ {color:#59c2ff; background-color:#173649} pre code span.sc /* SpecialChar */ {color:#95e6cb} pre code span.ss /* SpecialString */ {color:#95e6cb} pre code span.st /* String */ {color:#c2d94c} pre code span.va /* Variable */ {color:#39bae6} pre code span.vs /* VerbatimString */ {color:#c2d94c} pre code span.wa /* Warning */ {color:#f07178} pkgdown/inst/highlight-styles/arrow-dark.scss0000644000176200001440000000347214633374223021153 0ustar liggesuserspre code /* Normal */ {color:#f8f8f2} pre code span.al /* Alert */ {color:#f07178; background-color:#2a0f15; font-weight: bold} pre code span.an /* Annotation */ {color:#d4d0ab} pre code span.at /* Attribute */ {color:#00e0e0} pre code span.bn /* BaseN */ {color:#d4d0ab} pre code span.bu /* BuiltIn */ {color:#abe338} pre code span.cf /* ControlFlow */ {color:#ffa07a; font-weight: bold} pre code span.ch /* Char */ {color:#abe338} pre code span.cn /* Constant */ {color:#ffd700} pre code span.co /* Comment */ {color:#f8f8f2; font-style: italic} pre code span.cv /* CommentVar */ {color:#ffd700} pre code span.do /* Documentation */ {color:#f8f8f2} pre code span.dt /* DataType */ {color:#ffa07a} pre code span.dv /* DecVal */ {color:#d4d0ab} pre code span.er /* Error */ {color:#f07178; text-decoration: underline} pre code span.ex /* Extension */ {color:#00e0e0; font-weight: bold} pre code span.fl /* Float */ {color:#d4d0ab} pre code span.fu /* Function */ {color:#ffa07a} pre code span.im /* Import */ {color:#abe338} pre code span.in /* Information */ {color:#d4d0ab} pre code span.kw /* Keyword */ {color:#ffa07a; font-weight: bold} pre code span.op /* Operator */ {color:#ffa07a} pre code span.ot /* Other */ {color:#00e0e0} pre code span.pp /* Preprocessor */ {color:#dcc6e0} pre code span.re /* RegionMarker */ {color:#00e0e0; background-color:#f8f8f2} pre code span.sc /* SpecialChar */ {color:#abe338} pre code span.ss /* SpecialString */ {color:#abe338} pre code span.st /* String */ {color:#abe338} pre code span.va /* Variable */ {color:#00e0e0} pre code span.vs /* VerbatimString */ {color:#abe338} pre code span.wa /* Warning */ {color:#dcc6e0} pkgdown/inst/highlight-styles/atom-one-dark.scss0000644000176200001440000000345014245770621021535 0ustar liggesuserspre code /* Normal */ {color:#abb2bf} pre code span.al /* Alert */ {color:#95da4c; background-color:#4d1f24; font-weight: bold} pre code span.an /* Annotation */ {color:#98c379} pre code span.at /* Attribute */ {color:#c678dd} pre code span.bn /* BaseN */ {color:#d19a66} pre code span.bu /* BuiltIn */ {color:#c678dd} pre code span.cf /* ControlFlow */ {color:#c678dd} pre code span.ch /* Char */ {color:#98c379} pre code span.cn /* Constant */ {color:#d19a66} pre code span.co /* Comment */ {color:#5c6370; font-style: italic} pre code span.cv /* CommentVar */ {color:#e06c75; font-style: italic} pre code span.do /* Documentation */ {color:#a43340} pre code span.dt /* DataType */ {color:#c678dd} pre code span.dv /* DecVal */ {color:#d19a66} pre code span.er /* Error */ {color:#f44747; text-decoration: underline} pre code span.ex /* Extension */ {color:#61afef; font-weight: bold} pre code span.fl /* Float */ {color:#d19a66} pre code span.fu /* Function */ {color:#61afef} pre code span.im /* Import */ {color:#98c379} pre code span.in /* Information */ {color:#c45b00} pre code span.kw /* Keyword */ {color:#c678dd} pre code span.op /* Operator */ {color:#c678dd} pre code span.ot /* Others */ {color:#27ae60} pre code span.pp /* Preprocessor */ {color:#c678dd} pre code span.re /* RegionMarker */ {color:#2980b9; background-color:#153042} pre code span.sc /* SpecialChar */ {color:#56b6c2} pre code span.ss /* SpecialString */ {color:#da4453} pre code span.st /* String */ {color:#98c379} pre code span.va /* Variable */ {color:#e06c75} pre code span.vs /* VerbatimString */ {color:#da4453} pre code span.wa /* Warning */ {color:#da4453} pkgdown/inst/highlight-styles/solarized-dark.scss0000644000176200001440000000343314134110660021777 0ustar liggesuserspre {background-color: #002b36;} pre code /* Normal */ {color:#839496} pre code span.al /* Alert */ {color:#d33682; font-weight: bold} pre code span.an /* Annotation */ {color:#268bd2} pre code span.at /* Attribute */ {color:#268bd2} pre code span.bn /* BaseN */ {color:#2aa198} pre code span.bu /* BuiltIn */ {color:#cb4b16} pre code span.cf /* ControlFlow */ {color:#859900} pre code span.ch /* Char */ {color:#2aa198} pre code span.cn /* Constant */ {color:#2aa198; font-weight: bold} pre code span.co /* Comment */ {color:#586e75; font-style: italic} pre code span.cv /* CommentVar */ {color:#2aa198} pre code span.do /* Documentation */ {color:#dc322f} pre code span.dt /* DataType */ {color:#b58900} pre code span.dv /* DecVal */ {color:#2aa198} pre code span.er /* Error */ {color:#dc322f; text-decoration: underline} pre code span.ex /* Extension */ {color:#268bd2} pre code span.fl /* Float */ {color:#2aa198} pre code span.fu /* Function */ {color:#268bd2} pre code span.im /* Import */ {color:#2aa198} pre code span.in /* Information */ {color:#b58900} pre code span.kw /* Keyword */ {color:#859900} pre code span.op /* Operator */ {color:#859900} pre code span.ot /* Others */ {color:#859900} pre code span.pp /* Preprocessor */ {color:#cb4b16} pre code span.re /* RegionMarker */ {color:#268bd2; background-color:#073642} pre code span.sc /* SpecialChar */ {color:#dc322f} pre code span.ss /* SpecialString */ {color:#dc322f} pre code span.st /* String */ {color:#2aa198} pre code span.va /* Variable */ {color:#268bd2} pre code span.vs /* VerbatimString */ {color:#2aa198} pre code span.wa /* Warning */ {color:#cb4b16} pkgdown/inst/highlight-styles/solarized-light.scss0000644000176200001440000000354714134110660022173 0ustar liggesuserspre {background-color: #fdf6e3;} pre code /* Normal */ {color:#657b83} pre code span.al /* Alert */ {color:#d33682; font-weight: bold} pre code span.an /* Annotation */ {color:#268bd2} pre code span.at /* Attribute */ {color:#268bd2} pre code span.bn /* BaseN */ {color:#2aa198} pre code span.bu /* BuiltIn */ {color:#cb4b16} pre code span.cf /* ControlFlow */ {color:#859900; font-weight: bold} pre code span.ch /* Char */ {color:#2aa198} pre code span.cn /* Constant */ {color:#2aa198; font-weight: bold} pre code span.co /* Comment */ {color:#93a1a1; font-style: italic} pre code span.cv /* CommentVar */ {color:#2aa198} pre code span.do /* Documentation */ {color:#dc322f} pre code span.dt /* DataType */ {color:#b58900; font-weight: bold} pre code span.dv /* DecVal */ {color:#2aa198} pre code span.er /* Error */ {color:#dc322f; text-decoration: underline} pre code span.ex /* Extension */ {color:#268bd2; font-weight: bold} pre code span.fl /* Float */ {color:#2aa198} pre code span.fu /* Function */ {color:#268bd2} pre code span.im /* Import */ {color:#2aa198} pre code span.in /* Information */ {color:#b58900} pre code span.kw /* Keyword */ {color:#859900; font-weight: bold} pre code span.op /* Operator */ {color:#859900} pre code span.ot /* Others */ {color:#859900} pre code span.pp /* Preprocessor */ {color:#cb4b16} pre code span.re /* RegionMarker */ {color:#268bd2; background-color:#eee8d5} pre code span.sc /* SpecialChar */ {color:#dc322f} pre code span.ss /* SpecialString */ {color:#dc322f} pre code span.st /* String */ {color:#2aa198} pre code span.va /* Variable */ {color:#268bd2} pre code span.vs /* VerbatimString */ {color:#2aa198} pre code span.wa /* Warning */ {color:#cb4b16} pkgdown/README.md0000644000176200001440000000715414671045013013212 0ustar liggesusers # pkgdown CRAN Status R-CMD-check [![Codecov test coverage](https://codecov.io/gh/r-lib/pkgdown/branch/main/graph/badge.svg)](https://app.codecov.io/gh/r-lib/pkgdown?branch=main) pkgdown is designed to make it quick and easy to build a website for your package. You can see pkgdown in action at : this is the output of pkgdown applied to the latest version of pkgdown. Learn more in `vignette("pkgdown")` or `?build_site`. ## Installation
    ``` r # Install released version from CRAN install.packages("pkgdown") ```
    ``` r # Install development version from GitHub # install.packages("pak") pak::pak("r-lib/pkgdown") ```
    ## Usage Get started with [usethis](https://usethis.r-lib.org/): ``` r # Run once to configure your package to use and deploy pkgdown usethis::use_pkgdown_github_pages() ``` ``` r # Preview your site locally before publishing pkgdown::build_site() ``` This adds the necessary components and sets up GitHub Actions[^1] for automatic site building when deploying. Your `README.md` becomes the homepage, documentation in `man/` generates a function reference, and vignettes will be rendered into `articles/`. ### pkgdown 2.0.0 and Bootstrap 5 pkgdown 2.0.0 includes an upgrade from Bootstrap 3 to Bootstrap 5, which is accompanied by a whole bunch of minor UI improvements. If you’ve heavily customised your site, there’s a small chance that this will break your site, so everyone needs to explicitly opt-in to the upgrade by adding the following to `_pkgdown.yml`: ``` yaml template: bootstrap: 5 ``` Then learn about the many new ways to customise your site in `vignette("customise")`. ## In the wild At last count, pkgdown is used [by over 12,000 packages](https://github.com/search?q=path%3A_pkgdown.yml+language%3AYAML&type=code&l=YAML). Here are a few examples: - [bayesplot](http://mc-stan.org/bayesplot/index.html) ([source](https://github.com/stan-dev/bayesplot/tree/gh-pages)): plotting functions for posterior analysis, model checking, and MCMC diagnostics. - [valr](https://rnabioco.github.io/valr/) ([source](https://github.com/rnabioco/valr)): read and manipulate genome intervals and signals. - [mkin](https://pkgdown.jrwb.de/mkin/) ([source](https://github.com/jranke/mkin)): calculation routines based on the FOCUS Kinetics Report - [NMF](http://renozao.github.io/NMF/master/index.html) ([source](https://github.com/renozao/NMF)): a framework to perform non-negative matrix factorization (NMF). - [tidyverse and r-lib packages source](https://github.com/search?q=path%3A%22_pkgdown.yml%22+AND+%28org%3Atidyverse+OR+org%3Ar-lib%29&type=code) Comparing the source and output of these sites is a great way to learn new pkgdown techniques. ## Code of conduct Please note that this project is released with a [Contributor Code of Conduct](https://pkgdown.r-lib.org/CODE_OF_CONDUCT.html). By participating in this project you agree to abide by its terms. [^1]: If you don’t use GitHub, you can use `usethis::use_pkgdown()` + `pkgdown::build_site()` to create a website. pkgdown/build/0000755000176200001440000000000014672347611013035 5ustar liggesuserspkgdown/build/vignette.rds0000644000176200001440000000064114672347611015375 0ustar liggesusersRMS0,P*c@ 806B6$͟IL!rࢇ&do]ڰƍ--;v=FӚhn#2md5CR桑aab š.V\,Om"@(*tB B#ɨ2rHU@0xVfݣ̉ P"pSYN/N[> dEF#%|`0}jҤ۹^|jvlF-lFԻi<ό䶡0&{+ C1Ug"r9̰/ Ӯop嶅-*?͎ y~u9j $6ƴ?-[{XwV]?>}M]lv4]ݸ*QZ$Yd'BEeW) Wds{8957F-a9U#'%) @7R@zCfQ^)uo}TAi X%EJ搫LQFC -_@fn9CoQjVRؚE9!9(5v)2+a)jlpk52};Z\f ބOVicV8:|=]3# | 3B-c&) BBGG^\@@_JEor7)6p@2-4#ayBWOΌYWO D5ׁ:,=X4D]K}zѠ( i(I҆4>(JP %JbpŬ߱2XW,Mj#pQ,!0 j t§c o$qQ1H +ߋF eӜ"P1HhtPS/<ቇ* K@ [JFՒm BǸQ](ո6ԙťnTk@/n•"@aqX(,K"@aBaQ`M1M-P*0 KpK%HDП>'oP/HB7=D}pP{_K4teDj9QLCAms,RN "ېV@*>c !si!( W HeD`]H߮۲b1L Ix10QLKdtJ<ӓܳ'e X׵PXBO6/̔"#2))vC;{&=<# oFE4[ to!%b4r>-njUkj[%1 Fqs?6 ۻ;{/^J' є ^-6rpF1OcB%TaVRM-αʢ\}s\ rR 7PJy~? Q<'T^M;2q_ፇ+e# oMIxmW`\ wX_NRGpkgdown/man/0000755000176200001440000000000014672347601012510 5ustar liggesuserspkgdown/man/build_news.Rd0000644000176200001440000000545214634573316015142 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/build-news.R \name{build_news} \alias{build_news} \title{Build news section} \usage{ build_news(pkg = ".", override = list(), preview = FALSE) } \arguments{ \item{pkg}{Path to package.} \item{override}{An optional named list used to temporarily override values in \verb{_pkgdown.yml}} \item{preview}{If \code{TRUE}, or \code{is.na(preview) && interactive()}, will preview freshly generated section in browser.} } \description{ A \code{NEWS.md} will be broken up into versions using level one (\verb{#}) or level two headings (\verb{##}) that (partially) match one of the following forms (ignoring case): \itemize{ \item \verb{\{package name\} 1.3.0} \item \verb{\{package name\} v1.3.0} \item \verb{Version 1.3.0} \item \verb{Changes in 1.3.0} \item \verb{Changes in v1.3.0} } } \details{ A \href{https://style.tidyverse.org/news.html}{common structure} for news files is to use a top level heading for each release, and use a second level heading to break up individual bullets into sections. \if{html}{\out{
    }}\preformatted{# foofy 1.0.0 ## Major changes * Can now work with all grooveable grobbles! ## Minor improvements and bug fixes * Printing scrobbles no longer errors (@githubusername, #100) * Wibbles are now 55\% less jibbly (#200) }\if{html}{\out{
    }} Issues and contributors will be automatically linked to the corresponding pages on GitHub if the GitHub repo can be discovered from the \code{DESCRIPTION} (typically from a \code{URL} entry containing \code{github.com}) If a version is available on CRAN, the release date will automatically be added to the heading (see below for how to suppress); if not available on CRAN, "Unreleased" will be added. } \section{YAML config}{ To automatically link to release announcements, include a \code{releases} section. \if{html}{\out{
    }}\preformatted{news: releases: - text: "usethis 1.3.0" href: https://www.tidyverse.org/articles/2018/02/usethis-1-3-0/ - text: "usethis 1.0.0 (and 1.1.0)" href: https://www.tidyverse.org/articles/2017/11/usethis-1.0.0/ }\if{html}{\out{
    }} Control whether news is present on one page or multiple pages with the \code{one_page} field. The default is \code{true}. \if{html}{\out{
    }}\preformatted{news: one_page: false }\if{html}{\out{
    }} Suppress the default addition of CRAN release dates with: \if{html}{\out{
    }}\preformatted{news: cran_dates: false }\if{html}{\out{
    }} } \seealso{ \href{https://style.tidyverse.org/news.html}{Tidyverse style for News} Other site components: \code{\link{build_articles}()}, \code{\link{build_home}()}, \code{\link{build_reference}()}, \code{\link{build_tutorials}()} } \concept{site components} pkgdown/man/test-verbatim.Rd0000644000176200001440000000254114633374223015564 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/test.R \name{test-verbatim} \alias{test-verbatim} \title{Test case: preformatted blocks & syntax highlighting} \description{ Manual test cases for various ways of embedding code in sections. All code blocks should have copy and paste button. } \section{Should be highlighted}{ Valid R code in \verb{\preformatted{}}: \if{html}{\out{
    }}\preformatted{mean(a + 1) }\if{html}{\out{
    }} R code in \code{R} block: \if{html}{\out{
    }}\preformatted{mean(a + 1) }\if{html}{\out{
    }} R code in \code{r} block: \if{html}{\out{
    }}\preformatted{mean(a + 1) }\if{html}{\out{
    }} Yaml \if{html}{\out{
    }}\preformatted{yaml: [a, 1] }\if{html}{\out{
    }} } \section{Shouldn't be highlighted}{ Non-R code in \verb{\preformatted{}} \if{html}{\out{
    }}\preformatted{yaml: [a, b, c] }\if{html}{\out{
    }} } \seealso{ Other tests: \code{\link{index}}, \code{\link{test-crayon}}, \code{\link{test-dont}}, \code{\link{test-figures}}, \code{\link{test-links}}, \code{\link{test-lists}}, \code{\link{test-long-lines}}, \code{\link{test-output-styles}}, \code{\link{test-params}}, \code{\link{test-sexpr-title}}, \code{\link{test-tables}} } \concept{tests} \keyword{internal} pkgdown/man/test-lists.Rd0000644000176200001440000000372314633374223015114 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/test.R \name{test-lists} \alias{test-lists} \title{Test case: lists} \description{ \subsection{Bulleted list}{ \itemize{ \item a \item This is an item... That spans multiple paragraphs. } } \subsection{Bulleted list (single item)}{ \itemize{\item a} } \subsection{Numbered list}{ \enumerate{ \item a \item b } } \subsection{Definition list}{ \describe{ \item{short}{short} \item{short}{Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.} \item{Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.}{short} \item{Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.}{Lorem ipsum adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.} } } } \seealso{ Other tests: \code{\link{index}}, \code{\link{test-crayon}}, \code{\link{test-dont}}, \code{\link{test-figures}}, \code{\link{test-links}}, \code{\link{test-long-lines}}, \code{\link{test-output-styles}}, \code{\link{test-params}}, \code{\link{test-sexpr-title}}, \code{\link{test-tables}}, \code{\link{test-verbatim}} } \concept{tests} \keyword{internal} pkgdown/man/build_home.Rd0000644000176200001440000002655114634573316015121 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/build-home.R, R/build-home-index.R \name{build_home} \alias{build_home} \alias{build_home_index} \title{Build home section} \usage{ build_home(pkg = ".", override = list(), preview = FALSE, quiet = TRUE) build_home_index(pkg = ".", override = list(), quiet = TRUE) } \arguments{ \item{pkg}{Path to package.} \item{override}{An optional named list used to temporarily override values in \verb{_pkgdown.yml}} \item{preview}{If \code{TRUE}, or \code{is.na(preview) && interactive()}, will preview freshly generated section in browser.} \item{quiet}{Set to \code{FALSE} to display output of knitr and pandoc. This is useful when debugging.} } \description{ \code{build_home()} function generates pages at the top-level of the site including: \itemize{ \item The home page \item HTML files from any \code{.md} files in \verb{./} or \verb{.github/}. \item The authors page (from \code{DESCRIPTION}) \item The citation page (from \code{inst/CITATION}, if present). \item The license page \item A default 404 page if \verb{.github/404.md} is not found. } \code{build_home_index()} rebuilds just the index page; it's useful for rapidly iterating when experimenting with site styles. } \section{Home page}{ The main content of the home page (\code{index.html}) is generated from \code{pkgdown/index.md}, \code{index.md}, or \code{README.md}, in that order. Most packages will use \code{README.md} because that's also displayed by GitHub and CRAN. Use \code{index.md} if you want your package website to look different to your README, and use \code{pkgdown/index.md} if you don't want that file to live in your package root directory. If you use \code{index.Rmd} or \code{README.Rmd} it's your responsibility to knit the document to create the corresponding \code{.md}. pkgdown does not do this for you because it only touches files in the \verb{doc/} directory. Extra markdown files in the base directory (e.g. \code{ROADMAP.md}) or in \verb{.github/} (e.g. \code{CODE_OF_CONDUCT.md}) are copied by \code{build_home()} to \verb{docs/} and converted to HTML. The home page also features a sidebar with information extracted from the package. You can tweak it via the configuration file, to help make the home page an as informative as possible landing page. \subsection{Images and figures}{ If you want to include images in your \code{README.md}, they must be stored somewhere in the package so that they can be displayed on the CRAN website. The best place to put them is \code{man/figures}. If you are generating figures with R Markdown, make sure you set up \code{fig.path} as followed: \if{html}{\out{
    }}\preformatted{knitr::opts_chunk$set( fig.path = "man/figures/" ) }\if{html}{\out{
    }} This should usually go in a chunk with \code{include = FALSE}. \if{html}{\out{
    }}\preformatted{```\{r chunk-name, include=FALSE\}`r ''` knitr::opts_chunk$set( fig.path = "man/figures/" ) ``` }\if{html}{\out{
    }} } \subsection{Package logo}{ If you have a package logo, you can include it at the top of your README in a level-one heading: \if{html}{\out{
    }}\preformatted{# pkgdown }\if{html}{\out{
    }} \code{\link[=init_site]{init_site()}} will also automatically create a favicon set from your package logo. } \subsection{YAML config - title and description}{ By default, the page title and description are extracted automatically from the \code{Title} and \code{Description} fields \code{DESCRIPTION} (stripping single quotes off quoted words). CRAN ensures that these fields don't contain phrases like "R package" because that's obvious on CRAN. To make your package more findable on search engines, it's good practice to override the \code{title} and \code{description}, thinking about what people might search for: \if{html}{\out{
    }}\preformatted{home: title: An R package for pool-noodle discovery description: > Do you love R? Do you love pool-noodles? If so, you might enjoy using this package to automatically discover and add pool-noodles to your growing collection. }\if{html}{\out{
    }} (Note the use of YAML's \code{>} i.e. "YAML pipes"; this is a convenient way of writing paragraphs of text.) } \subsection{Dev badges}{ pkgdown identifies badges in three ways: \itemize{ \item Any image-containing links between \verb{} and \verb{}, as e.g. created by \code{usethis::use_readme_md()} or \code{usethis::use_readme_rmd()}. There should always be an empty line after the \verb{} line. If you divide badges into paragraphs, make sure to add an empty line before the \verb{} line. \item Any image-containing links within \verb{
    }. \item Within the first paragraph, if it only contains image-containing links. } Identified badges are \strong{removed} from the \emph{main content}. They are shown or not in the \emph{sidebar} depending on the development mode and sidebar customization, see the sidebar section. } } \section{Authors}{ By default, pkgdown will display author information in three places: \itemize{ \item the sidebar, \item the left part side of the footer, \item the author page. } This documentation describes how to customise the overall author display. See \code{?build_home} and \code{?build_site} for details about changing the location of the authors information within the home sidebar and the site footer. \subsection{Authors ORCID and bio}{ Author ORCID identification numbers in the \code{DESCRIPTION} are linked using the ORCID logo: \if{html}{\out{
    }}\preformatted{Authors@R: c( person("Hadley", "Wickham", , "hadley@rstudio.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0003-4757-117X") ), person("Jay", "Hesselberth", role = "aut", comment = c(ORCID = "0000-0002-6299-179X") ) ) }\if{html}{\out{
    }} If you want to add more details about authors or their involvement with the package, you can use the comment field, which will be rendered on the authors page. \if{html}{\out{
    }}\preformatted{Authors@R: c( person("Hadley", "Wickham", , "hadley@rstudio.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0003-4757-117X", "Indenter-in-chief") ), person("Jay", "Hesselberth", role = "aut", comment = c(ORCID = "0000-0002-6299-179X") ) ) }\if{html}{\out{
    }} } \subsection{Additional control via YAML}{ You can control additinal aspects of the authors display via the \code{authors} YAML field: \itemize{ \item display of each author in the footer, sidebar and authors page, \item which authors (by role) are displayed in the sidebar and footer, \item text before authors in the footer, \item text before and after authors in the sidebar, \item text before and after authors on the authors page. } You can modify how each author's name is displayed by adding a subsection for \code{authors}. Each entry in \code{authors} should be named the author's name (matching \code{DESCRIPTION}) and can contain \code{href} and/or \code{html} fields: \itemize{ \item If \code{href} is provided, the author's name will be linked to this URL. \item If \code{html} is provided, it will be shown instead of the author's name. This is particularly useful if you want to display the logo of a corporate sponsor. Use an absolute URL to an image, not a relative link. Use an empty alternative text rather than no alternative text so a screen-reader would skip over it. } \if{html}{\out{
    }}\preformatted{authors: firstname lastname: href: "http://name-website.com" html: "" }\if{html}{\out{
    }} By default, the "developers" list shown in the sidebar and footer is populated by the maintainer ("cre"), authors ("aut"), and funder ("fnd") from the \code{DESCRIPTION}. You could choose other roles for filtering. With the configuration below: \itemize{ \item only the maintainer and funder(s) appear in the footer, after the text "Crafted by", \item all authors and contributors appear in the sidebar, \item the authors list on the sidebar is preceded and followed by some text, \item the authors list on the authors page is preceded and followed by some text. } \if{html}{\out{
    }}\preformatted{authors: footer: roles: [cre, fnd] text: "Crafted by" sidebar: roles: [aut, ctb] before: "So *who* does the work?" after: "Thanks all!" before: "This package is proudly brought to you by:" after: "See the [changelog](news/index.html) for other contributors. :pray:" }\if{html}{\out{
    }} If you want to filter authors based on something else than their roles, consider using a custom sidebar/footer component (see \code{?build_home}/\code{?build_site}, respectively). } } \section{Sidebar}{ You can customise the homepage sidebar with the \code{home.sidebar} field. It's made up of two pieces: \code{structure}, which defines the overall layout, and \code{components}, which defines what each piece looks like. This organisation makes it easy to mix and match the pkgdown defaults with your own customisations. This is the default structure: \if{html}{\out{
    }}\preformatted{home: sidebar: structure: [links, license, community, citation, authors, dev] }\if{html}{\out{
    }} These are drawn from seven built-in components: \itemize{ \item \code{links}: automated links generated from \code{URL} and \code{BugReports} fields from \code{DESCRIPTION} plus manual links from the \code{home.links} field: \if{html}{\out{
    }}\preformatted{home: links: - text: Link text href: https://website.com - text: Roadmap href: /roadmap.html }\if{html}{\out{
    }} \item \code{license}: Licensing information if \code{LICENSE}/\code{LICENCE} or \code{LICENSE.md}/\code{LICENCE.md} files are present. \item \code{community}: links to to \code{.github/CONTRIBUTING.md}, \code{.github/CODE_OF_CONDUCT.md}, etc. \item \code{citation}: link to package citation information. Uses either \code{inst/CITATION} or, if absent, information from the \code{DESCRIPTION}. \item \code{authors}: selected authors from the \code{DESCRIPTION}. \item \code{dev}: development status badges extracted from \code{README.md}/\code{index.md}. This is only shown for "development" versions of websites; see "Development mode" in \code{?build_site} for details. \item \code{toc}: a table of contents for the README (not shown by default). } You can also add your own components, where \code{text} is markdown text: \if{html}{\out{
    }}\preformatted{home: sidebar: structure: [authors, custom, toc, dev] components: custom: title: Funding text: We are *grateful* for funding! }\if{html}{\out{
    }} Alternatively, you can provide a ready-made sidebar HTML: \if{html}{\out{
    }}\preformatted{home: sidebar: html: path-to-sidebar.html }\if{html}{\out{
    }} Or completely remove it: \if{html}{\out{
    }}\preformatted{home: sidebar: FALSE }\if{html}{\out{
    }} } \seealso{ Other site components: \code{\link{build_articles}()}, \code{\link{build_news}()}, \code{\link{build_reference}()}, \code{\link{build_tutorials}()} } \concept{site components} pkgdown/man/autolink_html.Rd0000644000176200001440000000171014634573316015652 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/autolink_html.R \name{autolink_html} \alias{autolink_html} \title{Automatically link references and articles in an HTML page} \usage{ autolink_html(input, output = input, local_packages = character()) } \arguments{ \item{input, output}{Input and output paths for HTML file} \item{local_packages}{A named character vector providing relative paths (value) to packages (name) that can be reached with relative links from the target HTML document.} } \description{ \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Please use \code{\link[downlit:downlit_html_path]{downlit::downlit_html_path()}} instead. } \examples{ \dontrun{ autolink_html("path/to/file.html", local_packages = c( shiny = "shiny", shinydashboard = "shinydashboard" ) ) } } \keyword{internal} pkgdown/man/as_pkgdown.Rd0000644000176200001440000000102714605012704015120 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/package.R \name{as_pkgdown} \alias{as_pkgdown} \title{Generate pkgdown data structure} \usage{ as_pkgdown(pkg = ".", override = list()) } \arguments{ \item{pkg}{Path to package.} \item{override}{An optional named list used to temporarily override values in \verb{_pkgdown.yml}} } \description{ You will generally not need to use this unless you need a custom site design and you're writing your own equivalent of \code{\link[=build_site]{build_site()}}. } pkgdown/man/fig_settings.Rd0000644000176200001440000000152214633374223015461 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/figure.R \name{fig_settings} \alias{fig_settings} \title{Get current settings for figures} \usage{ fig_settings() } \value{ A list containing the entries from the \code{figures} field in \verb{_pkgdown.yml} (see \code{\link[=build_reference]{build_reference()}}), with default values added. Computed \code{width} and \code{height} values (in pixels) are also included. } \description{ You will generally not need to use this function unless you are handling custom plot output. Packages needing custom parameters should ask users to place them within the \code{other.parameters} entry under the package name, e.g. \if{html}{\out{
    }}\preformatted{figures: other.parameters: rgl: fig.asp: 1 }\if{html}{\out{
    }} } \keyword{internal} pkgdown/man/build_redirects.Rd0000644000176200001440000000253214633374223016141 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/build-redirects.R \name{build_redirects} \alias{build_redirects} \title{Build redirects} \usage{ build_redirects(pkg = ".", override = list()) } \arguments{ \item{pkg}{Path to package.} \item{override}{An optional named list used to temporarily override values in \verb{_pkgdown.yml}} } \description{ If you change the structure of your documentation (by renaming vignettes or help topics) you can setup redirects from the old content to the new content. One or several now-absent pages can be redirected to a new page (or to a new section of a new page). This works by creating a html page that performs a "meta refresh", which isn't the best way of doing a redirect but works everywhere that you might deploy your site. The syntax is the following, with old paths on the left, and new paths or URLs on the right. \if{html}{\out{
    }}\preformatted{redirects: - ["articles/old-vignette-name.html", "articles/new-vignette-name.html"] - ["articles/another-old-vignette-name.html", "articles/new-vignette-name.html"] - ["articles/yet-another-old-vignette-name.html", "https://pkgdown.r-lib.org/dev"] }\if{html}{\out{
    }} If for some reason you choose to redirect an existing page make sure to exclude it from the search index, see \code{?build_search}. } pkgdown/man/clean.Rd0000644000176200001440000000072614645463761014074 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/clean.R \name{clean_site} \alias{clean_site} \alias{clean_cache} \title{Clean site} \usage{ clean_site(pkg = ".", quiet = FALSE) clean_cache(pkg = ".", quiet = FALSE) } \arguments{ \item{pkg}{Path to package.} \item{quiet}{If \code{TRUE}, suppresses a message.} } \description{ Delete all files in \verb{docs/} (except for \code{CNAME}). Delete all files in the pkgdown cache directory. } pkgdown/man/build_favicons.Rd0000644000176200001440000000205514634573316015772 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/build-favicons.R \name{build_favicons} \alias{build_favicons} \title{Initialise favicons from package logo} \usage{ build_favicons(pkg = ".", overwrite = FALSE) } \arguments{ \item{pkg}{Path to package.} \item{overwrite}{If \code{TRUE}, re-create favicons from package logo.} } \description{ This function auto-detects the location of your package logo (with the name \code{logo.svg} (recommended format) or \code{logo.png}, created with \code{usethis::use_logo()}) and runs it through the \url{https://realfavicongenerator.net} API to build a complete set of favicons with different sizes, as needed for modern web usage. You only need to run the function once. The favicon set will be stored in \code{pkgdown/favicon} and copied by \code{\link[=init_site]{init_site()}} to the relevant location when the website is rebuilt. Once complete, you should add \verb{pkgdown/} to \code{.Rbuildignore } to avoid a NOTE during package checking. (\code{usethis::use_logo()} does this for you!) } pkgdown/man/check_pkgdown.Rd0000644000176200001440000000150714633374223015605 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/check.R \name{check_pkgdown} \alias{check_pkgdown} \alias{pkgdown_sitrep} \title{Check \verb{_pkgdown.yml}} \usage{ check_pkgdown(pkg = ".") pkgdown_sitrep(pkg = ".") } \arguments{ \item{pkg}{Path to package.} } \description{ This pair of functions checks that your \verb{_pkgdown.yml} is valid without building the whole site. \code{check_pkgdown()} errors at the first problem; \code{pkgdown_sitrep()} reports the status of all checks. Currently they check that: \itemize{ \item There's a \code{url} in the pkgdown configuration, which is also recorded in the \code{URL} field of the \code{DESCRIPTION}. \item All opengraph metadata is valid. \item All reference topics are included in the index. \item All articles/vignettes are included in the index. } } pkgdown/man/deploy_site_github.Rd0000644000176200001440000000414514151771664016667 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/deploy-site.R \name{deploy_site_github} \alias{deploy_site_github} \title{Deploy a pkgdown site on Travis-CI to Github Pages} \usage{ deploy_site_github( pkg = ".", install = TRUE, tarball = Sys.getenv("PKG_TARBALL", ""), ssh_id = Sys.getenv("id_rsa", ""), commit_message = construct_commit_message(pkg), clean = FALSE, verbose = FALSE, host = "github.com", ..., repo_slug = Sys.getenv("TRAVIS_REPO_SLUG", "") ) } \arguments{ \item{pkg}{Path to package.} \item{install}{Optionally, opt-out of automatic installation. This is necessary if the package you're documenting is a dependency of pkgdown} \item{tarball}{The location of the built package tarball. The default Travis configuration for R packages sets \code{PKG_TARBALL} to this path.} \item{ssh_id}{The private id to use, a base64 encoded content of the private pem file. This should \emph{not} be your personal private key. Instead create a new keypair specifically for deploying the site. The easiest way is to use \code{travis::use_travis_deploy()}.} \item{commit_message}{The commit message to be used for the commit.} \item{clean}{Clean all files from old site.} \item{verbose}{Print verbose output} \item{host}{The GitHub host url.} \item{...}{Additional arguments passed to \code{\link[=build_site]{build_site()}}.} \item{repo_slug}{The \code{user/repo} slug for the repository.} } \description{ \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#superseded}{\figure{lifecycle-superseded.svg}{options: alt='[Superseded]'}}}{\strong{[Superseded]}} \code{deploy_site_github()} was designed to deploy your site from Travis CI, which we no longer recommend, so this function is deprecated. There are two replacements: \itemize{ \item \code{\link[usethis:use_pkgdown]{usethis::use_pkgdown_github_pages()}} will setup a GitHub action to automatically build and deploy your package website to GitHub pages. \item \code{\link[=deploy_to_branch]{deploy_to_branch()}} can be called locally to build and deploy your website to any desired branch. } } \keyword{internal} pkgdown/man/init_site.Rd0000644000176200001440000000300614634573316014767 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/init.R \name{init_site} \alias{init_site} \title{Initialise site infrastructure} \usage{ init_site(pkg = ".", override = list()) } \arguments{ \item{pkg}{Path to package.} \item{override}{An optional named list used to temporarily override values in \verb{_pkgdown.yml}} } \description{ \code{init_site()}: \itemize{ \item creates the output directory (\verb{docs/}), \item generates a machine readable description of the site, used for autolinking, \item copies CSS/JS assets and extra files, and \item runs \code{build_favicons()}, if needed. } Typically, you will not need to call this function directly, as all \verb{build_*()} functions will run \code{init_site()} if needed. The only good reasons to call \code{init_site()} directly are the following: \itemize{ \item If you add or modify a package logo. \item If you add or modify \code{pkgdown/extra.scss}. \item If you modify \code{template.bslib} variables in \verb{_pkgdown.yml}. } See \code{vignette("customise")} for the various ways you can customise the display of your site. } \section{Build-ignored files}{ We recommend using \code{\link[usethis:use_pkgdown]{usethis::use_pkgdown_github_pages()}} to build-ignore \verb{docs/} and \verb{_pkgdown.yml}. If use another directory, or create the site manually, you'll need to add them to \code{.Rbuildignore} yourself. A \code{NOTE} about an unexpected file during \verb{R CMD CHECK} is an indication you have not correctly ignored these files. } pkgdown/man/test-crayon.Rd0000644000176200001440000000132714633374223015247 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/test.R \name{test-crayon} \alias{test-crayon} \title{Test case: crayon} \description{ Test case: crayon } \examples{ cat(cli::col_red("This is red"), "\n") cat(cli::col_blue("This is blue"), "\n") message(cli::col_green("This is green")) warning(cli::style_bold("This is bold")) } \seealso{ Other tests: \code{\link{index}}, \code{\link{test-dont}}, \code{\link{test-figures}}, \code{\link{test-links}}, \code{\link{test-lists}}, \code{\link{test-long-lines}}, \code{\link{test-output-styles}}, \code{\link{test-params}}, \code{\link{test-sexpr-title}}, \code{\link{test-tables}}, \code{\link{test-verbatim}} } \concept{tests} \keyword{internal} pkgdown/man/index.Rd0000644000176200001440000000103314633374223014100 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/test.R \name{index} \alias{index} \alias{test-index} \title{Index} \description{ Index } \seealso{ Other tests: \code{\link{test-crayon}}, \code{\link{test-dont}}, \code{\link{test-figures}}, \code{\link{test-links}}, \code{\link{test-lists}}, \code{\link{test-long-lines}}, \code{\link{test-output-styles}}, \code{\link{test-params}}, \code{\link{test-sexpr-title}}, \code{\link{test-tables}}, \code{\link{test-verbatim}} } \concept{tests} \keyword{internal} pkgdown/man/build_articles.Rd0000644000176200001440000002420514634573316015771 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/build-articles.R, R/build-article.R \name{build_articles} \alias{build_articles} \alias{build_article} \alias{build_articles_index} \title{Build articles section} \usage{ build_articles( pkg = ".", quiet = TRUE, lazy = TRUE, seed = 1014L, override = list(), preview = FALSE ) build_article( name, pkg = ".", lazy = FALSE, seed = 1014L, new_process = TRUE, pandoc_args = character(), override = list(), quiet = TRUE ) build_articles_index(pkg = ".", override = list()) } \arguments{ \item{pkg}{Path to package.} \item{quiet}{Set to \code{FALSE} to display output of knitr and pandoc. This is useful when debugging.} \item{lazy}{If \code{TRUE}, will only re-build article if input file has been modified more recently than the output file.} \item{seed}{Seed used to initialize random number generation in order to make article output reproducible. An integer scalar or \code{NULL} for no seed.} \item{override}{An optional named list used to temporarily override values in \verb{_pkgdown.yml}} \item{preview}{If \code{TRUE}, or \code{is.na(preview) && interactive()}, will preview freshly generated section in browser.} \item{name}{Name of article to render. This should be either a path relative to \verb{vignettes/} without extension, or \code{index} or \code{README}.} \item{new_process}{Build the article in a clean R process? The default, \code{TRUE}, ensures that every article is build in a fresh environment, but you may want to set it to \code{FALSE} to make debugging easier.} \item{pandoc_args}{Pass additional arguments to pandoc. Used for testing.} } \description{ \code{build_articles()} renders each R Markdown file underneath \verb{vignettes/} and saves it to \verb{articles/}. There are two exceptions: \itemize{ \item Files that start with \verb{_} (e.g., \verb{_index.Rmd}) are ignored, enabling the use of child documents. \item Files in \code{vignettes/tutorials} are handled by \code{\link[=build_tutorials]{build_tutorials()}} } Vignettes are rendered using a special document format that reconciles \code{\link[rmarkdown:html_document]{rmarkdown::html_document()}} with the pkgdown template. This means articles behave slightly differently to vignettes, particularly with respect to external files, and custom output formats. See below for more details. Note that when you run \code{build_articles()} directly (outside of \code{\link[=build_site]{build_site()}}) vignettes will use the currently installed version of the package, not the current source version. This makes iteration quicker when you are primarily working on the text of an article. } \section{Index and navbar}{ You can control the articles index and navbar with a \code{articles} field in your \verb{_pkgdown.yml}. If you use it, pkgdown will check that all articles are included, and will error if you have missed any. The \code{articles} field defines a list of sections, each of which can contain four fields: \itemize{ \item \code{title} (required): title of section, which appears as a heading on the articles index. \item \code{desc} (optional): An optional markdown description displayed underneath the section title. \item \code{navbar} (optional): A couple of words used to label this section in the navbar. If omitted, this section of vignettes will not appear in the navbar. \item \code{contents} (required): a list of article names to include in the section. This can either be names of individual vignettes or a call to \code{starts_with()}. The name of a vignette includes its path under \code{vignettes} without extension so that the name of the vignette found at \code{vignettes/pizza/slice.Rmd} is \code{pizza/slice}. } The title and description of individual vignettes displayed on the index comes from \code{title} and \code{description} fields of the YAML header in the Rmds. For example, this yaml might be used for some version of dplyr: \if{html}{\out{
    }}\preformatted{articles: - title: Main verbs navbar: ~ contents: - one-table - two-table - rowwise - colwise - title: Developer desc: Vignettes aimed at package developers contents: - programming - packages }\if{html}{\out{
    }} Note the use of the \code{navbar} fields. \verb{navbar: ~} means that the "Main verbs" will appear in the navbar without a heading; the absence of the \code{navbar} field in the developer vignettes means that they will only be accessible via the articles index. The navbar will include a link to the articles index if one or more vignettes are not available through the navbar. If some vignettes appear in the navbar drop-down list and others do not, the list will automatically include a "More ..." link at the bottom; if no vignettes appear in the the navbar, it will link directly to the articles index instead of providing a drop-down. \subsection{Get started}{ Note that a vignette with the same name as the package (e.g., \code{vignettes/pkgdown.Rmd} or \code{vignettes/articles/pkgdown.Rmd}) automatically becomes a top-level "Get started" link, and will not appear in the articles drop-down. (If your package name includes a \code{.}, e.g. \code{pack.down}, use a \code{-} in the vignette name, e.g. \code{pack-down.Rmd}.) } \subsection{Missing articles}{ pkgdown will warn if there are (non-internal) articles that aren't listed in the articles index. You can suppress such warnings by listing the affected articles in a section with \code{title: internal} (case sensitive); this section will not be displayed on the index page. } \subsection{External articles}{ You can link to arbitrary additional articles by adding an \code{external-articles} entry to \verb{_pkgdown.yml}. It should contain an array of objects with fields \code{name}, \code{title}, \code{href}, and \code{description}. \if{html}{\out{
    }}\preformatted{external-articles: - name: subsampling title: Subsampling for Class Imbalances description: Improve model performance in imbalanced data sets through undersampling or oversampling. href: https://www.tidymodels.org/learn/models/sub-sampling/ }\if{html}{\out{
    }} If you've defined a custom articles index, you'll need to include the name in one of the \code{contents} fields. } } \section{External files}{ pkgdown differs from base R in its handling of external files. When building vignettes, R assumes that vignettes are self-contained (a reasonable assumption when most vignettes were PDFs) and only copies files explicitly listed in \code{.install_extras}. pkgdown takes a different approach based on \code{\link[rmarkdown:find_external_resources]{rmarkdown::find_external_resources()}}, and it will also copy any images that you link to. If for some reason the automatic detection doesn't work, you will need to add a \code{resource_files} field to the yaml metadata, e.g.: \if{html}{\out{
    }}\preformatted{--- title: My Document resource_files: - data/mydata.csv - images/figure.png --- }\if{html}{\out{
    }} Note that you can not use the \code{fig.path} to change the output directory of generated figures as its default value is a strong assumption of rmarkdown. } \section{Embedding Shiny apps}{ If you would like to embed a Shiny app into an article, the app will have to be hosted independently, (e.g. \url{https://www.shinyapps.io}). Then, you can embed the app into your article using an \verb{