compileprofile-spacetests 0.3.0 → 0.4.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.
Files changed (37) hide show
  1. package/CLAUDE.md +114 -114
  2. package/README.md +171 -147
  3. package/dist/cjs/common-interfaces.d.ts +33 -1
  4. package/dist/cjs/gonogo.js +89 -57
  5. package/dist/cjs/nback.d.ts +6 -2
  6. package/dist/cjs/nback.js +132 -2
  7. package/dist/cjs/spatial-cognition.js +0 -2
  8. package/dist/esm/common-interfaces.d.ts +33 -1
  9. package/dist/esm/gonogo.js +89 -57
  10. package/dist/esm/nback.d.ts +6 -2
  11. package/dist/esm/nback.js +128 -2
  12. package/dist/esm/spatial-cognition.js +0 -2
  13. package/example-data/emotions.json +807 -807
  14. package/example-data/gonogo.json +5392 -5392
  15. package/example-data/nback.json +892 -892
  16. package/example-data/participant.json +6 -6
  17. package/example-data/spatial-cognition.json +462 -462
  18. package/jest.config.js +13 -13
  19. package/original/emotion-recognition.R +39 -39
  20. package/original/gonogo.R +32 -32
  21. package/package.json +40 -40
  22. package/src/__tests__/integration/browserInfo.test.ts +16 -16
  23. package/src/__tests__/integration/emotions.test.ts +172 -172
  24. package/src/__tests__/integration/gonogo.test.ts +293 -183
  25. package/src/__tests__/integration/nback-versions.test.ts +182 -0
  26. package/src/__tests__/integration/nback.test.ts +148 -148
  27. package/src/__tests__/integration/spatial-cognition.test.ts +171 -171
  28. package/src/__tests__/test-utils/testData.ts +79 -79
  29. package/src/common-interfaces.ts +124 -78
  30. package/src/emotions.ts +98 -98
  31. package/src/getters.ts +21 -21
  32. package/src/gonogo.ts +149 -127
  33. package/src/index.ts +39 -39
  34. package/src/nback.ts +182 -61
  35. package/src/spatial-cognition.ts +110 -112
  36. package/tsconfig.cjs.json +12 -12
  37. package/tsconfig.esm.json +14 -14
@@ -1,80 +1,80 @@
1
- import * as fs from 'fs';
2
- import * as path from 'path';
3
-
4
- // Define interfaces for our test data types
5
- export interface TestDataFiles {
6
- spatialCognition: any[];
7
- nback: any[];
8
- participant: any[];
9
- gonogo: any[];
10
- emotions: any[];
11
- }
12
-
13
- // Function to load all test data
14
- export function loadTestData(type: string): TestDataFiles {
15
- const dataDir = path.join(process.cwd(), 'example-data');
16
-
17
- if (type === 'spatialCognition') {
18
- return {
19
- spatialCognition: JSON.parse(fs.readFileSync(path.join(dataDir, 'spatial-cognition.json'), 'utf-8')),
20
- nback: [],
21
- participant: [],
22
- gonogo: [],
23
- emotions: []
24
- };
25
- }
26
- if (type === 'nback') {
27
- return {
28
- spatialCognition: [],
29
- nback: JSON.parse(fs.readFileSync(path.join(dataDir, 'nback.json'), 'utf-8')),
30
- participant: [],
31
- gonogo: [],
32
- emotions: []
33
- };
34
- }
35
- if (type === 'participant') {
36
- return {
37
- spatialCognition: [],
38
- nback: [],
39
- participant: JSON.parse(fs.readFileSync(path.join(dataDir, 'participant.json'), 'utf-8')),
40
- gonogo: [],
41
- emotions: []
42
- };
43
- }
44
- if (type === 'gonogo') {
45
- return {
46
- spatialCognition: [],
47
- nback: [],
48
- participant: [],
49
- gonogo: JSON.parse(fs.readFileSync(path.join(dataDir, 'gonogo.json'), 'utf-8')),
50
- emotions: []
51
- };
52
- }
53
- if (type === 'emotions') {
54
- return {
55
- spatialCognition: [],
56
- nback: [],
57
- participant: [],
58
- gonogo: [],
59
- emotions: JSON.parse(fs.readFileSync(path.join(dataDir, 'emotions.json'), 'utf-8'))
60
- };
61
- }
62
- if (type === 'all') {
63
- return {
64
- spatialCognition: JSON.parse(fs.readFileSync(path.join(dataDir, 'spatial-cognition.json'), 'utf-8')),
65
- nback: JSON.parse(fs.readFileSync(path.join(dataDir, 'nback.json'), 'utf-8')),
66
- participant: JSON.parse(fs.readFileSync(path.join(dataDir, 'participant.json'), 'utf-8')),
67
- gonogo: JSON.parse(fs.readFileSync(path.join(dataDir, 'gonogo.json'), 'utf-8')),
68
- emotions: JSON.parse(fs.readFileSync(path.join(dataDir, 'emotions.json'), 'utf-8'))
69
- };
70
- }
71
-
72
- // Default return for unknown types
73
- return {
74
- spatialCognition: [],
75
- nback: [],
76
- participant: [],
77
- gonogo: [],
78
- emotions: []
79
- };
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+
4
+ // Define interfaces for our test data types
5
+ export interface TestDataFiles {
6
+ spatialCognition: any[];
7
+ nback: any[];
8
+ participant: any[];
9
+ gonogo: any[];
10
+ emotions: any[];
11
+ }
12
+
13
+ // Function to load all test data
14
+ export function loadTestData(type: string): TestDataFiles {
15
+ const dataDir = path.join(process.cwd(), 'example-data');
16
+
17
+ if (type === 'spatialCognition') {
18
+ return {
19
+ spatialCognition: JSON.parse(fs.readFileSync(path.join(dataDir, 'spatial-cognition.json'), 'utf-8')),
20
+ nback: [],
21
+ participant: [],
22
+ gonogo: [],
23
+ emotions: []
24
+ };
25
+ }
26
+ if (type === 'nback') {
27
+ return {
28
+ spatialCognition: [],
29
+ nback: JSON.parse(fs.readFileSync(path.join(dataDir, 'nback.json'), 'utf-8')),
30
+ participant: [],
31
+ gonogo: [],
32
+ emotions: []
33
+ };
34
+ }
35
+ if (type === 'participant') {
36
+ return {
37
+ spatialCognition: [],
38
+ nback: [],
39
+ participant: JSON.parse(fs.readFileSync(path.join(dataDir, 'participant.json'), 'utf-8')),
40
+ gonogo: [],
41
+ emotions: []
42
+ };
43
+ }
44
+ if (type === 'gonogo') {
45
+ return {
46
+ spatialCognition: [],
47
+ nback: [],
48
+ participant: [],
49
+ gonogo: JSON.parse(fs.readFileSync(path.join(dataDir, 'gonogo.json'), 'utf-8')),
50
+ emotions: []
51
+ };
52
+ }
53
+ if (type === 'emotions') {
54
+ return {
55
+ spatialCognition: [],
56
+ nback: [],
57
+ participant: [],
58
+ gonogo: [],
59
+ emotions: JSON.parse(fs.readFileSync(path.join(dataDir, 'emotions.json'), 'utf-8'))
60
+ };
61
+ }
62
+ if (type === 'all') {
63
+ return {
64
+ spatialCognition: JSON.parse(fs.readFileSync(path.join(dataDir, 'spatial-cognition.json'), 'utf-8')),
65
+ nback: JSON.parse(fs.readFileSync(path.join(dataDir, 'nback.json'), 'utf-8')),
66
+ participant: JSON.parse(fs.readFileSync(path.join(dataDir, 'participant.json'), 'utf-8')),
67
+ gonogo: JSON.parse(fs.readFileSync(path.join(dataDir, 'gonogo.json'), 'utf-8')),
68
+ emotions: JSON.parse(fs.readFileSync(path.join(dataDir, 'emotions.json'), 'utf-8'))
69
+ };
70
+ }
71
+
72
+ // Default return for unknown types
73
+ return {
74
+ spatialCognition: [],
75
+ nback: [],
76
+ participant: [],
77
+ gonogo: [],
78
+ emotions: []
79
+ };
80
80
  }
@@ -1,79 +1,125 @@
1
- interface CommonResults {
2
- n_trials: number;
3
- n_correct_trials: number;
4
- n_incorrect_trials: number;
5
- avg_rt_total: number;
6
- avg_rt_correct: number;
7
- avg_rt_incorrect: number;
8
- performance_score: number;
9
- }
10
-
11
- interface NbackSpecialResults {
12
- target_trials: {
13
- n: number;
14
- avg_rt: number;
15
- avg_acc: number;
16
- };
17
- non_target_trials: {
18
- n: number;
19
- avg_rt: number;
20
- avg_acc: number;
21
- };
22
- }
23
-
24
- interface SpatialSpecialResults {
25
- by_distance: any[];
26
- by_angle: any[];
27
- by_rotation: any[];
28
- }
29
-
30
- interface GonogoSpecialResults {
31
- by_block: any[];
32
- go_trials: {
33
- n: number;
34
- avg_rt: number;
35
- avg_acc: number;
36
- };
37
- nogo_trials: {
38
- n: number;
39
- avg_rt: number;
40
- avg_acc: number;
41
- };
42
- }
43
-
44
- interface EmotionSpecialResults {
45
- by_emotion: any[];
46
- confusion_matrix: any;
47
- }
48
-
49
- interface NbackResultsStructure {
50
- common: CommonResults;
51
- special: NbackSpecialResults;
52
- }
53
-
54
- interface SpatialResultsStructure {
55
- common: CommonResults;
56
- special: SpatialSpecialResults;
57
- }
58
-
59
- interface GonogoResultsStructure {
60
- common: CommonResults;
61
- special: GonogoSpecialResults;
62
- }
63
-
64
- interface EmotionResultsStructure {
65
- common: CommonResults;
66
- special: EmotionSpecialResults;
67
- }
68
-
69
- export {
70
- CommonResults,
71
- NbackResultsStructure,
72
- SpatialResultsStructure,
73
- GonogoResultsStructure,
74
- EmotionResultsStructure,
75
- NbackSpecialResults,
76
- SpatialSpecialResults,
77
- GonogoSpecialResults,
78
- EmotionSpecialResults
1
+ interface CommonResults {
2
+ n_trials: number;
3
+ n_correct_trials: number;
4
+ n_incorrect_trials: number;
5
+ avg_rt_total: number;
6
+ avg_rt_correct: number;
7
+ avg_rt_incorrect: number;
8
+ performance_score: number;
9
+ }
10
+
11
+ // Accuracy, signal detection and reaction times for one group of n-back trials
12
+ interface NbackGroupResults {
13
+ n_trials: number;
14
+ n_correct_trials: number;
15
+ performance_score: number;
16
+ n_targets: number;
17
+ n_non_targets: number;
18
+ hits: number;
19
+ misses: number;
20
+ false_alarms: number;
21
+ correct_rejections: number;
22
+ hit_rate: number | null;
23
+ false_alarm_rate: number | null;
24
+ d_prime: number | null;
25
+ // Lures: non-targets repeating an image from a distance other than N. Their false alarms are
26
+ // also counted in false_alarms; a high lure_false_alarm_rate means responding to familiarity.
27
+ n_lures: number;
28
+ lure_false_alarms: number;
29
+ lure_false_alarm_rate: number | null;
30
+ avg_rt_hits: number | null;
31
+ avg_rt_false_alarms: number | null;
32
+ }
33
+
34
+ interface NbackBlockResults extends NbackGroupResults {
35
+ block: string;
36
+ block_index: number;
37
+ n_back: number;
38
+ }
39
+
40
+ interface NbackLevelResults extends NbackGroupResults {
41
+ n_back: number;
42
+ }
43
+
44
+ interface NbackSpecialResults {
45
+ target_trials: {
46
+ n: number;
47
+ avg_rt: number;
48
+ avg_acc: number;
49
+ };
50
+ non_target_trials: {
51
+ n: number;
52
+ avg_rt: number;
53
+ avg_acc: number;
54
+ };
55
+ // Only for test version 2+ data, whose trials carry n_back, block and block_index
56
+ by_block?: NbackBlockResults[];
57
+ by_nback?: NbackLevelResults[];
58
+ }
59
+
60
+ interface SpatialSpecialResults {
61
+ by_distance: any[];
62
+ by_angle: any[];
63
+ by_rotation: any[];
64
+ }
65
+
66
+ interface GonogoSpecialResults {
67
+ // Mean of go_trials.avg_acc (hit rate) and nogo_trials.avg_acc (correct-rejection rate).
68
+ // This is the accuracy the performance score uses, so withholding counts as much as responding.
69
+ balanced_acc: number;
70
+ // Per block: avg_rt over hits only, avg_acc = proportion correct, plus hit_rate,
71
+ // correct_rejection_rate and balanced_acc.
72
+ by_block: any[];
73
+ go_trials: {
74
+ n: number;
75
+ avg_rt: number; // mean RT of hits (go trials with a response); 0 when there are none
76
+ avg_acc: number; // hit rate
77
+ n_omissions: number; // go trials without a response
78
+ };
79
+ nogo_trials: {
80
+ n: number;
81
+ avg_rt: number; // mean RT of false alarms (no-go trials with a response); 0 when there are none
82
+ avg_acc: number; // correct-rejection rate
83
+ n_commissions: number; // no-go trials with a response (false alarms)
84
+ };
85
+ }
86
+
87
+ interface EmotionSpecialResults {
88
+ by_emotion: any[];
89
+ confusion_matrix: any;
90
+ }
91
+
92
+ interface NbackResultsStructure {
93
+ common: CommonResults;
94
+ special: NbackSpecialResults;
95
+ }
96
+
97
+ interface SpatialResultsStructure {
98
+ common: CommonResults;
99
+ special: SpatialSpecialResults;
100
+ }
101
+
102
+ interface GonogoResultsStructure {
103
+ common: CommonResults;
104
+ special: GonogoSpecialResults;
105
+ }
106
+
107
+ interface EmotionResultsStructure {
108
+ common: CommonResults;
109
+ special: EmotionSpecialResults;
110
+ }
111
+
112
+ export {
113
+ CommonResults,
114
+ NbackResultsStructure,
115
+ SpatialResultsStructure,
116
+ GonogoResultsStructure,
117
+ EmotionResultsStructure,
118
+ NbackSpecialResults,
119
+ NbackGroupResults,
120
+ NbackBlockResults,
121
+ NbackLevelResults,
122
+ SpatialSpecialResults,
123
+ GonogoSpecialResults,
124
+ EmotionSpecialResults
79
125
  };
package/src/emotions.ts CHANGED
@@ -1,98 +1,98 @@
1
- import { EmotionResultsStructure, CommonResults, EmotionSpecialResults } from './common-interfaces';
2
-
3
- const EMOTION_MAP = ["neutral", "sad", "happy", "surprised", "angry"];
4
-
5
- const emotion_calculate_results = (obj: any[]): EmotionResultsStructure => {
6
- const trials = emotion_extract_trials(obj);
7
- if (trials.length === 0) {
8
- throw new Error("No trials found");
9
- }
10
- return emotion_results(trials);
11
- };
12
-
13
- const emotion_extract_trials = (obj: any[]) => {
14
- // filter trials where response and rt are defined and not null
15
- let trials = obj.filter((o: any) => 'response' in o && 'rt' in o && 'emotion' in o);
16
- trials = trials.filter((o: any) => o.response !== null && o.rt !== null);
17
- trials.forEach((o: any) => {
18
- const match = o.emotion.match(/\/([^/]+)_([0-9]+)\.png/);
19
- if (match) {
20
- o.stimulus = match[0];
21
- o.emotion = match[1];
22
- o.image_number = match[2];
23
- //this is <emotion>_<number>.png
24
- o.image = `${match[1]}_${match[2]}.png`;
25
- }
26
- })
27
- trials.forEach((o: any) => {
28
- o.emotion_response = EMOTION_MAP[o.response] || "unknown";
29
- o.correct = o.emotion === o.emotion_response;
30
- // in the older ones there were 15 trials per rotation
31
- });
32
- return trials;
33
- }
34
-
35
- const emotion_results = (obj: any[]): EmotionResultsStructure => {
36
- if (obj.length === 0) {
37
- throw new Error("No trials found");
38
- }
39
-
40
- const correct_trials = obj.filter((o: any) => o.correct === true);
41
- const incorrect_trials = obj.filter((o: any) => o.correct === false);
42
-
43
- const total_rt = obj.reduce((a, b) => a + (b.rt || 0), 0);
44
- const correct_rt = correct_trials.reduce((a, b) => a + (b.rt || 0), 0);
45
- const incorrect_rt = incorrect_trials.reduce((a, b) => a + (b.rt || 0), 0);
46
-
47
- const avg_rt = total_rt / obj.length;
48
- const avg_acc = correct_trials.length / obj.length;
49
-
50
- // Calculate performance score using the existing formula
51
- const best_score = 1000;
52
- const worst_score = 10000;
53
- let performance = avg_rt / (Math.pow(avg_acc, 5) + 0.001);
54
- performance = Math.min(Math.max(performance, best_score), worst_score);
55
- const performance_score = (1 - ((performance - best_score) / (worst_score - best_score))) * 100;
56
-
57
- const common: CommonResults = {
58
- n_trials: obj.length,
59
- n_correct_trials: correct_trials.length,
60
- n_incorrect_trials: incorrect_trials.length,
61
- avg_rt_total: avg_rt,
62
- avg_rt_correct: correct_trials.length > 0 ? correct_rt / correct_trials.length : 0,
63
- avg_rt_incorrect: incorrect_trials.length > 0 ? incorrect_rt / incorrect_trials.length : 0,
64
- performance_score
65
- };
66
-
67
- // Group by emotion for special results
68
- const by_emotion = EMOTION_MAP.map(emotion => {
69
- const emotion_trials = obj.filter((o: any) => o.emotion === emotion);
70
- return {
71
- emotion,
72
- n: emotion_trials.length,
73
- avg_rt: emotion_trials.length > 0 ? emotion_trials.reduce((a, b) => a + (b.rt || 0), 0) / emotion_trials.length : 0,
74
- avg_acc: emotion_trials.length > 0 ? emotion_trials.reduce((a, b) => a + (b.correct ? 1 : 0), 0) / emotion_trials.length : 0,
75
- };
76
- });
77
-
78
- // Create confusion matrix
79
- const confusion_matrix = EMOTION_MAP.reduce((matrix: any, actual: string) => {
80
- matrix[actual] = EMOTION_MAP.reduce((row: any, predicted: string) => {
81
- row[predicted] = obj.filter((o: any) => o.emotion === actual && o.emotion_response === predicted).length;
82
- return row;
83
- }, {});
84
- return matrix;
85
- }, {});
86
-
87
- const special: EmotionSpecialResults = {
88
- by_emotion,
89
- confusion_matrix
90
- };
91
-
92
- return {
93
- common,
94
- special
95
- };
96
- }
97
-
98
- export {EmotionResultsStructure, emotion_calculate_results, emotion_extract_trials, emotion_results};
1
+ import { EmotionResultsStructure, CommonResults, EmotionSpecialResults } from './common-interfaces';
2
+
3
+ const EMOTION_MAP = ["neutral", "sad", "happy", "surprised", "angry"];
4
+
5
+ const emotion_calculate_results = (obj: any[]): EmotionResultsStructure => {
6
+ const trials = emotion_extract_trials(obj);
7
+ if (trials.length === 0) {
8
+ throw new Error("No trials found");
9
+ }
10
+ return emotion_results(trials);
11
+ };
12
+
13
+ const emotion_extract_trials = (obj: any[]) => {
14
+ // filter trials where response and rt are defined and not null
15
+ let trials = obj.filter((o: any) => 'response' in o && 'rt' in o && 'emotion' in o);
16
+ trials = trials.filter((o: any) => o.response !== null && o.rt !== null);
17
+ trials.forEach((o: any) => {
18
+ const match = o.emotion.match(/\/([^/]+)_([0-9]+)\.png/);
19
+ if (match) {
20
+ o.stimulus = match[0];
21
+ o.emotion = match[1];
22
+ o.image_number = match[2];
23
+ //this is <emotion>_<number>.png
24
+ o.image = `${match[1]}_${match[2]}.png`;
25
+ }
26
+ })
27
+ trials.forEach((o: any) => {
28
+ o.emotion_response = EMOTION_MAP[o.response] || "unknown";
29
+ o.correct = o.emotion === o.emotion_response;
30
+ // in the older ones there were 15 trials per rotation
31
+ });
32
+ return trials;
33
+ }
34
+
35
+ const emotion_results = (obj: any[]): EmotionResultsStructure => {
36
+ if (obj.length === 0) {
37
+ throw new Error("No trials found");
38
+ }
39
+
40
+ const correct_trials = obj.filter((o: any) => o.correct === true);
41
+ const incorrect_trials = obj.filter((o: any) => o.correct === false);
42
+
43
+ const total_rt = obj.reduce((a, b) => a + (b.rt || 0), 0);
44
+ const correct_rt = correct_trials.reduce((a, b) => a + (b.rt || 0), 0);
45
+ const incorrect_rt = incorrect_trials.reduce((a, b) => a + (b.rt || 0), 0);
46
+
47
+ const avg_rt = total_rt / obj.length;
48
+ const avg_acc = correct_trials.length / obj.length;
49
+
50
+ // Calculate performance score using the existing formula
51
+ const best_score = 1000;
52
+ const worst_score = 10000;
53
+ let performance = avg_rt / (Math.pow(avg_acc, 5) + 0.001);
54
+ performance = Math.min(Math.max(performance, best_score), worst_score);
55
+ const performance_score = (1 - ((performance - best_score) / (worst_score - best_score))) * 100;
56
+
57
+ const common: CommonResults = {
58
+ n_trials: obj.length,
59
+ n_correct_trials: correct_trials.length,
60
+ n_incorrect_trials: incorrect_trials.length,
61
+ avg_rt_total: avg_rt,
62
+ avg_rt_correct: correct_trials.length > 0 ? correct_rt / correct_trials.length : 0,
63
+ avg_rt_incorrect: incorrect_trials.length > 0 ? incorrect_rt / incorrect_trials.length : 0,
64
+ performance_score
65
+ };
66
+
67
+ // Group by emotion for special results
68
+ const by_emotion = EMOTION_MAP.map(emotion => {
69
+ const emotion_trials = obj.filter((o: any) => o.emotion === emotion);
70
+ return {
71
+ emotion,
72
+ n: emotion_trials.length,
73
+ avg_rt: emotion_trials.length > 0 ? emotion_trials.reduce((a, b) => a + (b.rt || 0), 0) / emotion_trials.length : 0,
74
+ avg_acc: emotion_trials.length > 0 ? emotion_trials.reduce((a, b) => a + (b.correct ? 1 : 0), 0) / emotion_trials.length : 0,
75
+ };
76
+ });
77
+
78
+ // Create confusion matrix
79
+ const confusion_matrix = EMOTION_MAP.reduce((matrix: any, actual: string) => {
80
+ matrix[actual] = EMOTION_MAP.reduce((row: any, predicted: string) => {
81
+ row[predicted] = obj.filter((o: any) => o.emotion === actual && o.emotion_response === predicted).length;
82
+ return row;
83
+ }, {});
84
+ return matrix;
85
+ }, {});
86
+
87
+ const special: EmotionSpecialResults = {
88
+ by_emotion,
89
+ confusion_matrix
90
+ };
91
+
92
+ return {
93
+ common,
94
+ special
95
+ };
96
+ }
97
+
98
+ export {EmotionResultsStructure, emotion_calculate_results, emotion_extract_trials, emotion_results};
package/src/getters.ts CHANGED
@@ -1,21 +1,21 @@
1
- function getBrowserInformation(data: any[]): any {
2
- const browserInfo = data.find(row => row.trial_type === "browser-check");
3
- if (!browserInfo) {
4
- return null;
5
- }
6
- return {
7
- os: browserInfo.os,
8
- mobile: browserInfo.mobile,
9
- fullscreen: browserInfo.fullscreen,
10
- vsync_rate: browserInfo.vsync_rate,
11
- webcam: browserInfo.webcam,
12
- microphone: browserInfo.microphone,
13
- browser: browserInfo.browser,
14
- browser_version: browserInfo.browser_version,
15
- webaudio: browserInfo.webaudio,
16
- width: browserInfo.width,
17
- height: browserInfo.height
18
- };
19
- }
20
-
21
- export { getBrowserInformation };
1
+ function getBrowserInformation(data: any[]): any {
2
+ const browserInfo = data.find(row => row.trial_type === "browser-check");
3
+ if (!browserInfo) {
4
+ return null;
5
+ }
6
+ return {
7
+ os: browserInfo.os,
8
+ mobile: browserInfo.mobile,
9
+ fullscreen: browserInfo.fullscreen,
10
+ vsync_rate: browserInfo.vsync_rate,
11
+ webcam: browserInfo.webcam,
12
+ microphone: browserInfo.microphone,
13
+ browser: browserInfo.browser,
14
+ browser_version: browserInfo.browser_version,
15
+ webaudio: browserInfo.webaudio,
16
+ width: browserInfo.width,
17
+ height: browserInfo.height
18
+ };
19
+ }
20
+
21
+ export { getBrowserInformation };