shinycssloaders/0000755000176200001440000000000013610121112013453 5ustar liggesusersshinycssloaders/NAMESPACE0000644000176200001440000000010513607376045014715 0ustar liggesusers# Generated by roxygen2: do not edit by hand export(withSpinner) shinycssloaders/README.md0000644000176200001440000000734513607441212014757 0ustar liggesusers# shinycssloaders [![CRAN](http://www.r-pkg.org/badges/version/shinycssloaders)](https://cran.r-project.org/package=shinycssloaders) [![](https://cranlogs.r-pkg.org/badges/shinycssloaders)](https://CRAN.R-project.org/package=shinycssloaders) Add loader animations (spinners) to Shiny Outputs (e.g. plots, tables). Loading animations leverage on [Shiny JS events](https://shiny.rstudio.com/articles/js-events.html) and will show whilst the output value is not yet available or is 'out-of-date' (i.e. has been invalidated and the client hasn't received the new value). The spinners won't show if the output is not rendered (e.g. a `validate` or `req` is preventing it from being shown). ![](https://cloud.githubusercontent.com/assets/15079591/26738969/69141f08-47d0-11e7-848a-9d1705b613f0.gif) The advantages of using this package are: * Automatic spinner showing / hiding. Just add one extra R function call (see below) and your output will have the spinner showing at just the right times * Customizeable spinner colour (for each output or globally) * Customizeable spinner size (for each output or globally) * Choose from 8 different well-designed spinner types The CSS animations are bundled from [https://projects.lukehaas.me/css-loaders/](https://projects.lukehaas.me/css-loaders/), where you can see how they appear. You can use it for any type of shiny output, by wrapping the UI element with the `withSpinner` tag: ``` # load the library library(shinycssloaders) ... withSpinner(plotOutput("my_plot")) # if you have `%>%` loaded, you can do plotOutput("my_plot") %>% withSpinner() ... ``` > For outputs with uknown heights (e.g. tables), a 'proxy' container will be inserted, as the spinner cannot be centered with respect to a height that is uknown to the client (e.g. you might return a really large / small table, who knows?). By default the proxy container will be of height '400px', however if your output is expected to be substantially larger / smaller, you can adjust this with `proxy.height` option. ## Installation The package is now available on CRAN, however for the latest (and hopefully greatest!) version you can use the `devtools` package to install it from github directly: ``` devtools::install_github('andrewsali/shinycssloaders') ``` ## Demo To see how this works in action, you can check my example on [shinyapps.io](https://frontside.shinyapps.io/example/) or - in case my free shinyapps monthly allowance is over - run the example application from github directly: ``` shiny::runGitHub('andrewsali/shinycssloaders', subdir = "inst/examples/basic") ``` To see how the spinner works for outputs with undefined height, you can check out [this example](https://frontside.shinyapps.io/table/) or run it from github directly: ``` shiny::runGitHub('andrewsali/shinycssloaders', subdir = "inst/examples/table") ``` ## Changing the spinner colour You can specify a spinner colour for each output or set a variable globally. ### Locally for each output Just add `color` attribute to `withSpinner`: ``` plotOutput("my_plot") %>% withSpinner(color="#0dc5c1") ``` ### Globally You can use `options(spinner.color="#0dc5c1")` to set the global colour. ### Background color Spinner types 2-3 require you to specify a background color as well, which should match the background color of the container hosting the output. The other spinners work automatically without having to specify a background color. ## Changing the spinner size The spinners scale in a relative fashion by specifying the `size` argument of withSpinner (default value is 1, so if you need to double the spinner for example, set size to 2). You can also set the size globally using `options(spinner.size=my_size)`. shinycssloaders/man/0000755000176200001440000000000013607376045014255 5ustar liggesusersshinycssloaders/man/shinycssloaders.Rd0000644000176200001440000000136113607376045017762 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/shinycssloaders-package.r \docType{package} \name{shinycssloaders} \alias{shinycssloaders} \alias{shinycssloaders-package} \title{shinycssloaders.} \description{ Add automatic loading animations to your Shiny outputs (e.g. plots, tables) by adding a single function call around the Shiny output function. Animations automatically show / hide when the output is recalculating / recalculated (or error is throws). You can choose from 8 different types of animations and you can also customize the color / size of the animation. } \details{ For further reference on how to use the package, please refer to \url{https://github.com/andrewsali/shinycssloaders} } shinycssloaders/man/withSpinner.Rd0000644000176200001440000000304513607376045017060 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/withSpinner.R \name{withSpinner} \alias{withSpinner} \title{Add a spinner (loader) that shows when an output is recalculating} \usage{ withSpinner(ui_element, type = getOption("spinner.type", default = 1), color = getOption("spinner.color", default = "#0275D8"), size = getOption("spinner.size", default = 1), color.background = getOption("spinner.color.background"), custom.css = FALSE, proxy.height = if (grepl("height:\\\\s*\\\\d", ui_element)) NULL else "400px") } \arguments{ \item{ui_element}{A UI element that should be wrapped with a spinner when the corresponding output is being calculated.} \item{type}{The type of spinner to use, valid values are integers between 1-8. They correspond to the enumeration in \url{https://projects.lukehaas.me/css-loaders/}} \item{color}{The color of the spinner to be applied in HTML in hex format} \item{size}{The size of the spinner, relative to it's default size.} \item{color.background}{For certain spinners (type 2-3), you will need to specify the background colour of the spinner} \item{custom.css}{If custom css is to be applied, we don't enforce the color / size options to the given spinner id} \item{proxy.height}{If the output doesn't specify the output height, you can set a proxy height. It defaults to 400px for outputs with undefined height.} } \description{ Add a spinner (loader) that shows when an output is recalculating } \examples{ \dontrun{withSpinner(plotOutput("my_plot"))} } shinycssloaders/DESCRIPTION0000644000176200001440000000232513610121112015163 0ustar liggesusersPackage: shinycssloaders Type: Package Title: Add CSS Loading Animations to 'shiny' Outputs Version: 0.3 Authors@R: c( person("Andras","Sali",email="andras.sali@alphacruncher.hu",role=c("aut"),comment="Original creator of shinycssloaders package"), person("Luke","Hass",role=c("ctb","cph"),comment="Author of included CSS loader code"), person("Dean","Attali",email="daattali@gmail.com",role=c("aut","cre"),comment="Creator of Shiny-wrapper code") ) Description: Automatically show loader animations while a Shiny output is (re)calculating. This is mostly a wrapper around the css-loaders created by Luke Hass . License: GPL-3 URL: https://github.com/andrewsali/shinycssloaders BugReports: https://github.com/andrewsali/shinycssloaders/issues Depends: R (>= 3.1) Imports: digest, glue, grDevices, shiny RoxygenNote: 6.0.1 NeedsCompilation: no Packaged: 2020-01-14 22:40:30 UTC; Oriane Author: Andras Sali [aut] (Original creator of shinycssloaders package), Luke Hass [ctb, cph] (Author of included CSS loader code), Dean Attali [aut, cre] (Creator of Shiny-wrapper code) Maintainer: Dean Attali Repository: CRAN Date/Publication: 2020-01-16 17:50:02 UTC shinycssloaders/R/0000755000176200001440000000000013607376045013703 5ustar liggesusersshinycssloaders/R/withSpinner.R0000644000176200001440000001264013607376045016343 0ustar liggesusers#' Add a spinner (loader) that shows when an output is recalculating #' @export #' @param ui_element A UI element that should be wrapped with a spinner when the corresponding output is being calculated. #' @param type The type of spinner to use, valid values are integers between 1-8. They correspond to the enumeration in \url{https://projects.lukehaas.me/css-loaders/} #' @param color The color of the spinner to be applied in HTML in hex format #' @param size The size of the spinner, relative to it's default size. #' @param color.background For certain spinners (type 2-3), you will need to specify the background colour of the spinner #' @param custom.css If custom css is to be applied, we don't enforce the color / size options to the given spinner id #' @param proxy.height If the output doesn't specify the output height, you can set a proxy height. It defaults to 400px for outputs with undefined height. #' @examples #' \dontrun{withSpinner(plotOutput("my_plot"))} withSpinner <- function(ui_element,type=getOption("spinner.type",default=1),color=getOption("spinner.color",default="#0275D8"),size=getOption("spinner.size",default=1),color.background=getOption("spinner.color.background"),custom.css=FALSE,proxy.height=if (grepl("height:\\s*\\d",ui_element)) NULL else "400px") { stopifnot(type %in% 1:8) if (grepl("rgb",color,fixed=TRUE)) { stop("Color should be given in hex format") } # each spinner will have a unique id, to allow seperate sizing - based on hashing the UI element code id <- paste0("spinner-",digest::digest(ui_element)) add_style <- function(x) { shiny::tags$head( shiny::tags$style( shiny::HTML( x ) ) ) } css_size <- css_color <- shiny::tagList() if (!custom.css) { color.alpha <- sprintf("rgba(%s,0)",paste(grDevices::col2rgb(color),collapse=",")) if (type==1) { css_color <- add_style( glue::glue("#{id}, #{id}:before, #{id}:after {{background: {color}}} #{id} {{color: {color}}}") ) } if (type %in% c(2,3) && is.null(color.background)) { stop("For spinner types 2 & 3 you need to specify manually a background color. This should match the background color of the container.") } if (type == 2) { css_color <- add_style( glue::glue("#{id} {{color: {color}}} #{id}:before, #{id}:after {{background: {color.background};}}") ) } if (type == 3) { css_color <- add_style( glue::glue( "#{id} {{ background: -moz-linear-gradient(left, {color} 10%, {color.alpha} 42%); background: -webkit-linear-gradient(left, {color} 10%, {color.alpha} 42%); background: -o-linear-gradient(left, {color} 10%, {color.alpha} 42%); background: -ms-linear-gradient(left, {color} 10%, {color.alpha} 42%); background: linear-gradient(to right, {color} 10%, {color.alpha} 42%); }} #{id}:before {{ background: {color} }} #{id}:after {{ background: {color.background}; }} ") ) } if (type %in% c(4,6,7)) { css_color <- add_style( glue::glue("#{id} {{color: {color}}}") ) } if (type==5) { base_css <- paste(readLines(system.file("css-loaders/css/load5.css",package="shinycssloaders")),collapse=" ") base_css <- gsub(".load5 .loader",paste0("#",id),base_css) base_css <- gsub("load5",paste0("load5-",id),base_css,fixed=TRUE) base_css <- gsub("255, 255, 255",paste(grDevices::col2rgb(color),collapse=','),base_css,fixed=TRUE) base_css <- gsub("#ffffff",color,base_css,fixed=TRUE) css_color <- add_style(base_css) } if (type == 8) { css_color <- add_style( glue::glue(" #{id} {{ border-top: 1.1em solid rgba({paste(grDevices::col2rgb(color),collapse=',')}, 0.2); border-right: 1.1em solid rgba({paste(grDevices::col2rgb(color),collapse=',')}, 0.2); border-bottom: 1.1em solid rgba({paste(grDevices::col2rgb(color),collapse=',')}, 0.2); border-left: 1.1em solid {color}; }} ") ) } # get default font-size from css, and cut it by 25%, as for outputs we usually need something smaller size <- round(c(11,11,10,20,25,90,10,10)[type] * size * 0.75) css_size <- add_style( glue::glue("#{id} {{font-size: {size}px}}",id,size) ) } proxy_element <- shiny::tagList() if (!is.null(proxy.height)) { proxy_element <- shiny::div(style=glue::glue("height:{ifelse(is.null(proxy.height),'100%',proxy.height)}"), class="shiny-spinner-placeholder") } shiny::tagList( shiny::singleton( shiny::tags$head(shiny::tags$link(rel="stylesheet",href="assets/spinner.css")) ), shiny::singleton( shiny::tags$script(src="assets/spinner.js") ), shiny::singleton( shiny::tags$head(shiny::tags$link(rel="stylesheet",href=sprintf("css-loaders/css/fallback.css",type))) ), shiny::singleton( shiny::tags$head(shiny::tags$link(rel="stylesheet",href=sprintf("css-loaders/css/load%s.css",type))) ), css_color, css_size, shiny::div(class="shiny-spinner-output-container", shiny::div(class=sprintf("load-container load%s shiny-spinner-hidden",type), shiny::div(id=id,class="loader","Loading...") ), proxy_element, ui_element ) ) }shinycssloaders/R/globals.R0000644000176200001440000000042013607376045015445 0ustar liggesusers.onLoad <- function(libname, pkgname) { shiny::addResourcePath(prefix = "assets",directoryPath = system.file("assets",package="shinycssloaders")) shiny::addResourcePath(prefix = "css-loaders",directoryPath = system.file("css-loaders",package="shinycssloaders")) } shinycssloaders/R/shinycssloaders-package.r0000644000176200001440000000111713607376045020674 0ustar liggesusers#' shinycssloaders. #' #' Add automatic loading animations to your Shiny outputs (e.g. plots, tables) by adding a single function call #' around the Shiny output function. Animations automatically show / hide when the output #' is recalculating / recalculated (or error is throws). You can choose from 8 different types of animations and you can #' also customize the color / size of the animation. #' #' For further reference on how to use the package, please refer to \url{https://github.com/andrewsali/shinycssloaders} #' #' @name shinycssloaders #' @docType package NULL shinycssloaders/NEWS.md0000644000176200001440000000203113607401344014563 0ustar liggesusers# shinycssloaders 0.3 2020-01-14 - Remove debug message from JS console (#26) - Ensure spinner doesn't show forever when used on dynamic outputs - Fix bug that caused errors with outputs with special ID characters and caused errors when using shiny bookmarks (#16) - Fix type 1 and type 7 spinners on IE11 (#1) # shinycssloaders 0.2.0 ## New features * Better support for outputs with non-fixed height (e.g. tables with heights depending on the data received from the server), by embedding a 'proxy' container which contains the spinner. An attempt is made to automatically deduce if the output has fixed / variable height and in the latter case the proxy container will have a default height of '400px'. Otherwise the `proxy.height` option can be used to explicitly control the size of the proxy container. ## Bug-fixes * Fix vertical scroll-bar appearing for Type 3 spinners * Fix error message still showing when recalculating for htmlwidgets # shinycssloaders 0.1.0 The first working version of the package. shinycssloaders/MD50000644000176200001440000000566213610121112013774 0ustar liggesusers92f6a699fb96be09d8dce8b35d38cc0e *DESCRIPTION 22bfb875c6f72c48e7bdd5b5db6052ce *NAMESPACE 78be363f1b845d5ef78f6cafee70d40e *NEWS.md 8ad50df03e40135c596de093c23e3bba *R/globals.R 236a39bbc88580c07127e97c5d3cedec *R/shinycssloaders-package.r 410c82db8d5d659457db8ad7f32391d4 *R/withSpinner.R afb3eccadc483f7868d17d2abc9d7708 *README.md db35f4907512247f381ca177cc30291c *inst/assets/spinner.css 99d2f91ce9ed551853f6c8092f7e9cfb *inst/assets/spinner.js 8a387219b6d73d26a463564a1e78f1fe *inst/css-loaders/Gruntfile.js d15cf40aef1f3959b3826b7a67f32379 *inst/css-loaders/LICENSE 91b43835cc476fd661f7cb019741b6b8 *inst/css-loaders/README.md 1160dcbd59f30cc05e11fadaee879d6f *inst/css-loaders/bower.json 1180fef3e8e08b4b16e079695b466fc5 *inst/css-loaders/css/fallback.css 8a055d269e6d52b8377a4fe8c831d62b *inst/css-loaders/css/load1.css 41b12b80e6c8ddd820f8c03b4cb9a12f *inst/css-loaders/css/load2.css 3f63205e087cfa3d4ab500249f2f94b2 *inst/css-loaders/css/load3.css 0be4c153cffffb7b7058d9ed13a55b30 *inst/css-loaders/css/load4.css d809e20e1083a06a67d15b23d6e6383b *inst/css-loaders/css/load5.css 5de9b2fdb76fb4cb632be778afe85e68 *inst/css-loaders/css/load6.css e9ca1b0952e69f6a5ebdcace8019c284 *inst/css-loaders/css/load7.css 157f03db3ab7259c285baa3d73780235 *inst/css-loaders/css/load8.css 7ca29272ecd932d23f5a65a8b4c33543 *inst/css-loaders/images/css-loaders-screenshot.jpg 18e961f3df032b98761361262a201443 *inst/css-loaders/less/fallback.less fe647ecf38b280470957bb2d26ba303d *inst/css-loaders/less/load1.less 1b211c4ccff3603447753661835a84ae *inst/css-loaders/less/load2.less d80985e9ad861b16d926505d71315b10 *inst/css-loaders/less/load3.less 6eca0642d3dad1e41333fa628e762f15 *inst/css-loaders/less/load4.less f0ffdde2809eb00e3112c303dada93fe *inst/css-loaders/less/load5.less 87bc642544f3d03807e52f8c580762bc *inst/css-loaders/less/load6.less 8240c8976f7ef4bf433724ad519f7988 *inst/css-loaders/less/load7.less 40cf0f2fbfe150b5c32c24de26a43ef6 *inst/css-loaders/less/load8.less 8726f8e3c0fbea32b52912428d9d3938 *inst/css-loaders/package.json 18e961f3df032b98761361262a201443 *inst/css-loaders/sass/fallback.scss de3025f2653abb9c34f13aa941dc5181 *inst/css-loaders/sass/load1.scss 7a38d2937b159bd0cf06e91ed6d2b74e *inst/css-loaders/sass/load2.scss 45e761c1b39212c0dac3109431f046bd *inst/css-loaders/sass/load3.scss d7ae62f2c3eea1baba6c3eddeeeafccd *inst/css-loaders/sass/load4.scss 194a50e1e98f867a1308b72743548512 *inst/css-loaders/sass/load5.scss c86d2d9a1fa806a3ba096bcb9cbad432 *inst/css-loaders/sass/load6.scss a3c72f11d9825bbc30b0bc4a52ee1794 *inst/css-loaders/sass/load7.scss 5daa24a8617d7d1aca979da575002e7b *inst/css-loaders/sass/load8.scss 83a8413502472527e689d414ebc3f877 *inst/examples/app.R 675beaa4ca2e2b5d8df3efa3579c61c2 *inst/examples/base_table/app.R 1acc1c6be0e0de7fc46e9714e332161d *inst/examples/plotly/app.R 546fd0784ac8fd73969ac632268e6637 *inst/examples/table/app.R b19d23b4821281cf94d194fb02eac226 *man/shinycssloaders.Rd 8d4843fffe7495ae15a9637fe11f83d1 *man/withSpinner.Rd shinycssloaders/inst/0000755000176200001440000000000013607441527014455 5ustar liggesusersshinycssloaders/inst/examples/0000755000176200001440000000000013607441536016273 5ustar liggesusersshinycssloaders/inst/examples/plotly/0000755000176200001440000000000013607376045017620 5ustar liggesusersshinycssloaders/inst/examples/plotly/app.R0000644000176200001440000000341413607376045020525 0ustar liggesuserslibrary(shiny) library(shinycssloaders) library(plotly) # for spinners 2-3 match the background color of wellPanel options(spinner.color.background="#F5F5F5") ui <- fluidPage( wellPanel( tags$b("This example shows the loading spinner whilst the plot is loading and hides the spinner when the plot is not shown."), br(),br(), tags$ul( tags$li("You can use it to wrap any kind of output."), tags$li("To see what happens on recalculation, click the recalculate button"), tags$li("To see what happens if no output should be generated, check off 'Show plots'.") ), checkboxInput("show_plot","Show plot",value=TRUE), actionButton("redraw_plot","Re-draw plots") ), do.call(tabsetPanel,lapply(1:8,function(.type) { tabPanel(paste0("Type ",.type), fluidRow( column(width=6, wellPanel( tags$b("With spinner:"), withSpinner(plotlyOutput(paste0("plot",.type)),type=.type) ) ), column(width=6, wellPanel( tags$b("Without spinner (default):"), plotlyOutput(paste0("nospin_plot",.type)) ) ) ) ) })) ) server <- function(input, output,session) { for (i in 1:8) { output[[paste0("nospin_plot",i)]] <- output[[paste0("plot",i)]] <- renderPlotly({ validate(need(input$show_plot,"Show plot is unchecked. Check to see plot.")) input$redraw_plot Sys.sleep(5) # just for demo so you can enjoy the animation plot_ly( x = runif(1e4), y = runif(1e4) ) }) } } shinyApp(ui = ui, server = server) shinycssloaders/inst/examples/base_table/0000755000176200001440000000000013607376045020356 5ustar liggesusersshinycssloaders/inst/examples/base_table/app.R0000644000176200001440000000441013607376045021260 0ustar liggesuserslibrary(shiny) library(shinycssloaders) library(DT) # for spinners 2-3 match the background color of wellPanel options(spinner.color.background="#F5F5F5") ui <- fluidPage( wellPanel( tags$b("This example shows the loading spinner whilst a data-table is loading and hides the spinner when the data-table is not shown."), br(), br(), tags$b(style="color:red","Since the table height is not known ex-ante (as it depends on the rows selected), we insert a 'proxy' container that emulates the unknown table. The spinner is centered with respect to the proxy. The proxy height is configurable and should in general represent an 'expected' output height."), br(), br(), tags$ul( tags$li("You can use it to wrap any kind of output."), tags$li("To see what happens on recalculation, click the recalculate button"), tags$li("To see what happens if no output should be generated, check off 'Show plots'.") ), checkboxInput("show_plot","Show tables",value=TRUE), actionButton("redraw_plot","Re-draw tables"), br(), br(), fluidRow( column( sliderInput("n_rows","Number of rows in table",min=1,max=nrow(mtcars),value=10,step = 1), width=3) ) ), do.call(tabsetPanel,lapply(1:8,function(.type) { tabPanel(paste0("Type ",.type), fluidRow( column(width=6, wellPanel( tags$b("With spinner:"), withSpinner(tableOutput(paste0("table",.type)),type=.type) ) ), column(width=6, wellPanel( tags$b("Without spinner (default):"), tableOutput(paste0("nospin_table",.type)) ) ) ) ) })) ) server <- function(input, output,session) { for (i in 1:8) { output[[paste0("nospin_table",i)]] <- output[[paste0("table",i)]] <- renderTable({ validate(need(input$show_plot,"Show table is unchecked. Check to see table.")) input$redraw_plot Sys.sleep(5) # just for demo so you can enjoy the animation mtcars[1:input$n_rows,] }) } } shinyApp(ui = ui, server = server) shinycssloaders/inst/examples/table/0000755000176200001440000000000013607376045017364 5ustar liggesusersshinycssloaders/inst/examples/table/app.R0000644000176200001440000000451213607376045020271 0ustar liggesuserslibrary(shiny) library(shinycssloaders) library(DT) # for spinners 2-3 match the background color of wellPanel options(spinner.color.background="#F5F5F5") ui <- fluidPage( wellPanel( tags$b("This example shows the loading spinner whilst a data-table is loading and hides the spinner when the data-table is not shown."), br(), br(), tags$b(style="color:red","Since the table height is not known ex-ante (as it depends on the rows selected), we insert a 'proxy' container that emulates the unknown table. The spinner is centered with respect to the proxy. The proxy height is configurable and should in general represent an 'expected' output height."), br(), br(), tags$ul( tags$li("You can use it to wrap any kind of output."), tags$li("To see what happens on recalculation, click the recalculate button"), tags$li("To see what happens if no output should be generated, check off 'Show plots'.") ), checkboxInput("show_plot","Show tables",value=TRUE), actionButton("redraw_plot","Re-draw tables"), br(), br(), fluidRow( column( sliderInput("n_rows","Number of rows in table",min=1,max=nrow(mtcars),value=10,step = 1), width=3) ) ), do.call(tabsetPanel,lapply(1:8,function(.type) { tabPanel(paste0("Type ",.type), fluidRow( column(width=6, wellPanel( tags$b("With spinner:"), withSpinner(DT::dataTableOutput(paste0("table",.type)),type=.type) ) ), column(width=6, wellPanel( tags$b("Without spinner (default):"), DT::dataTableOutput(paste0("nospin_table",.type)) ) ) ) ) })) ) server <- function(input, output,session) { for (i in 1:8) { output[[paste0("nospin_table",i)]] <- output[[paste0("table",i)]] <- DT::renderDataTable({ validate(need(input$show_plot,"Show table is unchecked. Check to see table.")) input$redraw_plot Sys.sleep(5) # just for demo so you can enjoy the animation mtcars[,1:4] %>% datatable(options=list(pageLength=input$n_rows)) }) } } shinyApp(ui = ui, server = server) shinycssloaders/inst/examples/app.R0000644000176200001440000000336213607376045017204 0ustar liggesuserslibrary(shiny) library(shinycssloaders) # for spinners 2-3 match the background color of wellPanel options(spinner.color.background="#F5F5F5") ui <- fluidPage( wellPanel( tags$b("This example shows the loading spinner whilst the plot is loading and hides the spinner when the plot is not shown."), br(),br(), tags$ul( tags$li("You can use it to wrap any kind of output."), tags$li("To see what happens on recalculation, click the recalculate button"), tags$li("To see what happens if no output should be generated, check off 'Show plots'.") ), checkboxInput("show_plot","Show plot",value=TRUE), actionButton("redraw_plot","Re-draw plots") ), do.call(tabsetPanel,lapply(1:8,function(.type) { tabPanel(paste0("Type ",.type), fluidRow( column(width=6, wellPanel( tags$b("With spinner:"), withSpinner(plotOutput(paste0("plot",.type)),type=.type) ) ), column(width=6, wellPanel( tags$b("Without spinner (default):"), plotOutput(paste0("nospin_plot",.type)) ) ) ) ) })) ) server <- function(input, output,session) { for (i in 1:8) { output[[paste0("nospin_plot",i)]] <- output[[paste0("plot",i)]] <- renderPlot({ validate(need(input$show_plot,"Show plot is unchecked. Check to see plot.")) input$redraw_plot Sys.sleep(5) # just for demo so you can enjoy the animation plot( x = runif(1e4), y = runif(1e4) ) }) } } shinyApp(ui = ui, server = server) shinycssloaders/inst/assets/0000755000176200001440000000000013607376045015761 5ustar liggesusersshinycssloaders/inst/assets/spinner.css0000644000176200001440000000075013607376045020153 0ustar liggesusers.shiny-spinner-output-container { position: relative; } .load-container { position: absolute; top: 50%; -webkit-transform: translateY(-50%); transform: translateY(-50%); /* to avoid showing a vertical scrollbar http://stackoverflow.com/questions/38251204/horizontal-animation-causes-vertical-scrollbar-in-css */ overflow:hidden; width: 100%; } .shiny-spinner-hidden { position: absolute; top:0; left:0; z-index: -1; visibility:hidden; }shinycssloaders/inst/assets/spinner.js0000644000176200001440000000401013607376045017770 0ustar liggesusers(function() { var output_states = []; function escapeSelector(s) { return s.replace(/([!"#$%&'()*+,-./:;<=>?@\[\\\]^`{|}~])/g, "\\$1"); } function show_spinner(id) { var selector = "#"+escapeSelector(id); $(selector).siblings(".load-container, .shiny-spinner-placeholder").removeClass('shiny-spinner-hidden'); $(selector).siblings(".load-container").siblings('.shiny-bound-output, .shiny-output-error').css('visibility', 'hidden'); // if there is a proxy div, hide the previous output $(selector).siblings(".shiny-spinner-placeholder").siblings('.shiny-bound-output, .shiny-output-error').addClass('shiny-spinner-hidden'); } function hide_spinner(id) { var selector = "#"+escapeSelector(id); $(selector).siblings(".load-container, .shiny-spinner-placeholder").addClass('shiny-spinner-hidden'); $(selector).siblings(".load-container").siblings('.shiny-bound-output').css('visibility', 'visible'); // if there is a proxy div, show the previous output in case it was hidden $(selector).siblings(".shiny-spinner-placeholder").siblings('.shiny-bound-output').removeClass('shiny-spinner-hidden'); } function update_spinner(id) { if (!(id in output_states)) { show_spinner(id); } if (output_states[id] <= 0) { show_spinner(id); } else { hide_spinner(id); } } $(document).on('shiny:bound', function(event){ /* if not bound before, then set the value to 0 */ if (!(event.target.id in output_states)) { output_states[event.target.id] = 0; } update_spinner(event.target.id); }); /* When recalculating starts, show the spinner container & hide the output */ $(document).on('shiny:outputinvalidated', function(event) { output_states[event.target.id] = 0; update_spinner(event.target.id); }); /* When new value or error comes in, hide spinner container (if any) & show the output */ $(document).on('shiny:value shiny:error', function(event) { output_states[event.target.id] = 1; update_spinner(event.target.id); }); }()); shinycssloaders/inst/css-loaders/0000755000176200001440000000000013607441536016674 5ustar liggesusersshinycssloaders/inst/css-loaders/Gruntfile.js0000644000176200001440000000212413607376045021172 0ustar liggesusersmodule.exports = function(grunt) { // Project configuration. grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), jade: { compile: { files: [{ expand: true, cwd: 'jade/', src: ['**/*.jade'], dest: '', ext: '.html' }] } }, less: { src: { expand: true, cwd: 'less/', src: ['**/*.less'], dest: 'css/', ext: '.css' } }, sass: { options: { sourcemap:'none' }, src: { expand: true, cwd: 'sass/', src: ['**/*.scss'], dest: 'css/', ext: '.css' } }, watch: { files: ['less/**/*.less','jade/**/*.jade'], tasks: ['default'] } }); grunt.loadNpmTasks('grunt-contrib-jade'); grunt.loadNpmTasks('grunt-contrib-less'); grunt.loadNpmTasks('grunt-contrib-sass'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.registerTask('default', ['less','jade','watch']); }; shinycssloaders/inst/css-loaders/LICENSE0000644000176200001440000000210613607376045017702 0ustar liggesusersThe MIT License (MIT) Copyright (c) 2014 Luke Haas Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.shinycssloaders/inst/css-loaders/bower.json0000644000176200001440000000077513607376045020720 0ustar liggesusers{ "name": "css-loading-spinners", "version": "1.0.0", "homepage": "https://github.com/lukehaas/css-loaders", "authors": [ "Luke Haas " ], "description": "A collection of single element loading spinners, animated with CSS ", "main": "css", "moduleType": [ "globals" ], "keywords": [ "CSS", "spinner", "loader" ], "license": "MIT", "ignore": [ "**/.*", "node_modules", "bower_components", "tests" ] } shinycssloaders/inst/css-loaders/README.md0000644000176200001440000000403313607376045020155 0ustar liggesusers# [Single Element CSS Spinners](http://projects.lukehaas.me/css-loaders) This is a collection of loading spinners animated with CSS. Each spinner consists of a single `div` with a class of `loader` and content text of "Loading...". The text is for screen readers and can be used as a fallback state for older browsers. The aim of this project was to create a set of minimal loading spinners that are visually appealing and also convey their intended meaning. A strict limit of one element per loader (not including pseudo-elements) was placed on this project based on the belief that something as simple as a loader doesn't deserve more. Each loader is given a font size in pixels and all other sizes are in ems so to change the size of a loader, just adjust the font-size. ## Demo [![css-loaders-screenshot](https://raw.githubusercontent.com/lukehaas/css-loaders/step2/images/css-loaders-screenshot.jpg)](http://projects.lukehaas.me/css-loaders) > [Check it live](http://projects.lukehaas.me/css-loaders). ## Browser Support ![IE](https://raw.github.com/alrra/browser-logos/master/internet-explorer/internet-explorer_48x48.png) | ![Chrome](https://raw.github.com/alrra/browser-logos/master/chrome/chrome_48x48.png) | ![Firefox](https://raw.github.com/alrra/browser-logos/master/firefox/firefox_48x48.png) | ![Opera](https://raw.github.com/alrra/browser-logos/master/opera/opera_48x48.png) | ![Safari](https://raw.github.com/alrra/browser-logos/master/safari/safari_48x48.png) --- | --- | --- | --- | --- | IE 10+ ✔ | Chrome 4.0+ ✔ | Firefox 16.0+ ✔ | Opera 15.0+ ✔ | Safari 4.0+ ✔ | ## Contributing 1. Fork it! 2. Create your feature branch: `git checkout -b my-new-feature` 3. Commit your changes: `git commit -m 'Add some feature'` 4. Push to the branch: `git push origin my-new-feature` 5. Submit a pull request :) ## History For detailed changelog, check [Releases](https://github.com/lukehaas/css-loaders/releases). ## License [MIT License](https://github.com/lukehaas/css-loaders/blob/step2/LICENSE) shinycssloaders/inst/css-loaders/less/0000755000176200001440000000000013607376045017644 5ustar liggesusersshinycssloaders/inst/css-loaders/less/load5.less0000644000176200001440000000717213607376045021547 0ustar liggesusers@foreground: #fff; .load5 { .loader { margin:100px auto; font-size:25px; width:1em; height:1em; border-radius:50%; position:relative; text-indent:-9999em; -webkit-animation:load5 1.1s infinite ease; animation:load5 1.1s infinite ease; -webkit-transform: translateZ(0); -ms-transform: translateZ(0); transform: translateZ(0); } } @-webkit-keyframes load5 {.load5-frames;} @keyframes load5 {.load5-frames;} .load5-frames() { 0%, 100% { box-shadow:0em -2.6em 0em 0em fade(@foreground,100%), 1.8em -1.8em 0 0em fade(@foreground,20%), 2.5em 0em 0 0em fade(@foreground,20%), 1.75em 1.75em 0 0em fade(@foreground,20%), 0em 2.5em 0 0em fade(@foreground,20%), -1.8em 1.8em 0 0em fade(@foreground,20%), -2.6em 0em 0 0em fade(@foreground,50%), -1.8em -1.8em 0 0em fade(@foreground,70%); } 12.5% { box-shadow:0em -2.6em 0em 0em fade(@foreground,70%), 1.8em -1.8em 0 0em fade(@foreground,100%), 2.5em 0em 0 0em fade(@foreground,20%), 1.75em 1.75em 0 0em fade(@foreground,20%), 0em 2.5em 0 0em fade(@foreground,20%), -1.8em 1.8em 0 0em fade(@foreground,20%), -2.6em 0em 0 0em fade(@foreground,20%), -1.8em -1.8em 0 0em fade(@foreground,50%); } 25% { box-shadow:0em -2.6em 0em 0em fade(@foreground,50%), 1.8em -1.8em 0 0em fade(@foreground,70%), 2.5em 0em 0 0em fade(@foreground,100%), 1.75em 1.75em 0 0em fade(@foreground,20%), 0em 2.5em 0 0em fade(@foreground,20%), -1.8em 1.8em 0 0em fade(@foreground,20%), -2.6em 0em 0 0em fade(@foreground,20%), -1.8em -1.8em 0 0em fade(@foreground,20%); } 37.5% { box-shadow:0em -2.6em 0em 0em fade(@foreground,20%), 1.8em -1.8em 0 0em fade(@foreground,50%), 2.5em 0em 0 0em fade(@foreground,70%), 1.75em 1.75em 0 0em fade(@foreground,100%), 0em 2.5em 0 0em fade(@foreground,20%), -1.8em 1.8em 0 0em fade(@foreground,20%), -2.6em 0em 0 0em fade(@foreground,20%), -1.8em -1.8em 0 0em fade(@foreground,20%); } 50% { box-shadow:0em -2.6em 0em 0em fade(@foreground,20%), 1.8em -1.8em 0 0em fade(@foreground,20%), 2.5em 0em 0 0em fade(@foreground,50%), 1.75em 1.75em 0 0em fade(@foreground,70%), 0em 2.5em 0 0em fade(@foreground,100%), -1.8em 1.8em 0 0em fade(@foreground,20%), -2.6em 0em 0 0em fade(@foreground,20%), -1.8em -1.8em 0 0em fade(@foreground,20%); } 62.5% { box-shadow:0em -2.6em 0em 0em fade(@foreground,20%), 1.8em -1.8em 0 0em fade(@foreground,20%), 2.5em 0em 0 0em fade(@foreground,20%), 1.75em 1.75em 0 0em fade(@foreground,50%), 0em 2.5em 0 0em fade(@foreground,70%), -1.8em 1.8em 0 0em fade(@foreground,100%), -2.6em 0em 0 0em fade(@foreground,20%), -1.8em -1.8em 0 0em fade(@foreground,20%); } 75% { box-shadow:0em -2.6em 0em 0em fade(@foreground,20%), 1.8em -1.8em 0 0em fade(@foreground,20%), 2.5em 0em 0 0em fade(@foreground,20%), 1.75em 1.75em 0 0em fade(@foreground,20%), 0em 2.5em 0 0em fade(@foreground,50%), -1.8em 1.8em 0 0em fade(@foreground,70%), -2.6em 0em 0 0em fade(@foreground,100%), -1.8em -1.8em 0 0em fade(@foreground,20%); } 87.5% { box-shadow:0em -2.6em 0em 0em fade(@foreground,20%), 1.8em -1.8em 0 0em fade(@foreground,20%), 2.5em 0em 0 0em fade(@foreground,20%), 1.75em 1.75em 0 0em fade(@foreground,20%), 0em 2.5em 0 0em fade(@foreground,20%), -1.8em 1.8em 0 0em fade(@foreground,50%), -2.6em 0em 0 0em fade(@foreground,70%), -1.8em -1.8em 0 0em fade(@foreground,100%); } } shinycssloaders/inst/css-loaders/less/load1.less0000644000176200001440000000204213607376045021532 0ustar liggesusers@foreground: #FFF; .load1 { .loader, .loader:before, .loader:after { background:@foreground; -webkit-animation:load1 1s infinite ease-in-out; animation:load1 1s infinite ease-in-out; width:1em; height:4em; } .loader { color:@foreground; text-indent:-9999em; margin:88px auto; position:relative; font-size:11px; -webkit-transform: translateZ(0); -ms-transform: translateZ(0); transform: translateZ(0); -webkit-animation-delay:-0.16s; animation-delay:-0.16s; &:before, &:after { position:absolute; top:0; content:''; } &:before { left:-1.5em; -webkit-animation-delay:-0.32s; animation-delay:-0.32s; } &:after { left:1.5em; } } } @-webkit-keyframes load1 {.load1-frames;} @keyframes load1 {.load1-frames;} .load1-frames() { 0%, 80%, 100% { box-shadow:0 0; height:4em; } 40% { box-shadow:0 -2em; height:5em; } } shinycssloaders/inst/css-loaders/less/load7.less0000644000176200001440000000213313607376045021541 0ustar liggesusers@foreground: #fff; .load7 { .loader, .loader:before, .loader:after { border-radius:50%; width:2.5em; height:2.5em; -webkit-animation-fill-mode: both; animation-fill-mode: both; -webkit-animation:load7 1.8s infinite ease-in-out; animation:load7 1.8s infinite ease-in-out; } .loader { color:@foreground; font-size:10px; margin:80px auto; position:relative; text-indent:-9999em; -webkit-transform: translateZ(0); -ms-transform: translateZ(0); transform: translateZ(0); -webkit-animation-delay:-0.16s; animation-delay:-0.16s; &:before, &:after { content:''; position:absolute; top:0; } &:before { left:-3.5em; -webkit-animation-delay:-0.32s; animation-delay:-0.32s; } &:after { left:3.5em; } } } @-webkit-keyframes load7 {.load7-frames;} @keyframes load7 {.load7-frames;} .load7-frames() { 0%, 80%, 100% { box-shadow:0 2.5em 0 -1.3em; } 40% { box-shadow:0 2.5em 0 0; } } shinycssloaders/inst/css-loaders/less/load3.less0000644000176200001440000000320613607376045021537 0ustar liggesusers@background: hsl(179,88%,41%); @foreground: #FFF; .load3 { .loader { font-size:10px; margin:50px auto; text-indent:-9999em; width:11em; height:11em; border-radius:50%; background: @foreground; background: -moz-linear-gradient(left, fade(@foreground,100%) 10%, fade(@foreground,0%) 42%); background: -webkit-linear-gradient(left, fade(@foreground,100%) 10%,fade(@foreground,0%) 42%); background: -o-linear-gradient(left, fade(@foreground,100%) 10%,fade(@foreground,0%) 42%); background: -ms-linear-gradient(left, fade(@foreground,100%) 10%,fade(@foreground,0%) 42%); background: linear-gradient(to right, fade(@foreground,100%) 10%,fade(@foreground,0%) 42%); position: relative; -webkit-animation:load3 1.4s infinite linear; animation:load3 1.4s infinite linear; -webkit-transform: translateZ(0); -ms-transform: translateZ(0); transform: translateZ(0); &:before { width:50%; height:50%; background: @foreground; border-radius: 100% 0 0 0; position:absolute; top:0; left:0; content:''; } &:after { background:@background; width:75%; height:75%; border-radius:50%; content:''; margin:auto; position: absolute; top: 0; left: 0; bottom: 0; right: 0; } } } @-webkit-keyframes load3 {.load3-frames;} @keyframes load3 {.load3-frames;} .load3-frames() { 0% { -webkit-transform:rotate(0deg); transform:rotate(0deg); } 100% { -webkit-transform:rotate(360deg); transform:rotate(360deg); } } shinycssloaders/inst/css-loaders/less/load6.less0000644000176200001440000000334113607376045021542 0ustar liggesusers@foreground: #fff; .load6 { .loader { color:@foreground; font-size:90px; text-indent:-9999em; overflow: hidden; width:1em; height:1em; border-radius:50%; margin:72px auto; position:relative; -webkit-transform: translateZ(0); -ms-transform: translateZ(0); transform: translateZ(0); -webkit-animation:load6 1.7s infinite ease; animation:load6 1.7s infinite ease; } } @-webkit-keyframes load6 {.load6-frames;} @keyframes load6 {.load6-frames;} .load6-frames() { 0% { -webkit-transform:rotate(0deg); transform:rotate(0deg); box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em; } 5%, 95% { box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em; } 10%, 59% { box-shadow: 0 -0.83em 0 -0.4em, -0.087em -0.825em 0 -0.42em, -0.173em -0.812em 0 -0.44em, -0.256em -0.789em 0 -0.46em, -0.297em -0.775em 0 -0.477em; } 20% { box-shadow: 0 -0.83em 0 -0.4em, -0.338em -0.758em 0 -0.42em, -0.555em -0.617em 0 -0.44em, -0.671em -0.488em 0 -0.46em, -0.749em -0.34em 0 -0.477em; } 38% { box-shadow: 0 -0.83em 0 -0.4em, -0.377em -0.74em 0 -0.42em, -0.645em -0.522em 0 -0.44em, -0.775em -0.297em 0 -0.46em, -0.82em -0.09em 0 -0.477em; } 100% { -webkit-transform:rotate(360deg); transform:rotate(360deg); box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em; } } shinycssloaders/inst/css-loaders/less/fallback.less0000644000176200001440000000106113607376045022271 0ustar liggesusers/* Import this if you are using modernizr (recommended) It means that loaders will fallback to a text state of simply saying "Loading..." in older browsers */ .no-cssanimations { .load-container { .loader { text-indent:0; text-align:center; color:#FFF; font-size:17px; background:none; border:0 none; width:auto; height:auto; margin:1em auto; overflow:visible; box-shadow:none; -webkit-animation:none; animation:none; &:before, &:after { display:none; } } } } shinycssloaders/inst/css-loaders/less/load2.less0000644000176200001440000000277513607376045021550 0ustar liggesusers@background: hsl(179,88%,41%); @foreground: #FFF; .load2 { .loader, .loader:before, .loader:after { border-radius:50%; } .loader { color:@foreground; font-size:11px; text-indent:-99999em; margin:55px auto; position:relative; width:10em; height:10em; box-shadow: inset 0 0 0 1em; -webkit-transform: translateZ(0); -ms-transform: translateZ(0); transform: translateZ(0); &:before, &:after { position:absolute; content:''; } &:before { width:5.2em; height:10.2em; background: @background; border-radius: 10.2em 0 0 10.2em; top:-0.1em; left:-0.1em; -webkit-transform-origin:5.1em 5.1em; transform-origin:5.1em 5.1em; -webkit-animation:load2 2s infinite ease 1.5s; animation:load2 2s infinite ease 1.5s; } &:after { width:5.2em; height:10.2em; background: @background; border-radius: 0 10.2em 10.2em 0; top:-0.1em; left:4.9em; -webkit-transform-origin:0.1em 5.1em; transform-origin:0.1em 5.1em; -webkit-animation:load2 2s infinite ease; animation:load2 2s infinite ease; } } } @-webkit-keyframes load2 {.load2-frames;} @keyframes load2 {.load2-frames;} .load2-frames() { 0% { -webkit-transform:rotate(0deg); transform:rotate(0deg); } 100% { -webkit-transform:rotate(360deg); transform:rotate(360deg); } } shinycssloaders/inst/css-loaders/less/load8.less0000644000176200001440000000164013607376045021544 0ustar liggesusers@foreground: #fff; .load8 { .loader, .loader:after { border-radius:50%; width:10em; height:10em; } .loader { margin:60px auto; font-size:10px; position:relative; text-indent:-9999em; border-top:1.1em solid fade(@foreground,20%); border-right:1.1em solid fade(@foreground,20%); border-bottom:1.1em solid fade(@foreground,20%); border-left:1.1em solid fade(@foreground,100%); -webkit-transform: translateZ(0); -ms-transform: translateZ(0); transform: translateZ(0); -webkit-animation:load8 1.1s infinite linear; animation:load8 1.1s infinite linear; } } @-webkit-keyframes load8 {.load8-frames;} @keyframes load8 {.load8-frames;} .load8-frames() { 0% { -webkit-transform:rotate(0deg); transform:rotate(0deg); } 100% { -webkit-transform:rotate(360deg); transform:rotate(360deg); } } shinycssloaders/inst/css-loaders/less/load4.less0000644000176200001440000000403513607376045021541 0ustar liggesusers@foreground: #FFF; .load4 { .loader { color:@foreground; font-size:20px; margin:100px auto; width:1em; height:1em; border-radius:50%; position:relative; text-indent:-9999em; -webkit-animation:load4 1.3s infinite linear; animation:load4 1.3s infinite linear; -webkit-transform: translateZ(0); -ms-transform: translateZ(0); transform: translateZ(0); } } @-webkit-keyframes load4 {.load4-frames;} @keyframes load4 {.load4-frames;} .load4-frames() { 0%, 100% { box-shadow:0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0; } 12.5% { box-shadow:0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em; } 25% { box-shadow:0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em; } 37.5% { box-shadow:0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em, 0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em; } 50% { box-shadow:0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em, 0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em; } 62.5% { box-shadow:0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em; } 75% { box-shadow:0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em, -2em -2em 0 0; } 87.5% { box-shadow:0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em; } } shinycssloaders/inst/css-loaders/package.json0000644000176200001440000000066313607376045021171 0ustar liggesusers{ "name": "css-loaders", "version": "0.1.0", "description": "", "main": "Gruntfile.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "Luke Haas", "license": "BSD", "devDependencies": { "grunt": "~0.4.4", "grunt-contrib-jade": "~0.11.0", "grunt-contrib-less": "^0.11.0", "grunt-contrib-sass": "^1.0.0", "grunt-contrib-watch": "^0.6.1" } } shinycssloaders/inst/css-loaders/sass/0000755000176200001440000000000013607376045017647 5ustar liggesusersshinycssloaders/inst/css-loaders/sass/load8.scss0000644000176200001440000000166313607376045021561 0ustar liggesusers$foreground: #fff; .load8 { .loader, .loader:after { border-radius:50%; width:10em; height:10em; } .loader { margin:60px auto; font-size:10px; position:relative; text-indent:-9999em; border-top:1.1em solid rgba($foreground,0.2); border-right:1.1em solid rgba($foreground,0.2); border-bottom:1.1em solid rgba($foreground,0.2); border-left:1.1em solid rgba($foreground,1); -webkit-transform: translateZ(0); -ms-transform: translateZ(0); transform: translateZ(0); -webkit-animation:load8 1.1s infinite linear; animation:load8 1.1s infinite linear; } } @mixin load8-frames() { 0% { -webkit-transform:rotate(0deg); transform:rotate(0deg); } 100% { -webkit-transform:rotate(360deg); transform:rotate(360deg); } } @-webkit-keyframes load8 {@include load8-frames;} @keyframes load8 {@include load8-frames;} shinycssloaders/inst/css-loaders/sass/load6.scss0000644000176200001440000000336713607376045021562 0ustar liggesusers$foreground: #fff; .load6 { .loader { color:$foreground; font-size:90px; text-indent:-9999em; overflow: hidden; width:1em; height:1em; border-radius:50%; margin:72px auto; position:relative; -webkit-transform: translateZ(0); -ms-transform: translateZ(0); transform: translateZ(0); -webkit-animation:load6 1.7s infinite ease; animation:load6 1.7s infinite ease; } } @mixin load6-frames() { 0% { -webkit-transform:rotate(0deg); transform:rotate(0deg); box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em; } 5%, 95% { box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em; } 10%, 59% { box-shadow: 0 -0.83em 0 -0.4em, -0.087em -0.825em 0 -0.42em, -0.173em -0.812em 0 -0.44em, -0.256em -0.789em 0 -0.46em, -0.297em -0.775em 0 -0.477em; } 20% { box-shadow: 0 -0.83em 0 -0.4em, -0.338em -0.758em 0 -0.42em, -0.555em -0.617em 0 -0.44em, -0.671em -0.488em 0 -0.46em, -0.749em -0.34em 0 -0.477em; } 38% { box-shadow: 0 -0.83em 0 -0.4em, -0.377em -0.74em 0 -0.42em, -0.645em -0.522em 0 -0.44em, -0.775em -0.297em 0 -0.46em, -0.82em -0.09em 0 -0.477em; } 100% { -webkit-transform:rotate(360deg); transform:rotate(360deg); box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em; } } @-webkit-keyframes load6 {@include load6-frames;} @keyframes load6 {@include load6-frames;} shinycssloaders/inst/css-loaders/sass/load3.scss0000644000176200001440000000321013607376045021542 0ustar liggesusers$background: hsl(179,88%,41%); $foreground: #FFF; .load3 { .loader { font-size:10px; margin:50px auto; text-indent:-9999em; width:11em; height:11em; border-radius:50%; background: $foreground; background: -moz-linear-gradient(left, rgba($foreground,1) 10%, rgba($foreground,0) 42%); background: -webkit-linear-gradient(left, rgba($foreground,1) 10%,rgba($foreground,0) 42%); background: -o-linear-gradient(left, rgba($foreground,1) 10%,rgba($foreground,0) 42%); background: -ms-linear-gradient(left, rgba($foreground,1) 10%,rgba($foreground,0) 42%); background: linear-gradient(to right, rgba($foreground,1) 10%,rgba($foreground,0) 42%); position: relative; -webkit-animation:load3 1.4s infinite linear; animation:load3 1.4s infinite linear; -webkit-transform: translateZ(0); -ms-transform: translateZ(0); transform: translateZ(0); &:before { width:50%; height:50%; background: $foreground; border-radius: 100% 0 0 0; position:absolute; top:0; left:0; content:''; } &:after { background:$background; width:75%; height:75%; border-radius:50%; content:''; margin:auto; position: absolute; top: 0; left: 0; bottom: 0; right: 0; } } } @mixin load3-frames() { 0% { -webkit-transform:rotate(0deg); transform:rotate(0deg); } 100% { -webkit-transform:rotate(360deg); transform:rotate(360deg); } } @-webkit-keyframes load3 {@include load3-frames;} @keyframes load3 {@include load3-frames;} shinycssloaders/inst/css-loaders/sass/load4.scss0000644000176200001440000000406513607376045021554 0ustar liggesusers$foreground: #FFF; .load4 { .loader { color:$foreground; font-size:20px; margin:100px auto; width:1em; height:1em; border-radius:50%; position:relative; text-indent:-9999em; -webkit-animation:load4 1.3s infinite linear; animation:load4 1.3s infinite linear; -webkit-transform: translateZ(0); -ms-transform: translateZ(0); transform: translateZ(0); } } @mixin load4-frames() { 0%, 100% { box-shadow:0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0; } 12.5% { box-shadow:0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em; } 25% { box-shadow:0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em; } 37.5% { box-shadow:0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em, 0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em; } 50% { box-shadow:0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em, 0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em; } 62.5% { box-shadow:0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em; } 75% { box-shadow:0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em, -2em -2em 0 0; } 87.5% { box-shadow:0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em; } } @-webkit-keyframes load4 {@include load4-frames;} @keyframes load4 {@include load4-frames;} shinycssloaders/inst/css-loaders/sass/fallback.scss0000644000176200001440000000106113607376045022301 0ustar liggesusers/* Import this if you are using modernizr (recommended) It means that loaders will fallback to a text state of simply saying "Loading..." in older browsers */ .no-cssanimations { .load-container { .loader { text-indent:0; text-align:center; color:#FFF; font-size:17px; background:none; border:0 none; width:auto; height:auto; margin:1em auto; overflow:visible; box-shadow:none; -webkit-animation:none; animation:none; &:before, &:after { display:none; } } } } shinycssloaders/inst/css-loaders/sass/load5.scss0000644000176200001440000000717013607376045021555 0ustar liggesusers$foreground: #fff; .load5 { .loader { margin:100px auto; font-size:25px; width:1em; height:1em; border-radius:50%; position:relative; text-indent:-9999em; -webkit-animation:load5 1.1s infinite ease; animation:load5 1.1s infinite ease; -webkit-transform: translateZ(0); -ms-transform: translateZ(0); transform: translateZ(0); } } @mixin load5-frames() { 0%, 100% { box-shadow:0em -2.6em 0em 0em rgba($foreground,1), 1.8em -1.8em 0 0em rgba($foreground,0.2), 2.5em 0em 0 0em rgba($foreground,0.2), 1.75em 1.75em 0 0em rgba($foreground,0.2), 0em 2.5em 0 0em rgba($foreground,0.2), -1.8em 1.8em 0 0em rgba($foreground,0.2), -2.6em 0em 0 0em rgba($foreground,0.5), -1.8em -1.8em 0 0em rgba($foreground,0.7); } 12.5% { box-shadow:0em -2.6em 0em 0em rgba($foreground,0.7), 1.8em -1.8em 0 0em rgba($foreground,1), 2.5em 0em 0 0em rgba($foreground,0.2), 1.75em 1.75em 0 0em rgba($foreground,0.2), 0em 2.5em 0 0em rgba($foreground,0.2), -1.8em 1.8em 0 0em rgba($foreground,0.2), -2.6em 0em 0 0em rgba($foreground,0.2), -1.8em -1.8em 0 0em rgba($foreground,0.5); } 25% { box-shadow:0em -2.6em 0em 0em rgba($foreground,0.5), 1.8em -1.8em 0 0em rgba($foreground,0.7), 2.5em 0em 0 0em rgba($foreground,1), 1.75em 1.75em 0 0em rgba($foreground,0.2), 0em 2.5em 0 0em rgba($foreground,0.2), -1.8em 1.8em 0 0em rgba($foreground,0.2), -2.6em 0em 0 0em rgba($foreground,0.2), -1.8em -1.8em 0 0em rgba($foreground,0.2); } 37.5% { box-shadow:0em -2.6em 0em 0em rgba($foreground,0.2), 1.8em -1.8em 0 0em rgba($foreground,0.5), 2.5em 0em 0 0em rgba($foreground,0.7), 1.75em 1.75em 0 0em rgba($foreground,1), 0em 2.5em 0 0em rgba($foreground,0.2), -1.8em 1.8em 0 0em rgba($foreground,0.2), -2.6em 0em 0 0em rgba($foreground,0.2), -1.8em -1.8em 0 0em rgba($foreground,0.2); } 50% { box-shadow:0em -2.6em 0em 0em rgba($foreground,0.2), 1.8em -1.8em 0 0em rgba($foreground,0.2), 2.5em 0em 0 0em rgba($foreground,0.5), 1.75em 1.75em 0 0em rgba($foreground,0.7), 0em 2.5em 0 0em rgba($foreground,1), -1.8em 1.8em 0 0em rgba($foreground,0.2), -2.6em 0em 0 0em rgba($foreground,0.2), -1.8em -1.8em 0 0em rgba($foreground,0.2); } 62.5% { box-shadow:0em -2.6em 0em 0em rgba($foreground,0.2), 1.8em -1.8em 0 0em rgba($foreground,0.2), 2.5em 0em 0 0em rgba($foreground,0.2), 1.75em 1.75em 0 0em rgba($foreground,0.5), 0em 2.5em 0 0em rgba($foreground,0.7), -1.8em 1.8em 0 0em rgba($foreground,1), -2.6em 0em 0 0em rgba($foreground,0.2), -1.8em -1.8em 0 0em rgba($foreground,0.2); } 75% { box-shadow:0em -2.6em 0em 0em rgba($foreground,0.2), 1.8em -1.8em 0 0em rgba($foreground,0.2), 2.5em 0em 0 0em rgba($foreground,0.2), 1.75em 1.75em 0 0em rgba($foreground,0.2), 0em 2.5em 0 0em rgba($foreground,0.5), -1.8em 1.8em 0 0em rgba($foreground,0.7), -2.6em 0em 0 0em rgba($foreground,1), -1.8em -1.8em 0 0em rgba($foreground,0.2); } 87.5% { box-shadow:0em -2.6em 0em 0em rgba($foreground,0.2), 1.8em -1.8em 0 0em rgba($foreground,0.2), 2.5em 0em 0 0em rgba($foreground,0.2), 1.75em 1.75em 0 0em rgba($foreground,0.2), 0em 2.5em 0 0em rgba($foreground,0.2), -1.8em 1.8em 0 0em rgba($foreground,0.5), -2.6em 0em 0 0em rgba($foreground,0.7), -1.8em -1.8em 0 0em rgba($foreground,1); } } @-webkit-keyframes load5 {@include load5-frames;} @keyframes load5 {@include load5-frames;} shinycssloaders/inst/css-loaders/sass/load7.scss0000644000176200001440000000216113607376045021552 0ustar liggesusers$foreground: #fff; .load7 { .loader, .loader:before, .loader:after { border-radius:50%; width:2.5em; height:2.5em; -webkit-animation-fill-mode: both; animation-fill-mode: both; -webkit-animation:load7 1.8s infinite ease-in-out; animation:load7 1.8s infinite ease-in-out; } .loader { color:$foreground; font-size:10px; margin:80px auto; position:relative; text-indent:-9999em; -webkit-transform: translateZ(0); -ms-transform: translateZ(0); transform: translateZ(0); -webkit-animation-delay:-0.16s; animation-delay:-0.16s; &:before, &:after { content:''; position:absolute; top:0; } &:before { left:-3.5em; -webkit-animation-delay:-0.32s; animation-delay:-0.32s; } &:after { left:3.5em; } } } @mixin load7-frames() { 0%, 80%, 100% { box-shadow:0 2.5em 0 -1.3em; } 40% { box-shadow:0 2.5em 0 0; } } @-webkit-keyframes load7 {@include load7-frames;} @keyframes load7 {@include load7-frames;} shinycssloaders/inst/css-loaders/sass/load2.scss0000644000176200001440000000302313607376045021543 0ustar liggesusers$background: hsl(179,88%,41%); $foreground: #FFF; .load2 { .loader, .loader:before, .loader:after { border-radius:50%; } .loader { color:$foreground; font-size:11px; text-indent:-99999em; margin:55px auto; position:relative; width:10em; height:10em; box-shadow: inset 0 0 0 1em; -webkit-transform: translateZ(0); -ms-transform: translateZ(0); transform: translateZ(0); &:before, &:after { position:absolute; content:''; } &:before { width:5.2em; height:10.2em; background: $background; border-radius: 10.2em 0 0 10.2em; top:-0.1em; left:-0.1em; -webkit-transform-origin:5.1em 5.1em; transform-origin:5.1em 5.1em; -webkit-animation:load2 2s infinite ease 1.5s; animation:load2 2s infinite ease 1.5s; } &:after { width:5.2em; height:10.2em; background: $background; border-radius: 0 10.2em 10.2em 0; top:-0.1em; left:4.9em; -webkit-transform-origin:0.1em 5.1em; transform-origin:0.1em 5.1em; -webkit-animation:load2 2s infinite ease; animation:load2 2s infinite ease; } } } @mixin load2-frames() { 0% { -webkit-transform:rotate(0deg); transform:rotate(0deg); } 100% { -webkit-transform:rotate(360deg); transform:rotate(360deg); } } @-webkit-keyframes load2 {@include load2-frames;} @keyframes load2 {@include load2-frames;} shinycssloaders/inst/css-loaders/sass/load1.scss0000644000176200001440000000206013607376045021542 0ustar liggesusers$foreground: #FFF; .load1 { .loader, .loader:before, .loader:after { background:$foreground; -webkit-animation:load1 1s infinite ease-in-out; animation:load1 1s infinite ease-in-out; width:1em; height:4em; } .loader { color:$foreground; text-indent:-9999em; margin:88px auto; position:relative; font-size:11px; -webkit-transform: translateZ(0); -ms-transform: translateZ(0); transform: translateZ(0); -webkit-animation-delay:-0.16s; animation-delay:-0.16s; &:before, &:after { position:absolute; top:0; content:''; } &:before { left:-1.5em; -webkit-animation-delay:-0.32s; animation-delay:-0.32s; } &:after { left:1.5em; } } } @mixin load1-frames { 0%, 80%, 100% { box-shadow:0 0; height:4em; } 40% { box-shadow:0 -2em; height:5em; } } @-webkit-keyframes load1 {@include load1-frames;} @keyframes load1 {@include load1-frames;} shinycssloaders/inst/css-loaders/images/0000755000176200001440000000000013607376045020143 5ustar liggesusersshinycssloaders/inst/css-loaders/images/css-loaders-screenshot.jpg0000644000176200001440000007375513607376045025260 0ustar liggesusersExifII*Ducky4-http://ns.adobe.com/xap/1.0/ !Adobed /JAw     ! !%%%%%%%%%%   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%   0@!12P`"3#p$4ABD6!1A@Qq 0a"2BRrP`#3bCpSsc$!1A0@P`Qaq"2 bpѰR#!1AQ @aq0P`p A>ſ~}zO]l S#}I:/O7puw=/zOl@tڞUMS&f=-.ɭm.nNU6p2l7W0ž^=/̦֯/7kddƾC&ͦaC*4=)}|c13PxN|ݺ|\>{x>|Fb#4zxMhR<봽O;aebܕ^#iR3$G;,t?>;it? ~/od$ J`=`"iz}%/\d^Yhb>LfȽs@zd^IQ1 "Ez &( D`,4YhE$%/\d^YhusWlQ@c0E,4 "ɨ$I1@J&3bYd^ſizfr[[_D/\ [~Zumpy}7 ";~]c0GW?9f "u{N?{8ޛ~_. "Sr\>GW "ez/BjbLfhl^O9ͮ,4 ?Coc94 [Q}'krȽs@Gt~u ,4I1@J&34}^U6z/S /\>=/+m0riSl@d^lt>Ȼ,ɦEwookobLfhl^1G@d^}~e}`/\xT>/d^;>:xLP; WMKF(7,4xpn,4'vYh{g}`LP; WM폗c &,4 oKǮhEָP?kܼ/\$(8z "|yk=/\:?Ms?/ɨbLfȽs@zM',4 ]~{IQ1 "Ez &( D`,4YhE$%/\d^YhbLfȽs@zd^IQ1%k[j@Ƚs@ 'P " DjZ/\28I1@J&3f=-Lo"qWYh.W6v={aɦMLK/\beSfQjqc__[Yh.Ytɦz-"N*Y4oIQi$'8&8&\$,4YhE$$,4YhE$$,4YhE$${=wl "Ez &( &(7z^|7GYh/\,4E+qII~lltZkoQl9ϛs &=zzd^ c&^=-\-vDž}H@I1@I1@uz~r۞k]6鵉}\Kz_,4 "oo_ʦEv54c5 &( &( '7M/FJ " =~Mzd^Qoq~O?Mc.M bb/\tľE mb_Vq}gIǪq/\v:>gˡ IIǷj-FnVcŽ " '|od^ m~~9=|,4vq[@(-$$lz-n/?L=/Mf^|fYh/\ut6:^#is}ߞd^*ra@LPLP˦=5[h/\2o5\ "@ "6{6,] P$$ " ҹ?Cs5zd^_1Yʦλ.I1@I1@dW>f=ek*894/\d^Yh~SW ǹFI1@I1@fcɮ%qooZ-fȮM<{` "_y~Mzd^ 3V\&94`$$=,JfȮ-/'zurs>>/\,4=Mdd"MII/ll_Vb/\d^Yhbb/\d^Yhbb/\d^Yhbbg]3ATe,4Ml\͏l*,K/\J(W8t@ "ek;ء4qoI[}H^HM %%Xgؚ-T&%c5qP J-@%8*/PLf2qoi}fb%L]M|Kz}/v1M2VFOsPU& /e+Xv׫ ISl ucuSfX4 X'4f2vC5?a AiQPD2܀oAzn N}*hܸU-p V*[QlA; ]p. pE~.X" I (fYbi)ƴP{Im(} C;SѵkOb*:DUPTO}сA76TnD6 A4 f]7 @u AȎU9UrUr 4E+Z:P(zA-Urh%89OtZUlӯ9ZA-XίrrqOw¹M}tpV \!Mg}j?2o'D(D#]հ#sHL}5sj?C#Q \ڢ(XOmnPLϔ14d[ʍ4I9wL!(}&P㶱EW )i+‹AAgu4 $ |m̕UM5T3^ʡ@S=iT(Qi[zg봪BPg鴭U -*"մBPO91nW\z1">JTA}x Miݣ"}qP៸zB2C1SF5qd1L}!=rP4oC{jE4PHʭFfL(j6_( y:՟A˽C*S2k*zUUUW]OS5Eh?EEEOAUn[un%[~oEzܷgz܃5QQQQSEEEEEM 4TTTTTpPծ} n[\kr/Eo[T!OP+@QP**^ʣB2fvNS4tV3KN/ʜJ٘Ƀ)SA~:93@q~TrI(q{`yIKF&I''[a{_ !y <S{DPa("i-8GK? SuB #qOR4 yEOd/r"tdcq~Tr[shSN.#dXKqHXZ|` n)s]+fY&k@2߱%H\ޟ%R7yisq;c'rIݸ\|tyv!m/vl~`/-Dzѓ{$bN(E3џ ?k"# 3'v'qDj3?av<dI+u'rHJ)gɒq ׵q'4g[z~0c%sSsgq/'q08MꆘFtre2;Zx{ˎii1:QwƘF߃cg~ dUl49J" -aS6@ DSP2 DF"fbgrmMFVK^V$-MG ѦHybLq$lo5n,K$"G:@-rܷ-rܷ-rܷ-rܷ-rܷ"Vn[n[n[n[n[+rܷ-rܷ-rܷ-rܷ-rܷ-r%n[n[n[n[n[W8ii1:QwƘF߃VSWV#tL5b䈦Iҍ3hV¶M8k*]DTr'^S!v0Pm+x[ª-DSJ1Y~&I#6gb2H#s* @|27g@n[i "L)H4C}=FY&%Nii6,%#7bhN4 Ljp&GGJ4otcO%a k]ՇgxLn4QwEx4EҌ{=S1\Z({ 3w^ES]E':GJ4(;cLtL㯊Jd!-588ܛ-6|;O$* ${q>)M9AT!v6GP؁k_>Hnⷔir!\UyEwyD Uo(8rj^O_H[Ʊ?bF_h!}'H?_n Z ۵\-n[mT`lvLJI$ i5&Grhd;!(yߪ:$}A\\SBfJ۫gIՎP H۫W@"w"kݣdk6ws6wMc9#{ltvW1KVwS5sOWvFל-,X1mtwv0Ko܆ְ_Jfkcuqbٮ_l\F$raܬ-c( gx,xK $JSH?[ήW:׶K`a{m|w!]\|-9# dH$./n{#"Đ y?!_mX@s%7wP>Jc;U\h.66+OŬc} eco<#qM,uPOa5}n$ljA2^vx:76X veg9`#'Sq{-|S[u%VB1㐹mWv_-wq75̂ym.$#Hk monmUK3I#[77W}%? بFpO4&[ol߯[s~gI Row;fVͷ[nv+R 4\5ҷ W[Jvvo}+H;fVҿݤ[ZSSRZZ=c#/)bK k5I+osjn,Jڿ*&MlB+6s+nsh=ųgl{c7 ,T/gʍ'38⼉ s7ʵ\ٟvo}o+y[V򷕼o+y[V򷕼o+y[SV򷕼o+y[V򷕼o+y[V򷕼5V򷕼o+y[V򷕼o+y[V򷕼y[V򷕼o+y[V򷕼o+y[VҿJWk{_om+A5ҷ GAm)"~'pPyoCNQlM(c/C(}_i8{7+8)Zho\ռp_jQ}|O`Wٞr`M;f l@2A'V9o.X@Lqw//yMNv"dk{ 9ysQ{Y%oս`/9s-CW[J^'B |wN"ĔgP,Ƽŏpv(J`Q3+:'Nœ[ A Ԃ7jah`ї(@#{9vLm( V阦*E1NMTY@Er=/][aJEj)˵M\yK$ k4٩d\N"2d!dA bi_ hpQZ_]iU g)|٩+H.Z> 1R^ơ=gD䅶BH# 9Q6]#TMC=;Vbrz?GDۓ$tq! n`f^H0O82k"36fUP' j$iڳ>SPF&N%-'o5V{>^W__'3օcN.)N#Bn~56 XQFQcཱӓ\T,|}T`)x\BoQ ɌSUC-tJN~ SSSq5fLpӿ`T4QM'[pӁ]\*.{#:.cjjiš9%|'UMƉu':^EB%9U`2#{9MGjC (tW 8/O.bzKO0wӑsMJ! O4:W2 K"9f88Ng5c6 ɇn41l}m07p\\PÑUYw 6 ۊ~9SSxډ1 x' 9jP B3S&ƟJ~fB3N^>nފ!S܌e'z}EL?.vOwS:P%GQSS*j$3SS*e@JeMLr$WIP$&;(ŷߤfD6P~ |Q|Q=COuq\seMLYʙS*gux6Su ?tFġ& ;=&e>T g͖rr_'X k%\4i&,+ʟ_zfTm򨇫S/Vb3~Y td{{DL}`6OX3*8(29OQC>V5\Ti,sҶ]EN`uFFǴDV H[(g똱?tSQc=XAHpW(."X情(#Ի50n${:HM3 *Il扔KWRg]`Y 9d{#)?║ZN "BӪ3TDfU,`bn&EDs5 6b##y6\IԩDb7l/v>I9z O=) T P77/C)R9Nu[EZ|O@u mQ) θf4'ʗ4Z ګd(dA8DH+rSf鐾WtPlaU%tdu*7*r 8*c=:.ɬȪK8|qM¿L7Piѩ"ua PVJϐ (D:|oWD+jO0rlzF[4u3s e* G)q L}ܤReURz3Dy/H@E?9 _2U݇WtVQzO1ܪ0dmlg s1a*5do˼ՀIlhdv+!4= V{T)^jdJSb|Xlk*Jd#9/_|A@H9mFKb@6NrS,';#ikUuqoߊyLqXYi+ X)r >YjQ0)4 rrZ1]s՚Ϣ͓kRUEEႶnVjiTZ-9&Yడ,v|vGǴ@#FΕe-/#qk؛<Zas1#iyHAμ n[cH4,&'s3\W[Joj% DbnaU S& Q)ͱH8T[`NQHO}nӇ=as$_<.2q.5I7y6Ez6Pv f)F]vBpֺSv5VUrլx2RmtKP|2OO>5iʢpAm! xA$ǰzK5P*mOs^aK*@(M=V!nYVG=T+5ZV 5\%%>z9JFQlԦS5"2k {pԬ,x"5Y!0=cnVתW0Mʉ YFJl}V6^_39魀}DdʿwEl,2I1jEZOcF\>mMmֱOXwFa.m}A,V\~U#`̞͘޴U1|b~L"?>i~=H:A鯚]j5>#PSLPZ 5/pڇzM)6Wk~tH[ڽ>ᢝʾ&9o W_cR6ެg,9qi:mNs;mU˶mrTMưb,m.&i8 -j?E~uG򯉎[?t6ԍEFU'ou\PD$Kxt*f"_w}UHlG򯉎[?t6ԍI(U>޹uT@}.)6Wč4-[J͙;^tz*7~PɚY|gR6:A,ҙls;ZO\:o{*ltNNɿ)-F+`[g\ZXٲ /z}ä ”t0iPp1R!e?B EmpHɇ`թy`#f/#2QYjs3֟xhAhF)l+lѻ~4nᢝJ&o8NOaV6l&X 0@UeqM9D&vkHCsaY%a1.fo[3C3b]6-g=&٣wׄvŧaYa`;) JZ"%4ݙel_Ehå+/ʝ]%d=#MLǨbT-Fk1/qȧwi{xv n+: \&gk_5ucu! ǩ HV * K:ض%]@3._F;%m:tIsi`֣5jr3/eJ&xi+;c(bVղϰFFם޾:a=4V +- ZdH #57"`7×Z`!Լ:7%ZTmyp^1Au=#kuR)*aV) =٣wEѫ:D/.xhE4V٣w 4nᢝT|Tz G鮒5I>ͥ-'NGp2SUlIP}J%""Wke2" <łjbT0sB79{B?\p@ugȐ `i3 v@PVuΫk ݱL5E @* 3*H'+|l6cQ|=9FI^17f"WYtMj#'.ZX5vJCTN iTIL[ _ʷ?xtT [6%?I/$Chd D/bE0aPOu.#104_{+\esha鞾//72m5Zw^ȵ 9N?OJL[3;c/ E|_|_s˴D)߮ *0e[#3i]1ah6ٲ Ve78//x/,1T`g9~[=xߎ0U`jlMUoŘL_|_|_|_ fn3e=כF..kg^2#3|_X\=LncRNeǨ_(7 /XFPl8QyCS*[򜲇湚df!IN<#hʹDZw)f ߆=Y ܊$a1JWlS0e*q#C"@/X#rַ6ċlmۺVCbFUV,I2FT@8@`zLJf`Pg>x7bZZs @:TR+X B&XFmKa6~#E!+Iz3yG[6J(10ff=ݥ{@(ާna,&;Xj0@0]Qs犃g8 .cze o | kK_X90a9z~#CDЯE6MщSIe>c [q~Ҝ*SXVىRX" u1š1,re:#Ä́s3Pcꀦw 9`bu?􋨥in\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r<ʼἱʼἱʼ ,r,qR b9W - :9 3Wq+]zϮiN3~urT3fD4Ϯ)s3'`G׏„?}s&Hz*3)3 X_X0g^.0ἱʼἱʼ-K.Bn-grAe_ ]k鞅> a ׬i4h=z[iXT1}e[N7#'VZie=/@: gTYRJ*TRJ*TRJTRJ*TRJ*TRJ*TRJ*TRJ*TJ*TRJ*TRJ+ycyc79W?ycyc7ҫs*UH`~UFII| bԀ(/=v--*7ʼXxq3Bz\Ň <ė:^8@1ycj=ҍG9JxLF(K8%aɼXONA;To\Xp3}'&>P9W.1ap̝6&7>3ed^@8N@ؖXJk.MA)"( LJ6|ĥ|Kை^Xph|-&p+x|izB6peW*h=abETׅF ^ʼἱʼ]oIS2")Lp54._5 L %9Xz,3Wh8egtk_Ħ5R=M6]z)һ@@r4SiMvs Wz)CҕUdqj~-ww h|p_n*ڀZ1؊#)4|i)aQ?T@JSiҝ)K`j@NCʏ|B= ?Yr˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\}1_}aTˆa9,~d8'˃3KkgBRp1_}K3?ij]=$is>YJOXi|}a_gBR|񰱊24^ΰ;Q"5Ȉ .k0}W.X`.պ+R[ `U2)PG(1ywl&%vk5osJ26/# M+taL޶qPzĐ R)7;J`]ڀٝF^W_xI>zeX^?a(|1Д42rX9dCX03`?'Ha@$FAY\-NaYqP%3 ᵩ_d p\@x*(ҮAHiCUSt2AXeQ;lB%K!X<bkT [0<@&J=\z2ܣ4 9k1 ^v062-( vp3[(F@1bVt+jw6xB-PˀC4aFwN\s>YJJH8lsW6 ! O*8f1ƕ]مR0+3nܱՔ.HB1s&"*9_ :ߦ(iW=s)?B6<@/:\AXX#~NlF8,q" P߼RUzli Kb-45G;J(Й0ƹt}VͷgFbTw4ԅkNsF&#(W&kE|v J-v~}CBXl %i_\1_}G~u%e9}Mr=:=c@2b:8O*U}1_}`T_,[T+fun[OnW+ۖ2xDu~jR-L0CՆ] XW5/w?q9>hzO<ޏ؟L,M==Yq4^W]vK f}C2O<+WOnW+ۍIਥ~,YھHR w"z^"&ڼpJG#[V'<,ՙ,5ڦEQצqw`$ &,Zo6қJi 5hvucy HB0 ejY+@: 5ec81(&*I{$VDx!sK1JYe(RblDeeL h8FWR&i5:ʟ-YH A}ᒁΘއH)&y\ESnFc&5%b2E ?S(%ѝS]]V$˾w%a:ȫ0΁!z@'Y/pbC294KPs2'r( a,|$̖aUǃˉ َh7CM.J&ETiܦTp֛+cSU GlClF(TYUYSศȶ# `@P{% be5O +4Um޵'2c J?D y#x 775 ,3n @0aPTe3% Iˆʵ9 JR!Q fY1 _p8;:D3 \ `a-Zb`[7m@>EkDԎom%\Q.\~.Vg1fIb 8Kj+?,Z Sq:$VVƲlJ`0š SE^rY4XJˍ ]Pͫk-*Jm9,`PtBKƌ,#"AєeJ4J1?u\' håC j[#kH/CLF"ˤ-rɌVbx{"ojb'#]EX"Rj`bR@SXX,5 Gxbnz[W)SUޡZK@GJfRdl% }-LH0AAA5 &ۉ:2G0skPZ[2 #_)BΒɆ} LIQPhJ,}QrS-ȸ3^2P1@=0 XsA)#oAj&y0ȝD';N"wȝD';N"wȝD';ZY';N"wȝD';N"wȝD';AEKKKKKKKKKKKKKKKKKKKKN",yKKKKKKKKKKKKKKKKKKKE؆S4QIf=#>ms0rĆ9~y9l+fPkyNHF(,q-?i (~ꡘVn-csud/2ChuÄ6fޅ" /0q0 Z}F%F]cM<+"tԩ wbJ匃6و":D|y}bc>r0 BAx{qe|8 >g8b ]CWJz]y٧YYOP}<`+XXB"l,>gϹk CR1q|80.d`:#o,t;zfG7}>-`}̎o?}[+/?aoWɃ_#29~y9l+gX0bTǭ`b!RM0]l@ W$D"2r1؆ڵWT+bkԛT9`tHMVV.z`7CCpjXī2:FЪ=04}1hirzD aޱ wa,Mۊ *T\ hr3%-LA ZS0UbSBq(~= .T%d kT4l;K(1Vd` Inr^4 or T@-@uYX~fG7ft~O?t~O?t~O?t~O?t~O?t\&"?t~O?t~O?t~O?t~O?t~OlN:~?SN:~?SN:~?SN:~?SN:~?S@30?t~O?t~O?t~O?t~O?t~OFLn#29~_y9l+-`}̎o>.|1 A/>_y9lPfg/?axzo L_Hf ljE kG˼xY C૎`aה,5ZN}岾Ld .i׹y{G@_;>):&;YJ!Ogii.WsբEI* X&]g}[+h]w1a%hȹ 6`匣LCq{/?ax֊GUU\UluxۋE %~r_&z UVm[cLȳ:]'7aMϧg$^6 p}P\Y^X^>(֬w2y +a-1Vaԣo(ٙ:c:8{T r$\RGhkbndqe2&I.S&s+5#Z}S ow&J&Ǖ` f%6-?Dbw>fG7}!HOgHuXmʒ)EbmԆue<y=j=  lވo[ݗ /e3#>ϯHZ5˓^ N3 (KP¯>-`I(KIQԤ,{ˏ~Z8̎o&v/@5 /e3#>Xf/´Z )43aoC7~P@D s0q&DL~LU-ges0rfG7}>-`}̎o>y49aOt&u!S&(f*|5`R,@ ,, l4JVpkoXaٷZ(. ߣ1gͨ!-u- ]dًC{p1P%B-(?Ǐ>Zոy1aPRa8(26_tIj 0!<2(Uf EUCfB[ce|8 Uw%SՌjcYYWb\PX`U(GUZV 7N #oL- |~fG7<+{V[?eoxDvu)R;C v؈u0a*̥X[?eox+{<&Y[?eox+{u^?j "NCWsrPÊba&DmJ^G%6/QgU+{V[?eoxu:+{V[?a`d;YL!^ o