├── .Rbuildignore
├── .gitignore
├── .workbch
├── DESCRIPTION
├── LICENSE
├── NAMESPACE
├── R
├── build_api.R
├── build_experiment.R
├── build_timeline.R
├── helpers_js.R
├── helpers_misc.R
├── trial_categorise.R
├── trial_simple.R
├── trial_survey.R
└── validators.R
├── README.Rmd
├── README.md
├── _pkgdown.yml
├── docs
├── 404.html
├── LICENSE-text.html
├── authors.html
├── docsearch.css
├── docsearch.js
├── index.html
├── link.svg
├── pkgdown.css
├── pkgdown.js
├── pkgdown.yml
└── reference
│ ├── add_properties.html
│ ├── add_resources.html
│ ├── any_key.html
│ ├── code.html
│ ├── cue_html.html
│ ├── cue_image.html
│ ├── cue_text.html
│ ├── experiment.html
│ ├── html_button_response.html
│ ├── html_keyboard_response.html
│ ├── html_slider_response.html
│ ├── image_button_response.html
│ ├── image_keyboard_response.html
│ ├── image_slider_response.html
│ ├── index.html
│ ├── js_array.html
│ ├── js_code.html
│ ├── js_logical.html
│ ├── js_numeric.html
│ ├── js_string.html
│ ├── js_struct.html
│ ├── jshelpers.html
│ ├── jspsych_add.html
│ ├── jspsych_create.html
│ ├── jspsych_init.html
│ ├── jspsych_write.html
│ ├── keys.html
│ ├── make_experiment.html
│ ├── no_key.html
│ ├── question.html
│ ├── question_likert.html
│ ├── question_multi.html
│ ├── question_multi_choice.html
│ ├── question_text.html
│ ├── reexports.html
│ ├── resource.html
│ ├── respond_button.html
│ ├── respond_key.html
│ ├── respond_slider.html
│ ├── response_button.html
│ ├── response_buttons.html
│ ├── response_freetext.html
│ ├── response_key.html
│ ├── response_keys.html
│ ├── response_likert.html
│ ├── response_pickone.html
│ ├── response_picksome.html
│ ├── response_slider.html
│ ├── run_locally.html
│ ├── set_resource.html
│ ├── stimulus_html.html
│ ├── stimulus_image.html
│ ├── string.html
│ ├── survey_likert.html
│ ├── survey_multi_choice.html
│ ├── survey_questions.html
│ ├── timeline.html
│ ├── trial.html
│ ├── trial_html_button.html
│ ├── trial_html_key.html
│ ├── trial_html_slider.html
│ ├── trial_image_button.html
│ ├── trial_image_key.html
│ ├── trial_image_slider.html
│ ├── trial_simple.html
│ ├── trial_stimulus_response.html
│ ├── trial_survey.html
│ ├── trial_survey_likert.html
│ ├── trial_survey_multi_choice.html
│ ├── trial_survey_multi_select.html
│ ├── trial_survey_text.html
│ ├── unquote.html
│ ├── use_variable.html
│ ├── variable.html
│ ├── with_parameters.html
│ └── with_variables.html
├── inst
└── extdata
│ ├── img
│ ├── bisexual.png
│ ├── bisexual.svg
│ ├── lesbian.svg
│ ├── rainbow.svg
│ └── transgender.svg
│ ├── jsPsych-6.1.0
│ ├── jspsych-animation.js
│ ├── jspsych-audio-button-response.js
│ ├── jspsych-audio-keyboard-response.js
│ ├── jspsych-audio-slider-response.js
│ ├── jspsych-call-function.js
│ ├── jspsych-categorize-animation.js
│ ├── jspsych-categorize-html.js
│ ├── jspsych-categorize-image.js
│ ├── jspsych-cloze.js
│ ├── jspsych-external-html.js
│ ├── jspsych-free-sort.js
│ ├── jspsych-fullscreen.js
│ ├── jspsych-html-button-response.js
│ ├── jspsych-html-keyboard-response.js
│ ├── jspsych-html-slider-response.js
│ ├── jspsych-iat-html.js
│ ├── jspsych-iat-image.js
│ ├── jspsych-image-button-response.js
│ ├── jspsych-image-keyboard-response.js
│ ├── jspsych-image-slider-response.js
│ ├── jspsych-instructions.js
│ ├── jspsych-rdk.js
│ ├── jspsych-reconstruction.js
│ ├── jspsych-resize.js
│ ├── jspsych-same-different-html.js
│ ├── jspsych-same-different-image.js
│ ├── jspsych-serial-reaction-time-mouse.js
│ ├── jspsych-serial-reaction-time.js
│ ├── jspsych-survey-html-form.js
│ ├── jspsych-survey-likert.js
│ ├── jspsych-survey-multi-choice.js
│ ├── jspsych-survey-multi-select.js
│ ├── jspsych-survey-text.js
│ ├── jspsych-video-button-response.js
│ ├── jspsych-video-keyboard-response.js
│ ├── jspsych-video-slider-response.js
│ ├── jspsych-visual-search-circle.js
│ ├── jspsych-vsl-animate-occlusion.js
│ ├── jspsych-vsl-grid-scene.js
│ ├── jspsych.css
│ ├── jspsych.js
│ └── license.txt
│ └── xprmntr.js
├── man
├── add_properties.Rd
├── add_resources.Rd
├── cue_html.Rd
├── cue_image.Rd
├── cue_text.Rd
├── experiment.Rd
├── jshelpers.Rd
├── question.Rd
├── reexports.Rd
├── resource.Rd
├── response_button.Rd
├── response_freetext.Rd
├── response_key.Rd
├── response_likert.Rd
├── response_pickone.Rd
├── response_picksome.Rd
├── response_slider.Rd
├── run_locally.Rd
├── timeline.Rd
├── trial.Rd
├── trial_simple.Rd
├── trial_survey.Rd
├── variable.Rd
├── with_parameters.Rd
└── with_variables.Rd
├── misc
├── demo1.R
├── demo1b.R
├── jspsych-6.0.5
│ ├── css
│ │ └── jspsych.css
│ ├── examples
│ │ ├── add-to-end-of-timeline.html
│ │ ├── conditional-and-loop-functions.html
│ │ ├── css
│ │ │ └── jquery-ui.css
│ │ ├── data-add-properties.html
│ │ ├── data-as-function.html
│ │ ├── data-from-timeline.html
│ │ ├── data-from-url.html
│ │ ├── demo-flanker.html
│ │ ├── demo-simple-rt-task.html
│ │ ├── demos
│ │ │ ├── demo_1.html
│ │ │ ├── demo_2.html
│ │ │ └── demo_3.html
│ │ ├── display-element-to-embed-experiment.html
│ │ ├── end-active-node.html
│ │ ├── end-experiment.html
│ │ ├── exclusions.html
│ │ ├── external_html
│ │ │ └── simple_consent.html
│ │ ├── img
│ │ │ ├── 1.gif
│ │ │ ├── 10.gif
│ │ │ ├── 11.gif
│ │ │ ├── 12.gif
│ │ │ ├── 2.gif
│ │ │ ├── 3.gif
│ │ │ ├── 4.gif
│ │ │ ├── 5.gif
│ │ │ ├── 6.gif
│ │ │ ├── 7.gif
│ │ │ ├── 8.gif
│ │ │ ├── 9.gif
│ │ │ ├── age
│ │ │ │ ├── of1.jpg
│ │ │ │ ├── of2.jpg
│ │ │ │ ├── of3.jpg
│ │ │ │ ├── om1.jpg
│ │ │ │ ├── om2.jpg
│ │ │ │ ├── om3.jpg
│ │ │ │ ├── yf1.jpg
│ │ │ │ ├── yf4.jpg
│ │ │ │ ├── yf5.jpg
│ │ │ │ ├── ym2.jpg
│ │ │ │ ├── ym3.jpg
│ │ │ │ └── ym5.jpg
│ │ │ ├── backwardN.gif
│ │ │ ├── blue.png
│ │ │ ├── con1.png
│ │ │ ├── con2.png
│ │ │ ├── fixation.gif
│ │ │ ├── happy_face_1.jpg
│ │ │ ├── happy_face_2.jpg
│ │ │ ├── happy_face_3.jpg
│ │ │ ├── happy_face_4.jpg
│ │ │ ├── inc1.png
│ │ │ ├── inc2.png
│ │ │ ├── normalN.gif
│ │ │ ├── orange.png
│ │ │ ├── redX.png
│ │ │ ├── ribbon.jpg
│ │ │ ├── sad_face_1.jpg
│ │ │ ├── sad_face_2.jpg
│ │ │ ├── sad_face_3.jpg
│ │ │ └── sad_face_4.jpg
│ │ ├── js
│ │ │ └── snap.svg-min.js
│ │ ├── jspsych-RDK.html
│ │ ├── jspsych-animation.html
│ │ ├── jspsych-audio-button-response.html
│ │ ├── jspsych-audio-keyboard-response.html
│ │ ├── jspsych-audio-slider-response.html
│ │ ├── jspsych-call-function.html
│ │ ├── jspsych-categorize-animation.html
│ │ ├── jspsych-categorize-html.html
│ │ ├── jspsych-categorize-image.html
│ │ ├── jspsych-form.html
│ │ ├── jspsych-free-sort.html
│ │ ├── jspsych-fullscreen.html
│ │ ├── jspsych-html-button-response.html
│ │ ├── jspsych-html-keyboard-response.html
│ │ ├── jspsych-html-slider-response.html
│ │ ├── jspsych-iat.html
│ │ ├── jspsych-image-button-response.html
│ │ ├── jspsych-image-keyboard-response.html
│ │ ├── jspsych-image-slider-response.html
│ │ ├── jspsych-instructions.html
│ │ ├── jspsych-reconstruction.html
│ │ ├── jspsych-resize.html
│ │ ├── jspsych-same-different-html.html
│ │ ├── jspsych-same-different-image.html
│ │ ├── jspsych-serial-reaction-time-mouse.html
│ │ ├── jspsych-serial-reaction-time.html
│ │ ├── jspsych-survey-likert.html
│ │ ├── jspsych-survey-multi-choice.html
│ │ ├── jspsych-survey-multi-select.html
│ │ ├── jspsych-survey-text.html
│ │ ├── jspsych-video.html
│ │ ├── jspsych-visual-search-circle.html
│ │ ├── jspsych-vsl-animate-occlusion.html
│ │ ├── jspsych-vsl-grid-scene.html
│ │ ├── lexical-decision.html
│ │ ├── pause-unpause.html
│ │ ├── progress-bar.html
│ │ ├── sound
│ │ │ ├── hammer.mp3
│ │ │ ├── sound.mp3
│ │ │ ├── speech_blue.mp3
│ │ │ ├── speech_green.mp3
│ │ │ ├── speech_joke.mp3
│ │ │ ├── speech_red.mp3
│ │ │ └── tone.mp3
│ │ ├── timeline-variables-sampling.html
│ │ ├── timeline-variables.html
│ │ └── video
│ │ │ └── sample_video.mp4
│ ├── jspsych.js
│ ├── license.txt
│ └── plugins
│ │ ├── jspsych-RDK.js
│ │ ├── jspsych-animation.js
│ │ ├── jspsych-audio-button-response.js
│ │ ├── jspsych-audio-keyboard-response.js
│ │ ├── jspsych-audio-slider-response.js
│ │ ├── jspsych-call-function.js
│ │ ├── jspsych-categorize-animation.js
│ │ ├── jspsych-categorize-html.js
│ │ ├── jspsych-categorize-image.js
│ │ ├── jspsych-external-html.js
│ │ ├── jspsych-free-sort.js
│ │ ├── jspsych-fullscreen.js
│ │ ├── jspsych-html-button-response.js
│ │ ├── jspsych-html-keyboard-response.js
│ │ ├── jspsych-html-slider-response.js
│ │ ├── jspsych-iat-html.js
│ │ ├── jspsych-iat-image.js
│ │ ├── jspsych-image-button-response.js
│ │ ├── jspsych-image-keyboard-response.js
│ │ ├── jspsych-image-slider-response.js
│ │ ├── jspsych-instructions.js
│ │ ├── jspsych-reconstruction.js
│ │ ├── jspsych-resize.js
│ │ ├── jspsych-same-different-html.js
│ │ ├── jspsych-same-different-image.js
│ │ ├── jspsych-serial-reaction-time-mouse.js
│ │ ├── jspsych-serial-reaction-time.js
│ │ ├── jspsych-survey-likert.js
│ │ ├── jspsych-survey-multi-choice.js
│ │ ├── jspsych-survey-multi-select.js
│ │ ├── jspsych-survey-text.js
│ │ ├── jspsych-video.js
│ │ ├── jspsych-visual-search-circle.js
│ │ ├── jspsych-vsl-animate-occlusion.js
│ │ ├── jspsych-vsl-grid-scene.js
│ │ └── template
│ │ └── jspsych-plugin-template.js
├── old_trial_html.R
├── old_trial_image.R
├── old_trial_survey.R
└── plumber.R
└── xprmntr.Rproj
/.Rbuildignore:
--------------------------------------------------------------------------------
1 | ^xprmntr\.Rproj$
2 | ^\.Rproj\.user$
3 | ^LICENSE\.md$
4 | ^README\.Rmd$
5 | ^misc$
6 | ^_pkgdown\.yml$
7 | ^docs$
8 | ^pkgdown$
9 | ^\.workbch$
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # History files
2 | .Rhistory
3 | .Rapp.history
4 |
5 | # Session Data files
6 | .RData
7 |
8 | # Example code in package build process
9 | *-Ex.R
10 |
11 | # Output files from R CMD build
12 | /*.tar.gz
13 |
14 | # Output files from R CMD check
15 | /*.Rcheck/
16 |
17 | # RStudio files
18 | .Rproj.user/
19 |
20 | # produced vignettes
21 | vignettes/*.html
22 | vignettes/*.pdf
23 |
24 | # OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3
25 | .httr-oauth
26 |
27 | # knitr and R markdown default cache directories
28 | /*_cache/
29 | /cache/
30 |
31 | # Temporary files created by R markdown
32 | *.utf8.md
33 | *.knit.md
34 |
35 | # Shiny token, see https://shiny.rstudio.com/articles/shinyapps.html
36 | rsconnect/
37 | .Rproj.user
38 |
--------------------------------------------------------------------------------
/.workbch:
--------------------------------------------------------------------------------
1 | xprmntr
2 | QdFIpyWKCi
3 |
--------------------------------------------------------------------------------
/DESCRIPTION:
--------------------------------------------------------------------------------
1 | Package: xprmntr
2 | Title: Behavioral Experiments in the Browser
3 | Version: 0.0.0.9000
4 | Authors@R:
5 | person(given = "Danielle",
6 | family = "Navarro",
7 | role = c("aut", "cre"),
8 | email = "d.navarro@unsw.edu.au",
9 | comment = c(ORCID = "0000-0001-7648-6578"))
10 | Description: What the package does (one paragraph).
11 | License: MIT + file LICENSE
12 | Encoding: UTF-8
13 | LazyData: true
14 | URL: https://github.com/djnavarro/xprmntr
15 | BugReports: https://github.com/djnavarro/xprmntr/issues
16 | RoxygenNote: 6.1.1
17 | Imports:
18 | jsonlite,
19 | plumber,
20 | readr,
21 | purrr,
22 | magrittr,
23 | methods,
24 | utils,
25 | tibble,
26 | rlang,
27 | dplyr
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | YEAR: 2019
2 | COPYRIGHT HOLDER: Danielle Navarro
3 |
--------------------------------------------------------------------------------
/NAMESPACE:
--------------------------------------------------------------------------------
1 | # Generated by roxygen2: do not edit by hand
2 |
3 | export("%>%")
4 | export(add_properties)
5 | export(add_resources)
6 | export(cue_html)
7 | export(cue_image)
8 | export(cue_text)
9 | export(experiment)
10 | export(js_array)
11 | export(js_code)
12 | export(js_logical)
13 | export(js_numeric)
14 | export(js_string)
15 | export(js_struct)
16 | export(question)
17 | export(resource)
18 | export(response_button)
19 | export(response_freetext)
20 | export(response_key)
21 | export(response_likert)
22 | export(response_pickone)
23 | export(response_picksome)
24 | export(response_slider)
25 | export(run_locally)
26 | export(timeline)
27 | export(trial)
28 | export(trial_simple)
29 | export(trial_survey)
30 | export(variable)
31 | export(with_parameters)
32 | export(with_variables)
33 | importFrom(magrittr,"%>%")
34 | importFrom(rlang,"%||%")
35 |
--------------------------------------------------------------------------------
/R/build_api.R:
--------------------------------------------------------------------------------
1 | # file: api_build.R
2 | # author: Danielle Navarro
3 |
4 | #' Run a jspsych experiment
5 | #'
6 | #' @param path the experiment directory
7 | #' @param port port to use
8 | #' @export
9 | run_locally <- function(path = ".", port = 8000) {
10 |
11 | pr <- plumber::plumber$new()
12 |
13 | static_site <- file.path(path, "experiment")
14 | data_folder <- file.path(path, "data")
15 | static_router <- plumber::PlumberStatic$new(static_site)
16 |
17 | pr$mount("/", static_router)
18 | pr$handle("POST", "/submit", function(req, res){
19 |
20 | dat <- jsonlite::fromJSON(req$postBody)
21 | dat <- readr::read_csv(dat$filedata)
22 |
23 | tsp <- get_timestamp()
24 | file_id <- paste(
25 | "data", get_timestamp(), get_alphanumeric(10), sep = "_"
26 | )
27 | dat$file_id <- file_id
28 | dat <- dat[, c(ncol(dat), 1:ncol(dat)-1), drop = FALSE]
29 | readr::write_csv(dat, file.path(data_folder, paste0(file_id, ".csv")))
30 | })
31 |
32 | pr$registerHook("exit", function(){
33 | print("Done!")
34 | })
35 |
36 | url <- paste0("http://localhost:", port)
37 | utils::browseURL(url)
38 | pr$run(swagger = FALSE, port = port)
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/R/build_timeline.R:
--------------------------------------------------------------------------------
1 | # file: timeline_build.R
2 | # author: Danielle Navarro
3 |
4 | #' Initialise a timeline
5 | #'
6 | #' @param ... trial objects to add to this timeline
7 | #' @export
8 | timeline <- function(...){
9 | tl <- list(timeline = list(...))
10 | class(tl) <- c("timeline", "list")
11 | tl
12 | }
13 |
14 | #' Adds an arbitrary trial to the timeline
15 | #'
16 | #' @param type the type of trial
17 | #' @param ... arguments passed to the trial plugin
18 | #' @export
19 | trial <- function(type, ...) {
20 | return(list(type = type, ...))
21 | }
22 |
23 | # lifted version
24 | trial_l <- purrr::lift_dl(trial)
25 |
26 | #' Use a timeline variable
27 | #'
28 | #' @param name name of the variable to insert
29 | #'
30 | #' @export
31 | #'
32 | variable <- function(name) {
33 | str <- paste0("jsPsych.timelineVariable('",name, "')")
34 | return(js_code(str))
35 | }
36 |
37 | #' Attach a timeline variable to timeline object
38 | #'
39 | #' @param timeline the timeline object
40 | #' @param ... name value pairs
41 | #'
42 | #' @export
43 | with_variables <- function(timeline, ...) {
44 | vars <- list(...)
45 | vars <- purrr::transpose(vars)
46 | timeline[["timeline_variables"]] <- vars
47 | return(timeline)
48 | }
49 |
50 | #' Attach a timeline variable to timeline object
51 | #'
52 | #' @param timeline the timeline object
53 | #' @param ... name value pairs
54 | #'
55 | #' @export
56 | with_parameters <- function(timeline, ...) {
57 | timeline <- c(timeline, ...)
58 | return(timeline)
59 | }
60 |
61 |
62 |
--------------------------------------------------------------------------------
/R/helpers_js.R:
--------------------------------------------------------------------------------
1 |
2 |
3 | #' Manually specify the JavaScript object type
4 | #'
5 | #' @param x an object to be coerced
6 | #' @param ... objects to be concatenated and coerced
7 | #' @name jshelpers
8 | NULL
9 |
10 | #' @export
11 | #' @rdname jshelpers
12 | js_code <- function(x) {
13 | class(x) <- "json"
14 | x
15 | }
16 |
17 | #' @export
18 | #' @rdname jshelpers
19 | js_logical <- function(x) {
20 | as.logical(x)
21 | }
22 |
23 | #' @export
24 | #' @rdname jshelpers
25 | js_numeric <- function(x) {
26 | as.numeric(x)
27 | }
28 |
29 |
30 | # the ... here are individual strings
31 |
32 | #' @export
33 | #' @rdname jshelpers
34 | js_string <- function(...) {
35 | s <- list(...)
36 | string_quote <- function(c) {
37 | if(methods::is(c,"json")) { return(c) }
38 | return(paste0('"',c,'"'))
39 | }
40 | s <- paste(lapply(s, string_quote), collapse = " + ")
41 | js_code(s)
42 | }
43 |
44 | # the ... here are list of name/value pairs
45 |
46 | #' @export
47 | #' @rdname jshelpers
48 | js_struct <- function(...) {
49 | list(...)
50 | }
51 |
52 |
53 | # the ... here are list of name/value pairs
54 |
55 | #' @export
56 | #' @rdname jshelpers
57 | js_array <- function(...) {
58 | classes <- purrr::map_chr(list(...), ~ class(.x)[1])
59 | if(any(classes == "list")) {
60 | return(list(...))
61 | }
62 | return(c(...))
63 | }
64 |
65 | list_to_jsarray <- purrr::lift_dl(js_array)
66 |
67 |
68 |
--------------------------------------------------------------------------------
/R/helpers_misc.R:
--------------------------------------------------------------------------------
1 | # file: helpers.R
2 | # author: Danielle Navarro
3 |
4 | any_key <- function() {
5 | js_code("jsPsych.ANY_KEY")
6 | }
7 |
8 | no_key <- function() {
9 | js_code("jsPsych.NO_KEY")
10 | }
11 |
12 |
13 | #' Refers to a resource file
14 | #'
15 | #' @param file path
16 | #' @export
17 | resource <- function(file) {
18 |
19 | # THIS IS A HACK -- FIX THIS
20 | audio <- c(".mp3", ".wav", ".aif", ".mid")
21 | video <- c(".mp4", ".mpg", ".mov", ".wmv")
22 | image <- c(".jpg", ".png", ".bmp", ".svg", ".tiff")
23 | script <- c(".js")
24 | style <- c(".css")
25 |
26 | # assign types based on file extensions
27 | fileext <- tolower(gsub("^.*(\\.[^\\.]*)$", "\\1", file))
28 | type <- rep("other", length(fileext))
29 | type[fileext %in% audio] <- "audio"
30 | type[fileext %in% video] <- "video"
31 | type[fileext %in% image] <- "image"
32 | type[fileext %in% script] <- "script"
33 | type[fileext %in% style] <- "style"
34 |
35 | file.path("resource", type, file)
36 | }
37 |
38 | drop_nulls <- function(x) {
39 | x[purrr::map_lgl(x, ~!is.null(.x))]
40 | }
41 |
42 | # returns a list of expressions
43 | capture_dots <- function(...) {
44 | as.list(substitute(list(...)))[-1L]
45 | }
46 |
47 | #' @importFrom magrittr %>%
48 | #' @export
49 | magrittr::`%>%`
50 |
51 | #' @importFrom rlang %||%
52 | NULL
53 |
54 | get_timestamp <- function() {
55 | tsp <- as.character(Sys.time())
56 | tsp <- gsub("[ :]", "-", tsp)
57 | return(tsp)
58 | }
59 |
60 | get_alphanumeric <- function(n = 5) {
61 | x <- c("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r",
62 | "s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9")
63 | r <- sample(x, size = n, replace = TRUE)
64 | r <- paste(r, collapse = "")
65 | return(r)
66 | }
67 |
--------------------------------------------------------------------------------
/R/trial_categorise.R:
--------------------------------------------------------------------------------
1 |
2 | #' Create a categorization trial
3 | #'
4 | #' @param cue the cue type for the trial
5 | #' @param response the response type for the question
6 | #' @param prompt prompt to be displayed with the stimulus (can include HTML markup)
7 | #' @param stimulus_duration how long to display stimulus in milliseconds? (default is to remain until response)
8 | #' @param trial_duration how long to wait for response in milliseconds? (default is to wait indefinitely)
9 | #' @param response_ends_trial does the trial end with response (default = TRUE) or continue until trial duration reached?
10 | #' @param ... arguments to be passed to trial()
11 | #'
12 | #' @return A trial object
13 | #' @export
14 | trial_categorize <- function(
15 | cue, # cue_image(), cue_html(), cue_animation(),
16 | response, # response_key()
17 | prompt = NULL, # not intended to be part of the "stimulus"
18 | stimulus_duration = NULL,
19 | trial_duration = NULL,
20 | response_ends_trial = TRUE,
21 | ...
22 | ) {
23 |
24 |
25 | # feedback defined by
26 | key_answer # anim + html + image
27 | text_answer
28 | correct_text
29 | incorrect_text
30 | feedback_duration
31 |
32 | force_correct_button_press # html + image
33 | show_stim_with_feedback # html
34 | show_feedback_on_timeout
35 |
36 |
37 | # animation cue parameters
38 | frame_time
39 | sequence_reps
40 | allow_responses_before_complete
41 |
42 |
43 |
44 | # validate the cue and response classes
45 | require_cue(cue, c("image", "html", "animation"))
46 | require_response(response, c("key"))
47 |
48 | # read off the types
49 | cue_type <- cue$cue_type
50 | response_type <- response$response_type
51 | if(response_type == "key") response_type <- "keyboard"
52 |
53 | # construct the plugin type
54 | plugin_type <- paste("categorize", cue_type, sep = "-")
55 |
56 | # strip the unnecessary fields
57 | cue$cue_type <- NULL
58 | response$response_type <- NULL
59 |
60 | # trial level parameters
61 | trial_parameters <- list(
62 | type = plugin_type,
63 | prompt = prompt,
64 | stimulus_duration = stimulus_duration,
65 | trial_duration = trial_duration,
66 | response_ends_trial = response_ends_trial,
67 | ...
68 | )
69 |
70 | # return the trial object
71 | trial_data <- c(cue, response, trial_parameters)
72 | return(drop_nulls(trial_l(trial_data)))
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/R/validators.R:
--------------------------------------------------------------------------------
1 |
2 | require_cue <- function(cue, type = NULL) {
3 | if(class(cue)[1] != "xpt_cue") {
4 | stop("object of type 'xpt_cue' is required", call. = FALSE)
5 | }
6 | if(!is.null(type)) {
7 | if(!(cue$cue_type %in% type)) {
8 | stop("invalid cue for this trial type", call. = FALSE)
9 | }
10 | }
11 | }
12 |
13 | require_response <- function(response, type = NULL) {
14 | if(class(response)[1] != "xpt_response") {
15 | stop("object of type 'xpt_response' is required", call. = FALSE)
16 | }
17 | if(!is.null(type)) {
18 | if(!(response$response_type %in% type)) {
19 | stop("invalid response for this trial type", call. = FALSE)
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/README.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | output: github_document
3 | ---
4 |
5 |
6 |
7 | ```{r, include = FALSE}
8 | knitr::opts_chunk$set(
9 | collapse = TRUE,
10 | comment = "#>",
11 | fig.path = "man/figures/README-",
12 | out.width = "100%"
13 | )
14 | ```
15 | # xprmntr
16 |
17 |
18 | [](https://www.tidyverse.org/lifecycle/#experimental)
19 | [](https://cran.r-project.org/package=xprmntr)
20 |
21 |
22 | The goal of `xprmntr` (pronounced: "experimenter") is to let users build behavioural experiments in R run through the browser, by providing wrappers to the [jspsych](https://www.jspsych.org/) javascript library.
23 |
24 | ## Installation
25 |
26 | The development version can be installed from [GitHub](https://github.com/) with:
27 |
28 | ```
29 | # install.packages("devtools")
30 | devtools::install_github("djnavarro/xprmntr")
31 | ```
32 |
33 | ## Goals
34 |
35 | The jsPsych library is organised around a system of *plugins* that generate specific trial types that can be used in a behavioural experiment. The initial goals in xprmtnr is:
36 |
37 | - To provide "general purpose" wrappers that can be used to insert *any* jsPsych plugin (including any novel plugin)
38 | - To provide a convenient API that wraps around the "standard" plugins that come bundled with jsPsych, and provides some structure for the user
39 | - To allow the client side experiment (jsPsych) to communicate with an R server using the plumber package so the experiment can call server-side R functions
40 | - To allow experiments to deploy locally, or github pages, etc.
41 | - To provide mechanisms to save locally, or to dropbox or similar cloud storage
42 |
43 |
44 | ## Notes
45 |
46 | - The "survey" family:
47 | - jspsych-survey-html-form
48 | - jspsych-survey-likert
49 | - jspsych-survey-multi-choice
50 | - jspsych-survey-multi-select
51 | - jspsych-survey-text
52 | - The "sr" family (stimulus-response):
53 | - jspsych-audio-button-response
54 | - jspsych-audio-keyboard-response
55 | - jspsych-audio-slider-response
56 | - jspsych-html-button-response
57 | - jspsych-html-keyboard-response
58 | - jspsych-html-slider-response
59 | - jspsych-image-button-response
60 | - jspsych-image-keyboard-response
61 | - jspsych-image-slider-response
62 | - jspsych-video-button-response
63 | - jspsych-video-keyboard-response
64 | - jspsych-video-slider-response
65 | - The "categorise" family:
66 | - jspsych-categorize-animation
67 | - jspsych-categorize-html
68 | - jspsych-categorize-image
69 | - Other... not sure yet
70 | - jspsych-animation
71 | - jspsych-cloze
72 | - jspsych-free-sort
73 | - jspsych-iat-html
74 | - jspsych-iat-image
75 | - jspsych-rdk
76 | - jspsych-reconstruction
77 | - jspsych-resize
78 | - jspsych-same-different-html
79 | - jspsych-same-different-image
80 | - jspsych-serial-reaction-time
81 | - jspsych-serial-reaction-time-mouse
82 | - jspsych-visual-search-circle
83 | - jspsych-vsl-animate-occlusion
84 | - jspsych-vsl-grid-scene
85 | - "Meta???" family (not strictly "trials")
86 | - jspsych-external-html
87 | - jspsych-call-function
88 | - jspsych-fullscreen
89 | - jspsych-instructions
90 | - possibly have wrappers for loop nodes & conditional nodes here??
91 |
92 |
93 | ## Possible design:
94 |
95 |
96 | - the "cue" family is used to specify the stimulus (broadly construed)
97 | - cue_html
98 | - cue_text
99 | - cue_image
100 | - cue_audio
101 | - cue_video
102 | - cue_animation
103 |
104 | - the "response" family is used to specify a response mechanism
105 | - response_button
106 | - response_key
107 | - response_slider (continuous)
108 | - response_likert (ordinal)
109 | - response_select (radio or checkbox)
110 | - response_mouse (???)
111 | - response_text (free text??)p
112 |
113 | - the "simple" family is a simple construction
114 | - the "survey" family: the trial is built from multiple questions; a question is a combination of a display_text + response_likert + response_select ...
115 | - the "iat", "same-diff", "categorise" seem like they could be made to fit this framework easily
116 |
117 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # xprmntr
5 |
6 |
7 |
8 | [](https://www.tidyverse.org/lifecycle/#experimental)
10 | [](https://cran.r-project.org/package=xprmntr)
12 |
13 |
14 | The goal of `xprmntr` (pronounced: “experimenter”) is to let users build
15 | behavioural experiments in R run through the browser, by providing
16 | wrappers to the [jspsych](https://www.jspsych.org/) javascript library.
17 |
18 | ## Installation
19 |
20 | The development version can be installed from
21 | [GitHub](https://github.com/) with:
22 |
23 | # install.packages("devtools")
24 | devtools::install_github("djnavarro/xprmntr")
25 |
26 | ## Goals
27 |
28 | The jsPsych library is organised around a system of *plugins* that
29 | generate specific trial types that can be used in a behavioural
30 | experiment. The initial goals in xprmtnr is:
31 |
32 | - To provide “general purpose” wrappers that can be used to insert
33 | *any* jsPsych plugin (including any novel plugin)
34 | - To provide a convenient API that wraps around the “standard” plugins
35 | that come bundled with jsPsych, and provides some structure for the
36 | user
37 | - To allow the client side experiment (jsPsych) to communicate with an
38 | R server using the plumber package so the experiment can call
39 | server-side R functions
40 | - To allow experiments to deploy locally, or github pages, etc.
41 | - To provide mechanisms to save locally, or to dropbox or similar
42 | cloud storage
43 |
44 | ## Notes
45 |
46 | - The “survey” family:
47 | - jspsych-survey-html-form
48 | - jspsych-survey-likert
49 | - jspsych-survey-multi-choice
50 | - jspsych-survey-multi-select
51 | - jspsych-survey-text
52 | - The “sr” family (stimulus-response):
53 | - jspsych-audio-button-response
54 | - jspsych-audio-keyboard-response
55 | - jspsych-audio-slider-response
56 | - jspsych-html-button-response
57 | - jspsych-html-keyboard-response
58 | - jspsych-html-slider-response
59 | - jspsych-image-button-response
60 | - jspsych-image-keyboard-response
61 | - jspsych-image-slider-response
62 | - jspsych-video-button-response
63 | - jspsych-video-keyboard-response
64 | - jspsych-video-slider-response
65 | - The “categorise” family:
66 | - jspsych-categorize-animation
67 | - jspsych-categorize-html
68 | - jspsych-categorize-image
69 | - Other… not sure yet
70 | - jspsych-animation
71 | - jspsych-cloze
72 | - jspsych-free-sort
73 | - jspsych-iat-html
74 | - jspsych-iat-image
75 | - jspsych-rdk
76 | - jspsych-reconstruction
77 | - jspsych-resize
78 | - jspsych-same-different-html
79 | - jspsych-same-different-image
80 | - jspsych-serial-reaction-time
81 | - jspsych-serial-reaction-time-mouse
82 | - jspsych-visual-search-circle
83 | - jspsych-vsl-animate-occlusion
84 | - jspsych-vsl-grid-scene
85 | - “Meta???” family (not strictly “trials”)
86 | - jspsych-external-html
87 | - jspsych-call-function
88 | - jspsych-fullscreen
89 | - jspsych-instructions
90 | - possibly have wrappers for loop nodes & conditional nodes here??
91 |
92 | ## Possible design:
93 |
94 | - the “cue” family is used to specify the stimulus (broadly construed)
95 | - cue\_html
96 | - cue\_text
97 | - cue\_image
98 | - cue\_audio
99 | - cue\_video
100 | - cue\_animation
101 | - the “response” family is used to specify a response mechanism
102 | - response\_button
103 | - response\_key
104 | - response\_slider (continuous)
105 | - response\_likert (ordinal)
106 | - response\_select (radio or checkbox)
107 | - response\_mouse (???)
108 | - response\_text (free text??)p
109 | - the “simple” family is a simple construction
110 | - the “survey” family: the trial is built from multiple questions; a
111 | question is a combination of a display\_text + response\_likert +
112 | response\_select …
113 | - the “iat”, “same-diff”, “categorise” seem like they could be made to
114 | fit this framework easily
115 |
--------------------------------------------------------------------------------
/_pkgdown.yml:
--------------------------------------------------------------------------------
1 | destination: docs
2 |
--------------------------------------------------------------------------------
/docs/docsearch.js:
--------------------------------------------------------------------------------
1 | $(function() {
2 |
3 | // register a handler to move the focus to the search bar
4 | // upon pressing shift + "/" (i.e. "?")
5 | $(document).on('keydown', function(e) {
6 | if (e.shiftKey && e.keyCode == 191) {
7 | e.preventDefault();
8 | $("#search-input").focus();
9 | }
10 | });
11 |
12 | $(document).ready(function() {
13 | // do keyword highlighting
14 | /* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */
15 | var mark = function() {
16 |
17 | var referrer = document.URL ;
18 | var paramKey = "q" ;
19 |
20 | if (referrer.indexOf("?") !== -1) {
21 | var qs = referrer.substr(referrer.indexOf('?') + 1);
22 | var qs_noanchor = qs.split('#')[0];
23 | var qsa = qs_noanchor.split('&');
24 | var keyword = "";
25 |
26 | for (var i = 0; i < qsa.length; i++) {
27 | var currentParam = qsa[i].split('=');
28 |
29 | if (currentParam.length !== 2) {
30 | continue;
31 | }
32 |
33 | if (currentParam[0] == paramKey) {
34 | keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20"));
35 | }
36 | }
37 |
38 | if (keyword !== "") {
39 | $(".contents").unmark({
40 | done: function() {
41 | $(".contents").mark(keyword);
42 | }
43 | });
44 | }
45 | }
46 | };
47 |
48 | mark();
49 | });
50 | });
51 |
52 | /* Search term highlighting ------------------------------*/
53 |
54 | function matchedWords(hit) {
55 | var words = [];
56 |
57 | var hierarchy = hit._highlightResult.hierarchy;
58 | // loop to fetch from lvl0, lvl1, etc.
59 | for (var idx in hierarchy) {
60 | words = words.concat(hierarchy[idx].matchedWords);
61 | }
62 |
63 | var content = hit._highlightResult.content;
64 | if (content) {
65 | words = words.concat(content.matchedWords);
66 | }
67 |
68 | // return unique words
69 | var words_uniq = [...new Set(words)];
70 | return words_uniq;
71 | }
72 |
73 | function updateHitURL(hit) {
74 |
75 | var words = matchedWords(hit);
76 | var url = "";
77 |
78 | if (hit.anchor) {
79 | url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor;
80 | } else {
81 | url = hit.url + '?q=' + escape(words.join(" "));
82 | }
83 |
84 | return url;
85 | }
86 |
--------------------------------------------------------------------------------
/docs/link.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/pkgdown.js:
--------------------------------------------------------------------------------
1 | /* http://gregfranko.com/blog/jquery-best-practices/ */
2 | (function($) {
3 | $(function() {
4 |
5 | $('.navbar-fixed-top').headroom();
6 |
7 | $('body').scrollspy({
8 | target: '#sidebar',
9 | offset: 60
10 | });
11 |
12 | $('[data-toggle="tooltip"]').tooltip();
13 |
14 | var cur_path = paths(location.pathname);
15 | var links = $("#navbar ul li a");
16 | var max_length = -1;
17 | var pos = -1;
18 | for (var i = 0; i < links.length; i++) {
19 | if (links[i].getAttribute("href") === "#")
20 | continue;
21 | // Ignore external links
22 | if (links[i].host !== location.host)
23 | continue;
24 |
25 | var nav_path = paths(links[i].pathname);
26 |
27 | var length = prefix_length(nav_path, cur_path);
28 | if (length > max_length) {
29 | max_length = length;
30 | pos = i;
31 | }
32 | }
33 |
34 | // Add class to parent
, and enclosing if in dropdown
35 | if (pos >= 0) {
36 | var menu_anchor = $(links[pos]);
37 | menu_anchor.parent().addClass("active");
38 | menu_anchor.closest("li.dropdown").addClass("active");
39 | }
40 | });
41 |
42 | function paths(pathname) {
43 | var pieces = pathname.split("/");
44 | pieces.shift(); // always starts with /
45 |
46 | var end = pieces[pieces.length - 1];
47 | if (end === "index.html" || end === "")
48 | pieces.pop();
49 | return(pieces);
50 | }
51 |
52 | // Returns -1 if not found
53 | function prefix_length(needle, haystack) {
54 | if (needle.length > haystack.length)
55 | return(-1);
56 |
57 | // Special case for length-0 haystack, since for loop won't run
58 | if (haystack.length === 0) {
59 | return(needle.length === 0 ? 0 : -1);
60 | }
61 |
62 | for (var i = 0; i < haystack.length; i++) {
63 | if (needle[i] != haystack[i])
64 | return(i);
65 | }
66 |
67 | return(haystack.length);
68 | }
69 |
70 | /* Clipboard --------------------------*/
71 |
72 | function changeTooltipMessage(element, msg) {
73 | var tooltipOriginalTitle=element.getAttribute('data-original-title');
74 | element.setAttribute('data-original-title', msg);
75 | $(element).tooltip('show');
76 | element.setAttribute('data-original-title', tooltipOriginalTitle);
77 | }
78 |
79 | if(ClipboardJS.isSupported()) {
80 | $(document).ready(function() {
81 | var copyButton = " ";
82 |
83 | $(".examples, div.sourceCode").addClass("hasCopyButton");
84 |
85 | // Insert copy buttons:
86 | $(copyButton).prependTo(".hasCopyButton");
87 |
88 | // Initialize tooltips:
89 | $('.btn-copy-ex').tooltip({container: 'body'});
90 |
91 | // Initialize clipboard:
92 | var clipboardBtnCopies = new ClipboardJS('[data-clipboard-copy]', {
93 | text: function(trigger) {
94 | return trigger.parentNode.textContent;
95 | }
96 | });
97 |
98 | clipboardBtnCopies.on('success', function(e) {
99 | changeTooltipMessage(e.trigger, 'Copied!');
100 | e.clearSelection();
101 | });
102 |
103 | clipboardBtnCopies.on('error', function() {
104 | changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy');
105 | });
106 | });
107 | }
108 | })(window.jQuery || window.$)
109 |
--------------------------------------------------------------------------------
/docs/pkgdown.yml:
--------------------------------------------------------------------------------
1 | pandoc: 2.3.1
2 | pkgdown: 1.3.0.9100
3 | pkgdown_sha: 75c3954d45c73f31750ae14fb08502d86adf3e2b
4 | articles: []
5 |
6 |
--------------------------------------------------------------------------------
/inst/extdata/img/bisexual.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/inst/extdata/img/bisexual.png
--------------------------------------------------------------------------------
/inst/extdata/img/bisexual.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/inst/extdata/img/lesbian.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/inst/extdata/img/rainbow.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/inst/extdata/img/transgender.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/inst/extdata/jsPsych-6.1.0/jspsych-call-function.js:
--------------------------------------------------------------------------------
1 | /**
2 | * jspsych-call-function
3 | * plugin for calling an arbitrary function during a jspsych experiment
4 | * Josh de Leeuw
5 | *
6 | * documentation: docs.jspsych.org
7 | *
8 | **/
9 |
10 | jsPsych.plugins['call-function'] = (function() {
11 |
12 | var plugin = {};
13 |
14 | plugin.info = {
15 | name: 'call-function',
16 | description: '',
17 | parameters: {
18 | func: {
19 | type: jsPsych.plugins.parameterType.FUNCTION,
20 | pretty_name: 'Function',
21 | default: undefined,
22 | description: 'Function to call'
23 | },
24 | async: {
25 | type: jsPsych.plugins.parameterType.BOOL,
26 | pretty_name: 'Asynchronous',
27 | default: false,
28 | description: 'Is the function call asynchronous?'
29 | }
30 | }
31 | }
32 |
33 | plugin.trial = function(display_element, trial) {
34 | trial.post_trial_gap = 0;
35 | var return_val;
36 |
37 | if(trial.async){
38 | var done = function(data){
39 | return_val = data;
40 | end_trial();
41 | }
42 | trial.func(done);
43 | } else {
44 | return_val = trial.func();
45 | end_trial();
46 | }
47 |
48 | function end_trial(){
49 | var trial_data = {
50 | value: return_val
51 | };
52 |
53 | jsPsych.finishTrial(trial_data);
54 | }
55 | };
56 |
57 | return plugin;
58 | })();
59 |
--------------------------------------------------------------------------------
/inst/extdata/jsPsych-6.1.0/jspsych-cloze.js:
--------------------------------------------------------------------------------
1 | /**
2 | * jspsych-cloze
3 | * Philipp Sprengholz
4 | *
5 | * Plugin for displaying a cloze test and checking participants answers against a correct solution.
6 | *
7 | * documentation: docs.jspsych.org
8 | **/
9 |
10 | jsPsych.plugins['cloze'] = (function () {
11 |
12 | var plugin = {};
13 |
14 | plugin.info = {
15 | name: 'cloze',
16 | description: '',
17 | parameters: {
18 | text: {
19 | type: jsPsych.plugins.parameterType.STRING,
20 | pretty_name: 'Cloze text',
21 | default: undefined,
22 | description: 'The cloze text to be displayed. Blanks are indicated by %% signs and automatically replaced by input fields. If there is a correct answer you want the system to check against, it must be typed between the two percentage signs (i.e. %solution%).'
23 | },
24 | button_text: {
25 | type: jsPsych.plugins.parameterType.STRING,
26 | pretty_name: 'Button text',
27 | default: 'OK',
28 | description: 'Text of the button participants have to press for finishing the cloze test.'
29 | },
30 | check_answers: {
31 | type: jsPsych.plugins.parameterType.BOOL,
32 | pretty_name: 'Check answers',
33 | default: false,
34 | description: 'Boolean value indicating if the answers given by participants should be compared against a correct solution given in the text (between % signs) after the button was clicked.'
35 | },
36 | mistake_fn: {
37 | type: jsPsych.plugins.parameterType.FUNCTION,
38 | pretty_name: 'Mistake function',
39 | default: function () {},
40 | description: 'Function called if check_answers is set to TRUE and there is a difference between the participants answers and the correct solution provided in the text.'
41 | }
42 | }
43 | };
44 |
45 | plugin.trial = function (display_element, trial) {
46 |
47 | var html = '';
48 | var elements = trial.text.split('%');
49 | var solutions = [];
50 |
51 | for (i=0; i';
61 | }
62 | }
63 | html += '
';
64 |
65 | display_element.innerHTML = html;
66 |
67 | var check = function() {
68 |
69 | var answers = [];
70 | var answers_correct = true;
71 |
72 | for (i=0; i'+trial.button_text+' ';
108 | display_element.querySelector('#finish_cloze_button').addEventListener('click', check);
109 | };
110 |
111 | return plugin;
112 | })();
--------------------------------------------------------------------------------
/inst/extdata/jsPsych-6.1.0/jspsych-external-html.js:
--------------------------------------------------------------------------------
1 | /** (July 2012, Erik Weitnauer)
2 | The html-plugin will load and display an external html pages. To proceed to the next, the
3 | user might either press a button on the page or a specific key. Afterwards, the page get hidden and
4 | the plugin will wait of a specified time before it proceeds.
5 |
6 | documentation: docs.jspsych.org
7 | */
8 |
9 | jsPsych.plugins['external-html'] = (function() {
10 |
11 | var plugin = {};
12 |
13 | plugin.info = {
14 | name: 'external-html',
15 | description: '',
16 | parameters: {
17 | url: {
18 | type: jsPsych.plugins.parameterType.STRING,
19 | pretty_name: 'URL',
20 | default: undefined,
21 | description: 'The url of the external html page'
22 | },
23 | cont_key: {
24 | type: jsPsych.plugins.parameterType.KEYCODE,
25 | pretty_name: 'Continue key',
26 | default: null,
27 | description: 'The key to continue to the next page.'
28 | },
29 | cont_btn: {
30 | type: jsPsych.plugins.parameterType.STRING,
31 | pretty_name: 'Continue button',
32 | default: null,
33 | description: 'The button to continue to the next page.'
34 | },
35 | check_fn: {
36 | type: jsPsych.plugins.parameterType.FUNCTION,
37 | pretty_name: 'Check function',
38 | default: function() { return true; },
39 | description: ''
40 | },
41 | force_refresh: {
42 | type: jsPsych.plugins.parameterType.BOOL,
43 | pretty_name: 'Force refresh',
44 | default: false,
45 | description: 'Refresh page.'
46 | },
47 | // if execute_Script == true, then all javascript code on the external page
48 | // will be executed in the plugin site within your jsPsych test
49 | execute_script: {
50 | type: jsPsych.plugins.parameterType.BOOL,
51 | pretty_name: 'Execute scripts',
52 | default: false,
53 | description: 'If true, JS scripts on the external html file will be executed.'
54 | }
55 | }
56 | }
57 |
58 | plugin.trial = function(display_element, trial) {
59 |
60 | var url = trial.url;
61 | if (trial.force_refresh) {
62 | url = trial.url + "?t=" + performance.now();
63 | }
64 |
65 | load(display_element, url, function() {
66 | var t0 = performance.now();
67 | var finish = function() {
68 | if (trial.check_fn && !trial.check_fn(display_element)) { return };
69 | if (trial.cont_key) { display_element.removeEventListener('keydown', key_listener); }
70 | var trial_data = {
71 | rt: performance.now() - t0,
72 | url: trial.url
73 | };
74 | display_element.innerHTML = '';
75 | jsPsych.finishTrial(trial_data);
76 | };
77 |
78 | // by default, scripts on the external page are not executed with XMLHttpRequest().
79 | // To activate their content through DOM manipulation, we need to relocate all script tags
80 | if (trial.execute_script) {
81 | for (const scriptElement of display_element.getElementsByTagName("script")) {
82 | const relocatedScript = document.createElement("script");
83 | relocatedScript.text = scriptElement.text;
84 | scriptElement.parentNode.replaceChild(relocatedScript, scriptElement);
85 | };
86 | }
87 |
88 | if (trial.cont_btn) { display_element.querySelector('#'+trial.cont_btn).addEventListener('click', finish); }
89 | if (trial.cont_key) {
90 | var key_listener = function(e) {
91 | if (e.which == trial.cont_key) finish();
92 | };
93 | display_element.addEventListener('keydown', key_listener);
94 | }
95 | });
96 | };
97 |
98 | // helper to load via XMLHttpRequest
99 | function load(element, file, callback){
100 | var xmlhttp = new XMLHttpRequest();
101 | xmlhttp.open("GET", file, true);
102 | xmlhttp.onload = function(){
103 | if(xmlhttp.status == 200 || xmlhttp.status == 0){ //Check if loaded
104 | element.innerHTML = xmlhttp.responseText;
105 | callback();
106 | }
107 | }
108 | xmlhttp.send();
109 | }
110 |
111 | return plugin;
112 | })();
113 |
--------------------------------------------------------------------------------
/inst/extdata/jsPsych-6.1.0/jspsych-fullscreen.js:
--------------------------------------------------------------------------------
1 | /* jspsych-fullscreen.js
2 | * Josh de Leeuw
3 | *
4 | * toggle fullscreen mode in the browser
5 | *
6 | */
7 |
8 | jsPsych.plugins.fullscreen = (function() {
9 |
10 | var plugin = {};
11 |
12 | plugin.info = {
13 | name: 'fullscreen',
14 | description: '',
15 | parameters: {
16 | fullscreen_mode: {
17 | type: jsPsych.plugins.parameterType.BOOL,
18 | pretty_name: 'Fullscreen mode',
19 | default: true,
20 | array: false,
21 | description: 'If true, experiment will enter fullscreen mode. If false, the browser will exit fullscreen mode.'
22 | },
23 | message: {
24 | type: jsPsych.plugins.parameterType.STRING,
25 | pretty_name: 'Message',
26 | default: 'The experiment will switch to full screen mode when you press the button below
',
27 | array: false,
28 | description: 'HTML content to display above the button to enter fullscreen mode.'
29 | },
30 | button_label: {
31 | type: jsPsych.plugins.parameterType.STRING,
32 | pretty_name: 'Button label',
33 | default: 'Continue',
34 | array: false,
35 | description: 'The text that appears on the button to enter fullscreen.'
36 | },
37 | delay_after: {
38 | type: jsPsych.plugins.parameterType.INT,
39 | pretty_name: 'Delay after',
40 | default: 1000,
41 | array: false,
42 | description: 'The length of time to delay after entering fullscreen mode before ending the trial.'
43 | },
44 | }
45 | }
46 |
47 | plugin.trial = function(display_element, trial) {
48 |
49 | // check if keys are allowed in fullscreen mode
50 | var keyboardNotAllowed = typeof Element !== 'undefined' && 'ALLOW_KEYBOARD_INPUT' in Element;
51 | if (keyboardNotAllowed) {
52 | // This is Safari, and keyboard events will be disabled. Don't allow fullscreen here.
53 | // do something else?
54 | endTrial();
55 | } else {
56 | if(trial.fullscreen_mode){
57 | display_element.innerHTML = trial.message + ''+trial.button_label+' ';
58 | var listener = display_element.querySelector('#jspsych-fullscreen-btn').addEventListener('click', function() {
59 | var element = document.documentElement;
60 | if (element.requestFullscreen) {
61 | element.requestFullscreen();
62 | } else if (element.mozRequestFullScreen) {
63 | element.mozRequestFullScreen();
64 | } else if (element.webkitRequestFullscreen) {
65 | element.webkitRequestFullscreen();
66 | } else if (element.msRequestFullscreen) {
67 | element.msRequestFullscreen();
68 | }
69 | endTrial();
70 | });
71 | } else {
72 | if (document.exitFullscreen) {
73 | document.exitFullscreen();
74 | } else if (document.msExitFullscreen) {
75 | document.msExitFullscreen();
76 | } else if (document.mozCancelFullScreen) {
77 | document.mozCancelFullScreen();
78 | } else if (document.webkitExitFullscreen) {
79 | document.webkitExitFullscreen();
80 | }
81 | endTrial();
82 | }
83 | }
84 |
85 | function endTrial() {
86 |
87 | display_element.innerHTML = '';
88 |
89 | jsPsych.pluginAPI.setTimeout(function(){
90 |
91 | var trial_data = {
92 | success: !keyboardNotAllowed
93 | };
94 |
95 | jsPsych.finishTrial(trial_data);
96 |
97 | }, trial.delay_after);
98 |
99 | }
100 |
101 | };
102 |
103 | return plugin;
104 | })();
105 |
--------------------------------------------------------------------------------
/inst/extdata/jsPsych-6.1.0/jspsych-html-keyboard-response.js:
--------------------------------------------------------------------------------
1 | /**
2 | * jspsych-html-keyboard-response
3 | * Josh de Leeuw
4 | *
5 | * plugin for displaying a stimulus and getting a keyboard response
6 | *
7 | * documentation: docs.jspsych.org
8 | *
9 | **/
10 |
11 |
12 | jsPsych.plugins["html-keyboard-response"] = (function() {
13 |
14 | var plugin = {};
15 |
16 | plugin.info = {
17 | name: 'html-keyboard-response',
18 | description: '',
19 | parameters: {
20 | stimulus: {
21 | type: jsPsych.plugins.parameterType.HTML_STRING,
22 | pretty_name: 'Stimulus',
23 | default: undefined,
24 | description: 'The HTML string to be displayed'
25 | },
26 | choices: {
27 | type: jsPsych.plugins.parameterType.KEYCODE,
28 | array: true,
29 | pretty_name: 'Choices',
30 | default: jsPsych.ALL_KEYS,
31 | description: 'The keys the subject is allowed to press to respond to the stimulus.'
32 | },
33 | prompt: {
34 | type: jsPsych.plugins.parameterType.STRING,
35 | pretty_name: 'Prompt',
36 | default: null,
37 | description: 'Any content here will be displayed below the stimulus.'
38 | },
39 | stimulus_duration: {
40 | type: jsPsych.plugins.parameterType.INT,
41 | pretty_name: 'Stimulus duration',
42 | default: null,
43 | description: 'How long to hide the stimulus.'
44 | },
45 | trial_duration: {
46 | type: jsPsych.plugins.parameterType.INT,
47 | pretty_name: 'Trial duration',
48 | default: null,
49 | description: 'How long to show trial before it ends.'
50 | },
51 | response_ends_trial: {
52 | type: jsPsych.plugins.parameterType.BOOL,
53 | pretty_name: 'Response ends trial',
54 | default: true,
55 | description: 'If true, trial will end when subject makes a response.'
56 | },
57 |
58 | }
59 | }
60 |
61 | plugin.trial = function(display_element, trial) {
62 |
63 | var new_html = ''+trial.stimulus+'
';
64 |
65 | // add prompt
66 | if(trial.prompt !== null){
67 | new_html += trial.prompt;
68 | }
69 |
70 | // draw
71 | display_element.innerHTML = new_html;
72 |
73 | // store response
74 | var response = {
75 | rt: null,
76 | key: null
77 | };
78 |
79 | // function to end trial when it is time
80 | var end_trial = function() {
81 |
82 | // kill any remaining setTimeout handlers
83 | jsPsych.pluginAPI.clearAllTimeouts();
84 |
85 | // kill keyboard listeners
86 | if (typeof keyboardListener !== 'undefined') {
87 | jsPsych.pluginAPI.cancelKeyboardResponse(keyboardListener);
88 | }
89 |
90 | // gather the data to store for the trial
91 | var trial_data = {
92 | "rt": response.rt,
93 | "stimulus": trial.stimulus,
94 | "key_press": response.key
95 | };
96 |
97 | // clear the display
98 | display_element.innerHTML = '';
99 |
100 | // move on to the next trial
101 | jsPsych.finishTrial(trial_data);
102 | };
103 |
104 | // function to handle responses by the subject
105 | var after_response = function(info) {
106 |
107 | // after a valid response, the stimulus will have the CSS class 'responded'
108 | // which can be used to provide visual feedback that a response was recorded
109 | display_element.querySelector('#jspsych-html-keyboard-response-stimulus').className += ' responded';
110 |
111 | // only record the first response
112 | if (response.key == null) {
113 | response = info;
114 | }
115 |
116 | if (trial.response_ends_trial) {
117 | end_trial();
118 | }
119 | };
120 |
121 | // start the response listener
122 | if (trial.choices != jsPsych.NO_KEYS) {
123 | var keyboardListener = jsPsych.pluginAPI.getKeyboardResponse({
124 | callback_function: after_response,
125 | valid_responses: trial.choices,
126 | rt_method: 'performance',
127 | persist: false,
128 | allow_held_key: false
129 | });
130 | }
131 |
132 | // hide stimulus if stimulus_duration is set
133 | if (trial.stimulus_duration !== null) {
134 | jsPsych.pluginAPI.setTimeout(function() {
135 | display_element.querySelector('#jspsych-html-keyboard-response-stimulus').style.visibility = 'hidden';
136 | }, trial.stimulus_duration);
137 | }
138 |
139 | // end trial if trial_duration is set
140 | if (trial.trial_duration !== null) {
141 | jsPsych.pluginAPI.setTimeout(function() {
142 | end_trial();
143 | }, trial.trial_duration);
144 | }
145 |
146 | };
147 |
148 | return plugin;
149 | })();
150 |
--------------------------------------------------------------------------------
/inst/extdata/jsPsych-6.1.0/jspsych-reconstruction.js:
--------------------------------------------------------------------------------
1 | /**
2 | * jspsych-reconstruction
3 | * a jspsych plugin for a reconstruction task where the subject recreates
4 | * a stimulus from memory
5 | *
6 | * Josh de Leeuw
7 | *
8 | * documentation: docs.jspsych.org
9 | *
10 | */
11 |
12 |
13 | jsPsych.plugins['reconstruction'] = (function() {
14 |
15 | var plugin = {};
16 |
17 | plugin.info = {
18 | name: 'reconstruction',
19 | description: '',
20 | parameters: {
21 | stim_function: {
22 | type: jsPsych.plugins.parameterType.FUNCTION,
23 | pretty_name: 'Stimulus function',
24 | default: undefined,
25 | description: 'A function with a single parameter that returns an HTML-formatted string representing the stimulus.'
26 | },
27 | starting_value: {
28 | type: jsPsych.plugins.parameterType.FLOAT,
29 | pretty_name: 'Starting value',
30 | default: 0.5,
31 | description: 'The starting value of the stimulus parameter.'
32 | },
33 | step_size: {
34 | type: jsPsych.plugins.parameterType.FLOAT,
35 | pretty_name: 'Step size',
36 | default: 0.05,
37 | description: 'The change in the stimulus parameter caused by pressing one of the modification keys.'
38 | },
39 | key_increase: {
40 | type: jsPsych.plugins.parameterType.KEYCODE,
41 | pretty_name: 'Key increase',
42 | default: 'h',
43 | description: 'The key to press for increasing the parameter value.'
44 | },
45 | key_decrease: {
46 | type: jsPsych.plugins.parameterType.KEYCODE,
47 | pretty_name: 'Key decrease',
48 | default: 'g',
49 | description: 'The key to press for decreasing the parameter value.'
50 | },
51 | button_label: {
52 | type: jsPsych.plugins.parameterType.STRING,
53 | pretty_name: 'Button label',
54 | default: 'Continue',
55 | description: 'The text that appears on the button to finish the trial.'
56 | }
57 | }
58 | }
59 |
60 | plugin.trial = function(display_element, trial) {
61 |
62 | // current param level
63 | var param = trial.starting_value;
64 |
65 | // set-up key listeners
66 | var after_response = function(info) {
67 |
68 | //console.log('fire');
69 |
70 | var key_i = (typeof trial.key_increase == 'string') ? jsPsych.pluginAPI.convertKeyCharacterToKeyCode(trial.key_increase) : trial.key_increase;
71 | var key_d = (typeof trial.key_decrease == 'string') ? jsPsych.pluginAPI.convertKeyCharacterToKeyCode(trial.key_decrease) : trial.key_decrease;
72 |
73 | // get new param value
74 | if (info.key == key_i) {
75 | param = param + trial.step_size;
76 | } else if (info.key == key_d) {
77 | param = param - trial.step_size;
78 | }
79 | param = Math.max(Math.min(1, param), 0);
80 |
81 | // refresh the display
82 | draw(param);
83 | }
84 |
85 | // listen for responses
86 | var key_listener = jsPsych.pluginAPI.getKeyboardResponse({
87 | callback_function: after_response,
88 | valid_responses: [trial.key_increase, trial.key_decrease],
89 | rt_method: 'performance',
90 | persist: true,
91 | allow_held_key: true
92 | });
93 | // draw first iteration
94 | draw(param);
95 |
96 | function draw(param) {
97 |
98 | //console.log(param);
99 |
100 | display_element.innerHTML = ''+trial.stim_function(param)+'
';
101 |
102 | // add submit button
103 | display_element.innerHTML += ''+trial.button_label+' ';
104 |
105 | display_element.querySelector('#jspsych-reconstruction-next').addEventListener('click', endTrial);
106 | }
107 |
108 | function endTrial() {
109 | // measure response time
110 | var endTime =performance.now();
111 | var response_time = endTime - startTime;
112 |
113 | // clear keyboard response
114 | jsPsych.pluginAPI.cancelKeyboardResponse(key_listener);
115 |
116 | // save data
117 | var trial_data = {
118 | "rt": response_time,
119 | "final_value": param,
120 | "start_value": trial.starting_value
121 | };
122 |
123 | display_element.innerHTML = '';
124 |
125 | // next trial
126 | jsPsych.finishTrial(trial_data);
127 | }
128 |
129 | var startTime = performance.now();
130 |
131 | };
132 |
133 | return plugin;
134 | })();
135 |
--------------------------------------------------------------------------------
/inst/extdata/jsPsych-6.1.0/jspsych-vsl-grid-scene.js:
--------------------------------------------------------------------------------
1 | /**
2 | * jsPsych plugin for showing scenes that mimic the experiments described in
3 | *
4 | * Fiser, J., & Aslin, R. N. (2001). Unsupervised statistical learning of
5 | * higher-order spatial structures from visual scenes. Psychological science,
6 | * 12(6), 499-504.
7 | *
8 | * Josh de Leeuw
9 | *
10 | * documentation: docs.jspsych.org
11 | *
12 | */
13 |
14 | jsPsych.plugins['vsl-grid-scene'] = (function() {
15 |
16 | var plugin = {};
17 |
18 | jsPsych.pluginAPI.registerPreload('vsl-grid-scene', 'stimuli', 'image');
19 |
20 | plugin.info = {
21 | name: 'vsl-grid-scene',
22 | description: '',
23 | parameters: {
24 | stimuli: {
25 | type: jsPsych.plugins.parameterType.IMAGE,
26 | pretty_name: 'Stimuli',
27 | array: true,
28 | default: undefined,
29 | description: 'An array that defines a grid.'
30 | },
31 | image_size: {
32 | type: jsPsych.plugins.parameterType.INT,
33 | pretty_name: 'Image size',
34 | array: true,
35 | default: [100,100],
36 | description: 'Array specifying the width and height of the images to show.'
37 | },
38 | trial_duration: {
39 | type: jsPsych.plugins.parameterType.INT,
40 | pretty_name: 'Trial duration',
41 | default: 2000,
42 | description: 'How long to show the stimulus for in milliseconds.'
43 | }
44 | }
45 | }
46 |
47 | plugin.trial = function(display_element, trial) {
48 |
49 | display_element.innerHTML = plugin.generate_stimulus(trial.stimuli, trial.image_size);
50 |
51 | jsPsych.pluginAPI.setTimeout(function() {
52 | endTrial();
53 | }, trial.trial_duration);
54 |
55 | function endTrial() {
56 |
57 | display_element.innerHTML = '';
58 |
59 | var trial_data = {
60 | "stimulus": JSON.stringify(trial.stimuli)
61 | };
62 |
63 | jsPsych.finishTrial(trial_data);
64 | }
65 | };
66 |
67 | plugin.generate_stimulus = function(pattern, image_size) {
68 | var nrows = pattern.length;
69 | var ncols = pattern[0].length;
70 |
71 | // create blank element to hold code that we generate
72 | var html = '';
73 |
74 | // create table
75 | html += '
';
77 |
78 | for (var row = 0; row < nrows; row++) {
79 | html += '';
80 |
81 | for (var col = 0; col < ncols; col++) {
82 | html += ''+
84 | '';
85 | if (pattern[row][col] !== 0) {
86 | html += '
';
88 | }
89 | html += '
';
90 | html += ' ';
91 | }
92 | html += ' ';
93 | }
94 |
95 | html += '
';
96 | html += '
';
97 |
98 | return html;
99 |
100 | };
101 |
102 | return plugin;
103 | })();
104 |
--------------------------------------------------------------------------------
/inst/extdata/jsPsych-6.1.0/jspsych.css:
--------------------------------------------------------------------------------
1 | /*
2 | * CSS for jsPsych experiments.
3 | *
4 | * This stylesheet provides minimal styling to make jsPsych
5 | * experiments look polished without any additional styles.
6 | */
7 |
8 | @import url(https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700);
9 |
10 | /* Container holding jsPsych content */
11 |
12 | .jspsych-display-element {
13 | display: flex;
14 | flex-direction: column;
15 | overflow-y: auto;
16 | }
17 |
18 | .jspsych-display-element:focus {
19 | outline: none;
20 | }
21 |
22 | .jspsych-content-wrapper {
23 | display: flex;
24 | margin: auto;
25 | flex: 1 1 100%;
26 | width: 100%;
27 | }
28 |
29 | .jspsych-content {
30 | max-width: 95%; /* this is mainly an IE 10-11 fix */
31 | text-align: center;
32 | margin: auto; /* this is for overflowing content */
33 | }
34 |
35 | .jspsych-top {
36 | align-items: flex-start;
37 | }
38 |
39 | .jspsych-middle {
40 | align-items: center;
41 | }
42 |
43 | /* fonts and type */
44 |
45 | .jspsych-display-element {
46 | font-family: 'Open Sans', 'Arial', sans-serif;
47 | font-size: 18px;
48 | line-height: 1.6em;
49 | }
50 |
51 | /* Form elements like input fields and buttons */
52 |
53 | .jspsych-display-element input[type="text"] {
54 | font-family: 'Open Sans', 'Arial', sans-serif;
55 | font-size: 14px;
56 | }
57 |
58 | /* borrowing Bootstrap style for btn elements, but combining styles a bit */
59 | .jspsych-btn {
60 | display: inline-block;
61 | padding: 6px 12px;
62 | margin: 0px;
63 | font-size: 14px;
64 | font-weight: 400;
65 | font-family: 'Open Sans', 'Arial', sans-serif;
66 | cursor: pointer;
67 | line-height: 1.4;
68 | text-align: center;
69 | white-space: nowrap;
70 | vertical-align: middle;
71 | background-image: none;
72 | border: 1px solid transparent;
73 | border-radius: 4px;
74 | color: #333;
75 | background-color: #fff;
76 | border-color: #ccc;
77 | }
78 |
79 | .jspsych-btn:hover {
80 | background-color: #ddd;
81 | border-color: #aaa;
82 | }
83 |
84 | .jspsych-btn:disabled {
85 | background-color: #eee;
86 | color: #aaa;
87 | border-color: #ccc;
88 | cursor: not-allowed;
89 | }
90 |
91 | /* jsPsych progress bar */
92 |
93 | #jspsych-progressbar-container {
94 | color: #555;
95 | border-bottom: 1px solid #dedede;
96 | background-color: #f9f9f9;
97 | margin-bottom: 1em;
98 | text-align: center;
99 | padding: 8px 0px;
100 | width: 100%;
101 | line-height: 1em;
102 | }
103 | #jspsych-progressbar-container span {
104 | font-size: 14px;
105 | padding-right: 14px;
106 | }
107 | #jspsych-progressbar-outer {
108 | background-color: #eee;
109 | width: 50%;
110 | margin: auto;
111 | height: 14px;
112 | display: inline-block;
113 | vertical-align: middle;
114 | box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);
115 | }
116 | #jspsych-progressbar-inner {
117 | background-color: #aaa;
118 | width: 0%;
119 | height: 100%;
120 | }
121 |
122 | /* Control appearance of jsPsych.data.displayData() */
123 | #jspsych-data-display {
124 | text-align: left;
125 | }
126 |
--------------------------------------------------------------------------------
/inst/extdata/jsPsych-6.1.0/license.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014-2018 Joshua R. de Leeuw
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/inst/extdata/xprmntr.js:
--------------------------------------------------------------------------------
1 | /**
2 | * xprmntr.js
3 | * Danielle Navarro
4 | *
5 | **/
6 |
7 | // bundle everything into the xprmntr object
8 | var xprmntr = {};
9 |
10 | // for use in the jsPsych.init() call
11 | xprmntr.save_locally = function() {
12 | var data = jsPsych.data.get().csv();
13 | var file = "xprmntr_local_name";
14 | var xhr = new XMLHttpRequest();
15 | xhr.open('POST', 'submit');
16 | xhr.setRequestHeader('Content-Type', 'application/json');
17 | xhr.send(JSON.stringify({filename: file, filedata: data}));
18 | };
19 |
20 |
--------------------------------------------------------------------------------
/man/add_properties.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/build_experiment.R
3 | \name{add_properties}
4 | \alias{add_properties}
5 | \title{Wrapper to jsPsych.data.addProperty}
6 | \usage{
7 | add_properties(...)
8 | }
9 | \arguments{
10 | \item{...}{Name/value pairs}
11 | }
12 | \description{
13 | Wrapper to jsPsych.data.addProperty
14 | }
15 |
--------------------------------------------------------------------------------
/man/add_resources.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/build_experiment.R
3 | \name{add_resources}
4 | \alias{add_resources}
5 | \title{Construct a resource specification from paths}
6 | \usage{
7 | add_resources(from, audio = c(".mp3", ".wav", ".aif", ".mid"),
8 | video = c(".mp4", ".mpg", ".mov", ".wmv"), image = c(".jpg", ".png",
9 | ".bmp", ".svg", ".tiff"), script = c(".js"), style = c(".css"))
10 | }
11 | \arguments{
12 | \item{from}{The paths to files/directories}
13 |
14 | \item{audio}{File extensions assumed to be audio}
15 |
16 | \item{video}{File extensions assumed to be video}
17 |
18 | \item{image}{File extensions assumed to be images}
19 |
20 | \item{script}{File extensions assumed to be scripts}
21 |
22 | \item{style}{File extensions assumed to be stylesheets}
23 | }
24 | \description{
25 | Construct a resource specification from paths
26 | }
27 |
--------------------------------------------------------------------------------
/man/cue_html.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/trial_simple.R
3 | \name{cue_html}
4 | \alias{cue_html}
5 | \title{Define an HTML cue}
6 | \usage{
7 | cue_html(stimulus)
8 | }
9 | \arguments{
10 | \item{stimulus}{HTML}
11 | }
12 | \value{
13 | An object of class xpt_cue
14 | }
15 | \description{
16 | Define an HTML cue
17 | }
18 |
--------------------------------------------------------------------------------
/man/cue_image.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/trial_simple.R
3 | \name{cue_image}
4 | \alias{cue_image}
5 | \title{Define an image cue}
6 | \usage{
7 | cue_image(stimulus, stimulus_height = NULL, stimulus_width = NULL,
8 | maintain_aspect_ratio = TRUE)
9 | }
10 | \arguments{
11 | \item{stimulus}{Image file, specified using the resource() function}
12 |
13 | \item{stimulus_height}{Image height in pixels (defaults to natural height)}
14 |
15 | \item{stimulus_width}{Image width in pixels (defaults to natural width)}
16 |
17 | \item{maintain_aspect_ratio}{Maintain aspect ratio (default = TRUE)}
18 | }
19 | \value{
20 | An object of class xpt_cue
21 | }
22 | \description{
23 | Define an image cue
24 | }
25 |
--------------------------------------------------------------------------------
/man/cue_text.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/trial_simple.R
3 | \name{cue_text}
4 | \alias{cue_text}
5 | \title{Define a text cue}
6 | \usage{
7 | cue_text(stimulus)
8 | }
9 | \arguments{
10 | \item{stimulus}{text}
11 | }
12 | \value{
13 | An object of class xpt_cue
14 | }
15 | \description{
16 | Define a text cue
17 | }
18 |
--------------------------------------------------------------------------------
/man/experiment.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/build_experiment.R
3 | \name{experiment}
4 | \alias{experiment}
5 | \title{Make the experiment}
6 | \usage{
7 | experiment(timeline, path, resources = NULL, columns = NULL, ...)
8 | }
9 | \arguments{
10 | \item{timeline}{tl}
11 |
12 | \item{path}{p}
13 |
14 | \item{resources}{r}
15 |
16 | \item{columns}{columns}
17 |
18 | \item{...}{pass to init}
19 | }
20 | \description{
21 | Make the experiment
22 | }
23 |
--------------------------------------------------------------------------------
/man/jshelpers.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/helpers_js.R
3 | \name{jshelpers}
4 | \alias{jshelpers}
5 | \alias{js_code}
6 | \alias{js_logical}
7 | \alias{js_numeric}
8 | \alias{js_string}
9 | \alias{js_struct}
10 | \alias{js_array}
11 | \title{Manually specify the JavaScript object type}
12 | \usage{
13 | js_code(x)
14 |
15 | js_logical(x)
16 |
17 | js_numeric(x)
18 |
19 | js_string(...)
20 |
21 | js_struct(...)
22 |
23 | js_array(...)
24 | }
25 | \arguments{
26 | \item{x}{an object to be coerced}
27 |
28 | \item{...}{objects to be concatenated and coerced}
29 | }
30 | \description{
31 | Manually specify the JavaScript object type
32 | }
33 |
--------------------------------------------------------------------------------
/man/question.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/trial_survey.R
3 | \name{question}
4 | \alias{question}
5 | \title{Create a survey question}
6 | \usage{
7 | question(cue, response, required = FALSE, name = NULL)
8 | }
9 | \arguments{
10 | \item{cue}{the prompt for the question}
11 |
12 | \item{response}{the response type for the question}
13 |
14 | \item{required}{is a response to the question required?}
15 |
16 | \item{name}{a convenient label for the question}
17 | }
18 | \value{
19 | An object of class xpt_question
20 | }
21 | \description{
22 | Create a survey question
23 | }
24 |
--------------------------------------------------------------------------------
/man/reexports.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/helpers_misc.R
3 | \docType{import}
4 | \name{reexports}
5 | \alias{reexports}
6 | \alias{\%>\%}
7 | \title{Objects exported from other packages}
8 | \keyword{internal}
9 | \description{
10 | These objects are imported from other packages. Follow the links
11 | below to see their documentation.
12 |
13 | \describe{
14 | \item{magrittr}{\code{\link[magrittr]{\%>\%}}}
15 | }}
16 |
17 |
--------------------------------------------------------------------------------
/man/resource.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/helpers_misc.R
3 | \name{resource}
4 | \alias{resource}
5 | \title{Refers to a resource file}
6 | \usage{
7 | resource(file)
8 | }
9 | \arguments{
10 | \item{file}{path}
11 | }
12 | \description{
13 | Refers to a resource file
14 | }
15 |
--------------------------------------------------------------------------------
/man/response_button.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/trial_simple.R
3 | \name{response_button}
4 | \alias{response_button}
5 | \title{Specify a button response}
6 | \usage{
7 | response_button(choices, button_html = NULL, margin_vertical = "0px",
8 | margin_horizontal = "8px")
9 | }
10 | \arguments{
11 | \item{choices}{Character vector with labels for the buttons}
12 |
13 | \item{button_html}{HTML templay specifying the buttons (defaults to jsPsych default)}
14 |
15 | \item{margin_vertical}{Vertical margin of the buttons (default "0px")}
16 |
17 | \item{margin_horizontal}{Horizontal margin of the buttons (default "8px")}
18 | }
19 | \value{
20 | An object of class xpt_response
21 | }
22 | \description{
23 | Specify a button response
24 | }
25 |
--------------------------------------------------------------------------------
/man/response_freetext.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/trial_survey.R
3 | \name{response_freetext}
4 | \alias{response_freetext}
5 | \title{Specify a free text response}
6 | \usage{
7 | response_freetext(placeholder = "", rows = 1, columns = 40)
8 | }
9 | \arguments{
10 | \item{placeholder}{String specifying the placeholder text}
11 |
12 | \item{rows}{Number of rows spanned by the text box}
13 |
14 | \item{columns}{Number of columns spanned by the text box}
15 | }
16 | \value{
17 | An object of class xpt_response
18 | }
19 | \description{
20 | Specify a free text response
21 | }
22 |
--------------------------------------------------------------------------------
/man/response_key.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/trial_simple.R
3 | \name{response_key}
4 | \alias{response_key}
5 | \title{Specify a keyboard response}
6 | \usage{
7 | response_key(...)
8 | }
9 | \arguments{
10 | \item{...}{Either single string "any" (default), "none", or characters specifying keys}
11 | }
12 | \value{
13 | An object of class xpt_response
14 | }
15 | \description{
16 | Specify a keyboard response
17 | }
18 |
--------------------------------------------------------------------------------
/man/response_likert.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/trial_survey.R
3 | \name{response_likert}
4 | \alias{response_likert}
5 | \title{Specify a Likert response}
6 | \usage{
7 | response_likert(labels, scale_width = NULL)
8 | }
9 | \arguments{
10 | \item{labels}{character vector of response labels}
11 |
12 | \item{scale_width}{width of the "slider" in pixels}
13 | }
14 | \value{
15 | An object of class xpt_response
16 | }
17 | \description{
18 | Specify a Likert response
19 | }
20 |
--------------------------------------------------------------------------------
/man/response_pickone.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/trial_survey.R
3 | \name{response_pickone}
4 | \alias{response_pickone}
5 | \title{Specify a 'pick one' response}
6 | \usage{
7 | response_pickone(options, horizontal = FALSE)
8 | }
9 | \arguments{
10 | \item{options}{character vector of options}
11 |
12 | \item{horizontal}{should radio buttons be laid out horizontally?}
13 | }
14 | \value{
15 | An object of class xpt_response
16 | }
17 | \description{
18 | Specify a 'pick one' response
19 | }
20 |
--------------------------------------------------------------------------------
/man/response_picksome.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/trial_survey.R
3 | \name{response_picksome}
4 | \alias{response_picksome}
5 | \title{Specify a 'pick some' response}
6 | \usage{
7 | response_picksome(options, horizontal = FALSE)
8 | }
9 | \arguments{
10 | \item{options}{character vector of options}
11 |
12 | \item{horizontal}{should check boxes be laid out horizontally?}
13 | }
14 | \value{
15 | An object of class xpt_response
16 | }
17 | \description{
18 | Specify a 'pick some' response
19 | }
20 |
--------------------------------------------------------------------------------
/man/response_slider.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/trial_simple.R
3 | \name{response_slider}
4 | \alias{response_slider}
5 | \title{Specify a slider response}
6 | \usage{
7 | response_slider(labels = NULL, button_label = "Continue", min = 0,
8 | max = 100, start = 50, step = 1, slider_width = NULL,
9 | require_movement = FALSE)
10 | }
11 | \arguments{
12 | \item{labels}{Character vector of labels, to be spaced equally along slider}
13 |
14 | \item{button_label}{Text displayed on button at the end (default = "Continue")}
15 |
16 | \item{min}{Minimum value of the slider (default = 0)}
17 |
18 | \item{max}{Maximum value of the slider (default = 100)}
19 |
20 | \item{start}{Starting value of the slider (default = 50)}
21 |
22 | \item{step}{Smallest increment of slider movement (default = 1)}
23 |
24 | \item{slider_width}{Horizontal width of slider (defaults to max width)}
25 |
26 | \item{require_movement}{Does user need to move the slider to continue? (default = FALSE)}
27 | }
28 | \value{
29 | An object of class xpt_response
30 | }
31 | \description{
32 | Specify a slider response
33 | }
34 |
--------------------------------------------------------------------------------
/man/run_locally.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/build_api.R
3 | \name{run_locally}
4 | \alias{run_locally}
5 | \title{Run a jspsych experiment}
6 | \usage{
7 | run_locally(path = ".", port = 8000)
8 | }
9 | \arguments{
10 | \item{path}{the experiment directory}
11 |
12 | \item{port}{port to use}
13 | }
14 | \description{
15 | Run a jspsych experiment
16 | }
17 |
--------------------------------------------------------------------------------
/man/timeline.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/build_timeline.R
3 | \name{timeline}
4 | \alias{timeline}
5 | \title{Initialise a timeline}
6 | \usage{
7 | timeline(...)
8 | }
9 | \arguments{
10 | \item{...}{trial objects to add to this timeline}
11 | }
12 | \description{
13 | Initialise a timeline
14 | }
15 |
--------------------------------------------------------------------------------
/man/trial.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/build_timeline.R
3 | \name{trial}
4 | \alias{trial}
5 | \title{Adds an arbitrary trial to the timeline}
6 | \usage{
7 | trial(type, ...)
8 | }
9 | \arguments{
10 | \item{type}{the type of trial}
11 |
12 | \item{...}{arguments passed to the trial plugin}
13 | }
14 | \description{
15 | Adds an arbitrary trial to the timeline
16 | }
17 |
--------------------------------------------------------------------------------
/man/trial_simple.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/trial_simple.R
3 | \name{trial_simple}
4 | \alias{trial_simple}
5 | \title{Create a simple trial}
6 | \usage{
7 | trial_simple(cue, response, prompt = NULL, stimulus_duration = NULL,
8 | trial_duration = NULL, response_ends_trial = TRUE, ...)
9 | }
10 | \arguments{
11 | \item{cue}{the cue type for the trial}
12 |
13 | \item{response}{the response type for the question}
14 |
15 | \item{prompt}{prompt to be displayed with the stimulus (can include HTML markup)}
16 |
17 | \item{stimulus_duration}{how long to display stimulus in milliseconds? (default is to remain until response)}
18 |
19 | \item{trial_duration}{how long to wait for response in milliseconds? (default is to wait indefinitely)}
20 |
21 | \item{response_ends_trial}{does the trial end with response (default = TRUE) or continue until trial duration reached?}
22 |
23 | \item{...}{arguments to be passed to trial()}
24 | }
25 | \value{
26 | A trial object
27 | }
28 | \description{
29 | Create a simple trial
30 | }
31 |
--------------------------------------------------------------------------------
/man/trial_survey.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/trial_survey.R
3 | \name{trial_survey}
4 | \alias{trial_survey}
5 | \title{Create a survey trial}
6 | \usage{
7 | trial_survey(questions, preamble = "",
8 | randomize_question_order = FALSE, button_label = "Continue")
9 | }
10 | \arguments{
11 | \item{questions}{A question or list of questions}
12 |
13 | \item{preamble}{Text to appear above the questions}
14 |
15 | \item{randomize_question_order}{Should order be randomised?}
16 |
17 | \item{button_label}{Text for the continue button}
18 | }
19 | \value{
20 | A trial object
21 | }
22 | \description{
23 | Create a survey trial
24 | }
25 |
--------------------------------------------------------------------------------
/man/variable.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/build_timeline.R
3 | \name{variable}
4 | \alias{variable}
5 | \title{Use a timeline variable}
6 | \usage{
7 | variable(name)
8 | }
9 | \arguments{
10 | \item{name}{name of the variable to insert}
11 | }
12 | \description{
13 | Use a timeline variable
14 | }
15 |
--------------------------------------------------------------------------------
/man/with_parameters.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/build_timeline.R
3 | \name{with_parameters}
4 | \alias{with_parameters}
5 | \title{Attach a timeline variable to timeline object}
6 | \usage{
7 | with_parameters(timeline, ...)
8 | }
9 | \arguments{
10 | \item{timeline}{the timeline object}
11 |
12 | \item{...}{name value pairs}
13 | }
14 | \description{
15 | Attach a timeline variable to timeline object
16 | }
17 |
--------------------------------------------------------------------------------
/man/with_variables.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/build_timeline.R
3 | \name{with_variables}
4 | \alias{with_variables}
5 | \title{Attach a timeline variable to timeline object}
6 | \usage{
7 | with_variables(timeline, ...)
8 | }
9 | \arguments{
10 | \item{timeline}{the timeline object}
11 |
12 | \item{...}{name value pairs}
13 | }
14 | \description{
15 | Attach a timeline variable to timeline object
16 | }
17 |
--------------------------------------------------------------------------------
/misc/demo1.R:
--------------------------------------------------------------------------------
1 | library(xprmntr)
2 |
3 |
4 | # define trial events -----------------------------------------------------
5 |
6 | # define a welcome trial
7 | welcome <- trial_html_key(
8 | "Welcome to the experiment! Press any key to continue",
9 | )
10 |
11 | # define a fixation trial
12 | fixation <- trial_html_key(
13 | stimulus = '+
',
14 | choices = no_key(),
15 | trial_duration = 500
16 | )
17 |
18 | # define a test trial
19 | query <- trial_image_key(
20 | stimulus = variable("stimulus"),
21 | prompt = variable("prompt"),
22 | choices = c("y","n")
23 | )
24 |
25 | # define a survey question
26 | likert1 <- question_likert(
27 | prompt = "How confident were you in your answers?",
28 | labels = c("very unsure", "somewhat unsure", "somewhat sure", "very sure"),
29 | required = TRUE
30 | )
31 |
32 | # define a survey question
33 | likert2 <- question_likert(
34 | prompt = "How bored were you in this experient?",
35 | labels = c("not at all bored", "somewhat bored", "very bored"),
36 | required = FALSE
37 | )
38 |
39 | # define a likert survey page
40 | survey1 <- trial_survey_likert(
41 | questions = list(likert1, likert2),
42 | preamble = "We have some questions"
43 | )
44 |
45 | # define a survey question
46 | multi1 <- question_multi(
47 | prompt = "What gender are you?",
48 | options = c("male", "female", "non-binary", "other"),
49 | required = FALSE
50 | )
51 |
52 | # define a survey question
53 | multi2 <- question_multi(
54 | prompt = "Do you identify as LGBTIQ?",
55 | options = c("yeah", "nah"),
56 | required = FALSE
57 | )
58 |
59 | # define a multiple choice survey page
60 | survey2 <- trial_survey_multi_choice(
61 | questions = list(multi1, multi2),
62 | preamble = "We have some more questions"
63 | )
64 |
65 | # define a survey question
66 | multi3 <- question_multi(
67 | prompt = "Select all that apply",
68 | options = c("lesbian", "gay", "bisexual", "transgender"),
69 | required = FALSE
70 | )
71 |
72 | # define a multi select page
73 | survey3 <- trial_survey_multi_select(
74 | questions = list(multi3)
75 | )
76 |
77 | # define a free text page
78 | survey4 <- trial_survey_text(
79 | questions = list(
80 | question_text(prompt = "Anything to add?", rows = 4),
81 | question_text(prompt = "Enter completion code")
82 | )
83 | )
84 |
85 | # define an end of experiment trial
86 | finish <- trial_html_key("All done!")
87 |
88 |
89 |
90 | # organise into a structure -----------------------------------------------
91 |
92 | flag_names <- c("bisexual", "transgender", "LGBT")
93 | flag_files <- c("bisexual.svg", "transgender.svg", "rainbow.svg")
94 |
95 | # testing procedure is a timeline of fixate/query events
96 | testing <- timeline(fixation, query) %>%
97 | with_variables(
98 | prompt = paste("is this the", flag_names, "flag? (y/n)"),
99 | stimulus = resource(flag_files)) %>%
100 | with_parameters(randomize_order = TRUE, repetitions = 2)
101 |
102 |
103 | # overall procedure
104 | all_events <- timeline(
105 | welcome,
106 | testing,
107 | survey1,
108 | survey2,
109 | survey3,
110 | survey4,
111 | finish
112 | )
113 |
114 |
115 |
116 |
117 | # write the experiment files ----------------------------------------------
118 |
119 | resources <- add_resources(system.file("extdata", "img", package = "xprmntr"))
120 |
121 | experiment(
122 | timeline = all_events,
123 | path = "~/Desktop/expt",
124 | resources = resources,
125 | default_iti = 250,
126 | on_finish = js_code("xprmntr.save_locally"),
127 | preload_images = resource(flag_files)
128 | )
129 |
130 |
131 |
132 |
133 | # run the experiment ------------------------------------------------------
134 |
135 | if(FALSE) {
136 | run_locally(
137 | path = "~/Desktop/expt",
138 | port = 8000
139 | )
140 | }
141 |
--------------------------------------------------------------------------------
/misc/demo1b.R:
--------------------------------------------------------------------------------
1 | library(xprmntr)
2 |
3 |
4 |
5 | # welcome trial -----------------------------------------------------------
6 |
7 | welcome_trial <- trial_simple(
8 | cue = cue_html("Welcome to the experiment! Press any key to continue"),
9 | response = response_key("any")
10 | )
11 |
12 |
13 |
14 |
15 | # choice trials -----------------------------------------------------------
16 |
17 | # define a fixation trial
18 | fixation <- trial_simple(
19 | cue = cue_html('+
'),
20 | response = response_key("none"),
21 | trial_duration = 500
22 | )
23 |
24 | # define a test trial
25 | query <- trial_simple(
26 | cue = cue_image(stimulus = variable("stimulus")),
27 | response = response_key("y", "n"),
28 | prompt = variable("prompt")
29 | )
30 |
31 | # define stimuli
32 | flag_names <- c("bisexual", "transgender", "LGBT")
33 | flag_files <- c("bisexual.svg", "transgender.svg", "rainbow.svg")
34 |
35 | # testing procedure is a timeline of fixate/query events
36 | choice_trials <- timeline(fixation, query) %>%
37 | with_variables(
38 | prompt = paste("is this the", flag_names, "flag? (y/n)"),
39 | stimulus = resource(flag_files)) %>%
40 | with_parameters(randomize_order = TRUE, repetitions = 2)
41 |
42 |
43 |
44 | # likert survey -----------------------------------------------------------
45 |
46 | # define some response scale
47 | confidence <- c("very unsure", "somewhat unsure", "somewhat sure", "very sure")
48 | boredom <- c("not at all bored", "somewhat bored", "very bored")
49 |
50 | # define a survey question
51 | likert_confidence <- question(
52 | cue = cue_text("How confident were you in your answers?"),
53 | response = response_likert(labels = confidence),
54 | required = TRUE
55 | )
56 |
57 | # define a survey question
58 | likert_bored <- question(
59 | cue = cue_text("How bored were you in your answers?"),
60 | response = response_likert(labels = boredom),
61 | required = FALSE
62 | )
63 |
64 | # compose a likert survey
65 | survey_likert <- trial_survey(
66 | questions = list(likert_confidence, likert_bored),
67 | preamble = "We have some questions"
68 | )
69 |
70 |
71 |
72 | # pick one survey ---------------------------------------------------------
73 |
74 | # define a survey question
75 | pickone_gender <- question(
76 | cue = cue_text("What gender are you?"),
77 | response = response_pickone(
78 | options = c("male", "female", "non-binary", "other")
79 | ),
80 | required = FALSE
81 | )
82 |
83 | # define a survey question
84 | pickone_identity <- question(
85 | cue = cue_text("Do you identify as LGBTIQ?"),
86 | response = response_pickone(
87 | options = c("yes", "no", "maybe")
88 | ),
89 | required = FALSE
90 | )
91 |
92 | # define a multiple choice survey page
93 | survey_pickone <- trial_survey(
94 | questions = list(pickone_gender, pickone_identity),
95 | preamble = "We have some more questions"
96 | )
97 |
98 |
99 |
100 | # pick some survey -----------------`---------------------------------------
101 |
102 |
103 | # define a survey question
104 | picksome_identities <- question(
105 | cue = cue_text("Select all that apply"),
106 | response = response_picksome(
107 | options = c("lesbian", "gay", "bisexual", "transgender",
108 | "intersex", "queer", "other")
109 | ),
110 | required = FALSE
111 | )
112 |
113 | # define a multi select page
114 | survey_picksome <- trial_survey(picksome_identities)
115 |
116 |
117 |
118 | # free text survey --------------------------------------------------------
119 |
120 |
121 |
122 | # define a free text page
123 | survey_freetext <- question(
124 | cue_text("Anything to add?"),
125 | response_freetext()
126 | ) %>%
127 | trial_survey()
128 |
129 |
130 |
131 | # finish trial ------------------------------------------------------------
132 |
133 | finish_trial <- trial_simple(
134 | cue_html("All done!"),
135 | response_key("any")
136 | )
137 |
138 |
139 |
140 |
141 | # organise into a structure -----------------------------------------------
142 |
143 | all_events <- timeline(
144 | welcome_trial,
145 | choice_trials,
146 | survey_likert,
147 | survey_pickone,
148 | survey_picksome,
149 | survey_freetext,
150 | finish_trial
151 | )
152 |
153 |
154 |
155 |
156 | # write the experiment files ----------------------------------------------
157 |
158 | resources <- add_resources(
159 | system.file("extdata", "img", package = "xprmntr")
160 | )
161 |
162 | experiment(
163 | timeline = all_events,
164 | path = "~/Desktop/expt",
165 | resources = resources,
166 | default_iti = 250,
167 | on_finish = js_code("xprmntr.save_locally"),
168 | preload_images = resource(flag_files)
169 | )
170 |
171 |
172 |
173 |
174 | # run the experiment ------------------------------------------------------
175 |
176 | if(FALSE) {
177 | run_locally(
178 | path = "~/Desktop/expt",
179 | port = 8000
180 | )
181 | }
182 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/css/jspsych.css:
--------------------------------------------------------------------------------
1 | /*
2 | * CSS for jsPsych experiments.
3 | *
4 | * This stylesheet provides minimal styling to make jsPsych
5 | * experiments look polished without any additional styles.
6 | */
7 |
8 | @import url(https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700);
9 |
10 | /* Container holding jsPsych content */
11 |
12 | .jspsych-display-element {
13 | display: flex;
14 | flex-direction: column;
15 | overflow-y: auto;
16 | }
17 |
18 | .jspsych-display-element:focus {
19 | outline: none;
20 | }
21 |
22 | .jspsych-content-wrapper {
23 | display: flex;
24 | margin: auto;
25 | flex: 1 1 100%;
26 | width: 100%;
27 | }
28 |
29 | .jspsych-content {
30 | max-width: 95%; /* this is mainly an IE 10-11 fix */
31 | text-align: center;
32 | margin: auto; /* this is for overflowing content */
33 | }
34 |
35 | .jspsych-top {
36 | align-items: flex-start;
37 | }
38 |
39 | .jspsych-middle {
40 | align-items: center;
41 | }
42 |
43 | /* fonts and type */
44 |
45 | .jspsych-display-element {
46 | font-family: 'Open Sans', 'Arial', sans-serif;
47 | font-size: 18px;
48 | line-height: 1.6em;
49 | }
50 |
51 | /* Form elements like input fields and buttons */
52 |
53 | .jspsych-display-element input[type="text"] {
54 | font-family: 'Open Sans', 'Arial', sans-serif;
55 | font-size: 14px;
56 | }
57 |
58 | /* borrowing Bootstrap style for btn elements, but combining styles a bit */
59 | .jspsych-btn {
60 | display: inline-block;
61 | padding: 6px 12px;
62 | margin: 0px;
63 | font-size: 14px;
64 | font-weight: 400;
65 | font-family: 'Open Sans', 'Arial', sans-serif;
66 | cursor: pointer;
67 | line-height: 1.4;
68 | text-align: center;
69 | white-space: nowrap;
70 | vertical-align: middle;
71 | background-image: none;
72 | border: 1px solid transparent;
73 | border-radius: 4px;
74 | color: #333;
75 | background-color: #fff;
76 | border-color: #ccc;
77 | }
78 |
79 | .jspsych-btn:hover {
80 | background-color: #ddd;
81 | border-color: #aaa;
82 | }
83 |
84 | .jspsych-btn:disabled {
85 | background-color: #eee;
86 | color: #aaa;
87 | border-color: #ccc;
88 | cursor: not-allowed;
89 | }
90 |
91 | /* jsPsych progress bar */
92 |
93 | #jspsych-progressbar-container {
94 | color: #555;
95 | border-bottom: 1px solid #dedede;
96 | background-color: #f9f9f9;
97 | margin-bottom: 1em;
98 | text-align: center;
99 | padding: 8px 0px;
100 | width: 100%;
101 | line-height: 1em;
102 | }
103 | #jspsych-progressbar-container span {
104 | font-size: 14px;
105 | padding-right: 14px;
106 | }
107 | #jspsych-progressbar-outer {
108 | background-color: #eee;
109 | width: 50%;
110 | margin: auto;
111 | height: 14px;
112 | display: inline-block;
113 | vertical-align: middle;
114 | box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);
115 | }
116 | #jspsych-progressbar-inner {
117 | background-color: #aaa;
118 | width: 0%;
119 | height: 100%;
120 | }
121 |
122 | /* Control appearance of jsPsych.data.displayData() */
123 | #jspsych-data-display {
124 | text-align: left;
125 | }
126 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/add-to-end-of-timeline.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
32 |
33 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/conditional-and-loop-functions.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
63 |
64 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/data-add-properties.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
14 |
15 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/data-as-function.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
14 |
15 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/data-from-timeline.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/data-from-url.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | The URL variable should be logged to the console
9 |
10 |
21 |
22 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/demo-flanker.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Flanker Task
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
108 |
109 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/demo-simple-rt-task.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | My experiment
5 |
6 |
7 |
8 |
9 |
10 |
11 |
104 |
105 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/demos/demo_1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
29 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/demos/demo_2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
14 |
15 |
43 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/demos/demo_3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
14 |
15 |
58 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/display-element-to-embed-experiment.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
17 |
18 |
19 |
20 |
21 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla.
22 |
23 | Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales ligula in libero. Sed dignissim lacinia nunc. Curabitur tortor. Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis. Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor. Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa.
24 |
25 | Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh. Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam nec ante. Sed lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin quam. Etiam ultrices.
26 |
27 | Suspendisse in justo eu magna luctus suscipit. Sed lectus. Integer euismod lacus luctus magna. Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor. Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit amet pede facilisis laoreet. Donec lacus nunc, viverra nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus.
28 |
29 | Ut ultrices ultrices enim. Curabitur sit amet mauris. Morbi in dui quis est pulvinar ullamcorper. Nulla facilisi. Integer lacinia sollicitudin massa. Cras metus. Sed aliquet risus a tortor. Integer id quam. Morbi mi. Quisque nisl felis, venenatis tristique, dignissim in, ultrices sit amet, augue. Proin sodales libero eget ante. Nulla quam.
30 |
31 |
32 |
33 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/end-active-node.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
15 |
16 |
17 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/end-experiment.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
14 |
15 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/exclusions.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
14 |
15 |
16 |
17 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/external_html/simple_consent.html:
--------------------------------------------------------------------------------
1 | This is a demo consent form. Click the checkbox below to indicate the you
2 | would like to participate in the experiment
3 | I agree to take part in this study.
4 | Start Experiment
5 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/1.gif
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/10.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/10.gif
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/11.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/11.gif
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/12.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/12.gif
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/2.gif
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/3.gif
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/4.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/4.gif
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/5.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/5.gif
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/6.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/6.gif
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/7.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/7.gif
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/8.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/8.gif
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/9.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/9.gif
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/age/of1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/age/of1.jpg
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/age/of2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/age/of2.jpg
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/age/of3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/age/of3.jpg
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/age/om1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/age/om1.jpg
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/age/om2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/age/om2.jpg
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/age/om3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/age/om3.jpg
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/age/yf1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/age/yf1.jpg
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/age/yf4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/age/yf4.jpg
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/age/yf5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/age/yf5.jpg
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/age/ym2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/age/ym2.jpg
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/age/ym3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/age/ym3.jpg
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/age/ym5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/age/ym5.jpg
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/backwardN.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/backwardN.gif
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/blue.png
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/con1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/con1.png
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/con2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/con2.png
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/fixation.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/fixation.gif
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/happy_face_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/happy_face_1.jpg
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/happy_face_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/happy_face_2.jpg
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/happy_face_3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/happy_face_3.jpg
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/happy_face_4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/happy_face_4.jpg
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/inc1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/inc1.png
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/inc2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/inc2.png
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/normalN.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/normalN.gif
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/orange.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/orange.png
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/redX.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/redX.png
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/ribbon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/ribbon.jpg
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/sad_face_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/sad_face_1.jpg
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/sad_face_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/sad_face_2.jpg
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/sad_face_3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/sad_face_3.jpg
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/img/sad_face_4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djnavarro/xprmntr/13b5762a22cfc806cf4735c2cf40ff64b5b98130/misc/jspsych-6.0.5/examples/img/sad_face_4.jpg
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-RDK.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
55 |
56 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-animation.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-audio-button-response.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
45 |
46 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-audio-keyboard-response.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-audio-slider-response.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-call-function.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
32 |
33 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-categorize-animation.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
14 |
15 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-categorize-html.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
14 |
15 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-categorize-image.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
14 |
15 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-form.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-free-sort.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
24 |
25 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-fullscreen.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
15 |
16 |
17 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-html-button-response.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
46 |
47 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-html-keyboard-response.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-html-slider-response.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
14 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-image-button-response.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
46 |
47 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-image-keyboard-response.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
14 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-image-slider-response.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
14 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-instructions.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
26 |
27 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-reconstruction.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
43 |
44 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-resize.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
34 |
35 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-same-different-html.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-same-different-image.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
14 |
15 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-serial-reaction-time-mouse.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-serial-reaction-time.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-survey-likert.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
26 |
27 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-survey-multi-choice.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
34 |
35 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-survey-multi-select.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
33 |
34 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-survey-text.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
27 |
28 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-video.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
26 |
27 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-visual-search-circle.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-vsl-animate-occlusion.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/jspsych-vsl-grid-scene.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
41 |
42 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/pause-unpause.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
33 |
34 |
--------------------------------------------------------------------------------
/misc/jspsych-6.0.5/examples/progress-bar.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
14 |
15 |
61 |
62 |