jspsych 6.3.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.
Files changed (401) hide show
  1. package/README.md +36 -37
  2. package/css/jspsych.css +39 -39
  3. package/dist/JsPsych.d.ts +112 -0
  4. package/dist/TimelineNode.d.ts +34 -0
  5. package/dist/index.browser.js +3171 -0
  6. package/dist/index.browser.js.map +1 -0
  7. package/dist/index.browser.min.js +2 -0
  8. package/dist/index.browser.min.js.map +1 -0
  9. package/dist/index.cjs +3165 -0
  10. package/dist/index.cjs.map +1 -0
  11. package/dist/index.d.ts +11 -0
  12. package/dist/index.js +3159 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/migration.d.ts +3 -0
  15. package/dist/modules/data/DataCollection.d.ts +45 -0
  16. package/dist/modules/data/DataColumn.d.ts +15 -0
  17. package/dist/modules/data/index.d.ts +25 -0
  18. package/dist/modules/data/utils.d.ts +3 -0
  19. package/dist/modules/extensions.d.ts +22 -0
  20. package/dist/modules/plugin-api/HardwareAPI.d.ts +15 -0
  21. package/dist/modules/plugin-api/KeyboardListenerAPI.d.ts +34 -0
  22. package/dist/modules/plugin-api/MediaAPI.d.ts +27 -0
  23. package/dist/modules/plugin-api/SimulationAPI.d.ts +41 -0
  24. package/dist/modules/plugin-api/TimeoutAPI.d.ts +5 -0
  25. package/dist/modules/plugin-api/index.d.ts +8 -0
  26. package/dist/modules/plugins.d.ts +136 -0
  27. package/dist/modules/randomization.d.ts +35 -0
  28. package/dist/modules/turk.d.ts +40 -0
  29. package/dist/modules/utils.d.ts +7 -0
  30. package/package.json +32 -15
  31. package/src/JsPsych.ts +884 -0
  32. package/src/TimelineNode.ts +536 -0
  33. package/src/index.ts +71 -0
  34. package/src/migration.ts +37 -0
  35. package/src/modules/data/DataCollection.ts +198 -0
  36. package/src/modules/data/DataColumn.ts +86 -0
  37. package/src/modules/data/index.ts +174 -0
  38. package/src/modules/data/utils.ts +75 -0
  39. package/src/modules/extensions.ts +23 -0
  40. package/src/modules/plugin-api/HardwareAPI.ts +32 -0
  41. package/src/modules/plugin-api/KeyboardListenerAPI.ts +165 -0
  42. package/src/modules/plugin-api/MediaAPI.ts +337 -0
  43. package/src/modules/plugin-api/SimulationAPI.ts +181 -0
  44. package/src/modules/plugin-api/TimeoutAPI.ts +16 -0
  45. package/src/modules/plugin-api/index.ts +28 -0
  46. package/src/modules/plugins.ts +165 -0
  47. package/src/modules/randomization.ts +327 -0
  48. package/src/modules/turk.ts +99 -0
  49. package/src/modules/utils.ts +30 -0
  50. package/.github/workflows/jest.yml +0 -20
  51. package/code-of-conduct.md +0 -56
  52. package/contributors.md +0 -61
  53. package/docs/CNAME +0 -1
  54. package/docs/about/about.md +0 -18
  55. package/docs/about/contributing.md +0 -43
  56. package/docs/about/license.md +0 -25
  57. package/docs/about/support.md +0 -7
  58. package/docs/core_library/jspsych-core.md +0 -719
  59. package/docs/core_library/jspsych-data.md +0 -587
  60. package/docs/core_library/jspsych-pluginAPI.md +0 -624
  61. package/docs/core_library/jspsych-randomization.md +0 -389
  62. package/docs/core_library/jspsych-turk.md +0 -98
  63. package/docs/extensions/extensions.md +0 -83
  64. package/docs/extensions/jspsych-ext-webgazer.md +0 -137
  65. package/docs/img/blue.png +0 -0
  66. package/docs/img/devtools-change-css.png +0 -0
  67. package/docs/img/devtools-css-errors.png +0 -0
  68. package/docs/img/devtools-inspect-element.png +0 -0
  69. package/docs/img/folder-setup.png +0 -0
  70. package/docs/img/folder-with-html.png +0 -0
  71. package/docs/img/githubreleases.jpg +0 -0
  72. package/docs/img/jspsych-favicon.png +0 -0
  73. package/docs/img/jspsych-logo-no-text-mono.svg +0 -493
  74. package/docs/img/jspsych-logo.jpg +0 -0
  75. package/docs/img/orange.png +0 -0
  76. package/docs/img/palmer_stim.png +0 -0
  77. package/docs/img/progress_bar.png +0 -0
  78. package/docs/img/prolific-study-completion.png +0 -0
  79. package/docs/img/prolific-study-link.png +0 -0
  80. package/docs/img/visual_search_example.jpg +0 -0
  81. package/docs/index.md +0 -9
  82. package/docs/overview/browser-device-support.md +0 -35
  83. package/docs/overview/callbacks.md +0 -180
  84. package/docs/overview/data.md +0 -281
  85. package/docs/overview/dynamic-parameters.md +0 -147
  86. package/docs/overview/exclude-browser.md +0 -32
  87. package/docs/overview/experiment-options.md +0 -149
  88. package/docs/overview/eye-tracking.md +0 -271
  89. package/docs/overview/fullscreen.md +0 -36
  90. package/docs/overview/media-preloading.md +0 -369
  91. package/docs/overview/mturk.md +0 -77
  92. package/docs/overview/plugins.md +0 -320
  93. package/docs/overview/progress-bar.md +0 -110
  94. package/docs/overview/prolific.md +0 -78
  95. package/docs/overview/record-browser-interactions.md +0 -23
  96. package/docs/overview/running-experiments.md +0 -95
  97. package/docs/overview/style.md +0 -293
  98. package/docs/overview/timeline.md +0 -457
  99. package/docs/plugins/jspsych-animation.md +0 -40
  100. package/docs/plugins/jspsych-audio-button-response.md +0 -60
  101. package/docs/plugins/jspsych-audio-keyboard-response.md +0 -58
  102. package/docs/plugins/jspsych-audio-slider-response.md +0 -53
  103. package/docs/plugins/jspsych-call-function.md +0 -81
  104. package/docs/plugins/jspsych-canvas-button-response.md +0 -66
  105. package/docs/plugins/jspsych-canvas-keyboard-response.md +0 -68
  106. package/docs/plugins/jspsych-canvas-slider-response.md +0 -89
  107. package/docs/plugins/jspsych-categorize-animation.md +0 -60
  108. package/docs/plugins/jspsych-categorize-html.md +0 -53
  109. package/docs/plugins/jspsych-categorize-image.md +0 -53
  110. package/docs/plugins/jspsych-cloze.md +0 -45
  111. package/docs/plugins/jspsych-external-html.md +0 -70
  112. package/docs/plugins/jspsych-free-sort.md +0 -56
  113. package/docs/plugins/jspsych-fullscreen.md +0 -57
  114. package/docs/plugins/jspsych-html-button-response.md +0 -42
  115. package/docs/plugins/jspsych-html-keyboard-response.md +0 -51
  116. package/docs/plugins/jspsych-html-slider-response.md +0 -45
  117. package/docs/plugins/jspsych-iat-html.md +0 -64
  118. package/docs/plugins/jspsych-iat-image.md +0 -64
  119. package/docs/plugins/jspsych-image-button-response.md +0 -48
  120. package/docs/plugins/jspsych-image-keyboard-response.md +0 -58
  121. package/docs/plugins/jspsych-image-slider-response.md +0 -54
  122. package/docs/plugins/jspsych-instructions.md +0 -58
  123. package/docs/plugins/jspsych-maxdiff.md +0 -41
  124. package/docs/plugins/jspsych-preload.md +0 -128
  125. package/docs/plugins/jspsych-rdk.md +0 -119
  126. package/docs/plugins/jspsych-reconstruction.md +0 -48
  127. package/docs/plugins/jspsych-resize.md +0 -39
  128. package/docs/plugins/jspsych-same-different-html.md +0 -53
  129. package/docs/plugins/jspsych-same-different-image.md +0 -66
  130. package/docs/plugins/jspsych-serial-reaction-time-mouse.md +0 -52
  131. package/docs/plugins/jspsych-serial-reaction-time.md +0 -57
  132. package/docs/plugins/jspsych-survey-html-form.md +0 -50
  133. package/docs/plugins/jspsych-survey-likert.md +0 -70
  134. package/docs/plugins/jspsych-survey-multi-choice.md +0 -48
  135. package/docs/plugins/jspsych-survey-multi-select.md +0 -53
  136. package/docs/plugins/jspsych-survey-text.md +0 -63
  137. package/docs/plugins/jspsych-video-button-response.md +0 -54
  138. package/docs/plugins/jspsych-video-keyboard-response.md +0 -50
  139. package/docs/plugins/jspsych-video-slider-response.md +0 -60
  140. package/docs/plugins/jspsych-virtual-chinrest.md +0 -105
  141. package/docs/plugins/jspsych-visual-search-circle.md +0 -52
  142. package/docs/plugins/jspsych-vsl-animate-occlusion.md +0 -55
  143. package/docs/plugins/jspsych-vsl-grid-scene.md +0 -62
  144. package/docs/plugins/jspsych-webgazer-calibrate.md +0 -61
  145. package/docs/plugins/jspsych-webgazer-init-camera.md +0 -30
  146. package/docs/plugins/jspsych-webgazer-validate.md +0 -44
  147. package/docs/plugins/list-of-plugins.md +0 -54
  148. package/docs/tutorials/hello-world.md +0 -162
  149. package/docs/tutorials/rt-task.md +0 -1334
  150. package/docs/tutorials/video-tutorials.md +0 -11
  151. package/examples/add-to-end-of-timeline.html +0 -38
  152. package/examples/case-sensitive-responses.html +0 -45
  153. package/examples/conditional-and-loop-functions.html +0 -64
  154. package/examples/css/jquery-ui.css +0 -1225
  155. package/examples/css-classes-parameter.html +0 -145
  156. package/examples/data-add-properties.html +0 -44
  157. package/examples/data-as-function.html +0 -39
  158. package/examples/data-from-timeline.html +0 -52
  159. package/examples/data-from-url.html +0 -21
  160. package/examples/demo-flanker.html +0 -117
  161. package/examples/demo-simple-rt-task.html +0 -120
  162. package/examples/demos/demo_1.html +0 -35
  163. package/examples/demos/demo_2.html +0 -50
  164. package/examples/demos/demo_3.html +0 -63
  165. package/examples/display-element-to-embed-experiment.html +0 -79
  166. package/examples/end-active-node.html +0 -52
  167. package/examples/end-experiment.html +0 -45
  168. package/examples/exclusions.html +0 -32
  169. package/examples/external_html/simple_consent.html +0 -4
  170. package/examples/img/1.gif +0 -0
  171. package/examples/img/10.gif +0 -0
  172. package/examples/img/11.gif +0 -0
  173. package/examples/img/12.gif +0 -0
  174. package/examples/img/2.gif +0 -0
  175. package/examples/img/3.gif +0 -0
  176. package/examples/img/4.gif +0 -0
  177. package/examples/img/5.gif +0 -0
  178. package/examples/img/6.gif +0 -0
  179. package/examples/img/7.gif +0 -0
  180. package/examples/img/8.gif +0 -0
  181. package/examples/img/9.gif +0 -0
  182. package/examples/img/age/of1.jpg +0 -0
  183. package/examples/img/age/of2.jpg +0 -0
  184. package/examples/img/age/of3.jpg +0 -0
  185. package/examples/img/age/om1.jpg +0 -0
  186. package/examples/img/age/om2.jpg +0 -0
  187. package/examples/img/age/om3.jpg +0 -0
  188. package/examples/img/age/yf1.jpg +0 -0
  189. package/examples/img/age/yf4.jpg +0 -0
  190. package/examples/img/age/yf5.jpg +0 -0
  191. package/examples/img/age/ym2.jpg +0 -0
  192. package/examples/img/age/ym3.jpg +0 -0
  193. package/examples/img/age/ym5.jpg +0 -0
  194. package/examples/img/backwardN.gif +0 -0
  195. package/examples/img/blue.png +0 -0
  196. package/examples/img/card.png +0 -0
  197. package/examples/img/con1.png +0 -0
  198. package/examples/img/con2.png +0 -0
  199. package/examples/img/fixation.gif +0 -0
  200. package/examples/img/happy_face_1.jpg +0 -0
  201. package/examples/img/happy_face_2.jpg +0 -0
  202. package/examples/img/happy_face_3.jpg +0 -0
  203. package/examples/img/happy_face_4.jpg +0 -0
  204. package/examples/img/inc1.png +0 -0
  205. package/examples/img/inc2.png +0 -0
  206. package/examples/img/normalN.gif +0 -0
  207. package/examples/img/orange.png +0 -0
  208. package/examples/img/redX.png +0 -0
  209. package/examples/img/ribbon.jpg +0 -0
  210. package/examples/img/sad_face_1.jpg +0 -0
  211. package/examples/img/sad_face_2.jpg +0 -0
  212. package/examples/img/sad_face_3.jpg +0 -0
  213. package/examples/img/sad_face_4.jpg +0 -0
  214. package/examples/js/snap.svg-min.js +0 -21
  215. package/examples/js/webgazer/ridgeWorker.mjs +0 -135
  216. package/examples/js/webgazer/webgazer.js +0 -88909
  217. package/examples/js/webgazer/worker_scripts/mat.js +0 -306
  218. package/examples/js/webgazer/worker_scripts/util.js +0 -398
  219. package/examples/jspsych-RDK.html +0 -58
  220. package/examples/jspsych-animation.html +0 -39
  221. package/examples/jspsych-audio-button-response.html +0 -58
  222. package/examples/jspsych-audio-keyboard-response.html +0 -68
  223. package/examples/jspsych-audio-slider-response.html +0 -61
  224. package/examples/jspsych-call-function.html +0 -32
  225. package/examples/jspsych-canvas-button-response.html +0 -95
  226. package/examples/jspsych-canvas-keyboard-response.html +0 -78
  227. package/examples/jspsych-canvas-slider-response.html +0 -67
  228. package/examples/jspsych-categorize-animation.html +0 -49
  229. package/examples/jspsych-categorize-html.html +0 -33
  230. package/examples/jspsych-categorize-image.html +0 -44
  231. package/examples/jspsych-cloze.html +0 -37
  232. package/examples/jspsych-free-sort.html +0 -109
  233. package/examples/jspsych-fullscreen.html +0 -45
  234. package/examples/jspsych-html-button-response.html +0 -43
  235. package/examples/jspsych-html-keyboard-response.html +0 -42
  236. package/examples/jspsych-html-slider-response.html +0 -53
  237. package/examples/jspsych-iat.html +0 -520
  238. package/examples/jspsych-image-button-response.html +0 -91
  239. package/examples/jspsych-image-keyboard-response.html +0 -85
  240. package/examples/jspsych-image-slider-response.html +0 -85
  241. package/examples/jspsych-instructions.html +0 -37
  242. package/examples/jspsych-maxdiff.html +0 -33
  243. package/examples/jspsych-preload.html +0 -140
  244. package/examples/jspsych-reconstruction.html +0 -43
  245. package/examples/jspsych-resize.html +0 -34
  246. package/examples/jspsych-same-different-html.html +0 -28
  247. package/examples/jspsych-same-different-image.html +0 -39
  248. package/examples/jspsych-serial-reaction-time-mouse.html +0 -98
  249. package/examples/jspsych-serial-reaction-time.html +0 -54
  250. package/examples/jspsych-survey-html-form.html +0 -33
  251. package/examples/jspsych-survey-likert.html +0 -42
  252. package/examples/jspsych-survey-multi-choice.html +0 -40
  253. package/examples/jspsych-survey-multi-select.html +0 -42
  254. package/examples/jspsych-survey-text.html +0 -34
  255. package/examples/jspsych-video-button-response.html +0 -65
  256. package/examples/jspsych-video-keyboard-response.html +0 -61
  257. package/examples/jspsych-video-slider-response.html +0 -63
  258. package/examples/jspsych-virtual-chinrest.html +0 -69
  259. package/examples/jspsych-visual-search-circle.html +0 -64
  260. package/examples/jspsych-vsl-animate-occlusion.html +0 -35
  261. package/examples/jspsych-vsl-grid-scene.html +0 -47
  262. package/examples/lexical-decision.html +0 -134
  263. package/examples/manual-preloading.html +0 -59
  264. package/examples/pause-unpause.html +0 -33
  265. package/examples/progress-bar.html +0 -68
  266. package/examples/save-trial-parameters.html +0 -98
  267. package/examples/sound/hammer.mp3 +0 -0
  268. package/examples/sound/sound.mp3 +0 -0
  269. package/examples/sound/speech_blue.mp3 +0 -0
  270. package/examples/sound/speech_green.mp3 +0 -0
  271. package/examples/sound/speech_joke.mp3 +0 -0
  272. package/examples/sound/speech_red.mp3 +0 -0
  273. package/examples/sound/tone.mp3 +0 -0
  274. package/examples/timeline-variables-sampling.html +0 -50
  275. package/examples/timeline-variables.html +0 -64
  276. package/examples/video/sample_video.mp4 +0 -0
  277. package/examples/webgazer.html +0 -174
  278. package/examples/webgazer_audio.html +0 -90
  279. package/examples/webgazer_image.html +0 -60
  280. package/extensions/jspsych-ext-webgazer.js +0 -265
  281. package/jspsych.js +0 -3023
  282. package/license.txt +0 -21
  283. package/mkdocs.yml +0 -118
  284. package/plugins/jspsych-animation.js +0 -189
  285. package/plugins/jspsych-audio-button-response.js +0 -269
  286. package/plugins/jspsych-audio-keyboard-response.js +0 -209
  287. package/plugins/jspsych-audio-slider-response.js +0 -278
  288. package/plugins/jspsych-call-function.js +0 -58
  289. package/plugins/jspsych-canvas-button-response.js +0 -199
  290. package/plugins/jspsych-canvas-keyboard-response.js +0 -155
  291. package/plugins/jspsych-canvas-slider-response.js +0 -207
  292. package/plugins/jspsych-categorize-animation.js +0 -266
  293. package/plugins/jspsych-categorize-html.js +0 -220
  294. package/plugins/jspsych-categorize-image.js +0 -222
  295. package/plugins/jspsych-cloze.js +0 -112
  296. package/plugins/jspsych-external-html.js +0 -112
  297. package/plugins/jspsych-free-sort.js +0 -478
  298. package/plugins/jspsych-fullscreen.js +0 -106
  299. package/plugins/jspsych-html-button-response.js +0 -188
  300. package/plugins/jspsych-html-keyboard-response.js +0 -149
  301. package/plugins/jspsych-html-slider-response.js +0 -202
  302. package/plugins/jspsych-iat-html.js +0 -284
  303. package/plugins/jspsych-iat-image.js +0 -286
  304. package/plugins/jspsych-image-button-response.js +0 -327
  305. package/plugins/jspsych-image-keyboard-response.js +0 -263
  306. package/plugins/jspsych-image-slider-response.js +0 -369
  307. package/plugins/jspsych-instructions.js +0 -237
  308. package/plugins/jspsych-maxdiff.js +0 -173
  309. package/plugins/jspsych-preload.js +0 -345
  310. package/plugins/jspsych-rdk.js +0 -1373
  311. package/plugins/jspsych-reconstruction.js +0 -134
  312. package/plugins/jspsych-resize.js +0 -166
  313. package/plugins/jspsych-same-different-html.js +0 -168
  314. package/plugins/jspsych-same-different-image.js +0 -169
  315. package/plugins/jspsych-serial-reaction-time-mouse.js +0 -212
  316. package/plugins/jspsych-serial-reaction-time.js +0 -247
  317. package/plugins/jspsych-survey-html-form.js +0 -171
  318. package/plugins/jspsych-survey-likert.js +0 -195
  319. package/plugins/jspsych-survey-multi-choice.js +0 -208
  320. package/plugins/jspsych-survey-multi-select.js +0 -232
  321. package/plugins/jspsych-survey-text.js +0 -185
  322. package/plugins/jspsych-video-button-response.js +0 -335
  323. package/plugins/jspsych-video-keyboard-response.js +0 -279
  324. package/plugins/jspsych-video-slider-response.js +0 -351
  325. package/plugins/jspsych-virtual-chinrest.js +0 -471
  326. package/plugins/jspsych-visual-search-circle.js +0 -259
  327. package/plugins/jspsych-vsl-animate-occlusion.js +0 -196
  328. package/plugins/jspsych-vsl-grid-scene.js +0 -103
  329. package/plugins/jspsych-webgazer-calibrate.js +0 -161
  330. package/plugins/jspsych-webgazer-init-camera.js +0 -139
  331. package/plugins/jspsych-webgazer-validate.js +0 -314
  332. package/plugins/template/jspsych-plugin-template.js +0 -35
  333. package/tests/README.md +0 -7
  334. package/tests/jsPsych/case-sensitive-responses.test.js +0 -53
  335. package/tests/jsPsych/css-classes-parameter.test.js +0 -107
  336. package/tests/jsPsych/default-iti.test.js +0 -51
  337. package/tests/jsPsych/default-parameters.test.js +0 -58
  338. package/tests/jsPsych/endexperiment.test.js +0 -49
  339. package/tests/jsPsych/events.test.js +0 -606
  340. package/tests/jsPsych/functions-as-parameters.test.js +0 -210
  341. package/tests/jsPsych/init.test.js +0 -48
  342. package/tests/jsPsych/loads.test.js +0 -7
  343. package/tests/jsPsych/min-rt.test.js +0 -58
  344. package/tests/jsPsych/progressbar.test.js +0 -202
  345. package/tests/jsPsych/timeline-variables.test.js +0 -531
  346. package/tests/jsPsych/timelines.test.js +0 -569
  347. package/tests/jsPsych.data/data-csv-conversion.test.js +0 -85
  348. package/tests/jsPsych.data/data-json-conversion.test.js +0 -120
  349. package/tests/jsPsych.data/datacollection.test.js +0 -117
  350. package/tests/jsPsych.data/datacolumn.test.js +0 -50
  351. package/tests/jsPsych.data/datamodule.test.js +0 -152
  352. package/tests/jsPsych.data/dataparameter.test.js +0 -251
  353. package/tests/jsPsych.data/interactions.test.js +0 -109
  354. package/tests/jsPsych.data/trialparameters.test.js +0 -175
  355. package/tests/jsPsych.extensions/extensions.test.js +0 -207
  356. package/tests/jsPsych.extensions/test-extension.js +0 -42
  357. package/tests/jsPsych.pluginAPI/pluginapi.test.js +0 -365
  358. package/tests/jsPsych.pluginAPI/preloads.test.js +0 -43
  359. package/tests/jsPsych.randomization/randomziation.test.js +0 -27
  360. package/tests/jsPsych.utils/utils.test.js +0 -58
  361. package/tests/plugins/plugin-animation.test.js +0 -34
  362. package/tests/plugins/plugin-audio-button-response.test.js +0 -15
  363. package/tests/plugins/plugin-audio-keyboard-response.test.js +0 -15
  364. package/tests/plugins/plugin-audio-slider-response.test.js +0 -15
  365. package/tests/plugins/plugin-call-function.test.js +0 -49
  366. package/tests/plugins/plugin-categorize-animation.test.js +0 -263
  367. package/tests/plugins/plugin-categorize-html.test.js +0 -17
  368. package/tests/plugins/plugin-categorize-image.test.js +0 -17
  369. package/tests/plugins/plugin-cloze.test.js +0 -157
  370. package/tests/plugins/plugin-free-sort.test.js +0 -106
  371. package/tests/plugins/plugin-fullscreen.test.js +0 -41
  372. package/tests/plugins/plugin-html-button-response.test.js +0 -161
  373. package/tests/plugins/plugin-html-keyboard-response.test.js +0 -139
  374. package/tests/plugins/plugin-html-slider-response.test.js +0 -155
  375. package/tests/plugins/plugin-iat-html.test.js +0 -299
  376. package/tests/plugins/plugin-iat-image.test.js +0 -298
  377. package/tests/plugins/plugin-image-button-response.test.js +0 -174
  378. package/tests/plugins/plugin-image-keyboard-response.test.js +0 -147
  379. package/tests/plugins/plugin-image-slider-response.test.js +0 -174
  380. package/tests/plugins/plugin-instructions.test.js +0 -85
  381. package/tests/plugins/plugin-maxdiff.test.js +0 -39
  382. package/tests/plugins/plugin-preload.test.js +0 -916
  383. package/tests/plugins/plugin-rdk.test.js +0 -61
  384. package/tests/plugins/plugin-reconstruction.test.js +0 -16
  385. package/tests/plugins/plugin-resize.test.js +0 -16
  386. package/tests/plugins/plugin-same-different-html.test.js +0 -17
  387. package/tests/plugins/plugin-same-different-image.test.js +0 -17
  388. package/tests/plugins/plugin-serial-reaction-time-mouse.test.js +0 -42
  389. package/tests/plugins/plugin-serial-reaction-time.test.js +0 -109
  390. package/tests/plugins/plugin-survey-html-form.test.js +0 -44
  391. package/tests/plugins/plugin-survey-likert.test.js +0 -48
  392. package/tests/plugins/plugin-survey-multi-choice.test.js +0 -47
  393. package/tests/plugins/plugin-survey-multi-select.test.js +0 -71
  394. package/tests/plugins/plugin-survey-text.test.js +0 -115
  395. package/tests/plugins/plugin-video-button-response.test.js +0 -32
  396. package/tests/plugins/plugin-video-keyboard-response.test.js +0 -32
  397. package/tests/plugins/plugin-video-slider-response.test.js +0 -31
  398. package/tests/plugins/plugin-visual-search-circle.test.js +0 -16
  399. package/tests/plugins/plugin-vsl-animate-occlusion.test.js +0 -16
  400. package/tests/plugins/plugin-vsl-grid-scene.test.js +0 -16
  401. package/tests/testing-utils.js +0 -13
@@ -1,306 +0,0 @@
1
- (function() {
2
- 'use strict';
3
-
4
- self.webgazer = self.webgazer || {};
5
- self.webgazer.mat = self.webgazer.mat || {};
6
-
7
- /**
8
- * Transposes an mxn array
9
- * @param {Array.<Array.<Number>>} matrix - of 'M x N' dimensionality
10
- * @return {Array.<Array.<Number>>} transposed matrix
11
- */
12
- self.webgazer.mat.transpose = function(matrix){
13
- var m = matrix.length;
14
- var n = matrix[0].length;
15
- var transposedMatrix = new Array(n);
16
-
17
- for (var i = 0; i < m; i++){
18
- for (var j = 0; j < n; j++){
19
- if (i === 0) transposedMatrix[j] = new Array(m);
20
- transposedMatrix[j][i] = matrix[i][j];
21
- }
22
- }
23
-
24
- return transposedMatrix;
25
- };
26
-
27
- /**
28
- * Get a sub-matrix of matrix
29
- * @param {Array.<Array.<Number>>} matrix - original matrix
30
- * @param {Array.<Number>} r - Array of row indices
31
- * @param {Number} j0 - Initial column index
32
- * @param {Number} j1 - Final column index
33
- * @returns {Array} The sub-matrix matrix(r(:),j0:j1)
34
- */
35
- self.webgazer.mat.getMatrix = function(matrix, r, j0, j1){
36
- var X = new Array(r.length),
37
- m = j1-j0+1;
38
-
39
- for (var i = 0; i < r.length; i++){
40
- X[i] = new Array(m);
41
- for (var j = j0; j <= j1; j++){
42
- X[i][j-j0] = matrix[r[i]][j];
43
- }
44
- }
45
- return X;
46
- };
47
-
48
- /**
49
- * Get a submatrix of matrix
50
- * @param {Array.<Array.<Number>>} matrix - original matrix
51
- * @param {Number} i0 - Initial row index
52
- * @param {Number} i1 - Final row index
53
- * @param {Number} j0 - Initial column index
54
- * @param {Number} j1 - Final column index
55
- * @return {Array} The sub-matrix matrix(i0:i1,j0:j1)
56
- */
57
- self.webgazer.mat.getSubMatrix = function(matrix, i0, i1, j0, j1){
58
- var size = j1 - j0 + 1,
59
- X = new Array(i1-i0+1);
60
-
61
- for (var i = i0; i <= i1; i++){
62
- var subI = i-i0;
63
-
64
- X[subI] = new Array(size);
65
-
66
- for (var j = j0; j <= j1; j++){
67
- X[subI][j-j0] = matrix[i][j];
68
- }
69
- }
70
- return X;
71
- };
72
-
73
- /**
74
- * Linear algebraic matrix multiplication, matrix1 * matrix2
75
- * @param {Array.<Array.<Number>>} matrix1
76
- * @param {Array.<Array.<Number>>} matrix2
77
- * @return {Array.<Array.<Number>>} Matrix product, matrix1 * matrix2
78
- */
79
- self.webgazer.mat.mult = function(matrix1, matrix2){
80
-
81
- if (matrix2.length != matrix1[0].length){
82
- console.log('Matrix inner dimensions must agree:');
83
-
84
- }
85
-
86
- var X = new Array(matrix1.length),
87
- Bcolj = new Array(matrix1[0].length);
88
-
89
- for (var j = 0; j < matrix2[0].length; j++){
90
- for (var k = 0; k < matrix1[0].length; k++){
91
- Bcolj[k] = matrix2[k][j];
92
- }
93
- for (var i = 0; i < matrix1.length; i++){
94
-
95
- if (j === 0)
96
- X[i] = new Array(matrix2[0].length);
97
-
98
- var Arowi = matrix1[i];
99
- var s = 0;
100
- for (var k = 0; k < matrix1[0].length; k++){
101
- s += Arowi[k]*Bcolj[k];
102
- }
103
- X[i][j] = s;
104
- }
105
- }
106
- return X;
107
- };
108
-
109
-
110
- /**
111
- * LUDecomposition to solve A*X = B, based on WEKA code
112
- * @param {Array.<Array.<Number>>} A - left matrix of equation to be solved
113
- * @param {Array.<Array.<Number>>} B - right matrix of equation to be solved
114
- * @return {Array.<Array.<Number>>} X so that L*U*X = B(piv,:)
115
- */
116
- self.webgazer.mat.LUDecomposition = function(A,B){
117
- var LU = new Array(A.length);
118
-
119
- for (var i = 0; i < A.length; i++){
120
- LU[i] = new Array(A[0].length);
121
- for (var j = 0; j < A[0].length; j++){
122
- LU[i][j] = A[i][j];
123
- }
124
- }
125
-
126
- var m = A.length;
127
- var n = A[0].length;
128
- var piv = new Array(m);
129
- for (var i = 0; i < m; i++){
130
- piv[i] = i;
131
- }
132
- var pivsign = 1;
133
- var LUrowi = new Array();
134
- var LUcolj = new Array(m);
135
- // Outer loop.
136
- for (var j = 0; j < n; j++){
137
- // Make a copy of the j-th column to localize references.
138
- for (var i = 0; i < m; i++){
139
- LUcolj[i] = LU[i][j];
140
- }
141
- // Apply previous transformations.
142
- for (var i = 0; i < m; i++){
143
- LUrowi = LU[i];
144
- // Most of the time is spent in the following dot product.
145
- var kmax = Math.min(i,j);
146
- var s = 0;
147
- for (var k = 0; k < kmax; k++){
148
- s += LUrowi[k]*LUcolj[k];
149
- }
150
- LUrowi[j] = LUcolj[i] -= s;
151
- }
152
- // Find pivot and exchange if necessary.
153
- var p = j;
154
- for (var i = j+1; i < m; i++){
155
- if (Math.abs(LUcolj[i]) > Math.abs(LUcolj[p])){
156
- p = i;
157
- }
158
- }
159
- if (p != j){
160
- for (var k = 0; k < n; k++){
161
- var t = LU[p][k];
162
- LU[p][k] = LU[j][k];
163
- LU[j][k] = t;
164
- }
165
- var k = piv[p];
166
- piv[p] = piv[j];
167
- piv[j] = k;
168
- pivsign = -pivsign;
169
- }
170
- // Compute multipliers.
171
- if (j < m & LU[j][j] != 0){
172
- for (var i = j+1; i < m; i++){
173
- LU[i][j] /= LU[j][j];
174
- }
175
- }
176
- }
177
- if (B.length != m){
178
- console.log('Matrix row dimensions must agree.');
179
- }
180
- for (var j = 0; j < n; j++){
181
- if (LU[j][j] === 0){
182
- console.log('Matrix is singular.')
183
- }
184
- }
185
- var nx = B[0].length;
186
- var X = self.webgazer.mat.getMatrix(B,piv,0,nx-1);
187
- // Solve L*Y = B(piv,:)
188
- for (var k = 0; k < n; k++){
189
- for (var i = k+1; i < n; i++){
190
- for (var j = 0; j < nx; j++){
191
- X[i][j] -= X[k][j]*LU[i][k];
192
- }
193
- }
194
- }
195
- // Solve U*X = Y;
196
- for (var k = n-1; k >= 0; k--){
197
- for (var j = 0; j < nx; j++){
198
- X[k][j] /= LU[k][k];
199
- }
200
- for (var i = 0; i < k; i++){
201
- for (var j = 0; j < nx; j++){
202
- X[i][j] -= X[k][j]*LU[i][k];
203
- }
204
- }
205
- }
206
- return X;
207
- };
208
-
209
- /**
210
- * Least squares solution of A*X = B, based on WEKA code
211
- * @param {Array.<Array.<Number>>} A - left side matrix to be solved
212
- * @param {Array.<Array.<Number>>} B - a matrix with as many rows as A and any number of columns.
213
- * @return {Array.<Array.<Number>>} X - that minimizes the two norms of QR*X-B.
214
- */
215
- self.webgazer.mat.QRDecomposition = function(A, B){
216
- // Initialize.
217
- var QR = new Array(A.length);
218
-
219
- for (var i = 0; i < A.length; i++){
220
- QR[i] = new Array(A[0].length);
221
- for (var j = 0; j < A[0].length; j++){
222
- QR[i][j] = A[i][j];
223
- }
224
- }
225
- var m = A.length;
226
- var n = A[0].length;
227
- var Rdiag = new Array(n);
228
- var nrm;
229
-
230
- // Main loop.
231
- for (var k = 0; k < n; k++){
232
- // Compute 2-norm of k-th column without under/overflow.
233
- nrm = 0;
234
- for (var i = k; i < m; i++){
235
- nrm = Math.hypot(nrm,QR[i][k]);
236
- }
237
- if (nrm != 0){
238
- // Form k-th Householder vector.
239
- if (QR[k][k] < 0){
240
- nrm = -nrm;
241
- }
242
- for (var i = k; i < m; i++){
243
- QR[i][k] /= nrm;
244
- }
245
- QR[k][k] += 1;
246
-
247
- // Apply transformation to remaining columns.
248
- for (var j = k+1; j < n; j++){
249
- var s = 0;
250
- for (var i = k; i < m; i++){
251
- s += QR[i][k]*QR[i][j];
252
- }
253
- s = -s/QR[k][k];
254
- for (var i = k; i < m; i++){
255
- QR[i][j] += s*QR[i][k];
256
- }
257
- }
258
- }
259
- Rdiag[k] = -nrm;
260
- }
261
- if (B.length != m){
262
- console.log('Matrix row dimensions must agree.');
263
- }
264
- for (var j = 0; j < n; j++){
265
- if (Rdiag[j] === 0)
266
- console.log('Matrix is rank deficient');
267
- }
268
- // Copy right hand side
269
- var nx = B[0].length;
270
- var X = new Array(B.length);
271
- for(var i=0; i<B.length; i++){
272
- X[i] = new Array(B[0].length);
273
- }
274
- for (var i = 0; i < B.length; i++){
275
- for (var j = 0; j < B[0].length; j++){
276
- X[i][j] = B[i][j];
277
- }
278
- }
279
- // Compute Y = transpose(Q)*B
280
- for (var k = 0; k < n; k++){
281
- for (var j = 0; j < nx; j++){
282
- var s = 0.0;
283
- for (var i = k; i < m; i++){
284
- s += QR[i][k]*X[i][j];
285
- }
286
- s = -s/QR[k][k];
287
- for (var i = k; i < m; i++){
288
- X[i][j] += s*QR[i][k];
289
- }
290
- }
291
- }
292
- // Solve R*X = Y;
293
- for (var k = n-1; k >= 0; k--){
294
- for (var j = 0; j < nx; j++){
295
- X[k][j] /= Rdiag[k];
296
- }
297
- for (var i = 0; i < k; i++){
298
- for (var j = 0; j < nx; j++){
299
- X[i][j] -= X[k][j]*QR[i][k];
300
- }
301
- }
302
- }
303
- return self.webgazer.mat.getSubMatrix(X,0,n-1,0,nx-1);
304
- }
305
-
306
- }());
@@ -1,398 +0,0 @@
1
- 'use strict';
2
- (function() {
3
-
4
- self.webgazer = self.webgazer || {};
5
- self.webgazer.util = self.webgazer.util || {};
6
- self.webgazer.mat = self.webgazer.mat || {};
7
-
8
- /**
9
- * Eye class, represents an eye patch detected in the video stream
10
- * @param {ImageData} patch - the image data corresponding to an eye
11
- * @param {Number} imagex - x-axis offset from the top-left corner of the video canvas
12
- * @param {Number} imagey - y-axis offset from the top-left corner of the video canvas
13
- * @param {Number} width - width of the eye patch
14
- * @param {Number} height - height of the eye patch
15
- */
16
- self.webgazer.util.Eye = function(patch, imagex, imagey, width, height) {
17
- this.patch = patch;
18
- this.imagex = imagex;
19
- this.imagey = imagey;
20
- this.width = width;
21
- this.height = height;
22
- };
23
-
24
-
25
- //Data Window class
26
- //operates like an array but 'wraps' data around to keep the array at a fixed windowSize
27
- /**
28
- * DataWindow class - Operates like an array, but 'wraps' data around to keep the array at a fixed windowSize
29
- * @param {Number} windowSize - defines the maximum size of the window
30
- * @param {Array} data - optional data to seed the DataWindow with
31
- **/
32
- self.webgazer.util.DataWindow = function(windowSize, data) {
33
- this.data = [];
34
- this.windowSize = windowSize;
35
- this.index = 0;
36
- this.length = 0;
37
- if(data){
38
- this.data = data.slice(data.length-windowSize,data.length);
39
- this.length = this.data.length;
40
- }
41
- };
42
-
43
- /**
44
- * [push description]
45
- * @param {*} entry - item to be inserted. It either grows the DataWindow or replaces the oldest item
46
- * @return {DataWindow} this
47
- */
48
- self.webgazer.util.DataWindow.prototype.push = function(entry) {
49
- if (this.data.length < this.windowSize) {
50
- this.data.push(entry);
51
- this.length = this.data.length;
52
- return this;
53
- }
54
-
55
- //replace oldest entry by wrapping around the DataWindow
56
- this.data[this.index] = entry;
57
- this.index = (this.index + 1) % this.windowSize;
58
- return this;
59
- };
60
-
61
- /**
62
- * Get the element at the ind position by wrapping around the DataWindow
63
- * @param {Number} ind index of desired entry
64
- * @return {*}
65
- */
66
- self.webgazer.util.DataWindow.prototype.get = function(ind) {
67
- return this.data[this.getTrueIndex(ind)];
68
- };
69
-
70
- /**
71
- * Gets the true this.data array index given an index for a desired element
72
- * @param {Number} ind - index of desired entry
73
- * @return {Number} index of desired entry in this.data
74
- */
75
- self.webgazer.util.DataWindow.prototype.getTrueIndex = function(ind) {
76
- if (this.data.length < this.windowSize) {
77
- return ind;
78
- } else {
79
- //wrap around ind so that we can traverse from oldest to newest
80
- return (ind + this.index) % this.windowSize;
81
- }
82
- };
83
-
84
- /**
85
- * Append all the contents of data
86
- * @param {Array} data - to be inserted
87
- */
88
- self.webgazer.util.DataWindow.prototype.addAll = function(data) {
89
- for (var i = 0; i < data.length; i++) {
90
- this.push(data[i]);
91
- }
92
- };
93
-
94
-
95
- //Helper functions
96
- /**
97
- * Grayscales an image patch. Can be used for the whole canvas, detected face, detected eye, etc.
98
- *
99
- * Code from tracking.js by Eduardo Lundgren, et al.
100
- * https://github.com/eduardolundgren/tracking.js/blob/master/src/tracking.js
101
- *
102
- * Software License Agreement (BSD License) Copyright (c) 2014, Eduardo A. Lundgren Melo. All rights reserved.
103
- * Redistribution and use of this software in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
104
- * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
105
- * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
106
- * The name of Eduardo A. Lundgren Melo may not be used to endorse or promote products derived from this software without specific prior written permission of Eduardo A. Lundgren Melo.
107
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
108
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
109
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
110
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
111
- *
112
- * @param {Array} pixels - image data to be grayscaled
113
- * @param {Number} width - width of image data to be grayscaled
114
- * @param {Number} height - height of image data to be grayscaled
115
- * @return {Array} grayscaledImage
116
- */
117
- self.webgazer.util.grayscale = function(pixels, width, height){
118
- var gray = new Uint8ClampedArray(pixels.length >> 2);
119
- var p = 0;
120
- var w = 0;
121
- for (var i = 0; i < height; i++) {
122
- for (var j = 0; j < width; j++) {
123
- var value = pixels[w] * 0.299 + pixels[w + 1] * 0.587 + pixels[w + 2] * 0.114;
124
- gray[p++] = value;
125
-
126
- w += 4;
127
- }
128
- }
129
- return gray;
130
- };
131
-
132
- /**
133
- * Increase contrast of an image.
134
- *
135
- * Code from Martin Tschirsich, Copyright (c) 2012.
136
- * https://github.com/mtschirs/js-objectdetect/blob/gh-pages/js/objectdetect.js
137
- *
138
- * @param {Array} src - grayscale integer array
139
- * @param {Number} step - sampling rate, control performance
140
- * @param {Array} dst - array to hold the resulting image
141
- */
142
- self.webgazer.util.equalizeHistogram = function(src, step, dst) {
143
- var srcLength = src.length;
144
- if (!dst) dst = src;
145
- if (!step) step = 5;
146
-
147
- // Compute histogram and histogram sum:
148
- var hist = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
149
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
150
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
151
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
152
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
153
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
154
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
155
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
156
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
157
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
158
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
159
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
160
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
161
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
162
- 0, 0, 0, 0];
163
-
164
- for (var i = 0; i < srcLength; i += step) {
165
- ++hist[src[i]];
166
- }
167
-
168
- // Compute integral histogram:
169
- var norm = 255 * step / srcLength,
170
- prev = 0;
171
- for (var i = 0; i < 256; ++i) {
172
- var h = hist[i];
173
- prev = h += prev;
174
- hist[i] = h * norm; // For non-integer src: ~~(h * norm + 0.5);
175
- }
176
-
177
- // Equalize image:
178
- for (var i = 0; i < srcLength; ++i) {
179
- dst[i] = hist[src[i]];
180
- }
181
- return dst;
182
- };
183
-
184
- self.webgazer.util.threshold = function(data, threshold) {
185
- for (let i = 0; i < data.length; i++) {
186
- data[i] = (data[i] > threshold) ? 255 : 0;
187
- }
188
- return data;
189
- };
190
-
191
- self.webgazer.util.correlation = function(data1, data2) {
192
- const length = Math.min(data1.length, data2.length);
193
- let count = 0;
194
- for (let i = 0; i < length; i++) {
195
- if (data1[i] === data2[i]) {
196
- count++;
197
- }
198
- }
199
- return count / Math.max(data1.length, data2.length);
200
- };
201
-
202
- /**
203
- * Gets an Eye object and resizes it to the desired resolution
204
- * @param {webgazer.util.Eye} eye - patch to be resized
205
- * @param {Number} resizeWidth - desired width
206
- * @param {Number} resizeHeight - desired height
207
- * @return {webgazer.util.Eye} resized eye patch
208
- */
209
- self.webgazer.util.resizeEye = function(eye, resizeWidth, resizeHeight) {
210
-
211
- var canvas = document.createElement('canvas');
212
- canvas.width = eye.width;
213
- canvas.height = eye.height;
214
-
215
- canvas.getContext('2d').putImageData(eye.patch,0,0);
216
-
217
- var tempCanvas = document.createElement('canvas');
218
-
219
- tempCanvas.width = resizeWidth;
220
- tempCanvas.height = resizeHeight;
221
-
222
- // save the canvas into temp canvas
223
- tempCanvas.getContext('2d').drawImage(canvas, 0, 0, canvas.width, canvas.height, 0, 0, resizeWidth, resizeHeight);
224
-
225
- return tempCanvas.getContext('2d').getImageData(0, 0, resizeWidth, resizeHeight);
226
- };
227
-
228
- /**
229
- * Checks if the prediction is within the boundaries of the viewport and constrains it
230
- * @param {Array} prediction [x,y] - predicted gaze coordinates
231
- * @return {Array} constrained coordinates
232
- */
233
- self.webgazer.util.bound = function(prediction){
234
- if(prediction.x < 0)
235
- prediction.x = 0;
236
- if(prediction.y < 0)
237
- prediction.y = 0;
238
- var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
239
- var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
240
- if(prediction.x > w){
241
- prediction.x = w;
242
- }
243
-
244
- if(prediction.y > h)
245
- {
246
- prediction.y = h;
247
- }
248
- return prediction;
249
- };
250
-
251
- /**
252
- * Write statistics in debug paragraph panel
253
- * @param {HTMLElement} para - The <p> tag where write data
254
- * @param {Object} stats - The stats data to output
255
- */
256
- function debugBoxWrite(para, stats) {
257
- var str = '';
258
- for (var key in stats) {
259
- str += key + ': ' + stats[key] + '\n';
260
- }
261
- para.innerText = str;
262
- }
263
-
264
- /**
265
- * Constructor of DebugBox object,
266
- * it insert an paragraph inside a div to the body, in view to display debug data
267
- * @param {Number} interval - The log interval
268
- * @constructor
269
- */
270
- self.webgazer.util.DebugBox = function(interval) {
271
- this.para = document.createElement('p');
272
- this.div = document.createElement('div');
273
- this.div.appendChild(this.para);
274
- document.body.appendChild(this.div);
275
-
276
- this.buttons = {};
277
- this.canvas = {};
278
- this.stats = {};
279
- var updateInterval = interval || 300;
280
- (function(localThis) {
281
- setInterval(function() {
282
- debugBoxWrite(localThis.para, localThis.stats);
283
- }, updateInterval);
284
- }(this));
285
- };
286
-
287
- /**
288
- * Add stat data for log
289
- * @param {String} key - The data key
290
- * @param {*} value - The value
291
- */
292
- self.webgazer.util.DebugBox.prototype.set = function(key, value) {
293
- this.stats[key] = value;
294
- };
295
-
296
- /**
297
- * Initialize stats in case where key does not exist, else
298
- * increment value for key
299
- * @param {String} key - The key to process
300
- * @param {Number} incBy - Value to increment for given key (default: 1)
301
- * @param {Number} init - Initial value in case where key does not exist (default: 0)
302
- */
303
- self.webgazer.util.DebugBox.prototype.inc = function(key, incBy, init) {
304
- if (!this.stats[key]) {
305
- this.stats[key] = init || 0;
306
- }
307
- this.stats[key] += incBy || 1;
308
- };
309
-
310
- /**
311
- * Create a button and register the given function to the button click event
312
- * @param {String} name - The button name to link
313
- * @param {Function} func - The onClick callback
314
- */
315
- self.webgazer.util.DebugBox.prototype.addButton = function(name, func) {
316
- if (!this.buttons[name]) {
317
- this.buttons[name] = document.createElement('button');
318
- this.div.appendChild(this.buttons[name]);
319
- }
320
- var button = this.buttons[name];
321
- this.buttons[name] = button;
322
- button.addEventListener('click', func);
323
- button.innerText = name;
324
- };
325
-
326
- /**
327
- * Search for a canvas elemenet with name, or create on if not exist.
328
- * Then send the canvas element as callback parameter.
329
- * @param {String} name - The canvas name to send/create
330
- * @param {Function} func - The callback function where send canvas
331
- */
332
- self.webgazer.util.DebugBox.prototype.show = function(name, func) {
333
- if (!this.canvas[name]) {
334
- this.canvas[name] = document.createElement('canvas');
335
- this.div.appendChild(this.canvas[name]);
336
- }
337
- var canvas = this.canvas[name];
338
- canvas.getContext('2d').clearRect(0,0, canvas.width, canvas.height);
339
- func(canvas);
340
- };
341
-
342
- /**
343
- * Kalman Filter constructor
344
- * Kalman filters work by reducing the amount of noise in a models.
345
- * https://blog.cordiner.net/2011/05/03/object-tracking-using-a-kalman-filter-matlab/
346
- *
347
- * @param {Array.<Array.<Number>>} F - transition matrix
348
- * @param {Array.<Array.<Number>>} Q - process noise matrix
349
- * @param {Array.<Array.<Number>>} H - maps between measurement vector and noise matrix
350
- * @param {Array.<Array.<Number>>} R - defines measurement error of the device
351
- * @param {Array} P_initial - the initial state
352
- * @param {Array} X_initial - the initial state of the device
353
- */
354
- self.webgazer.util.KalmanFilter = function(F, H, Q, R, P_initial, X_initial) {
355
- this.F = F; // State transition matrix
356
- this.Q = Q; // Process noise matrix
357
- this.H = H; // Transformation matrix
358
- this.R = R; // Measurement Noise
359
- this.P = P_initial; //Initial covariance matrix
360
- this.X = X_initial; //Initial guess of measurement
361
- };
362
-
363
- /**
364
- * Get Kalman next filtered value and update the internal state
365
- * @param {Array} z - the new measurement
366
- * @return {Array}
367
- */
368
- self.webgazer.util.KalmanFilter.prototype.update = function(z) {
369
-
370
- // Here, we define all the different matrix operations we will need
371
- var add = numeric.add, sub = numeric.sub, inv = numeric.inv, identity = numeric.identity;
372
- var mult = webgazer.mat.mult, transpose = webgazer.mat.transpose;
373
- //TODO cache variables like the transpose of H
374
-
375
- // prediction: X = F * X | P = F * P * F' + Q
376
- var X_p = mult(this.F, this.X); //Update state vector
377
- var P_p = add(mult(mult(this.F,this.P), transpose(this.F)), this.Q); //Predicted covaraince
378
-
379
- //Calculate the update values
380
- var y = sub(z, mult(this.H, X_p)); // This is the measurement error (between what we expect and the actual value)
381
- var S = add(mult(mult(this.H, P_p), transpose(this.H)), this.R); //This is the residual covariance (the error in the covariance)
382
-
383
- // kalman multiplier: K = P * H' * (H * P * H' + R)^-1
384
- var K = mult(P_p, mult(transpose(this.H), inv(S))); //This is the Optimal Kalman Gain
385
-
386
- //We need to change Y into it's column vector form
387
- for(var i = 0; i < y.length; i++){
388
- y[i] = [y[i]];
389
- }
390
-
391
- //Now we correct the internal values of the model
392
- // correction: X = X + K * (m - H * X) | P = (I - K * H) * P
393
- this.X = add(X_p, mult(K, y));
394
- this.P = mult(sub(identity(K.length), mult(K,this.H)), P_p);
395
- return transpose(mult(this.H, this.X))[0]; //Transforms the predicted state back into it's measurement form
396
- };
397
-
398
- }());