jspsych 7.1.1 → 7.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.browser.min.js","sources":["../../../node_modules/tslib/tslib.es6.js","../../../node_modules/auto-bind/index.js","../src/migration.ts","../src/modules/utils.ts","../src/modules/plugins.ts","../src/modules/data/DataColumn.ts","../src/modules/data/DataCollection.ts","../src/modules/data/utils.ts","../src/modules/data/index.ts","../src/modules/plugin-api/HardwareAPI.ts","../src/modules/plugin-api/KeyboardListenerAPI.ts","../src/modules/plugin-api/MediaAPI.ts","../src/modules/plugin-api/SimulationAPI.ts","../src/modules/plugin-api/TimeoutAPI.ts","../../../node_modules/random-words/index.js","../src/modules/randomization.ts","../src/modules/turk.ts","../src/TimelineNode.ts","../src/JsPsych.ts","../src/modules/plugin-api/index.ts","../src/index.ts"],"sourcesContent":["/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n","'use strict';\n\n// Gets all non-builtin properties up the prototype chain\nconst getAllProperties = object => {\n\tconst properties = new Set();\n\n\tdo {\n\t\tfor (const key of Reflect.ownKeys(object)) {\n\t\t\tproperties.add([object, key]);\n\t\t}\n\t} while ((object = Reflect.getPrototypeOf(object)) && object !== Object.prototype);\n\n\treturn properties;\n};\n\nmodule.exports = (self, {include, exclude} = {}) => {\n\tconst filter = key => {\n\t\tconst match = pattern => typeof pattern === 'string' ? key === pattern : pattern.test(key);\n\n\t\tif (include) {\n\t\t\treturn include.some(match);\n\t\t}\n\n\t\tif (exclude) {\n\t\t\treturn !exclude.some(match);\n\t\t}\n\n\t\treturn true;\n\t};\n\n\tfor (const [object, key] of getAllProperties(self.constructor.prototype)) {\n\t\tif (key === 'constructor' || !filter(key)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst descriptor = Reflect.getOwnPropertyDescriptor(object, key);\n\t\tif (descriptor && typeof descriptor.value === 'function') {\n\t\t\tself[key] = self[key].bind(self);\n\t\t}\n\t}\n\n\treturn self;\n};\n","export class MigrationError extends Error {\n constructor(message = \"The global `jsPsych` variable is no longer available in jsPsych v7.\") {\n super(\n `${message} Please follow the migration guide at https://www.jspsych.org/7.0/support/migration-v7/ to update your experiment.`\n );\n this.name = \"MigrationError\";\n }\n}\n\n// Define a global jsPsych object to handle invocations on it with migration errors\n(window as any).jsPsych = {\n get init() {\n throw new MigrationError(\"`jsPsych.init()` was replaced by `initJsPsych()` in jsPsych v7.\");\n },\n\n get data() {\n throw new MigrationError();\n },\n get randomization() {\n throw new MigrationError();\n },\n get turk() {\n throw new MigrationError();\n },\n get pluginAPI() {\n throw new MigrationError();\n },\n\n get ALL_KEYS() {\n throw new MigrationError(\n 'jsPsych.ALL_KEYS was replaced by the \"ALL_KEYS\" string in jsPsych v7.'\n );\n },\n get NO_KEYS() {\n throw new MigrationError('jsPsych.NO_KEYS was replaced by the \"NO_KEYS\" string in jsPsych v7.');\n },\n};\n","/**\n * Finds all of the unique items in an array.\n * @param arr The array to extract unique values from\n * @returns An array with one copy of each unique item in `arr`\n */\nexport function unique(arr: Array<any>) {\n return [...new Set(arr)];\n}\n\nexport function deepCopy(obj) {\n if (!obj) return obj;\n let out;\n if (Array.isArray(obj)) {\n out = [];\n for (const x of obj) {\n out.push(deepCopy(x));\n }\n return out;\n } else if (typeof obj === \"object\" && obj !== null) {\n out = {};\n for (const key in obj) {\n if (obj.hasOwnProperty(key)) {\n out[key] = deepCopy(obj[key]);\n }\n }\n return out;\n } else {\n return obj;\n }\n}\n","/**\nFlatten the type output to improve type hints shown in editors.\nBorrowed from type-fest\n*/\ntype Simplify<T> = { [KeyType in keyof T]: T[KeyType] };\n\n/**\nCreate a type that makes the given keys required. The remaining keys are kept as is.\nBorrowed from type-fest\n*/\ntype SetRequired<BaseType, Keys extends keyof BaseType> = Simplify<\n Omit<BaseType, Keys> & Required<Pick<BaseType, Keys>>\n>;\n\n/**\n * Parameter types for plugins\n */\nexport enum ParameterType {\n BOOL,\n STRING,\n INT,\n FLOAT,\n FUNCTION,\n KEY,\n KEYS,\n SELECT,\n HTML_STRING,\n IMAGE,\n AUDIO,\n VIDEO,\n OBJECT,\n COMPLEX,\n TIMELINE,\n}\n\ntype ParameterTypeMap = {\n [ParameterType.BOOL]: boolean;\n [ParameterType.STRING]: string;\n [ParameterType.INT]: number;\n [ParameterType.FLOAT]: number;\n [ParameterType.FUNCTION]: (...args: any[]) => any;\n [ParameterType.KEY]: string;\n [ParameterType.KEYS]: string[] | \"ALL_KEYS\" | \"NO_KEYS\";\n [ParameterType.SELECT]: any;\n [ParameterType.HTML_STRING]: string;\n [ParameterType.IMAGE]: string;\n [ParameterType.AUDIO]: string;\n [ParameterType.VIDEO]: string;\n [ParameterType.OBJECT]: object;\n [ParameterType.COMPLEX]: any;\n [ParameterType.TIMELINE]: any;\n};\n\nexport interface ParameterInfo {\n type: ParameterType;\n array?: boolean;\n pretty_name?: string;\n default?: any;\n preload?: boolean;\n}\n\nexport interface ParameterInfos {\n [key: string]: ParameterInfo;\n}\n\ntype InferredParameter<I extends ParameterInfo> = I[\"array\"] extends true\n ? Array<ParameterTypeMap[I[\"type\"]]>\n : ParameterTypeMap[I[\"type\"]];\n\ntype RequiredParameterNames<I extends ParameterInfos> = {\n [K in keyof I]: I[K][\"default\"] extends undefined ? K : never;\n}[keyof I];\n\ntype InferredParameters<I extends ParameterInfos> = SetRequired<\n {\n [Property in keyof I]?: InferredParameter<I[Property]>;\n },\n RequiredParameterNames<I>\n>;\n\nexport const universalPluginParameters = <const>{\n /**\n * Data to add to this trial (key-value pairs)\n */\n data: {\n type: ParameterType.OBJECT,\n pretty_name: \"Data\",\n default: {},\n },\n /**\n * Function to execute when trial begins\n */\n on_start: {\n type: ParameterType.FUNCTION,\n pretty_name: \"On start\",\n default: function () {\n return;\n },\n },\n /**\n * Function to execute when trial is finished\n */\n on_finish: {\n type: ParameterType.FUNCTION,\n pretty_name: \"On finish\",\n default: function () {\n return;\n },\n },\n /**\n * Function to execute after the trial has loaded\n */\n on_load: {\n type: ParameterType.FUNCTION,\n pretty_name: \"On load\",\n default: function () {\n return;\n },\n },\n /**\n * Length of gap between the end of this trial and the start of the next trial\n */\n post_trial_gap: {\n type: ParameterType.INT,\n pretty_name: \"Post trial gap\",\n default: null,\n },\n /**\n * A list of CSS classes to add to the jsPsych display element for the duration of this trial\n */\n css_classes: {\n type: ParameterType.STRING,\n pretty_name: \"Custom CSS classes\",\n default: null,\n },\n};\n\nexport type UniversalPluginParameters = InferredParameters<typeof universalPluginParameters>;\n\nexport interface PluginInfo {\n name: string;\n parameters: {\n [key: string]: ParameterInfo;\n };\n}\n\nexport interface JsPsychPlugin<I extends PluginInfo> {\n trial(\n display_element: HTMLElement,\n trial: TrialType<I>,\n on_load?: () => void\n ): void | Promise<any>;\n}\n\nexport type TrialType<I extends PluginInfo> = InferredParameters<I[\"parameters\"]> &\n UniversalPluginParameters;\n\nexport type PluginParameters<I extends PluginInfo> = InferredParameters<I[\"parameters\"]>;\n","export class DataColumn {\n constructor(public values = []) {}\n\n sum() {\n let s = 0;\n for (const v of this.values) {\n s += v;\n }\n return s;\n }\n\n mean() {\n return this.sum() / this.count();\n }\n\n median() {\n if (this.values.length === 0) {\n return undefined;\n }\n const numbers = this.values.slice(0).sort(function (a, b) {\n return a - b;\n });\n const middle = Math.floor(numbers.length / 2);\n const isEven = numbers.length % 2 === 0;\n return isEven ? (numbers[middle] + numbers[middle - 1]) / 2 : numbers[middle];\n }\n\n min() {\n return Math.min.apply(null, this.values);\n }\n\n max() {\n return Math.max.apply(null, this.values);\n }\n\n count() {\n return this.values.length;\n }\n\n variance() {\n const mean = this.mean();\n let sum_square_error = 0;\n for (const x of this.values) {\n sum_square_error += Math.pow(x - mean, 2);\n }\n const mse = sum_square_error / (this.values.length - 1);\n return mse;\n }\n\n sd() {\n const mse = this.variance();\n const rmse = Math.sqrt(mse);\n return rmse;\n }\n\n frequencies() {\n const unique = {};\n for (const x of this.values) {\n if (typeof unique[x] === \"undefined\") {\n unique[x] = 1;\n } else {\n unique[x]++;\n }\n }\n return unique;\n }\n\n all(eval_fn) {\n for (const x of this.values) {\n if (!eval_fn(x)) {\n return false;\n }\n }\n return true;\n }\n\n subset(eval_fn) {\n const out = [];\n for (const x of this.values) {\n if (eval_fn(x)) {\n out.push(x);\n }\n }\n return new DataColumn(out);\n }\n}\n","import { deepCopy } from \"../utils\";\nimport { DataColumn } from \"./DataColumn\";\nimport { JSON2CSV, saveTextToFile } from \"./utils\";\n\nexport class DataCollection {\n private trials: any[];\n\n constructor(data = []) {\n this.trials = data;\n }\n\n push(new_data) {\n this.trials.push(new_data);\n return this;\n }\n\n join(other_data_collection: DataCollection) {\n this.trials = this.trials.concat(other_data_collection.values());\n return this;\n }\n\n top() {\n if (this.trials.length <= 1) {\n return this;\n } else {\n return new DataCollection([this.trials[this.trials.length - 1]]);\n }\n }\n\n /**\n * Queries the first n elements in a collection of trials.\n *\n * @param n A positive integer of elements to return. A value of\n * n that is less than 1 will throw an error.\n *\n * @return First n objects of a collection of trials. If fewer than\n * n trials are available, the trials.length elements will\n * be returned.\n *\n */\n first(n = 1) {\n if (n < 1) {\n throw `You must query with a positive nonzero integer. Please use a\n different value for n.`;\n }\n if (this.trials.length === 0) return new DataCollection();\n if (n > this.trials.length) n = this.trials.length;\n return new DataCollection(this.trials.slice(0, n));\n }\n\n /**\n * Queries the last n elements in a collection of trials.\n *\n * @param n A positive integer of elements to return. A value of\n * n that is less than 1 will throw an error.\n *\n * @return Last n objects of a collection of trials. If fewer than\n * n trials are available, the trials.length elements will\n * be returned.\n *\n */\n last(n = 1) {\n if (n < 1) {\n throw `You must query with a positive nonzero integer. Please use a\n different value for n.`;\n }\n if (this.trials.length === 0) return new DataCollection();\n if (n > this.trials.length) n = this.trials.length;\n return new DataCollection(this.trials.slice(this.trials.length - n, this.trials.length));\n }\n\n values() {\n return this.trials;\n }\n\n count() {\n return this.trials.length;\n }\n\n readOnly() {\n return new DataCollection(deepCopy(this.trials));\n }\n\n addToAll(properties) {\n for (const trial of this.trials) {\n Object.assign(trial, properties);\n }\n return this;\n }\n\n addToLast(properties) {\n if (this.trials.length != 0) {\n Object.assign(this.trials[this.trials.length - 1], properties);\n }\n return this;\n }\n\n filter(filters) {\n // [{p1: v1, p2:v2}, {p1:v2}]\n // {p1: v1}\n let f;\n if (!Array.isArray(filters)) {\n f = deepCopy([filters]);\n } else {\n f = deepCopy(filters);\n }\n\n const filtered_data = [];\n for (const trial of this.trials) {\n let keep = false;\n for (const filter of f) {\n let match = true;\n for (const key of Object.keys(filter)) {\n if (typeof trial[key] !== \"undefined\" && trial[key] === filter[key]) {\n // matches on this key!\n } else {\n match = false;\n }\n }\n if (match) {\n keep = true;\n break;\n } // can break because each filter is OR.\n }\n if (keep) {\n filtered_data.push(trial);\n }\n }\n\n return new DataCollection(filtered_data);\n }\n\n filterCustom(fn) {\n return new DataCollection(this.trials.filter(fn));\n }\n\n select(column) {\n const values = [];\n for (const trial of this.trials) {\n if (typeof trial[column] !== \"undefined\") {\n values.push(trial[column]);\n }\n }\n return new DataColumn(values);\n }\n\n ignore(columns) {\n if (!Array.isArray(columns)) {\n columns = [columns];\n }\n const o = deepCopy(this.trials);\n for (const trial of o) {\n for (const delete_key of columns) {\n delete trial[delete_key];\n }\n }\n return new DataCollection(o);\n }\n\n uniqueNames() {\n const names = [];\n\n for (const trial of this.trials) {\n for (const key of Object.keys(trial)) {\n if (!names.includes(key)) {\n names.push(key);\n }\n }\n }\n\n return names;\n }\n\n csv() {\n return JSON2CSV(this.trials);\n }\n\n json(pretty = false) {\n if (pretty) {\n return JSON.stringify(this.trials, null, \"\\t\");\n }\n return JSON.stringify(this.trials);\n }\n\n localSave(format, filename) {\n format = format.toLowerCase();\n let data_string;\n if (format === \"json\") {\n data_string = this.json();\n } else if (format === \"csv\") {\n data_string = this.csv();\n } else {\n throw new Error('Invalid format specified for localSave. Must be \"json\" or \"csv\".');\n }\n\n saveTextToFile(data_string, filename);\n }\n}\n","// private function to save text file on local drive\nexport function saveTextToFile(textstr: string, filename: string) {\n const blobToSave = new Blob([textstr], {\n type: \"text/plain\",\n });\n let blobURL = \"\";\n if (typeof window.webkitURL !== \"undefined\") {\n blobURL = window.webkitURL.createObjectURL(blobToSave);\n } else {\n blobURL = window.URL.createObjectURL(blobToSave);\n }\n\n const link = document.createElement(\"a\");\n link.id = \"jspsych-download-as-text-link\";\n link.style.display = \"none\";\n link.download = filename;\n link.href = blobURL;\n link.click();\n}\n\n// this function based on code suggested by StackOverflow users:\n// http://stackoverflow.com/users/64741/zachary\n// http://stackoverflow.com/users/317/joseph-sturtevant\n\nexport function JSON2CSV(objArray) {\n const array = typeof objArray != \"object\" ? JSON.parse(objArray) : objArray;\n let line = \"\";\n let result = \"\";\n const columns = [];\n\n for (const row of array) {\n for (const key in row) {\n let keyString = key + \"\";\n keyString = '\"' + keyString.replace(/\"/g, '\"\"') + '\",';\n if (!columns.includes(key)) {\n columns.push(key);\n line += keyString;\n }\n }\n }\n\n line = line.slice(0, -1); // removes last comma\n result += line + \"\\r\\n\";\n\n for (const row of array) {\n line = \"\";\n for (const col of columns) {\n let value = typeof row[col] === \"undefined\" ? \"\" : row[col];\n if (typeof value == \"object\") {\n value = JSON.stringify(value);\n }\n const valueString = value + \"\";\n line += '\"' + valueString.replace(/\"/g, '\"\"') + '\",';\n }\n\n line = line.slice(0, -1);\n result += line + \"\\r\\n\";\n }\n\n return result;\n}\n\n// this function is modified from StackOverflow:\n// http://stackoverflow.com/posts/3855394\n\nexport function getQueryString() {\n const a = window.location.search.substr(1).split(\"&\");\n const b = {};\n for (let i = 0; i < a.length; ++i) {\n const p = a[i].split(\"=\", 2);\n if (p.length == 1) b[p[0]] = \"\";\n else b[p[0]] = decodeURIComponent(p[1].replace(/\\+/g, \" \"));\n }\n return b;\n}\n","import { JsPsych } from \"../../JsPsych\";\nimport { DataCollection } from \"./DataCollection\";\nimport { getQueryString } from \"./utils\";\n\nexport class JsPsychData {\n // data storage object\n private allData: DataCollection;\n\n // browser interaction event data\n private interactionData: DataCollection;\n\n // data properties for all trials\n private dataProperties = {};\n\n // cache the query_string\n private query_string;\n\n constructor(private jsPsych: JsPsych) {\n this.reset();\n }\n\n reset() {\n this.allData = new DataCollection();\n this.interactionData = new DataCollection();\n }\n\n get() {\n return this.allData;\n }\n\n getInteractionData() {\n return this.interactionData;\n }\n\n write(data_object) {\n const progress = this.jsPsych.getProgress();\n const trial = this.jsPsych.getCurrentTrial();\n\n //var trial_opt_data = typeof trial.data == 'function' ? trial.data() : trial.data;\n\n const default_data = {\n trial_type: trial.type.info.name,\n trial_index: progress.current_trial_global,\n time_elapsed: this.jsPsych.getTotalTime(),\n internal_node_id: this.jsPsych.getCurrentTimelineNodeID(),\n };\n\n this.allData.push({\n ...data_object,\n ...trial.data,\n ...default_data,\n ...this.dataProperties,\n });\n }\n\n addProperties(properties) {\n // first, add the properties to all data that's already stored\n this.allData.addToAll(properties);\n\n // now add to list so that it gets appended to all future data\n this.dataProperties = Object.assign({}, this.dataProperties, properties);\n }\n\n addDataToLastTrial(data) {\n this.allData.addToLast(data);\n }\n\n getDataByTimelineNode(node_id) {\n return this.allData.filterCustom(\n (x) => x.internal_node_id.slice(0, node_id.length) === node_id\n );\n }\n\n getLastTrialData() {\n return this.allData.top();\n }\n\n getLastTimelineData() {\n const lasttrial = this.getLastTrialData();\n const node_id = lasttrial.select(\"internal_node_id\").values[0];\n if (typeof node_id === \"undefined\") {\n return new DataCollection();\n } else {\n const parent_node_id = node_id.substr(0, node_id.lastIndexOf(\"-\"));\n const lastnodedata = this.getDataByTimelineNode(parent_node_id);\n return lastnodedata;\n }\n }\n\n displayData(format = \"json\") {\n format = format.toLowerCase();\n if (format != \"json\" && format != \"csv\") {\n console.log(\"Invalid format declared for displayData function. Using json as default.\");\n format = \"json\";\n }\n\n const data_string = format === \"json\" ? this.allData.json(true) : this.allData.csv();\n\n const display_element = this.jsPsych.getDisplayElement();\n\n display_element.innerHTML = '<pre id=\"jspsych-data-display\"></pre>';\n\n document.getElementById(\"jspsych-data-display\").textContent = data_string;\n }\n\n urlVariables() {\n if (typeof this.query_string == \"undefined\") {\n this.query_string = getQueryString();\n }\n return this.query_string;\n }\n\n getURLVariable(whichvar) {\n return this.urlVariables()[whichvar];\n }\n\n createInteractionListeners() {\n // blur event capture\n window.addEventListener(\"blur\", () => {\n const data = {\n event: \"blur\",\n trial: this.jsPsych.getProgress().current_trial_global,\n time: this.jsPsych.getTotalTime(),\n };\n this.interactionData.push(data);\n this.jsPsych.getInitSettings().on_interaction_data_update(data);\n });\n\n // focus event capture\n window.addEventListener(\"focus\", () => {\n const data = {\n event: \"focus\",\n trial: this.jsPsych.getProgress().current_trial_global,\n time: this.jsPsych.getTotalTime(),\n };\n this.interactionData.push(data);\n this.jsPsych.getInitSettings().on_interaction_data_update(data);\n });\n\n // fullscreen change capture\n const fullscreenchange = () => {\n const data = {\n event:\n // @ts-expect-error\n document.isFullScreen ||\n // @ts-expect-error\n document.webkitIsFullScreen ||\n // @ts-expect-error\n document.mozIsFullScreen ||\n document.fullscreenElement\n ? \"fullscreenenter\"\n : \"fullscreenexit\",\n trial: this.jsPsych.getProgress().current_trial_global,\n time: this.jsPsych.getTotalTime(),\n };\n this.interactionData.push(data);\n this.jsPsych.getInitSettings().on_interaction_data_update(data);\n };\n\n document.addEventListener(\"fullscreenchange\", fullscreenchange);\n document.addEventListener(\"mozfullscreenchange\", fullscreenchange);\n document.addEventListener(\"webkitfullscreenchange\", fullscreenchange);\n }\n\n // public methods for testing purposes. not recommended for use.\n _customInsert(data) {\n this.allData = new DataCollection(data);\n }\n\n _fullreset() {\n this.reset();\n this.dataProperties = {};\n }\n}\n","export class HardwareAPI {\n /**\n * Indicates whether this instance of jspsych has opened a hardware connection through our browser\n * extension\n **/\n hardwareConnected = false;\n\n constructor() {\n //it might be useful to open up a line of communication from the extension back to this page\n //script, again, this will have to pass through DOM events. For now speed is of no concern so I\n //will use jQuery\n document.addEventListener(\"jspsych-activate\", (evt) => {\n this.hardwareConnected = true;\n });\n }\n\n /**\n * Allows communication with user hardware through our custom Google Chrome extension + native C++ program\n * @param\t\tmess\tThe message to be passed to our extension, see its documentation for the expected members of this object.\n * @author\tDaniel Rivas\n *\n */\n hardware(mess) {\n //since Chrome extension content-scripts do not share the javascript environment with the page\n //script that loaded jspsych, we will need to use hacky methods like communicating through DOM\n //events.\n const jspsychEvt = new CustomEvent(\"jspsych\", { detail: mess });\n document.dispatchEvent(jspsychEvt);\n //And voila! it will be the job of the content script injected by the extension to listen for\n //the event and do the appropriate actions.\n }\n}\n","import autoBind from \"auto-bind\";\n\nexport type KeyboardListener = (e: KeyboardEvent) => void;\n\nexport type ValidResponses = string[] | \"ALL_KEYS\" | \"NO_KEYS\";\n\nexport interface GetKeyboardResponseOptions {\n callback_function: any;\n valid_responses?: ValidResponses;\n rt_method?: \"performance\" | \"audio\";\n persist?: boolean;\n audio_context?: AudioContext;\n audio_context_start_time?: number;\n allow_held_key?: boolean;\n minimum_valid_rt?: number;\n}\n\nexport class KeyboardListenerAPI {\n constructor(\n private getRootElement: () => Element | undefined,\n private areResponsesCaseSensitive: boolean = false,\n private minimumValidRt = 0\n ) {\n autoBind(this);\n this.registerRootListeners();\n }\n\n private listeners = new Set<KeyboardListener>();\n private heldKeys = new Set<string>();\n\n private areRootListenersRegistered = false;\n\n /**\n * If not previously done and `this.getRootElement()` returns an element, adds the root key\n * listeners to that element.\n */\n private registerRootListeners() {\n if (!this.areRootListenersRegistered) {\n const rootElement = this.getRootElement();\n if (rootElement) {\n rootElement.addEventListener(\"keydown\", this.rootKeydownListener);\n rootElement.addEventListener(\"keyup\", this.rootKeyupListener);\n this.areRootListenersRegistered = true;\n }\n }\n }\n\n private rootKeydownListener(e: KeyboardEvent) {\n // Iterate over a static copy of the listeners set because listeners might add other listeners\n // that we do not want to be included in the loop\n for (const listener of Array.from(this.listeners)) {\n listener(e);\n }\n this.heldKeys.add(this.toLowerCaseIfInsensitive(e.key));\n }\n\n private toLowerCaseIfInsensitive(string: string) {\n return this.areResponsesCaseSensitive ? string : string.toLowerCase();\n }\n\n private rootKeyupListener(e: KeyboardEvent) {\n this.heldKeys.delete(this.toLowerCaseIfInsensitive(e.key));\n }\n\n private isResponseValid(validResponses: ValidResponses, allowHeldKey: boolean, key: string) {\n // check if key was already held down\n if (!allowHeldKey && this.heldKeys.has(key)) {\n return false;\n }\n\n if (validResponses === \"ALL_KEYS\") {\n return true;\n }\n if (validResponses === \"NO_KEYS\") {\n return false;\n }\n\n return validResponses.includes(key);\n }\n\n getKeyboardResponse({\n callback_function,\n valid_responses = \"ALL_KEYS\",\n rt_method = \"performance\",\n persist,\n audio_context,\n audio_context_start_time,\n allow_held_key = false,\n minimum_valid_rt = this.minimumValidRt,\n }: GetKeyboardResponseOptions) {\n if (rt_method !== \"performance\" && rt_method !== \"audio\") {\n console.log(\n 'Invalid RT method specified in getKeyboardResponse. Defaulting to \"performance\" method.'\n );\n rt_method = \"performance\";\n }\n\n const usePerformanceRt = rt_method === \"performance\";\n const startTime = usePerformanceRt ? performance.now() : audio_context_start_time * 1000;\n\n this.registerRootListeners();\n\n if (!this.areResponsesCaseSensitive && typeof valid_responses !== \"string\") {\n valid_responses = valid_responses.map((r) => r.toLowerCase());\n }\n\n const listener: KeyboardListener = (e) => {\n const rt = Math.round(\n (rt_method == \"performance\" ? performance.now() : audio_context.currentTime * 1000) -\n startTime\n );\n if (rt < minimum_valid_rt) {\n return;\n }\n\n const key = this.toLowerCaseIfInsensitive(e.key);\n\n if (this.isResponseValid(valid_responses, allow_held_key, key)) {\n // if this is a valid response, then we don't want the key event to trigger other actions\n // like scrolling via the spacebar.\n e.preventDefault();\n\n if (!persist) {\n // remove keyboard listener if it exists\n this.cancelKeyboardResponse(listener);\n }\n\n callback_function({ key, rt });\n }\n };\n\n this.listeners.add(listener);\n return listener;\n }\n\n cancelKeyboardResponse(listener: KeyboardListener) {\n // remove the listener from the set of listeners if it is contained\n this.listeners.delete(listener);\n }\n\n cancelAllKeyboardResponses() {\n this.listeners.clear();\n }\n\n compareKeys(key1: string | null, key2: string | null) {\n if (\n (typeof key1 !== \"string\" && key1 !== null) ||\n (typeof key2 !== \"string\" && key2 !== null)\n ) {\n console.error(\n \"Error in jsPsych.pluginAPI.compareKeys: arguments must be key strings or null.\"\n );\n return undefined;\n }\n\n if (typeof key1 === \"string\" && typeof key2 === \"string\") {\n // if both values are strings, then check whether or not letter case should be converted before comparing (case_sensitive_responses in initJsPsych)\n return this.areResponsesCaseSensitive\n ? key1 === key2\n : key1.toLowerCase() === key2.toLowerCase();\n }\n\n return key1 === null && key2 === null;\n }\n}\n","import { ParameterType } from \"../../modules/plugins\";\nimport { unique } from \"../utils\";\n\nconst preloadParameterTypes = <const>[\n ParameterType.AUDIO,\n ParameterType.IMAGE,\n ParameterType.VIDEO,\n];\ntype PreloadType = typeof preloadParameterTypes[number];\n\nexport class MediaAPI {\n constructor(private useWebaudio: boolean, private webaudioContext?: AudioContext) {}\n\n // video //\n private video_buffers = {};\n getVideoBuffer(videoID) {\n return this.video_buffers[videoID];\n }\n\n // audio //\n private context = null;\n private audio_buffers = [];\n\n initAudio() {\n this.context = this.useWebaudio ? this.webaudioContext : null;\n }\n\n audioContext() {\n if (this.context !== null) {\n if (this.context.state !== \"running\") {\n this.context.resume();\n }\n }\n return this.context;\n }\n\n getAudioBuffer(audioID) {\n return new Promise((resolve, reject) => {\n // check whether audio file already preloaded\n if (\n typeof this.audio_buffers[audioID] == \"undefined\" ||\n this.audio_buffers[audioID] == \"tmp\"\n ) {\n // if audio is not already loaded, try to load it\n this.preloadAudio(\n [audioID],\n () => {\n resolve(this.audio_buffers[audioID]);\n },\n () => {},\n (e) => {\n reject(e.error);\n }\n );\n } else {\n // audio is already loaded\n resolve(this.audio_buffers[audioID]);\n }\n });\n }\n\n // preloading stimuli //\n private preload_requests = [];\n\n private img_cache = {};\n\n preloadAudio(\n files,\n callback_complete = () => {},\n callback_load = (filepath) => {},\n callback_error = (error_msg) => {}\n ) {\n files = unique(files.flat());\n\n let n_loaded = 0;\n\n if (files.length == 0) {\n callback_complete();\n return;\n }\n\n const load_audio_file_webaudio = (source, count = 1) => {\n const request = new XMLHttpRequest();\n request.open(\"GET\", source, true);\n request.responseType = \"arraybuffer\";\n request.onload = () => {\n this.context.decodeAudioData(\n request.response,\n (buffer) => {\n this.audio_buffers[source] = buffer;\n n_loaded++;\n callback_load(source);\n if (n_loaded == files.length) {\n callback_complete();\n }\n },\n (e) => {\n callback_error({ source: source, error: e });\n }\n );\n };\n request.onerror = function (e) {\n let err: ProgressEvent | string = e;\n if (this.status == 404) {\n err = \"404\";\n }\n callback_error({ source: source, error: err });\n };\n request.onloadend = function (e) {\n if (this.status == 404) {\n callback_error({ source: source, error: \"404\" });\n }\n };\n request.send();\n this.preload_requests.push(request);\n };\n\n const load_audio_file_html5audio = (source, count = 1) => {\n const audio = new Audio();\n const handleCanPlayThrough = () => {\n this.audio_buffers[source] = audio;\n n_loaded++;\n callback_load(source);\n if (n_loaded == files.length) {\n callback_complete();\n }\n audio.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n };\n audio.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n audio.addEventListener(\"error\", function handleError(e) {\n callback_error({ source: audio.src, error: e });\n audio.removeEventListener(\"error\", handleError);\n });\n audio.addEventListener(\"abort\", function handleAbort(e) {\n callback_error({ source: audio.src, error: e });\n audio.removeEventListener(\"abort\", handleAbort);\n });\n audio.src = source;\n this.preload_requests.push(audio);\n };\n\n for (const file of files) {\n if (typeof this.audio_buffers[file] !== \"undefined\") {\n n_loaded++;\n callback_load(file);\n if (n_loaded == files.length) {\n callback_complete();\n }\n } else {\n this.audio_buffers[file] = \"tmp\";\n if (this.audioContext() !== null) {\n load_audio_file_webaudio(file);\n } else {\n load_audio_file_html5audio(file);\n }\n }\n }\n }\n\n preloadImages(\n images,\n callback_complete = () => {},\n callback_load = (filepath) => {},\n callback_error = (error_msg) => {}\n ) {\n // flatten the images array\n images = unique(images.flat());\n\n var n_loaded = 0;\n\n if (images.length === 0) {\n callback_complete();\n return;\n }\n\n for (var i = 0; i < images.length; i++) {\n var img = new Image();\n\n img.onload = function () {\n n_loaded++;\n callback_load(img.src);\n if (n_loaded === images.length) {\n callback_complete();\n }\n };\n\n img.onerror = function (e) {\n callback_error({ source: img.src, error: e });\n };\n\n img.src = images[i];\n\n this.img_cache[images[i]] = img;\n this.preload_requests.push(img);\n }\n }\n\n preloadVideo(\n videos,\n callback_complete = () => {},\n callback_load = (filepath) => {},\n callback_error = (error_msg) => {}\n ) {\n // flatten the video array\n videos = unique(videos.flat());\n\n let n_loaded = 0;\n\n if (videos.length === 0) {\n callback_complete();\n return;\n }\n\n for (const video of videos) {\n const video_buffers = this.video_buffers;\n\n //based on option 4 here: http://dinbror.dk/blog/how-to-preload-entire-html5-video-before-play-solved/\n const request = new XMLHttpRequest();\n request.open(\"GET\", video, true);\n request.responseType = \"blob\";\n request.onload = function () {\n if (this.status === 200 || this.status === 0) {\n const videoBlob = this.response;\n video_buffers[video] = URL.createObjectURL(videoBlob); // IE10+\n n_loaded++;\n callback_load(video);\n if (n_loaded === videos.length) {\n callback_complete();\n }\n }\n };\n request.onerror = function (e) {\n let err: ProgressEvent | string = e;\n if (this.status == 404) {\n err = \"404\";\n }\n callback_error({ source: video, error: err });\n };\n request.onloadend = function (e) {\n if (this.status == 404) {\n callback_error({ source: video, error: \"404\" });\n }\n };\n request.send();\n this.preload_requests.push(request);\n }\n }\n\n private preloadMap = new Map<string, Record<string, PreloadType>>();\n\n getAutoPreloadList(timeline_description: any[]) {\n /** Map each preload parameter type to a set of paths to be preloaded */\n const preloadPaths = Object.fromEntries(\n preloadParameterTypes.map((type) => [type, new Set<string>()])\n );\n\n const traverseTimeline = (node, inheritedTrialType?) => {\n const isTimeline = typeof node.timeline !== \"undefined\";\n\n if (isTimeline) {\n for (const childNode of node.timeline) {\n traverseTimeline(childNode, node.type ?? inheritedTrialType);\n }\n } else if ((node.type ?? inheritedTrialType)?.info) {\n // node is a trial with type.info set\n\n // Get the plugin name and parameters object from the info object\n const { name: pluginName, parameters } = (node.type ?? inheritedTrialType).info;\n\n // Extract parameters to be preloaded and their types from parameter info if this has not\n // yet been done for `pluginName`\n if (!this.preloadMap.has(pluginName)) {\n this.preloadMap.set(\n pluginName,\n Object.fromEntries(\n Object.entries<any>(parameters)\n // Filter out parameter entries with media types and a non-false `preload` option\n .filter(\n ([_name, { type, preload }]) =>\n preloadParameterTypes.includes(type) && (preload ?? true)\n )\n // Map each entry's value to its parameter type\n .map(([name, { type }]) => [name, type])\n )\n );\n }\n\n // Add preload paths from this trial\n for (const [parameterName, parameterType] of Object.entries(\n this.preloadMap.get(pluginName)\n )) {\n const parameterValue = node[parameterName];\n const elements = preloadPaths[parameterType];\n\n if (typeof parameterValue === \"string\") {\n elements.add(parameterValue);\n } else if (Array.isArray(parameterValue)) {\n for (const element of parameterValue.flat()) {\n if (typeof element === \"string\") {\n elements.add(element);\n }\n }\n }\n }\n }\n };\n\n traverseTimeline({ timeline: timeline_description });\n\n return {\n images: [...preloadPaths[ParameterType.IMAGE]],\n audio: [...preloadPaths[ParameterType.AUDIO]],\n video: [...preloadPaths[ParameterType.VIDEO]],\n };\n }\n\n cancelPreloads() {\n for (const request of this.preload_requests) {\n request.onload = () => {};\n request.onerror = () => {};\n request.oncanplaythrough = () => {};\n request.onabort = () => {};\n }\n this.preload_requests = [];\n }\n\n private microphone_recorder: MediaRecorder = null;\n\n initializeMicrophoneRecorder(stream: MediaStream) {\n const recorder = new MediaRecorder(stream);\n this.microphone_recorder = recorder;\n }\n\n getMicrophoneRecorder(): MediaRecorder {\n return this.microphone_recorder;\n }\n}\n","export class SimulationAPI {\n dispatchEvent(event: Event) {\n document.body.dispatchEvent(event);\n }\n\n /**\n * Dispatches a `keydown` event for the specified key\n * @param key Character code (`.key` property) for the key to press.\n */\n keyDown(key: string) {\n this.dispatchEvent(new KeyboardEvent(\"keydown\", { key }));\n }\n\n /**\n * Dispatches a `keyup` event for the specified key\n * @param key Character code (`.key` property) for the key to press.\n */\n keyUp(key: string) {\n this.dispatchEvent(new KeyboardEvent(\"keyup\", { key }));\n }\n\n /**\n * Dispatches a `keydown` and `keyup` event in sequence to simulate pressing a key.\n * @param key Character code (`.key` property) for the key to press.\n * @param delay Length of time to wait (ms) before executing action\n */\n pressKey(key: string, delay = 0) {\n if (delay > 0) {\n setTimeout(() => {\n this.keyDown(key);\n this.keyUp(key);\n }, delay);\n } else {\n this.keyDown(key);\n this.keyUp(key);\n }\n }\n\n /**\n * Dispatches `mousedown`, `mouseup`, and `click` events on the target element\n * @param target The element to click\n * @param delay Length of time to wait (ms) before executing action\n */\n clickTarget(target: Element, delay = 0) {\n if (delay > 0) {\n setTimeout(() => {\n target.dispatchEvent(new MouseEvent(\"mousedown\", { bubbles: true }));\n target.dispatchEvent(new MouseEvent(\"mouseup\", { bubbles: true }));\n target.dispatchEvent(new MouseEvent(\"click\", { bubbles: true }));\n }, delay);\n } else {\n target.dispatchEvent(new MouseEvent(\"mousedown\", { bubbles: true }));\n target.dispatchEvent(new MouseEvent(\"mouseup\", { bubbles: true }));\n target.dispatchEvent(new MouseEvent(\"click\", { bubbles: true }));\n }\n }\n\n /**\n * Sets the value of a target text input\n * @param target A text input element to fill in\n * @param text Text to input\n * @param delay Length of time to wait (ms) before executing action\n */\n fillTextInput(target: HTMLInputElement, text: string, delay = 0) {\n if (delay > 0) {\n setTimeout(() => {\n target.value = text;\n }, delay);\n } else {\n target.value = text;\n }\n }\n\n /**\n * Picks a valid key from `choices`, taking into account jsPsych-specific\n * identifiers like \"NO_KEYS\" and \"ALL_KEYS\".\n * @param choices Which keys are valid.\n * @returns A key selected at random from the valid keys.\n */\n getValidKey(choices: \"NO_KEYS\" | \"ALL_KEYS\" | Array<string> | Array<Array<string>>) {\n const possible_keys = [\n \"a\",\n \"b\",\n \"c\",\n \"d\",\n \"e\",\n \"f\",\n \"g\",\n \"h\",\n \"i\",\n \"j\",\n \"k\",\n \"l\",\n \"m\",\n \"n\",\n \"o\",\n \"p\",\n \"q\",\n \"r\",\n \"s\",\n \"t\",\n \"u\",\n \"v\",\n \"w\",\n \"x\",\n \"y\",\n \"z\",\n \"0\",\n \"1\",\n \"2\",\n \"3\",\n \"4\",\n \"5\",\n \"6\",\n \"7\",\n \"8\",\n \"9\",\n \" \",\n ];\n\n let key;\n if (choices == \"NO_KEYS\") {\n key = null;\n } else if (choices == \"ALL_KEYS\") {\n key = possible_keys[Math.floor(Math.random() * possible_keys.length)];\n } else {\n const flat_choices = choices.flat();\n key = flat_choices[Math.floor(Math.random() * flat_choices.length)];\n }\n\n return key;\n }\n\n mergeSimulationData(default_data, simulation_options) {\n // override any data with data from simulation object\n return {\n ...default_data,\n ...simulation_options?.data,\n };\n }\n\n ensureSimulationDataConsistency(trial, data) {\n // All RTs must be rounded\n if (data.rt) {\n data.rt = Math.round(data.rt);\n }\n\n // If a trial_duration and rt exist, make sure that the RT is not longer than the trial.\n if (trial.trial_duration && data.rt && data.rt > trial.trial_duration) {\n data.rt = null;\n if (data.response) {\n data.response = null;\n }\n if (data.correct) {\n data.correct = false;\n }\n }\n\n // If trial.choices is NO_KEYS make sure that response and RT are null\n if (trial.choices && trial.choices == \"NO_KEYS\") {\n if (data.rt) {\n data.rt = null;\n }\n if (data.response) {\n data.response = null;\n }\n }\n\n // If response is not allowed before stimulus display complete, ensure RT\n // is longer than display time.\n if (trial.allow_response_before_complete) {\n if (trial.sequence_reps && trial.frame_time) {\n const min_time = trial.sequence_reps * trial.frame_time * trial.stimuli.length;\n if (data.rt < min_time) {\n data.rt = null;\n data.response = null;\n }\n }\n }\n }\n}\n","export class TimeoutAPI {\n private timeout_handlers = [];\n\n setTimeout(callback, delay) {\n const handle = window.setTimeout(callback, delay);\n this.timeout_handlers.push(handle);\n return handle;\n }\n\n clearAllTimeouts() {\n for (const handler of this.timeout_handlers) {\n clearTimeout(handler);\n }\n this.timeout_handlers = [];\n }\n}\n","var wordList = [\n // Borrowed from xkcd password generator which borrowed it from wherever\n \"ability\",\"able\",\"aboard\",\"about\",\"above\",\"accept\",\"accident\",\"according\",\n \"account\",\"accurate\",\"acres\",\"across\",\"act\",\"action\",\"active\",\"activity\",\n \"actual\",\"actually\",\"add\",\"addition\",\"additional\",\"adjective\",\"adult\",\"adventure\",\n \"advice\",\"affect\",\"afraid\",\"after\",\"afternoon\",\"again\",\"against\",\"age\",\n \"ago\",\"agree\",\"ahead\",\"aid\",\"air\",\"airplane\",\"alike\",\"alive\",\n \"all\",\"allow\",\"almost\",\"alone\",\"along\",\"aloud\",\"alphabet\",\"already\",\n \"also\",\"although\",\"am\",\"among\",\"amount\",\"ancient\",\"angle\",\"angry\",\n \"animal\",\"announced\",\"another\",\"answer\",\"ants\",\"any\",\"anybody\",\"anyone\",\n \"anything\",\"anyway\",\"anywhere\",\"apart\",\"apartment\",\"appearance\",\"apple\",\"applied\",\n \"appropriate\",\"are\",\"area\",\"arm\",\"army\",\"around\",\"arrange\",\"arrangement\",\n \"arrive\",\"arrow\",\"art\",\"article\",\"as\",\"aside\",\"ask\",\"asleep\",\n \"at\",\"ate\",\"atmosphere\",\"atom\",\"atomic\",\"attached\",\"attack\",\"attempt\",\n \"attention\",\"audience\",\"author\",\"automobile\",\"available\",\"average\",\"avoid\",\"aware\",\n \"away\",\"baby\",\"back\",\"bad\",\"badly\",\"bag\",\"balance\",\"ball\",\n \"balloon\",\"band\",\"bank\",\"bar\",\"bare\",\"bark\",\"barn\",\"base\",\n \"baseball\",\"basic\",\"basis\",\"basket\",\"bat\",\"battle\",\"be\",\"bean\",\n \"bear\",\"beat\",\"beautiful\",\"beauty\",\"became\",\"because\",\"become\",\"becoming\",\n \"bee\",\"been\",\"before\",\"began\",\"beginning\",\"begun\",\"behavior\",\"behind\",\n \"being\",\"believed\",\"bell\",\"belong\",\"below\",\"belt\",\"bend\",\"beneath\",\n \"bent\",\"beside\",\"best\",\"bet\",\"better\",\"between\",\"beyond\",\"bicycle\",\n \"bigger\",\"biggest\",\"bill\",\"birds\",\"birth\",\"birthday\",\"bit\",\"bite\",\n \"black\",\"blank\",\"blanket\",\"blew\",\"blind\",\"block\",\"blood\",\"blow\",\n \"blue\",\"board\",\"boat\",\"body\",\"bone\",\"book\",\"border\",\"born\",\n \"both\",\"bottle\",\"bottom\",\"bound\",\"bow\",\"bowl\",\"box\",\"boy\",\n \"brain\",\"branch\",\"brass\",\"brave\",\"bread\",\"break\",\"breakfast\",\"breath\",\n \"breathe\",\"breathing\",\"breeze\",\"brick\",\"bridge\",\"brief\",\"bright\",\"bring\",\n \"broad\",\"broke\",\"broken\",\"brother\",\"brought\",\"brown\",\"brush\",\"buffalo\",\n \"build\",\"building\",\"built\",\"buried\",\"burn\",\"burst\",\"bus\",\"bush\",\n \"business\",\"busy\",\"but\",\"butter\",\"buy\",\"by\",\"cabin\",\"cage\",\n \"cake\",\"call\",\"calm\",\"came\",\"camera\",\"camp\",\"can\",\"canal\",\n \"cannot\",\"cap\",\"capital\",\"captain\",\"captured\",\"car\",\"carbon\",\"card\",\n \"care\",\"careful\",\"carefully\",\"carried\",\"carry\",\"case\",\"cast\",\"castle\",\n \"cat\",\"catch\",\"cattle\",\"caught\",\"cause\",\"cave\",\"cell\",\"cent\",\n \"center\",\"central\",\"century\",\"certain\",\"certainly\",\"chain\",\"chair\",\"chamber\",\n \"chance\",\"change\",\"changing\",\"chapter\",\"character\",\"characteristic\",\"charge\",\"chart\",\n \"check\",\"cheese\",\"chemical\",\"chest\",\"chicken\",\"chief\",\"child\",\"children\",\n \"choice\",\"choose\",\"chose\",\"chosen\",\"church\",\"circle\",\"circus\",\"citizen\",\n \"city\",\"class\",\"classroom\",\"claws\",\"clay\",\"clean\",\"clear\",\"clearly\",\n \"climate\",\"climb\",\"clock\",\"close\",\"closely\",\"closer\",\"cloth\",\"clothes\",\n \"clothing\",\"cloud\",\"club\",\"coach\",\"coal\",\"coast\",\"coat\",\"coffee\",\n \"cold\",\"collect\",\"college\",\"colony\",\"color\",\"column\",\"combination\",\"combine\",\n \"come\",\"comfortable\",\"coming\",\"command\",\"common\",\"community\",\"company\",\"compare\",\n \"compass\",\"complete\",\"completely\",\"complex\",\"composed\",\"composition\",\"compound\",\"concerned\",\n \"condition\",\"congress\",\"connected\",\"consider\",\"consist\",\"consonant\",\"constantly\",\"construction\",\n \"contain\",\"continent\",\"continued\",\"contrast\",\"control\",\"conversation\",\"cook\",\"cookies\",\n \"cool\",\"copper\",\"copy\",\"corn\",\"corner\",\"correct\",\"correctly\",\"cost\",\n \"cotton\",\"could\",\"count\",\"country\",\"couple\",\"courage\",\"course\",\"court\",\n \"cover\",\"cow\",\"cowboy\",\"crack\",\"cream\",\"create\",\"creature\",\"crew\",\n \"crop\",\"cross\",\"crowd\",\"cry\",\"cup\",\"curious\",\"current\",\"curve\",\n \"customs\",\"cut\",\"cutting\",\"daily\",\"damage\",\"dance\",\"danger\",\"dangerous\",\n \"dark\",\"darkness\",\"date\",\"daughter\",\"dawn\",\"day\",\"dead\",\"deal\",\n \"dear\",\"death\",\"decide\",\"declared\",\"deep\",\"deeply\",\"deer\",\"definition\",\n \"degree\",\"depend\",\"depth\",\"describe\",\"desert\",\"design\",\"desk\",\"detail\",\n \"determine\",\"develop\",\"development\",\"diagram\",\"diameter\",\"did\",\"die\",\"differ\",\n \"difference\",\"different\",\"difficult\",\"difficulty\",\"dig\",\"dinner\",\"direct\",\"direction\",\n \"directly\",\"dirt\",\"dirty\",\"disappear\",\"discover\",\"discovery\",\"discuss\",\"discussion\",\n \"disease\",\"dish\",\"distance\",\"distant\",\"divide\",\"division\",\"do\",\"doctor\",\n \"does\",\"dog\",\"doing\",\"doll\",\"dollar\",\"done\",\"donkey\",\"door\",\n \"dot\",\"double\",\"doubt\",\"down\",\"dozen\",\"draw\",\"drawn\",\"dream\",\n \"dress\",\"drew\",\"dried\",\"drink\",\"drive\",\"driven\",\"driver\",\"driving\",\n \"drop\",\"dropped\",\"drove\",\"dry\",\"duck\",\"due\",\"dug\",\"dull\",\n \"during\",\"dust\",\"duty\",\"each\",\"eager\",\"ear\",\"earlier\",\"early\",\n \"earn\",\"earth\",\"easier\",\"easily\",\"east\",\"easy\",\"eat\",\"eaten\",\n \"edge\",\"education\",\"effect\",\"effort\",\"egg\",\"eight\",\"either\",\"electric\",\n \"electricity\",\"element\",\"elephant\",\"eleven\",\"else\",\"empty\",\"end\",\"enemy\",\n \"energy\",\"engine\",\"engineer\",\"enjoy\",\"enough\",\"enter\",\"entire\",\"entirely\",\n \"environment\",\"equal\",\"equally\",\"equator\",\"equipment\",\"escape\",\"especially\",\"essential\",\n \"establish\",\"even\",\"evening\",\"event\",\"eventually\",\"ever\",\"every\",\"everybody\",\n \"everyone\",\"everything\",\"everywhere\",\"evidence\",\"exact\",\"exactly\",\"examine\",\"example\",\n \"excellent\",\"except\",\"exchange\",\"excited\",\"excitement\",\"exciting\",\"exclaimed\",\"exercise\",\n \"exist\",\"expect\",\"experience\",\"experiment\",\"explain\",\"explanation\",\"explore\",\"express\",\n \"expression\",\"extra\",\"eye\",\"face\",\"facing\",\"fact\",\"factor\",\"factory\",\n \"failed\",\"fair\",\"fairly\",\"fall\",\"fallen\",\"familiar\",\"family\",\"famous\",\n \"far\",\"farm\",\"farmer\",\"farther\",\"fast\",\"fastened\",\"faster\",\"fat\",\n \"father\",\"favorite\",\"fear\",\"feathers\",\"feature\",\"fed\",\"feed\",\"feel\",\n \"feet\",\"fell\",\"fellow\",\"felt\",\"fence\",\"few\",\"fewer\",\"field\",\n \"fierce\",\"fifteen\",\"fifth\",\"fifty\",\"fight\",\"fighting\",\"figure\",\"fill\",\n \"film\",\"final\",\"finally\",\"find\",\"fine\",\"finest\",\"finger\",\"finish\",\n \"fire\",\"fireplace\",\"firm\",\"first\",\"fish\",\"five\",\"fix\",\"flag\",\n \"flame\",\"flat\",\"flew\",\"flies\",\"flight\",\"floating\",\"floor\",\"flow\",\n \"flower\",\"fly\",\"fog\",\"folks\",\"follow\",\"food\",\"foot\",\"football\",\n \"for\",\"force\",\"foreign\",\"forest\",\"forget\",\"forgot\",\"forgotten\",\"form\",\n \"former\",\"fort\",\"forth\",\"forty\",\"forward\",\"fought\",\"found\",\"four\",\n \"fourth\",\"fox\",\"frame\",\"free\",\"freedom\",\"frequently\",\"fresh\",\"friend\",\n \"friendly\",\"frighten\",\"frog\",\"from\",\"front\",\"frozen\",\"fruit\",\"fuel\",\n \"full\",\"fully\",\"fun\",\"function\",\"funny\",\"fur\",\"furniture\",\"further\",\n \"future\",\"gain\",\"game\",\"garage\",\"garden\",\"gas\",\"gasoline\",\"gate\",\n \"gather\",\"gave\",\"general\",\"generally\",\"gentle\",\"gently\",\"get\",\"getting\",\n \"giant\",\"gift\",\"girl\",\"give\",\"given\",\"giving\",\"glad\",\"glass\",\n \"globe\",\"go\",\"goes\",\"gold\",\"golden\",\"gone\",\"good\",\"goose\",\n \"got\",\"government\",\"grabbed\",\"grade\",\"gradually\",\"grain\",\"grandfather\",\"grandmother\",\n \"graph\",\"grass\",\"gravity\",\"gray\",\"great\",\"greater\",\"greatest\",\"greatly\",\n \"green\",\"grew\",\"ground\",\"group\",\"grow\",\"grown\",\"growth\",\"guard\",\n \"guess\",\"guide\",\"gulf\",\"gun\",\"habit\",\"had\",\"hair\",\"half\",\n \"halfway\",\"hall\",\"hand\",\"handle\",\"handsome\",\"hang\",\"happen\",\"happened\",\n \"happily\",\"happy\",\"harbor\",\"hard\",\"harder\",\"hardly\",\"has\",\"hat\",\n \"have\",\"having\",\"hay\",\"he\",\"headed\",\"heading\",\"health\",\"heard\",\n \"hearing\",\"heart\",\"heat\",\"heavy\",\"height\",\"held\",\"hello\",\"help\",\n \"helpful\",\"her\",\"herd\",\"here\",\"herself\",\"hidden\",\"hide\",\"high\",\n \"higher\",\"highest\",\"highway\",\"hill\",\"him\",\"himself\",\"his\",\"history\",\n \"hit\",\"hold\",\"hole\",\"hollow\",\"home\",\"honor\",\"hope\",\"horn\",\n \"horse\",\"hospital\",\"hot\",\"hour\",\"house\",\"how\",\"however\",\"huge\",\n \"human\",\"hundred\",\"hung\",\"hungry\",\"hunt\",\"hunter\",\"hurried\",\"hurry\",\n \"hurt\",\"husband\",\"ice\",\"idea\",\"identity\",\"if\",\"ill\",\"image\",\n \"imagine\",\"immediately\",\"importance\",\"important\",\"impossible\",\"improve\",\"in\",\"inch\",\n \"include\",\"including\",\"income\",\"increase\",\"indeed\",\"independent\",\"indicate\",\"individual\",\n \"industrial\",\"industry\",\"influence\",\"information\",\"inside\",\"instance\",\"instant\",\"instead\",\n \"instrument\",\"interest\",\"interior\",\"into\",\"introduced\",\"invented\",\"involved\",\"iron\",\n \"is\",\"island\",\"it\",\"its\",\"itself\",\"jack\",\"jar\",\"jet\",\n \"job\",\"join\",\"joined\",\"journey\",\"joy\",\"judge\",\"jump\",\"jungle\",\n \"just\",\"keep\",\"kept\",\"key\",\"kids\",\"kill\",\"kind\",\"kitchen\",\n \"knew\",\"knife\",\"know\",\"knowledge\",\"known\",\"label\",\"labor\",\"lack\",\n \"lady\",\"laid\",\"lake\",\"lamp\",\"land\",\"language\",\"large\",\"larger\",\n \"largest\",\"last\",\"late\",\"later\",\"laugh\",\"law\",\"lay\",\"layers\",\n \"lead\",\"leader\",\"leaf\",\"learn\",\"least\",\"leather\",\"leave\",\"leaving\",\n \"led\",\"left\",\"leg\",\"length\",\"lesson\",\"let\",\"letter\",\"level\",\n \"library\",\"lie\",\"life\",\"lift\",\"light\",\"like\",\"likely\",\"limited\",\n \"line\",\"lion\",\"lips\",\"liquid\",\"list\",\"listen\",\"little\",\"live\",\n \"living\",\"load\",\"local\",\"locate\",\"location\",\"log\",\"lonely\",\"long\",\n \"longer\",\"look\",\"loose\",\"lose\",\"loss\",\"lost\",\"lot\",\"loud\",\n \"love\",\"lovely\",\"low\",\"lower\",\"luck\",\"lucky\",\"lunch\",\"lungs\",\n \"lying\",\"machine\",\"machinery\",\"mad\",\"made\",\"magic\",\"magnet\",\"mail\",\n \"main\",\"mainly\",\"major\",\"make\",\"making\",\"man\",\"managed\",\"manner\",\n \"manufacturing\",\"many\",\"map\",\"mark\",\"market\",\"married\",\"mass\",\"massage\",\n \"master\",\"material\",\"mathematics\",\"matter\",\"may\",\"maybe\",\"me\",\"meal\",\n \"mean\",\"means\",\"meant\",\"measure\",\"meat\",\"medicine\",\"meet\",\"melted\",\n \"member\",\"memory\",\"men\",\"mental\",\"merely\",\"met\",\"metal\",\"method\",\n \"mice\",\"middle\",\"might\",\"mighty\",\"mile\",\"military\",\"milk\",\"mill\",\n \"mind\",\"mine\",\"minerals\",\"minute\",\"mirror\",\"missing\",\"mission\",\"mistake\",\n \"mix\",\"mixture\",\"model\",\"modern\",\"molecular\",\"moment\",\"money\",\"monkey\",\n \"month\",\"mood\",\"moon\",\"more\",\"morning\",\"most\",\"mostly\",\"mother\",\n \"motion\",\"motor\",\"mountain\",\"mouse\",\"mouth\",\"move\",\"movement\",\"movie\",\n \"moving\",\"mud\",\"muscle\",\"music\",\"musical\",\"must\",\"my\",\"myself\",\n \"mysterious\",\"nails\",\"name\",\"nation\",\"national\",\"native\",\"natural\",\"naturally\",\n \"nature\",\"near\",\"nearby\",\"nearer\",\"nearest\",\"nearly\",\"necessary\",\"neck\",\n \"needed\",\"needle\",\"needs\",\"negative\",\"neighbor\",\"neighborhood\",\"nervous\",\"nest\",\n \"never\",\"new\",\"news\",\"newspaper\",\"next\",\"nice\",\"night\",\"nine\",\n \"no\",\"nobody\",\"nodded\",\"noise\",\"none\",\"noon\",\"nor\",\"north\",\n \"nose\",\"not\",\"note\",\"noted\",\"nothing\",\"notice\",\"noun\",\"now\",\n \"number\",\"numeral\",\"nuts\",\"object\",\"observe\",\"obtain\",\"occasionally\",\"occur\",\n \"ocean\",\"of\",\"off\",\"offer\",\"office\",\"officer\",\"official\",\"oil\",\n \"old\",\"older\",\"oldest\",\"on\",\"once\",\"one\",\"only\",\"onto\",\n \"open\",\"operation\",\"opinion\",\"opportunity\",\"opposite\",\"or\",\"orange\",\"orbit\",\n \"order\",\"ordinary\",\"organization\",\"organized\",\"origin\",\"original\",\"other\",\"ought\",\n \"our\",\"ourselves\",\"out\",\"outer\",\"outline\",\"outside\",\"over\",\"own\",\n \"owner\",\"oxygen\",\"pack\",\"package\",\"page\",\"paid\",\"pain\",\"paint\",\n \"pair\",\"palace\",\"pale\",\"pan\",\"paper\",\"paragraph\",\"parallel\",\"parent\",\n \"park\",\"part\",\"particles\",\"particular\",\"particularly\",\"partly\",\"parts\",\"party\",\n \"pass\",\"passage\",\"past\",\"path\",\"pattern\",\"pay\",\"peace\",\"pen\",\n \"pencil\",\"people\",\"per\",\"percent\",\"perfect\",\"perfectly\",\"perhaps\",\"period\",\n \"person\",\"personal\",\"pet\",\"phrase\",\"physical\",\"piano\",\"pick\",\"picture\",\n \"pictured\",\"pie\",\"piece\",\"pig\",\"pile\",\"pilot\",\"pine\",\"pink\",\n \"pipe\",\"pitch\",\"place\",\"plain\",\"plan\",\"plane\",\"planet\",\"planned\",\n \"planning\",\"plant\",\"plastic\",\"plate\",\"plates\",\"play\",\"pleasant\",\"please\",\n \"pleasure\",\"plenty\",\"plural\",\"plus\",\"pocket\",\"poem\",\"poet\",\"poetry\",\n \"point\",\"pole\",\"police\",\"policeman\",\"political\",\"pond\",\"pony\",\"pool\",\n \"poor\",\"popular\",\"population\",\"porch\",\"port\",\"position\",\"positive\",\"possible\",\n \"possibly\",\"post\",\"pot\",\"potatoes\",\"pound\",\"pour\",\"powder\",\"power\",\n \"powerful\",\"practical\",\"practice\",\"prepare\",\"present\",\"president\",\"press\",\"pressure\",\n \"pretty\",\"prevent\",\"previous\",\"price\",\"pride\",\"primitive\",\"principal\",\"principle\",\n \"printed\",\"private\",\"prize\",\"probably\",\"problem\",\"process\",\"produce\",\"product\",\n \"production\",\"program\",\"progress\",\"promised\",\"proper\",\"properly\",\"property\",\"protection\",\n \"proud\",\"prove\",\"provide\",\"public\",\"pull\",\"pupil\",\"pure\",\"purple\",\n \"purpose\",\"push\",\"put\",\"putting\",\"quarter\",\"queen\",\"question\",\"quick\",\n \"quickly\",\"quiet\",\"quietly\",\"quite\",\"rabbit\",\"race\",\"radio\",\"railroad\",\n \"rain\",\"raise\",\"ran\",\"ranch\",\"range\",\"rapidly\",\"rate\",\"rather\",\n \"raw\",\"rays\",\"reach\",\"read\",\"reader\",\"ready\",\"real\",\"realize\",\n \"rear\",\"reason\",\"recall\",\"receive\",\"recent\",\"recently\",\"recognize\",\"record\",\n \"red\",\"refer\",\"refused\",\"region\",\"regular\",\"related\",\"relationship\",\"religious\",\n \"remain\",\"remarkable\",\"remember\",\"remove\",\"repeat\",\"replace\",\"replied\",\"report\",\n \"represent\",\"require\",\"research\",\"respect\",\"rest\",\"result\",\"return\",\"review\",\n \"rhyme\",\"rhythm\",\"rice\",\"rich\",\"ride\",\"riding\",\"right\",\"ring\",\n \"rise\",\"rising\",\"river\",\"road\",\"roar\",\"rock\",\"rocket\",\"rocky\",\n \"rod\",\"roll\",\"roof\",\"room\",\"root\",\"rope\",\"rose\",\"rough\",\n \"round\",\"route\",\"row\",\"rubbed\",\"rubber\",\"rule\",\"ruler\",\"run\",\n \"running\",\"rush\",\"sad\",\"saddle\",\"safe\",\"safety\",\"said\",\"sail\",\n \"sale\",\"salmon\",\"salt\",\"same\",\"sand\",\"sang\",\"sat\",\"satellites\",\n \"satisfied\",\"save\",\"saved\",\"saw\",\"say\",\"scale\",\"scared\",\"scene\",\n \"school\",\"science\",\"scientific\",\"scientist\",\"score\",\"screen\",\"sea\",\"search\",\n \"season\",\"seat\",\"second\",\"secret\",\"section\",\"see\",\"seed\",\"seeing\",\n \"seems\",\"seen\",\"seldom\",\"select\",\"selection\",\"sell\",\"send\",\"sense\",\n \"sent\",\"sentence\",\"separate\",\"series\",\"serious\",\"serve\",\"service\",\"sets\",\n \"setting\",\"settle\",\"settlers\",\"seven\",\"several\",\"shade\",\"shadow\",\"shake\",\n \"shaking\",\"shall\",\"shallow\",\"shape\",\"share\",\"sharp\",\"she\",\"sheep\",\n \"sheet\",\"shelf\",\"shells\",\"shelter\",\"shine\",\"shinning\",\"ship\",\"shirt\",\n \"shoe\",\"shoot\",\"shop\",\"shore\",\"short\",\"shorter\",\"shot\",\"should\",\n \"shoulder\",\"shout\",\"show\",\"shown\",\"shut\",\"sick\",\"sides\",\"sight\",\n \"sign\",\"signal\",\"silence\",\"silent\",\"silk\",\"silly\",\"silver\",\"similar\",\n \"simple\",\"simplest\",\"simply\",\"since\",\"sing\",\"single\",\"sink\",\"sister\",\n \"sit\",\"sitting\",\"situation\",\"six\",\"size\",\"skill\",\"skin\",\"sky\",\n \"slabs\",\"slave\",\"sleep\",\"slept\",\"slide\",\"slight\",\"slightly\",\"slip\",\n \"slipped\",\"slope\",\"slow\",\"slowly\",\"small\",\"smaller\",\"smallest\",\"smell\",\n \"smile\",\"smoke\",\"smooth\",\"snake\",\"snow\",\"so\",\"soap\",\"social\",\n \"society\",\"soft\",\"softly\",\"soil\",\"solar\",\"sold\",\"soldier\",\"solid\",\n \"solution\",\"solve\",\"some\",\"somebody\",\"somehow\",\"someone\",\"something\",\"sometime\",\n \"somewhere\",\"son\",\"song\",\"soon\",\"sort\",\"sound\",\"source\",\"south\",\n \"southern\",\"space\",\"speak\",\"special\",\"species\",\"specific\",\"speech\",\"speed\",\n \"spell\",\"spend\",\"spent\",\"spider\",\"spin\",\"spirit\",\"spite\",\"split\",\n \"spoken\",\"sport\",\"spread\",\"spring\",\"square\",\"stage\",\"stairs\",\"stand\",\n \"standard\",\"star\",\"stared\",\"start\",\"state\",\"statement\",\"station\",\"stay\",\n \"steady\",\"steam\",\"steel\",\"steep\",\"stems\",\"step\",\"stepped\",\"stick\",\n \"stiff\",\"still\",\"stock\",\"stomach\",\"stone\",\"stood\",\"stop\",\"stopped\",\n \"store\",\"storm\",\"story\",\"stove\",\"straight\",\"strange\",\"stranger\",\"straw\",\n \"stream\",\"street\",\"strength\",\"stretch\",\"strike\",\"string\",\"strip\",\"strong\",\n \"stronger\",\"struck\",\"structure\",\"struggle\",\"stuck\",\"student\",\"studied\",\"studying\",\n \"subject\",\"substance\",\"success\",\"successful\",\"such\",\"sudden\",\"suddenly\",\"sugar\",\n \"suggest\",\"suit\",\"sum\",\"summer\",\"sun\",\"sunlight\",\"supper\",\"supply\",\n \"support\",\"suppose\",\"sure\",\"surface\",\"surprise\",\"surrounded\",\"swam\",\"sweet\",\n \"swept\",\"swim\",\"swimming\",\"swing\",\"swung\",\"syllable\",\"symbol\",\"system\",\n \"table\",\"tail\",\"take\",\"taken\",\"tales\",\"talk\",\"tall\",\"tank\",\n \"tape\",\"task\",\"taste\",\"taught\",\"tax\",\"tea\",\"teach\",\"teacher\",\n \"team\",\"tears\",\"teeth\",\"telephone\",\"television\",\"tell\",\"temperature\",\"ten\",\n \"tent\",\"term\",\"terrible\",\"test\",\"than\",\"thank\",\"that\",\"thee\",\n \"them\",\"themselves\",\"then\",\"theory\",\"there\",\"therefore\",\"these\",\"they\",\n \"thick\",\"thin\",\"thing\",\"think\",\"third\",\"thirty\",\"this\",\"those\",\n \"thou\",\"though\",\"thought\",\"thousand\",\"thread\",\"three\",\"threw\",\"throat\",\n \"through\",\"throughout\",\"throw\",\"thrown\",\"thumb\",\"thus\",\"thy\",\"tide\",\n \"tie\",\"tight\",\"tightly\",\"till\",\"time\",\"tin\",\"tiny\",\"tip\",\n \"tired\",\"title\",\"to\",\"tobacco\",\"today\",\"together\",\"told\",\"tomorrow\",\n \"tone\",\"tongue\",\"tonight\",\"too\",\"took\",\"tool\",\"top\",\"topic\",\n \"torn\",\"total\",\"touch\",\"toward\",\"tower\",\"town\",\"toy\",\"trace\",\n \"track\",\"trade\",\"traffic\",\"trail\",\"train\",\"transportation\",\"trap\",\"travel\",\n \"treated\",\"tree\",\"triangle\",\"tribe\",\"trick\",\"tried\",\"trip\",\"troops\",\n \"tropical\",\"trouble\",\"truck\",\"trunk\",\"truth\",\"try\",\"tube\",\"tune\",\n \"turn\",\"twelve\",\"twenty\",\"twice\",\"two\",\"type\",\"typical\",\"uncle\",\n \"under\",\"underline\",\"understanding\",\"unhappy\",\"union\",\"unit\",\"universe\",\"unknown\",\n \"unless\",\"until\",\"unusual\",\"up\",\"upon\",\"upper\",\"upward\",\"us\",\n \"use\",\"useful\",\"using\",\"usual\",\"usually\",\"valley\",\"valuable\",\"value\",\n \"vapor\",\"variety\",\"various\",\"vast\",\"vegetable\",\"verb\",\"vertical\",\"very\",\n \"vessels\",\"victory\",\"view\",\"village\",\"visit\",\"visitor\",\"voice\",\"volume\",\n \"vote\",\"vowel\",\"voyage\",\"wagon\",\"wait\",\"walk\",\"wall\",\"want\",\n \"war\",\"warm\",\"warn\",\"was\",\"wash\",\"waste\",\"watch\",\"water\",\n \"wave\",\"way\",\"we\",\"weak\",\"wealth\",\"wear\",\"weather\",\"week\",\n \"weigh\",\"weight\",\"welcome\",\"well\",\"went\",\"were\",\"west\",\"western\",\n \"wet\",\"whale\",\"what\",\"whatever\",\"wheat\",\"wheel\",\"when\",\"whenever\",\n \"where\",\"wherever\",\"whether\",\"which\",\"while\",\"whispered\",\"whistle\",\"white\",\n \"who\",\"whole\",\"whom\",\"whose\",\"why\",\"wide\",\"widely\",\"wife\",\n \"wild\",\"will\",\"willing\",\"win\",\"wind\",\"window\",\"wing\",\"winter\",\n \"wire\",\"wise\",\"wish\",\"with\",\"within\",\"without\",\"wolf\",\"women\",\n \"won\",\"wonder\",\"wonderful\",\"wood\",\"wooden\",\"wool\",\"word\",\"wore\",\n \"work\",\"worker\",\"world\",\"worried\",\"worry\",\"worse\",\"worth\",\"would\",\n \"wrapped\",\"write\",\"writer\",\"writing\",\"written\",\"wrong\",\"wrote\",\"yard\",\n \"year\",\"yellow\",\"yes\",\"yesterday\",\"yet\",\"you\",\"young\",\"younger\",\n \"your\",\"yourself\",\"youth\",\"zero\",\"zebra\",\"zipper\",\"zoo\",\"zulu\"\n];\n\nfunction words(options) {\n\n function word() {\n if (options && options.maxLength > 1) {\n return generateWordWithMaxLength();\n } else {\n return generateRandomWord();\n }\n }\n\n function generateWordWithMaxLength() {\n var rightSize = false;\n var wordUsed;\n while (!rightSize) { \n wordUsed = generateRandomWord();\n if(wordUsed.length <= options.maxLength) {\n rightSize = true;\n }\n\n }\n return wordUsed;\n }\n\n function generateRandomWord() {\n return wordList[randInt(wordList.length)];\n }\n\n function randInt(lessThan) {\n return Math.floor(Math.random() * lessThan);\n }\n\n // No arguments = generate one word\n if (typeof(options) === 'undefined') {\n return word();\n }\n\n // Just a number = return that many words\n if (typeof(options) === 'number') {\n options = { exactly: options };\n }\n\n // options supported: exactly, min, max, join\n if (options.exactly) {\n options.min = options.exactly;\n options.max = options.exactly;\n }\n \n // not a number = one word par string\n if (typeof(options.wordsPerString) !== 'number') {\n options.wordsPerString = 1;\n }\n\n //not a function = returns the raw word\n if (typeof(options.formatter) !== 'function') {\n options.formatter = (word) => word;\n }\n\n //not a string = separator is a space\n if (typeof(options.separator) !== 'string') {\n options.separator = ' ';\n }\n\n var total = options.min + randInt(options.max + 1 - options.min);\n var results = [];\n var token = '';\n var relativeIndex = 0;\n\n for (var i = 0; (i < total * options.wordsPerString); i++) {\n if (relativeIndex === options.wordsPerString - 1) {\n token += options.formatter(word(), relativeIndex);\n }\n else {\n token += options.formatter(word(), relativeIndex) + options.separator;\n }\n relativeIndex++;\n if ((i + 1) % options.wordsPerString === 0) {\n results.push(token);\n token = ''; \n relativeIndex = 0;\n }\n \n }\n if (typeof options.join === 'string') {\n results = results.join(options.join);\n }\n\n return results;\n}\n\nmodule.exports = words;\n// Export the word list as it is often useful\nwords.wordList = wordList;\n","import rw from \"random-words\";\n\nexport function repeat(array, repetitions, unpack = false) {\n const arr_isArray = Array.isArray(array);\n const rep_isArray = Array.isArray(repetitions);\n\n // if array is not an array, then we just repeat the item\n if (!arr_isArray) {\n if (!rep_isArray) {\n array = [array];\n repetitions = [repetitions];\n } else {\n repetitions = [repetitions[0]];\n console.log(\n \"Unclear parameters given to randomization.repeat. Multiple set sizes specified, but only one item exists to sample. Proceeding using the first set size.\"\n );\n }\n } else {\n // if repetitions is not an array, but array is, then we\n // repeat repetitions for each entry in array\n if (!rep_isArray) {\n let reps = [];\n for (let i = 0; i < array.length; i++) {\n reps.push(repetitions);\n }\n repetitions = reps;\n } else {\n if (array.length != repetitions.length) {\n console.warn(\n \"Unclear parameters given to randomization.repeat. Items and repetitions are unequal lengths. Behavior may not be as expected.\"\n );\n // throw warning if repetitions is too short, use first rep ONLY.\n if (repetitions.length < array.length) {\n let reps = [];\n for (let i = 0; i < array.length; i++) {\n reps.push(repetitions);\n }\n repetitions = reps;\n } else {\n // throw warning if too long, and then use the first N\n repetitions = repetitions.slice(0, array.length);\n }\n }\n }\n }\n\n // should be clear at this point to assume that array and repetitions are arrays with == length\n let allsamples = [];\n for (let i = 0; i < array.length; i++) {\n for (let j = 0; j < repetitions[i]; j++) {\n if (array[i] == null || typeof array[i] != \"object\") {\n allsamples.push(array[i]);\n } else {\n allsamples.push(Object.assign({}, array[i]));\n }\n }\n }\n\n let out: any = shuffle(allsamples);\n\n if (unpack) {\n out = unpackArray(out);\n }\n\n return out;\n}\n\nexport function shuffle(array: Array<any>) {\n if (!Array.isArray(array)) {\n console.error(\"Argument to shuffle() must be an array.\");\n }\n\n const copy_array = array.slice(0);\n let m = copy_array.length,\n t,\n i;\n\n // While there remain elements to shuffle…\n while (m) {\n // Pick a remaining element…\n i = Math.floor(Math.random() * m--);\n\n // And swap it with the current element.\n t = copy_array[m];\n copy_array[m] = copy_array[i];\n copy_array[i] = t;\n }\n\n return copy_array;\n}\n\nexport function shuffleNoRepeats(arr: Array<any>, equalityTest: (a: any, b: any) => boolean) {\n if (!Array.isArray(arr)) {\n console.error(\"First argument to shuffleNoRepeats() must be an array.\");\n }\n if (typeof equalityTest !== \"undefined\" && typeof equalityTest !== \"function\") {\n console.error(\"Second argument to shuffleNoRepeats() must be a function.\");\n }\n // define a default equalityTest\n if (typeof equalityTest == \"undefined\") {\n equalityTest = function (a, b) {\n if (a === b) {\n return true;\n } else {\n return false;\n }\n };\n }\n\n const random_shuffle = shuffle(arr);\n for (let i = 0; i < random_shuffle.length - 1; i++) {\n if (equalityTest(random_shuffle[i], random_shuffle[i + 1])) {\n // neighbors are equal, pick a new random neighbor to swap (not the first or last element, to avoid edge cases)\n let random_pick = Math.floor(Math.random() * (random_shuffle.length - 2)) + 1;\n // test to make sure the new neighbor isn't equal to the old one\n while (\n equalityTest(random_shuffle[i + 1], random_shuffle[random_pick]) ||\n equalityTest(random_shuffle[i + 1], random_shuffle[random_pick + 1]) ||\n equalityTest(random_shuffle[i + 1], random_shuffle[random_pick - 1])\n ) {\n random_pick = Math.floor(Math.random() * (random_shuffle.length - 2)) + 1;\n }\n const new_neighbor = random_shuffle[random_pick];\n random_shuffle[random_pick] = random_shuffle[i + 1];\n random_shuffle[i + 1] = new_neighbor;\n }\n }\n\n return random_shuffle;\n}\n\nexport function shuffleAlternateGroups(arr_groups, random_group_order = false) {\n const n_groups = arr_groups.length;\n if (n_groups == 1) {\n console.warn(\n \"shuffleAlternateGroups() was called with only one group. Defaulting to simple shuffle.\"\n );\n return shuffle(arr_groups[0]);\n }\n\n let group_order = [];\n for (let i = 0; i < n_groups; i++) {\n group_order.push(i);\n }\n if (random_group_order) {\n group_order = shuffle(group_order);\n }\n\n const randomized_groups = [];\n let min_length = null;\n for (let i = 0; i < n_groups; i++) {\n min_length =\n min_length === null ? arr_groups[i].length : Math.min(min_length, arr_groups[i].length);\n randomized_groups.push(shuffle(arr_groups[i]));\n }\n\n const out = [];\n for (let i = 0; i < min_length; i++) {\n for (let j = 0; j < group_order.length; j++) {\n out.push(randomized_groups[group_order[j]][i]);\n }\n }\n\n return out;\n}\n\nexport function sampleWithoutReplacement(arr, size) {\n if (!Array.isArray(arr)) {\n console.error(\"First argument to sampleWithoutReplacement() must be an array\");\n }\n\n if (size > arr.length) {\n console.error(\"Cannot take a sample larger than the size of the set of items to sample.\");\n }\n return shuffle(arr).slice(0, size);\n}\n\nexport function sampleWithReplacement(arr, size, weights?) {\n if (!Array.isArray(arr)) {\n console.error(\"First argument to sampleWithReplacement() must be an array\");\n }\n\n const normalized_weights = [];\n if (typeof weights !== \"undefined\") {\n if (weights.length !== arr.length) {\n console.error(\n \"The length of the weights array must equal the length of the array \" +\n \"to be sampled from.\"\n );\n }\n let weight_sum = 0;\n for (const weight of weights) {\n weight_sum += weight;\n }\n for (const weight of weights) {\n normalized_weights.push(weight / weight_sum);\n }\n } else {\n for (let i = 0; i < arr.length; i++) {\n normalized_weights.push(1 / arr.length);\n }\n }\n\n const cumulative_weights = [normalized_weights[0]];\n for (let i = 1; i < normalized_weights.length; i++) {\n cumulative_weights.push(normalized_weights[i] + cumulative_weights[i - 1]);\n }\n\n const samp = [];\n for (let i = 0; i < size; i++) {\n const rnd = Math.random();\n let index = 0;\n while (rnd > cumulative_weights[index]) {\n index++;\n }\n samp.push(arr[index]);\n }\n return samp;\n}\n\nexport function factorial(factors: Record<string, any>, repetitions = 1, unpack = false) {\n let design = [{}];\n for (const [factorName, factor] of Object.entries(factors)) {\n const new_design = [];\n for (const level of factor) {\n for (const cell of design) {\n new_design.push({ ...cell, [factorName]: level });\n }\n }\n design = new_design;\n }\n\n return repeat(design, repetitions, unpack);\n}\n\nexport function randomID(length = 32) {\n let result = \"\";\n const chars = \"0123456789abcdefghjklmnopqrstuvwxyz\";\n for (let i = 0; i < length; i++) {\n result += chars[Math.floor(Math.random() * chars.length)];\n }\n return result;\n}\n\n/**\n * Generate a random integer from `lower` to `upper`, inclusive of both end points.\n * @param lower The lowest value it is possible to generate\n * @param upper The highest value it is possible to generate\n * @returns A random integer\n */\nexport function randomInt(lower: number, upper: number) {\n if (upper < lower) {\n throw new Error(\"Upper boundary must be less than or equal to lower boundary\");\n }\n return lower + Math.floor(Math.random() * (upper - lower + 1));\n}\n\n/**\n * Generates a random sample from a Bernoulli distribution.\n * @param p The probability of sampling 1.\n * @returns 0, with probability 1-p, or 1, with probability p.\n */\nexport function sampleBernoulli(p: number) {\n return Math.random() <= p ? 1 : 0;\n}\n\nexport function sampleNormal(mean: number, standard_deviation: number) {\n return randn_bm() * standard_deviation + mean;\n}\n\nexport function sampleExponential(rate: number) {\n return -Math.log(Math.random()) / rate;\n}\n\nexport function sampleExGaussian(\n mean: number,\n standard_deviation: number,\n rate: number,\n positive = false\n) {\n let s = sampleNormal(mean, standard_deviation) + sampleExponential(rate);\n if (positive) {\n while (s <= 0) {\n s = sampleNormal(mean, standard_deviation) + sampleExponential(rate);\n }\n }\n return s;\n}\n\n/**\n * Generate one or more random words.\n *\n * This is a wrapper function for the {@link https://www.npmjs.com/package/random-words `random-words` npm package}.\n *\n * @param opts An object with optional properties `min`, `max`, `exactly`,\n * `join`, `maxLength`, `wordsPerString`, `separator`, and `formatter`.\n *\n * @returns An array of words or a single string, depending on parameter choices.\n */\nexport function randomWords(opts) {\n return rw(opts);\n}\n\n// Box-Muller transformation for a random sample from normal distribution with mean = 0, std = 1\n// https://stackoverflow.com/a/36481059/3726673\nfunction randn_bm() {\n var u = 0,\n v = 0;\n while (u === 0) u = Math.random(); //Converting [0,1) to (0,1)\n while (v === 0) v = Math.random();\n return Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);\n}\n\nfunction unpackArray(array) {\n const out = {};\n\n for (const x of array) {\n for (const key of Object.keys(x)) {\n if (typeof out[key] === \"undefined\") {\n out[key] = [];\n }\n out[key].push(x[key]);\n }\n }\n\n return out;\n}\n","interface turkInformation {\n /**\n * Is the experiment being loaded in preview mode on Mechanical Turk?\n */\n previewMode: boolean;\n /**\n * Is the experiment being loaded outside of the Mechanical Turk environment?\n */\n outsideTurk: boolean;\n /**\n * The HIT ID.\n */\n hitId: string;\n /**\n * The Assignment ID.\n */\n assignmentId: string;\n /**\n * The worker ID.\n */\n workerId: string;\n /**\n * URL for submission of the HIT.\n */\n turkSubmitTo: string;\n}\n\n/**\n * Gets information about the Mechanical Turk Environment, HIT, Assignment, and Worker\n * by parsing the URL variables that Mechanical Turk generates.\n * @returns An object containing information about the Mechanical Turk Environment, HIT, Assignment, and Worker.\n */\nexport function turkInfo(): turkInformation {\n const turk: turkInformation = {\n previewMode: false,\n outsideTurk: false,\n hitId: \"INVALID_URL_PARAMETER\",\n assignmentId: \"INVALID_URL_PARAMETER\",\n workerId: \"INVALID_URL_PARAMETER\",\n turkSubmitTo: \"INVALID_URL_PARAMETER\",\n };\n\n const param = function (url, name) {\n name = name.replace(/[\\[]/, \"\\\\[\").replace(/[\\]]/, \"\\\\]\");\n const regexS = \"[\\\\?&]\" + name + \"=([^&#]*)\";\n const regex = new RegExp(regexS);\n const results = regex.exec(url);\n return results == null ? \"\" : results[1];\n };\n\n const src = param(window.location.href, \"assignmentId\")\n ? window.location.href\n : document.referrer;\n\n const keys = [\"assignmentId\", \"hitId\", \"workerId\", \"turkSubmitTo\"];\n keys.map(function (key) {\n turk[key] = unescape(param(src, key));\n });\n\n turk.previewMode = turk.assignmentId == \"ASSIGNMENT_ID_NOT_AVAILABLE\";\n\n turk.outsideTurk =\n !turk.previewMode && turk.hitId === \"\" && turk.assignmentId == \"\" && turk.workerId == \"\";\n\n return turk;\n}\n\n/**\n * Send data to Mechnical Turk for storage.\n * @param data An object containing `key:value` pairs to send to Mechanical Turk. Values\n * cannot contain nested objects, arrays, or functions.\n * @returns Nothing\n */\nexport function submitToTurk(data) {\n const turk = turkInfo();\n const assignmentId = turk.assignmentId;\n const turkSubmitTo = turk.turkSubmitTo;\n\n if (!assignmentId || !turkSubmitTo) return;\n\n const form = document.createElement(\"form\");\n form.method = \"POST\";\n form.action = turkSubmitTo + \"/mturk/externalSubmit?assignmentId=\" + assignmentId;\n\n for (const key in data) {\n if (data.hasOwnProperty(key)) {\n const hiddenField = document.createElement(\"input\");\n hiddenField.type = \"hidden\";\n hiddenField.name = key;\n hiddenField.id = key;\n hiddenField.value = data[key];\n\n form.appendChild(hiddenField);\n }\n }\n\n document.body.appendChild(form);\n form.submit();\n}\n","import { JsPsych } from \"./JsPsych\";\nimport {\n repeat,\n sampleWithReplacement,\n sampleWithoutReplacement,\n shuffle,\n shuffleAlternateGroups,\n} from \"./modules/randomization\";\nimport { deepCopy } from \"./modules/utils\";\n\nexport class TimelineNode {\n // a unique ID for this node, relative to the parent\n relative_id;\n\n // store the parent for this node\n parent_node;\n\n // parameters for the trial if the node contains a trial\n trial_parameters;\n\n // parameters for nodes that contain timelines\n timeline_parameters;\n\n // stores trial information on a node that contains a timeline\n // used for adding new trials\n node_trial_data;\n\n // track progress through the node\n progress = <any>{\n current_location: -1, // where on the timeline (which timelinenode)\n current_variable_set: 0, // which set of variables to use from timeline_variables\n current_repetition: 0, // how many times through the variable set on this run of the node\n current_iteration: 0, // how many times this node has been revisited\n done: false,\n };\n\n end_message?: string;\n\n // constructor\n constructor(private jsPsych: JsPsych, parameters, parent?, relativeID?) {\n // store a link to the parent of this node\n this.parent_node = parent;\n\n // create the ID for this node\n this.relative_id = typeof parent === \"undefined\" ? 0 : relativeID;\n\n // check if there is a timeline parameter\n // if there is, then this node has its own timeline\n if (typeof parameters.timeline !== \"undefined\") {\n // create timeline properties\n this.timeline_parameters = {\n timeline: [],\n loop_function: parameters.loop_function,\n conditional_function: parameters.conditional_function,\n sample: parameters.sample,\n randomize_order:\n typeof parameters.randomize_order == \"undefined\" ? false : parameters.randomize_order,\n repetitions: typeof parameters.repetitions == \"undefined\" ? 1 : parameters.repetitions,\n timeline_variables:\n typeof parameters.timeline_variables == \"undefined\"\n ? [{}]\n : parameters.timeline_variables,\n on_timeline_finish: parameters.on_timeline_finish,\n on_timeline_start: parameters.on_timeline_start,\n };\n\n this.setTimelineVariablesOrder();\n\n // extract all of the node level data and parameters\n // but remove all of the timeline-level specific information\n // since this will be used to copy things down hierarchically\n var node_data = Object.assign({}, parameters);\n delete node_data.timeline;\n delete node_data.conditional_function;\n delete node_data.loop_function;\n delete node_data.randomize_order;\n delete node_data.repetitions;\n delete node_data.timeline_variables;\n delete node_data.sample;\n delete node_data.on_timeline_start;\n delete node_data.on_timeline_finish;\n this.node_trial_data = node_data; // store for later...\n\n // create a TimelineNode for each element in the timeline\n for (var i = 0; i < parameters.timeline.length; i++) {\n // merge parameters\n var merged_parameters = Object.assign({}, node_data, parameters.timeline[i]);\n // merge any data from the parent node into child nodes\n if (typeof node_data.data == \"object\" && typeof parameters.timeline[i].data == \"object\") {\n var merged_data = Object.assign({}, node_data.data, parameters.timeline[i].data);\n merged_parameters.data = merged_data;\n }\n this.timeline_parameters.timeline.push(\n new TimelineNode(this.jsPsych, merged_parameters, this, i)\n );\n }\n }\n // if there is no timeline parameter, then this node is a trial node\n else {\n // check to see if a valid trial type is defined\n if (typeof parameters.type === \"undefined\") {\n console.error(\n 'Trial level node is missing the \"type\" parameter. The parameters for the node are: ' +\n JSON.stringify(parameters)\n );\n }\n // create a deep copy of the parameters for the trial\n this.trial_parameters = { ...parameters };\n }\n }\n\n // recursively get the next trial to run.\n // if this node is a leaf (trial), then return the trial.\n // otherwise, recursively find the next trial in the child timeline.\n trial() {\n if (typeof this.timeline_parameters == \"undefined\") {\n // returns a clone of the trial_parameters to\n // protect functions.\n return deepCopy(this.trial_parameters);\n } else {\n if (this.progress.current_location >= this.timeline_parameters.timeline.length) {\n return null;\n } else {\n return this.timeline_parameters.timeline[this.progress.current_location].trial();\n }\n }\n }\n\n markCurrentTrialComplete() {\n if (typeof this.timeline_parameters === \"undefined\") {\n this.progress.done = true;\n } else {\n this.timeline_parameters.timeline[this.progress.current_location].markCurrentTrialComplete();\n }\n }\n\n nextRepetiton() {\n this.setTimelineVariablesOrder();\n this.progress.current_location = -1;\n this.progress.current_variable_set = 0;\n this.progress.current_repetition++;\n for (var i = 0; i < this.timeline_parameters.timeline.length; i++) {\n this.timeline_parameters.timeline[i].reset();\n }\n }\n\n // set the order for going through the timeline variables array\n setTimelineVariablesOrder() {\n const timeline_parameters = this.timeline_parameters;\n\n // check to make sure this node has variables\n if (\n typeof timeline_parameters === \"undefined\" ||\n typeof timeline_parameters.timeline_variables === \"undefined\"\n ) {\n return;\n }\n\n var order = [];\n for (var i = 0; i < timeline_parameters.timeline_variables.length; i++) {\n order.push(i);\n }\n\n if (typeof timeline_parameters.sample !== \"undefined\") {\n if (timeline_parameters.sample.type == \"custom\") {\n order = timeline_parameters.sample.fn(order);\n } else if (timeline_parameters.sample.type == \"with-replacement\") {\n order = sampleWithReplacement(\n order,\n timeline_parameters.sample.size,\n timeline_parameters.sample.weights\n );\n } else if (timeline_parameters.sample.type == \"without-replacement\") {\n order = sampleWithoutReplacement(order, timeline_parameters.sample.size);\n } else if (timeline_parameters.sample.type == \"fixed-repetitions\") {\n order = repeat(order, timeline_parameters.sample.size, false);\n } else if (timeline_parameters.sample.type == \"alternate-groups\") {\n order = shuffleAlternateGroups(\n timeline_parameters.sample.groups,\n timeline_parameters.sample.randomize_group_order\n );\n } else {\n console.error(\n 'Invalid type in timeline sample parameters. Valid options for type are \"custom\", \"with-replacement\", \"without-replacement\", \"fixed-repetitions\", and \"alternate-groups\"'\n );\n }\n }\n\n if (timeline_parameters.randomize_order) {\n order = shuffle(order);\n }\n\n this.progress.order = order;\n }\n\n // next variable set\n nextSet() {\n this.progress.current_location = -1;\n this.progress.current_variable_set++;\n for (var i = 0; i < this.timeline_parameters.timeline.length; i++) {\n this.timeline_parameters.timeline[i].reset();\n }\n }\n\n // update the current trial node to be completed\n // returns true if the node is complete after advance (all subnodes are also complete)\n // returns false otherwise\n advance() {\n const progress = this.progress;\n const timeline_parameters = this.timeline_parameters;\n const internal = this.jsPsych.internal;\n\n // first check to see if done\n if (progress.done) {\n return true;\n }\n\n // if node has not started yet (progress.current_location == -1),\n // then try to start the node.\n if (progress.current_location == -1) {\n // check for on_timeline_start and conditonal function on nodes with timelines\n if (typeof timeline_parameters !== \"undefined\") {\n // only run the conditional function if this is the first repetition of the timeline when\n // repetitions > 1, and only when on the first variable set\n if (\n typeof timeline_parameters.conditional_function !== \"undefined\" &&\n progress.current_repetition == 0 &&\n progress.current_variable_set == 0\n ) {\n internal.call_immediate = true;\n var conditional_result = timeline_parameters.conditional_function();\n internal.call_immediate = false;\n // if the conditional_function() returns false, then the timeline\n // doesn't run and is marked as complete.\n if (conditional_result == false) {\n progress.done = true;\n return true;\n }\n }\n\n // if we reach this point then the node has its own timeline and will start\n // so we need to check if there is an on_timeline_start function if we are on the first variable set\n if (\n typeof timeline_parameters.on_timeline_start !== \"undefined\" &&\n progress.current_variable_set == 0\n ) {\n timeline_parameters.on_timeline_start();\n }\n }\n // if we reach this point, then either the node doesn't have a timeline of the\n // conditional function returned true and it can start\n progress.current_location = 0;\n // call advance again on this node now that it is pointing to a new location\n return this.advance();\n }\n\n // if this node has a timeline, propogate down to the current trial.\n if (typeof timeline_parameters !== \"undefined\") {\n var have_node_to_run = false;\n // keep incrementing the location in the timeline until one of the nodes reached is incomplete\n while (\n progress.current_location < timeline_parameters.timeline.length &&\n have_node_to_run == false\n ) {\n // check to see if the node currently pointed at is done\n var target_complete = timeline_parameters.timeline[progress.current_location].advance();\n if (!target_complete) {\n have_node_to_run = true;\n return false;\n } else {\n progress.current_location++;\n }\n }\n\n // if we've reached the end of the timeline (which, if the code is here, we have)\n\n // there are a few steps to see what to do next...\n\n // first, check the timeline_variables to see if we need to loop through again\n // with a new set of variables\n if (progress.current_variable_set < progress.order.length - 1) {\n // reset the progress of the node to be with the new set\n this.nextSet();\n // then try to advance this node again.\n return this.advance();\n }\n\n // if we're all done with the timeline_variables, then check to see if there are more repetitions\n else if (progress.current_repetition < timeline_parameters.repetitions - 1) {\n this.nextRepetiton();\n // check to see if there is an on_timeline_finish function\n if (typeof timeline_parameters.on_timeline_finish !== \"undefined\") {\n timeline_parameters.on_timeline_finish();\n }\n return this.advance();\n }\n\n // if we're all done with the repetitions...\n else {\n // check to see if there is an on_timeline_finish function\n if (typeof timeline_parameters.on_timeline_finish !== \"undefined\") {\n timeline_parameters.on_timeline_finish();\n }\n\n // if we're all done with the repetitions, check if there is a loop function.\n if (typeof timeline_parameters.loop_function !== \"undefined\") {\n internal.call_immediate = true;\n if (timeline_parameters.loop_function(this.generatedData())) {\n this.reset();\n internal.call_immediate = false;\n return this.parent_node.advance();\n } else {\n progress.done = true;\n internal.call_immediate = false;\n return true;\n }\n }\n }\n\n // no more loops on this timeline, we're done!\n progress.done = true;\n return true;\n }\n }\n\n // check the status of the done flag\n isComplete() {\n return this.progress.done;\n }\n\n // getter method for timeline variables\n getTimelineVariableValue(variable_name: string) {\n if (typeof this.timeline_parameters == \"undefined\") {\n return undefined;\n }\n var v =\n this.timeline_parameters.timeline_variables[\n this.progress.order[this.progress.current_variable_set]\n ][variable_name];\n return v;\n }\n\n // recursive upward search for timeline variables\n findTimelineVariable(variable_name) {\n var v = this.getTimelineVariableValue(variable_name);\n if (typeof v == \"undefined\") {\n if (typeof this.parent_node !== \"undefined\") {\n return this.parent_node.findTimelineVariable(variable_name);\n } else {\n return undefined;\n }\n } else {\n return v;\n }\n }\n\n // recursive downward search for active trial to extract timeline variable\n timelineVariable(variable_name: string) {\n if (typeof this.timeline_parameters == \"undefined\") {\n return this.findTimelineVariable(variable_name);\n } else {\n // if progress.current_location is -1, then the timeline variable is being evaluated\n // in a function that runs prior to the trial starting, so we should treat that trial\n // as being the active trial for purposes of finding the value of the timeline variable\n var loc = Math.max(0, this.progress.current_location);\n // if loc is greater than the number of elements on this timeline, then the timeline\n // variable is being evaluated in a function that runs after the trial on the timeline\n // are complete but before advancing to the next (like a loop_function).\n // treat the last active trial as the active trial for this purpose.\n if (loc == this.timeline_parameters.timeline.length) {\n loc = loc - 1;\n }\n // now find the variable\n return this.timeline_parameters.timeline[loc].timelineVariable(variable_name);\n }\n }\n\n // recursively get all the timeline variables for this trial\n allTimelineVariables() {\n var all_tvs = this.allTimelineVariablesNames();\n var all_tvs_vals = <any>{};\n for (var i = 0; i < all_tvs.length; i++) {\n all_tvs_vals[all_tvs[i]] = this.timelineVariable(all_tvs[i]);\n }\n return all_tvs_vals;\n }\n\n // helper to get all the names at this stage.\n allTimelineVariablesNames(so_far = []) {\n if (typeof this.timeline_parameters !== \"undefined\") {\n so_far = so_far.concat(\n Object.keys(\n this.timeline_parameters.timeline_variables[\n this.progress.order[this.progress.current_variable_set]\n ]\n )\n );\n // if progress.current_location is -1, then the timeline variable is being evaluated\n // in a function that runs prior to the trial starting, so we should treat that trial\n // as being the active trial for purposes of finding the value of the timeline variable\n var loc = Math.max(0, this.progress.current_location);\n // if loc is greater than the number of elements on this timeline, then the timeline\n // variable is being evaluated in a function that runs after the trial on the timeline\n // are complete but before advancing to the next (like a loop_function).\n // treat the last active trial as the active trial for this purpose.\n if (loc == this.timeline_parameters.timeline.length) {\n loc = loc - 1;\n }\n // now find the variable\n return this.timeline_parameters.timeline[loc].allTimelineVariablesNames(so_far);\n }\n if (typeof this.timeline_parameters == \"undefined\") {\n return so_far;\n }\n }\n\n // recursively get the number of **trials** contained in the timeline\n // assuming that while loops execute exactly once and if conditionals\n // always run\n length() {\n var length = 0;\n if (typeof this.timeline_parameters !== \"undefined\") {\n for (var i = 0; i < this.timeline_parameters.timeline.length; i++) {\n length += this.timeline_parameters.timeline[i].length();\n }\n } else {\n return 1;\n }\n return length;\n }\n\n // return the percentage of trials completed, grouped at the first child level\n // counts a set of trials as complete when the child node is done\n percentComplete() {\n var total_trials = this.length();\n var completed_trials = 0;\n for (var i = 0; i < this.timeline_parameters.timeline.length; i++) {\n if (this.timeline_parameters.timeline[i].isComplete()) {\n completed_trials += this.timeline_parameters.timeline[i].length();\n }\n }\n return (completed_trials / total_trials) * 100;\n }\n\n // resets the node and all subnodes to original state\n // but increments the current_iteration counter\n reset() {\n this.progress.current_location = -1;\n this.progress.current_repetition = 0;\n this.progress.current_variable_set = 0;\n this.progress.current_iteration++;\n this.progress.done = false;\n this.setTimelineVariablesOrder();\n if (typeof this.timeline_parameters != \"undefined\") {\n for (var i = 0; i < this.timeline_parameters.timeline.length; i++) {\n this.timeline_parameters.timeline[i].reset();\n }\n }\n }\n\n // mark this node as finished\n end() {\n this.progress.done = true;\n }\n\n // recursively end whatever sub-node is running the current trial\n endActiveNode() {\n if (typeof this.timeline_parameters == \"undefined\") {\n this.end();\n this.parent_node.end();\n } else {\n this.timeline_parameters.timeline[this.progress.current_location].endActiveNode();\n }\n }\n\n // get a unique ID associated with this node\n // the ID reflects the current iteration through this node.\n ID() {\n var id = \"\";\n if (typeof this.parent_node == \"undefined\") {\n return \"0.\" + this.progress.current_iteration;\n } else {\n id += this.parent_node.ID() + \"-\";\n id += this.relative_id + \".\" + this.progress.current_iteration;\n return id;\n }\n }\n\n // get the ID of the active trial\n activeID() {\n if (typeof this.timeline_parameters == \"undefined\") {\n return this.ID();\n } else {\n return this.timeline_parameters.timeline[this.progress.current_location].activeID();\n }\n }\n\n // get all the data generated within this node\n generatedData() {\n return this.jsPsych.data.getDataByTimelineNode(this.ID());\n }\n\n // get all the trials of a particular type\n trialsOfType(type) {\n if (typeof this.timeline_parameters == \"undefined\") {\n if (this.trial_parameters.type == type) {\n return this.trial_parameters;\n } else {\n return [];\n }\n } else {\n var trials = [];\n for (var i = 0; i < this.timeline_parameters.timeline.length; i++) {\n var t = this.timeline_parameters.timeline[i].trialsOfType(type);\n trials = trials.concat(t);\n }\n return trials;\n }\n }\n\n // add new trials to end of this timeline\n insert(parameters) {\n if (typeof this.timeline_parameters === \"undefined\") {\n console.error(\"Cannot add new trials to a trial-level node.\");\n } else {\n this.timeline_parameters.timeline.push(\n new TimelineNode(\n this.jsPsych,\n { ...this.node_trial_data, ...parameters },\n this,\n this.timeline_parameters.timeline.length\n )\n );\n }\n }\n}\n","import autoBind from \"auto-bind\";\n\nimport { version } from \"../package.json\";\nimport { MigrationError } from \"./migration\";\nimport { JsPsychData } from \"./modules/data\";\nimport { PluginAPI, createJointPluginAPIObject } from \"./modules/plugin-api\";\nimport { ParameterType, universalPluginParameters } from \"./modules/plugins\";\nimport * as randomization from \"./modules/randomization\";\nimport * as turk from \"./modules/turk\";\nimport * as utils from \"./modules/utils\";\nimport { TimelineNode } from \"./TimelineNode\";\n\nfunction delay(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport class JsPsych {\n extensions = <any>{};\n turk = turk;\n randomization = randomization;\n utils = utils;\n data: JsPsychData;\n pluginAPI: PluginAPI;\n\n version() {\n return version;\n }\n\n //\n // private variables\n //\n\n /**\n * options\n */\n private opts: any = {};\n\n /**\n * experiment timeline\n */\n private timeline: TimelineNode;\n private timelineDescription: any[];\n\n // flow control\n private global_trial_index = 0;\n private current_trial: any = {};\n private current_trial_finished = false;\n\n // target DOM element\n private DOM_container: HTMLElement;\n private DOM_target: HTMLElement;\n\n /**\n * time that the experiment began\n */\n private exp_start_time;\n\n /**\n * is the experiment paused?\n */\n private paused = false;\n private waiting = false;\n\n /**\n * is the page retrieved directly via file:// protocol (true) or hosted on a server (false)?\n */\n private file_protocol = false;\n\n /**\n * Promise that is resolved when `finishExperiment()` is called\n */\n private finished: Promise<void>;\n private resolveFinishedPromise: () => void;\n\n /**\n * is the experiment running in `simulate()` mode\n */\n private simulation_mode: \"data-only\" | \"visual\" = null;\n\n /**\n * simulation options passed in via `simulate()`\n */\n private simulation_options;\n\n // storing a single webaudio context to prevent problems with multiple inits\n // of jsPsych\n webaudio_context: AudioContext = null;\n\n internal = {\n /**\n * this flag is used to determine whether we are in a scope where\n * jsPsych.timelineVariable() should be executed immediately or\n * whether it should return a function to access the variable later.\n *\n **/\n call_immediate: false,\n };\n\n constructor(options?) {\n // override default options if user specifies an option\n options = {\n display_element: undefined,\n on_finish: () => {},\n on_trial_start: () => {},\n on_trial_finish: () => {},\n on_data_update: () => {},\n on_interaction_data_update: () => {},\n on_close: () => {},\n use_webaudio: true,\n exclusions: {},\n show_progress_bar: false,\n message_progress_bar: \"Completion Progress\",\n auto_update_progress_bar: true,\n default_iti: 0,\n minimum_valid_rt: 0,\n experiment_width: null,\n override_safe_mode: false,\n case_sensitive_responses: false,\n extensions: [],\n ...options,\n };\n this.opts = options;\n\n autoBind(this); // so we can pass JsPsych methods as callbacks and `this` remains the JsPsych instance\n\n this.webaudio_context =\n typeof window !== \"undefined\" && typeof window.AudioContext !== \"undefined\"\n ? new AudioContext()\n : null;\n\n // detect whether page is running in browser as a local file, and if so, disable web audio and video preloading to prevent CORS issues\n if (\n window.location.protocol == \"file:\" &&\n (options.override_safe_mode === false || typeof options.override_safe_mode === \"undefined\")\n ) {\n options.use_webaudio = false;\n this.file_protocol = true;\n console.warn(\n \"jsPsych detected that it is running via the file:// protocol and not on a web server. \" +\n \"To prevent issues with cross-origin requests, Web Audio and video preloading have been disabled. \" +\n \"If you would like to override this setting, you can set 'override_safe_mode' to 'true' in initJsPsych. \" +\n \"For more information, see: https://www.jspsych.org/overview/running-experiments\"\n );\n }\n\n // initialize modules\n this.data = new JsPsychData(this);\n this.pluginAPI = createJointPluginAPIObject(this);\n\n // create instances of extensions\n for (const extension of options.extensions) {\n this.extensions[extension.type.info.name] = new extension.type(this);\n }\n\n // initialize audio context based on options and browser capabilities\n this.pluginAPI.initAudio();\n }\n\n /**\n * Starts an experiment using the provided timeline and returns a promise that is resolved when\n * the experiment is finished.\n *\n * @param timeline The timeline to be run\n */\n async run(timeline: any[]) {\n if (typeof timeline === \"undefined\") {\n console.error(\"No timeline declared in jsPsych.run. Cannot start experiment.\");\n }\n\n if (timeline.length === 0) {\n console.error(\n \"No trials have been added to the timeline (the timeline is an empty array). Cannot start experiment.\"\n );\n }\n\n // create experiment timeline\n this.timelineDescription = timeline;\n this.timeline = new TimelineNode(this, { timeline });\n\n await this.prepareDom();\n await this.checkExclusions(this.opts.exclusions);\n await this.loadExtensions(this.opts.extensions);\n\n document.documentElement.setAttribute(\"jspsych\", \"present\");\n\n this.startExperiment();\n await this.finished;\n }\n\n async simulate(\n timeline: any[],\n simulation_mode: \"data-only\" | \"visual\" = \"data-only\",\n simulation_options = {}\n ) {\n this.simulation_mode = simulation_mode;\n this.simulation_options = simulation_options;\n await this.run(timeline);\n }\n\n getProgress() {\n return {\n total_trials: typeof this.timeline === \"undefined\" ? undefined : this.timeline.length(),\n current_trial_global: this.global_trial_index,\n percent_complete: typeof this.timeline === \"undefined\" ? 0 : this.timeline.percentComplete(),\n };\n }\n\n getStartTime() {\n return this.exp_start_time;\n }\n\n getTotalTime() {\n if (typeof this.exp_start_time === \"undefined\") {\n return 0;\n }\n return new Date().getTime() - this.exp_start_time.getTime();\n }\n\n getDisplayElement() {\n return this.DOM_target;\n }\n\n getDisplayContainerElement() {\n return this.DOM_container;\n }\n\n finishTrial(data = {}) {\n if (this.current_trial_finished) {\n return;\n }\n this.current_trial_finished = true;\n\n // remove any CSS classes that were added to the DOM via css_classes parameter\n if (\n typeof this.current_trial.css_classes !== \"undefined\" &&\n Array.isArray(this.current_trial.css_classes)\n ) {\n this.DOM_target.classList.remove(...this.current_trial.css_classes);\n }\n\n // write the data from the trial\n this.data.write(data);\n\n // get back the data with all of the defaults in\n const trial_data = this.data.get().filter({ trial_index: this.global_trial_index });\n\n // for trial-level callbacks, we just want to pass in a reference to the values\n // of the DataCollection, for easy access and editing.\n const trial_data_values = trial_data.values()[0];\n\n const current_trial = this.current_trial;\n\n if (typeof current_trial.save_trial_parameters === \"object\") {\n for (const key of Object.keys(current_trial.save_trial_parameters)) {\n const key_val = current_trial.save_trial_parameters[key];\n if (key_val === true) {\n if (typeof current_trial[key] === \"undefined\") {\n console.warn(\n `Invalid parameter specified in save_trial_parameters. Trial has no property called \"${key}\".`\n );\n } else if (typeof current_trial[key] === \"function\") {\n trial_data_values[key] = current_trial[key].toString();\n } else {\n trial_data_values[key] = current_trial[key];\n }\n }\n if (key_val === false) {\n // we don't allow internal_node_id or trial_index to be deleted because it would break other things\n if (key !== \"internal_node_id\" && key !== \"trial_index\") {\n delete trial_data_values[key];\n }\n }\n }\n }\n // handle extension callbacks\n if (Array.isArray(current_trial.extensions)) {\n for (const extension of current_trial.extensions) {\n const ext_data_values = this.extensions[extension.type.info.name].on_finish(\n extension.params\n );\n Object.assign(trial_data_values, ext_data_values);\n }\n }\n\n // about to execute lots of callbacks, so switch context.\n this.internal.call_immediate = true;\n\n // handle callback at plugin level\n if (typeof current_trial.on_finish === \"function\") {\n current_trial.on_finish(trial_data_values);\n }\n\n // handle callback at whole-experiment level\n this.opts.on_trial_finish(trial_data_values);\n\n // after the above callbacks are complete, then the data should be finalized\n // for this trial. call the on_data_update handler, passing in the same\n // data object that just went through the trial's finish handlers.\n this.opts.on_data_update(trial_data_values);\n\n // done with callbacks\n this.internal.call_immediate = false;\n\n // wait for iti\n if (\n typeof current_trial.post_trial_gap === null ||\n typeof current_trial.post_trial_gap === \"undefined\"\n ) {\n if (this.opts.default_iti > 0) {\n setTimeout(this.nextTrial, this.opts.default_iti);\n } else {\n this.nextTrial();\n }\n } else {\n if (current_trial.post_trial_gap > 0) {\n setTimeout(this.nextTrial, current_trial.post_trial_gap);\n } else {\n this.nextTrial();\n }\n }\n }\n\n endExperiment(end_message = \"\", data = {}) {\n this.timeline.end_message = end_message;\n this.timeline.end();\n this.pluginAPI.cancelAllKeyboardResponses();\n this.pluginAPI.clearAllTimeouts();\n this.finishTrial(data);\n }\n\n endCurrentTimeline() {\n this.timeline.endActiveNode();\n }\n\n getCurrentTrial() {\n return this.current_trial;\n }\n\n getInitSettings() {\n return this.opts;\n }\n\n getCurrentTimelineNodeID() {\n return this.timeline.activeID();\n }\n\n timelineVariable(varname: string, immediate = false) {\n if (this.internal.call_immediate || immediate === true) {\n return this.timeline.timelineVariable(varname);\n } else {\n return {\n timelineVariablePlaceholder: true,\n timelineVariableFunction: () => this.timeline.timelineVariable(varname),\n };\n }\n }\n\n getAllTimelineVariables() {\n return this.timeline.allTimelineVariables();\n }\n\n addNodeToEndOfTimeline(new_timeline, preload_callback?) {\n this.timeline.insert(new_timeline);\n }\n\n pauseExperiment() {\n this.paused = true;\n }\n\n resumeExperiment() {\n this.paused = false;\n if (this.waiting) {\n this.waiting = false;\n this.nextTrial();\n }\n }\n\n loadFail(message) {\n message = message || \"<p>The experiment failed to load.</p>\";\n this.DOM_target.innerHTML = message;\n }\n\n getSafeModeStatus() {\n return this.file_protocol;\n }\n\n getTimeline() {\n return this.timelineDescription;\n }\n\n private async prepareDom() {\n // Wait until the document is ready\n if (document.readyState !== \"complete\") {\n await new Promise((resolve) => {\n window.addEventListener(\"load\", resolve);\n });\n }\n\n const options = this.opts;\n\n // set DOM element where jsPsych will render content\n // if undefined, then jsPsych will use the <body> tag and the entire page\n if (typeof options.display_element === \"undefined\") {\n // check if there is a body element on the page\n const body = document.querySelector(\"body\");\n if (body === null) {\n document.documentElement.appendChild(document.createElement(\"body\"));\n }\n // using the full page, so we need the HTML element to\n // have 100% height, and body to be full width and height with\n // no margin\n document.querySelector(\"html\").style.height = \"100%\";\n document.querySelector(\"body\").style.margin = \"0px\";\n document.querySelector(\"body\").style.height = \"100%\";\n document.querySelector(\"body\").style.width = \"100%\";\n options.display_element = document.querySelector(\"body\");\n } else {\n // make sure that the display element exists on the page\n const display =\n options.display_element instanceof Element\n ? options.display_element\n : document.querySelector(\"#\" + options.display_element);\n if (display === null) {\n console.error(\"The display_element specified in initJsPsych() does not exist in the DOM.\");\n } else {\n options.display_element = display;\n }\n }\n\n options.display_element.innerHTML =\n '<div class=\"jspsych-content-wrapper\"><div id=\"jspsych-content\"></div></div>';\n this.DOM_container = options.display_element;\n this.DOM_target = document.querySelector(\"#jspsych-content\");\n\n // set experiment_width if not null\n if (options.experiment_width !== null) {\n this.DOM_target.style.width = options.experiment_width + \"px\";\n }\n\n // add tabIndex attribute to scope event listeners\n options.display_element.tabIndex = 0;\n\n // add CSS class to DOM_target\n if (options.display_element.className.indexOf(\"jspsych-display-element\") === -1) {\n options.display_element.className += \" jspsych-display-element\";\n }\n this.DOM_target.className += \"jspsych-content\";\n\n // create listeners for user browser interaction\n this.data.createInteractionListeners();\n\n // add event for closing window\n window.addEventListener(\"beforeunload\", options.on_close);\n }\n\n private async loadExtensions(extensions) {\n // run the .initialize method of any extensions that are in use\n // these should return a Promise to indicate when loading is complete\n\n try {\n await Promise.all(\n extensions.map((extension) =>\n this.extensions[extension.type.info.name].initialize(extension.params || {})\n )\n );\n } catch (error_message) {\n console.error(error_message);\n throw new Error(error_message);\n }\n }\n\n private startExperiment() {\n this.finished = new Promise((resolve) => {\n this.resolveFinishedPromise = resolve;\n });\n\n // show progress bar if requested\n if (this.opts.show_progress_bar === true) {\n this.drawProgressBar(this.opts.message_progress_bar);\n }\n\n // record the start time\n this.exp_start_time = new Date();\n\n // begin!\n this.timeline.advance();\n this.doTrial(this.timeline.trial());\n }\n\n private finishExperiment() {\n const finish_result = this.opts.on_finish(this.data.get());\n\n const done_handler = () => {\n if (typeof this.timeline.end_message !== \"undefined\") {\n this.DOM_target.innerHTML = this.timeline.end_message;\n }\n this.resolveFinishedPromise();\n };\n\n if (finish_result) {\n Promise.resolve(finish_result).then(done_handler);\n } else {\n done_handler();\n }\n }\n\n private nextTrial() {\n // if experiment is paused, don't do anything.\n if (this.paused) {\n this.waiting = true;\n return;\n }\n\n this.global_trial_index++;\n\n // advance timeline\n this.timeline.markCurrentTrialComplete();\n const complete = this.timeline.advance();\n\n // update progress bar if shown\n if (this.opts.show_progress_bar === true && this.opts.auto_update_progress_bar === true) {\n this.updateProgressBar();\n }\n\n // check if experiment is over\n if (complete) {\n this.finishExperiment();\n return;\n }\n\n this.doTrial(this.timeline.trial());\n }\n\n private doTrial(trial) {\n this.current_trial = trial;\n this.current_trial_finished = false;\n\n // process all timeline variables for this trial\n this.evaluateTimelineVariables(trial);\n\n if (typeof trial.type === \"string\") {\n throw new MigrationError(\n \"A string was provided as the trial's `type` parameter. Since jsPsych v7, the `type` parameter needs to be a plugin object.\"\n );\n }\n\n // instantiate the plugin for this trial\n trial.type = {\n // this is a hack to internally keep the old plugin object structure and prevent touching more\n // of the core jspsych code\n ...autoBind(new trial.type(this)),\n info: trial.type.info,\n };\n\n // evaluate variables that are functions\n this.evaluateFunctionParameters(trial);\n\n // get default values for parameters\n this.setDefaultValues(trial);\n\n // about to execute callbacks\n this.internal.call_immediate = true;\n\n // call experiment wide callback\n this.opts.on_trial_start(trial);\n\n // call trial specific callback if it exists\n if (typeof trial.on_start === \"function\") {\n trial.on_start(trial);\n }\n\n // call any on_start functions for extensions\n if (Array.isArray(trial.extensions)) {\n for (const extension of trial.extensions) {\n this.extensions[extension.type.info.name].on_start(extension.params);\n }\n }\n\n // apply the focus to the element containing the experiment.\n this.DOM_container.focus();\n\n // reset the scroll on the DOM target\n this.DOM_target.scrollTop = 0;\n\n // add CSS classes to the DOM_target if they exist in trial.css_classes\n if (typeof trial.css_classes !== \"undefined\") {\n if (!Array.isArray(trial.css_classes) && typeof trial.css_classes === \"string\") {\n trial.css_classes = [trial.css_classes];\n }\n if (Array.isArray(trial.css_classes)) {\n this.DOM_target.classList.add(...trial.css_classes);\n }\n }\n\n // setup on_load event callback\n const load_callback = () => {\n if (typeof trial.on_load === \"function\") {\n trial.on_load();\n }\n\n // call any on_load functions for extensions\n if (Array.isArray(trial.extensions)) {\n for (const extension of trial.extensions) {\n this.extensions[extension.type.info.name].on_load(extension.params);\n }\n }\n };\n\n let trial_complete;\n if (!this.simulation_mode) {\n trial_complete = trial.type.trial(this.DOM_target, trial, load_callback);\n }\n if (this.simulation_mode) {\n // check if the trial supports simulation\n if (trial.type.simulate) {\n let trial_sim_opts;\n if (!trial.simulation_options) {\n trial_sim_opts = this.simulation_options.default;\n }\n if (trial.simulation_options) {\n if (typeof trial.simulation_options == \"string\") {\n if (this.simulation_options[trial.simulation_options]) {\n trial_sim_opts = this.simulation_options[trial.simulation_options];\n } else if (this.simulation_options.default) {\n console.log(\n `No matching simulation options found for \"${trial.simulation_options}\". Using \"default\" options.`\n );\n trial_sim_opts = this.simulation_options.default;\n } else {\n console.log(\n `No matching simulation options found for \"${trial.simulation_options}\" and no \"default\" options provided. Using the default values provided by the plugin.`\n );\n trial_sim_opts = {};\n }\n } else {\n trial_sim_opts = trial.simulation_options;\n }\n }\n trial_sim_opts = this.utils.deepCopy(trial_sim_opts);\n trial_sim_opts = this.replaceFunctionsWithValues(trial_sim_opts, null);\n\n if (trial_sim_opts?.simulate === false) {\n trial_complete = trial.type.trial(this.DOM_target, trial, load_callback);\n } else {\n trial_complete = trial.type.simulate(\n trial,\n trial_sim_opts?.mode || this.simulation_mode,\n trial_sim_opts,\n load_callback\n );\n }\n } else {\n // trial doesn't have a simulate method, so just run as usual\n trial_complete = trial.type.trial(this.DOM_target, trial, load_callback);\n }\n }\n\n // see if trial_complete is a Promise by looking for .then() function\n const is_promise = trial_complete && typeof trial_complete.then == \"function\";\n\n // in simulation mode we let the simulate function call the load_callback always.\n if (!is_promise && !this.simulation_mode) {\n load_callback();\n }\n\n // done with callbacks\n this.internal.call_immediate = false;\n }\n\n private evaluateTimelineVariables(trial) {\n for (const key of Object.keys(trial)) {\n if (key === \"type\") {\n // skip the `type` parameter as it contains a plugin\n //continue;\n }\n // timeline variables on the root level\n if (\n typeof trial[key] === \"object\" &&\n trial[key] !== null &&\n typeof trial[key].timelineVariablePlaceholder !== \"undefined\"\n ) {\n /*trial[key].toString().replace(/\\s/g, \"\") ==\n \"function(){returntimeline.timelineVariable(varname);}\"\n )*/ trial[key] = trial[key].timelineVariableFunction();\n }\n // timeline variables that are nested in objects\n if (typeof trial[key] === \"object\" && trial[key] !== null) {\n this.evaluateTimelineVariables(trial[key]);\n }\n }\n }\n\n private evaluateFunctionParameters(trial) {\n // set a flag so that jsPsych.timelineVariable() is immediately executed in this context\n this.internal.call_immediate = true;\n\n // iterate over each parameter\n for (const key of Object.keys(trial)) {\n // check to make sure parameter is not \"type\", since that was eval'd above.\n if (key !== \"type\") {\n // this if statement is checking to see if the parameter type is expected to be a function, in which case we should NOT evaluate it.\n // the first line checks if the parameter is defined in the universalPluginParameters set\n // the second line checks the plugin-specific parameters\n if (\n typeof universalPluginParameters[key] !== \"undefined\" &&\n universalPluginParameters[key].type !== ParameterType.FUNCTION\n ) {\n trial[key] = this.replaceFunctionsWithValues(trial[key], null);\n }\n if (\n typeof trial.type.info.parameters[key] !== \"undefined\" &&\n trial.type.info.parameters[key].type !== ParameterType.FUNCTION\n ) {\n trial[key] = this.replaceFunctionsWithValues(trial[key], trial.type.info.parameters[key]);\n }\n }\n }\n // reset so jsPsych.timelineVariable() is no longer immediately executed\n this.internal.call_immediate = false;\n }\n\n private replaceFunctionsWithValues(obj, info) {\n // null typeof is 'object' (?!?!), so need to run this first!\n if (obj === null) {\n return obj;\n }\n // arrays\n else if (Array.isArray(obj)) {\n for (let i = 0; i < obj.length; i++) {\n obj[i] = this.replaceFunctionsWithValues(obj[i], info);\n }\n }\n // objects\n else if (typeof obj === \"object\") {\n if (info === null || !info.nested) {\n for (const key of Object.keys(obj)) {\n if (key === \"type\") {\n // Ignore the object's `type` field because it contains a plugin and we do not want to\n // call plugin functions\n continue;\n }\n obj[key] = this.replaceFunctionsWithValues(obj[key], null);\n }\n } else {\n for (const key of Object.keys(obj)) {\n if (\n typeof info.nested[key] === \"object\" &&\n info.nested[key].type !== ParameterType.FUNCTION\n ) {\n obj[key] = this.replaceFunctionsWithValues(obj[key], info.nested[key]);\n }\n }\n }\n } else if (typeof obj === \"function\") {\n return obj();\n }\n return obj;\n }\n\n private setDefaultValues(trial) {\n for (const param in trial.type.info.parameters) {\n // check if parameter is complex with nested defaults\n if (trial.type.info.parameters[param].type === ParameterType.COMPLEX) {\n if (trial.type.info.parameters[param].array === true) {\n // iterate over each entry in the array\n trial[param].forEach(function (ip, i) {\n // check each parameter in the plugin description\n for (const p in trial.type.info.parameters[param].nested) {\n if (typeof trial[param][i][p] === \"undefined\" || trial[param][i][p] === null) {\n if (typeof trial.type.info.parameters[param].nested[p].default === \"undefined\") {\n console.error(\n \"You must specify a value for the \" +\n p +\n \" parameter (nested in the \" +\n param +\n \" parameter) in the \" +\n trial.type +\n \" plugin.\"\n );\n } else {\n trial[param][i][p] = trial.type.info.parameters[param].nested[p].default;\n }\n }\n }\n });\n }\n }\n // if it's not nested, checking is much easier and do that here:\n else if (typeof trial[param] === \"undefined\" || trial[param] === null) {\n if (typeof trial.type.info.parameters[param].default === \"undefined\") {\n console.error(\n \"You must specify a value for the \" +\n param +\n \" parameter in the \" +\n trial.type.info.name +\n \" plugin.\"\n );\n } else {\n trial[param] = trial.type.info.parameters[param].default;\n }\n }\n }\n }\n\n private async checkExclusions(exclusions) {\n if (exclusions.min_width || exclusions.min_height || exclusions.audio) {\n console.warn(\n \"The exclusions option in `initJsPsych()` is deprecated and will be removed in a future version. We recommend using the browser-check plugin instead. See https://www.jspsych.org/latest/plugins/browser-check/.\"\n );\n }\n // MINIMUM SIZE\n if (exclusions.min_width || exclusions.min_height) {\n const mw = exclusions.min_width || 0;\n const mh = exclusions.min_height || 0;\n\n if (window.innerWidth < mw || window.innerHeight < mh) {\n this.getDisplayElement().innerHTML =\n \"<p>Your browser window is too small to complete this experiment. \" +\n \"Please maximize the size of your browser window. If your browser window is already maximized, \" +\n \"you will not be able to complete this experiment.</p>\" +\n \"<p>The minimum width is \" +\n mw +\n \"px. Your current width is \" +\n window.innerWidth +\n \"px.</p>\" +\n \"<p>The minimum height is \" +\n mh +\n \"px. Your current height is \" +\n window.innerHeight +\n \"px.</p>\";\n\n // Wait for window size to increase\n while (window.innerWidth < mw || window.innerHeight < mh) {\n await delay(100);\n }\n\n this.getDisplayElement().innerHTML = \"\";\n }\n }\n\n // WEB AUDIO API\n if (typeof exclusions.audio !== \"undefined\" && exclusions.audio) {\n if (!window.hasOwnProperty(\"AudioContext\") && !window.hasOwnProperty(\"webkitAudioContext\")) {\n this.getDisplayElement().innerHTML =\n \"<p>Your browser does not support the WebAudio API, which means that you will not \" +\n \"be able to complete the experiment.</p><p>Browsers that support the WebAudio API include \" +\n \"Chrome, Firefox, Safari, and Edge.</p>\";\n throw new Error();\n }\n }\n }\n\n private drawProgressBar(msg) {\n document\n .querySelector(\".jspsych-display-element\")\n .insertAdjacentHTML(\n \"afterbegin\",\n '<div id=\"jspsych-progressbar-container\">' +\n \"<span>\" +\n msg +\n \"</span>\" +\n '<div id=\"jspsych-progressbar-outer\">' +\n '<div id=\"jspsych-progressbar-inner\"></div>' +\n \"</div></div>\"\n );\n }\n\n private updateProgressBar() {\n this.setProgressBar(this.getProgress().percent_complete / 100);\n }\n\n private progress_bar_amount = 0;\n\n setProgressBar(proportion_complete) {\n proportion_complete = Math.max(Math.min(1, proportion_complete), 0);\n document.querySelector<HTMLElement>(\"#jspsych-progressbar-inner\").style.width =\n proportion_complete * 100 + \"%\";\n this.progress_bar_amount = proportion_complete;\n }\n\n getProgressBarCompleted() {\n return this.progress_bar_amount;\n }\n}\n","import autoBind from \"auto-bind\";\n\nimport { JsPsych } from \"../../JsPsych\";\nimport { HardwareAPI } from \"./HardwareAPI\";\nimport { KeyboardListenerAPI } from \"./KeyboardListenerAPI\";\nimport { MediaAPI } from \"./MediaAPI\";\nimport { SimulationAPI } from \"./SimulationAPI\";\nimport { TimeoutAPI } from \"./TimeoutAPI\";\n\nexport function createJointPluginAPIObject(jsPsych: JsPsych) {\n const settings = jsPsych.getInitSettings();\n return Object.assign(\n {},\n ...[\n new KeyboardListenerAPI(\n jsPsych.getDisplayContainerElement,\n settings.case_sensitive_responses,\n settings.minimum_valid_rt\n ),\n new TimeoutAPI(),\n new MediaAPI(settings.use_webaudio, jsPsych.webaudio_context),\n new HardwareAPI(),\n new SimulationAPI(),\n ].map((object) => autoBind(object))\n ) as KeyboardListenerAPI & TimeoutAPI & MediaAPI & HardwareAPI & SimulationAPI;\n}\n\nexport type PluginAPI = ReturnType<typeof createJointPluginAPIObject>;\n","import { JsPsych } from \"./JsPsych\";\nimport { MigrationError } from \"./migration\";\n\n// temporary patch for Safari\nif (\n typeof window !== \"undefined\" &&\n window.hasOwnProperty(\"webkitAudioContext\") &&\n !window.hasOwnProperty(\"AudioContext\")\n) {\n // @ts-expect-error\n window.AudioContext = webkitAudioContext;\n}\n// end patch\n\n// The following function provides a uniform interface to initialize jsPsych, no matter whether a\n// browser supports ES6 classes or not (and whether the ES6 build or the Babel build is used).\n/**\n * Creates a new JsPsych instance using the provided options.\n *\n * @param options The options to pass to the JsPsych constructor\n * @returns A new JsPsych instance\n */\nexport function initJsPsych(options?) {\n const jsPsych = new JsPsych(options);\n\n // Handle invocations of non-existent v6 methods with migration errors\n const migrationMessages = {\n init: \"`jsPsych.init()` was replaced by `initJsPsych()` in jsPsych v7.\",\n\n ALL_KEYS: 'jsPsych.ALL_KEYS was replaced by the \"ALL_KEYS\" string in jsPsych v7.',\n NO_KEYS: 'jsPsych.NO_KEYS was replaced by the \"NO_KEYS\" string in jsPsych v7.',\n\n // Getter functions that were renamed\n currentTimelineNodeID:\n \"`currentTimelineNodeID()` was renamed to `getCurrentTimelineNodeID()` in jsPsych v7.\",\n progress: \"`progress()` was renamed to `getProgress()` in jsPsych v7.\",\n startTime: \"`startTime()` was renamed to `getStartTime()` in jsPsych v7.\",\n totalTime: \"`totalTime()` was renamed to `getTotalTime()` in jsPsych v7.\",\n currentTrial: \"`currentTrial()` was renamed to `getCurrentTrial()` in jsPsych v7.\",\n initSettings: \"`initSettings()` was renamed to `getInitSettings()` in jsPsych v7.\",\n allTimelineVariables:\n \"`allTimelineVariables()` was renamed to `getAllTimelineVariables()` in jsPsych v7.\",\n };\n\n Object.defineProperties(\n jsPsych,\n Object.fromEntries(\n Object.entries(migrationMessages).map(([key, message]) => [\n key,\n {\n get() {\n throw new MigrationError(message);\n },\n },\n ])\n )\n );\n\n return jsPsych;\n}\n\nexport { JsPsych } from \"./JsPsych\";\nexport {\n JsPsychPlugin,\n PluginInfo,\n TrialType,\n ParameterType,\n universalPluginParameters,\n UniversalPluginParameters,\n} from \"./modules/plugins\";\nexport { JsPsychExtension, JsPsychExtensionInfo } from \"./modules/extensions\";\n"],"names":["__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","value","step","next","e","rejected","result","done","then","apply","getAllProperties","object","properties","Set","Reflect","ownKeys","key","add","getPrototypeOf","Object","prototype","autoBind","self","include","exclude","filter","match","pattern","test","some","constructor","descriptor","getOwnPropertyDescriptor","bind","MigrationError","Error","message","super","this","name","unique","arr","deepCopy","obj","out","Array","isArray","x","push","hasOwnProperty","window","jsPsych","init","data","randomization","turk","pluginAPI","ALL_KEYS","NO_KEYS","ParameterType","DataColumn","values","sum","s","v","mean","count","median","length","numbers","slice","sort","a","b","middle","Math","floor","min","max","variance","sum_square_error","pow","sd","mse","sqrt","frequencies","all","eval_fn","subset","DataCollection","trials","new_data","join","other_data_collection","concat","top","first","n","last","readOnly","addToAll","trial","assign","addToLast","filters","f","filtered_data","keep","keys","filterCustom","fn","select","column","ignore","columns","o","delete_key","uniqueNames","names","includes","csv","objArray","array","JSON","parse","line","row","keyString","replace","col","stringify","JSON2CSV","json","pretty","localSave","format","filename","data_string","toLowerCase","textstr","blobToSave","Blob","type","blobURL","webkitURL","createObjectURL","URL","link","document","createElement","id","style","display","download","href","click","saveTextToFile","JsPsychData","reset","allData","interactionData","get","getInteractionData","write","data_object","progress","getProgress","getCurrentTrial","default_data","trial_type","info","trial_index","current_trial_global","time_elapsed","getTotalTime","internal_node_id","getCurrentTimelineNodeID","dataProperties","addProperties","addDataToLastTrial","getDataByTimelineNode","node_id","getLastTrialData","getLastTimelineData","parent_node_id","substr","lastIndexOf","displayData","console","log","getDisplayElement","innerHTML","getElementById","textContent","urlVariables","query_string","location","search","split","i","p","decodeURIComponent","getQueryString","getURLVariable","whichvar","createInteractionListeners","addEventListener","event","time","getInitSettings","on_interaction_data_update","fullscreenchange","isFullScreen","webkitIsFullScreen","mozIsFullScreen","fullscreenElement","_customInsert","_fullreset","HardwareAPI","evt","hardwareConnected","hardware","mess","jspsychEvt","CustomEvent","detail","dispatchEvent","KeyboardListenerAPI","getRootElement","areResponsesCaseSensitive","minimumValidRt","registerRootListeners","areRootListenersRegistered","rootElement","rootKeydownListener","rootKeyupListener","listener","from","listeners","heldKeys","toLowerCaseIfInsensitive","string","delete","isResponseValid","validResponses","allowHeldKey","has","getKeyboardResponse","callback_function","valid_responses","rt_method","persist","audio_context","audio_context_start_time","allow_held_key","minimum_valid_rt","startTime","performance","now","map","r","rt","round","currentTime","preventDefault","cancelKeyboardResponse","cancelAllKeyboardResponses","clear","compareKeys","key1","key2","error","universalPluginParameters","OBJECT","pretty_name","default","on_start","FUNCTION","on_finish","on_load","post_trial_gap","INT","css_classes","STRING","preloadParameterTypes","AUDIO","IMAGE","VIDEO","MediaAPI","useWebaudio","webaudioContext","Map","getVideoBuffer","videoID","video_buffers","initAudio","context","audioContext","state","resume","getAudioBuffer","audioID","audio_buffers","preloadAudio","files","callback_complete","callback_load","filepath","callback_error","error_msg","flat","n_loaded","load_audio_file_webaudio","source","request","XMLHttpRequest","open","responseType","onload","decodeAudioData","response","buffer","onerror","err","status","onloadend","send","preload_requests","load_audio_file_html5audio","audio","Audio","handleCanPlayThrough","removeEventListener","handleError","src","handleAbort","file","preloadImages","images","img","Image","img_cache","preloadVideo","videos","video","videoBlob","getAutoPreloadList","timeline_description","preloadPaths","fromEntries","traverseTimeline","node","inheritedTrialType","timeline","childNode","pluginName","parameters","preloadMap","set","entries","_name","preload","parameterName","parameterType","parameterValue","elements","element","cancelPreloads","oncanplaythrough","onabort","initializeMicrophoneRecorder","stream","recorder","MediaRecorder","microphone_recorder","getMicrophoneRecorder","SimulationAPI","body","keyDown","KeyboardEvent","keyUp","pressKey","delay","setTimeout","clickTarget","target","MouseEvent","bubbles","fillTextInput","text","getValidKey","choices","possible_keys","random","flat_choices","mergeSimulationData","simulation_options","ensureSimulationDataConsistency","trial_duration","correct","allow_response_before_complete","sequence_reps","frame_time","min_time","stimuli","TimeoutAPI","callback","handle","timeout_handlers","clearAllTimeouts","handler","clearTimeout","wordList","words","options","word","maxLength","wordUsed","rightSize","generateRandomWord","generateWordWithMaxLength","randInt","lessThan","exactly","wordsPerString","formatter","separator","total","results","token","relativeIndex","randomWords","repeat","repetitions","unpack","arr_isArray","rep_isArray","warn","reps","allsamples","j","shuffle","unpackArray","copy_array","t","m","shuffleAlternateGroups","arr_groups","random_group_order","n_groups","group_order","randomized_groups","min_length","sampleWithoutReplacement","size","sampleWithReplacement","weights","normalized_weights","weight_sum","weight","cumulative_weights","samp","rnd","index","sampleNormal","standard_deviation","u","cos","PI","randn_bm","sampleExponential","rate","equalityTest","random_shuffle","random_pick","new_neighbor","factors","design","factorName","factor","new_design","level","cell","chars","lower","upper","positive","opts","rw","turkInfo","previewMode","outsideTurk","hitId","assignmentId","workerId","turkSubmitTo","param","url","RegExp","exec","referrer","unescape","form","method","action","hiddenField","appendChild","submit","TimelineNode","parent","relativeID","current_location","current_variable_set","current_repetition","current_iteration","parent_node","relative_id","timeline_parameters","loop_function","conditional_function","sample","randomize_order","timeline_variables","on_timeline_finish","on_timeline_start","setTimelineVariablesOrder","node_data","node_trial_data","merged_parameters","merged_data","trial_parameters","markCurrentTrialComplete","nextRepetiton","order","groups","randomize_group_order","nextSet","advance","internal","call_immediate","conditional_result","have_node_to_run","generatedData","isComplete","getTimelineVariableValue","variable_name","findTimelineVariable","timelineVariable","loc","allTimelineVariables","all_tvs","allTimelineVariablesNames","all_tvs_vals","so_far","percentComplete","total_trials","completed_trials","end","endActiveNode","ID","activeID","trialsOfType","insert","ms","JsPsych","utils","display_element","undefined","on_trial_start","on_trial_finish","on_data_update","on_close","use_webaudio","exclusions","show_progress_bar","message_progress_bar","auto_update_progress_bar","default_iti","experiment_width","override_safe_mode","case_sensitive_responses","extensions","webaudio_context","AudioContext","protocol","file_protocol","settings","getDisplayContainerElement","createJointPluginAPIObject","extension","version","run","timelineDescription","prepareDom","checkExclusions","loadExtensions","documentElement","setAttribute","startExperiment","finished","simulate","simulation_mode","global_trial_index","percent_complete","getStartTime","exp_start_time","Date","getTime","DOM_target","DOM_container","finishTrial","current_trial_finished","current_trial","classList","remove","trial_data_values","save_trial_parameters","key_val","toString","ext_data_values","params","nextTrial","endExperiment","end_message","endCurrentTimeline","varname","immediate","timelineVariablePlaceholder","timelineVariableFunction","getAllTimelineVariables","addNodeToEndOfTimeline","new_timeline","preload_callback","pauseExperiment","paused","resumeExperiment","waiting","loadFail","getSafeModeStatus","getTimeline","readyState","querySelector","height","margin","width","Element","tabIndex","className","indexOf","initialize","error_message","resolveFinishedPromise","drawProgressBar","doTrial","finishExperiment","finish_result","done_handler","complete","updateProgressBar","evaluateTimelineVariables","evaluateFunctionParameters","setDefaultValues","focus","scrollTop","load_callback","trial_complete","trial_sim_opts","replaceFunctionsWithValues","mode","nested","COMPLEX","forEach","ip","min_width","min_height","mw","mh","innerWidth","innerHeight","msg","insertAdjacentHTML","setProgressBar","proportion_complete","progress_bar_amount","getProgressBarCompleted","webkitAudioContext","defineProperties","currentTimelineNodeID","totalTime","currentTrial","initSettings"],"mappings":"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"}
1
+ {"version":3,"file":"index.browser.min.js","sources":["../../../node_modules/tslib/tslib.es6.js","../../../node_modules/auto-bind/index.js","../src/migration.ts","../src/modules/utils.ts","../src/modules/plugins.ts","../src/modules/data/DataColumn.ts","../src/modules/data/DataCollection.ts","../src/modules/data/utils.ts","../src/modules/data/index.ts","../src/modules/plugin-api/HardwareAPI.ts","../src/modules/plugin-api/KeyboardListenerAPI.ts","../src/modules/plugin-api/MediaAPI.ts","../src/modules/plugin-api/SimulationAPI.ts","../src/modules/plugin-api/TimeoutAPI.ts","../../../node_modules/random-words/index.js","../src/modules/randomization.ts","../src/modules/turk.ts","../src/TimelineNode.ts","../src/JsPsych.ts","../src/modules/plugin-api/index.ts","../src/index.ts"],"sourcesContent":["/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n","'use strict';\n\n// Gets all non-builtin properties up the prototype chain\nconst getAllProperties = object => {\n\tconst properties = new Set();\n\n\tdo {\n\t\tfor (const key of Reflect.ownKeys(object)) {\n\t\t\tproperties.add([object, key]);\n\t\t}\n\t} while ((object = Reflect.getPrototypeOf(object)) && object !== Object.prototype);\n\n\treturn properties;\n};\n\nmodule.exports = (self, {include, exclude} = {}) => {\n\tconst filter = key => {\n\t\tconst match = pattern => typeof pattern === 'string' ? key === pattern : pattern.test(key);\n\n\t\tif (include) {\n\t\t\treturn include.some(match);\n\t\t}\n\n\t\tif (exclude) {\n\t\t\treturn !exclude.some(match);\n\t\t}\n\n\t\treturn true;\n\t};\n\n\tfor (const [object, key] of getAllProperties(self.constructor.prototype)) {\n\t\tif (key === 'constructor' || !filter(key)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst descriptor = Reflect.getOwnPropertyDescriptor(object, key);\n\t\tif (descriptor && typeof descriptor.value === 'function') {\n\t\t\tself[key] = self[key].bind(self);\n\t\t}\n\t}\n\n\treturn self;\n};\n","export class MigrationError extends Error {\n constructor(message = \"The global `jsPsych` variable is no longer available in jsPsych v7.\") {\n super(\n `${message} Please follow the migration guide at https://www.jspsych.org/7.0/support/migration-v7/ to update your experiment.`\n );\n this.name = \"MigrationError\";\n }\n}\n\n// Define a global jsPsych object to handle invocations on it with migration errors\n(window as any).jsPsych = {\n get init() {\n throw new MigrationError(\"`jsPsych.init()` was replaced by `initJsPsych()` in jsPsych v7.\");\n },\n\n get data() {\n throw new MigrationError();\n },\n get randomization() {\n throw new MigrationError();\n },\n get turk() {\n throw new MigrationError();\n },\n get pluginAPI() {\n throw new MigrationError();\n },\n\n get ALL_KEYS() {\n throw new MigrationError(\n 'jsPsych.ALL_KEYS was replaced by the \"ALL_KEYS\" string in jsPsych v7.'\n );\n },\n get NO_KEYS() {\n throw new MigrationError('jsPsych.NO_KEYS was replaced by the \"NO_KEYS\" string in jsPsych v7.');\n },\n};\n","/**\n * Finds all of the unique items in an array.\n * @param arr The array to extract unique values from\n * @returns An array with one copy of each unique item in `arr`\n */\nexport function unique(arr: Array<any>) {\n return [...new Set(arr)];\n}\n\nexport function deepCopy(obj) {\n if (!obj) return obj;\n let out;\n if (Array.isArray(obj)) {\n out = [];\n for (const x of obj) {\n out.push(deepCopy(x));\n }\n return out;\n } else if (typeof obj === \"object\" && obj !== null) {\n out = {};\n for (const key in obj) {\n if (obj.hasOwnProperty(key)) {\n out[key] = deepCopy(obj[key]);\n }\n }\n return out;\n } else {\n return obj;\n }\n}\n","/**\nFlatten the type output to improve type hints shown in editors.\nBorrowed from type-fest\n*/\ntype Simplify<T> = { [KeyType in keyof T]: T[KeyType] };\n\n/**\nCreate a type that makes the given keys required. The remaining keys are kept as is.\nBorrowed from type-fest\n*/\ntype SetRequired<BaseType, Keys extends keyof BaseType> = Simplify<\n Omit<BaseType, Keys> & Required<Pick<BaseType, Keys>>\n>;\n\n/**\n * Parameter types for plugins\n */\nexport enum ParameterType {\n BOOL,\n STRING,\n INT,\n FLOAT,\n FUNCTION,\n KEY,\n KEYS,\n SELECT,\n HTML_STRING,\n IMAGE,\n AUDIO,\n VIDEO,\n OBJECT,\n COMPLEX,\n TIMELINE,\n}\n\ntype ParameterTypeMap = {\n [ParameterType.BOOL]: boolean;\n [ParameterType.STRING]: string;\n [ParameterType.INT]: number;\n [ParameterType.FLOAT]: number;\n [ParameterType.FUNCTION]: (...args: any[]) => any;\n [ParameterType.KEY]: string;\n [ParameterType.KEYS]: string[] | \"ALL_KEYS\" | \"NO_KEYS\";\n [ParameterType.SELECT]: any;\n [ParameterType.HTML_STRING]: string;\n [ParameterType.IMAGE]: string;\n [ParameterType.AUDIO]: string;\n [ParameterType.VIDEO]: string;\n [ParameterType.OBJECT]: object;\n [ParameterType.COMPLEX]: any;\n [ParameterType.TIMELINE]: any;\n};\n\nexport interface ParameterInfo {\n type: ParameterType;\n array?: boolean;\n pretty_name?: string;\n default?: any;\n preload?: boolean;\n}\n\nexport interface ParameterInfos {\n [key: string]: ParameterInfo;\n}\n\ntype InferredParameter<I extends ParameterInfo> = I[\"array\"] extends true\n ? Array<ParameterTypeMap[I[\"type\"]]>\n : ParameterTypeMap[I[\"type\"]];\n\ntype RequiredParameterNames<I extends ParameterInfos> = {\n [K in keyof I]: I[K][\"default\"] extends undefined ? K : never;\n}[keyof I];\n\ntype InferredParameters<I extends ParameterInfos> = SetRequired<\n {\n [Property in keyof I]?: InferredParameter<I[Property]>;\n },\n RequiredParameterNames<I>\n>;\n\nexport const universalPluginParameters = <const>{\n /**\n * Data to add to this trial (key-value pairs)\n */\n data: {\n type: ParameterType.OBJECT,\n pretty_name: \"Data\",\n default: {},\n },\n /**\n * Function to execute when trial begins\n */\n on_start: {\n type: ParameterType.FUNCTION,\n pretty_name: \"On start\",\n default: function () {\n return;\n },\n },\n /**\n * Function to execute when trial is finished\n */\n on_finish: {\n type: ParameterType.FUNCTION,\n pretty_name: \"On finish\",\n default: function () {\n return;\n },\n },\n /**\n * Function to execute after the trial has loaded\n */\n on_load: {\n type: ParameterType.FUNCTION,\n pretty_name: \"On load\",\n default: function () {\n return;\n },\n },\n /**\n * Length of gap between the end of this trial and the start of the next trial\n */\n post_trial_gap: {\n type: ParameterType.INT,\n pretty_name: \"Post trial gap\",\n default: null,\n },\n /**\n * A list of CSS classes to add to the jsPsych display element for the duration of this trial\n */\n css_classes: {\n type: ParameterType.STRING,\n pretty_name: \"Custom CSS classes\",\n default: null,\n },\n /**\n * Options to control simulation mode for the trial.\n */\n simulation_options: {\n type: ParameterType.COMPLEX,\n default: null,\n },\n};\n\nexport type UniversalPluginParameters = InferredParameters<typeof universalPluginParameters>;\n\nexport interface PluginInfo {\n name: string;\n parameters: {\n [key: string]: ParameterInfo;\n };\n}\n\nexport interface JsPsychPlugin<I extends PluginInfo> {\n trial(\n display_element: HTMLElement,\n trial: TrialType<I>,\n on_load?: () => void\n ): void | Promise<any>;\n}\n\nexport type TrialType<I extends PluginInfo> = InferredParameters<I[\"parameters\"]> &\n UniversalPluginParameters;\n\nexport type PluginParameters<I extends PluginInfo> = InferredParameters<I[\"parameters\"]>;\n","export class DataColumn {\n constructor(public values = []) {}\n\n sum() {\n let s = 0;\n for (const v of this.values) {\n s += v;\n }\n return s;\n }\n\n mean() {\n return this.sum() / this.count();\n }\n\n median() {\n if (this.values.length === 0) {\n return undefined;\n }\n const numbers = this.values.slice(0).sort(function (a, b) {\n return a - b;\n });\n const middle = Math.floor(numbers.length / 2);\n const isEven = numbers.length % 2 === 0;\n return isEven ? (numbers[middle] + numbers[middle - 1]) / 2 : numbers[middle];\n }\n\n min() {\n return Math.min.apply(null, this.values);\n }\n\n max() {\n return Math.max.apply(null, this.values);\n }\n\n count() {\n return this.values.length;\n }\n\n variance() {\n const mean = this.mean();\n let sum_square_error = 0;\n for (const x of this.values) {\n sum_square_error += Math.pow(x - mean, 2);\n }\n const mse = sum_square_error / (this.values.length - 1);\n return mse;\n }\n\n sd() {\n const mse = this.variance();\n const rmse = Math.sqrt(mse);\n return rmse;\n }\n\n frequencies() {\n const unique = {};\n for (const x of this.values) {\n if (typeof unique[x] === \"undefined\") {\n unique[x] = 1;\n } else {\n unique[x]++;\n }\n }\n return unique;\n }\n\n all(eval_fn) {\n for (const x of this.values) {\n if (!eval_fn(x)) {\n return false;\n }\n }\n return true;\n }\n\n subset(eval_fn) {\n const out = [];\n for (const x of this.values) {\n if (eval_fn(x)) {\n out.push(x);\n }\n }\n return new DataColumn(out);\n }\n}\n","import { deepCopy } from \"../utils\";\nimport { DataColumn } from \"./DataColumn\";\nimport { JSON2CSV, saveTextToFile } from \"./utils\";\n\nexport class DataCollection {\n private trials: any[];\n\n constructor(data = []) {\n this.trials = data;\n }\n\n push(new_data) {\n this.trials.push(new_data);\n return this;\n }\n\n join(other_data_collection: DataCollection) {\n this.trials = this.trials.concat(other_data_collection.values());\n return this;\n }\n\n top() {\n if (this.trials.length <= 1) {\n return this;\n } else {\n return new DataCollection([this.trials[this.trials.length - 1]]);\n }\n }\n\n /**\n * Queries the first n elements in a collection of trials.\n *\n * @param n A positive integer of elements to return. A value of\n * n that is less than 1 will throw an error.\n *\n * @return First n objects of a collection of trials. If fewer than\n * n trials are available, the trials.length elements will\n * be returned.\n *\n */\n first(n = 1) {\n if (n < 1) {\n throw `You must query with a positive nonzero integer. Please use a\n different value for n.`;\n }\n if (this.trials.length === 0) return new DataCollection();\n if (n > this.trials.length) n = this.trials.length;\n return new DataCollection(this.trials.slice(0, n));\n }\n\n /**\n * Queries the last n elements in a collection of trials.\n *\n * @param n A positive integer of elements to return. A value of\n * n that is less than 1 will throw an error.\n *\n * @return Last n objects of a collection of trials. If fewer than\n * n trials are available, the trials.length elements will\n * be returned.\n *\n */\n last(n = 1) {\n if (n < 1) {\n throw `You must query with a positive nonzero integer. Please use a\n different value for n.`;\n }\n if (this.trials.length === 0) return new DataCollection();\n if (n > this.trials.length) n = this.trials.length;\n return new DataCollection(this.trials.slice(this.trials.length - n, this.trials.length));\n }\n\n values() {\n return this.trials;\n }\n\n count() {\n return this.trials.length;\n }\n\n readOnly() {\n return new DataCollection(deepCopy(this.trials));\n }\n\n addToAll(properties) {\n for (const trial of this.trials) {\n Object.assign(trial, properties);\n }\n return this;\n }\n\n addToLast(properties) {\n if (this.trials.length != 0) {\n Object.assign(this.trials[this.trials.length - 1], properties);\n }\n return this;\n }\n\n filter(filters) {\n // [{p1: v1, p2:v2}, {p1:v2}]\n // {p1: v1}\n let f;\n if (!Array.isArray(filters)) {\n f = deepCopy([filters]);\n } else {\n f = deepCopy(filters);\n }\n\n const filtered_data = [];\n for (const trial of this.trials) {\n let keep = false;\n for (const filter of f) {\n let match = true;\n for (const key of Object.keys(filter)) {\n if (typeof trial[key] !== \"undefined\" && trial[key] === filter[key]) {\n // matches on this key!\n } else {\n match = false;\n }\n }\n if (match) {\n keep = true;\n break;\n } // can break because each filter is OR.\n }\n if (keep) {\n filtered_data.push(trial);\n }\n }\n\n return new DataCollection(filtered_data);\n }\n\n filterCustom(fn) {\n return new DataCollection(this.trials.filter(fn));\n }\n\n select(column) {\n const values = [];\n for (const trial of this.trials) {\n if (typeof trial[column] !== \"undefined\") {\n values.push(trial[column]);\n }\n }\n return new DataColumn(values);\n }\n\n ignore(columns) {\n if (!Array.isArray(columns)) {\n columns = [columns];\n }\n const o = deepCopy(this.trials);\n for (const trial of o) {\n for (const delete_key of columns) {\n delete trial[delete_key];\n }\n }\n return new DataCollection(o);\n }\n\n uniqueNames() {\n const names = [];\n\n for (const trial of this.trials) {\n for (const key of Object.keys(trial)) {\n if (!names.includes(key)) {\n names.push(key);\n }\n }\n }\n\n return names;\n }\n\n csv() {\n return JSON2CSV(this.trials);\n }\n\n json(pretty = false) {\n if (pretty) {\n return JSON.stringify(this.trials, null, \"\\t\");\n }\n return JSON.stringify(this.trials);\n }\n\n localSave(format, filename) {\n format = format.toLowerCase();\n let data_string;\n if (format === \"json\") {\n data_string = this.json();\n } else if (format === \"csv\") {\n data_string = this.csv();\n } else {\n throw new Error('Invalid format specified for localSave. Must be \"json\" or \"csv\".');\n }\n\n saveTextToFile(data_string, filename);\n }\n}\n","// private function to save text file on local drive\nexport function saveTextToFile(textstr: string, filename: string) {\n const blobToSave = new Blob([textstr], {\n type: \"text/plain\",\n });\n let blobURL = \"\";\n if (typeof window.webkitURL !== \"undefined\") {\n blobURL = window.webkitURL.createObjectURL(blobToSave);\n } else {\n blobURL = window.URL.createObjectURL(blobToSave);\n }\n\n const link = document.createElement(\"a\");\n link.id = \"jspsych-download-as-text-link\";\n link.style.display = \"none\";\n link.download = filename;\n link.href = blobURL;\n link.click();\n}\n\n// this function based on code suggested by StackOverflow users:\n// http://stackoverflow.com/users/64741/zachary\n// http://stackoverflow.com/users/317/joseph-sturtevant\n\nexport function JSON2CSV(objArray) {\n const array = typeof objArray != \"object\" ? JSON.parse(objArray) : objArray;\n let line = \"\";\n let result = \"\";\n const columns = [];\n\n for (const row of array) {\n for (const key in row) {\n let keyString = key + \"\";\n keyString = '\"' + keyString.replace(/\"/g, '\"\"') + '\",';\n if (!columns.includes(key)) {\n columns.push(key);\n line += keyString;\n }\n }\n }\n\n line = line.slice(0, -1); // removes last comma\n result += line + \"\\r\\n\";\n\n for (const row of array) {\n line = \"\";\n for (const col of columns) {\n let value = typeof row[col] === \"undefined\" ? \"\" : row[col];\n if (typeof value == \"object\") {\n value = JSON.stringify(value);\n }\n const valueString = value + \"\";\n line += '\"' + valueString.replace(/\"/g, '\"\"') + '\",';\n }\n\n line = line.slice(0, -1);\n result += line + \"\\r\\n\";\n }\n\n return result;\n}\n\n// this function is modified from StackOverflow:\n// http://stackoverflow.com/posts/3855394\n\nexport function getQueryString() {\n const a = window.location.search.substr(1).split(\"&\");\n const b = {};\n for (let i = 0; i < a.length; ++i) {\n const p = a[i].split(\"=\", 2);\n if (p.length == 1) b[p[0]] = \"\";\n else b[p[0]] = decodeURIComponent(p[1].replace(/\\+/g, \" \"));\n }\n return b;\n}\n","import { JsPsych } from \"../../JsPsych\";\nimport { DataCollection } from \"./DataCollection\";\nimport { getQueryString } from \"./utils\";\n\nexport class JsPsychData {\n // data storage object\n private allData: DataCollection;\n\n // browser interaction event data\n private interactionData: DataCollection;\n\n // data properties for all trials\n private dataProperties = {};\n\n // cache the query_string\n private query_string;\n\n constructor(private jsPsych: JsPsych) {\n this.reset();\n }\n\n reset() {\n this.allData = new DataCollection();\n this.interactionData = new DataCollection();\n }\n\n get() {\n return this.allData;\n }\n\n getInteractionData() {\n return this.interactionData;\n }\n\n write(data_object) {\n const progress = this.jsPsych.getProgress();\n const trial = this.jsPsych.getCurrentTrial();\n\n //var trial_opt_data = typeof trial.data == 'function' ? trial.data() : trial.data;\n\n const default_data = {\n trial_type: trial.type.info.name,\n trial_index: progress.current_trial_global,\n time_elapsed: this.jsPsych.getTotalTime(),\n internal_node_id: this.jsPsych.getCurrentTimelineNodeID(),\n };\n\n this.allData.push({\n ...data_object,\n ...trial.data,\n ...default_data,\n ...this.dataProperties,\n });\n }\n\n addProperties(properties) {\n // first, add the properties to all data that's already stored\n this.allData.addToAll(properties);\n\n // now add to list so that it gets appended to all future data\n this.dataProperties = Object.assign({}, this.dataProperties, properties);\n }\n\n addDataToLastTrial(data) {\n this.allData.addToLast(data);\n }\n\n getDataByTimelineNode(node_id) {\n return this.allData.filterCustom(\n (x) => x.internal_node_id.slice(0, node_id.length) === node_id\n );\n }\n\n getLastTrialData() {\n return this.allData.top();\n }\n\n getLastTimelineData() {\n const lasttrial = this.getLastTrialData();\n const node_id = lasttrial.select(\"internal_node_id\").values[0];\n if (typeof node_id === \"undefined\") {\n return new DataCollection();\n } else {\n const parent_node_id = node_id.substr(0, node_id.lastIndexOf(\"-\"));\n const lastnodedata = this.getDataByTimelineNode(parent_node_id);\n return lastnodedata;\n }\n }\n\n displayData(format = \"json\") {\n format = format.toLowerCase();\n if (format != \"json\" && format != \"csv\") {\n console.log(\"Invalid format declared for displayData function. Using json as default.\");\n format = \"json\";\n }\n\n const data_string = format === \"json\" ? this.allData.json(true) : this.allData.csv();\n\n const display_element = this.jsPsych.getDisplayElement();\n\n display_element.innerHTML = '<pre id=\"jspsych-data-display\"></pre>';\n\n document.getElementById(\"jspsych-data-display\").textContent = data_string;\n }\n\n urlVariables() {\n if (typeof this.query_string == \"undefined\") {\n this.query_string = getQueryString();\n }\n return this.query_string;\n }\n\n getURLVariable(whichvar) {\n return this.urlVariables()[whichvar];\n }\n\n createInteractionListeners() {\n // blur event capture\n window.addEventListener(\"blur\", () => {\n const data = {\n event: \"blur\",\n trial: this.jsPsych.getProgress().current_trial_global,\n time: this.jsPsych.getTotalTime(),\n };\n this.interactionData.push(data);\n this.jsPsych.getInitSettings().on_interaction_data_update(data);\n });\n\n // focus event capture\n window.addEventListener(\"focus\", () => {\n const data = {\n event: \"focus\",\n trial: this.jsPsych.getProgress().current_trial_global,\n time: this.jsPsych.getTotalTime(),\n };\n this.interactionData.push(data);\n this.jsPsych.getInitSettings().on_interaction_data_update(data);\n });\n\n // fullscreen change capture\n const fullscreenchange = () => {\n const data = {\n event:\n // @ts-expect-error\n document.isFullScreen ||\n // @ts-expect-error\n document.webkitIsFullScreen ||\n // @ts-expect-error\n document.mozIsFullScreen ||\n document.fullscreenElement\n ? \"fullscreenenter\"\n : \"fullscreenexit\",\n trial: this.jsPsych.getProgress().current_trial_global,\n time: this.jsPsych.getTotalTime(),\n };\n this.interactionData.push(data);\n this.jsPsych.getInitSettings().on_interaction_data_update(data);\n };\n\n document.addEventListener(\"fullscreenchange\", fullscreenchange);\n document.addEventListener(\"mozfullscreenchange\", fullscreenchange);\n document.addEventListener(\"webkitfullscreenchange\", fullscreenchange);\n }\n\n // public methods for testing purposes. not recommended for use.\n _customInsert(data) {\n this.allData = new DataCollection(data);\n }\n\n _fullreset() {\n this.reset();\n this.dataProperties = {};\n }\n}\n","export class HardwareAPI {\n /**\n * Indicates whether this instance of jspsych has opened a hardware connection through our browser\n * extension\n **/\n hardwareConnected = false;\n\n constructor() {\n //it might be useful to open up a line of communication from the extension back to this page\n //script, again, this will have to pass through DOM events. For now speed is of no concern so I\n //will use jQuery\n document.addEventListener(\"jspsych-activate\", (evt) => {\n this.hardwareConnected = true;\n });\n }\n\n /**\n * Allows communication with user hardware through our custom Google Chrome extension + native C++ program\n * @param\t\tmess\tThe message to be passed to our extension, see its documentation for the expected members of this object.\n * @author\tDaniel Rivas\n *\n */\n hardware(mess) {\n //since Chrome extension content-scripts do not share the javascript environment with the page\n //script that loaded jspsych, we will need to use hacky methods like communicating through DOM\n //events.\n const jspsychEvt = new CustomEvent(\"jspsych\", { detail: mess });\n document.dispatchEvent(jspsychEvt);\n //And voila! it will be the job of the content script injected by the extension to listen for\n //the event and do the appropriate actions.\n }\n}\n","import autoBind from \"auto-bind\";\n\nexport type KeyboardListener = (e: KeyboardEvent) => void;\n\nexport type ValidResponses = string[] | \"ALL_KEYS\" | \"NO_KEYS\";\n\nexport interface GetKeyboardResponseOptions {\n callback_function: any;\n valid_responses?: ValidResponses;\n rt_method?: \"performance\" | \"audio\";\n persist?: boolean;\n audio_context?: AudioContext;\n audio_context_start_time?: number;\n allow_held_key?: boolean;\n minimum_valid_rt?: number;\n}\n\nexport class KeyboardListenerAPI {\n constructor(\n private getRootElement: () => Element | undefined,\n private areResponsesCaseSensitive: boolean = false,\n private minimumValidRt = 0\n ) {\n autoBind(this);\n this.registerRootListeners();\n }\n\n private listeners = new Set<KeyboardListener>();\n private heldKeys = new Set<string>();\n\n private areRootListenersRegistered = false;\n\n /**\n * If not previously done and `this.getRootElement()` returns an element, adds the root key\n * listeners to that element.\n */\n private registerRootListeners() {\n if (!this.areRootListenersRegistered) {\n const rootElement = this.getRootElement();\n if (rootElement) {\n rootElement.addEventListener(\"keydown\", this.rootKeydownListener);\n rootElement.addEventListener(\"keyup\", this.rootKeyupListener);\n this.areRootListenersRegistered = true;\n }\n }\n }\n\n private rootKeydownListener(e: KeyboardEvent) {\n // Iterate over a static copy of the listeners set because listeners might add other listeners\n // that we do not want to be included in the loop\n for (const listener of Array.from(this.listeners)) {\n listener(e);\n }\n this.heldKeys.add(this.toLowerCaseIfInsensitive(e.key));\n }\n\n private toLowerCaseIfInsensitive(string: string) {\n return this.areResponsesCaseSensitive ? string : string.toLowerCase();\n }\n\n private rootKeyupListener(e: KeyboardEvent) {\n this.heldKeys.delete(this.toLowerCaseIfInsensitive(e.key));\n }\n\n private isResponseValid(validResponses: ValidResponses, allowHeldKey: boolean, key: string) {\n // check if key was already held down\n if (!allowHeldKey && this.heldKeys.has(key)) {\n return false;\n }\n\n if (validResponses === \"ALL_KEYS\") {\n return true;\n }\n if (validResponses === \"NO_KEYS\") {\n return false;\n }\n\n return validResponses.includes(key);\n }\n\n getKeyboardResponse({\n callback_function,\n valid_responses = \"ALL_KEYS\",\n rt_method = \"performance\",\n persist,\n audio_context,\n audio_context_start_time,\n allow_held_key = false,\n minimum_valid_rt = this.minimumValidRt,\n }: GetKeyboardResponseOptions) {\n if (rt_method !== \"performance\" && rt_method !== \"audio\") {\n console.log(\n 'Invalid RT method specified in getKeyboardResponse. Defaulting to \"performance\" method.'\n );\n rt_method = \"performance\";\n }\n\n const usePerformanceRt = rt_method === \"performance\";\n const startTime = usePerformanceRt ? performance.now() : audio_context_start_time * 1000;\n\n this.registerRootListeners();\n\n if (!this.areResponsesCaseSensitive && typeof valid_responses !== \"string\") {\n valid_responses = valid_responses.map((r) => r.toLowerCase());\n }\n\n const listener: KeyboardListener = (e) => {\n const rt = Math.round(\n (rt_method == \"performance\" ? performance.now() : audio_context.currentTime * 1000) -\n startTime\n );\n if (rt < minimum_valid_rt) {\n return;\n }\n\n const key = this.toLowerCaseIfInsensitive(e.key);\n\n if (this.isResponseValid(valid_responses, allow_held_key, key)) {\n // if this is a valid response, then we don't want the key event to trigger other actions\n // like scrolling via the spacebar.\n e.preventDefault();\n\n if (!persist) {\n // remove keyboard listener if it exists\n this.cancelKeyboardResponse(listener);\n }\n\n callback_function({ key, rt });\n }\n };\n\n this.listeners.add(listener);\n return listener;\n }\n\n cancelKeyboardResponse(listener: KeyboardListener) {\n // remove the listener from the set of listeners if it is contained\n this.listeners.delete(listener);\n }\n\n cancelAllKeyboardResponses() {\n this.listeners.clear();\n }\n\n compareKeys(key1: string | null, key2: string | null) {\n if (\n (typeof key1 !== \"string\" && key1 !== null) ||\n (typeof key2 !== \"string\" && key2 !== null)\n ) {\n console.error(\n \"Error in jsPsych.pluginAPI.compareKeys: arguments must be key strings or null.\"\n );\n return undefined;\n }\n\n if (typeof key1 === \"string\" && typeof key2 === \"string\") {\n // if both values are strings, then check whether or not letter case should be converted before comparing (case_sensitive_responses in initJsPsych)\n return this.areResponsesCaseSensitive\n ? key1 === key2\n : key1.toLowerCase() === key2.toLowerCase();\n }\n\n return key1 === null && key2 === null;\n }\n}\n","import { ParameterType } from \"../../modules/plugins\";\nimport { unique } from \"../utils\";\n\nconst preloadParameterTypes = <const>[\n ParameterType.AUDIO,\n ParameterType.IMAGE,\n ParameterType.VIDEO,\n];\ntype PreloadType = typeof preloadParameterTypes[number];\n\nexport class MediaAPI {\n constructor(private useWebaudio: boolean, private webaudioContext?: AudioContext) {}\n\n // video //\n private video_buffers = {};\n getVideoBuffer(videoID) {\n return this.video_buffers[videoID];\n }\n\n // audio //\n private context = null;\n private audio_buffers = [];\n\n initAudio() {\n this.context = this.useWebaudio ? this.webaudioContext : null;\n }\n\n audioContext() {\n if (this.context !== null) {\n if (this.context.state !== \"running\") {\n this.context.resume();\n }\n }\n return this.context;\n }\n\n getAudioBuffer(audioID) {\n return new Promise((resolve, reject) => {\n // check whether audio file already preloaded\n if (\n typeof this.audio_buffers[audioID] == \"undefined\" ||\n this.audio_buffers[audioID] == \"tmp\"\n ) {\n // if audio is not already loaded, try to load it\n this.preloadAudio(\n [audioID],\n () => {\n resolve(this.audio_buffers[audioID]);\n },\n () => {},\n (e) => {\n reject(e.error);\n }\n );\n } else {\n // audio is already loaded\n resolve(this.audio_buffers[audioID]);\n }\n });\n }\n\n // preloading stimuli //\n private preload_requests = [];\n\n private img_cache = {};\n\n preloadAudio(\n files,\n callback_complete = () => {},\n callback_load = (filepath) => {},\n callback_error = (error_msg) => {}\n ) {\n files = unique(files.flat());\n\n let n_loaded = 0;\n\n if (files.length == 0) {\n callback_complete();\n return;\n }\n\n const load_audio_file_webaudio = (source, count = 1) => {\n const request = new XMLHttpRequest();\n request.open(\"GET\", source, true);\n request.responseType = \"arraybuffer\";\n request.onload = () => {\n this.context.decodeAudioData(\n request.response,\n (buffer) => {\n this.audio_buffers[source] = buffer;\n n_loaded++;\n callback_load(source);\n if (n_loaded == files.length) {\n callback_complete();\n }\n },\n (e) => {\n callback_error({ source: source, error: e });\n }\n );\n };\n request.onerror = function (e) {\n let err: ProgressEvent | string = e;\n if (this.status == 404) {\n err = \"404\";\n }\n callback_error({ source: source, error: err });\n };\n request.onloadend = function (e) {\n if (this.status == 404) {\n callback_error({ source: source, error: \"404\" });\n }\n };\n request.send();\n this.preload_requests.push(request);\n };\n\n const load_audio_file_html5audio = (source, count = 1) => {\n const audio = new Audio();\n const handleCanPlayThrough = () => {\n this.audio_buffers[source] = audio;\n n_loaded++;\n callback_load(source);\n if (n_loaded == files.length) {\n callback_complete();\n }\n audio.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n };\n audio.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n audio.addEventListener(\"error\", function handleError(e) {\n callback_error({ source: audio.src, error: e });\n audio.removeEventListener(\"error\", handleError);\n });\n audio.addEventListener(\"abort\", function handleAbort(e) {\n callback_error({ source: audio.src, error: e });\n audio.removeEventListener(\"abort\", handleAbort);\n });\n audio.src = source;\n this.preload_requests.push(audio);\n };\n\n for (const file of files) {\n if (typeof this.audio_buffers[file] !== \"undefined\") {\n n_loaded++;\n callback_load(file);\n if (n_loaded == files.length) {\n callback_complete();\n }\n } else {\n this.audio_buffers[file] = \"tmp\";\n if (this.audioContext() !== null) {\n load_audio_file_webaudio(file);\n } else {\n load_audio_file_html5audio(file);\n }\n }\n }\n }\n\n preloadImages(\n images,\n callback_complete = () => {},\n callback_load = (filepath) => {},\n callback_error = (error_msg) => {}\n ) {\n // flatten the images array\n images = unique(images.flat());\n\n var n_loaded = 0;\n\n if (images.length === 0) {\n callback_complete();\n return;\n }\n\n for (var i = 0; i < images.length; i++) {\n var img = new Image();\n\n img.onload = function () {\n n_loaded++;\n callback_load(img.src);\n if (n_loaded === images.length) {\n callback_complete();\n }\n };\n\n img.onerror = function (e) {\n callback_error({ source: img.src, error: e });\n };\n\n img.src = images[i];\n\n this.img_cache[images[i]] = img;\n this.preload_requests.push(img);\n }\n }\n\n preloadVideo(\n videos,\n callback_complete = () => {},\n callback_load = (filepath) => {},\n callback_error = (error_msg) => {}\n ) {\n // flatten the video array\n videos = unique(videos.flat());\n\n let n_loaded = 0;\n\n if (videos.length === 0) {\n callback_complete();\n return;\n }\n\n for (const video of videos) {\n const video_buffers = this.video_buffers;\n\n //based on option 4 here: http://dinbror.dk/blog/how-to-preload-entire-html5-video-before-play-solved/\n const request = new XMLHttpRequest();\n request.open(\"GET\", video, true);\n request.responseType = \"blob\";\n request.onload = function () {\n if (this.status === 200 || this.status === 0) {\n const videoBlob = this.response;\n video_buffers[video] = URL.createObjectURL(videoBlob); // IE10+\n n_loaded++;\n callback_load(video);\n if (n_loaded === videos.length) {\n callback_complete();\n }\n }\n };\n request.onerror = function (e) {\n let err: ProgressEvent | string = e;\n if (this.status == 404) {\n err = \"404\";\n }\n callback_error({ source: video, error: err });\n };\n request.onloadend = function (e) {\n if (this.status == 404) {\n callback_error({ source: video, error: \"404\" });\n }\n };\n request.send();\n this.preload_requests.push(request);\n }\n }\n\n private preloadMap = new Map<string, Record<string, PreloadType>>();\n\n getAutoPreloadList(timeline_description: any[]) {\n /** Map each preload parameter type to a set of paths to be preloaded */\n const preloadPaths = Object.fromEntries(\n preloadParameterTypes.map((type) => [type, new Set<string>()])\n );\n\n const traverseTimeline = (node, inheritedTrialType?) => {\n const isTimeline = typeof node.timeline !== \"undefined\";\n\n if (isTimeline) {\n for (const childNode of node.timeline) {\n traverseTimeline(childNode, node.type ?? inheritedTrialType);\n }\n } else if ((node.type ?? inheritedTrialType)?.info) {\n // node is a trial with type.info set\n\n // Get the plugin name and parameters object from the info object\n const { name: pluginName, parameters } = (node.type ?? inheritedTrialType).info;\n\n // Extract parameters to be preloaded and their types from parameter info if this has not\n // yet been done for `pluginName`\n if (!this.preloadMap.has(pluginName)) {\n this.preloadMap.set(\n pluginName,\n Object.fromEntries(\n Object.entries<any>(parameters)\n // Filter out parameter entries with media types and a non-false `preload` option\n .filter(\n ([_name, { type, preload }]) =>\n preloadParameterTypes.includes(type) && (preload ?? true)\n )\n // Map each entry's value to its parameter type\n .map(([name, { type }]) => [name, type])\n )\n );\n }\n\n // Add preload paths from this trial\n for (const [parameterName, parameterType] of Object.entries(\n this.preloadMap.get(pluginName)\n )) {\n const parameterValue = node[parameterName];\n const elements = preloadPaths[parameterType];\n\n if (typeof parameterValue === \"string\") {\n elements.add(parameterValue);\n } else if (Array.isArray(parameterValue)) {\n for (const element of parameterValue.flat()) {\n if (typeof element === \"string\") {\n elements.add(element);\n }\n }\n }\n }\n }\n };\n\n traverseTimeline({ timeline: timeline_description });\n\n return {\n images: [...preloadPaths[ParameterType.IMAGE]],\n audio: [...preloadPaths[ParameterType.AUDIO]],\n video: [...preloadPaths[ParameterType.VIDEO]],\n };\n }\n\n cancelPreloads() {\n for (const request of this.preload_requests) {\n request.onload = () => {};\n request.onerror = () => {};\n request.oncanplaythrough = () => {};\n request.onabort = () => {};\n }\n this.preload_requests = [];\n }\n\n private microphone_recorder: MediaRecorder = null;\n\n initializeMicrophoneRecorder(stream: MediaStream) {\n const recorder = new MediaRecorder(stream);\n this.microphone_recorder = recorder;\n }\n\n getMicrophoneRecorder(): MediaRecorder {\n return this.microphone_recorder;\n }\n}\n","export class SimulationAPI {\n dispatchEvent(event: Event) {\n document.body.dispatchEvent(event);\n }\n\n /**\n * Dispatches a `keydown` event for the specified key\n * @param key Character code (`.key` property) for the key to press.\n */\n keyDown(key: string) {\n this.dispatchEvent(new KeyboardEvent(\"keydown\", { key }));\n }\n\n /**\n * Dispatches a `keyup` event for the specified key\n * @param key Character code (`.key` property) for the key to press.\n */\n keyUp(key: string) {\n this.dispatchEvent(new KeyboardEvent(\"keyup\", { key }));\n }\n\n /**\n * Dispatches a `keydown` and `keyup` event in sequence to simulate pressing a key.\n * @param key Character code (`.key` property) for the key to press.\n * @param delay Length of time to wait (ms) before executing action\n */\n pressKey(key: string, delay = 0) {\n if (delay > 0) {\n setTimeout(() => {\n this.keyDown(key);\n this.keyUp(key);\n }, delay);\n } else {\n this.keyDown(key);\n this.keyUp(key);\n }\n }\n\n /**\n * Dispatches `mousedown`, `mouseup`, and `click` events on the target element\n * @param target The element to click\n * @param delay Length of time to wait (ms) before executing action\n */\n clickTarget(target: Element, delay = 0) {\n if (delay > 0) {\n setTimeout(() => {\n target.dispatchEvent(new MouseEvent(\"mousedown\", { bubbles: true }));\n target.dispatchEvent(new MouseEvent(\"mouseup\", { bubbles: true }));\n target.dispatchEvent(new MouseEvent(\"click\", { bubbles: true }));\n }, delay);\n } else {\n target.dispatchEvent(new MouseEvent(\"mousedown\", { bubbles: true }));\n target.dispatchEvent(new MouseEvent(\"mouseup\", { bubbles: true }));\n target.dispatchEvent(new MouseEvent(\"click\", { bubbles: true }));\n }\n }\n\n /**\n * Sets the value of a target text input\n * @param target A text input element to fill in\n * @param text Text to input\n * @param delay Length of time to wait (ms) before executing action\n */\n fillTextInput(target: HTMLInputElement, text: string, delay = 0) {\n if (delay > 0) {\n setTimeout(() => {\n target.value = text;\n }, delay);\n } else {\n target.value = text;\n }\n }\n\n /**\n * Picks a valid key from `choices`, taking into account jsPsych-specific\n * identifiers like \"NO_KEYS\" and \"ALL_KEYS\".\n * @param choices Which keys are valid.\n * @returns A key selected at random from the valid keys.\n */\n getValidKey(choices: \"NO_KEYS\" | \"ALL_KEYS\" | Array<string> | Array<Array<string>>) {\n const possible_keys = [\n \"a\",\n \"b\",\n \"c\",\n \"d\",\n \"e\",\n \"f\",\n \"g\",\n \"h\",\n \"i\",\n \"j\",\n \"k\",\n \"l\",\n \"m\",\n \"n\",\n \"o\",\n \"p\",\n \"q\",\n \"r\",\n \"s\",\n \"t\",\n \"u\",\n \"v\",\n \"w\",\n \"x\",\n \"y\",\n \"z\",\n \"0\",\n \"1\",\n \"2\",\n \"3\",\n \"4\",\n \"5\",\n \"6\",\n \"7\",\n \"8\",\n \"9\",\n \" \",\n ];\n\n let key;\n if (choices == \"NO_KEYS\") {\n key = null;\n } else if (choices == \"ALL_KEYS\") {\n key = possible_keys[Math.floor(Math.random() * possible_keys.length)];\n } else {\n const flat_choices = choices.flat();\n key = flat_choices[Math.floor(Math.random() * flat_choices.length)];\n }\n\n return key;\n }\n\n mergeSimulationData(default_data, simulation_options) {\n // override any data with data from simulation object\n return {\n ...default_data,\n ...simulation_options?.data,\n };\n }\n\n ensureSimulationDataConsistency(trial, data) {\n // All RTs must be rounded\n if (data.rt) {\n data.rt = Math.round(data.rt);\n }\n\n // If a trial_duration and rt exist, make sure that the RT is not longer than the trial.\n if (trial.trial_duration && data.rt && data.rt > trial.trial_duration) {\n data.rt = null;\n if (data.response) {\n data.response = null;\n }\n if (data.correct) {\n data.correct = false;\n }\n }\n\n // If trial.choices is NO_KEYS make sure that response and RT are null\n if (trial.choices && trial.choices == \"NO_KEYS\") {\n if (data.rt) {\n data.rt = null;\n }\n if (data.response) {\n data.response = null;\n }\n }\n\n // If response is not allowed before stimulus display complete, ensure RT\n // is longer than display time.\n if (trial.allow_response_before_complete) {\n if (trial.sequence_reps && trial.frame_time) {\n const min_time = trial.sequence_reps * trial.frame_time * trial.stimuli.length;\n if (data.rt < min_time) {\n data.rt = null;\n data.response = null;\n }\n }\n }\n }\n}\n","export class TimeoutAPI {\n private timeout_handlers = [];\n\n setTimeout(callback, delay) {\n const handle = window.setTimeout(callback, delay);\n this.timeout_handlers.push(handle);\n return handle;\n }\n\n clearAllTimeouts() {\n for (const handler of this.timeout_handlers) {\n clearTimeout(handler);\n }\n this.timeout_handlers = [];\n }\n}\n","var wordList = [\n // Borrowed from xkcd password generator which borrowed it from wherever\n \"ability\",\"able\",\"aboard\",\"about\",\"above\",\"accept\",\"accident\",\"according\",\n \"account\",\"accurate\",\"acres\",\"across\",\"act\",\"action\",\"active\",\"activity\",\n \"actual\",\"actually\",\"add\",\"addition\",\"additional\",\"adjective\",\"adult\",\"adventure\",\n \"advice\",\"affect\",\"afraid\",\"after\",\"afternoon\",\"again\",\"against\",\"age\",\n \"ago\",\"agree\",\"ahead\",\"aid\",\"air\",\"airplane\",\"alike\",\"alive\",\n \"all\",\"allow\",\"almost\",\"alone\",\"along\",\"aloud\",\"alphabet\",\"already\",\n \"also\",\"although\",\"am\",\"among\",\"amount\",\"ancient\",\"angle\",\"angry\",\n \"animal\",\"announced\",\"another\",\"answer\",\"ants\",\"any\",\"anybody\",\"anyone\",\n \"anything\",\"anyway\",\"anywhere\",\"apart\",\"apartment\",\"appearance\",\"apple\",\"applied\",\n \"appropriate\",\"are\",\"area\",\"arm\",\"army\",\"around\",\"arrange\",\"arrangement\",\n \"arrive\",\"arrow\",\"art\",\"article\",\"as\",\"aside\",\"ask\",\"asleep\",\n \"at\",\"ate\",\"atmosphere\",\"atom\",\"atomic\",\"attached\",\"attack\",\"attempt\",\n \"attention\",\"audience\",\"author\",\"automobile\",\"available\",\"average\",\"avoid\",\"aware\",\n \"away\",\"baby\",\"back\",\"bad\",\"badly\",\"bag\",\"balance\",\"ball\",\n \"balloon\",\"band\",\"bank\",\"bar\",\"bare\",\"bark\",\"barn\",\"base\",\n \"baseball\",\"basic\",\"basis\",\"basket\",\"bat\",\"battle\",\"be\",\"bean\",\n \"bear\",\"beat\",\"beautiful\",\"beauty\",\"became\",\"because\",\"become\",\"becoming\",\n \"bee\",\"been\",\"before\",\"began\",\"beginning\",\"begun\",\"behavior\",\"behind\",\n \"being\",\"believed\",\"bell\",\"belong\",\"below\",\"belt\",\"bend\",\"beneath\",\n \"bent\",\"beside\",\"best\",\"bet\",\"better\",\"between\",\"beyond\",\"bicycle\",\n \"bigger\",\"biggest\",\"bill\",\"birds\",\"birth\",\"birthday\",\"bit\",\"bite\",\n \"black\",\"blank\",\"blanket\",\"blew\",\"blind\",\"block\",\"blood\",\"blow\",\n \"blue\",\"board\",\"boat\",\"body\",\"bone\",\"book\",\"border\",\"born\",\n \"both\",\"bottle\",\"bottom\",\"bound\",\"bow\",\"bowl\",\"box\",\"boy\",\n \"brain\",\"branch\",\"brass\",\"brave\",\"bread\",\"break\",\"breakfast\",\"breath\",\n \"breathe\",\"breathing\",\"breeze\",\"brick\",\"bridge\",\"brief\",\"bright\",\"bring\",\n \"broad\",\"broke\",\"broken\",\"brother\",\"brought\",\"brown\",\"brush\",\"buffalo\",\n \"build\",\"building\",\"built\",\"buried\",\"burn\",\"burst\",\"bus\",\"bush\",\n \"business\",\"busy\",\"but\",\"butter\",\"buy\",\"by\",\"cabin\",\"cage\",\n \"cake\",\"call\",\"calm\",\"came\",\"camera\",\"camp\",\"can\",\"canal\",\n \"cannot\",\"cap\",\"capital\",\"captain\",\"captured\",\"car\",\"carbon\",\"card\",\n \"care\",\"careful\",\"carefully\",\"carried\",\"carry\",\"case\",\"cast\",\"castle\",\n \"cat\",\"catch\",\"cattle\",\"caught\",\"cause\",\"cave\",\"cell\",\"cent\",\n \"center\",\"central\",\"century\",\"certain\",\"certainly\",\"chain\",\"chair\",\"chamber\",\n \"chance\",\"change\",\"changing\",\"chapter\",\"character\",\"characteristic\",\"charge\",\"chart\",\n \"check\",\"cheese\",\"chemical\",\"chest\",\"chicken\",\"chief\",\"child\",\"children\",\n \"choice\",\"choose\",\"chose\",\"chosen\",\"church\",\"circle\",\"circus\",\"citizen\",\n \"city\",\"class\",\"classroom\",\"claws\",\"clay\",\"clean\",\"clear\",\"clearly\",\n \"climate\",\"climb\",\"clock\",\"close\",\"closely\",\"closer\",\"cloth\",\"clothes\",\n \"clothing\",\"cloud\",\"club\",\"coach\",\"coal\",\"coast\",\"coat\",\"coffee\",\n \"cold\",\"collect\",\"college\",\"colony\",\"color\",\"column\",\"combination\",\"combine\",\n \"come\",\"comfortable\",\"coming\",\"command\",\"common\",\"community\",\"company\",\"compare\",\n \"compass\",\"complete\",\"completely\",\"complex\",\"composed\",\"composition\",\"compound\",\"concerned\",\n \"condition\",\"congress\",\"connected\",\"consider\",\"consist\",\"consonant\",\"constantly\",\"construction\",\n \"contain\",\"continent\",\"continued\",\"contrast\",\"control\",\"conversation\",\"cook\",\"cookies\",\n \"cool\",\"copper\",\"copy\",\"corn\",\"corner\",\"correct\",\"correctly\",\"cost\",\n \"cotton\",\"could\",\"count\",\"country\",\"couple\",\"courage\",\"course\",\"court\",\n \"cover\",\"cow\",\"cowboy\",\"crack\",\"cream\",\"create\",\"creature\",\"crew\",\n \"crop\",\"cross\",\"crowd\",\"cry\",\"cup\",\"curious\",\"current\",\"curve\",\n \"customs\",\"cut\",\"cutting\",\"daily\",\"damage\",\"dance\",\"danger\",\"dangerous\",\n \"dark\",\"darkness\",\"date\",\"daughter\",\"dawn\",\"day\",\"dead\",\"deal\",\n \"dear\",\"death\",\"decide\",\"declared\",\"deep\",\"deeply\",\"deer\",\"definition\",\n \"degree\",\"depend\",\"depth\",\"describe\",\"desert\",\"design\",\"desk\",\"detail\",\n \"determine\",\"develop\",\"development\",\"diagram\",\"diameter\",\"did\",\"die\",\"differ\",\n \"difference\",\"different\",\"difficult\",\"difficulty\",\"dig\",\"dinner\",\"direct\",\"direction\",\n \"directly\",\"dirt\",\"dirty\",\"disappear\",\"discover\",\"discovery\",\"discuss\",\"discussion\",\n \"disease\",\"dish\",\"distance\",\"distant\",\"divide\",\"division\",\"do\",\"doctor\",\n \"does\",\"dog\",\"doing\",\"doll\",\"dollar\",\"done\",\"donkey\",\"door\",\n \"dot\",\"double\",\"doubt\",\"down\",\"dozen\",\"draw\",\"drawn\",\"dream\",\n \"dress\",\"drew\",\"dried\",\"drink\",\"drive\",\"driven\",\"driver\",\"driving\",\n \"drop\",\"dropped\",\"drove\",\"dry\",\"duck\",\"due\",\"dug\",\"dull\",\n \"during\",\"dust\",\"duty\",\"each\",\"eager\",\"ear\",\"earlier\",\"early\",\n \"earn\",\"earth\",\"easier\",\"easily\",\"east\",\"easy\",\"eat\",\"eaten\",\n \"edge\",\"education\",\"effect\",\"effort\",\"egg\",\"eight\",\"either\",\"electric\",\n \"electricity\",\"element\",\"elephant\",\"eleven\",\"else\",\"empty\",\"end\",\"enemy\",\n \"energy\",\"engine\",\"engineer\",\"enjoy\",\"enough\",\"enter\",\"entire\",\"entirely\",\n \"environment\",\"equal\",\"equally\",\"equator\",\"equipment\",\"escape\",\"especially\",\"essential\",\n \"establish\",\"even\",\"evening\",\"event\",\"eventually\",\"ever\",\"every\",\"everybody\",\n \"everyone\",\"everything\",\"everywhere\",\"evidence\",\"exact\",\"exactly\",\"examine\",\"example\",\n \"excellent\",\"except\",\"exchange\",\"excited\",\"excitement\",\"exciting\",\"exclaimed\",\"exercise\",\n \"exist\",\"expect\",\"experience\",\"experiment\",\"explain\",\"explanation\",\"explore\",\"express\",\n \"expression\",\"extra\",\"eye\",\"face\",\"facing\",\"fact\",\"factor\",\"factory\",\n \"failed\",\"fair\",\"fairly\",\"fall\",\"fallen\",\"familiar\",\"family\",\"famous\",\n \"far\",\"farm\",\"farmer\",\"farther\",\"fast\",\"fastened\",\"faster\",\"fat\",\n \"father\",\"favorite\",\"fear\",\"feathers\",\"feature\",\"fed\",\"feed\",\"feel\",\n \"feet\",\"fell\",\"fellow\",\"felt\",\"fence\",\"few\",\"fewer\",\"field\",\n \"fierce\",\"fifteen\",\"fifth\",\"fifty\",\"fight\",\"fighting\",\"figure\",\"fill\",\n \"film\",\"final\",\"finally\",\"find\",\"fine\",\"finest\",\"finger\",\"finish\",\n \"fire\",\"fireplace\",\"firm\",\"first\",\"fish\",\"five\",\"fix\",\"flag\",\n \"flame\",\"flat\",\"flew\",\"flies\",\"flight\",\"floating\",\"floor\",\"flow\",\n \"flower\",\"fly\",\"fog\",\"folks\",\"follow\",\"food\",\"foot\",\"football\",\n \"for\",\"force\",\"foreign\",\"forest\",\"forget\",\"forgot\",\"forgotten\",\"form\",\n \"former\",\"fort\",\"forth\",\"forty\",\"forward\",\"fought\",\"found\",\"four\",\n \"fourth\",\"fox\",\"frame\",\"free\",\"freedom\",\"frequently\",\"fresh\",\"friend\",\n \"friendly\",\"frighten\",\"frog\",\"from\",\"front\",\"frozen\",\"fruit\",\"fuel\",\n \"full\",\"fully\",\"fun\",\"function\",\"funny\",\"fur\",\"furniture\",\"further\",\n \"future\",\"gain\",\"game\",\"garage\",\"garden\",\"gas\",\"gasoline\",\"gate\",\n \"gather\",\"gave\",\"general\",\"generally\",\"gentle\",\"gently\",\"get\",\"getting\",\n \"giant\",\"gift\",\"girl\",\"give\",\"given\",\"giving\",\"glad\",\"glass\",\n \"globe\",\"go\",\"goes\",\"gold\",\"golden\",\"gone\",\"good\",\"goose\",\n \"got\",\"government\",\"grabbed\",\"grade\",\"gradually\",\"grain\",\"grandfather\",\"grandmother\",\n \"graph\",\"grass\",\"gravity\",\"gray\",\"great\",\"greater\",\"greatest\",\"greatly\",\n \"green\",\"grew\",\"ground\",\"group\",\"grow\",\"grown\",\"growth\",\"guard\",\n \"guess\",\"guide\",\"gulf\",\"gun\",\"habit\",\"had\",\"hair\",\"half\",\n \"halfway\",\"hall\",\"hand\",\"handle\",\"handsome\",\"hang\",\"happen\",\"happened\",\n \"happily\",\"happy\",\"harbor\",\"hard\",\"harder\",\"hardly\",\"has\",\"hat\",\n \"have\",\"having\",\"hay\",\"he\",\"headed\",\"heading\",\"health\",\"heard\",\n \"hearing\",\"heart\",\"heat\",\"heavy\",\"height\",\"held\",\"hello\",\"help\",\n \"helpful\",\"her\",\"herd\",\"here\",\"herself\",\"hidden\",\"hide\",\"high\",\n \"higher\",\"highest\",\"highway\",\"hill\",\"him\",\"himself\",\"his\",\"history\",\n \"hit\",\"hold\",\"hole\",\"hollow\",\"home\",\"honor\",\"hope\",\"horn\",\n \"horse\",\"hospital\",\"hot\",\"hour\",\"house\",\"how\",\"however\",\"huge\",\n \"human\",\"hundred\",\"hung\",\"hungry\",\"hunt\",\"hunter\",\"hurried\",\"hurry\",\n \"hurt\",\"husband\",\"ice\",\"idea\",\"identity\",\"if\",\"ill\",\"image\",\n \"imagine\",\"immediately\",\"importance\",\"important\",\"impossible\",\"improve\",\"in\",\"inch\",\n \"include\",\"including\",\"income\",\"increase\",\"indeed\",\"independent\",\"indicate\",\"individual\",\n \"industrial\",\"industry\",\"influence\",\"information\",\"inside\",\"instance\",\"instant\",\"instead\",\n \"instrument\",\"interest\",\"interior\",\"into\",\"introduced\",\"invented\",\"involved\",\"iron\",\n \"is\",\"island\",\"it\",\"its\",\"itself\",\"jack\",\"jar\",\"jet\",\n \"job\",\"join\",\"joined\",\"journey\",\"joy\",\"judge\",\"jump\",\"jungle\",\n \"just\",\"keep\",\"kept\",\"key\",\"kids\",\"kill\",\"kind\",\"kitchen\",\n \"knew\",\"knife\",\"know\",\"knowledge\",\"known\",\"label\",\"labor\",\"lack\",\n \"lady\",\"laid\",\"lake\",\"lamp\",\"land\",\"language\",\"large\",\"larger\",\n \"largest\",\"last\",\"late\",\"later\",\"laugh\",\"law\",\"lay\",\"layers\",\n \"lead\",\"leader\",\"leaf\",\"learn\",\"least\",\"leather\",\"leave\",\"leaving\",\n \"led\",\"left\",\"leg\",\"length\",\"lesson\",\"let\",\"letter\",\"level\",\n \"library\",\"lie\",\"life\",\"lift\",\"light\",\"like\",\"likely\",\"limited\",\n \"line\",\"lion\",\"lips\",\"liquid\",\"list\",\"listen\",\"little\",\"live\",\n \"living\",\"load\",\"local\",\"locate\",\"location\",\"log\",\"lonely\",\"long\",\n \"longer\",\"look\",\"loose\",\"lose\",\"loss\",\"lost\",\"lot\",\"loud\",\n \"love\",\"lovely\",\"low\",\"lower\",\"luck\",\"lucky\",\"lunch\",\"lungs\",\n \"lying\",\"machine\",\"machinery\",\"mad\",\"made\",\"magic\",\"magnet\",\"mail\",\n \"main\",\"mainly\",\"major\",\"make\",\"making\",\"man\",\"managed\",\"manner\",\n \"manufacturing\",\"many\",\"map\",\"mark\",\"market\",\"married\",\"mass\",\"massage\",\n \"master\",\"material\",\"mathematics\",\"matter\",\"may\",\"maybe\",\"me\",\"meal\",\n \"mean\",\"means\",\"meant\",\"measure\",\"meat\",\"medicine\",\"meet\",\"melted\",\n \"member\",\"memory\",\"men\",\"mental\",\"merely\",\"met\",\"metal\",\"method\",\n \"mice\",\"middle\",\"might\",\"mighty\",\"mile\",\"military\",\"milk\",\"mill\",\n \"mind\",\"mine\",\"minerals\",\"minute\",\"mirror\",\"missing\",\"mission\",\"mistake\",\n \"mix\",\"mixture\",\"model\",\"modern\",\"molecular\",\"moment\",\"money\",\"monkey\",\n \"month\",\"mood\",\"moon\",\"more\",\"morning\",\"most\",\"mostly\",\"mother\",\n \"motion\",\"motor\",\"mountain\",\"mouse\",\"mouth\",\"move\",\"movement\",\"movie\",\n \"moving\",\"mud\",\"muscle\",\"music\",\"musical\",\"must\",\"my\",\"myself\",\n \"mysterious\",\"nails\",\"name\",\"nation\",\"national\",\"native\",\"natural\",\"naturally\",\n \"nature\",\"near\",\"nearby\",\"nearer\",\"nearest\",\"nearly\",\"necessary\",\"neck\",\n \"needed\",\"needle\",\"needs\",\"negative\",\"neighbor\",\"neighborhood\",\"nervous\",\"nest\",\n \"never\",\"new\",\"news\",\"newspaper\",\"next\",\"nice\",\"night\",\"nine\",\n \"no\",\"nobody\",\"nodded\",\"noise\",\"none\",\"noon\",\"nor\",\"north\",\n \"nose\",\"not\",\"note\",\"noted\",\"nothing\",\"notice\",\"noun\",\"now\",\n \"number\",\"numeral\",\"nuts\",\"object\",\"observe\",\"obtain\",\"occasionally\",\"occur\",\n \"ocean\",\"of\",\"off\",\"offer\",\"office\",\"officer\",\"official\",\"oil\",\n \"old\",\"older\",\"oldest\",\"on\",\"once\",\"one\",\"only\",\"onto\",\n \"open\",\"operation\",\"opinion\",\"opportunity\",\"opposite\",\"or\",\"orange\",\"orbit\",\n \"order\",\"ordinary\",\"organization\",\"organized\",\"origin\",\"original\",\"other\",\"ought\",\n \"our\",\"ourselves\",\"out\",\"outer\",\"outline\",\"outside\",\"over\",\"own\",\n \"owner\",\"oxygen\",\"pack\",\"package\",\"page\",\"paid\",\"pain\",\"paint\",\n \"pair\",\"palace\",\"pale\",\"pan\",\"paper\",\"paragraph\",\"parallel\",\"parent\",\n \"park\",\"part\",\"particles\",\"particular\",\"particularly\",\"partly\",\"parts\",\"party\",\n \"pass\",\"passage\",\"past\",\"path\",\"pattern\",\"pay\",\"peace\",\"pen\",\n \"pencil\",\"people\",\"per\",\"percent\",\"perfect\",\"perfectly\",\"perhaps\",\"period\",\n \"person\",\"personal\",\"pet\",\"phrase\",\"physical\",\"piano\",\"pick\",\"picture\",\n \"pictured\",\"pie\",\"piece\",\"pig\",\"pile\",\"pilot\",\"pine\",\"pink\",\n \"pipe\",\"pitch\",\"place\",\"plain\",\"plan\",\"plane\",\"planet\",\"planned\",\n \"planning\",\"plant\",\"plastic\",\"plate\",\"plates\",\"play\",\"pleasant\",\"please\",\n \"pleasure\",\"plenty\",\"plural\",\"plus\",\"pocket\",\"poem\",\"poet\",\"poetry\",\n \"point\",\"pole\",\"police\",\"policeman\",\"political\",\"pond\",\"pony\",\"pool\",\n \"poor\",\"popular\",\"population\",\"porch\",\"port\",\"position\",\"positive\",\"possible\",\n \"possibly\",\"post\",\"pot\",\"potatoes\",\"pound\",\"pour\",\"powder\",\"power\",\n \"powerful\",\"practical\",\"practice\",\"prepare\",\"present\",\"president\",\"press\",\"pressure\",\n \"pretty\",\"prevent\",\"previous\",\"price\",\"pride\",\"primitive\",\"principal\",\"principle\",\n \"printed\",\"private\",\"prize\",\"probably\",\"problem\",\"process\",\"produce\",\"product\",\n \"production\",\"program\",\"progress\",\"promised\",\"proper\",\"properly\",\"property\",\"protection\",\n \"proud\",\"prove\",\"provide\",\"public\",\"pull\",\"pupil\",\"pure\",\"purple\",\n \"purpose\",\"push\",\"put\",\"putting\",\"quarter\",\"queen\",\"question\",\"quick\",\n \"quickly\",\"quiet\",\"quietly\",\"quite\",\"rabbit\",\"race\",\"radio\",\"railroad\",\n \"rain\",\"raise\",\"ran\",\"ranch\",\"range\",\"rapidly\",\"rate\",\"rather\",\n \"raw\",\"rays\",\"reach\",\"read\",\"reader\",\"ready\",\"real\",\"realize\",\n \"rear\",\"reason\",\"recall\",\"receive\",\"recent\",\"recently\",\"recognize\",\"record\",\n \"red\",\"refer\",\"refused\",\"region\",\"regular\",\"related\",\"relationship\",\"religious\",\n \"remain\",\"remarkable\",\"remember\",\"remove\",\"repeat\",\"replace\",\"replied\",\"report\",\n \"represent\",\"require\",\"research\",\"respect\",\"rest\",\"result\",\"return\",\"review\",\n \"rhyme\",\"rhythm\",\"rice\",\"rich\",\"ride\",\"riding\",\"right\",\"ring\",\n \"rise\",\"rising\",\"river\",\"road\",\"roar\",\"rock\",\"rocket\",\"rocky\",\n \"rod\",\"roll\",\"roof\",\"room\",\"root\",\"rope\",\"rose\",\"rough\",\n \"round\",\"route\",\"row\",\"rubbed\",\"rubber\",\"rule\",\"ruler\",\"run\",\n \"running\",\"rush\",\"sad\",\"saddle\",\"safe\",\"safety\",\"said\",\"sail\",\n \"sale\",\"salmon\",\"salt\",\"same\",\"sand\",\"sang\",\"sat\",\"satellites\",\n \"satisfied\",\"save\",\"saved\",\"saw\",\"say\",\"scale\",\"scared\",\"scene\",\n \"school\",\"science\",\"scientific\",\"scientist\",\"score\",\"screen\",\"sea\",\"search\",\n \"season\",\"seat\",\"second\",\"secret\",\"section\",\"see\",\"seed\",\"seeing\",\n \"seems\",\"seen\",\"seldom\",\"select\",\"selection\",\"sell\",\"send\",\"sense\",\n \"sent\",\"sentence\",\"separate\",\"series\",\"serious\",\"serve\",\"service\",\"sets\",\n \"setting\",\"settle\",\"settlers\",\"seven\",\"several\",\"shade\",\"shadow\",\"shake\",\n \"shaking\",\"shall\",\"shallow\",\"shape\",\"share\",\"sharp\",\"she\",\"sheep\",\n \"sheet\",\"shelf\",\"shells\",\"shelter\",\"shine\",\"shinning\",\"ship\",\"shirt\",\n \"shoe\",\"shoot\",\"shop\",\"shore\",\"short\",\"shorter\",\"shot\",\"should\",\n \"shoulder\",\"shout\",\"show\",\"shown\",\"shut\",\"sick\",\"sides\",\"sight\",\n \"sign\",\"signal\",\"silence\",\"silent\",\"silk\",\"silly\",\"silver\",\"similar\",\n \"simple\",\"simplest\",\"simply\",\"since\",\"sing\",\"single\",\"sink\",\"sister\",\n \"sit\",\"sitting\",\"situation\",\"six\",\"size\",\"skill\",\"skin\",\"sky\",\n \"slabs\",\"slave\",\"sleep\",\"slept\",\"slide\",\"slight\",\"slightly\",\"slip\",\n \"slipped\",\"slope\",\"slow\",\"slowly\",\"small\",\"smaller\",\"smallest\",\"smell\",\n \"smile\",\"smoke\",\"smooth\",\"snake\",\"snow\",\"so\",\"soap\",\"social\",\n \"society\",\"soft\",\"softly\",\"soil\",\"solar\",\"sold\",\"soldier\",\"solid\",\n \"solution\",\"solve\",\"some\",\"somebody\",\"somehow\",\"someone\",\"something\",\"sometime\",\n \"somewhere\",\"son\",\"song\",\"soon\",\"sort\",\"sound\",\"source\",\"south\",\n \"southern\",\"space\",\"speak\",\"special\",\"species\",\"specific\",\"speech\",\"speed\",\n \"spell\",\"spend\",\"spent\",\"spider\",\"spin\",\"spirit\",\"spite\",\"split\",\n \"spoken\",\"sport\",\"spread\",\"spring\",\"square\",\"stage\",\"stairs\",\"stand\",\n \"standard\",\"star\",\"stared\",\"start\",\"state\",\"statement\",\"station\",\"stay\",\n \"steady\",\"steam\",\"steel\",\"steep\",\"stems\",\"step\",\"stepped\",\"stick\",\n \"stiff\",\"still\",\"stock\",\"stomach\",\"stone\",\"stood\",\"stop\",\"stopped\",\n \"store\",\"storm\",\"story\",\"stove\",\"straight\",\"strange\",\"stranger\",\"straw\",\n \"stream\",\"street\",\"strength\",\"stretch\",\"strike\",\"string\",\"strip\",\"strong\",\n \"stronger\",\"struck\",\"structure\",\"struggle\",\"stuck\",\"student\",\"studied\",\"studying\",\n \"subject\",\"substance\",\"success\",\"successful\",\"such\",\"sudden\",\"suddenly\",\"sugar\",\n \"suggest\",\"suit\",\"sum\",\"summer\",\"sun\",\"sunlight\",\"supper\",\"supply\",\n \"support\",\"suppose\",\"sure\",\"surface\",\"surprise\",\"surrounded\",\"swam\",\"sweet\",\n \"swept\",\"swim\",\"swimming\",\"swing\",\"swung\",\"syllable\",\"symbol\",\"system\",\n \"table\",\"tail\",\"take\",\"taken\",\"tales\",\"talk\",\"tall\",\"tank\",\n \"tape\",\"task\",\"taste\",\"taught\",\"tax\",\"tea\",\"teach\",\"teacher\",\n \"team\",\"tears\",\"teeth\",\"telephone\",\"television\",\"tell\",\"temperature\",\"ten\",\n \"tent\",\"term\",\"terrible\",\"test\",\"than\",\"thank\",\"that\",\"thee\",\n \"them\",\"themselves\",\"then\",\"theory\",\"there\",\"therefore\",\"these\",\"they\",\n \"thick\",\"thin\",\"thing\",\"think\",\"third\",\"thirty\",\"this\",\"those\",\n \"thou\",\"though\",\"thought\",\"thousand\",\"thread\",\"three\",\"threw\",\"throat\",\n \"through\",\"throughout\",\"throw\",\"thrown\",\"thumb\",\"thus\",\"thy\",\"tide\",\n \"tie\",\"tight\",\"tightly\",\"till\",\"time\",\"tin\",\"tiny\",\"tip\",\n \"tired\",\"title\",\"to\",\"tobacco\",\"today\",\"together\",\"told\",\"tomorrow\",\n \"tone\",\"tongue\",\"tonight\",\"too\",\"took\",\"tool\",\"top\",\"topic\",\n \"torn\",\"total\",\"touch\",\"toward\",\"tower\",\"town\",\"toy\",\"trace\",\n \"track\",\"trade\",\"traffic\",\"trail\",\"train\",\"transportation\",\"trap\",\"travel\",\n \"treated\",\"tree\",\"triangle\",\"tribe\",\"trick\",\"tried\",\"trip\",\"troops\",\n \"tropical\",\"trouble\",\"truck\",\"trunk\",\"truth\",\"try\",\"tube\",\"tune\",\n \"turn\",\"twelve\",\"twenty\",\"twice\",\"two\",\"type\",\"typical\",\"uncle\",\n \"under\",\"underline\",\"understanding\",\"unhappy\",\"union\",\"unit\",\"universe\",\"unknown\",\n \"unless\",\"until\",\"unusual\",\"up\",\"upon\",\"upper\",\"upward\",\"us\",\n \"use\",\"useful\",\"using\",\"usual\",\"usually\",\"valley\",\"valuable\",\"value\",\n \"vapor\",\"variety\",\"various\",\"vast\",\"vegetable\",\"verb\",\"vertical\",\"very\",\n \"vessels\",\"victory\",\"view\",\"village\",\"visit\",\"visitor\",\"voice\",\"volume\",\n \"vote\",\"vowel\",\"voyage\",\"wagon\",\"wait\",\"walk\",\"wall\",\"want\",\n \"war\",\"warm\",\"warn\",\"was\",\"wash\",\"waste\",\"watch\",\"water\",\n \"wave\",\"way\",\"we\",\"weak\",\"wealth\",\"wear\",\"weather\",\"week\",\n \"weigh\",\"weight\",\"welcome\",\"well\",\"went\",\"were\",\"west\",\"western\",\n \"wet\",\"whale\",\"what\",\"whatever\",\"wheat\",\"wheel\",\"when\",\"whenever\",\n \"where\",\"wherever\",\"whether\",\"which\",\"while\",\"whispered\",\"whistle\",\"white\",\n \"who\",\"whole\",\"whom\",\"whose\",\"why\",\"wide\",\"widely\",\"wife\",\n \"wild\",\"will\",\"willing\",\"win\",\"wind\",\"window\",\"wing\",\"winter\",\n \"wire\",\"wise\",\"wish\",\"with\",\"within\",\"without\",\"wolf\",\"women\",\n \"won\",\"wonder\",\"wonderful\",\"wood\",\"wooden\",\"wool\",\"word\",\"wore\",\n \"work\",\"worker\",\"world\",\"worried\",\"worry\",\"worse\",\"worth\",\"would\",\n \"wrapped\",\"write\",\"writer\",\"writing\",\"written\",\"wrong\",\"wrote\",\"yard\",\n \"year\",\"yellow\",\"yes\",\"yesterday\",\"yet\",\"you\",\"young\",\"younger\",\n \"your\",\"yourself\",\"youth\",\"zero\",\"zebra\",\"zipper\",\"zoo\",\"zulu\"\n];\n\nfunction words(options) {\n\n function word() {\n if (options && options.maxLength > 1) {\n return generateWordWithMaxLength();\n } else {\n return generateRandomWord();\n }\n }\n\n function generateWordWithMaxLength() {\n var rightSize = false;\n var wordUsed;\n while (!rightSize) { \n wordUsed = generateRandomWord();\n if(wordUsed.length <= options.maxLength) {\n rightSize = true;\n }\n\n }\n return wordUsed;\n }\n\n function generateRandomWord() {\n return wordList[randInt(wordList.length)];\n }\n\n function randInt(lessThan) {\n return Math.floor(Math.random() * lessThan);\n }\n\n // No arguments = generate one word\n if (typeof(options) === 'undefined') {\n return word();\n }\n\n // Just a number = return that many words\n if (typeof(options) === 'number') {\n options = { exactly: options };\n }\n\n // options supported: exactly, min, max, join\n if (options.exactly) {\n options.min = options.exactly;\n options.max = options.exactly;\n }\n \n // not a number = one word par string\n if (typeof(options.wordsPerString) !== 'number') {\n options.wordsPerString = 1;\n }\n\n //not a function = returns the raw word\n if (typeof(options.formatter) !== 'function') {\n options.formatter = (word) => word;\n }\n\n //not a string = separator is a space\n if (typeof(options.separator) !== 'string') {\n options.separator = ' ';\n }\n\n var total = options.min + randInt(options.max + 1 - options.min);\n var results = [];\n var token = '';\n var relativeIndex = 0;\n\n for (var i = 0; (i < total * options.wordsPerString); i++) {\n if (relativeIndex === options.wordsPerString - 1) {\n token += options.formatter(word(), relativeIndex);\n }\n else {\n token += options.formatter(word(), relativeIndex) + options.separator;\n }\n relativeIndex++;\n if ((i + 1) % options.wordsPerString === 0) {\n results.push(token);\n token = ''; \n relativeIndex = 0;\n }\n \n }\n if (typeof options.join === 'string') {\n results = results.join(options.join);\n }\n\n return results;\n}\n\nmodule.exports = words;\n// Export the word list as it is often useful\nwords.wordList = wordList;\n","import rw from \"random-words\";\n\nexport function repeat(array, repetitions, unpack = false) {\n const arr_isArray = Array.isArray(array);\n const rep_isArray = Array.isArray(repetitions);\n\n // if array is not an array, then we just repeat the item\n if (!arr_isArray) {\n if (!rep_isArray) {\n array = [array];\n repetitions = [repetitions];\n } else {\n repetitions = [repetitions[0]];\n console.log(\n \"Unclear parameters given to randomization.repeat. Multiple set sizes specified, but only one item exists to sample. Proceeding using the first set size.\"\n );\n }\n } else {\n // if repetitions is not an array, but array is, then we\n // repeat repetitions for each entry in array\n if (!rep_isArray) {\n let reps = [];\n for (let i = 0; i < array.length; i++) {\n reps.push(repetitions);\n }\n repetitions = reps;\n } else {\n if (array.length != repetitions.length) {\n console.warn(\n \"Unclear parameters given to randomization.repeat. Items and repetitions are unequal lengths. Behavior may not be as expected.\"\n );\n // throw warning if repetitions is too short, use first rep ONLY.\n if (repetitions.length < array.length) {\n let reps = [];\n for (let i = 0; i < array.length; i++) {\n reps.push(repetitions);\n }\n repetitions = reps;\n } else {\n // throw warning if too long, and then use the first N\n repetitions = repetitions.slice(0, array.length);\n }\n }\n }\n }\n\n // should be clear at this point to assume that array and repetitions are arrays with == length\n let allsamples = [];\n for (let i = 0; i < array.length; i++) {\n for (let j = 0; j < repetitions[i]; j++) {\n if (array[i] == null || typeof array[i] != \"object\") {\n allsamples.push(array[i]);\n } else {\n allsamples.push(Object.assign({}, array[i]));\n }\n }\n }\n\n let out: any = shuffle(allsamples);\n\n if (unpack) {\n out = unpackArray(out);\n }\n\n return out;\n}\n\nexport function shuffle(array: Array<any>) {\n if (!Array.isArray(array)) {\n console.error(\"Argument to shuffle() must be an array.\");\n }\n\n const copy_array = array.slice(0);\n let m = copy_array.length,\n t,\n i;\n\n // While there remain elements to shuffle…\n while (m) {\n // Pick a remaining element…\n i = Math.floor(Math.random() * m--);\n\n // And swap it with the current element.\n t = copy_array[m];\n copy_array[m] = copy_array[i];\n copy_array[i] = t;\n }\n\n return copy_array;\n}\n\nexport function shuffleNoRepeats(arr: Array<any>, equalityTest: (a: any, b: any) => boolean) {\n if (!Array.isArray(arr)) {\n console.error(\"First argument to shuffleNoRepeats() must be an array.\");\n }\n if (typeof equalityTest !== \"undefined\" && typeof equalityTest !== \"function\") {\n console.error(\"Second argument to shuffleNoRepeats() must be a function.\");\n }\n // define a default equalityTest\n if (typeof equalityTest == \"undefined\") {\n equalityTest = function (a, b) {\n if (a === b) {\n return true;\n } else {\n return false;\n }\n };\n }\n\n const random_shuffle = shuffle(arr);\n for (let i = 0; i < random_shuffle.length - 1; i++) {\n if (equalityTest(random_shuffle[i], random_shuffle[i + 1])) {\n // neighbors are equal, pick a new random neighbor to swap (not the first or last element, to avoid edge cases)\n let random_pick = Math.floor(Math.random() * (random_shuffle.length - 2)) + 1;\n // test to make sure the new neighbor isn't equal to the old one\n while (\n equalityTest(random_shuffle[i + 1], random_shuffle[random_pick]) ||\n equalityTest(random_shuffle[i + 1], random_shuffle[random_pick + 1]) ||\n equalityTest(random_shuffle[i + 1], random_shuffle[random_pick - 1])\n ) {\n random_pick = Math.floor(Math.random() * (random_shuffle.length - 2)) + 1;\n }\n const new_neighbor = random_shuffle[random_pick];\n random_shuffle[random_pick] = random_shuffle[i + 1];\n random_shuffle[i + 1] = new_neighbor;\n }\n }\n\n return random_shuffle;\n}\n\nexport function shuffleAlternateGroups(arr_groups, random_group_order = false) {\n const n_groups = arr_groups.length;\n if (n_groups == 1) {\n console.warn(\n \"shuffleAlternateGroups() was called with only one group. Defaulting to simple shuffle.\"\n );\n return shuffle(arr_groups[0]);\n }\n\n let group_order = [];\n for (let i = 0; i < n_groups; i++) {\n group_order.push(i);\n }\n if (random_group_order) {\n group_order = shuffle(group_order);\n }\n\n const randomized_groups = [];\n let min_length = null;\n for (let i = 0; i < n_groups; i++) {\n min_length =\n min_length === null ? arr_groups[i].length : Math.min(min_length, arr_groups[i].length);\n randomized_groups.push(shuffle(arr_groups[i]));\n }\n\n const out = [];\n for (let i = 0; i < min_length; i++) {\n for (let j = 0; j < group_order.length; j++) {\n out.push(randomized_groups[group_order[j]][i]);\n }\n }\n\n return out;\n}\n\nexport function sampleWithoutReplacement(arr, size) {\n if (!Array.isArray(arr)) {\n console.error(\"First argument to sampleWithoutReplacement() must be an array\");\n }\n\n if (size > arr.length) {\n console.error(\"Cannot take a sample larger than the size of the set of items to sample.\");\n }\n return shuffle(arr).slice(0, size);\n}\n\nexport function sampleWithReplacement(arr, size, weights?) {\n if (!Array.isArray(arr)) {\n console.error(\"First argument to sampleWithReplacement() must be an array\");\n }\n\n const normalized_weights = [];\n if (typeof weights !== \"undefined\") {\n if (weights.length !== arr.length) {\n console.error(\n \"The length of the weights array must equal the length of the array \" +\n \"to be sampled from.\"\n );\n }\n let weight_sum = 0;\n for (const weight of weights) {\n weight_sum += weight;\n }\n for (const weight of weights) {\n normalized_weights.push(weight / weight_sum);\n }\n } else {\n for (let i = 0; i < arr.length; i++) {\n normalized_weights.push(1 / arr.length);\n }\n }\n\n const cumulative_weights = [normalized_weights[0]];\n for (let i = 1; i < normalized_weights.length; i++) {\n cumulative_weights.push(normalized_weights[i] + cumulative_weights[i - 1]);\n }\n\n const samp = [];\n for (let i = 0; i < size; i++) {\n const rnd = Math.random();\n let index = 0;\n while (rnd > cumulative_weights[index]) {\n index++;\n }\n samp.push(arr[index]);\n }\n return samp;\n}\n\nexport function factorial(factors: Record<string, any>, repetitions = 1, unpack = false) {\n let design = [{}];\n for (const [factorName, factor] of Object.entries(factors)) {\n const new_design = [];\n for (const level of factor) {\n for (const cell of design) {\n new_design.push({ ...cell, [factorName]: level });\n }\n }\n design = new_design;\n }\n\n return repeat(design, repetitions, unpack);\n}\n\nexport function randomID(length = 32) {\n let result = \"\";\n const chars = \"0123456789abcdefghjklmnopqrstuvwxyz\";\n for (let i = 0; i < length; i++) {\n result += chars[Math.floor(Math.random() * chars.length)];\n }\n return result;\n}\n\n/**\n * Generate a random integer from `lower` to `upper`, inclusive of both end points.\n * @param lower The lowest value it is possible to generate\n * @param upper The highest value it is possible to generate\n * @returns A random integer\n */\nexport function randomInt(lower: number, upper: number) {\n if (upper < lower) {\n throw new Error(\"Upper boundary must be less than or equal to lower boundary\");\n }\n return lower + Math.floor(Math.random() * (upper - lower + 1));\n}\n\n/**\n * Generates a random sample from a Bernoulli distribution.\n * @param p The probability of sampling 1.\n * @returns 0, with probability 1-p, or 1, with probability p.\n */\nexport function sampleBernoulli(p: number) {\n return Math.random() <= p ? 1 : 0;\n}\n\nexport function sampleNormal(mean: number, standard_deviation: number) {\n return randn_bm() * standard_deviation + mean;\n}\n\nexport function sampleExponential(rate: number) {\n return -Math.log(Math.random()) / rate;\n}\n\nexport function sampleExGaussian(\n mean: number,\n standard_deviation: number,\n rate: number,\n positive = false\n) {\n let s = sampleNormal(mean, standard_deviation) + sampleExponential(rate);\n if (positive) {\n while (s <= 0) {\n s = sampleNormal(mean, standard_deviation) + sampleExponential(rate);\n }\n }\n return s;\n}\n\n/**\n * Generate one or more random words.\n *\n * This is a wrapper function for the {@link https://www.npmjs.com/package/random-words `random-words` npm package}.\n *\n * @param opts An object with optional properties `min`, `max`, `exactly`,\n * `join`, `maxLength`, `wordsPerString`, `separator`, and `formatter`.\n *\n * @returns An array of words or a single string, depending on parameter choices.\n */\nexport function randomWords(opts) {\n return rw(opts);\n}\n\n// Box-Muller transformation for a random sample from normal distribution with mean = 0, std = 1\n// https://stackoverflow.com/a/36481059/3726673\nfunction randn_bm() {\n var u = 0,\n v = 0;\n while (u === 0) u = Math.random(); //Converting [0,1) to (0,1)\n while (v === 0) v = Math.random();\n return Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);\n}\n\nfunction unpackArray(array) {\n const out = {};\n\n for (const x of array) {\n for (const key of Object.keys(x)) {\n if (typeof out[key] === \"undefined\") {\n out[key] = [];\n }\n out[key].push(x[key]);\n }\n }\n\n return out;\n}\n","interface turkInformation {\n /**\n * Is the experiment being loaded in preview mode on Mechanical Turk?\n */\n previewMode: boolean;\n /**\n * Is the experiment being loaded outside of the Mechanical Turk environment?\n */\n outsideTurk: boolean;\n /**\n * The HIT ID.\n */\n hitId: string;\n /**\n * The Assignment ID.\n */\n assignmentId: string;\n /**\n * The worker ID.\n */\n workerId: string;\n /**\n * URL for submission of the HIT.\n */\n turkSubmitTo: string;\n}\n\n/**\n * Gets information about the Mechanical Turk Environment, HIT, Assignment, and Worker\n * by parsing the URL variables that Mechanical Turk generates.\n * @returns An object containing information about the Mechanical Turk Environment, HIT, Assignment, and Worker.\n */\nexport function turkInfo(): turkInformation {\n const turk: turkInformation = {\n previewMode: false,\n outsideTurk: false,\n hitId: \"INVALID_URL_PARAMETER\",\n assignmentId: \"INVALID_URL_PARAMETER\",\n workerId: \"INVALID_URL_PARAMETER\",\n turkSubmitTo: \"INVALID_URL_PARAMETER\",\n };\n\n const param = function (url, name) {\n name = name.replace(/[\\[]/, \"\\\\[\").replace(/[\\]]/, \"\\\\]\");\n const regexS = \"[\\\\?&]\" + name + \"=([^&#]*)\";\n const regex = new RegExp(regexS);\n const results = regex.exec(url);\n return results == null ? \"\" : results[1];\n };\n\n const src = param(window.location.href, \"assignmentId\")\n ? window.location.href\n : document.referrer;\n\n const keys = [\"assignmentId\", \"hitId\", \"workerId\", \"turkSubmitTo\"];\n keys.map(function (key) {\n turk[key] = unescape(param(src, key));\n });\n\n turk.previewMode = turk.assignmentId == \"ASSIGNMENT_ID_NOT_AVAILABLE\";\n\n turk.outsideTurk =\n !turk.previewMode && turk.hitId === \"\" && turk.assignmentId == \"\" && turk.workerId == \"\";\n\n return turk;\n}\n\n/**\n * Send data to Mechnical Turk for storage.\n * @param data An object containing `key:value` pairs to send to Mechanical Turk. Values\n * cannot contain nested objects, arrays, or functions.\n * @returns Nothing\n */\nexport function submitToTurk(data) {\n const turk = turkInfo();\n const assignmentId = turk.assignmentId;\n const turkSubmitTo = turk.turkSubmitTo;\n\n if (!assignmentId || !turkSubmitTo) return;\n\n const form = document.createElement(\"form\");\n form.method = \"POST\";\n form.action = turkSubmitTo + \"/mturk/externalSubmit?assignmentId=\" + assignmentId;\n\n for (const key in data) {\n if (data.hasOwnProperty(key)) {\n const hiddenField = document.createElement(\"input\");\n hiddenField.type = \"hidden\";\n hiddenField.name = key;\n hiddenField.id = key;\n hiddenField.value = data[key];\n\n form.appendChild(hiddenField);\n }\n }\n\n document.body.appendChild(form);\n form.submit();\n}\n","import { JsPsych } from \"./JsPsych\";\nimport {\n repeat,\n sampleWithReplacement,\n sampleWithoutReplacement,\n shuffle,\n shuffleAlternateGroups,\n} from \"./modules/randomization\";\nimport { deepCopy } from \"./modules/utils\";\n\nexport class TimelineNode {\n // a unique ID for this node, relative to the parent\n relative_id;\n\n // store the parent for this node\n parent_node;\n\n // parameters for the trial if the node contains a trial\n trial_parameters;\n\n // parameters for nodes that contain timelines\n timeline_parameters;\n\n // stores trial information on a node that contains a timeline\n // used for adding new trials\n node_trial_data;\n\n // track progress through the node\n progress = <any>{\n current_location: -1, // where on the timeline (which timelinenode)\n current_variable_set: 0, // which set of variables to use from timeline_variables\n current_repetition: 0, // how many times through the variable set on this run of the node\n current_iteration: 0, // how many times this node has been revisited\n done: false,\n };\n\n end_message?: string;\n\n // constructor\n constructor(private jsPsych: JsPsych, parameters, parent?, relativeID?) {\n // store a link to the parent of this node\n this.parent_node = parent;\n\n // create the ID for this node\n this.relative_id = typeof parent === \"undefined\" ? 0 : relativeID;\n\n // check if there is a timeline parameter\n // if there is, then this node has its own timeline\n if (typeof parameters.timeline !== \"undefined\") {\n // create timeline properties\n this.timeline_parameters = {\n timeline: [],\n loop_function: parameters.loop_function,\n conditional_function: parameters.conditional_function,\n sample: parameters.sample,\n randomize_order:\n typeof parameters.randomize_order == \"undefined\" ? false : parameters.randomize_order,\n repetitions: typeof parameters.repetitions == \"undefined\" ? 1 : parameters.repetitions,\n timeline_variables:\n typeof parameters.timeline_variables == \"undefined\"\n ? [{}]\n : parameters.timeline_variables,\n on_timeline_finish: parameters.on_timeline_finish,\n on_timeline_start: parameters.on_timeline_start,\n };\n\n this.setTimelineVariablesOrder();\n\n // extract all of the node level data and parameters\n // but remove all of the timeline-level specific information\n // since this will be used to copy things down hierarchically\n var node_data = Object.assign({}, parameters);\n delete node_data.timeline;\n delete node_data.conditional_function;\n delete node_data.loop_function;\n delete node_data.randomize_order;\n delete node_data.repetitions;\n delete node_data.timeline_variables;\n delete node_data.sample;\n delete node_data.on_timeline_start;\n delete node_data.on_timeline_finish;\n this.node_trial_data = node_data; // store for later...\n\n // create a TimelineNode for each element in the timeline\n for (var i = 0; i < parameters.timeline.length; i++) {\n // merge parameters\n var merged_parameters = Object.assign({}, node_data, parameters.timeline[i]);\n // merge any data from the parent node into child nodes\n if (typeof node_data.data == \"object\" && typeof parameters.timeline[i].data == \"object\") {\n var merged_data = Object.assign({}, node_data.data, parameters.timeline[i].data);\n merged_parameters.data = merged_data;\n }\n this.timeline_parameters.timeline.push(\n new TimelineNode(this.jsPsych, merged_parameters, this, i)\n );\n }\n }\n // if there is no timeline parameter, then this node is a trial node\n else {\n // check to see if a valid trial type is defined\n if (typeof parameters.type === \"undefined\") {\n console.error(\n 'Trial level node is missing the \"type\" parameter. The parameters for the node are: ' +\n JSON.stringify(parameters)\n );\n }\n // create a deep copy of the parameters for the trial\n this.trial_parameters = { ...parameters };\n }\n }\n\n // recursively get the next trial to run.\n // if this node is a leaf (trial), then return the trial.\n // otherwise, recursively find the next trial in the child timeline.\n trial() {\n if (typeof this.timeline_parameters == \"undefined\") {\n // returns a clone of the trial_parameters to\n // protect functions.\n return deepCopy(this.trial_parameters);\n } else {\n if (this.progress.current_location >= this.timeline_parameters.timeline.length) {\n return null;\n } else {\n return this.timeline_parameters.timeline[this.progress.current_location].trial();\n }\n }\n }\n\n markCurrentTrialComplete() {\n if (typeof this.timeline_parameters === \"undefined\") {\n this.progress.done = true;\n } else {\n this.timeline_parameters.timeline[this.progress.current_location].markCurrentTrialComplete();\n }\n }\n\n nextRepetiton() {\n this.setTimelineVariablesOrder();\n this.progress.current_location = -1;\n this.progress.current_variable_set = 0;\n this.progress.current_repetition++;\n for (var i = 0; i < this.timeline_parameters.timeline.length; i++) {\n this.timeline_parameters.timeline[i].reset();\n }\n }\n\n // set the order for going through the timeline variables array\n setTimelineVariablesOrder() {\n const timeline_parameters = this.timeline_parameters;\n\n // check to make sure this node has variables\n if (\n typeof timeline_parameters === \"undefined\" ||\n typeof timeline_parameters.timeline_variables === \"undefined\"\n ) {\n return;\n }\n\n var order = [];\n for (var i = 0; i < timeline_parameters.timeline_variables.length; i++) {\n order.push(i);\n }\n\n if (typeof timeline_parameters.sample !== \"undefined\") {\n if (timeline_parameters.sample.type == \"custom\") {\n order = timeline_parameters.sample.fn(order);\n } else if (timeline_parameters.sample.type == \"with-replacement\") {\n order = sampleWithReplacement(\n order,\n timeline_parameters.sample.size,\n timeline_parameters.sample.weights\n );\n } else if (timeline_parameters.sample.type == \"without-replacement\") {\n order = sampleWithoutReplacement(order, timeline_parameters.sample.size);\n } else if (timeline_parameters.sample.type == \"fixed-repetitions\") {\n order = repeat(order, timeline_parameters.sample.size, false);\n } else if (timeline_parameters.sample.type == \"alternate-groups\") {\n order = shuffleAlternateGroups(\n timeline_parameters.sample.groups,\n timeline_parameters.sample.randomize_group_order\n );\n } else {\n console.error(\n 'Invalid type in timeline sample parameters. Valid options for type are \"custom\", \"with-replacement\", \"without-replacement\", \"fixed-repetitions\", and \"alternate-groups\"'\n );\n }\n }\n\n if (timeline_parameters.randomize_order) {\n order = shuffle(order);\n }\n\n this.progress.order = order;\n }\n\n // next variable set\n nextSet() {\n this.progress.current_location = -1;\n this.progress.current_variable_set++;\n for (var i = 0; i < this.timeline_parameters.timeline.length; i++) {\n this.timeline_parameters.timeline[i].reset();\n }\n }\n\n // update the current trial node to be completed\n // returns true if the node is complete after advance (all subnodes are also complete)\n // returns false otherwise\n advance() {\n const progress = this.progress;\n const timeline_parameters = this.timeline_parameters;\n const internal = this.jsPsych.internal;\n\n // first check to see if done\n if (progress.done) {\n return true;\n }\n\n // if node has not started yet (progress.current_location == -1),\n // then try to start the node.\n if (progress.current_location == -1) {\n // check for on_timeline_start and conditonal function on nodes with timelines\n if (typeof timeline_parameters !== \"undefined\") {\n // only run the conditional function if this is the first repetition of the timeline when\n // repetitions > 1, and only when on the first variable set\n if (\n typeof timeline_parameters.conditional_function !== \"undefined\" &&\n progress.current_repetition == 0 &&\n progress.current_variable_set == 0\n ) {\n internal.call_immediate = true;\n var conditional_result = timeline_parameters.conditional_function();\n internal.call_immediate = false;\n // if the conditional_function() returns false, then the timeline\n // doesn't run and is marked as complete.\n if (conditional_result == false) {\n progress.done = true;\n return true;\n }\n }\n\n // if we reach this point then the node has its own timeline and will start\n // so we need to check if there is an on_timeline_start function if we are on the first variable set\n if (\n typeof timeline_parameters.on_timeline_start !== \"undefined\" &&\n progress.current_variable_set == 0\n ) {\n timeline_parameters.on_timeline_start();\n }\n }\n // if we reach this point, then either the node doesn't have a timeline of the\n // conditional function returned true and it can start\n progress.current_location = 0;\n // call advance again on this node now that it is pointing to a new location\n return this.advance();\n }\n\n // if this node has a timeline, propogate down to the current trial.\n if (typeof timeline_parameters !== \"undefined\") {\n var have_node_to_run = false;\n // keep incrementing the location in the timeline until one of the nodes reached is incomplete\n while (\n progress.current_location < timeline_parameters.timeline.length &&\n have_node_to_run == false\n ) {\n // check to see if the node currently pointed at is done\n var target_complete = timeline_parameters.timeline[progress.current_location].advance();\n if (!target_complete) {\n have_node_to_run = true;\n return false;\n } else {\n progress.current_location++;\n }\n }\n\n // if we've reached the end of the timeline (which, if the code is here, we have)\n\n // there are a few steps to see what to do next...\n\n // first, check the timeline_variables to see if we need to loop through again\n // with a new set of variables\n if (progress.current_variable_set < progress.order.length - 1) {\n // reset the progress of the node to be with the new set\n this.nextSet();\n // then try to advance this node again.\n return this.advance();\n }\n\n // if we're all done with the timeline_variables, then check to see if there are more repetitions\n else if (progress.current_repetition < timeline_parameters.repetitions - 1) {\n this.nextRepetiton();\n // check to see if there is an on_timeline_finish function\n if (typeof timeline_parameters.on_timeline_finish !== \"undefined\") {\n timeline_parameters.on_timeline_finish();\n }\n return this.advance();\n }\n\n // if we're all done with the repetitions...\n else {\n // check to see if there is an on_timeline_finish function\n if (typeof timeline_parameters.on_timeline_finish !== \"undefined\") {\n timeline_parameters.on_timeline_finish();\n }\n\n // if we're all done with the repetitions, check if there is a loop function.\n if (typeof timeline_parameters.loop_function !== \"undefined\") {\n internal.call_immediate = true;\n if (timeline_parameters.loop_function(this.generatedData())) {\n this.reset();\n internal.call_immediate = false;\n return this.parent_node.advance();\n } else {\n progress.done = true;\n internal.call_immediate = false;\n return true;\n }\n }\n }\n\n // no more loops on this timeline, we're done!\n progress.done = true;\n return true;\n }\n }\n\n // check the status of the done flag\n isComplete() {\n return this.progress.done;\n }\n\n // getter method for timeline variables\n getTimelineVariableValue(variable_name: string) {\n if (typeof this.timeline_parameters == \"undefined\") {\n return undefined;\n }\n var v =\n this.timeline_parameters.timeline_variables[\n this.progress.order[this.progress.current_variable_set]\n ][variable_name];\n return v;\n }\n\n // recursive upward search for timeline variables\n findTimelineVariable(variable_name) {\n var v = this.getTimelineVariableValue(variable_name);\n if (typeof v == \"undefined\") {\n if (typeof this.parent_node !== \"undefined\") {\n return this.parent_node.findTimelineVariable(variable_name);\n } else {\n return undefined;\n }\n } else {\n return v;\n }\n }\n\n // recursive downward search for active trial to extract timeline variable\n timelineVariable(variable_name: string) {\n if (typeof this.timeline_parameters == \"undefined\") {\n return this.findTimelineVariable(variable_name);\n } else {\n // if progress.current_location is -1, then the timeline variable is being evaluated\n // in a function that runs prior to the trial starting, so we should treat that trial\n // as being the active trial for purposes of finding the value of the timeline variable\n var loc = Math.max(0, this.progress.current_location);\n // if loc is greater than the number of elements on this timeline, then the timeline\n // variable is being evaluated in a function that runs after the trial on the timeline\n // are complete but before advancing to the next (like a loop_function).\n // treat the last active trial as the active trial for this purpose.\n if (loc == this.timeline_parameters.timeline.length) {\n loc = loc - 1;\n }\n // now find the variable\n return this.timeline_parameters.timeline[loc].timelineVariable(variable_name);\n }\n }\n\n // recursively get all the timeline variables for this trial\n allTimelineVariables() {\n var all_tvs = this.allTimelineVariablesNames();\n var all_tvs_vals = <any>{};\n for (var i = 0; i < all_tvs.length; i++) {\n all_tvs_vals[all_tvs[i]] = this.timelineVariable(all_tvs[i]);\n }\n return all_tvs_vals;\n }\n\n // helper to get all the names at this stage.\n allTimelineVariablesNames(so_far = []) {\n if (typeof this.timeline_parameters !== \"undefined\") {\n so_far = so_far.concat(\n Object.keys(\n this.timeline_parameters.timeline_variables[\n this.progress.order[this.progress.current_variable_set]\n ]\n )\n );\n // if progress.current_location is -1, then the timeline variable is being evaluated\n // in a function that runs prior to the trial starting, so we should treat that trial\n // as being the active trial for purposes of finding the value of the timeline variable\n var loc = Math.max(0, this.progress.current_location);\n // if loc is greater than the number of elements on this timeline, then the timeline\n // variable is being evaluated in a function that runs after the trial on the timeline\n // are complete but before advancing to the next (like a loop_function).\n // treat the last active trial as the active trial for this purpose.\n if (loc == this.timeline_parameters.timeline.length) {\n loc = loc - 1;\n }\n // now find the variable\n return this.timeline_parameters.timeline[loc].allTimelineVariablesNames(so_far);\n }\n if (typeof this.timeline_parameters == \"undefined\") {\n return so_far;\n }\n }\n\n // recursively get the number of **trials** contained in the timeline\n // assuming that while loops execute exactly once and if conditionals\n // always run\n length() {\n var length = 0;\n if (typeof this.timeline_parameters !== \"undefined\") {\n for (var i = 0; i < this.timeline_parameters.timeline.length; i++) {\n length += this.timeline_parameters.timeline[i].length();\n }\n } else {\n return 1;\n }\n return length;\n }\n\n // return the percentage of trials completed, grouped at the first child level\n // counts a set of trials as complete when the child node is done\n percentComplete() {\n var total_trials = this.length();\n var completed_trials = 0;\n for (var i = 0; i < this.timeline_parameters.timeline.length; i++) {\n if (this.timeline_parameters.timeline[i].isComplete()) {\n completed_trials += this.timeline_parameters.timeline[i].length();\n }\n }\n return (completed_trials / total_trials) * 100;\n }\n\n // resets the node and all subnodes to original state\n // but increments the current_iteration counter\n reset() {\n this.progress.current_location = -1;\n this.progress.current_repetition = 0;\n this.progress.current_variable_set = 0;\n this.progress.current_iteration++;\n this.progress.done = false;\n this.setTimelineVariablesOrder();\n if (typeof this.timeline_parameters != \"undefined\") {\n for (var i = 0; i < this.timeline_parameters.timeline.length; i++) {\n this.timeline_parameters.timeline[i].reset();\n }\n }\n }\n\n // mark this node as finished\n end() {\n this.progress.done = true;\n }\n\n // recursively end whatever sub-node is running the current trial\n endActiveNode() {\n if (typeof this.timeline_parameters == \"undefined\") {\n this.end();\n this.parent_node.end();\n } else {\n this.timeline_parameters.timeline[this.progress.current_location].endActiveNode();\n }\n }\n\n // get a unique ID associated with this node\n // the ID reflects the current iteration through this node.\n ID() {\n var id = \"\";\n if (typeof this.parent_node == \"undefined\") {\n return \"0.\" + this.progress.current_iteration;\n } else {\n id += this.parent_node.ID() + \"-\";\n id += this.relative_id + \".\" + this.progress.current_iteration;\n return id;\n }\n }\n\n // get the ID of the active trial\n activeID() {\n if (typeof this.timeline_parameters == \"undefined\") {\n return this.ID();\n } else {\n return this.timeline_parameters.timeline[this.progress.current_location].activeID();\n }\n }\n\n // get all the data generated within this node\n generatedData() {\n return this.jsPsych.data.getDataByTimelineNode(this.ID());\n }\n\n // get all the trials of a particular type\n trialsOfType(type) {\n if (typeof this.timeline_parameters == \"undefined\") {\n if (this.trial_parameters.type == type) {\n return this.trial_parameters;\n } else {\n return [];\n }\n } else {\n var trials = [];\n for (var i = 0; i < this.timeline_parameters.timeline.length; i++) {\n var t = this.timeline_parameters.timeline[i].trialsOfType(type);\n trials = trials.concat(t);\n }\n return trials;\n }\n }\n\n // add new trials to end of this timeline\n insert(parameters) {\n if (typeof this.timeline_parameters === \"undefined\") {\n console.error(\"Cannot add new trials to a trial-level node.\");\n } else {\n this.timeline_parameters.timeline.push(\n new TimelineNode(\n this.jsPsych,\n { ...this.node_trial_data, ...parameters },\n this,\n this.timeline_parameters.timeline.length\n )\n );\n }\n }\n}\n","import autoBind from \"auto-bind\";\n\nimport { version } from \"../package.json\";\nimport { MigrationError } from \"./migration\";\nimport { JsPsychData } from \"./modules/data\";\nimport { PluginAPI, createJointPluginAPIObject } from \"./modules/plugin-api\";\nimport { ParameterType, universalPluginParameters } from \"./modules/plugins\";\nimport * as randomization from \"./modules/randomization\";\nimport * as turk from \"./modules/turk\";\nimport * as utils from \"./modules/utils\";\nimport { TimelineNode } from \"./TimelineNode\";\n\nfunction delay(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport class JsPsych {\n extensions = <any>{};\n turk = turk;\n randomization = randomization;\n utils = utils;\n data: JsPsychData;\n pluginAPI: PluginAPI;\n\n version() {\n return version;\n }\n\n //\n // private variables\n //\n\n /**\n * options\n */\n private opts: any = {};\n\n /**\n * experiment timeline\n */\n private timeline: TimelineNode;\n private timelineDescription: any[];\n\n // flow control\n private global_trial_index = 0;\n private current_trial: any = {};\n private current_trial_finished = false;\n\n // target DOM element\n private DOM_container: HTMLElement;\n private DOM_target: HTMLElement;\n\n /**\n * time that the experiment began\n */\n private exp_start_time;\n\n /**\n * is the experiment paused?\n */\n private paused = false;\n private waiting = false;\n\n /**\n * is the page retrieved directly via file:// protocol (true) or hosted on a server (false)?\n */\n private file_protocol = false;\n\n /**\n * Promise that is resolved when `finishExperiment()` is called\n */\n private finished: Promise<void>;\n private resolveFinishedPromise: () => void;\n\n /**\n * is the experiment running in `simulate()` mode\n */\n private simulation_mode: \"data-only\" | \"visual\" = null;\n\n /**\n * simulation options passed in via `simulate()`\n */\n private simulation_options;\n\n // storing a single webaudio context to prevent problems with multiple inits\n // of jsPsych\n webaudio_context: AudioContext = null;\n\n internal = {\n /**\n * this flag is used to determine whether we are in a scope where\n * jsPsych.timelineVariable() should be executed immediately or\n * whether it should return a function to access the variable later.\n *\n **/\n call_immediate: false,\n };\n\n constructor(options?) {\n // override default options if user specifies an option\n options = {\n display_element: undefined,\n on_finish: () => {},\n on_trial_start: () => {},\n on_trial_finish: () => {},\n on_data_update: () => {},\n on_interaction_data_update: () => {},\n on_close: () => {},\n use_webaudio: true,\n exclusions: {},\n show_progress_bar: false,\n message_progress_bar: \"Completion Progress\",\n auto_update_progress_bar: true,\n default_iti: 0,\n minimum_valid_rt: 0,\n experiment_width: null,\n override_safe_mode: false,\n case_sensitive_responses: false,\n extensions: [],\n ...options,\n };\n this.opts = options;\n\n autoBind(this); // so we can pass JsPsych methods as callbacks and `this` remains the JsPsych instance\n\n this.webaudio_context =\n typeof window !== \"undefined\" && typeof window.AudioContext !== \"undefined\"\n ? new AudioContext()\n : null;\n\n // detect whether page is running in browser as a local file, and if so, disable web audio and video preloading to prevent CORS issues\n if (\n window.location.protocol == \"file:\" &&\n (options.override_safe_mode === false || typeof options.override_safe_mode === \"undefined\")\n ) {\n options.use_webaudio = false;\n this.file_protocol = true;\n console.warn(\n \"jsPsych detected that it is running via the file:// protocol and not on a web server. \" +\n \"To prevent issues with cross-origin requests, Web Audio and video preloading have been disabled. \" +\n \"If you would like to override this setting, you can set 'override_safe_mode' to 'true' in initJsPsych. \" +\n \"For more information, see: https://www.jspsych.org/overview/running-experiments\"\n );\n }\n\n // initialize modules\n this.data = new JsPsychData(this);\n this.pluginAPI = createJointPluginAPIObject(this);\n\n // create instances of extensions\n for (const extension of options.extensions) {\n this.extensions[extension.type.info.name] = new extension.type(this);\n }\n\n // initialize audio context based on options and browser capabilities\n this.pluginAPI.initAudio();\n }\n\n /**\n * Starts an experiment using the provided timeline and returns a promise that is resolved when\n * the experiment is finished.\n *\n * @param timeline The timeline to be run\n */\n async run(timeline: any[]) {\n if (typeof timeline === \"undefined\") {\n console.error(\"No timeline declared in jsPsych.run. Cannot start experiment.\");\n }\n\n if (timeline.length === 0) {\n console.error(\n \"No trials have been added to the timeline (the timeline is an empty array). Cannot start experiment.\"\n );\n }\n\n // create experiment timeline\n this.timelineDescription = timeline;\n this.timeline = new TimelineNode(this, { timeline });\n\n await this.prepareDom();\n await this.checkExclusions(this.opts.exclusions);\n await this.loadExtensions(this.opts.extensions);\n\n document.documentElement.setAttribute(\"jspsych\", \"present\");\n\n this.startExperiment();\n await this.finished;\n }\n\n async simulate(\n timeline: any[],\n simulation_mode: \"data-only\" | \"visual\" = \"data-only\",\n simulation_options = {}\n ) {\n this.simulation_mode = simulation_mode;\n this.simulation_options = simulation_options;\n await this.run(timeline);\n }\n\n getProgress() {\n return {\n total_trials: typeof this.timeline === \"undefined\" ? undefined : this.timeline.length(),\n current_trial_global: this.global_trial_index,\n percent_complete: typeof this.timeline === \"undefined\" ? 0 : this.timeline.percentComplete(),\n };\n }\n\n getStartTime() {\n return this.exp_start_time;\n }\n\n getTotalTime() {\n if (typeof this.exp_start_time === \"undefined\") {\n return 0;\n }\n return new Date().getTime() - this.exp_start_time.getTime();\n }\n\n getDisplayElement() {\n return this.DOM_target;\n }\n\n getDisplayContainerElement() {\n return this.DOM_container;\n }\n\n finishTrial(data = {}) {\n if (this.current_trial_finished) {\n return;\n }\n this.current_trial_finished = true;\n\n // remove any CSS classes that were added to the DOM via css_classes parameter\n if (\n typeof this.current_trial.css_classes !== \"undefined\" &&\n Array.isArray(this.current_trial.css_classes)\n ) {\n this.DOM_target.classList.remove(...this.current_trial.css_classes);\n }\n\n // write the data from the trial\n this.data.write(data);\n\n // get back the data with all of the defaults in\n const trial_data = this.data.get().filter({ trial_index: this.global_trial_index });\n\n // for trial-level callbacks, we just want to pass in a reference to the values\n // of the DataCollection, for easy access and editing.\n const trial_data_values = trial_data.values()[0];\n\n const current_trial = this.current_trial;\n\n if (typeof current_trial.save_trial_parameters === \"object\") {\n for (const key of Object.keys(current_trial.save_trial_parameters)) {\n const key_val = current_trial.save_trial_parameters[key];\n if (key_val === true) {\n if (typeof current_trial[key] === \"undefined\") {\n console.warn(\n `Invalid parameter specified in save_trial_parameters. Trial has no property called \"${key}\".`\n );\n } else if (typeof current_trial[key] === \"function\") {\n trial_data_values[key] = current_trial[key].toString();\n } else {\n trial_data_values[key] = current_trial[key];\n }\n }\n if (key_val === false) {\n // we don't allow internal_node_id or trial_index to be deleted because it would break other things\n if (key !== \"internal_node_id\" && key !== \"trial_index\") {\n delete trial_data_values[key];\n }\n }\n }\n }\n // handle extension callbacks\n if (Array.isArray(current_trial.extensions)) {\n for (const extension of current_trial.extensions) {\n const ext_data_values = this.extensions[extension.type.info.name].on_finish(\n extension.params\n );\n Object.assign(trial_data_values, ext_data_values);\n }\n }\n\n // about to execute lots of callbacks, so switch context.\n this.internal.call_immediate = true;\n\n // handle callback at plugin level\n if (typeof current_trial.on_finish === \"function\") {\n current_trial.on_finish(trial_data_values);\n }\n\n // handle callback at whole-experiment level\n this.opts.on_trial_finish(trial_data_values);\n\n // after the above callbacks are complete, then the data should be finalized\n // for this trial. call the on_data_update handler, passing in the same\n // data object that just went through the trial's finish handlers.\n this.opts.on_data_update(trial_data_values);\n\n // done with callbacks\n this.internal.call_immediate = false;\n\n // wait for iti\n if (\n typeof current_trial.post_trial_gap === null ||\n typeof current_trial.post_trial_gap === \"undefined\"\n ) {\n if (this.opts.default_iti > 0) {\n setTimeout(this.nextTrial, this.opts.default_iti);\n } else {\n this.nextTrial();\n }\n } else {\n if (current_trial.post_trial_gap > 0) {\n setTimeout(this.nextTrial, current_trial.post_trial_gap);\n } else {\n this.nextTrial();\n }\n }\n }\n\n endExperiment(end_message = \"\", data = {}) {\n this.timeline.end_message = end_message;\n this.timeline.end();\n this.pluginAPI.cancelAllKeyboardResponses();\n this.pluginAPI.clearAllTimeouts();\n this.finishTrial(data);\n }\n\n endCurrentTimeline() {\n this.timeline.endActiveNode();\n }\n\n getCurrentTrial() {\n return this.current_trial;\n }\n\n getInitSettings() {\n return this.opts;\n }\n\n getCurrentTimelineNodeID() {\n return this.timeline.activeID();\n }\n\n timelineVariable(varname: string, immediate = false) {\n if (this.internal.call_immediate || immediate === true) {\n return this.timeline.timelineVariable(varname);\n } else {\n return {\n timelineVariablePlaceholder: true,\n timelineVariableFunction: () => this.timeline.timelineVariable(varname),\n };\n }\n }\n\n getAllTimelineVariables() {\n return this.timeline.allTimelineVariables();\n }\n\n addNodeToEndOfTimeline(new_timeline, preload_callback?) {\n this.timeline.insert(new_timeline);\n }\n\n pauseExperiment() {\n this.paused = true;\n }\n\n resumeExperiment() {\n this.paused = false;\n if (this.waiting) {\n this.waiting = false;\n this.nextTrial();\n }\n }\n\n loadFail(message) {\n message = message || \"<p>The experiment failed to load.</p>\";\n this.DOM_target.innerHTML = message;\n }\n\n getSafeModeStatus() {\n return this.file_protocol;\n }\n\n getTimeline() {\n return this.timelineDescription;\n }\n\n private async prepareDom() {\n // Wait until the document is ready\n if (document.readyState !== \"complete\") {\n await new Promise((resolve) => {\n window.addEventListener(\"load\", resolve);\n });\n }\n\n const options = this.opts;\n\n // set DOM element where jsPsych will render content\n // if undefined, then jsPsych will use the <body> tag and the entire page\n if (typeof options.display_element === \"undefined\") {\n // check if there is a body element on the page\n const body = document.querySelector(\"body\");\n if (body === null) {\n document.documentElement.appendChild(document.createElement(\"body\"));\n }\n // using the full page, so we need the HTML element to\n // have 100% height, and body to be full width and height with\n // no margin\n document.querySelector(\"html\").style.height = \"100%\";\n document.querySelector(\"body\").style.margin = \"0px\";\n document.querySelector(\"body\").style.height = \"100%\";\n document.querySelector(\"body\").style.width = \"100%\";\n options.display_element = document.querySelector(\"body\");\n } else {\n // make sure that the display element exists on the page\n const display =\n options.display_element instanceof Element\n ? options.display_element\n : document.querySelector(\"#\" + options.display_element);\n if (display === null) {\n console.error(\"The display_element specified in initJsPsych() does not exist in the DOM.\");\n } else {\n options.display_element = display;\n }\n }\n\n options.display_element.innerHTML =\n '<div class=\"jspsych-content-wrapper\"><div id=\"jspsych-content\"></div></div>';\n this.DOM_container = options.display_element;\n this.DOM_target = document.querySelector(\"#jspsych-content\");\n\n // set experiment_width if not null\n if (options.experiment_width !== null) {\n this.DOM_target.style.width = options.experiment_width + \"px\";\n }\n\n // add tabIndex attribute to scope event listeners\n options.display_element.tabIndex = 0;\n\n // add CSS class to DOM_target\n if (options.display_element.className.indexOf(\"jspsych-display-element\") === -1) {\n options.display_element.className += \" jspsych-display-element\";\n }\n this.DOM_target.className += \"jspsych-content\";\n\n // create listeners for user browser interaction\n this.data.createInteractionListeners();\n\n // add event for closing window\n window.addEventListener(\"beforeunload\", options.on_close);\n }\n\n private async loadExtensions(extensions) {\n // run the .initialize method of any extensions that are in use\n // these should return a Promise to indicate when loading is complete\n\n try {\n await Promise.all(\n extensions.map((extension) =>\n this.extensions[extension.type.info.name].initialize(extension.params || {})\n )\n );\n } catch (error_message) {\n console.error(error_message);\n throw new Error(error_message);\n }\n }\n\n private startExperiment() {\n this.finished = new Promise((resolve) => {\n this.resolveFinishedPromise = resolve;\n });\n\n // show progress bar if requested\n if (this.opts.show_progress_bar === true) {\n this.drawProgressBar(this.opts.message_progress_bar);\n }\n\n // record the start time\n this.exp_start_time = new Date();\n\n // begin!\n this.timeline.advance();\n this.doTrial(this.timeline.trial());\n }\n\n private finishExperiment() {\n const finish_result = this.opts.on_finish(this.data.get());\n\n const done_handler = () => {\n if (typeof this.timeline.end_message !== \"undefined\") {\n this.DOM_target.innerHTML = this.timeline.end_message;\n }\n this.resolveFinishedPromise();\n };\n\n if (finish_result) {\n Promise.resolve(finish_result).then(done_handler);\n } else {\n done_handler();\n }\n }\n\n private nextTrial() {\n // if experiment is paused, don't do anything.\n if (this.paused) {\n this.waiting = true;\n return;\n }\n\n this.global_trial_index++;\n\n // advance timeline\n this.timeline.markCurrentTrialComplete();\n const complete = this.timeline.advance();\n\n // update progress bar if shown\n if (this.opts.show_progress_bar === true && this.opts.auto_update_progress_bar === true) {\n this.updateProgressBar();\n }\n\n // check if experiment is over\n if (complete) {\n this.finishExperiment();\n return;\n }\n\n this.doTrial(this.timeline.trial());\n }\n\n private doTrial(trial) {\n this.current_trial = trial;\n this.current_trial_finished = false;\n\n // process all timeline variables for this trial\n this.evaluateTimelineVariables(trial);\n\n if (typeof trial.type === \"string\") {\n throw new MigrationError(\n \"A string was provided as the trial's `type` parameter. Since jsPsych v7, the `type` parameter needs to be a plugin object.\"\n );\n }\n\n // instantiate the plugin for this trial\n trial.type = {\n // this is a hack to internally keep the old plugin object structure and prevent touching more\n // of the core jspsych code\n ...autoBind(new trial.type(this)),\n info: trial.type.info,\n };\n\n // evaluate variables that are functions\n this.evaluateFunctionParameters(trial);\n\n // get default values for parameters\n this.setDefaultValues(trial);\n\n // about to execute callbacks\n this.internal.call_immediate = true;\n\n // call experiment wide callback\n this.opts.on_trial_start(trial);\n\n // call trial specific callback if it exists\n if (typeof trial.on_start === \"function\") {\n trial.on_start(trial);\n }\n\n // call any on_start functions for extensions\n if (Array.isArray(trial.extensions)) {\n for (const extension of trial.extensions) {\n this.extensions[extension.type.info.name].on_start(extension.params);\n }\n }\n\n // apply the focus to the element containing the experiment.\n this.DOM_container.focus();\n\n // reset the scroll on the DOM target\n this.DOM_target.scrollTop = 0;\n\n // add CSS classes to the DOM_target if they exist in trial.css_classes\n if (typeof trial.css_classes !== \"undefined\") {\n if (!Array.isArray(trial.css_classes) && typeof trial.css_classes === \"string\") {\n trial.css_classes = [trial.css_classes];\n }\n if (Array.isArray(trial.css_classes)) {\n this.DOM_target.classList.add(...trial.css_classes);\n }\n }\n\n // setup on_load event callback\n const load_callback = () => {\n if (typeof trial.on_load === \"function\") {\n trial.on_load();\n }\n\n // call any on_load functions for extensions\n if (Array.isArray(trial.extensions)) {\n for (const extension of trial.extensions) {\n this.extensions[extension.type.info.name].on_load(extension.params);\n }\n }\n };\n\n let trial_complete;\n if (!this.simulation_mode) {\n trial_complete = trial.type.trial(this.DOM_target, trial, load_callback);\n }\n if (this.simulation_mode) {\n // check if the trial supports simulation\n if (trial.type.simulate) {\n let trial_sim_opts;\n if (!trial.simulation_options) {\n trial_sim_opts = this.simulation_options.default;\n }\n if (trial.simulation_options) {\n if (typeof trial.simulation_options == \"string\") {\n if (this.simulation_options[trial.simulation_options]) {\n trial_sim_opts = this.simulation_options[trial.simulation_options];\n } else if (this.simulation_options.default) {\n console.log(\n `No matching simulation options found for \"${trial.simulation_options}\". Using \"default\" options.`\n );\n trial_sim_opts = this.simulation_options.default;\n } else {\n console.log(\n `No matching simulation options found for \"${trial.simulation_options}\" and no \"default\" options provided. Using the default values provided by the plugin.`\n );\n trial_sim_opts = {};\n }\n } else {\n trial_sim_opts = trial.simulation_options;\n }\n }\n trial_sim_opts = this.utils.deepCopy(trial_sim_opts);\n trial_sim_opts = this.replaceFunctionsWithValues(trial_sim_opts, null);\n\n if (trial_sim_opts?.simulate === false) {\n trial_complete = trial.type.trial(this.DOM_target, trial, load_callback);\n } else {\n trial_complete = trial.type.simulate(\n trial,\n trial_sim_opts?.mode || this.simulation_mode,\n trial_sim_opts,\n load_callback\n );\n }\n } else {\n // trial doesn't have a simulate method, so just run as usual\n trial_complete = trial.type.trial(this.DOM_target, trial, load_callback);\n }\n }\n\n // see if trial_complete is a Promise by looking for .then() function\n const is_promise = trial_complete && typeof trial_complete.then == \"function\";\n\n // in simulation mode we let the simulate function call the load_callback always.\n if (!is_promise && !this.simulation_mode) {\n load_callback();\n }\n\n // done with callbacks\n this.internal.call_immediate = false;\n }\n\n private evaluateTimelineVariables(trial) {\n for (const key of Object.keys(trial)) {\n if (key === \"type\") {\n // skip the `type` parameter as it contains a plugin\n //continue;\n }\n // timeline variables on the root level\n if (\n typeof trial[key] === \"object\" &&\n trial[key] !== null &&\n typeof trial[key].timelineVariablePlaceholder !== \"undefined\"\n ) {\n /*trial[key].toString().replace(/\\s/g, \"\") ==\n \"function(){returntimeline.timelineVariable(varname);}\"\n )*/ trial[key] = trial[key].timelineVariableFunction();\n }\n // timeline variables that are nested in objects\n if (typeof trial[key] === \"object\" && trial[key] !== null) {\n this.evaluateTimelineVariables(trial[key]);\n }\n }\n }\n\n private evaluateFunctionParameters(trial) {\n // set a flag so that jsPsych.timelineVariable() is immediately executed in this context\n this.internal.call_immediate = true;\n\n // iterate over each parameter\n for (const key of Object.keys(trial)) {\n // check to make sure parameter is not \"type\", since that was eval'd above.\n if (key !== \"type\") {\n // this if statement is checking to see if the parameter type is expected to be a function, in which case we should NOT evaluate it.\n // the first line checks if the parameter is defined in the universalPluginParameters set\n // the second line checks the plugin-specific parameters\n if (\n typeof universalPluginParameters[key] !== \"undefined\" &&\n universalPluginParameters[key].type !== ParameterType.FUNCTION\n ) {\n trial[key] = this.replaceFunctionsWithValues(trial[key], null);\n }\n if (\n typeof trial.type.info.parameters[key] !== \"undefined\" &&\n trial.type.info.parameters[key].type !== ParameterType.FUNCTION\n ) {\n trial[key] = this.replaceFunctionsWithValues(trial[key], trial.type.info.parameters[key]);\n }\n }\n }\n // reset so jsPsych.timelineVariable() is no longer immediately executed\n this.internal.call_immediate = false;\n }\n\n private replaceFunctionsWithValues(obj, info) {\n // null typeof is 'object' (?!?!), so need to run this first!\n if (obj === null) {\n return obj;\n }\n // arrays\n else if (Array.isArray(obj)) {\n for (let i = 0; i < obj.length; i++) {\n obj[i] = this.replaceFunctionsWithValues(obj[i], info);\n }\n }\n // objects\n else if (typeof obj === \"object\") {\n if (info === null || !info.nested) {\n for (const key of Object.keys(obj)) {\n if (key === \"type\") {\n // Ignore the object's `type` field because it contains a plugin and we do not want to\n // call plugin functions\n continue;\n }\n obj[key] = this.replaceFunctionsWithValues(obj[key], null);\n }\n } else {\n for (const key of Object.keys(obj)) {\n if (\n typeof info.nested[key] === \"object\" &&\n info.nested[key].type !== ParameterType.FUNCTION\n ) {\n obj[key] = this.replaceFunctionsWithValues(obj[key], info.nested[key]);\n }\n }\n }\n } else if (typeof obj === \"function\") {\n return obj();\n }\n return obj;\n }\n\n private setDefaultValues(trial) {\n for (const param in trial.type.info.parameters) {\n // check if parameter is complex with nested defaults\n if (trial.type.info.parameters[param].type === ParameterType.COMPLEX) {\n if (trial.type.info.parameters[param].array === true) {\n // iterate over each entry in the array\n trial[param].forEach(function (ip, i) {\n // check each parameter in the plugin description\n for (const p in trial.type.info.parameters[param].nested) {\n if (typeof trial[param][i][p] === \"undefined\" || trial[param][i][p] === null) {\n if (typeof trial.type.info.parameters[param].nested[p].default === \"undefined\") {\n console.error(\n \"You must specify a value for the \" +\n p +\n \" parameter (nested in the \" +\n param +\n \" parameter) in the \" +\n trial.type +\n \" plugin.\"\n );\n } else {\n trial[param][i][p] = trial.type.info.parameters[param].nested[p].default;\n }\n }\n }\n });\n }\n }\n // if it's not nested, checking is much easier and do that here:\n else if (typeof trial[param] === \"undefined\" || trial[param] === null) {\n if (typeof trial.type.info.parameters[param].default === \"undefined\") {\n console.error(\n \"You must specify a value for the \" +\n param +\n \" parameter in the \" +\n trial.type.info.name +\n \" plugin.\"\n );\n } else {\n trial[param] = trial.type.info.parameters[param].default;\n }\n }\n }\n }\n\n private async checkExclusions(exclusions) {\n if (exclusions.min_width || exclusions.min_height || exclusions.audio) {\n console.warn(\n \"The exclusions option in `initJsPsych()` is deprecated and will be removed in a future version. We recommend using the browser-check plugin instead. See https://www.jspsych.org/latest/plugins/browser-check/.\"\n );\n }\n // MINIMUM SIZE\n if (exclusions.min_width || exclusions.min_height) {\n const mw = exclusions.min_width || 0;\n const mh = exclusions.min_height || 0;\n\n if (window.innerWidth < mw || window.innerHeight < mh) {\n this.getDisplayElement().innerHTML =\n \"<p>Your browser window is too small to complete this experiment. \" +\n \"Please maximize the size of your browser window. If your browser window is already maximized, \" +\n \"you will not be able to complete this experiment.</p>\" +\n \"<p>The minimum width is \" +\n mw +\n \"px. Your current width is \" +\n window.innerWidth +\n \"px.</p>\" +\n \"<p>The minimum height is \" +\n mh +\n \"px. Your current height is \" +\n window.innerHeight +\n \"px.</p>\";\n\n // Wait for window size to increase\n while (window.innerWidth < mw || window.innerHeight < mh) {\n await delay(100);\n }\n\n this.getDisplayElement().innerHTML = \"\";\n }\n }\n\n // WEB AUDIO API\n if (typeof exclusions.audio !== \"undefined\" && exclusions.audio) {\n if (!window.hasOwnProperty(\"AudioContext\") && !window.hasOwnProperty(\"webkitAudioContext\")) {\n this.getDisplayElement().innerHTML =\n \"<p>Your browser does not support the WebAudio API, which means that you will not \" +\n \"be able to complete the experiment.</p><p>Browsers that support the WebAudio API include \" +\n \"Chrome, Firefox, Safari, and Edge.</p>\";\n throw new Error();\n }\n }\n }\n\n private drawProgressBar(msg) {\n document\n .querySelector(\".jspsych-display-element\")\n .insertAdjacentHTML(\n \"afterbegin\",\n '<div id=\"jspsych-progressbar-container\">' +\n \"<span>\" +\n msg +\n \"</span>\" +\n '<div id=\"jspsych-progressbar-outer\">' +\n '<div id=\"jspsych-progressbar-inner\"></div>' +\n \"</div></div>\"\n );\n }\n\n private updateProgressBar() {\n this.setProgressBar(this.getProgress().percent_complete / 100);\n }\n\n private progress_bar_amount = 0;\n\n setProgressBar(proportion_complete) {\n proportion_complete = Math.max(Math.min(1, proportion_complete), 0);\n document.querySelector<HTMLElement>(\"#jspsych-progressbar-inner\").style.width =\n proportion_complete * 100 + \"%\";\n this.progress_bar_amount = proportion_complete;\n }\n\n getProgressBarCompleted() {\n return this.progress_bar_amount;\n }\n}\n","import autoBind from \"auto-bind\";\n\nimport { JsPsych } from \"../../JsPsych\";\nimport { HardwareAPI } from \"./HardwareAPI\";\nimport { KeyboardListenerAPI } from \"./KeyboardListenerAPI\";\nimport { MediaAPI } from \"./MediaAPI\";\nimport { SimulationAPI } from \"./SimulationAPI\";\nimport { TimeoutAPI } from \"./TimeoutAPI\";\n\nexport function createJointPluginAPIObject(jsPsych: JsPsych) {\n const settings = jsPsych.getInitSettings();\n return Object.assign(\n {},\n ...[\n new KeyboardListenerAPI(\n jsPsych.getDisplayContainerElement,\n settings.case_sensitive_responses,\n settings.minimum_valid_rt\n ),\n new TimeoutAPI(),\n new MediaAPI(settings.use_webaudio, jsPsych.webaudio_context),\n new HardwareAPI(),\n new SimulationAPI(),\n ].map((object) => autoBind(object))\n ) as KeyboardListenerAPI & TimeoutAPI & MediaAPI & HardwareAPI & SimulationAPI;\n}\n\nexport type PluginAPI = ReturnType<typeof createJointPluginAPIObject>;\n","import { JsPsych } from \"./JsPsych\";\nimport { MigrationError } from \"./migration\";\n\n// temporary patch for Safari\nif (\n typeof window !== \"undefined\" &&\n window.hasOwnProperty(\"webkitAudioContext\") &&\n !window.hasOwnProperty(\"AudioContext\")\n) {\n // @ts-expect-error\n window.AudioContext = webkitAudioContext;\n}\n// end patch\n\n// The following function provides a uniform interface to initialize jsPsych, no matter whether a\n// browser supports ES6 classes or not (and whether the ES6 build or the Babel build is used).\n/**\n * Creates a new JsPsych instance using the provided options.\n *\n * @param options The options to pass to the JsPsych constructor\n * @returns A new JsPsych instance\n */\nexport function initJsPsych(options?) {\n const jsPsych = new JsPsych(options);\n\n // Handle invocations of non-existent v6 methods with migration errors\n const migrationMessages = {\n init: \"`jsPsych.init()` was replaced by `initJsPsych()` in jsPsych v7.\",\n\n ALL_KEYS: 'jsPsych.ALL_KEYS was replaced by the \"ALL_KEYS\" string in jsPsych v7.',\n NO_KEYS: 'jsPsych.NO_KEYS was replaced by the \"NO_KEYS\" string in jsPsych v7.',\n\n // Getter functions that were renamed\n currentTimelineNodeID:\n \"`currentTimelineNodeID()` was renamed to `getCurrentTimelineNodeID()` in jsPsych v7.\",\n progress: \"`progress()` was renamed to `getProgress()` in jsPsych v7.\",\n startTime: \"`startTime()` was renamed to `getStartTime()` in jsPsych v7.\",\n totalTime: \"`totalTime()` was renamed to `getTotalTime()` in jsPsych v7.\",\n currentTrial: \"`currentTrial()` was renamed to `getCurrentTrial()` in jsPsych v7.\",\n initSettings: \"`initSettings()` was renamed to `getInitSettings()` in jsPsych v7.\",\n allTimelineVariables:\n \"`allTimelineVariables()` was renamed to `getAllTimelineVariables()` in jsPsych v7.\",\n };\n\n Object.defineProperties(\n jsPsych,\n Object.fromEntries(\n Object.entries(migrationMessages).map(([key, message]) => [\n key,\n {\n get() {\n throw new MigrationError(message);\n },\n },\n ])\n )\n );\n\n return jsPsych;\n}\n\nexport { JsPsych } from \"./JsPsych\";\nexport {\n JsPsychPlugin,\n PluginInfo,\n TrialType,\n ParameterType,\n universalPluginParameters,\n UniversalPluginParameters,\n} from \"./modules/plugins\";\nexport { JsPsychExtension, JsPsychExtensionInfo } from \"./modules/extensions\";\n"],"names":["__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","value","step","next","e","rejected","result","done","then","apply","getAllProperties","object","properties","Set","Reflect","ownKeys","key","add","getPrototypeOf","Object","prototype","autoBind","self","include","exclude","filter","match","pattern","test","some","constructor","descriptor","getOwnPropertyDescriptor","bind","MigrationError","Error","message","super","this","name","unique","arr","deepCopy","obj","out","Array","isArray","x","push","hasOwnProperty","window","jsPsych","init","data","randomization","turk","pluginAPI","ALL_KEYS","NO_KEYS","ParameterType","DataColumn","values","sum","s","v","mean","count","median","length","numbers","slice","sort","a","b","middle","Math","floor","min","max","variance","sum_square_error","pow","sd","mse","sqrt","frequencies","all","eval_fn","subset","DataCollection","trials","new_data","join","other_data_collection","concat","top","first","n","last","readOnly","addToAll","trial","assign","addToLast","filters","f","filtered_data","keep","keys","filterCustom","fn","select","column","ignore","columns","o","delete_key","uniqueNames","names","includes","csv","objArray","array","JSON","parse","line","row","keyString","replace","col","stringify","JSON2CSV","json","pretty","localSave","format","filename","data_string","toLowerCase","textstr","blobToSave","Blob","type","blobURL","webkitURL","createObjectURL","URL","link","document","createElement","id","style","display","download","href","click","saveTextToFile","JsPsychData","reset","allData","interactionData","get","getInteractionData","write","data_object","progress","getProgress","getCurrentTrial","default_data","trial_type","info","trial_index","current_trial_global","time_elapsed","getTotalTime","internal_node_id","getCurrentTimelineNodeID","dataProperties","addProperties","addDataToLastTrial","getDataByTimelineNode","node_id","getLastTrialData","getLastTimelineData","parent_node_id","substr","lastIndexOf","displayData","console","log","getDisplayElement","innerHTML","getElementById","textContent","urlVariables","query_string","location","search","split","i","p","decodeURIComponent","getQueryString","getURLVariable","whichvar","createInteractionListeners","addEventListener","event","time","getInitSettings","on_interaction_data_update","fullscreenchange","isFullScreen","webkitIsFullScreen","mozIsFullScreen","fullscreenElement","_customInsert","_fullreset","HardwareAPI","evt","hardwareConnected","hardware","mess","jspsychEvt","CustomEvent","detail","dispatchEvent","KeyboardListenerAPI","getRootElement","areResponsesCaseSensitive","minimumValidRt","registerRootListeners","areRootListenersRegistered","rootElement","rootKeydownListener","rootKeyupListener","listener","from","listeners","heldKeys","toLowerCaseIfInsensitive","string","delete","isResponseValid","validResponses","allowHeldKey","has","getKeyboardResponse","callback_function","valid_responses","rt_method","persist","audio_context","audio_context_start_time","allow_held_key","minimum_valid_rt","startTime","performance","now","map","r","rt","round","currentTime","preventDefault","cancelKeyboardResponse","cancelAllKeyboardResponses","clear","compareKeys","key1","key2","error","universalPluginParameters","OBJECT","pretty_name","default","on_start","FUNCTION","on_finish","on_load","post_trial_gap","INT","css_classes","STRING","simulation_options","COMPLEX","preloadParameterTypes","AUDIO","IMAGE","VIDEO","MediaAPI","useWebaudio","webaudioContext","Map","getVideoBuffer","videoID","video_buffers","initAudio","context","audioContext","state","resume","getAudioBuffer","audioID","audio_buffers","preloadAudio","files","callback_complete","callback_load","filepath","callback_error","error_msg","flat","n_loaded","load_audio_file_webaudio","source","request","XMLHttpRequest","open","responseType","onload","decodeAudioData","response","buffer","onerror","err","status","onloadend","send","preload_requests","load_audio_file_html5audio","audio","Audio","handleCanPlayThrough","removeEventListener","handleError","src","handleAbort","file","preloadImages","images","img","Image","img_cache","preloadVideo","videos","video","videoBlob","getAutoPreloadList","timeline_description","preloadPaths","fromEntries","traverseTimeline","node","inheritedTrialType","timeline","childNode","pluginName","parameters","preloadMap","set","entries","_name","preload","parameterName","parameterType","parameterValue","elements","element","cancelPreloads","oncanplaythrough","onabort","initializeMicrophoneRecorder","stream","recorder","MediaRecorder","microphone_recorder","getMicrophoneRecorder","SimulationAPI","body","keyDown","KeyboardEvent","keyUp","pressKey","delay","setTimeout","clickTarget","target","MouseEvent","bubbles","fillTextInput","text","getValidKey","choices","possible_keys","random","flat_choices","mergeSimulationData","ensureSimulationDataConsistency","trial_duration","correct","allow_response_before_complete","sequence_reps","frame_time","min_time","stimuli","TimeoutAPI","callback","handle","timeout_handlers","clearAllTimeouts","handler","clearTimeout","wordList","words","options","word","maxLength","wordUsed","rightSize","generateRandomWord","generateWordWithMaxLength","randInt","lessThan","exactly","wordsPerString","formatter","separator","total","results","token","relativeIndex","randomWords","repeat","repetitions","unpack","arr_isArray","rep_isArray","warn","reps","allsamples","j","shuffle","unpackArray","copy_array","t","m","shuffleAlternateGroups","arr_groups","random_group_order","n_groups","group_order","randomized_groups","min_length","sampleWithoutReplacement","size","sampleWithReplacement","weights","normalized_weights","weight_sum","weight","cumulative_weights","samp","rnd","index","sampleNormal","standard_deviation","u","cos","PI","randn_bm","sampleExponential","rate","equalityTest","random_shuffle","random_pick","new_neighbor","factors","design","factorName","factor","new_design","level","cell","chars","lower","upper","positive","opts","rw","turkInfo","previewMode","outsideTurk","hitId","assignmentId","workerId","turkSubmitTo","param","url","RegExp","exec","referrer","unescape","form","method","action","hiddenField","appendChild","submit","TimelineNode","parent","relativeID","current_location","current_variable_set","current_repetition","current_iteration","parent_node","relative_id","timeline_parameters","loop_function","conditional_function","sample","randomize_order","timeline_variables","on_timeline_finish","on_timeline_start","setTimelineVariablesOrder","node_data","node_trial_data","merged_parameters","merged_data","trial_parameters","markCurrentTrialComplete","nextRepetiton","order","groups","randomize_group_order","nextSet","advance","internal","call_immediate","conditional_result","have_node_to_run","generatedData","isComplete","getTimelineVariableValue","variable_name","findTimelineVariable","timelineVariable","loc","allTimelineVariables","all_tvs","allTimelineVariablesNames","all_tvs_vals","so_far","percentComplete","total_trials","completed_trials","end","endActiveNode","ID","activeID","trialsOfType","insert","ms","JsPsych","utils","display_element","undefined","on_trial_start","on_trial_finish","on_data_update","on_close","use_webaudio","exclusions","show_progress_bar","message_progress_bar","auto_update_progress_bar","default_iti","experiment_width","override_safe_mode","case_sensitive_responses","extensions","webaudio_context","AudioContext","protocol","file_protocol","settings","getDisplayContainerElement","createJointPluginAPIObject","extension","version","run","timelineDescription","prepareDom","checkExclusions","loadExtensions","documentElement","setAttribute","startExperiment","finished","simulate","simulation_mode","global_trial_index","percent_complete","getStartTime","exp_start_time","Date","getTime","DOM_target","DOM_container","finishTrial","current_trial_finished","current_trial","classList","remove","trial_data_values","save_trial_parameters","key_val","toString","ext_data_values","params","nextTrial","endExperiment","end_message","endCurrentTimeline","varname","immediate","timelineVariablePlaceholder","timelineVariableFunction","getAllTimelineVariables","addNodeToEndOfTimeline","new_timeline","preload_callback","pauseExperiment","paused","resumeExperiment","waiting","loadFail","getSafeModeStatus","getTimeline","readyState","querySelector","height","margin","width","Element","tabIndex","className","indexOf","initialize","error_message","resolveFinishedPromise","drawProgressBar","doTrial","finishExperiment","finish_result","done_handler","complete","updateProgressBar","evaluateTimelineVariables","evaluateFunctionParameters","setDefaultValues","focus","scrollTop","load_callback","trial_complete","trial_sim_opts","replaceFunctionsWithValues","mode","nested","forEach","ip","min_width","min_height","mw","mh","innerWidth","innerHeight","msg","insertAdjacentHTML","setProgressBar","proportion_complete","progress_bar_amount","getProgressBarCompleted","webkitAudioContext","defineProperties","currentTimelineNodeID","totalTime","currentTrial","initSettings"],"mappings":"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"}