@jspsych/plugin-video-keyboard-response 1.1.3 → 2.1.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.cjs CHANGED
@@ -2,329 +2,323 @@
2
2
 
3
3
  var jspsych = require('jspsych');
4
4
 
5
+ var version = "2.1.0";
6
+
5
7
  const info = {
6
- name: "video-keyboard-response",
7
- parameters: {
8
- /** Array of the video file(s) to play. Video can be provided in multiple file formats for better cross-browser support. */
9
- stimulus: {
10
- type: jspsych.ParameterType.VIDEO,
11
- pretty_name: "Video",
12
- default: undefined,
13
- array: true,
14
- },
15
- /** Array containing the key(s) the subject is allowed to press to respond to the stimulus. */
16
- choices: {
17
- type: jspsych.ParameterType.KEYS,
18
- pretty_name: "Choices",
19
- default: "ALL_KEYS",
20
- },
21
- /** Any content here will be displayed below the stimulus. */
22
- prompt: {
23
- type: jspsych.ParameterType.HTML_STRING,
24
- pretty_name: "Prompt",
25
- default: null,
26
- },
27
- /** The width of the video in pixels. */
28
- width: {
29
- type: jspsych.ParameterType.INT,
30
- pretty_name: "Width",
31
- default: "",
32
- },
33
- /** The height of the video display in pixels. */
34
- height: {
35
- type: jspsych.ParameterType.INT,
36
- pretty_name: "Height",
37
- default: "",
38
- },
39
- /** If true, the video will begin playing as soon as it has loaded. */
40
- autoplay: {
41
- type: jspsych.ParameterType.BOOL,
42
- pretty_name: "Autoplay",
43
- default: true,
44
- },
45
- /** If true, the subject will be able to pause the video or move the playback to any point in the video. */
46
- controls: {
47
- type: jspsych.ParameterType.BOOL,
48
- pretty_name: "Controls",
49
- default: false,
50
- },
51
- /** Time to start the clip. If null (default), video will start at the beginning of the file. */
52
- start: {
53
- type: jspsych.ParameterType.FLOAT,
54
- pretty_name: "Start",
55
- default: null,
56
- },
57
- /** Time to stop the clip. If null (default), video will stop at the end of the file. */
58
- stop: {
59
- type: jspsych.ParameterType.FLOAT,
60
- pretty_name: "Stop",
61
- default: null,
62
- },
63
- /** The playback rate of the video. 1 is normal, <1 is slower, >1 is faster. */
64
- rate: {
65
- type: jspsych.ParameterType.FLOAT,
66
- pretty_name: "Rate",
67
- default: 1,
68
- },
69
- /** If true, the trial will end immediately after the video finishes playing. */
70
- trial_ends_after_video: {
71
- type: jspsych.ParameterType.BOOL,
72
- pretty_name: "End trial after video finishes",
73
- default: false,
74
- },
75
- /** How long to show trial before it ends. */
76
- trial_duration: {
77
- type: jspsych.ParameterType.INT,
78
- pretty_name: "Trial duration",
79
- default: null,
80
- },
81
- /** If true, the trial will end when subject makes a response. */
82
- response_ends_trial: {
83
- type: jspsych.ParameterType.BOOL,
84
- pretty_name: "Response ends trial",
85
- default: true,
86
- },
87
- /** If true, then responses are allowed while the video is playing. If false, then the video must finish playing before a response is accepted. */
88
- response_allowed_while_playing: {
89
- type: jspsych.ParameterType.BOOL,
90
- pretty_name: "Response allowed while playing",
91
- default: true,
92
- },
8
+ name: "video-keyboard-response",
9
+ version,
10
+ parameters: {
11
+ /** Array of the video file(s) to play. Video can be provided in multiple file formats for better cross-browser support. */
12
+ stimulus: {
13
+ type: jspsych.ParameterType.VIDEO,
14
+ pretty_name: "Video",
15
+ default: void 0,
16
+ array: true
17
+ },
18
+ /** Array containing the key(s) the subject is allowed to press to respond to the stimulus. */
19
+ choices: {
20
+ type: jspsych.ParameterType.KEYS,
21
+ pretty_name: "Choices",
22
+ default: "ALL_KEYS"
23
+ },
24
+ /** Any content here will be displayed below the stimulus. */
25
+ prompt: {
26
+ type: jspsych.ParameterType.HTML_STRING,
27
+ pretty_name: "Prompt",
28
+ default: null
29
+ },
30
+ /** The width of the video in pixels. */
31
+ width: {
32
+ type: jspsych.ParameterType.INT,
33
+ pretty_name: "Width",
34
+ default: ""
35
+ },
36
+ /** The height of the video display in pixels. */
37
+ height: {
38
+ type: jspsych.ParameterType.INT,
39
+ pretty_name: "Height",
40
+ default: ""
41
+ },
42
+ /** If true, the video will begin playing as soon as it has loaded. */
43
+ autoplay: {
44
+ type: jspsych.ParameterType.BOOL,
45
+ pretty_name: "Autoplay",
46
+ default: true
47
+ },
48
+ /** If true, the subject will be able to pause the video or move the playback to any point in the video. */
49
+ controls: {
50
+ type: jspsych.ParameterType.BOOL,
51
+ pretty_name: "Controls",
52
+ default: false
53
+ },
54
+ /** Time to start the clip. If null (default), video will start at the beginning of the file. */
55
+ start: {
56
+ type: jspsych.ParameterType.FLOAT,
57
+ pretty_name: "Start",
58
+ default: null
59
+ },
60
+ /** Time to stop the clip. If null (default), video will stop at the end of the file. */
61
+ stop: {
62
+ type: jspsych.ParameterType.FLOAT,
63
+ pretty_name: "Stop",
64
+ default: null
65
+ },
66
+ /** The playback rate of the video. 1 is normal, <1 is slower, >1 is faster. */
67
+ rate: {
68
+ type: jspsych.ParameterType.FLOAT,
69
+ pretty_name: "Rate",
70
+ default: 1
71
+ },
72
+ /** If true, the trial will end immediately after the video finishes playing. */
73
+ trial_ends_after_video: {
74
+ type: jspsych.ParameterType.BOOL,
75
+ pretty_name: "End trial after video finishes",
76
+ default: false
77
+ },
78
+ /** How long to show trial before it ends. */
79
+ trial_duration: {
80
+ type: jspsych.ParameterType.INT,
81
+ pretty_name: "Trial duration",
82
+ default: null
93
83
  },
84
+ /** If true, the trial will end when subject makes a response. */
85
+ response_ends_trial: {
86
+ type: jspsych.ParameterType.BOOL,
87
+ pretty_name: "Response ends trial",
88
+ default: true
89
+ },
90
+ /** If true, then responses are allowed while the video is playing. If false, then the video must finish playing before a response is accepted. */
91
+ response_allowed_while_playing: {
92
+ type: jspsych.ParameterType.BOOL,
93
+ pretty_name: "Response allowed while playing",
94
+ default: true
95
+ }
96
+ },
97
+ data: {
98
+ /** Indicates which key the participant pressed. */
99
+ response: {
100
+ type: jspsych.ParameterType.STRING
101
+ },
102
+ /** The response time in milliseconds for the participant to make a response. The time is measured from when the
103
+ * stimulus first appears on the screen until the participant's response.
104
+ * */
105
+ rt: {
106
+ type: jspsych.ParameterType.INT
107
+ },
108
+ /** The `stimulus` array. This will be encoded as a JSON string when data is saved using the `.json()` or `.csv()` functions. */
109
+ stimulus: {
110
+ type: jspsych.ParameterType.STRING,
111
+ array: true
112
+ }
113
+ },
114
+ // prettier-ignore
115
+ citations: {
116
+ "apa": "de Leeuw, J. R., Gilbert, R. A., & Luchterhandt, B. (2023). jsPsych: Enabling an Open-Source Collaborative Ecosystem of Behavioral Experiments. Journal of Open Source Software, 8(85), 5351. https://doi.org/10.21105/joss.05351 ",
117
+ "bibtex": '@article{Leeuw2023jsPsych, author = {de Leeuw, Joshua R. and Gilbert, Rebecca A. and Luchterhandt, Bj{\\" o}rn}, journal = {Journal of Open Source Software}, doi = {10.21105/joss.05351}, issn = {2475-9066}, number = {85}, year = {2023}, month = {may 11}, pages = {5351}, publisher = {Open Journals}, title = {jsPsych: Enabling an {Open}-{Source} {Collaborative} {Ecosystem} of {Behavioral} {Experiments}}, url = {https://joss.theoj.org/papers/10.21105/joss.05351}, volume = {8}, } '
118
+ }
94
119
  };
95
- /**
96
- * **video-keyboard-response**
97
- *
98
- * jsPsych plugin for playing a video file and getting a keyboard response
99
- *
100
- * @author Josh de Leeuw
101
- * @see {@link https://www.jspsych.org/plugins/jspsych-video-keyboard-response/ video-keyboard-response plugin documentation on jspsych.org}
102
- */
103
120
  class VideoKeyboardResponsePlugin {
104
- constructor(jsPsych) {
105
- this.jsPsych = jsPsych;
106
- }
107
- trial(display_element, trial) {
108
- // catch mistake where stimuli are not an array
109
- if (!Array.isArray(trial.stimulus)) {
110
- throw new Error(`
121
+ constructor(jsPsych) {
122
+ this.jsPsych = jsPsych;
123
+ }
124
+ static {
125
+ this.info = info;
126
+ }
127
+ trial(display_element, trial) {
128
+ if (!Array.isArray(trial.stimulus)) {
129
+ throw new Error(`
111
130
  The stimulus property for the video-keyboard-response plugin must be an array
112
131
  of files. See https://www.jspsych.org/latest/plugins/video-keyboard-response/#parameters
113
132
  `);
133
+ }
134
+ var video_html = "<div>";
135
+ video_html += '<video id="jspsych-video-keyboard-response-stimulus"';
136
+ if (trial.width) {
137
+ video_html += ' width="' + trial.width + '"';
138
+ }
139
+ if (trial.height) {
140
+ video_html += ' height="' + trial.height + '"';
141
+ }
142
+ if (trial.autoplay && trial.start == null) {
143
+ video_html += " autoplay ";
144
+ }
145
+ if (trial.controls) {
146
+ video_html += " controls ";
147
+ }
148
+ if (trial.start !== null) {
149
+ video_html += ' style="visibility: hidden;"';
150
+ }
151
+ video_html += ">";
152
+ var video_preload_blob = this.jsPsych.pluginAPI.getVideoBuffer(trial.stimulus[0]);
153
+ if (!video_preload_blob) {
154
+ for (var i = 0; i < trial.stimulus.length; i++) {
155
+ var file_name = trial.stimulus[i];
156
+ if (file_name.indexOf("?") > -1) {
157
+ file_name = file_name.substring(0, file_name.indexOf("?"));
114
158
  }
115
- // setup stimulus
116
- var video_html = "<div>";
117
- video_html += '<video id="jspsych-video-keyboard-response-stimulus"';
118
- if (trial.width) {
119
- video_html += ' width="' + trial.width + '"';
120
- }
121
- if (trial.height) {
122
- video_html += ' height="' + trial.height + '"';
123
- }
124
- if (trial.autoplay && trial.start == null) {
125
- // if autoplay is true and the start time is specified, then the video will start automatically
126
- // via the play() method, rather than the autoplay attribute, to prevent showing the first frame
127
- video_html += " autoplay ";
128
- }
129
- if (trial.controls) {
130
- video_html += " controls ";
131
- }
132
- if (trial.start !== null) {
133
- // hide video element when page loads if the start time is specified,
134
- // to prevent the video element from showing the first frame
135
- video_html += ' style="visibility: hidden;"';
136
- }
137
- video_html += ">";
138
- var video_preload_blob = this.jsPsych.pluginAPI.getVideoBuffer(trial.stimulus[0]);
139
- if (!video_preload_blob) {
140
- for (var i = 0; i < trial.stimulus.length; i++) {
141
- var file_name = trial.stimulus[i];
142
- if (file_name.indexOf("?") > -1) {
143
- file_name = file_name.substring(0, file_name.indexOf("?"));
144
- }
145
- var type = file_name.substr(file_name.lastIndexOf(".") + 1);
146
- type = type.toLowerCase();
147
- if (type == "mov") {
148
- console.warn("Warning: video-keyboard-response plugin does not reliably support .mov files.");
149
- }
150
- video_html += '<source src="' + file_name + '" type="video/' + type + '">';
151
- }
152
- }
153
- video_html += "</video>";
154
- video_html += "</div>";
155
- // add prompt if there is one
156
- if (trial.prompt !== null) {
157
- video_html += trial.prompt;
158
- }
159
- display_element.innerHTML = video_html;
160
- var video_element = display_element.querySelector("#jspsych-video-keyboard-response-stimulus");
161
- if (video_preload_blob) {
162
- video_element.src = video_preload_blob;
163
- }
164
- video_element.onended = () => {
165
- if (trial.trial_ends_after_video) {
166
- end_trial();
167
- }
168
- if (trial.response_allowed_while_playing == false && !trial.trial_ends_after_video) {
169
- // start keyboard listener
170
- this.jsPsych.pluginAPI.getKeyboardResponse({
171
- callback_function: after_response,
172
- valid_responses: trial.choices,
173
- rt_method: "performance",
174
- persist: false,
175
- allow_held_key: false,
176
- });
177
- }
178
- };
179
- video_element.playbackRate = trial.rate;
180
- // if video start time is specified, hide the video and set the starting time
181
- // before showing and playing, so that the video doesn't automatically show the first frame
182
- if (trial.start !== null) {
183
- video_element.pause();
184
- video_element.onseeked = () => {
185
- video_element.style.visibility = "visible";
186
- video_element.muted = false;
187
- if (trial.autoplay) {
188
- video_element.play();
189
- }
190
- else {
191
- video_element.pause();
192
- }
193
- video_element.onseeked = () => { };
194
- };
195
- video_element.onplaying = () => {
196
- video_element.currentTime = trial.start;
197
- video_element.onplaying = () => { };
198
- };
199
- // fix for iOS/MacOS browsers: videos aren't seekable until they start playing, so need to hide/mute, play,
200
- // change current time, then show/unmute
201
- video_element.muted = true;
202
- video_element.play();
159
+ var type = file_name.substr(file_name.lastIndexOf(".") + 1);
160
+ type = type.toLowerCase();
161
+ if (type == "mov") {
162
+ console.warn(
163
+ "Warning: video-keyboard-response plugin does not reliably support .mov files."
164
+ );
203
165
  }
204
- let stopped = false;
205
- if (trial.stop !== null) {
206
- video_element.addEventListener("timeupdate", (e) => {
207
- var currenttime = video_element.currentTime;
208
- if (currenttime >= trial.stop) {
209
- if (!trial.response_allowed_while_playing) {
210
- this.jsPsych.pluginAPI.getKeyboardResponse({
211
- callback_function: after_response,
212
- valid_responses: trial.choices,
213
- rt_method: "performance",
214
- persist: false,
215
- allow_held_key: false,
216
- });
217
- }
218
- video_element.pause();
219
- if (trial.trial_ends_after_video && !stopped) {
220
- // this is to prevent end_trial from being called twice, because the timeupdate event
221
- // can fire in quick succession
222
- stopped = true;
223
- end_trial();
224
- }
225
- }
226
- });
166
+ video_html += '<source src="' + file_name + '" type="video/' + type + '">';
167
+ }
168
+ }
169
+ video_html += "</video>";
170
+ video_html += "</div>";
171
+ if (trial.prompt !== null) {
172
+ video_html += trial.prompt;
173
+ }
174
+ display_element.innerHTML = video_html;
175
+ var video_element = display_element.querySelector(
176
+ "#jspsych-video-keyboard-response-stimulus"
177
+ );
178
+ if (video_preload_blob) {
179
+ video_element.src = video_preload_blob;
180
+ }
181
+ video_element.onended = () => {
182
+ if (trial.trial_ends_after_video) {
183
+ end_trial();
184
+ }
185
+ if (trial.response_allowed_while_playing == false && !trial.trial_ends_after_video) {
186
+ this.jsPsych.pluginAPI.getKeyboardResponse({
187
+ callback_function: after_response,
188
+ valid_responses: trial.choices,
189
+ rt_method: "performance",
190
+ persist: false,
191
+ allow_held_key: false
192
+ });
193
+ }
194
+ };
195
+ video_element.playbackRate = trial.rate;
196
+ if (trial.start !== null) {
197
+ video_element.pause();
198
+ video_element.onseeked = () => {
199
+ video_element.style.visibility = "visible";
200
+ video_element.muted = false;
201
+ if (trial.autoplay) {
202
+ video_element.play();
203
+ } else {
204
+ video_element.pause();
227
205
  }
228
- // store response
229
- var response = {
230
- rt: null,
231
- key: null,
232
- };
233
- // function to end trial when it is time
234
- const end_trial = () => {
235
- // kill any remaining setTimeout handlers
236
- this.jsPsych.pluginAPI.clearAllTimeouts();
237
- // kill keyboard listeners
238
- this.jsPsych.pluginAPI.cancelAllKeyboardResponses();
239
- // stop the video file if it is playing
240
- // remove end event listeners if they exist
241
- display_element
242
- .querySelector("#jspsych-video-keyboard-response-stimulus")
243
- .pause();
244
- display_element.querySelector("#jspsych-video-keyboard-response-stimulus").onended = () => { };
245
- // gather the data to store for the trial
246
- var trial_data = {
247
- rt: response.rt,
248
- stimulus: trial.stimulus,
249
- response: response.key,
250
- };
251
- // clear the display
252
- display_element.innerHTML = "";
253
- // move on to the next trial
254
- this.jsPsych.finishTrial(trial_data);
206
+ video_element.onseeked = () => {
255
207
  };
256
- // function to handle responses by the subject
257
- var after_response = (info) => {
258
- // after a valid response, the stimulus will have the CSS class 'responded'
259
- // which can be used to provide visual feedback that a response was recorded
260
- display_element.querySelector("#jspsych-video-keyboard-response-stimulus").className +=
261
- " responded";
262
- // only record the first response
263
- if (response.key == null) {
264
- response = info;
265
- }
266
- if (trial.response_ends_trial) {
267
- end_trial();
268
- }
208
+ };
209
+ video_element.onplaying = () => {
210
+ video_element.currentTime = trial.start;
211
+ video_element.onplaying = () => {
269
212
  };
270
- // start the response listener
271
- if (trial.choices != "NO_KEYS" && trial.response_allowed_while_playing) {
213
+ };
214
+ video_element.muted = true;
215
+ video_element.play();
216
+ }
217
+ let stopped = false;
218
+ if (trial.stop !== null) {
219
+ video_element.addEventListener("timeupdate", (e) => {
220
+ var currenttime = video_element.currentTime;
221
+ if (currenttime >= trial.stop) {
222
+ if (!trial.response_allowed_while_playing) {
272
223
  this.jsPsych.pluginAPI.getKeyboardResponse({
273
- callback_function: after_response,
274
- valid_responses: trial.choices,
275
- rt_method: "performance",
276
- persist: false,
277
- allow_held_key: false,
224
+ callback_function: after_response,
225
+ valid_responses: trial.choices,
226
+ rt_method: "performance",
227
+ persist: false,
228
+ allow_held_key: false
278
229
  });
230
+ }
231
+ video_element.pause();
232
+ if (trial.trial_ends_after_video && !stopped) {
233
+ stopped = true;
234
+ end_trial();
235
+ }
279
236
  }
280
- // end trial if time limit is set
281
- if (trial.trial_duration !== null) {
282
- this.jsPsych.pluginAPI.setTimeout(end_trial, trial.trial_duration);
283
- }
237
+ });
284
238
  }
285
- simulate(trial, simulation_mode, simulation_options, load_callback) {
286
- if (simulation_mode == "data-only") {
287
- load_callback();
288
- this.simulate_data_only(trial, simulation_options);
289
- }
290
- if (simulation_mode == "visual") {
291
- this.simulate_visual(trial, simulation_options, load_callback);
292
- }
239
+ var response = {
240
+ rt: null,
241
+ key: null
242
+ };
243
+ const end_trial = () => {
244
+ this.jsPsych.pluginAPI.cancelAllKeyboardResponses();
245
+ display_element.querySelector("#jspsych-video-keyboard-response-stimulus").pause();
246
+ display_element.querySelector(
247
+ "#jspsych-video-keyboard-response-stimulus"
248
+ ).onended = () => {
249
+ };
250
+ var trial_data = {
251
+ rt: response.rt,
252
+ stimulus: trial.stimulus,
253
+ response: response.key
254
+ };
255
+ this.jsPsych.finishTrial(trial_data);
256
+ };
257
+ var after_response = (info2) => {
258
+ display_element.querySelector("#jspsych-video-keyboard-response-stimulus").className += " responded";
259
+ if (response.key == null) {
260
+ response = info2;
261
+ }
262
+ if (trial.response_ends_trial) {
263
+ end_trial();
264
+ }
265
+ };
266
+ if (trial.choices != "NO_KEYS" && trial.response_allowed_while_playing) {
267
+ this.jsPsych.pluginAPI.getKeyboardResponse({
268
+ callback_function: after_response,
269
+ valid_responses: trial.choices,
270
+ rt_method: "performance",
271
+ persist: false,
272
+ allow_held_key: false
273
+ });
293
274
  }
294
- simulate_data_only(trial, simulation_options) {
295
- const data = this.create_simulation_data(trial, simulation_options);
296
- this.jsPsych.finishTrial(data);
275
+ if (trial.trial_duration !== null) {
276
+ this.jsPsych.pluginAPI.setTimeout(end_trial, trial.trial_duration);
297
277
  }
298
- simulate_visual(trial, simulation_options, load_callback) {
299
- const data = this.create_simulation_data(trial, simulation_options);
300
- const display_element = this.jsPsych.getDisplayElement();
301
- this.trial(display_element, trial);
302
- load_callback();
303
- const video_element = display_element.querySelector("#jspsych-video-button-response-stimulus");
304
- const respond = () => {
305
- if (data.rt !== null) {
306
- this.jsPsych.pluginAPI.pressKey(data.response, data.rt);
307
- }
308
- };
309
- if (!trial.response_allowed_while_playing) {
310
- video_element.addEventListener("ended", respond);
311
- }
312
- else {
313
- respond();
314
- }
278
+ }
279
+ simulate(trial, simulation_mode, simulation_options, load_callback) {
280
+ if (simulation_mode == "data-only") {
281
+ load_callback();
282
+ this.simulate_data_only(trial, simulation_options);
315
283
  }
316
- create_simulation_data(trial, simulation_options) {
317
- const default_data = {
318
- stimulus: trial.stimulus,
319
- rt: this.jsPsych.randomization.sampleExGaussian(500, 50, 1 / 150, true),
320
- response: this.jsPsych.pluginAPI.getValidKey(trial.choices),
321
- };
322
- const data = this.jsPsych.pluginAPI.mergeSimulationData(default_data, simulation_options);
323
- this.jsPsych.pluginAPI.ensureSimulationDataConsistency(trial, data);
324
- return data;
284
+ if (simulation_mode == "visual") {
285
+ this.simulate_visual(trial, simulation_options, load_callback);
286
+ }
287
+ }
288
+ simulate_data_only(trial, simulation_options) {
289
+ const data = this.create_simulation_data(trial, simulation_options);
290
+ this.jsPsych.finishTrial(data);
291
+ }
292
+ simulate_visual(trial, simulation_options, load_callback) {
293
+ const data = this.create_simulation_data(trial, simulation_options);
294
+ const display_element = this.jsPsych.getDisplayElement();
295
+ this.trial(display_element, trial);
296
+ load_callback();
297
+ const video_element = display_element.querySelector(
298
+ "#jspsych-video-button-response-stimulus"
299
+ );
300
+ const respond = () => {
301
+ if (data.rt !== null) {
302
+ this.jsPsych.pluginAPI.pressKey(data.response, data.rt);
303
+ }
304
+ };
305
+ if (!trial.response_allowed_while_playing) {
306
+ video_element.addEventListener("ended", respond);
307
+ } else {
308
+ respond();
325
309
  }
310
+ }
311
+ create_simulation_data(trial, simulation_options) {
312
+ const default_data = {
313
+ stimulus: trial.stimulus,
314
+ rt: this.jsPsych.randomization.sampleExGaussian(500, 50, 1 / 150, true),
315
+ response: this.jsPsych.pluginAPI.getValidKey(trial.choices)
316
+ };
317
+ const data = this.jsPsych.pluginAPI.mergeSimulationData(default_data, simulation_options);
318
+ this.jsPsych.pluginAPI.ensureSimulationDataConsistency(trial, data);
319
+ return data;
320
+ }
326
321
  }
327
- VideoKeyboardResponsePlugin.info = info;
328
322
 
329
323
  module.exports = VideoKeyboardResponsePlugin;
330
324
  //# sourceMappingURL=index.cjs.map