jspsych 7.2.1 → 7.3.0
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.
- package/dist/index.browser.js +192 -152
- package/dist/index.browser.js.map +1 -1
- package/dist/index.browser.min.js +1 -1
- package/dist/index.browser.min.js.map +1 -1
- package/dist/index.cjs +192 -152
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +192 -152
- package/dist/index.js.map +1 -1
- package/dist/modules/extensions.d.ts +1 -1
- package/dist/modules/plugin-api/MediaAPI.d.ts +6 -1
- package/package.json +2 -2
- package/src/JsPsych.ts +66 -48
- package/src/TimelineNode.ts +10 -2
- package/src/index.ts +2 -0
- package/src/modules/extensions.ts +1 -1
- package/src/modules/plugin-api/MediaAPI.ts +21 -1
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
/******************************************************************************
|
|
6
6
|
Copyright (c) Microsoft Corporation.
|
|
7
7
|
|
|
8
8
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
@@ -71,7 +71,7 @@ var autoBind = (self, {include, exclude} = {}) => {
|
|
|
71
71
|
return self;
|
|
72
72
|
};
|
|
73
73
|
|
|
74
|
-
var version = "7.
|
|
74
|
+
var version = "7.3.0";
|
|
75
75
|
|
|
76
76
|
class MigrationError extends Error {
|
|
77
77
|
constructor(message = "The global `jsPsych` variable is no longer available in jsPsych v7.") {
|
|
@@ -843,8 +843,13 @@ class MediaAPI {
|
|
|
843
843
|
this.img_cache = {};
|
|
844
844
|
this.preloadMap = new Map();
|
|
845
845
|
this.microphone_recorder = null;
|
|
846
|
+
this.camera_stream = null;
|
|
847
|
+
this.camera_recorder = null;
|
|
846
848
|
}
|
|
847
849
|
getVideoBuffer(videoID) {
|
|
850
|
+
if (videoID.startsWith("blob:")) {
|
|
851
|
+
this.video_buffers[videoID] = videoID;
|
|
852
|
+
}
|
|
848
853
|
return this.video_buffers[videoID];
|
|
849
854
|
}
|
|
850
855
|
initAudio() {
|
|
@@ -1086,6 +1091,17 @@ class MediaAPI {
|
|
|
1086
1091
|
getMicrophoneRecorder() {
|
|
1087
1092
|
return this.microphone_recorder;
|
|
1088
1093
|
}
|
|
1094
|
+
initializeCameraRecorder(stream, opts) {
|
|
1095
|
+
this.camera_stream = stream;
|
|
1096
|
+
const recorder = new MediaRecorder(stream, opts);
|
|
1097
|
+
this.camera_recorder = recorder;
|
|
1098
|
+
}
|
|
1099
|
+
getCameraStream() {
|
|
1100
|
+
return this.camera_stream;
|
|
1101
|
+
}
|
|
1102
|
+
getCameraRecorder() {
|
|
1103
|
+
return this.camera_recorder;
|
|
1104
|
+
}
|
|
1089
1105
|
}
|
|
1090
1106
|
|
|
1091
1107
|
class SimulationAPI {
|
|
@@ -1631,119 +1647,119 @@ words.wordList = wordList;
|
|
|
1631
1647
|
var alea = {exports: {}};
|
|
1632
1648
|
|
|
1633
1649
|
(function (module) {
|
|
1634
|
-
// A port of an algorithm by Johannes Baagøe <baagoe@baagoe.com>, 2010
|
|
1635
|
-
// http://baagoe.com/en/RandomMusings/javascript/
|
|
1636
|
-
// https://github.com/nquinlan/better-random-numbers-for-javascript-mirror
|
|
1637
|
-
// Original work is under MIT license -
|
|
1638
|
-
|
|
1639
|
-
// Copyright (C) 2010 by Johannes Baagøe <baagoe@baagoe.org>
|
|
1640
|
-
//
|
|
1641
|
-
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
1642
|
-
// of this software and associated documentation files (the "Software"), to deal
|
|
1643
|
-
// in the Software without restriction, including without limitation the rights
|
|
1644
|
-
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
1645
|
-
// copies of the Software, and to permit persons to whom the Software is
|
|
1646
|
-
// furnished to do so, subject to the following conditions:
|
|
1647
|
-
//
|
|
1648
|
-
// The above copyright notice and this permission notice shall be included in
|
|
1649
|
-
// all copies or substantial portions of the Software.
|
|
1650
|
-
//
|
|
1651
|
-
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
1652
|
-
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
1653
|
-
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
1654
|
-
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
1655
|
-
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
1656
|
-
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
1657
|
-
// THE SOFTWARE.
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
(function(global, module, define) {
|
|
1662
|
-
|
|
1663
|
-
function Alea(seed) {
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
}
|
|
1686
|
-
|
|
1687
|
-
function copy(f, t) {
|
|
1688
|
-
t.c = f.c;
|
|
1689
|
-
t.s0 = f.s0;
|
|
1690
|
-
t.s1 = f.s1;
|
|
1691
|
-
t.s2 = f.s2;
|
|
1692
|
-
return t;
|
|
1693
|
-
}
|
|
1650
|
+
// A port of an algorithm by Johannes Baagøe <baagoe@baagoe.com>, 2010
|
|
1651
|
+
// http://baagoe.com/en/RandomMusings/javascript/
|
|
1652
|
+
// https://github.com/nquinlan/better-random-numbers-for-javascript-mirror
|
|
1653
|
+
// Original work is under MIT license -
|
|
1654
|
+
|
|
1655
|
+
// Copyright (C) 2010 by Johannes Baagøe <baagoe@baagoe.org>
|
|
1656
|
+
//
|
|
1657
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
1658
|
+
// of this software and associated documentation files (the "Software"), to deal
|
|
1659
|
+
// in the Software without restriction, including without limitation the rights
|
|
1660
|
+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
1661
|
+
// copies of the Software, and to permit persons to whom the Software is
|
|
1662
|
+
// furnished to do so, subject to the following conditions:
|
|
1663
|
+
//
|
|
1664
|
+
// The above copyright notice and this permission notice shall be included in
|
|
1665
|
+
// all copies or substantial portions of the Software.
|
|
1666
|
+
//
|
|
1667
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
1668
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
1669
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
1670
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
1671
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
1672
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
1673
|
+
// THE SOFTWARE.
|
|
1674
|
+
|
|
1675
|
+
|
|
1676
|
+
|
|
1677
|
+
(function(global, module, define) {
|
|
1678
|
+
|
|
1679
|
+
function Alea(seed) {
|
|
1680
|
+
var me = this, mash = Mash();
|
|
1681
|
+
|
|
1682
|
+
me.next = function() {
|
|
1683
|
+
var t = 2091639 * me.s0 + me.c * 2.3283064365386963e-10; // 2^-32
|
|
1684
|
+
me.s0 = me.s1;
|
|
1685
|
+
me.s1 = me.s2;
|
|
1686
|
+
return me.s2 = t - (me.c = t | 0);
|
|
1687
|
+
};
|
|
1688
|
+
|
|
1689
|
+
// Apply the seeding algorithm from Baagoe.
|
|
1690
|
+
me.c = 1;
|
|
1691
|
+
me.s0 = mash(' ');
|
|
1692
|
+
me.s1 = mash(' ');
|
|
1693
|
+
me.s2 = mash(' ');
|
|
1694
|
+
me.s0 -= mash(seed);
|
|
1695
|
+
if (me.s0 < 0) { me.s0 += 1; }
|
|
1696
|
+
me.s1 -= mash(seed);
|
|
1697
|
+
if (me.s1 < 0) { me.s1 += 1; }
|
|
1698
|
+
me.s2 -= mash(seed);
|
|
1699
|
+
if (me.s2 < 0) { me.s2 += 1; }
|
|
1700
|
+
mash = null;
|
|
1701
|
+
}
|
|
1694
1702
|
|
|
1695
|
-
function
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
};
|
|
1703
|
-
prng.quick = prng;
|
|
1704
|
-
if (state) {
|
|
1705
|
-
if (typeof(state) == 'object') copy(state, xg);
|
|
1706
|
-
prng.state = function() { return copy(xg, {}); };
|
|
1707
|
-
}
|
|
1708
|
-
return prng;
|
|
1709
|
-
}
|
|
1703
|
+
function copy(f, t) {
|
|
1704
|
+
t.c = f.c;
|
|
1705
|
+
t.s0 = f.s0;
|
|
1706
|
+
t.s1 = f.s1;
|
|
1707
|
+
t.s2 = f.s2;
|
|
1708
|
+
return t;
|
|
1709
|
+
}
|
|
1710
1710
|
|
|
1711
|
-
function
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
|
|
1727
|
-
};
|
|
1711
|
+
function impl(seed, opts) {
|
|
1712
|
+
var xg = new Alea(seed),
|
|
1713
|
+
state = opts && opts.state,
|
|
1714
|
+
prng = xg.next;
|
|
1715
|
+
prng.int32 = function() { return (xg.next() * 0x100000000) | 0; };
|
|
1716
|
+
prng.double = function() {
|
|
1717
|
+
return prng() + (prng() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53
|
|
1718
|
+
};
|
|
1719
|
+
prng.quick = prng;
|
|
1720
|
+
if (state) {
|
|
1721
|
+
if (typeof(state) == 'object') copy(state, xg);
|
|
1722
|
+
prng.state = function() { return copy(xg, {}); };
|
|
1723
|
+
}
|
|
1724
|
+
return prng;
|
|
1725
|
+
}
|
|
1728
1726
|
|
|
1729
|
-
|
|
1730
|
-
|
|
1727
|
+
function Mash() {
|
|
1728
|
+
var n = 0xefc8249d;
|
|
1729
|
+
|
|
1730
|
+
var mash = function(data) {
|
|
1731
|
+
data = String(data);
|
|
1732
|
+
for (var i = 0; i < data.length; i++) {
|
|
1733
|
+
n += data.charCodeAt(i);
|
|
1734
|
+
var h = 0.02519603282416938 * n;
|
|
1735
|
+
n = h >>> 0;
|
|
1736
|
+
h -= n;
|
|
1737
|
+
h *= n;
|
|
1738
|
+
n = h >>> 0;
|
|
1739
|
+
h -= n;
|
|
1740
|
+
n += h * 0x100000000; // 2^32
|
|
1741
|
+
}
|
|
1742
|
+
return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
|
|
1743
|
+
};
|
|
1744
|
+
|
|
1745
|
+
return mash;
|
|
1746
|
+
}
|
|
1731
1747
|
|
|
1732
1748
|
|
|
1733
|
-
if (module && module.exports) {
|
|
1734
|
-
|
|
1735
|
-
} else if (define && define.amd) {
|
|
1736
|
-
|
|
1737
|
-
} else {
|
|
1738
|
-
|
|
1739
|
-
}
|
|
1749
|
+
if (module && module.exports) {
|
|
1750
|
+
module.exports = impl;
|
|
1751
|
+
} else if (define && define.amd) {
|
|
1752
|
+
define(function() { return impl; });
|
|
1753
|
+
} else {
|
|
1754
|
+
this.alea = impl;
|
|
1755
|
+
}
|
|
1740
1756
|
|
|
1741
|
-
})(
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
);
|
|
1746
|
-
}(alea));
|
|
1757
|
+
})(
|
|
1758
|
+
commonjsGlobal,
|
|
1759
|
+
module, // present in node.js
|
|
1760
|
+
(typeof undefined) == 'function' // present with an AMD loader
|
|
1761
|
+
);
|
|
1762
|
+
} (alea));
|
|
1747
1763
|
|
|
1748
1764
|
var seedrandom = alea.exports;
|
|
1749
1765
|
|
|
@@ -2410,7 +2426,11 @@ class TimelineNode {
|
|
|
2410
2426
|
// recursive downward search for active trial to extract timeline variable
|
|
2411
2427
|
timelineVariable(variable_name) {
|
|
2412
2428
|
if (typeof this.timeline_parameters == "undefined") {
|
|
2413
|
-
|
|
2429
|
+
const val = this.findTimelineVariable(variable_name);
|
|
2430
|
+
if (typeof val === "undefined") {
|
|
2431
|
+
console.warn("Timeline variable " + variable_name + " not found.");
|
|
2432
|
+
}
|
|
2433
|
+
return val;
|
|
2414
2434
|
}
|
|
2415
2435
|
else {
|
|
2416
2436
|
// if progress.current_location is -1, then the timeline variable is being evaluated
|
|
@@ -2425,7 +2445,11 @@ class TimelineNode {
|
|
|
2425
2445
|
loc = loc - 1;
|
|
2426
2446
|
}
|
|
2427
2447
|
// now find the variable
|
|
2428
|
-
|
|
2448
|
+
const val = this.timeline_parameters.timeline[loc].timelineVariable(variable_name);
|
|
2449
|
+
if (typeof val === "undefined") {
|
|
2450
|
+
console.warn("Timeline variable " + variable_name + " not found.");
|
|
2451
|
+
}
|
|
2452
|
+
return val;
|
|
2429
2453
|
}
|
|
2430
2454
|
}
|
|
2431
2455
|
// recursively get all the timeline variables for this trial
|
|
@@ -2703,6 +2727,7 @@ class JsPsych {
|
|
|
2703
2727
|
return this.DOM_container;
|
|
2704
2728
|
}
|
|
2705
2729
|
finishTrial(data = {}) {
|
|
2730
|
+
var _a;
|
|
2706
2731
|
if (this.current_trial_finished) {
|
|
2707
2732
|
return;
|
|
2708
2733
|
}
|
|
@@ -2715,7 +2740,7 @@ class JsPsych {
|
|
|
2715
2740
|
// write the data from the trial
|
|
2716
2741
|
this.data.write(data);
|
|
2717
2742
|
// get back the data with all of the defaults in
|
|
2718
|
-
const trial_data = this.data.
|
|
2743
|
+
const trial_data = this.data.getLastTrialData();
|
|
2719
2744
|
// for trial-level callbacks, we just want to pass in a reference to the values
|
|
2720
2745
|
// of the DataCollection, for easy access and editing.
|
|
2721
2746
|
const trial_data_values = trial_data.values()[0];
|
|
@@ -2743,46 +2768,58 @@ class JsPsych {
|
|
|
2743
2768
|
}
|
|
2744
2769
|
}
|
|
2745
2770
|
// handle extension callbacks
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2771
|
+
const extensionCallbackResults = ((_a = current_trial.extensions) !== null && _a !== void 0 ? _a : []).map((extension) => this.extensions[extension.type.info.name].on_finish(extension.params));
|
|
2772
|
+
const onExtensionCallbacksFinished = () => {
|
|
2773
|
+
// about to execute lots of callbacks, so switch context.
|
|
2774
|
+
this.internal.call_immediate = true;
|
|
2775
|
+
// handle callback at plugin level
|
|
2776
|
+
if (typeof current_trial.on_finish === "function") {
|
|
2777
|
+
current_trial.on_finish(trial_data_values);
|
|
2778
|
+
}
|
|
2779
|
+
// handle callback at whole-experiment level
|
|
2780
|
+
this.opts.on_trial_finish(trial_data_values);
|
|
2781
|
+
// after the above callbacks are complete, then the data should be finalized
|
|
2782
|
+
// for this trial. call the on_data_update handler, passing in the same
|
|
2783
|
+
// data object that just went through the trial's finish handlers.
|
|
2784
|
+
this.opts.on_data_update(trial_data_values);
|
|
2785
|
+
// done with callbacks
|
|
2786
|
+
this.internal.call_immediate = false;
|
|
2787
|
+
// wait for iti
|
|
2788
|
+
if (this.simulation_mode === "data-only") {
|
|
2789
|
+
this.nextTrial();
|
|
2750
2790
|
}
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
this.opts.on_trial_finish(trial_data_values);
|
|
2760
|
-
// after the above callbacks are complete, then the data should be finalized
|
|
2761
|
-
// for this trial. call the on_data_update handler, passing in the same
|
|
2762
|
-
// data object that just went through the trial's finish handlers.
|
|
2763
|
-
this.opts.on_data_update(trial_data_values);
|
|
2764
|
-
// done with callbacks
|
|
2765
|
-
this.internal.call_immediate = false;
|
|
2766
|
-
// wait for iti
|
|
2767
|
-
if (this.simulation_mode === "data-only") {
|
|
2768
|
-
this.nextTrial();
|
|
2769
|
-
}
|
|
2770
|
-
else if (typeof current_trial.post_trial_gap === null ||
|
|
2771
|
-
typeof current_trial.post_trial_gap === "undefined") {
|
|
2772
|
-
if (this.opts.default_iti > 0) {
|
|
2773
|
-
setTimeout(this.nextTrial, this.opts.default_iti);
|
|
2791
|
+
else if (typeof current_trial.post_trial_gap === null ||
|
|
2792
|
+
typeof current_trial.post_trial_gap === "undefined") {
|
|
2793
|
+
if (this.opts.default_iti > 0) {
|
|
2794
|
+
setTimeout(this.nextTrial, this.opts.default_iti);
|
|
2795
|
+
}
|
|
2796
|
+
else {
|
|
2797
|
+
this.nextTrial();
|
|
2798
|
+
}
|
|
2774
2799
|
}
|
|
2775
2800
|
else {
|
|
2776
|
-
|
|
2801
|
+
if (current_trial.post_trial_gap > 0) {
|
|
2802
|
+
setTimeout(this.nextTrial, current_trial.post_trial_gap);
|
|
2803
|
+
}
|
|
2804
|
+
else {
|
|
2805
|
+
this.nextTrial();
|
|
2806
|
+
}
|
|
2777
2807
|
}
|
|
2808
|
+
};
|
|
2809
|
+
// Strictly using Promise.resolve to turn all values into promises would be cleaner here, but it
|
|
2810
|
+
// would require user test code to make the event loop tick after every simulated key press even
|
|
2811
|
+
// if there are no async `on_finish` methods. Hence, in order to avoid a breaking change, we
|
|
2812
|
+
// only rely on the event loop if at least one `on_finish` method returns a promise.
|
|
2813
|
+
if (extensionCallbackResults.some((result) => typeof result.then === "function")) {
|
|
2814
|
+
Promise.all(extensionCallbackResults.map((result) => Promise.resolve(result).then((ext_data_values) => {
|
|
2815
|
+
Object.assign(trial_data_values, ext_data_values);
|
|
2816
|
+
}))).then(onExtensionCallbacksFinished);
|
|
2778
2817
|
}
|
|
2779
2818
|
else {
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
}
|
|
2783
|
-
else {
|
|
2784
|
-
this.nextTrial();
|
|
2819
|
+
for (const values of extensionCallbackResults) {
|
|
2820
|
+
Object.assign(trial_data_values, values);
|
|
2785
2821
|
}
|
|
2822
|
+
onExtensionCallbacksFinished();
|
|
2786
2823
|
}
|
|
2787
2824
|
}
|
|
2788
2825
|
endExperiment(end_message = "", data = {}) {
|
|
@@ -3070,16 +3107,16 @@ class JsPsych {
|
|
|
3070
3107
|
}
|
|
3071
3108
|
evaluateTimelineVariables(trial) {
|
|
3072
3109
|
for (const key of Object.keys(trial)) {
|
|
3073
|
-
// timeline variables on the root level
|
|
3074
3110
|
if (typeof trial[key] === "object" &&
|
|
3075
3111
|
trial[key] !== null &&
|
|
3076
3112
|
typeof trial[key].timelineVariablePlaceholder !== "undefined") {
|
|
3077
|
-
|
|
3078
|
-
"function(){returntimeline.timelineVariable(varname);}"
|
|
3079
|
-
)*/ trial[key] = trial[key].timelineVariableFunction();
|
|
3113
|
+
trial[key] = trial[key].timelineVariableFunction();
|
|
3080
3114
|
}
|
|
3081
3115
|
// timeline variables that are nested in objects
|
|
3082
|
-
if (typeof trial[key] === "object" &&
|
|
3116
|
+
if (typeof trial[key] === "object" &&
|
|
3117
|
+
trial[key] !== null &&
|
|
3118
|
+
key !== "timeline" &&
|
|
3119
|
+
key !== "timeline_variables") {
|
|
3083
3120
|
this.evaluateTimelineVariables(trial[key]);
|
|
3084
3121
|
}
|
|
3085
3122
|
}
|
|
@@ -3122,9 +3159,11 @@ class JsPsych {
|
|
|
3122
3159
|
else if (typeof obj === "object") {
|
|
3123
3160
|
if (info === null || !info.nested) {
|
|
3124
3161
|
for (const key of Object.keys(obj)) {
|
|
3125
|
-
if (key === "type") {
|
|
3162
|
+
if (key === "type" || key === "timeline" || key === "timeline_variables") {
|
|
3126
3163
|
// Ignore the object's `type` field because it contains a plugin and we do not want to
|
|
3127
|
-
// call plugin functions
|
|
3164
|
+
// call plugin functions. Also ignore `timeline` and `timeline_variables` because they
|
|
3165
|
+
// are used in the `trials` parameter of the preload plugin and we don't want to actually
|
|
3166
|
+
// evaluate those in that context.
|
|
3128
3167
|
continue;
|
|
3129
3168
|
}
|
|
3130
3169
|
obj[key] = this.replaceFunctionsWithValues(obj[key], null);
|
|
@@ -3254,6 +3293,7 @@ class JsPsych {
|
|
|
3254
3293
|
}
|
|
3255
3294
|
}
|
|
3256
3295
|
|
|
3296
|
+
// __rollup-babel-import-regenerator-runtime__
|
|
3257
3297
|
// temporary patch for Safari
|
|
3258
3298
|
if (typeof window !== "undefined" &&
|
|
3259
3299
|
window.hasOwnProperty("webkitAudioContext") &&
|