From 088bae3ccfb0bfee174a342f9ea1b7a1732d9ef9 Mon Sep 17 00:00:00 2001 From: cpsievert Date: Tue, 19 Jan 2016 15:34:58 -0600 Subject: [PATCH 1/5] Copy extras over from plotly.js, if necessary --- R/plotly.R | 8 ++++++-- R/print.R | 3 +++ R/utils.R | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/R/plotly.R b/R/plotly.R index 0d6e3d1a9b..7ab1a7b56d 100644 --- a/R/plotly.R +++ b/R/plotly.R @@ -192,6 +192,9 @@ layout <- function(p = last_plot(), ..., #' @param displayModeBar display the modebar (T, F, or 'hover') #' @param displaylogo add the plotly logo on the end of the modebar #' @param plot3dPixelRatio increase the pixel ratio for 3D plot images +#' @param mathjax whether to include mathjax. If \code{TRUE}, you must have +#' a local copy of plotly.js and set the environment variable plotly_jsdir to +#' its location #' @author Carson Sievert #' @export @@ -201,7 +204,7 @@ config <- function(p = last_plot(), staticPlot = F, workspace = F, editable = F, autosizable = F, fillFrame = F, scrollZoom = F, doubleClick = 'reset+autosize', showTips = F, showLink = T, sendData = T, linkText = 'Edit chart', displayModeBar = 'hover', - displaylogo = T, plot3dPixelRatio = 2) { + displaylogo = T, plot3dPixelRatio = 2, mathjax = FALSE) { conf <- list( staticPlot = staticPlot, workspace = workspace, @@ -216,7 +219,8 @@ config <- function(p = last_plot(), staticPlot = F, workspace = F, editable = F, linkText = linkText, displayModeBar = displayModeBar, displaylogo = displaylogo, - plot3dPixelRatio = plot3dPixelRatio + plot3dPixelRatio = plot3dPixelRatio, + mathjax = mathjax ) p <- last_plot(p) p$config <- c(p$config, conf) diff --git a/R/print.R b/R/print.R index ff4c507d63..5c0472687d 100644 --- a/R/print.R +++ b/R/print.R @@ -40,6 +40,8 @@ as.widget <- function(x, ...) { ) # customize the JSON serializer (for htmlwidgets) attr(p, 'TOJSON_FUNC') <- to_JSON + # get plotlyjs assets, if necessary + deps <- get_assets(p) htmlwidgets::createWidget( name = "plotly", x = p, @@ -49,6 +51,7 @@ as.widget <- function(x, ...) { padding = 5, browser.fill = TRUE ), + dependencies = deps, ... ) } diff --git a/R/utils.R b/R/utils.R index 7b33882c71..08cfd2b32d 100644 --- a/R/utils.R +++ b/R/utils.R @@ -229,3 +229,62 @@ cat_profile <- function(key, value, path = "~") { message("Adding plotly_", key, " environment variable to ", r_profile) cat(snippet, file = r_profile, append = TRUE) } + +get_assets <- function(p) { + types <- unlist(lapply(p$data, "[[", "type")) + deps <- list(NULL) + # if there are any geo trace(s), add the geo assets dependency + if (any(grepl("geo|choropleth", types))) { + deps[[1]] <- plotly_dist("geo") + } + if (isTRUE(p$config$mathjax)) { + deps[[2]] <- plotly_dist("mathjax") + } + deps +} + +# helper function for including large plotlyjs assets +plotly_dist <- function(extra = c("mathjax", "geo")) { + path <- Sys.getenv("plotly_jsdir", unset = NA) + if (extra[1] == "mathjax") { + if (is.na(path)) { + stop("MathJax support requires a local clone of the plotly.js repo \n", + "https://github.com/plotly/plotly.js \n", + "Once you have plotly.js locally, set the plotly_jsdir \n", + "environment variable with the path to plotly.js") + } else { + mj <- file.path(path, "dist", "extras", "mathjax", "MathJax.js") + if (!file.exists(mj)) stop("Couldn't locate MathJax.js") + # parse the version + mathjax <- readLines(mj) + pat <- 'MathJax.fileversion="[0-9]+.[0-9]+.[0-9]+' + ver <- regmatches(mathjax, regexpr(pat, mathjax)) + ver <- sub('"', '', strsplit(ver, "=")[[1]][2]) + htmltools::htmlDependency( + name = "mathjax", + version = ver, + src = dirname(mj), + script = basename(mj) + ) + } + } + if (extra[1] == "geo") { + if (is.na(path)) { + warning("Rendering 'geo' traces without an internet connection \n", + "requires a local clone of the plotly.js repo \n", + "https://github.com/plotly/plotly.js \n", + "Once you have plotly.js locally, set the plotly_jsdir \n", + "environment variable with the path to plotly.js") + return(NULL) + } else { + geo <- file.path(path, "dist", "plotly-geo-assets.js") + if (!file.exists(geo)) stop("Couldn't locate plotly-geo-assets.js") + htmltools::htmlDependency( + name = "plotly-geo-assets", + src = dirname(geo), + version = "1.0", + script = basename(geo) + ) + } + } +} From 004bbf55c9a1fcd14233d817ade7acffc51d51c2 Mon Sep 17 00:00:00 2001 From: cpsievert Date: Tue, 19 Jan 2016 16:41:51 -0600 Subject: [PATCH 2/5] fix dependency handling --- R/utils.R | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/R/utils.R b/R/utils.R index 08cfd2b32d..aed6ef8e05 100644 --- a/R/utils.R +++ b/R/utils.R @@ -235,10 +235,10 @@ get_assets <- function(p) { deps <- list(NULL) # if there are any geo trace(s), add the geo assets dependency if (any(grepl("geo|choropleth", types))) { - deps[[1]] <- plotly_dist("geo") + deps <- c(deps, plotly_dist("geo")) } if (isTRUE(p$config$mathjax)) { - deps[[2]] <- plotly_dist("mathjax") + deps <- c(deps, plotly_dist("mathjax")) } deps } @@ -260,12 +260,13 @@ plotly_dist <- function(extra = c("mathjax", "geo")) { pat <- 'MathJax.fileversion="[0-9]+.[0-9]+.[0-9]+' ver <- regmatches(mathjax, regexpr(pat, mathjax)) ver <- sub('"', '', strsplit(ver, "=")[[1]][2]) - htmltools::htmlDependency( + dep <- htmltools::htmlDependency( name = "mathjax", version = ver, src = dirname(mj), script = basename(mj) ) + return(list(dep)) } } if (extra[1] == "geo") { @@ -279,12 +280,13 @@ plotly_dist <- function(extra = c("mathjax", "geo")) { } else { geo <- file.path(path, "dist", "plotly-geo-assets.js") if (!file.exists(geo)) stop("Couldn't locate plotly-geo-assets.js") - htmltools::htmlDependency( + dep <- htmltools::htmlDependency( name = "plotly-geo-assets", src = dirname(geo), version = "1.0", script = basename(geo) ) + return(list(dep)) } } } From a7d61b261aaaa5126538ef2df16c054b979cb2b1 Mon Sep 17 00:00:00 2001 From: cpsievert Date: Wed, 20 Jan 2016 14:32:28 -0600 Subject: [PATCH 3/5] reorganize dependency logic for more control over their placement --- R/plotly.R | 9 +- R/print.R | 4 +- R/utils.R | 61 +++++++----- inst/htmlwidgets/lib/plotlyjs/package.json | 103 +++++++++++++++++++++ inst/htmlwidgets/plotly.js | 7 ++ inst/htmlwidgets/plotly.yaml | 5 - inst/plotlyjs.R | 2 + man/config.Rd | 9 +- 8 files changed, 167 insertions(+), 33 deletions(-) create mode 100644 inst/htmlwidgets/lib/plotlyjs/package.json delete mode 100644 inst/htmlwidgets/plotly.yaml diff --git a/R/plotly.R b/R/plotly.R index 7ab1a7b56d..b0cb454b98 100644 --- a/R/plotly.R +++ b/R/plotly.R @@ -192,9 +192,12 @@ layout <- function(p = last_plot(), ..., #' @param displayModeBar display the modebar (T, F, or 'hover') #' @param displaylogo add the plotly logo on the end of the modebar #' @param plot3dPixelRatio increase the pixel ratio for 3D plot images -#' @param mathjax whether to include mathjax. If \code{TRUE}, you must have -#' a local copy of plotly.js and set the environment variable plotly_jsdir to -#' its location +#' @param mathjax If \code{FALSE}, don't attempt to include mathjax. +#' If \code{'cdn'}, mathjax will be loaded externally (meaning an internet +#' connection is needed to view the graph). If \code{'local'}, a local copy +#' of mathjax will be included. For this to work, you'll need a local copy of +#' plotly.js and set the environment variable plotly_jsdir to its location on +#' your machine. #' @author Carson Sievert #' @export diff --git a/R/print.R b/R/print.R index 5c0472687d..21db4ec657 100644 --- a/R/print.R +++ b/R/print.R @@ -40,8 +40,6 @@ as.widget <- function(x, ...) { ) # customize the JSON serializer (for htmlwidgets) attr(p, 'TOJSON_FUNC') <- to_JSON - # get plotlyjs assets, if necessary - deps <- get_assets(p) htmlwidgets::createWidget( name = "plotly", x = p, @@ -51,7 +49,7 @@ as.widget <- function(x, ...) { padding = 5, browser.fill = TRUE ), - dependencies = deps, + dependencies = plotly_dependencies(p), ... ) } diff --git a/R/utils.R b/R/utils.R index aed6ef8e05..6052a1a1ef 100644 --- a/R/utils.R +++ b/R/utils.R @@ -230,25 +230,24 @@ cat_profile <- function(key, value, path = "~") { cat(snippet, file = r_profile, append = TRUE) } -get_assets <- function(p) { - types <- unlist(lapply(p$data, "[[", "type")) - deps <- list(NULL) - # if there are any geo trace(s), add the geo assets dependency - if (any(grepl("geo|choropleth", types))) { - deps <- c(deps, plotly_dist("geo")) - } - if (isTRUE(p$config$mathjax)) { - deps <- c(deps, plotly_dist("mathjax")) - } - deps + +# Needed since we can't control the order of conditional dependencies +plotly_dependencies <- function(p) { + deps <- list( + html_dependency_mathjax(p), + html_dependency_geo(p), + # TODO: build plotlyjs without d3/topojson and include separately? + html_dependency_plotly() + ) + # mathjax/geo dependencies may return NULL which can cause problems + Filter(Negate(is.null), deps) } -# helper function for including large plotlyjs assets -plotly_dist <- function(extra = c("mathjax", "geo")) { - path <- Sys.getenv("plotly_jsdir", unset = NA) - if (extra[1] == "mathjax") { +html_dependency_mathjax <- function(p) { + if (isTRUE(p$config$mathjax == "local")) { + path <- Sys.getenv("plotly_jsdir", unset = NA) if (is.na(path)) { - stop("MathJax support requires a local clone of the plotly.js repo \n", + stop("Local mathjax requires a local clone of the plotly.js repo \n", "https://github.com/plotly/plotly.js \n", "Once you have plotly.js locally, set the plotly_jsdir \n", "environment variable with the path to plotly.js") @@ -264,12 +263,19 @@ plotly_dist <- function(extra = c("mathjax", "geo")) { name = "mathjax", version = ver, src = dirname(mj), - script = basename(mj) + script = c(basename(mj), "config/TeX-AMS-MML_SVG.js") ) - return(list(dep)) + return(dep) } } - if (extra[1] == "geo") { + return(NULL) +} + +html_dependency_geo <- function(p) { + types <- unlist(lapply(p$data, "[[", "type")) + # if there are any geo trace(s), add the geo assets dependency + if (any(grepl("geo|choropleth", types))) { + path <- Sys.getenv("plotly_jsdir", unset = NA) if (is.na(path)) { warning("Rendering 'geo' traces without an internet connection \n", "requires a local clone of the plotly.js repo \n", @@ -283,10 +289,23 @@ plotly_dist <- function(extra = c("mathjax", "geo")) { dep <- htmltools::htmlDependency( name = "plotly-geo-assets", src = dirname(geo), - version = "1.0", + version = plotly_version(), script = basename(geo) ) - return(list(dep)) } } } + +html_dependency_plotly <- function() { + htmltools::htmlDependency( + name = "plotly.js", + src = system.file("htmlwidgets", "lib", "plotlyjs", package = "plotly"), + version = plotly_version(), + script = "plotly-latest.min.js" + ) +} + +plotly_version <- function() { + pkg <- system.file("htmlwidgets", "lib", "plotlyjs", "package.json", package = "plotly") + jsonlite::fromJSON(pkg)$version +} diff --git a/inst/htmlwidgets/lib/plotlyjs/package.json b/inst/htmlwidgets/lib/plotlyjs/package.json new file mode 100644 index 0000000000..8b3b1cb104 --- /dev/null +++ b/inst/htmlwidgets/lib/plotlyjs/package.json @@ -0,0 +1,103 @@ +{ + "name": "plotly.js", + "version": "1.4.1", + "description": "The open source javascript graphing library that powers plotly", + "license": "MIT", + "main": "./src/index.js", + "webpack": "./dist/plotly.min.js", + "repository": { + "type": "git", + "url": "https://github.com/plotly/plotly.js.git" + }, + "bugs": { + "url": "https://github.com/plotly/plotly.js/issues" + }, + "author": "Plotly, Inc.", + "keywords": [ + "graphing", + "plotting", + "data", + "visualization", + "plotly" + ], + "scripts": { + "preprocess": "node tasks/preprocess.js", + "bundle": "node tasks/bundle.js", + "header": "node tasks/header.js", + "build": "npm run preprocess && npm run bundle && npm run header", + "cibuild": "node tasks/cibundle.js", + "watch": "node tasks/watch_plotly.js", + "lint": "cd src && jshint . || true", + "test-jasmine": "karma start test/jasmine/karma.conf.js", + "citest-jasmine": "karma start test/jasmine/karma.ciconf.js", + "test-image": "./tasks/test_image.sh", + "test-syntax": "node test/syntax_test.js", + "test": "npm run test-jasmine && npm test-image", + "start-test_dashboard": "node devtools/test_dashboard/server.js", + "start-image_viewer": "node devtools/image_viewer/server.js", + "baseline": "./tasks/baseline.sh", + "version": "npm run build && git add -A dist", + "postversion": "git push && git push --tags" + }, + "dependencies": { + "3d-view": "^2.0.0", + "alpha-shape": "^1.0.0", + "arraytools": "^1.0.0", + "convex-hull": "^1.0.3", + "d3": "3.5.6", + "delaunay-triangulate": "^1.1.6", + "es6-promise": "^3.0.2", + "fast-isnumeric": "^1.1.1", + "fs-extra": "^0.26.2", + "gl-error2d": "^1.0.0", + "gl-error3d": "^1.0.0", + "gl-line2d": "^1.2.1", + "gl-line3d": "^1.0.1", + "gl-mat4": "^1.1.2", + "gl-mesh3d": "^1.0.4", + "gl-plot2d": "^1.1.6", + "gl-plot3d": "^1.3.0", + "gl-scatter2d": "^1.0.5", + "gl-scatter2d-fancy": "^1.1.1", + "gl-scatter3d": "^1.0.4", + "gl-select-box": "^1.0.1", + "gl-spikes2d": "^1.0.1", + "gl-surface3d": "^1.1.0", + "mouse-change": "^1.1.1", + "mouse-wheel": "^1.0.2", + "ndarray": "^1.0.16", + "ndarray-fill": "^1.0.1", + "ndarray-homography": "^1.0.0", + "ndarray-ops": "^1.2.2", + "right-now": "^1.0.0", + "robust-orientation": "^1.1.3", + "sane-topojson": "^1.2.0", + "superscript-text": "^1.0.0", + "tinycolor2": "1.1.2", + "topojson": "^1.6.19" + }, + "devDependencies": { + "brfs": "^1.4.1", + "browserify": "^12.0.1", + "browserify-transform-tools": "^1.5.0", + "ecstatic": "^1.2.0", + "falafel": "^1.2.0", + "glob": "^6.0.1", + "jasmine-core": "^2.3.4", + "jshint": "^2.8.0", + "karma": "^0.13.15", + "karma-browserify": "^4.4.1", + "karma-chrome-launcher": "^0.2.1", + "karma-coverage": "^0.5.3", + "karma-firefox-launcher": "^0.1.6", + "karma-jasmine": "^0.3.6", + "node-sass": "^3.4.1", + "open": "0.0.5", + "prepend-file": "^1.3.0", + "prettysize": "0.0.3", + "through2": "^2.0.0", + "uglify-js": "^2.5.0", + "watchify": "^3.6.0", + "xml2js": "^0.4.15" + } +} diff --git a/inst/htmlwidgets/plotly.js b/inst/htmlwidgets/plotly.js index 2c4f18e6e3..b0c6afa503 100644 --- a/inst/htmlwidgets/plotly.js +++ b/inst/htmlwidgets/plotly.js @@ -19,6 +19,13 @@ HTMLWidgets.widget({ if (!instance.plotly) { Plotly.plot(el.id, x.data, x.layout, x.config); instance.plotly = true; + if (x.config.mathjax == "cdn" && !instance.mathjax) { + var script = document.createElement("script"); + script.type = "text/javascript"; + script.src = "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_SVG"; + document.getElementsByTagName("head")[0].appendChild(script); + instance.mathjax = true; + } } else { Plotly.newPlot(el.id, x.data, x.layout); } diff --git a/inst/htmlwidgets/plotly.yaml b/inst/htmlwidgets/plotly.yaml deleted file mode 100644 index a8f8da40a9..0000000000 --- a/inst/htmlwidgets/plotly.yaml +++ /dev/null @@ -1,5 +0,0 @@ -dependencies: - - name: plotlyjs - version: 1.4.1 - src: "htmlwidgets/lib/plotlyjs" - script: plotly-latest.min.js diff --git a/inst/plotlyjs.R b/inst/plotlyjs.R index c784098879..31817fdbf5 100644 --- a/inst/plotlyjs.R +++ b/inst/plotlyjs.R @@ -8,6 +8,8 @@ p <- Sys.glob("plotly-plotly.js*/dist/plotly.min.js") file.copy(p, "inst/htmlwidgets/lib/plotlyjs/plotly-latest.min.js", overwrite = T) l <- Sys.glob("plotly-plotly.js*/LICENSE") file.copy(l, "inst/htmlwidgets/lib/plotlyjs/LICENSE", overwrite = T) +l <- Sys.glob("plotly-plotly.js*/package.json") +file.copy(l, "inst/htmlwidgets/lib/plotlyjs/package.json", overwrite = T) unlink("plotly-plotly.js*", recursive = T) # update plotly.yml with version basename(zip) diff --git a/man/config.Rd b/man/config.Rd index fd1785f8ca..d7fe141340 100644 --- a/man/config.Rd +++ b/man/config.Rd @@ -8,7 +8,7 @@ config(p = last_plot(), staticPlot = F, workspace = F, editable = F, autosizable = F, fillFrame = F, scrollZoom = F, doubleClick = "reset+autosize", showTips = F, showLink = T, sendData = T, linkText = "Edit chart", displayModeBar = "hover", - displaylogo = T, plot3dPixelRatio = 2) + displaylogo = T, plot3dPixelRatio = 2, mathjax = FALSE) } \arguments{ \item{p}{a plotly object} @@ -40,6 +40,13 @@ config(p = last_plot(), staticPlot = F, workspace = F, editable = F, \item{displaylogo}{add the plotly logo on the end of the modebar} \item{plot3dPixelRatio}{increase the pixel ratio for 3D plot images} + +\item{mathjax}{If \code{FALSE}, don't attempt to include mathjax. +If \code{'cdn'}, mathjax will be loaded externally (meaning an internet +connection is needed to view the graph). If \code{'local'}, a local copy +of mathjax will be included. For this to work, you'll need a local copy of +plotly.js and set the environment variable plotly_jsdir to its location on +your machine.} } \description{ Set the default configuration for plotly From b01a554f634f597a6e3c9977442f8cb30434474d Mon Sep 17 00:00:00 2001 From: cpsievert Date: Mon, 25 Jan 2016 09:32:55 -0600 Subject: [PATCH 4/5] include mathjax cdn injection script as its own dependency --- R/utils.R | 8 ++++++++ inst/htmlwidgets/lib/mathjax/mathjax-cdn.js | 6 ++++++ inst/htmlwidgets/plotly.js | 7 ------- vignettes/intro.Rmd | 4 ++-- 4 files changed, 16 insertions(+), 9 deletions(-) create mode 100644 inst/htmlwidgets/lib/mathjax/mathjax-cdn.js diff --git a/R/utils.R b/R/utils.R index 6052a1a1ef..267b6dc4c1 100644 --- a/R/utils.R +++ b/R/utils.R @@ -268,6 +268,14 @@ html_dependency_mathjax <- function(p) { return(dep) } } + if (isTRUE(p$config$mathjax == "cdn")) { + htmltools::htmlDependency( + name = "mathjax-cdn", + version = "latest", + src = system.file("htmlwidgets", "lib", "mathjax", package = "plotly"), + script = "mathjax-cdn.js" + ) + } return(NULL) } diff --git a/inst/htmlwidgets/lib/mathjax/mathjax-cdn.js b/inst/htmlwidgets/lib/mathjax/mathjax-cdn.js new file mode 100644 index 0000000000..a1b2281f53 --- /dev/null +++ b/inst/htmlwidgets/lib/mathjax/mathjax-cdn.js @@ -0,0 +1,6 @@ +(function () { + var script = document.createElement("script"); + script.type = "text/javascript"; + script.src = "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_SVG"; + document.getElementsByTagName("head")[0].appendChild(script); +})(); diff --git a/inst/htmlwidgets/plotly.js b/inst/htmlwidgets/plotly.js index b0c6afa503..2c4f18e6e3 100644 --- a/inst/htmlwidgets/plotly.js +++ b/inst/htmlwidgets/plotly.js @@ -19,13 +19,6 @@ HTMLWidgets.widget({ if (!instance.plotly) { Plotly.plot(el.id, x.data, x.layout, x.config); instance.plotly = true; - if (x.config.mathjax == "cdn" && !instance.mathjax) { - var script = document.createElement("script"); - script.type = "text/javascript"; - script.src = "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_SVG"; - document.getElementsByTagName("head")[0].appendChild(script); - instance.mathjax = true; - } } else { Plotly.newPlot(el.id, x.data, x.layout); } diff --git a/vignettes/intro.Rmd b/vignettes/intro.Rmd index 3400f16af0..823005c278 100644 --- a/vignettes/intro.Rmd +++ b/vignettes/intro.Rmd @@ -36,7 +36,7 @@ You can manually add a trace to an existing plot with `add_trace()`. In that cas ```{r} m <- loess(unemploy / pop ~ as.numeric(date), data = economics) p <- plot_ly(economics, x = date, y = unemploy / pop, name = "raw") -add_trace(p, y = fitted(m), name = "loess") +add_trace(p, x = date, y = fitted(m), name = "loess") ``` __plotly__ was designed with a [pure, predictable, and pipeable interface](https://dl.dropboxusercontent.com/u/41902/pipe-dsls.pdf) in mind, so you can also use the `%>%` operator to create a visualization pipeline: @@ -44,7 +44,7 @@ __plotly__ was designed with a [pure, predictable, and pipeable interface](https ```{r} economics %>% plot_ly(x = date, y = unemploy / pop) %>% - add_trace(y = fitted(m)) %>% + add_trace(x = date, y = fitted(m)) %>% layout(showlegend = F) ``` From d0e032856b73483473e7e2e07660c057768830c2 Mon Sep 17 00:00:00 2001 From: cpsievert Date: Mon, 25 Jan 2016 09:41:44 -0600 Subject: [PATCH 5/5] valid version --- R/utils.R | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/R/utils.R b/R/utils.R index 267b6dc4c1..04f8184182 100644 --- a/R/utils.R +++ b/R/utils.R @@ -269,12 +269,13 @@ html_dependency_mathjax <- function(p) { } } if (isTRUE(p$config$mathjax == "cdn")) { - htmltools::htmlDependency( + dep <- htmltools::htmlDependency( name = "mathjax-cdn", - version = "latest", + version = "1.0", src = system.file("htmlwidgets", "lib", "mathjax", package = "plotly"), script = "mathjax-cdn.js" ) + return(dep) } return(NULL) }