diff --git a/.Rbuildignore b/.Rbuildignore index d73b159..560d88c 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -2,3 +2,4 @@ ^\.Rproj\.user$ ^\.buildkite.* ^revdep$ +^cran-comments.md$ diff --git a/DESCRIPTION b/DESCRIPTION index 74bdc07..3e02a57 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,15 +1,15 @@ Package: wilson Type: Package Title: Web-Based Interactive Omics Visualization -Version: 2.0.0 +Version: 2.0.1 Authors@R: c( person("Hendrik", "Schultheis", email = "hendrik.schultheis@mpi-bn.mpg.de", role = c("aut", "cre")), person("Jens", "Preussner", email = "jens.preussner@mpi-bn.mpg.de", role = "aut"), person("Looso", "Mario", email = "mario.looso@mpi-bn.mpg.de", role = "aut")) -Description: This package provides modules for web-based tools that use plot based strategies to visualize and analyze multi-omics data. - 'wilson' utilizes the 'shiny' and 'plotly' frameworks to provide a user friendly dashboard for interactive plotting. -URL: https://github.molgen.mpg.de/loosolab/wilson -BugReports: https://github.molgen.mpg.de/loosolab/wilson/issues +Description: Tool-set of modules for creating web-based applications that use plot based strategies to visualize and analyze multi-omics data. + This package utilizes the 'shiny' and 'plotly' frameworks to provide a user friendly dashboard for interactive plotting. +URL: https://github.molgen.mpg.de/loosolab/wilson/ +BugReports: https://github.molgen.mpg.de/loosolab/wilson/issues/ License: MIT + file LICENSE Encoding: UTF-8 LazyData: true @@ -47,4 +47,9 @@ Imports: shiny, methods, R6 RoxygenNote: 6.0.1 -biocViews: +biocViews: +Suggests: knitr, + rmarkdown, + testthat, + vdiffr +VignetteBuilder: knitr diff --git a/NEWS.md b/NEWS.md new file mode 100644 index 0000000..5bbbfcc --- /dev/null +++ b/NEWS.md @@ -0,0 +1,25 @@ +# wilson 2.0.1 +- tests added +# wilson 2.0.0 +## Features +- clarion class: + - easier data-format validation by providing several checks + - simplified module usage (only forward clarion object) for top-level modules (e.g. filter & plot) + - provide functions for frequent tasks (e.g. get_name, is_delimited, etc.) + +- geneView: + - group columns by one or more factors + +- pca: + - color & shape grouping by selected factor(s) + +- scatterPlot: + - add name to hovertext if available (only interactive) + +## Misc +- improved notifications (closable, more) +- overall code quality improvements via usage of packages goodpractice and lintr +- removed deprecated colorPicker + +# wilson 1.0.0 +first public release diff --git a/R/function.R b/R/function.R index d93701a..754c715 100644 --- a/R/function.R +++ b/R/function.R @@ -125,7 +125,7 @@ create_scatterplot <- function(data, data.labels = NULL, data.hovertext = NULL, if (density) { ### kernel density # plot$layers <- c(stat_density2d(geom = "tile", aes(fill = ..density..^0.25), n=200, contour=FALSE) + aes_(fill = as.name(var)), plot$layers) # n = resolution; density less sparse - plot <- plot + ggplot2::stat_density2d(geom = "tile", ggplot2::aes_(fill = ~ ..density.. ^ 0.25), n = 200, contour = FALSE) + plot <- plot + ggplot2::stat_density2d(geom = "tile", ggplot2::aes_(fill = ~ ..density.. ^ 0.25, color = NULL), n = 200, contour = FALSE) plot <- plot + ggplot2::scale_fill_gradient(low = "white", high = "black") + # guides(fill=FALSE) + # remove density legend @@ -1152,7 +1152,7 @@ searchData <- function(input, choices, options = c("=", "<", ">"), min. = min(ch } # range - if ("inner" == options){ + if ("inner" == options) { if (x >= input[1] & x <= input[2]) return(TRUE) } if ("outer" == options) { @@ -1203,15 +1203,17 @@ searchData <- function(input, choices, options = c("=", "<", ">"), min. = min(ch download <- function(file, filename, plot, width, height, ppi = 72, save_plot = TRUE, ui = NULL) { session <- shiny::getDefaultReactiveDomain() - # show notification - shiny::showNotification( - id = session$ns("download-note"), - shiny::tags$b("Preparing download files. Please wait..."), - duration = NULL, - closeButton = FALSE, - type = "message" - ) - shinyjs::runjs(paste0("$(document.getElementById('", paste0("shiny-notification-", session$ns("download-note")), "')).addClass('notification-position-center');")) + if (!is.null(session)) { + # show notification + shiny::showNotification( + id = session$ns("download-note"), + shiny::tags$b("Preparing download files. Please wait..."), + duration = NULL, + closeButton = FALSE, + type = "message" + ) + shinyjs::runjs(paste0("$(document.getElementById('", paste0("shiny-notification-", session$ns("download-note")), "')).addClass('notification-position-center');")) + } # cut off file extension name <- sub("(.*)\\..*$", replacement = "\\1", filename) @@ -1283,8 +1285,10 @@ download <- function(file, filename, plot, width, height, ppi = 72, save_plot = # remove tmp files file.remove(files) - # remove notification - shiny::removeNotification(session$ns("download-note")) + if (!is.null(session)) { + # remove notification + shiny::removeNotification(session$ns("download-note")) + } return(out) } diff --git a/R/global.R b/R/global.R index 75aea44..97bc8af 100644 --- a/R/global.R +++ b/R/global.R @@ -11,8 +11,10 @@ wilson.globals <- new.env(parent = emptyenv()) #' #' @export set_logger <- function(logger, token = NULL) { - if (is.null(logger) || methods::is(logger, "logger")) { + if (methods::is(logger, "logger")) { assign(x = paste0("logger", token), value = logger, envir = wilson.globals) + } else if (is.null(logger)) { + rm(list = paste0("logger", token), envir = wilson.globals) } } diff --git a/R/parser.R b/R/parser.R index 9827548..475ecb1 100644 --- a/R/parser.R +++ b/R/parser.R @@ -25,6 +25,8 @@ #' @param version pre-header information about version (optional) #' @param experiment_id pre-header information about experiment id (optional) #' +#' @return TRUE on success +#' #' @export parse_MaxQuant <- function(proteinGroups_in, summary_in, outfile, outfile_reduced, config = system.file("extdata", "parser_MaxQuant_config.json", package = "wilson"), delimiter = ";", format = NULL, version = NULL, experiment_id = NULL){ if (missing(proteinGroups_in)) { @@ -85,7 +87,7 @@ parse_MaxQuant <- function(proteinGroups_in, summary_in, outfile, outfile_reduce # @return String level of given column get_sample_level <- function(col_head, isSample, full_list) { # Get the level of all 'sample' columns. - # Default: level <- "sample" + # Default: level is "sample" if (grepl("Ratio", col_head, perl = TRUE)) { if (grepl("type", col_head, perl = TRUE)) return("feature") return("contrast") @@ -165,7 +167,7 @@ parse_MaxQuant <- function(proteinGroups_in, summary_in, outfile, outfile_reduce # @param version version number # @param exp_id experiment id # @param pGroups data table protein groups file - write_clarion_file <- function(meta, out, format, version, exp_id, pGroups, delimiter){ + write_clarion_file <- function(meta, out, format, version, exp_id, pGroups, delimiter) { to_append <- FALSE if (!missing(format)) { write(paste0("!format=", format), file = out, append = to_append) @@ -188,10 +190,21 @@ parse_MaxQuant <- function(proteinGroups_in, summary_in, outfile, outfile_reduce # reading files in data tables proteinGroups <- data.table::fread(proteinGroups_in, header = TRUE, quote = "") summary_file <- data.table::fread(summary_in, header = TRUE) - meta_config <- rjson::fromJSON(file = config) + + meta_config <- tryCatch({ + rjson::fromJSON(file = config) + }, error = function(cond) { + stop("Could not read config file") + }, warning = function(w) { + stop("Could not read config file") + }) # getting experiment names - exp_names <- (unique(summary_file[Experiment != "", Experiment])) + if ("Experiment" %in% colnames(summary_file)) { + exp_names <- unique(summary_file[Experiment != "", Experiment]) + } else { + stop("wrong format on summary file: column \'Experiment\' misssing") + } meta <- get_meta_from_config(meta_config = meta_config) @@ -203,6 +216,9 @@ parse_MaxQuant <- function(proteinGroups_in, summary_in, outfile, outfile_reduce sample_ary <- meta_config$type_array reduced_list <- meta_config$reduced_list full_sample_list <- c(sample_scores, sample_ratios, sample_probability, sample_category, sample_ary) + if (is.null(reduced_list)) { + stop("reduced_list is missing in config file") + } # get column names col_names <- colnames(proteinGroups) @@ -214,7 +230,7 @@ parse_MaxQuant <- function(proteinGroups_in, summary_in, outfile, outfile_reduce # append rows to data table with metadata samples_list <- lapply(col_names, function(col_head) { - unlist(lapply(exp_names, function(name){ + unlist(lapply(exp_names, function(name) { name_brackets <- paste0("\\Q", name) exp_regex <- paste0("\\Q ", name) sample_description <- strsplit(col_head, exp_regex) @@ -286,6 +302,8 @@ parse_MaxQuant <- function(proteinGroups_in, summary_in, outfile, outfile_reduce # writing reduced CLARION file write_clarion_file(meta = meta_reduced, out = outfile_reduced, format = format, version = version, exp_id = experiment_id, pGroups = proteinGroups, delimiter = delimiter) + + return(TRUE) } #' Method to parse input file. diff --git a/R/release_questions.R b/R/release_questions.R new file mode 100644 index 0000000..d2ed440 --- /dev/null +++ b/R/release_questions.R @@ -0,0 +1,8 @@ +#' Defines additional questions asked before CRAN submission. +#' DO NOT EXPORT! +release_questions <- function() { + c( + "Re-run reverse dependencies?", + "Abide good practices?" + ) +} diff --git a/README.md b/README.md index 8555793..1bd6f53 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # WIlsON: Webbased Interactive Omics visualizatioN - The R Package -*Buildkite:* [![Build status](https://badge.buildkite.com/d79f55bb3e3cf0d70d6784feb8c6e26182d602f534e74fac4e.svg?branch=master)](https://buildkite.com/loosolab/wilson) +*Buildkite:* ![Build status](https://badge.buildkite.com/d79f55bb3e3cf0d70d6784feb8c6e26182d602f534e74fac4e.svg?branch=master) ## Abstract #### Objective @@ -12,9 +12,9 @@ The WIlsON R package employs the R Shiny and Plotly web-based frameworks using a The WIlsON R package includes a toolbox of R Shiny modules that can be used to construct a wide array of web-interfaces for plotting feature-based data. ## Availability -All components of the WIlsON R package have been implemented in an integrated web application that is available for download from the Github repository [wilson-apps](https://github.molgen.mpg.de/loosolab/wilson-apps) and can be tested on our [official demonstration server](http://loosolab.mpi-bn.mpg.de/apps/wilson/). +All components of the WIlsON R package have been implemented in an integrated web application that is available for download from the Github repository [wilson-apps](https://github.molgen.mpg.de/loosolab/wilson-apps/) and can be tested on our [official demonstration server](http://loosolab.mpi-bn.mpg.de/apps/wilson/). -Usage instructions can be found in the extensive [documentation](https://github.molgen.mpg.de/loosolab/wilson-apps/wiki). +Usage instructions can be found in the extensive [documentation](https://github.molgen.mpg.de/loosolab/wilson-apps/wiki/). Get a Docker container [here](https://hub.docker.com/r/loosolab/wilson/). @@ -37,7 +37,7 @@ CLARION: generiC fiLe formAt foR quantItative cOmparsions of high throughput scr CLARION is a data format especially developed to be used with WIlsON, which relies on a tab-delimited table with a metadata header to describe the following columns. It is based on the Summarized Experiment format and supports all types of data which can be reduced to features and their annotation (e.g. genes, transcripts, proteins, probes) with assigned numerical values (e.g. count, score, log2foldchange, z-score, p-value). Most result tables derived from RNA-Seq, ChIP/ATAC-Seq, Proteomics, Microarrays, and many other analyses can thus be easily reformatted to become compatible without having to modify the code of WIlsON for each specific experiment. -Please check the following link for details considering the [CLARION format](https://github.molgen.mpg.de/loosolab/wilson-apps/wiki/CLARION-Format). +Please check the following link for details considering the [CLARION format](https://github.molgen.mpg.de/loosolab/wilson-apps/wiki/CLARION-Format/). ## How to cite *Schultheis H, Kuenne C, Preussner J, Wiegandt R, Fust A, Bentsen M, Looso M*. WIlsON: Webbased Interactive Omics VisualizatioN. (2018), doi: https://XY diff --git a/cran-comments.md b/cran-comments.md new file mode 100644 index 0000000..57c8438 --- /dev/null +++ b/cran-comments.md @@ -0,0 +1,57 @@ +# Submission 1 +## Test environments +* local windows 7 install, R 3.5.1 +* debian 9.4, R 3.4.1 +* win-builder (devel and release) + +## R CMD check results +There were no ERRORs or WARNINGs. + +There was 1 NOTE: + +* New submission + +* Possibly mis-spelled words in DESCRIPTION: + Omics (3:30) + omics (9:126) + + Both are spelled correctly. First is capital because of title case. + +## Downstream dependencies +I have also run R CMD check on downstream dependencies of wilson +(https://github.molgen.mpg.de/loosolab/wilson/tree/master/revdep). +All packages that I could install passed. + +## Reviewer comments +Thanks, we see you have lots of cuntions without examples (which may be reasonable given they are not intended t be called by users directly). +Nevertheless, it would be good to have them tested, so please create, if examples are not feasible, at least tests that execute the various functions in your package. + +Best, +Uwe Ligges + +# Submission 2 +## Test environments +* local windows 7 install, R 3.5.1 +* debian 9.4, R 3.4.1 +* win-builder (devel and release) + +## Submission comments +Addressed reviewer comments by adding tests where possible. + +## R CMD check results +There were no ERRORs or WARNINGs. + +There was 1 NOTE: + +* New submission + +* Possibly mis-spelled words in DESCRIPTION: + Omics (3:30) + omics (9:126) + + Both are spelled correctly. First is capital because of title case. + +## Downstream dependencies +I have also run R CMD check on downstream dependencies of wilson +(https://github.molgen.mpg.de/loosolab/wilson/tree/master/revdep). +All packages that I could install passed. diff --git a/man/parse_MaxQuant.Rd b/man/parse_MaxQuant.Rd index 300c565..d17e81a 100644 --- a/man/parse_MaxQuant.Rd +++ b/man/parse_MaxQuant.Rd @@ -29,6 +29,9 @@ parse_MaxQuant(proteinGroups_in, summary_in, outfile, outfile_reduced, \item{experiment_id}{pre-header information about experiment id (optional)} } +\value{ +TRUE on success +} \description{ List with columns of reduced version (see config.json file) If you only want the samples of a specific keyword write: column;exp diff --git a/man/release_questions.Rd b/man/release_questions.Rd new file mode 100644 index 0000000..4d86795 --- /dev/null +++ b/man/release_questions.Rd @@ -0,0 +1,13 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/release_questions.R +\name{release_questions} +\alias{release_questions} +\title{Defines additional questions asked before CRAN submission. +DO NOT EXPORT!} +\usage{ +release_questions() +} +\description{ +Defines additional questions asked before CRAN submission. +DO NOT EXPORT! +} diff --git a/revdep/README.md b/revdep/README.md index 3b38cae..97e39b4 100644 --- a/revdep/README.md +++ b/revdep/README.md @@ -4,48 +4,52 @@ |setting |value | |:--------|:----------------------------| -|version |R version 3.5.0 (2018-04-23) | +|version |R version 3.5.1 (2018-07-02) | |system |x86_64, mingw32 | |ui |RStudio (1.2.747) | |language |(EN) | |collate |German_Germany.1252 | |tz |Europe/Berlin | -|date |2018-06-29 | +|date |2018-07-16 | ## Packages |package |* |version |date |source | |:---------------|:--|:-------|:----------|:-----------------------------------| -|circlize | |0.4.4 |2018-06-10 |CRAN (R 3.5.0) | -|colourpicker | |1.0 |2017-09-27 |CRAN (R 3.5.0) | +|circlize | |0.4.4 |2018-06-10 |CRAN (R 3.5.1) | +|colourpicker | |1.0 |2017-09-27 |CRAN (R 3.5.1) | |ComplexHeatmap | |1.18.1 |2018-06-19 |Bioconductor (R 3.5.0) | -|data.table | |1.11.4 |2018-05-27 |CRAN (R 3.5.0) | +|data.table | |1.11.4 |2018-05-27 |CRAN (R 3.5.1) | |DESeq2 | |1.20.0 |2018-05-01 |Bioconductor | -|DT | |0.4 |2018-01-30 |CRAN (R 3.5.0) | -|factoextra | |1.0.5 |2017-08-22 |CRAN (R 3.5.0) | -|FactoMineR | |1.41 |2018-05-04 |CRAN (R 3.5.0) | -|ggplot2 | |2.2.1 |2016-12-30 |CRAN (R 3.5.0) | -|ggrepel | |0.8.0 |2018-05-09 |CRAN (R 3.5.0) | -|gplots | |3.0.1 |2016-03-30 |CRAN (R 3.5.0) | -|heatmaply | |0.15.0 |2018-06-23 |CRAN (R 3.5.0) | -|log4r | |0.2 |2014-09-29 |CRAN (R 3.5.0) | -|openssl | |1.0.1 |2018-03-03 |CRAN (R 3.5.0) | -|plotly | |4.7.1 |2017-07-29 |CRAN (R 3.5.0) | -|plyr | |1.8.4 |2016-06-08 |CRAN (R 3.5.0) | -|R6 | |2.2.2 |2017-06-17 |CRAN (R 3.5.0) | +|DT | |0.4 |2018-01-30 |CRAN (R 3.5.1) | +|factoextra | |1.0.5 |2017-08-22 |CRAN (R 3.5.1) | +|FactoMineR | |1.41 |2018-05-04 |CRAN (R 3.5.1) | +|ggplot2 | |3.0.0 |2018-07-03 |CRAN (R 3.5.1) | +|ggrepel | |0.8.0 |2018-05-09 |CRAN (R 3.5.1) | +|gplots | |3.0.1 |2016-03-30 |CRAN (R 3.5.1) | +|heatmaply | |0.15.2 |2018-07-06 |CRAN (R 3.5.1) | +|knitr | |1.20 |2018-02-20 |CRAN (R 3.5.1) | +|log4r | |0.2 |2014-09-29 |CRAN (R 3.5.1) | +|openssl | |1.0.1 |2018-03-03 |CRAN (R 3.5.1) | +|plotly | |4.7.1 |2017-07-29 |CRAN (R 3.5.1) | +|plyr | |1.8.4 |2016-06-08 |CRAN (R 3.5.1) | +|R6 | |2.2.2 |2017-06-17 |CRAN (R 3.5.1) | |RColorBrewer | |1.1-2 |2014-12-07 |CRAN (R 3.5.0) | -|reshape | |0.8.7 |2017-08-06 |CRAN (R 3.5.0) | -|rintrojs | |0.2.0 |2017-07-04 |CRAN (R 3.5.0) | +|reshape | |0.8.7 |2017-08-06 |CRAN (R 3.5.1) | +|rintrojs | |0.2.0 |2017-07-04 |CRAN (R 3.5.1) | |rje | |1.9 |2014-08-06 |CRAN (R 3.5.0) | |rjson | |0.2.20 |2018-06-08 |CRAN (R 3.5.0) | |RJSONIO | |1.3-0 |2014-07-28 |CRAN (R 3.5.0) | -|scales | |0.5.0 |2017-08-24 |CRAN (R 3.5.0) | -|shiny | |1.1.0 |2018-05-17 |CRAN (R 3.5.0) | -|shinycssloaders | |0.2.0 |2017-05-12 |CRAN (R 3.5.0) | -|shinydashboard | |0.7.0 |2018-03-21 |CRAN (R 3.5.0) | -|shinyjs | |1.0 |2018-01-08 |CRAN (R 3.5.0) | -|viridis | |0.5.1 |2018-03-29 |CRAN (R 3.5.0) | -|wilson | |2.0.0 |2018-06-29 |local (HendrikSchultheis/wilson@NA) | +|rmarkdown | |1.10 |2018-06-11 |CRAN (R 3.5.1) | +|scales | |0.5.0 |2017-08-24 |CRAN (R 3.5.1) | +|shiny | |1.1.0 |2018-05-17 |CRAN (R 3.5.1) | +|shinycssloaders | |0.2.0 |2017-05-12 |CRAN (R 3.5.1) | +|shinydashboard | |0.7.0 |2018-03-21 |CRAN (R 3.5.1) | +|shinyjs | |1.0 |2018-01-08 |CRAN (R 3.5.1) | +|testthat | |2.0.0 |2017-12-13 |CRAN (R 3.5.1) | +|vdiffr | |0.2.3 |2018-04-27 |CRAN (R 3.5.1) | +|viridis | |0.5.1 |2018-03-29 |CRAN (R 3.5.1) | +|wilson | |2.0.1 |2018-07-16 |local (HendrikSchultheis/wilson@NA) | # Check results diff --git a/revdep/checks.rds b/revdep/checks.rds index dc78959..103e5c1 100644 Binary files a/revdep/checks.rds and b/revdep/checks.rds differ diff --git a/revdep/problems.md b/revdep/problems.md index 368348c..8bbf2e7 100644 --- a/revdep/problems.md +++ b/revdep/problems.md @@ -4,48 +4,52 @@ |setting |value | |:--------|:----------------------------| -|version |R version 3.5.0 (2018-04-23) | +|version |R version 3.5.1 (2018-07-02) | |system |x86_64, mingw32 | |ui |RStudio (1.2.747) | |language |(EN) | |collate |German_Germany.1252 | |tz |Europe/Berlin | -|date |2018-06-29 | +|date |2018-07-16 | ## Packages |package |* |version |date |source | |:---------------|:--|:-------|:----------|:-----------------------------------| -|circlize | |0.4.4 |2018-06-10 |CRAN (R 3.5.0) | -|colourpicker | |1.0 |2017-09-27 |CRAN (R 3.5.0) | +|circlize | |0.4.4 |2018-06-10 |CRAN (R 3.5.1) | +|colourpicker | |1.0 |2017-09-27 |CRAN (R 3.5.1) | |ComplexHeatmap | |1.18.1 |2018-06-19 |Bioconductor (R 3.5.0) | -|data.table | |1.11.4 |2018-05-27 |CRAN (R 3.5.0) | +|data.table | |1.11.4 |2018-05-27 |CRAN (R 3.5.1) | |DESeq2 | |1.20.0 |2018-05-01 |Bioconductor | -|DT | |0.4 |2018-01-30 |CRAN (R 3.5.0) | -|factoextra | |1.0.5 |2017-08-22 |CRAN (R 3.5.0) | -|FactoMineR | |1.41 |2018-05-04 |CRAN (R 3.5.0) | -|ggplot2 | |2.2.1 |2016-12-30 |CRAN (R 3.5.0) | -|ggrepel | |0.8.0 |2018-05-09 |CRAN (R 3.5.0) | -|gplots | |3.0.1 |2016-03-30 |CRAN (R 3.5.0) | -|heatmaply | |0.15.0 |2018-06-23 |CRAN (R 3.5.0) | -|log4r | |0.2 |2014-09-29 |CRAN (R 3.5.0) | -|openssl | |1.0.1 |2018-03-03 |CRAN (R 3.5.0) | -|plotly | |4.7.1 |2017-07-29 |CRAN (R 3.5.0) | -|plyr | |1.8.4 |2016-06-08 |CRAN (R 3.5.0) | -|R6 | |2.2.2 |2017-06-17 |CRAN (R 3.5.0) | +|DT | |0.4 |2018-01-30 |CRAN (R 3.5.1) | +|factoextra | |1.0.5 |2017-08-22 |CRAN (R 3.5.1) | +|FactoMineR | |1.41 |2018-05-04 |CRAN (R 3.5.1) | +|ggplot2 | |3.0.0 |2018-07-03 |CRAN (R 3.5.1) | +|ggrepel | |0.8.0 |2018-05-09 |CRAN (R 3.5.1) | +|gplots | |3.0.1 |2016-03-30 |CRAN (R 3.5.1) | +|heatmaply | |0.15.2 |2018-07-06 |CRAN (R 3.5.1) | +|knitr | |1.20 |2018-02-20 |CRAN (R 3.5.1) | +|log4r | |0.2 |2014-09-29 |CRAN (R 3.5.1) | +|openssl | |1.0.1 |2018-03-03 |CRAN (R 3.5.1) | +|plotly | |4.7.1 |2017-07-29 |CRAN (R 3.5.1) | +|plyr | |1.8.4 |2016-06-08 |CRAN (R 3.5.1) | +|R6 | |2.2.2 |2017-06-17 |CRAN (R 3.5.1) | |RColorBrewer | |1.1-2 |2014-12-07 |CRAN (R 3.5.0) | -|reshape | |0.8.7 |2017-08-06 |CRAN (R 3.5.0) | -|rintrojs | |0.2.0 |2017-07-04 |CRAN (R 3.5.0) | +|reshape | |0.8.7 |2017-08-06 |CRAN (R 3.5.1) | +|rintrojs | |0.2.0 |2017-07-04 |CRAN (R 3.5.1) | |rje | |1.9 |2014-08-06 |CRAN (R 3.5.0) | |rjson | |0.2.20 |2018-06-08 |CRAN (R 3.5.0) | |RJSONIO | |1.3-0 |2014-07-28 |CRAN (R 3.5.0) | -|scales | |0.5.0 |2017-08-24 |CRAN (R 3.5.0) | -|shiny | |1.1.0 |2018-05-17 |CRAN (R 3.5.0) | -|shinycssloaders | |0.2.0 |2017-05-12 |CRAN (R 3.5.0) | -|shinydashboard | |0.7.0 |2018-03-21 |CRAN (R 3.5.0) | -|shinyjs | |1.0 |2018-01-08 |CRAN (R 3.5.0) | -|viridis | |0.5.1 |2018-03-29 |CRAN (R 3.5.0) | -|wilson | |2.0.0 |2018-06-29 |local (HendrikSchultheis/wilson@NA) | +|rmarkdown | |1.10 |2018-06-11 |CRAN (R 3.5.1) | +|scales | |0.5.0 |2017-08-24 |CRAN (R 3.5.1) | +|shiny | |1.1.0 |2018-05-17 |CRAN (R 3.5.1) | +|shinycssloaders | |0.2.0 |2017-05-12 |CRAN (R 3.5.1) | +|shinydashboard | |0.7.0 |2018-03-21 |CRAN (R 3.5.1) | +|shinyjs | |1.0 |2018-01-08 |CRAN (R 3.5.1) | +|testthat | |2.0.0 |2017-12-13 |CRAN (R 3.5.1) | +|vdiffr | |0.2.3 |2018-04-27 |CRAN (R 3.5.1) | +|viridis | |0.5.1 |2018-03-29 |CRAN (R 3.5.1) | +|wilson | |2.0.1 |2018-07-16 |local (HendrikSchultheis/wilson@NA) | # Check results diff --git a/tests/figs/create-static-plots/static-geneview.svg b/tests/figs/create-static-plots/static-geneview.svg new file mode 100644 index 0000000..6793332 --- /dev/null +++ b/tests/figs/create-static-plots/static-geneview.svg @@ -0,0 +1,374 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Mazda RX4 +Mazda RX4 Wag +Datsun 710 +Hornet 4 Drive +Hornet Sportabout +Valiant +Duster 360 +Merc 240D +Merc 230 +Merc 280 +Merc 280C +Merc 450SE +Merc 450SL +Merc 450SLC +Cadillac Fleetwood +Lincoln Continental +Chrysler Imperial +Fiat 128 +Honda Civic +Toyota Corolla +Toyota Corona +Dodge Challenger +AMC Javelin +Camaro Z28 +Pontiac Firebird +Fiat X1-9 +Porsche 914-2 +Lotus Europa +Ford Pantera L +Ferrari Dino +Maserati Bora +Volvo 142E + + + + + + + + + +a +b +static geneview + diff --git a/tests/figs/create-static-plots/static-heatmap.svg b/tests/figs/create-static-plots/static-heatmap.svg new file mode 100644 index 0000000..ffcf28a --- /dev/null +++ b/tests/figs/create-static-plots/static-heatmap.svg @@ -0,0 +1,523 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Mazda RX4 +Mazda RX4 Wag +Datsun 710 +Hornet 4 Drive +Hornet Sportabout +Valiant +Duster 360 +Merc 240D +Merc 230 +Merc 280 +Merc 280C +Merc 450SE +Merc 450SL +Merc 450SLC +Cadillac Fleetwood +Lincoln Continental +Chrysler Imperial +Fiat 128 +Honda Civic +Toyota Corolla +Toyota Corona +Dodge Challenger +AMC Javelin +Camaro Z28 +Pontiac Firebird +Fiat X1-9 +Porsche 914-2 +Lotus Europa +Ford Pantera L +Ferrari Dino +Maserati Bora +Volvo 142E +mpg +cyl +disp +hp +drat +wt +qsec +vs +am +gear +carb +auto +0 +100 +200 +300 +400 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/figs/create-static-plots/static-pca.svg b/tests/figs/create-static-plots/static-pca.svg new file mode 100644 index 0000000..609ff93 --- /dev/null +++ b/tests/figs/create-static-plots/static-pca.svg @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +-1 +0 +1 +2 + + + + + + + + + +0 +5 +10 +15 +Dim1 (96.7%) +Dim2 (2.4%) + + + + + + + +a +b +c + diff --git a/tests/figs/create-static-plots/static-scatterplot.svg b/tests/figs/create-static-plots/static-scatterplot.svg new file mode 100644 index 0000000..38aa278 --- /dev/null +++ b/tests/figs/create-static-plots/static-scatterplot.svg @@ -0,0 +1,40103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +100 +200 +300 + + + + + + + + + + +10 +15 +20 +25 +30 +35 +mpg +hp + + +0.05 +0.10 +Density + + + + + +vs + + + + + + +0 +1 +static scatterplot + diff --git a/tests/figs/deps.txt b/tests/figs/deps.txt new file mode 100644 index 0000000..8bd22f8 --- /dev/null +++ b/tests/figs/deps.txt @@ -0,0 +1,6 @@ +Fontconfig: 2.11.94 +FreeType: 2.6.0 +Cairo: 1.14.2 +vdiffr: 0.2.3 +svglite: 1.2.1 +ggplot2: 3.0.0 diff --git a/tests/testthat.R b/tests/testthat.R new file mode 100644 index 0000000..a7d9752 --- /dev/null +++ b/tests/testthat.R @@ -0,0 +1,4 @@ +library(testthat) +library(wilson) + +test_check("wilson") diff --git a/tests/testthat/fail_config.json b/tests/testthat/fail_config.json new file mode 100644 index 0000000..8d82f3b --- /dev/null +++ b/tests/testthat/fail_config.json @@ -0,0 +1,291 @@ +{ + "meta": [ + { + "col_name": "Protein IDs", + "level": "feature", + "type": "array", + "label": "IDs", + "sublabel": "proteins" + }, + { + "col_name": "Majority protein IDs", + "level": "feature", + "type": "array", + "label": "IDs", + "sublabel": "majority protein" + }, + { + "col_name": "Protein names", + "level": "feature", + "type": "array", + "label": "protein names", + "sublabel": "" + }, + { + "col_name": "Gene names", + "level": "feature", + "type": "array", + "label": "gene names", + "sublabel": "" + }, + { + "col_name": "Fasta headers", + "level": "feature", + "type": "array", + "label": "fasta headers", + "sublabel": "" + }, + { + "col_name": "id", + "level": "feature", + "type": "unique_id", + "label": "unique identifier", + "sublabel": "" + }, + { + "col_name": "Peptide IDs", + "level": "feature", + "type": "array", + "label": "IDs", + "sublabel": "peptide" + }, + { + "col_name": "Mod. peptide IDs", + "level": "feature", + "type": "array", + "label": "IDs", + "sublabel": "mod. peptide" + }, + { + "col_name": "Evidence IDs", + "level": "feature", + "type": "array", + "label": "IDs", + "sublabel": "evidence" + }, + { + "col_name": "MS/MS IDs", + "level": "feature", + "type": "array", + "label": "IDs", + "sublabel": "MS/MS" + }, + { + "col_name": "Mol. weight [kDa]", + "level": "feature", + "type": "category", + "label": "Mol. weight [kDa]", + "sublabel": "" + }, + { + "col_name": "Sequence length", + "level": "feature", + "type": "category", + "label": "length", + "sublabel": "Sequence" + }, + { + "col_name": "Sequence lengths", + "level": "feature", + "type": "array", + "label": "lengths", + "sublabel": "Sequence" + }, + { + "col_name": "Reverse", + "level": "feature", + "type": "category", + "label": "Reverse", + "sublabel": "" + }, + { + "col_name": "Potential contaminant", + "level": "feature", + "type": "category", + "label": "Potential contaminant", + "sublabel": "" + }, + { + "col_name": "Oxidation (M) site IDs", + "level": "feature", + "type": "array", + "label": "IDs", + "sublabel": "Oxidation (M) site" + }, + { + "col_name": "Oxidation (M) site positions", + "level": "feature", + "type": "array", + "label": "positions", + "sublabel": "Oxidation (M) site" + }, + { + "col_name": "Phospho (STY) site IDs", + "level": "feature", + "type": "array", + "label": "IDs", + "sublabel": "Phospho (STY) site" + }, + { + "col_name": "Phospho (STY) site positions", + "level": "feature", + "type": "array", + "label": "positions", + "sublabel": "Phospho (STY) site" + }, + { + "col_name": "Peptide counts (all)", + "level": "condition", + "type": "array", + "label": "counts", + "sublabel": "all peptide" + }, + { + "col_name": "Peptide counts (razor+unique)", + "level": "condition", + "type": "array", + "label": "counts", + "sublabel": "razor+unique peptides" + }, + { + "col_name": "Peptide counts (unique)", + "level": "condition", + "type": "array", + "label": "counts", + "sublabel": "unique peptides" + }, + { + "col_name": "Number of proteins", + "level": "condition", + "type": "score", + "label": "count", + "sublabel": "proteins" + }, + { + "col_name": "Peptides", + "level": "condition", + "type": "score", + "label": "count", + "sublabel": "Peptides" + }, + { + "col_name": "Razor + unique peptides", + "level": "condition", + "type": "score", + "label": "count", + "sublabel": "Razor + unique peptides" + }, + { + "col_name": "Unique peptides", + "level": "condition", + "type": "score", + "label": "count", + "sublabel": "Unique peptides" + }, + { + "col_name": "MS/MS count", + "level": "condition", + "type": "score", + "label": "count", + "sublabel": "MS/MS" + }, + { + "col_name": "Fraction average", + "level": "condition", + "type": "score", + "label": "fraction", + "sublabel": "average" + }, + { + "col_name": "Best MS/MS", + "level": "condition", + "type": "array", + "label": "MS/MS", + "sublabel": "best" + }, + { + "col_name": "Intensity", + "level": "condition", + "type": "score", + "label": "Intensity", + "sublabel": "" + }, + { + "col_name": "Intensity L", + "level": "condition", + "type": "score", + "label": "Intensity", + "sublabel": "L" + }, + { + "col_name": "Intensity M", + "level": "condition", + "type": "score", + "label": "Intensity", + "sublabel": "M" + }, + { + "col_name": "Intensity H", + "level": "condition", + "type": "score", + "label": "Intensity", + "sublabel": "H" + }, + { + "col_name": "Q-value", + "level": "condition", + "type": "probability", + "label": "q-value", + "sublabel": "" + }, + { + "col_name": "Score", + "level": "condition", + "type": "probability", + "label": "score", + "sublabel": "" + }, + { + "col_name": "Unique sequence coverage [%]", + "level": "condition", + "type": "ratio", + "label": "sequence coverage", + "sublabel": "Unique" + }, + { + "col_name": "Unique + razor sequence coverage [%]", + "level": "condition", + "type": "ratio", + "label": "sequence coverage", + "sublabel": "Unique + razor" + }, + { + "col_name": "Sequence coverage [%]", + "level": "condition", + "type": "ratio", + "label": "sequence coverage", + "sublabel": "" + }, + { + "col_name": "Only identified by site", + "level": "feature", + "type": "category", + "label": "identified by site", + "sublabel": "" + }, + { + "col_name": "Peptide is razor", + "level": "condition", + "type": "array", + "label": "peptide", + "sublabel": "is razor" + } + ], + + "type_scores": + ["Peptides", "Razor + unique peptides", "Unique peptides", "Ratio M/L count", "Ratio M/L iso-count", "Ratio H/L count", "Ratio H/L iso-count" , + "Ratio H/M count", "Ratio H/M iso-count", "Intensity", "Intensity L", "Intensity M", "Intensity H", "MS/MS count", "LFQ intensity", "Reporter intensity count", + "Reporter intensity corrected", "Reporter intensity", "Fraction", "iBAQ"] + +} + diff --git a/tests/testthat/proteinGroups_test.txt b/tests/testthat/proteinGroups_test.txt new file mode 100755 index 0000000..6a22524 --- /dev/null +++ b/tests/testthat/proteinGroups_test.txt @@ -0,0 +1,2 @@ +Protein IDs Majority protein IDs Peptide counts (all) Peptide counts (razor+unique) Peptide counts (unique) Protein names Gene names Fasta headers Number of proteins Peptides Razor + unique peptides Unique peptides Peptides Exp1 Peptides Exp2 Razor + unique peptides Exp1 Razor + unique peptides Exp2 Unique peptides Exp1 Unique peptides Exp2 Sequence coverage [%] Unique + razor sequence coverage [%] Unique sequence coverage [%] Mol. weight [kDa] Sequence length Sequence lengths Fraction average Fraction 1 Fraction 2 Fraction 3 Fraction 4 Fraction 5 Fraction 6 Fraction 7 Fraction 8 Q-value Score Reporter intensity corrected 0 Reporter intensity corrected 1 Reporter intensity corrected 2 Reporter intensity corrected 3 Reporter intensity corrected 4 Reporter intensity corrected 5 Reporter intensity 0 Reporter intensity 1 Reporter intensity 2 Reporter intensity 3 Reporter intensity 4 Reporter intensity 5 Reporter intensity count 0 Reporter intensity count 1 Reporter intensity count 2 Reporter intensity count 3 Reporter intensity count 4 Reporter intensity count 5 Reporter intensity corrected 0 Exp1 Reporter intensity corrected 1 Exp1 Reporter intensity corrected 2 Exp1 Reporter intensity corrected 3 Exp1 Reporter intensity corrected 4 Exp1 Reporter intensity corrected 5 Exp1 Reporter intensity corrected 0 Exp2 Reporter intensity corrected 1 Exp2 Reporter intensity corrected 2 Exp2 Reporter intensity corrected 3 Exp2 Reporter intensity corrected 4 Exp2 Reporter intensity corrected 5 Exp2 Reporter intensity 0 Exp1 Reporter intensity 1 Exp1 Reporter intensity 2 Exp1 Reporter intensity 3 Exp1 Reporter intensity 4 Exp1 Reporter intensity 5 Exp1 Reporter intensity 0 Exp2 Reporter intensity 1 Exp2 Reporter intensity 2 Exp2 Reporter intensity 3 Exp2 Reporter intensity 4 Exp2 Reporter intensity 5 Exp2 Reporter intensity count 0 Exp1 Reporter intensity count 1 Exp1 Reporter intensity count 2 Exp1 Reporter intensity count 3 Exp1 Reporter intensity count 4 Exp1 Reporter intensity count 5 Exp1 Reporter intensity count 0 Exp2 Reporter intensity count 1 Exp2 Reporter intensity count 2 Exp2 Reporter intensity count 3 Exp2 Reporter intensity count 4 Exp2 Reporter intensity count 5 Exp2 Sequence coverage Exp1 [%] Sequence coverage Exp2 [%] Intensity Intensity Exp1 Intensity Exp2 MS/MS count Only identified by site Reverse Potential contaminant id Peptide IDs Peptide is razor Mod. peptide IDs Evidence IDs MS/MS IDs Best MS/MS Oxidation (M) site IDs Oxidation (M) site positions +A0A068BEQ2;P50171;P50171-2;G3UX44 A0A068BEQ2;P50171;P50171-2;G3UX44 11;11;11;10 11;11;11;10 11;11;11;10 Estradiol 17-beta-dehydrogenase 8 H2-Ke6;Hsd17b8 tr|A0A068BEQ2|A0A068BEQ2_MOUSE H2-K region expressed gene 6, isoform CRA_a OS=Mus musculus GN=H2-Ke6 PE=2 SV=1;sp|P50171|DHB8_MOUSE Estradiol 17-beta-dehydrogenase 8 OS=Mus musculus GN=Hsd17b8 PE=1 SV=2;sp|P50171-2|DHB8_MOUSE Isoform Long of Estradiol 17-b 4 11 11 11 9 9 9 9 9 9 61.4 61.4 61.4 26.587 259 259;259;274;234 6.32 2 1 1 3 4 4 5 17 0 309.9 422810 381560 394980 374200 414580 428320 405880 379740 401170 384810 418890 414670 29 29 29 29 29 29 159850 141420 149170 147480 162360 166190 262960 240140 245810 226710 252220 262130 153390 140950 151450 151320 164040 160930 252490 238790 249720 233490 254850 253730 12 12 12 12 12 12 17 17 17 17 17 17 46.3 51 8493600000 3090200000 5403400000 42 0 1707;5068;5754;17624;17838;18452;24153;26755;37315;45123;45334 True;True;True;True;True;True;True;True;True;True;True 1818;5449;5450;6176;18892;19121;19782;25924;28715;40406;48814;49037 5720;5721;5722;5723;5724;16176;16177;18100;56337;56338;56339;56340;57035;57036;57037;57038;57039;57040;59065;59066;59067;59068;77499;77500;85797;119780;119781;119782;119783;145479;145480;145481;145482;145483;146163;146164;146165 6359;6360;6361;6362;6363;6364;6365;6366;17918;17919;20019;62610;62611;62612;62613;63369;63370;63371;63372;63373;63374;65658;65659;65660;65661;86004;86005;86006;86007;95195;133113;133114;133115;133116;161672;161673;161674;161675;161676;162411;162412;162413 6366;17919;20019;62610;63370;65660;86006;95195;133113;161676;162411 0;1 113;204 \ No newline at end of file diff --git a/tests/testthat/success_config.json b/tests/testthat/success_config.json new file mode 100644 index 0000000..84bee88 --- /dev/null +++ b/tests/testthat/success_config.json @@ -0,0 +1,322 @@ +{ + "meta": [ + { + "col_name": "Protein IDs", + "level": "feature", + "type": "array", + "label": "IDs", + "sublabel": "proteins" + }, + { + "col_name": "Majority protein IDs", + "level": "feature", + "type": "array", + "label": "IDs", + "sublabel": "majority protein" + }, + { + "col_name": "Protein names", + "level": "feature", + "type": "array", + "label": "protein names", + "sublabel": "" + }, + { + "col_name": "Gene names", + "level": "feature", + "type": "array", + "label": "gene names", + "sublabel": "" + }, + { + "col_name": "Fasta headers", + "level": "feature", + "type": "array", + "label": "fasta headers", + "sublabel": "" + }, + { + "col_name": "id", + "level": "feature", + "type": "unique_id", + "label": "unique identifier", + "sublabel": "" + }, + { + "col_name": "Peptide IDs", + "level": "feature", + "type": "array", + "label": "IDs", + "sublabel": "peptide" + }, + { + "col_name": "Mod. peptide IDs", + "level": "feature", + "type": "array", + "label": "IDs", + "sublabel": "mod. peptide" + }, + { + "col_name": "Evidence IDs", + "level": "feature", + "type": "array", + "label": "IDs", + "sublabel": "evidence" + }, + { + "col_name": "MS/MS IDs", + "level": "feature", + "type": "array", + "label": "IDs", + "sublabel": "MS/MS" + }, + { + "col_name": "Mol. weight [kDa]", + "level": "feature", + "type": "category", + "label": "Mol. weight [kDa]", + "sublabel": "" + }, + { + "col_name": "Sequence length", + "level": "feature", + "type": "category", + "label": "length", + "sublabel": "Sequence" + }, + { + "col_name": "Sequence lengths", + "level": "feature", + "type": "array", + "label": "lengths", + "sublabel": "Sequence" + }, + { + "col_name": "Reverse", + "level": "feature", + "type": "category", + "label": "Reverse", + "sublabel": "" + }, + { + "col_name": "Potential contaminant", + "level": "feature", + "type": "category", + "label": "Potential contaminant", + "sublabel": "" + }, + { + "col_name": "Oxidation (M) site IDs", + "level": "feature", + "type": "array", + "label": "IDs", + "sublabel": "Oxidation (M) site" + }, + { + "col_name": "Oxidation (M) site positions", + "level": "feature", + "type": "array", + "label": "positions", + "sublabel": "Oxidation (M) site" + }, + { + "col_name": "Phospho (STY) site IDs", + "level": "feature", + "type": "array", + "label": "IDs", + "sublabel": "Phospho (STY) site" + }, + { + "col_name": "Phospho (STY) site positions", + "level": "feature", + "type": "array", + "label": "positions", + "sublabel": "Phospho (STY) site" + }, + { + "col_name": "Peptide counts (all)", + "level": "condition", + "type": "array", + "label": "counts", + "sublabel": "all peptide" + }, + { + "col_name": "Peptide counts (razor+unique)", + "level": "condition", + "type": "array", + "label": "counts", + "sublabel": "razor+unique peptides" + }, + { + "col_name": "Peptide counts (unique)", + "level": "condition", + "type": "array", + "label": "counts", + "sublabel": "unique peptides" + }, + { + "col_name": "Number of proteins", + "level": "condition", + "type": "score", + "label": "count", + "sublabel": "proteins" + }, + { + "col_name": "Peptides", + "level": "condition", + "type": "score", + "label": "count", + "sublabel": "Peptides" + }, + { + "col_name": "Razor + unique peptides", + "level": "condition", + "type": "score", + "label": "count", + "sublabel": "Razor + unique peptides" + }, + { + "col_name": "Unique peptides", + "level": "condition", + "type": "score", + "label": "count", + "sublabel": "Unique peptides" + }, + { + "col_name": "MS/MS count", + "level": "condition", + "type": "score", + "label": "count", + "sublabel": "MS/MS" + }, + { + "col_name": "Fraction average", + "level": "condition", + "type": "score", + "label": "fraction", + "sublabel": "average" + }, + { + "col_name": "Best MS/MS", + "level": "condition", + "type": "array", + "label": "MS/MS", + "sublabel": "best" + }, + { + "col_name": "Intensity", + "level": "condition", + "type": "score", + "label": "Intensity", + "sublabel": "" + }, + { + "col_name": "Intensity L", + "level": "condition", + "type": "score", + "label": "Intensity", + "sublabel": "L" + }, + { + "col_name": "Intensity M", + "level": "condition", + "type": "score", + "label": "Intensity", + "sublabel": "M" + }, + { + "col_name": "Intensity H", + "level": "condition", + "type": "score", + "label": "Intensity", + "sublabel": "H" + }, + { + "col_name": "Q-value", + "level": "condition", + "type": "probability", + "label": "q-value", + "sublabel": "" + }, + { + "col_name": "Score", + "level": "condition", + "type": "probability", + "label": "score", + "sublabel": "" + }, + { + "col_name": "Unique sequence coverage [%]", + "level": "condition", + "type": "ratio", + "label": "sequence coverage", + "sublabel": "Unique" + }, + { + "col_name": "Unique + razor sequence coverage [%]", + "level": "condition", + "type": "ratio", + "label": "sequence coverage", + "sublabel": "Unique + razor" + }, + { + "col_name": "Sequence coverage [%]", + "level": "condition", + "type": "ratio", + "label": "sequence coverage", + "sublabel": "" + }, + { + "col_name": "Only identified by site", + "level": "feature", + "type": "category", + "label": "identified by site", + "sublabel": "" + }, + { + "col_name": "Peptide is razor", + "level": "condition", + "type": "array", + "label": "peptide", + "sublabel": "is razor" + } + ], + + "type_scores": + ["Peptides", "Razor + unique peptides", "Unique peptides", "Ratio M/L count", "Ratio M/L iso-count", "Ratio H/L count", "Ratio H/L iso-count" , + "Ratio H/M count", "Ratio H/M iso-count", "Intensity", "Intensity L", "Intensity M", "Intensity H", "MS/MS count", "LFQ intensity", + "Reporter intensity count", "Reporter intensity corrected", "Reporter intensity", "Fraction", "iBAQ", + "Reporter intensity corrected 0", "Reporter intensity corrected 1","Reporter intensity corrected 2", "Reporter intensity corrected 3", + "Reporter intensity corrected 4", "Reporter intensity corrected 5", "Reporter intensity 0", "Reporter intensity 1", + "Reporter intensity 2", "Reporter intensity 3", "Reporter intensity 4", "Reporter intensity 5", "Reporter intensity count 0", + "Reporter intensity count 1", "Reporter intensity count 2", "Reporter intensity count 3", "Reporter intensity count 4", + "Reporter intensity count 5" ], + + "type_ratios": + ["Sequence coverage", "Ratio H/M variability [%]", "Ratio H/M normalized", "Ratio H/M", "Ratio H/L variability [%]", "Ratio H/L normalized", "Ratio H/L", + "Ratio M/L", "Ratio M/L variability [%]", "Ratio M/L normalized"], + + "type_probability":[], + + "type_category": + ["Ratio H/M type", "Ratio H/L type", "Ratio M/L type", "Identification type"], + + "type_array": + [], + + "reduced_list": + ["Protein IDs", "Majority protein IDs", "Protein names", "Gene names", "Fasta headers", + "Peptides;exp", "Razor + unique peptides;exp", "Unique peptides;exp", "Mol. weight [kDa]", + "Sequence length", "Sequence coverage;exp", "Intensity;exp", "Reverse", "Potential contaminant", + "id", "Peptide IDs", "Mod. peptide IDs", "Evidence IDs", "Sequence lengths", "Phospho (STY) site IDs", + "Reporter intensity corrected 0;exp", + "Reporter intensity corrected 1;exp", + "Reporter intensity corrected 2;exp", + "Reporter intensity corrected 3;exp", + "Reporter intensity corrected 4;exp", + "Reporter intensity corrected 5;exp", + "LFQ intensity", + "Intensity L", "Intensity H", "Intensity M", "Ratio M/L normalized;exp", "Ratio H/L normalized;exp", + "Ratio H/M normalized;exp"] +} + diff --git a/tests/testthat/summary_test.txt b/tests/testthat/summary_test.txt new file mode 100755 index 0000000..fe507de --- /dev/null +++ b/tests/testthat/summary_test.txt @@ -0,0 +1,3 @@ +Raw file Experiment +raw_file1 Exp1 +raw_file2 Exp2 diff --git a/tests/testthat/summary_test_2.txt b/tests/testthat/summary_test_2.txt new file mode 100755 index 0000000..1e20ef8 --- /dev/null +++ b/tests/testthat/summary_test_2.txt @@ -0,0 +1,3 @@ +Raw file False +raw_file1 Exp1 +raw_file2 Exp2 diff --git a/tests/testthat/test-download.R b/tests/testthat/test-download.R new file mode 100644 index 0000000..f5f7dd4 --- /dev/null +++ b/tests/testthat/test-download.R @@ -0,0 +1,39 @@ +context("Download") + +test_that("ggplot is downloadable", { + plot <- ggplot2::ggplot(mtcars, ggplot2::aes(mpg, hp)) + ggplot2::geom_point() + width <- 20 + height <- 20 + file <- tempfile(fileext = ".zip") + filename <- "plot" + + expect_false(file.exists(file)) + expect_silent(download(file = file, filename = filename, plot = plot, width = width, height = height)) + expect_true(file.exists(file)) +}) + +test_that("plotly is downloadable", { + skip_on_cran() + + plot <- plotly::ggplotly(ggplot2::ggplot(mtcars, ggplot2::aes(mpg, hp)) + ggplot2::geom_point()) + width <- 20 + height <- 20 + file <- tempfile(fileext = ".zip") + filename <- "plot" + + expect_false(file.exists(file)) + expect_silent(download(file = file, filename = filename, plot = plot, width = width, height = height)) + expect_true(file.exists(file)) +}) + +test_that("complexHeatmap is downloadable", { + plot <- ComplexHeatmap::Heatmap(mtcars) + width <- 20 + height <- 20 + file <- tempfile(fileext = ".zip") + filename <- "plot" + + expect_false(file.exists(file)) + expect_silent(download(file = file, filename = filename, plot = plot, width = width, height = height)) + expect_true(file.exists(file)) +}) diff --git a/tests/testthat/test-equalize.R b/tests/testthat/test-equalize.R new file mode 100644 index 0000000..3509f28 --- /dev/null +++ b/tests/testthat/test-equalize.R @@ -0,0 +1,21 @@ +context("Equalize tables and vectors") + +test_that("equalize works with tables", { + table <- data.table::data.table(seq_len(10), seq(11, 20)) + eq <- equalize(table) + + expect_length(eq, 2) + expect_equal(eq, c(-20, 20)) +}) + +test_that("equalize works with vectors", { + vec <- seq_len(10) + eq <- equalize(vec) + + expect_length(eq, 2) + expect_equal(eq, c(-10, 10)) +}) + +test_that("non-numeric throws error", { + expect_error(equalize("a")) +}) diff --git a/tests/testthat/test-forceArgs.R b/tests/testthat/test-forceArgs.R new file mode 100644 index 0000000..2a628bc --- /dev/null +++ b/tests/testthat/test-forceArgs.R @@ -0,0 +1,31 @@ +context("forceArgs") + +test_that("arguments are evaluated", { + lazy_fun <- function(x, y) function() c(x, y) + forceArgs_fun <- function(x, y) { + forceArgs() + function() c(x, y) + } + + lazy_funList <- list() + for (i in 1:2) { + lazy_funList[[i]] <- lazy_fun(x = i, y = i) + } + lazy_result <- vapply(lazy_funList, function(x) x(), FUN.VALUE = numeric(2)) + + + forceArgs_funList <- list() + for (j in 1:2) { + forceArgs_funList[[j]] <- forceArgs_fun(x = j, y = j) + } + forceArgs_result <- vapply(forceArgs_funList, function(x) x(), FUN.VALUE = numeric(2)) + + forceAndCall_funList <- list() + for (k in 1:2) { + forceAndCall_funList[[k]] <- forceAndCall(n = 2, lazy_fun, x = k, y = k) + } + forceAndCall_result <- vapply(forceAndCall_funList, function(x) x(), FUN.VALUE = numeric(2)) + + expect_false(all(lazy_result == forceArgs_result)) + expect_equal(forceArgs_result, forceAndCall_result) +}) diff --git a/tests/testthat/test-interactive-plots.R b/tests/testthat/test-interactive-plots.R new file mode 100644 index 0000000..05df80a --- /dev/null +++ b/tests/testthat/test-interactive-plots.R @@ -0,0 +1,23 @@ +context("Create interactive plots") + +test_that("scatterplot can be created", { + data <- data.table::data.table(mtcars[, c("mpg", "hp", "vs")], keep.rownames = "id") + + out <- create_scatterplot(data, highlight.data = data[1:3,], highlight.color = "blue", color = c("red", "green"), categorized = TRUE, plot.method = "interactive") + expect_is(out$plot, class = "plotly") +}) + +test_that("heatmap can be created", { + data <- data.table::data.table(mtcars, keep.rownames = "id") + + out <- create_heatmap(data, colors = c("red", "green"), plot.method = "interactive") + expect_is(out$plot, class = "plotly") +}) + +test_that("geneview can be created", { + data <- data.table::data.table(mtcars, keep.rownames = "id") + grouping <- grouping <- data.table::data.table(names(data)[-1], factor = rep(c("a", "b"), length.out = ncol(data) - 1)) + + out <- create_geneview(data, grouping = grouping, colors = c("red", "green"), plot.method = "interactive") + expect_is(out$plot, class = "plotly") +}) diff --git a/tests/testthat/test-logging.R b/tests/testthat/test-logging.R new file mode 100644 index 0000000..1a54de6 --- /dev/null +++ b/tests/testthat/test-logging.R @@ -0,0 +1,27 @@ +context("Logging") + +test_that("logger can be created and deleted", { + logger <- log4r::create.logger() + token <- "test" + + expect_false(exists(paste0("logger", token), envir = wilson.globals)) + set_logger(logger = logger, token = token) + expect_identical(logger, get(paste0("logger", token), envir = wilson.globals)) + set_logger(logger = NULL, token = token) + expect_false(exists(paste0("logger", token), envir = wilson.globals)) +}) + +test_that("message can be logged", { + logfile <- tempfile() + logger <- log4r::create.logger(logfile = logfile, level = "DEBUG") + token <- "test_log" + + set_logger(logger = logger, token = token) + expect_false(file.exists(logfile)) + log_message("test message", level = "DEBUG", token = token) + expect_true(file.exists(logfile)) + file.remove(logfile) + set_logger(logger = NULL, token = token) + log_message("test message", level = "DEBUG", token = token) + expect_false(file.exists(logfile)) +}) diff --git a/tests/testthat/test-parser.R b/tests/testthat/test-parser.R new file mode 100644 index 0000000..859a2fd --- /dev/null +++ b/tests/testthat/test-parser.R @@ -0,0 +1,12 @@ +context("Parse clarion file") + +test_that("file is parsed correctly", { + object <- parser(file = "wiki_example.clarion", dec = ",") + + expect_is(object, "Clarion") + expect_equal(object$get_delimiter(), "|") + expect_equal(object$get_factors(), object$metadata[, c("key", "factor1", "factor2")]) + expect_equal(object$get_id(), "id") + expect_equal(object$get_name(), "name") + expect_equal(object$is_delimited(names(object$data)), c(rep(FALSE, 3), TRUE, rep(FALSE, 8))) +}) diff --git a/tests/testthat/test-searchData.R b/tests/testthat/test-searchData.R new file mode 100644 index 0000000..22be414 --- /dev/null +++ b/tests/testthat/test-searchData.R @@ -0,0 +1,51 @@ +context("orNumeric searchData function") + +test_that("no selection returns all TRUE", { + input <- c(5) + choices <- c(seq_len(20), NA, NaN) + selection <- searchData(input = input, choices = choices, options = NULL) + + expect_length(selection, length(choices)) + expect_type(selection, "logical") + expect_equal(selection, rep(TRUE, length(choices))) +}) + +test_that("ranged selection is correct", { + input <- c(2, 5) + choices <- c(seq_len(20), NA, NaN) + selection_inner <- searchData(input = input, choices = choices, options = "inner") + selection_outer <- searchData(input = input, choices = choices, options = "outer") + + expect_length(selection_inner, length(choices)) + expect_type(selection_inner, "logical") + expect_equal(selection_inner, c(FALSE, rep(TRUE, 4), rep(FALSE, 17))) + + expect_length(selection_outer, length(choices)) + expect_type(selection_outer, "logical") + expect_equal(selection_outer, c(TRUE, rep(FALSE, 4), rep(TRUE, 15), rep(FALSE, 2))) +}) + +test_that("single selection is correct", { + input <- c(2) + choices <- c(seq_len(20), NA, NaN) + selection_equal <- searchData(input = input, choices = choices, options = "=") + selection_smaller <- searchData(input = input, choices = choices, options = "<") + selection_greater <- searchData(input = input, choices = choices, options = ">") + selection_all <- searchData(input = input, choices = choices, options = c("=", "<", ">")) + + expect_length(selection_equal, length(choices)) + expect_type(selection_equal, "logical") + expect_equal(selection_equal, c(FALSE, TRUE, rep(FALSE, 20))) + + expect_length(selection_smaller, length(choices)) + expect_type(selection_smaller, "logical") + expect_equal(selection_smaller, c(TRUE, rep(FALSE, 21))) + + expect_length(selection_greater, length(choices)) + expect_type(selection_greater, "logical") + expect_equal(selection_greater, c(rep(FALSE, 2), rep(TRUE, 18), rep(FALSE, 2))) + + expect_length(selection_all, length(choices)) + expect_type(selection_all, "logical") + expect_equal(selection_all, c(rep(TRUE, 20), rep(FALSE, 2))) +}) diff --git a/tests/testthat/test-static-plots.R b/tests/testthat/test-static-plots.R new file mode 100644 index 0000000..b301dfc --- /dev/null +++ b/tests/testthat/test-static-plots.R @@ -0,0 +1,31 @@ +context("Create static plots") + +test_that("scatterplot can be created", { + data <- data.table::data.table(mtcars[, c("mpg", "hp", "vs")], keep.rownames = "id") + + out <- create_scatterplot(data, highlight.data = data[1:3,], highlight.color = "blue", color = c("red", "green"), categorized = TRUE) + vdiffr::expect_doppelganger("static scatterplot", out$plot) +}) + +test_that("pca can be created", { + data <- data.table::data.table(mtcars, keep.rownames = "id") + grouping <- rep(c("a", "b", "c"), length.out = ncol(data) - 1) + + out <- create_pca(data, color.group = grouping, shape.group = grouping, palette = c("red", "green", "blue")) + vdiffr::expect_doppelganger("static pca", out$plot) +}) + +test_that("heatmap can be created", { + data <- data.table::data.table(mtcars, keep.rownames = "id") + + out <- create_heatmap(data, colors = c("red", "green")) + vdiffr::expect_doppelganger("static heatmap", out$plot) +}) + +test_that("geneview can be created", { + data <- data.table::data.table(mtcars, keep.rownames = "id") + grouping <- grouping <- data.table::data.table(names(data)[-1], factor = rep(c("a", "b"), length.out = ncol(data) - 1)) + + out <- create_geneview(data, grouping = grouping, colors = c("red", "green")) + vdiffr::expect_doppelganger("static geneview", out$plot) +}) diff --git a/tests/testthat/test_mqparser.R b/tests/testthat/test_mqparser.R new file mode 100644 index 0000000..be5acd9 --- /dev/null +++ b/tests/testthat/test_mqparser.R @@ -0,0 +1,25 @@ +context("MaxQuant parser") + +test_that("all needed input parameteres are given", { + expect_error(parse_MaxQuant(), "The proteinGroups file was not given") + expect_error(parse_MaxQuant(proteinGroups_in = "./path/path/"), "The summary file was not given") + expect_error(parse_MaxQuant(proteinGroups_in = "./path/path/", summary_in = "./path/path/"), + "The output file was not given") + expect_error(parse_MaxQuant(proteinGroups_in = "./path/path/", summary_in = "./path/path/", + outfile = "./path/path/"), "The output_reduced file was not given") +}) + +test_that("mq_parser", { + + expect_error(parse_MaxQuant(proteinGroups_in = "proteinGroups_test.txt", summary_in = "summary_test_2.txt", + outfile = "./out", outfile_reduced = "./outres" ), + "wrong format on summary file: column \'Experiment\' misssing") + expect_true(parse_MaxQuant(proteinGroups_in = "proteinGroups_test.txt", summary_in = "summary_test.txt", + outfile = "./out", outfile_reduced = "./outres", config = "success_config.json")) + expect_error(parse_MaxQuant(proteinGroups_in = "proteinGroups_test.txt", summary_in = "summary_test.txt", + outfile = "./out", outfile_reduced = "./outres", config = "" ), + "Could not read config file") + expect_error(parse_MaxQuant(proteinGroups_in = "proteinGroups_test.txt", summary_in = "summary_test.txt", + outfile = "./out", outfile_reduced = "./outres", config = "fail_config.json" ), + "reduced_list is missing in config file") +}) diff --git a/tests/testthat/wiki_example.clarion b/tests/testthat/wiki_example.clarion new file mode 100644 index 0000000..919074a --- /dev/null +++ b/tests/testthat/wiki_example.clarion @@ -0,0 +1,23 @@ +!format=Clarion +!version=1.0 +!experiment_id=123456 +!delimiter=| +#key factor1 factor2 level type label sub_label +#id feature unique_id Identifier unique +#name feature name Name +#active feature category Active +#attr feature array Attributes +#sample_a_1 sample_a 6h sample score Sample A first +#sample_a_2 sample_a 12h sample score Sample A second +#sample_b_1 sample_b 6h sample score Sample B first +#sample_b_2 sample_b 12h sample score Sample B second +#mean_a sample_a condition score Sample A mean +#mean_b sample_b condition score Sample B mean +#fc_ab contrast ratio Sample A|Sample B Fold change +#pval contrast probability Sample A|Sample B P-Value +id name active attr sample_a_1 sample_a_2 sample_b_1 sample_b_2 mean_a mean_b fc_ab pval +id_1 AAA Yes attr1|attr2 10000 100 50 500 5050 275 18,36363636 0,1 +id_2 BBB Yes attr2|attr3 300 400 40000 2302 350 21151 0,016547681 0,2 +id_3 CCC No attr3|attr4 20 2300 12002 5600 1160 8801 0,131803204 0,4 +id_4 DDD No attr5 1234 10 9500 1200 622 5350 0,116261682 0,01 +id_5 EEE No attr7|attr8|attr1 900 450 940 60 675 500 1,35 0,9 diff --git a/vignettes/intro.Rmd b/vignettes/intro.Rmd new file mode 100644 index 0000000..5832988 --- /dev/null +++ b/vignettes/intro.Rmd @@ -0,0 +1,87 @@ +--- +title: "Introduction" +author: "Hendrik Schultheis" +date: "`r Sys.Date()`" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Introduction} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r setup, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +This vignette describes the intended workflow and usage of the wilson package for building an application and provides a simple example. + +**Prerequisites:** + +* be familiar with the basic structure of a [shiny-app](https://shiny.rstudio.com/articles/basics.html) and [shinydashboard](https://rstudio.github.io/shinydashboard/get_started.html) +* know how to use [shiny-modules](https://shiny.rstudio.com/articles/modules.html#using-modules) +* have a sufficient dataset in clarion-format + * either by [converting](https://github.molgen.mpg.de/loosolab/wilson-apps/wiki/CLARION-Format/) your own data + * or downloading from [here](https://github.molgen.mpg.de/loosolab/wilson-apps/tree/master/wilson-basic/data/) + +## Workflow + +The workflow of a wilson-application can roughly be divided into three basic steps: + +1. load data +2. filter data +3. visualize data + +But depending on the actual implementation neither the order nor the number of steps are set. Resulting in enhanced usability as for example the filter can be changed at any given time. + +## Example + +In this example we will create a wilson-application with a static dataset, a single visualization method and a preceding filter, seperated into a *Filter* and a *Visualization* tab. + +So to start we first import the needed packages and afterwards define the application interface: +``` +library(shiny) +library(shinydashboard) +library(wilson) + +# Define UI for application +ui <- dashboardPage( + header = dashboardHeader(disable = TRUE), + sidebar = dashboardSidebar(disable = TRUE), + body = dashboardBody( + tags$style(type = "text/css", "body {padding-top: 50px;}"), + navbarPage( + title = "wilson example", + position = "fixed-top", + tabPanel(title = "Filter", + # Load filter UI + featureSelectorUI(id = "filter")), + tabPanel(title = "Visualization", + # Load scatterplot UI + scatterPlotUI(id = "scatter")) + ))) +``` +This code creates an UI with two tabs. The first tab with the title *Filter* contains the filter UI called with `featureSelectorUI()` whereas the UI needed for a scatterplot called with `scatterPlotUI()` is enclosed by the second tab (*Visualization*). + +Second the server function needs to be as follows: +``` +# Define server logic required for filtering and plotting +server <- function(input, output, session) { + # load/ parse data + # change this path to match your file location + data <- parser("../wilson-apps/wilson-basic/data/A_RNAseq_Zhang_2015.se") + + # Load filter server logic + filtered_data <- callModule(module = featureSelector, id = "filter", clarion = data) + # Load scatterplot server logic + callModule(module = scatterPlot, id = "scatter", clarion = reactive(filtered_data()$object)) +} + +# Run the application +shinyApp(ui = ui, server = server) +``` +The server reacts to user interactions whith the interface. Once started it will first parse the given [clarion](https://github.molgen.mpg.de/loosolab/wilson-apps/wiki/CLARION-Format/) file into a clarion object, performing validation steps in the process. Next the server functions of the necessary [modules](https://shiny.rstudio.com/articles/modules.html) defined in the UI (notice the matching ids) are loaded. Whereas the filter module bluntly accepts the data object with `clarion = data` the plot module receives its data via `clarion = reactive(filtered_data()$object)`. Wrapping in `reactive()` is due to the fact, that the filtered data object returned from the filter module is in a reactive context which essentially means shiny 'knows' when this variable changes. Read more about shiny's reactivity system [here](https://shiny.rstudio.com/articles/reactivity-overview.html). + +For a more advanced example of a wilson-application see the [wilson-basic app](https://github.molgen.mpg.de/loosolab/wilson-apps/blob/master/wilson-basic/app.R) in our [wilson-apps](https://github.molgen.mpg.de/loosolab/wilson-apps/) repository. diff --git a/wilson.Rproj b/wilson.Rproj index 49f2092..6291372 100644 --- a/wilson.Rproj +++ b/wilson.Rproj @@ -17,3 +17,4 @@ StripTrailingWhitespace: Yes BuildType: Package PackageUseDevtools: Yes PackageInstallArgs: --no-multiarch --with-keep.source +PackageCheckArgs: --as-cran