```{r renv.ignore = TRUE}
{{id}}_module_ui <- function(id) {
  ns <- shiny::NS(id)
  tagList(
    # UI
```
```{r renv.ignore = TRUE, purl = {{download}} }
    input_task_button(ns("run"), "Run module {{id}}", type = "default", icon = icon("arrow-turn-down")),
    downloadButton(ns("download"), "Download")
```
```{r renv.ignore = TRUE, purl = {{!download}} }
    input_task_button(ns("run"), "Run module {{id}}", type = "default", icon = icon("arrow-turn-down"))
```
```{r renv.ignore = TRUE}
  )
}

{{id}}_module_server <- function(id, common, parent_session, map) {
  moduleServer(id, function(input, output, session) {
```
```{r renv.ignore = TRUE, purl = {{download}} }
  shinyjs::hide("download")
```
```{r renv.ignore = TRUE}
  # create the asynchronous task
  common$tasks${{id}} <- ExtendedTask$new(function(...) {
    mirai::mirai(run(...), environment(), .args = list(run = {{id}}))
  }) |> bind_task_button("run")

    observeEvent(input$run, {
      # WARNING ####

      # FUNCTION CALL ####
      common$logger |> writeLog(type = "starting", "Starting to run {{id}}")
      # invoke the async task
      common$tasks${{id}}$invoke()
      # reactivate the results observer if it has already been used
      results$resume()

      # METADATA ####
      # Populate using metadata()
    })


    results <- observe({
      # LOAD INTO COMMON ####

      # fetch the result
      result <- common$tasks${{id}}$result()
      # suspend the observer
      results$suspend()

      # check the class of the result is the class when the function runs successfully
      if (class(result) == "list"){

        common$logger |> writeLog(type = "complete", "{{id}} has completed")

        # TRIGGER
        trigger("{{id}}")
```
```{r renv.ignore = TRUE, purl = {{download}} }
    shinyjs::show("download")
```
```{r renv.ignore = TRUE, purl = {{map}} }
        # explicitly call the mapping function
        do.call("{{id}}_module_map", list(map, common))
        show_map(parent_session)
```
```{r renv.ignore = TRUE}
        # set an input value to use in testing
        shinyjs::runjs("Shiny.setInputValue('{{id}}-complete', 'complete');")
      } else {
        common$logger |> writeLog(type = "error", result)
      }
    })
```
```{r renv.ignore = TRUE, purl = {{result}} }

    output$result <- renderText({
      watch("{{id}}")
      # Result
    })
```
```{r renv.ignore = TRUE, purl = {{download}} }
  output$download <- downloadHandler(
    filename = function() {
      "placeholder.ext"
    },
    content = function(file) {
      # Download content
    })
```
```{r renv.ignore = TRUE, purl = {{save}} }
    return(list(
      save = function() {
        # Save any values that should be saved when the current session is saved
        # Populate using save_and_load()
      },
      load = function(state) {
        # Load
        # Populate using save_and_load()
      }
    ))
```
```{r renv.ignore = TRUE}
  })
}

```{r renv.ignore = TRUE, purl = {{result}} }
{{id}}_module_result <- function(id) {
  ns <- NS(id)

  # Result UI
  verbatimTextOutput(ns("result"))
}
```
```{r renv.ignore = TRUE, purl = {{map}} }
{{id}}_module_map <- function(map, common) {
  # Map logic
}
```
```{r renv.ignore = TRUE, purl = {{rmd}} }
{{id}}_module_rmd <- function(common) {
  # Variables used in the module's Rmd code
  # Populate using metadata()
}
```
