diff --git a/.lintr b/.lintr
index 34473d27..0a0bb22f 100644
--- a/.lintr
+++ b/.lintr
@@ -1,5 +1,6 @@
linters: linters_with_defaults(
line_length_linter = line_length_linter(120),
cyclocomp_linter = NULL,
- object_usage_linter = NULL
+ object_usage_linter = NULL,
+ indentation_linter = NULL
)
diff --git a/NEWS.md b/NEWS.md
index 17127b47..7471c1be 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,5 +1,9 @@
# teal.reporter 0.3.1.9001
+### Enhancements
+
+* Report cards are now included in bookmarks. When using the `shiny` bookmarking mechanism, present report cards will be available in the restored application.
+
# teal.reporter 0.3.1
### Enhancements
diff --git a/R/AddCardModule.R b/R/AddCardModule.R
index d5646d55..91825da2 100644
--- a/R/AddCardModule.R
+++ b/R/AddCardModule.R
@@ -88,125 +88,129 @@ add_card_button_srv <- function(id, reporter, card_fun) {
checkmate::assert_class(reporter, "Reporter")
checkmate::assert_subset(names(formals(card_fun)), c("card", "comment", "label"), empty.ok = TRUE)
- shiny::moduleServer(
- id,
- function(input, output, session) {
- ns <- session$ns
- add_modal <- function() {
- shiny::modalDialog(
- easyClose = TRUE,
- shiny::tags$h3("Add a Card to the Report"),
- shiny::tags$hr(),
- shiny::textInput(
- ns("label"),
- "Card Name",
- value = "",
- placeholder = "Add the card title here",
- width = "100%"
- ),
- shiny::textAreaInput(
- ns("comment"),
- "Comment",
- value = "",
- placeholder = "Add a comment here...",
- width = "100%"
- ),
- shiny::tags$script(
- shiny::HTML(
- sprintf(
- "
+ shiny::moduleServer(id, function(input, output, session) {
+ shiny::setBookmarkExclude(c(
+ "add_report_card_button", "download_button", "reset_reporter",
+ "add_card_ok", "download_data", "reset_reporter_ok",
+ "label", "comment"
+ ))
+
+ ns <- session$ns
+
+ add_modal <- function() {
+ shiny::modalDialog(
+ easyClose = TRUE,
+ shiny::tags$h3("Add a Card to the Report"),
+ shiny::tags$hr(),
+ shiny::textInput(
+ ns("label"),
+ "Card Name",
+ value = "",
+ placeholder = "Add the card title here",
+ width = "100%"
+ ),
+ shiny::textAreaInput(
+ ns("comment"),
+ "Comment",
+ value = "",
+ placeholder = "Add a comment here...",
+ width = "100%"
+ ),
+ shiny::tags$script(
+ shiny::HTML(
+ sprintf(
+ "
$('#shiny-modal').on('shown.bs.modal', () => {
$('#%s').focus()
})
",
- ns("label")
- )
+ ns("label")
)
+ )
+ ),
+ footer = shiny::div(
+ shiny::tags$button(
+ type = "button",
+ class = "btn btn-secondary",
+ `data-dismiss` = "modal",
+ `data-bs-dismiss` = "modal",
+ NULL,
+ "Cancel"
),
- footer = shiny::div(
- shiny::tags$button(
- type = "button",
- class = "btn btn-secondary",
- `data-dismiss` = "modal",
- `data-bs-dismiss` = "modal",
- NULL,
- "Cancel"
- ),
- shiny::tags$button(
- id = ns("add_card_ok"),
- type = "button",
- class = "btn btn-primary action-button",
- `data-val` = shiny::restoreInput(id = ns("add_card_ok"), default = NULL),
- NULL,
- "Add Card"
- )
+ shiny::tags$button(
+ id = ns("add_card_ok"),
+ type = "button",
+ class = "btn btn-primary action-button",
+ `data-val` = shiny::restoreInput(id = ns("add_card_ok"), default = NULL),
+ NULL,
+ "Add Card"
)
)
- }
-
- shiny::observeEvent(input$add_report_card_button, {
- shiny::showModal(add_modal())
- })
+ )
+ }
- # the add card button is disabled when clicked to prevent multi-clicks
- # please check the ui part for more information
- shiny::observeEvent(input$add_card_ok, {
- card_fun_args_nams <- names(formals(card_fun))
- has_card_arg <- "card" %in% card_fun_args_nams
- has_comment_arg <- "comment" %in% card_fun_args_nams
- has_label_arg <- "label" %in% card_fun_args_nams
+ shiny::observeEvent(input$add_report_card_button, {
+ shiny::showModal(add_modal())
+ })
- arg_list <- list()
+ # the add card button is disabled when clicked to prevent multi-clicks
+ # please check the ui part for more information
+ shiny::observeEvent(input$add_card_ok, {
+ card_fun_args_nams <- names(formals(card_fun))
+ has_card_arg <- "card" %in% card_fun_args_nams
+ has_comment_arg <- "comment" %in% card_fun_args_nams
+ has_label_arg <- "label" %in% card_fun_args_nams
- if (has_comment_arg) {
- arg_list <- c(arg_list, list(comment = input$comment))
- }
- if (has_label_arg) {
- arg_list <- c(arg_list, list(label = input$label))
- }
+ arg_list <- list()
- if (has_card_arg) {
- # The default_card is defined here because formals() returns a pairedlist object
- # of formal parameter names and their default values. The values are missing
- # if not defined and the missing check does not work if supplied formals(card_fun)[[1]]
- default_card <- formals(card_fun)$card
- card <- `if`(
- missing(default_card),
- ReportCard$new(),
- eval(default_card, envir = environment(card_fun))
- )
- arg_list <- c(arg_list, list(card = card))
- }
+ if (has_comment_arg) {
+ arg_list <- c(arg_list, list(comment = input$comment))
+ }
+ if (has_label_arg) {
+ arg_list <- c(arg_list, list(label = input$label))
+ }
- card <- try(do.call(card_fun, arg_list))
+ if (has_card_arg) {
+ # The default_card is defined here because formals() returns a pairedlist object
+ # of formal parameter names and their default values. The values are missing
+ # if not defined and the missing check does not work if supplied formals(card_fun)[[1]]
+ default_card <- formals(card_fun)$card
+ card <- `if`(
+ missing(default_card),
+ ReportCard$new(),
+ eval(default_card, envir = environment(card_fun))
+ )
+ arg_list <- c(arg_list, list(card = card))
+ }
- if (inherits(card, "try-error")) {
- msg <- paste0(
- "The card could not be added to the report. ",
- "Have the outputs for the report been created yet? If not please try again when they ",
- "are ready. Otherwise contact your application developer"
- )
- warning(msg)
- shiny::showNotification(
- msg,
- type = "error"
- )
- } else {
- checkmate::assert_class(card, "ReportCard")
- if (!has_comment_arg && length(input$comment) > 0 && input$comment != "") {
- card$append_text("Comment", "header3")
- card$append_text(input$comment)
- }
+ card <- try(do.call(card_fun, arg_list))
- if (!has_label_arg && length(input$label) == 1 && input$label != "") {
- card$set_name(input$label)
- }
+ if (inherits(card, "try-error")) {
+ msg <- paste0(
+ "The card could not be added to the report. ",
+ "Have the outputs for the report been created yet? If not please try again when they ",
+ "are ready. Otherwise contact your application developer"
+ )
+ warning(msg)
+ shiny::showNotification(
+ msg,
+ type = "error"
+ )
+ } else {
+ checkmate::assert_class(card, "ReportCard")
+ if (!has_comment_arg && length(input$comment) > 0 && input$comment != "") {
+ card$append_text("Comment", "header3")
+ card$append_text(input$comment)
+ }
- reporter$append_cards(list(card))
- shiny::showNotification(sprintf("The card added successfully."), type = "message")
- shiny::removeModal()
+ if (!has_label_arg && length(input$label) == 1 && input$label != "") {
+ card$set_name(input$label)
}
- })
- }
- )
+
+ reporter$append_cards(list(card))
+ shiny::showNotification(sprintf("The card added successfully."), type = "message")
+ shiny::removeModal()
+ }
+ })
+ })
}
diff --git a/R/DownloadModule.R b/R/DownloadModule.R
index c0e8f3b3..578fc777 100644
--- a/R/DownloadModule.R
+++ b/R/DownloadModule.R
@@ -73,85 +73,84 @@ download_report_button_srv <- function(id,
)
checkmate::assert_true(rmd_yaml_args[["output"]] %in% rmd_output)
- shiny::moduleServer(
- id,
- function(input, output, session) {
- ns <- session$ns
+ shiny::moduleServer(id, function(input, output, session) {
+ shiny::setBookmarkExclude(c("download_button"))
- download_modal <- function() {
- nr_cards <- length(reporter$get_cards())
- downb <- shiny::tags$a(
- id = ns("download_data"),
- class = paste("btn btn-primary shiny-download-link", if (nr_cards) NULL else "disabled"),
- style = if (nr_cards) NULL else "pointer-events: none;",
- href = "",
- target = "_blank",
- download = NA,
- shiny::icon("download"),
- "Download"
- )
- shiny::modalDialog(
- easyClose = TRUE,
- shiny::tags$h3("Download the Report"),
- shiny::tags$hr(),
- if (length(reporter$get_cards()) == 0) {
- shiny::tags$div(
- class = "mb-4",
- shiny::tags$p(
- class = "text-danger",
- shiny::tags$strong("No Cards Added")
- )
- )
- } else {
- shiny::tags$div(
- class = "mb-4",
- shiny::tags$p(
- class = "text-success",
- shiny::tags$strong(paste("Number of cards: ", nr_cards))
- ),
+ ns <- session$ns
+
+ download_modal <- function() {
+ nr_cards <- length(reporter$get_cards())
+ downb <- shiny::tags$a(
+ id = ns("download_data"),
+ class = paste("btn btn-primary shiny-download-link", if (nr_cards) NULL else "disabled"),
+ style = if (nr_cards) NULL else "pointer-events: none;",
+ href = "",
+ target = "_blank",
+ download = NA,
+ shiny::icon("download"),
+ "Download"
+ )
+ shiny::modalDialog(
+ easyClose = TRUE,
+ shiny::tags$h3("Download the Report"),
+ shiny::tags$hr(),
+ if (length(reporter$get_cards()) == 0) {
+ shiny::tags$div(
+ class = "mb-4",
+ shiny::tags$p(
+ class = "text-danger",
+ shiny::tags$strong("No Cards Added")
)
- },
- reporter_download_inputs(
- rmd_yaml_args = rmd_yaml_args,
- rmd_output = rmd_output,
- showrcode = any_rcode_block(reporter),
- session = session
- ),
- footer = shiny::tagList(
- shiny::tags$button(
- type = "button",
- class = "btn btn-secondary",
- `data-dismiss` = "modal",
- `data-bs-dismiss` = "modal",
- NULL,
- "Cancel"
+ )
+ } else {
+ shiny::tags$div(
+ class = "mb-4",
+ shiny::tags$p(
+ class = "text-success",
+ shiny::tags$strong(paste("Number of cards: ", nr_cards))
),
- downb
)
- )
- }
-
- shiny::observeEvent(input$download_button, {
- shiny::showModal(download_modal())
- })
-
- output$download_data <- shiny::downloadHandler(
- filename = function() {
- paste("report_", format(Sys.time(), "%y%m%d%H%M%S"), ".zip", sep = "")
},
- content = function(file) {
- shiny::showNotification("Rendering and Downloading the document.")
- shinybusy::block(id = ns("download_data"), text = "", type = "dots")
- input_list <- lapply(names(rmd_yaml_args), function(x) input[[x]])
- names(input_list) <- names(rmd_yaml_args)
- if (is.logical(input$showrcode)) global_knitr[["echo"]] <- input$showrcode
- report_render_and_compress(reporter, input_list, global_knitr, file)
- shinybusy::unblock(id = ns("download_data"))
- },
- contentType = "application/zip"
+ reporter_download_inputs(
+ rmd_yaml_args = rmd_yaml_args,
+ rmd_output = rmd_output,
+ showrcode = any_rcode_block(reporter),
+ session = session
+ ),
+ footer = shiny::tagList(
+ shiny::tags$button(
+ type = "button",
+ class = "btn btn-secondary",
+ `data-dismiss` = "modal",
+ `data-bs-dismiss` = "modal",
+ NULL,
+ "Cancel"
+ ),
+ downb
+ )
)
}
- )
+
+ shiny::observeEvent(input$download_button, {
+ shiny::showModal(download_modal())
+ })
+
+ output$download_data <- shiny::downloadHandler(
+ filename = function() {
+ paste("report_", format(Sys.time(), "%y%m%d%H%M%S"), ".zip", sep = "")
+ },
+ content = function(file) {
+ shiny::showNotification("Rendering and Downloading the document.")
+ shinybusy::block(id = ns("download_data"), text = "", type = "dots")
+ input_list <- lapply(names(rmd_yaml_args), function(x) input[[x]])
+ names(input_list) <- names(rmd_yaml_args)
+ if (is.logical(input$showrcode)) global_knitr[["echo"]] <- input$showrcode
+ report_render_and_compress(reporter, input_list, global_knitr, file)
+ shinybusy::unblock(id = ns("download_data"))
+ },
+ contentType = "application/zip"
+ )
+ })
}
#' Render the report
diff --git a/R/Previewer.R b/R/Previewer.R
index 5e0a81f4..45fce4c7 100644
--- a/R/Previewer.R
+++ b/R/Previewer.R
@@ -6,6 +6,8 @@
#' and interact with report cards that have been added to a report.
#' It includes a previewer interface to see the cards and options to modify the report before downloading.
#'
+#' Cards are saved by the `shiny` bookmarking mechanism.
+#'
#' For more details see the vignette: `vignette("previewerReporter", "teal.reporter")`.
#'
#' @details `r global_knitr_details()`
@@ -77,133 +79,140 @@ reporter_previewer_srv <- function(id,
)
checkmate::assert_true(rmd_yaml_args[["output"]] %in% rmd_output)
- shiny::moduleServer(
- id,
- function(input, output, session) {
- ns <- session$ns
+ shiny::moduleServer(id, function(input, output, session) {
+ shiny::setBookmarkExclude(c(
+ "card_remove_id", "card_down_id", "card_up_id", "remove_card_ok", "showrcode", "download_data_prev"
+ ))
+ session$onBookmark(function(state) {
+ state$values$report_cards <- reporter$get_cards()
+ })
+ session$onRestored(function(state) {
+ reporter$append_cards(state$values$report_cards)
+ })
- reset_report_button_srv("resetButtonPreviewer", reporter)
+ ns <- session$ns
- output$encoding <- shiny::renderUI({
- reporter$get_reactive_add_card()
- shiny::tagList(
- shiny::tags$h3("Download the Report"),
- shiny::tags$hr(),
- reporter_download_inputs(
- rmd_yaml_args = rmd_yaml_args,
- rmd_output = rmd_output,
- showrcode = any_rcode_block(reporter),
- session = session
- ),
- htmltools::tagAppendAttributes(
- shiny::tags$a(
- id = ns("download_data_prev"),
- class = "btn btn-primary shiny-download-link",
- href = "",
- target = "_blank",
- download = NA,
- shiny::tags$span("Download Report", shiny::icon("download"))
- ),
- class = if (length(reporter$get_cards())) "" else "disabled"
+ reset_report_button_srv("resetButtonPreviewer", reporter)
+
+ output$encoding <- shiny::renderUI({
+ reporter$get_reactive_add_card()
+ shiny::tagList(
+ shiny::tags$h3("Download the Report"),
+ shiny::tags$hr(),
+ reporter_download_inputs(
+ rmd_yaml_args = rmd_yaml_args,
+ rmd_output = rmd_output,
+ showrcode = any_rcode_block(reporter),
+ session = session
+ ),
+ htmltools::tagAppendAttributes(
+ shiny::tags$a(
+ id = ns("download_data_prev"),
+ class = "btn btn-primary shiny-download-link",
+ href = "",
+ target = "_blank",
+ download = NA,
+ shiny::tags$span("Download Report", shiny::icon("download"))
),
- reset_report_button_ui(ns("resetButtonPreviewer"), label = "Reset Report")
- )
- })
+ class = if (length(reporter$get_cards())) "" else "disabled"
+ ),
+ reset_report_button_ui(ns("resetButtonPreviewer"), label = "Reset Report")
+ )
+ })
- output$pcards <- shiny::renderUI({
- reporter$get_reactive_add_card()
- input$card_remove_id
- input$card_down_id
- input$card_up_id
+ output$pcards <- shiny::renderUI({
+ reporter$get_reactive_add_card()
+ input$card_remove_id
+ input$card_down_id
+ input$card_up_id
- cards <- reporter$get_cards()
+ cards <- reporter$get_cards()
- if (length(cards)) {
- shiny::tags$div(
- class = "panel-group accordion",
- id = "reporter_previewer_panel",
- lapply(seq_along(cards), function(ic) {
- previewer_collapse_item(ic, cards[[ic]]$get_name(), cards[[ic]]$get_content())
- })
- )
- } else {
- shiny::tags$div(
- id = "reporter_previewer_panel_no_cards",
- shiny::tags$p(
- class = "text-danger mt-4",
- shiny::tags$strong("No Cards added")
- )
+ if (length(cards)) {
+ shiny::tags$div(
+ class = "panel-group accordion",
+ id = "reporter_previewer_panel",
+ lapply(seq_along(cards), function(ic) {
+ previewer_collapse_item(ic, cards[[ic]]$get_name(), cards[[ic]]$get_content())
+ })
+ )
+ } else {
+ shiny::tags$div(
+ id = "reporter_previewer_panel_no_cards",
+ shiny::tags$p(
+ class = "text-danger mt-4",
+ shiny::tags$strong("No Cards added")
)
- }
- })
+ )
+ }
+ })
- shiny::observeEvent(input$card_remove_id, {
- shiny::showModal(
- shiny::modalDialog(
- title = "Remove the Report Card",
- shiny::tags$p(
- shiny::HTML(
- sprintf(
- "Do you really want to remove the card %s from the Report?",
- input$card_remove_id
- )
+ shiny::observeEvent(input$card_remove_id, {
+ shiny::showModal(
+ shiny::modalDialog(
+ title = "Remove the Report Card",
+ shiny::tags$p(
+ shiny::HTML(
+ sprintf(
+ "Do you really want to remove the card %s from the Report?",
+ input$card_remove_id
)
- ),
- footer = shiny::tagList(
- shiny::tags$button(
- type = "button",
- class = "btn btn-secondary",
- `data-dismiss` = "modal",
- `data-bs-dismiss` = "modal",
- NULL,
- "Cancel"
- ),
- shiny::actionButton(ns("remove_card_ok"), "OK", class = "btn-danger")
)
+ ),
+ footer = shiny::tagList(
+ shiny::tags$button(
+ type = "button",
+ class = "btn btn-secondary",
+ `data-dismiss` = "modal",
+ `data-bs-dismiss` = "modal",
+ NULL,
+ "Cancel"
+ ),
+ shiny::actionButton(ns("remove_card_ok"), "OK", class = "btn-danger")
)
)
- })
+ )
+ })
- shiny::observeEvent(input$remove_card_ok, {
- reporter$remove_cards(input$card_remove_id)
- shiny::removeModal()
- })
+ shiny::observeEvent(input$remove_card_ok, {
+ reporter$remove_cards(input$card_remove_id)
+ shiny::removeModal()
+ })
- shiny::observeEvent(input$card_up_id, {
- if (input$card_up_id > 1) {
- reporter$swap_cards(
- as.integer(input$card_up_id),
- as.integer(input$card_up_id - 1)
- )
- }
- })
+ shiny::observeEvent(input$card_up_id, {
+ if (input$card_up_id > 1) {
+ reporter$swap_cards(
+ as.integer(input$card_up_id),
+ as.integer(input$card_up_id - 1)
+ )
+ }
+ })
- shiny::observeEvent(input$card_down_id, {
- if (input$card_down_id < length(reporter$get_cards())) {
- reporter$swap_cards(
- as.integer(input$card_down_id),
- as.integer(input$card_down_id + 1)
- )
- }
- })
+ shiny::observeEvent(input$card_down_id, {
+ if (input$card_down_id < length(reporter$get_cards())) {
+ reporter$swap_cards(
+ as.integer(input$card_down_id),
+ as.integer(input$card_down_id + 1)
+ )
+ }
+ })
- output$download_data_prev <- shiny::downloadHandler(
- filename = function() {
- paste("report_", format(Sys.time(), "%y%m%d%H%M%S"), ".zip", sep = "")
- },
- content = function(file) {
- shiny::showNotification("Rendering and Downloading the document.")
- shinybusy::block(id = ns("download_data_prev"), text = "", type = "dots")
- input_list <- lapply(names(rmd_yaml_args), function(x) input[[x]])
- names(input_list) <- names(rmd_yaml_args)
- if (is.logical(input$showrcode)) global_knitr[["echo"]] <- input$showrcode
- report_render_and_compress(reporter, input_list, global_knitr, file)
- shinybusy::unblock(id = ns("download_data_prev"))
- },
- contentType = "application/zip"
- )
- }
- )
+ output$download_data_prev <- shiny::downloadHandler(
+ filename = function() {
+ paste("report_", format(Sys.time(), "%y%m%d%H%M%S"), ".zip", sep = "")
+ },
+ content = function(file) {
+ shiny::showNotification("Rendering and Downloading the document.")
+ shinybusy::block(id = ns("download_data_prev"), text = "", type = "dots")
+ input_list <- lapply(names(rmd_yaml_args), function(x) input[[x]])
+ names(input_list) <- names(rmd_yaml_args)
+ if (is.logical(input$showrcode)) global_knitr[["echo"]] <- input$showrcode
+ report_render_and_compress(reporter, input_list, global_knitr, file)
+ shinybusy::unblock(id = ns("download_data_prev"))
+ },
+ contentType = "application/zip"
+ )
+ })
}
#' @noRd
diff --git a/R/ResetModule.R b/R/ResetModule.R
index 59a74afc..d7f214ae 100644
--- a/R/ResetModule.R
+++ b/R/ResetModule.R
@@ -45,42 +45,41 @@ reset_report_button_ui <- function(id, label = NULL) {
reset_report_button_srv <- function(id, reporter) {
checkmate::assert_class(reporter, "Reporter")
- shiny::moduleServer(
- id,
- function(input, output, session) {
- ns <- session$ns
- nr_cards <- length(reporter$get_cards())
+ shiny::moduleServer(id, function(input, output, session) {
+ shiny::setBookmarkExclude(c("reset_reporter"))
+ ns <- session$ns
+ nr_cards <- length(reporter$get_cards())
- shiny::observeEvent(input$reset_reporter, {
- shiny::showModal(
- shiny::modalDialog(
- shiny::tags$h3("Reset the Report"),
- shiny::tags$hr(),
- shiny::tags$strong(
- shiny::tags$p(
- "Are you sure you want to reset the report? (This will remove ALL previously added cards)."
- )
- ),
- footer = shiny::tagList(
- shiny::tags$button(
- type = "button",
- class = "btn btn-secondary",
- `data-dismiss` = "modal",
- `data-bs-dismiss` = "modal",
- NULL,
- "Cancel"
- ),
- shiny::actionButton(ns("reset_reporter_ok"), "Reset", class = "btn-danger")
+
+ shiny::observeEvent(input$reset_reporter, {
+ shiny::showModal(
+ shiny::modalDialog(
+ shiny::tags$h3("Reset the Report"),
+ shiny::tags$hr(),
+ shiny::tags$strong(
+ shiny::tags$p(
+ "Are you sure you want to reset the report? (This will remove ALL previously added cards)."
)
+ ),
+ footer = shiny::tagList(
+ shiny::tags$button(
+ type = "button",
+ class = "btn btn-secondary",
+ `data-dismiss` = "modal",
+ `data-bs-dismiss` = "modal",
+ NULL,
+ "Cancel"
+ ),
+ shiny::actionButton(ns("reset_reporter_ok"), "Reset", class = "btn-danger")
)
)
- })
+ )
+ })
- shiny::observeEvent(input$reset_reporter_ok, {
- reporter$reset()
- shiny::removeModal()
- })
- }
- )
+ shiny::observeEvent(input$reset_reporter_ok, {
+ reporter$reset()
+ shiny::removeModal()
+ })
+ })
}
diff --git a/man/reporter_previewer.Rd b/man/reporter_previewer.Rd
index 1d9a9024..c4667414 100644
--- a/man/reporter_previewer.Rd
+++ b/man/reporter_previewer.Rd
@@ -46,6 +46,8 @@ Module offers functionalities to visualize, manipulate,
and interact with report cards that have been added to a report.
It includes a previewer interface to see the cards and options to modify the report before downloading.
+Cards are saved by the \code{shiny} bookmarking mechanism.
+
For more details see the vignette: \code{vignette("previewerReporter", "teal.reporter")}.
}
\details{