';
showAlert(
errorMessage,
- 'Click here to retry',
+ translator.t('buttons.clickRetry'),
function () {
frameSequence.unshift(frame);
showFrame('null');
@@ -89,8 +102,8 @@ export function render(onComplete) {
frameSequence.unshift(frame);
showAlert(
- 'Please respond as quickly as you can.
' + 'Click the left or right button.
',
- 'Click here to retry',
+ translator.t('timeout.message') + '
',
+ translator.t('buttons.clickRetry'),
function () {
showFrame('null');
setTimeout(function () {
@@ -117,7 +130,7 @@ export function render(onComplete) {
if (frame.type === 'begin')
showAlert(
frame.message,
- 'Click here for instructions',
+ translator.t('buttons.clickInstructions'),
function () {
nextTrial();
},
@@ -127,7 +140,7 @@ export function render(onComplete) {
else if (frame.type === 'message')
showAlert(
frame.message,
- 'Click here to continue',
+ translator.t('buttons.clickContinue'),
function () {
showFrame('null');
nextTrial();
@@ -141,7 +154,9 @@ export function render(onComplete) {
function () {
requestAnimationFrame(function () {
getID('sequence').innerHTML = frame.LN;
- getID('judgement').innerHTML = frame.judgement.toString().toUpperCase();
+ getID('judgement').innerHTML = frame.judgement
+ ? translator.t('judgement.' + frame.judgement).toUpperCase()
+ : '';
showFrame(null);
});
},
@@ -244,40 +259,33 @@ export function render(onComplete) {
// for a single trial/frame
function setFrameSequence() {
var TestMessage;
+ var instructionsHeading = '
' + translator.t('instructions.heading') + '
';
TestMessage = {
- begin: '
Letter/Number Switching
' + "
",
+ begin: '
' + translator.t('instructions.title') + '
' + "
",
instructions: [
- '
Instructions
' +
+ instructionsHeading +
"
" +
- 'Here your job is to report ' +
- 'either the number or the letter ' +
- 'in this letter/number pair.
',
- '
Instructions
' +
+ translator.t('instructions.step1') +
+ '
',
+ instructionsHeading +
"
" +
- 'The word above the letter-number pair ' +
- 'tells you what to report ' +
- "(here it's the number).
",
- '
Instructions
' +
+ translator.t('instructions.step2') +
+ '
',
+ instructionsHeading +
"
" +
- 'To report the number 1, you click ' +
- 'the button that has that number (left).
',
- '
Instructions
' +
+ translator.t('instructions.step3') +
+ '
',
+ instructionsHeading +
"
" +
- 'To report the letter z, you click ' +
- 'the button that has that letter (right).
',
- '
Instructions
' +
+ translator.t('instructions.step4') +
+ '
',
+ instructionsHeading +
"
" +
- "Let's do some practice.
",
- 'Excellent! ' + 'You have completed the practice.
' +
- 'Look at the word on top, then ' +
- 'click the button that has ' +
- 'the letter or number in the pair below.
' +
- 'Please try to be QUICK, ' +
- 'but also ACCURATE.
'
- ]
+ test: [translator.t('test.remember') + '
']
};
// type of frame to display
diff --git a/lib/interactive/TMB_LN_SWITCHING/translator.ts b/lib/interactive/TMB_LN_SWITCHING/translator.ts
new file mode 100644
index 0000000..382d932
--- /dev/null
+++ b/lib/interactive/TMB_LN_SWITCHING/translator.ts
@@ -0,0 +1,90 @@
+import { Translator } from '/runtime/v1/@opendatacapture/runtime-core';
+
+export const translator = new Translator({
+ translations: {
+ buttons: {
+ clickContinue: {
+ en: 'Click here to continue',
+ fr: 'Cliquez ici pour continuer'
+ },
+ clickInstructions: {
+ en: 'Click here for instructions',
+ fr: 'Cliquez ici pour les instructions'
+ },
+ clickRetry: {
+ en: 'Click here to retry',
+ fr: 'Cliquez ici pour réessayer'
+ }
+ },
+ judgement: {
+ letter: {
+ en: 'letter',
+ fr: 'lettre'
+ },
+ number: {
+ en: 'number',
+ fr: 'chiffre'
+ }
+ },
+ practiceError: {
+ target: {
+ en: 'Your target was the {judgement} {target}:',
+ fr: 'Votre cible était : {judgement} {target}'
+ },
+ shouldRight: {
+ en: 'you should have clicked the right button.',
+ fr: 'vous auriez dû cliquer sur le bouton de droite.'
+ },
+ shouldLeft: {
+ en: 'you should have clicked the left button.',
+ fr: 'vous auriez dû cliquer sur le bouton de gauche.'
+ }
+ },
+ timeout: {
+ message: {
+ en: 'Please respond as quickly as you can.
Click the left or right button.',
+ fr: 'Veuillez répondre aussi vite que possible.
Cliquez sur le bouton de gauche ou de droite.'
+ }
+ },
+ instructions: {
+ title: {
+ en: 'Letter/Number Switching',
+ fr: 'Alternance lettres/chiffres'
+ },
+ heading: {
+ en: 'Instructions',
+ fr: 'Instructions'
+ },
+ step1: {
+ en: 'Here your job is to report either the number or the letter in this letter/number pair.',
+ fr: 'Ici, votre tâche est de rapporter soit le chiffre, soit la lettre de cette paire lettre/chiffre.'
+ },
+ step2: {
+ en: 'The word above the letter-number pair tells you what to report (here it’s the number).',
+ fr: 'Le mot au-dessus de la paire lettre-chiffre vous indique quoi rapporter (ici, c’est le chiffre).'
+ },
+ step3: {
+ en: 'To report the number 1, you click the button that has that number (left).',
+ fr: 'Pour rapporter le chiffre 1, vous cliquez sur le bouton qui contient ce chiffre (gauche).'
+ },
+ step4: {
+ en: 'To report the letter z, you click the button that has that letter (right).',
+ fr: 'Pour rapporter la lettre z, vous cliquez sur le bouton qui contient cette lettre (droite).'
+ },
+ letsPractice: {
+ en: 'Let’s do some practice.',
+ fr: 'Faisons quelques essais d’entraînement.'
+ },
+ excellent: {
+ en: 'Excellent! You have completed the practice.
Now let’s do more.',
+ fr: 'Excellent ! Vous avez terminé l’entraînement.
Passons à la suite.'
+ }
+ },
+ test: {
+ remember: {
+ en: 'Remember!
Look at the word on top, then click the button that has the letter or number in the pair below.
Please try to be QUICK, but also ACCURATE.',
+ fr: 'Rappel !
Regardez le mot en haut, puis cliquez sur le bouton qui contient la lettre ou le chiffre de la paire ci-dessous.
Essayez d’être RAPIDE, mais aussi PRÉCIS.'
+ }
+ }
+ }
+});
diff --git a/lib/interactive/TMB_MOT/TestMyBrain.12.18.min.js b/lib/interactive/TMB_MOT/TestMyBrain.12.18.min.js
index bdd2350..6616145 100644
--- a/lib/interactive/TMB_MOT/TestMyBrain.12.18.min.js
+++ b/lib/interactive/TMB_MOT/TestMyBrain.12.18.min.js
@@ -56,7 +56,6 @@ function showFrame() {
for (
tmbObjs.frames.length || (tmbObjs.frames = document.getElementsByTagName('div')), t = tmbObjs.frames.length;
t--;
-
)
((e = n.indexOf(tmbObjs.frames[t].id) > -1 ? 'block' : 'none'),
tmbObjs.frames[t].style.display !== e && (tmbObjs.frames[t].style.display = e));
@@ -70,7 +69,6 @@ function showFrameClass() {
for (
tmbObjs.frames.length || (tmbObjs.frames = document.getElementsByTagName('div')), t = tmbObjs.frames.length;
t--;
-
)
((e = n.indexOf(tmbObjs.frames[t].className) > -1 ? 'block' : 'none'),
tmbObjs.frames[t].style.display !== e && (tmbObjs.frames[t].style.display = e));
@@ -517,7 +515,6 @@ function imagePreLoad(e, t) {
(t.addEventListener('load', c, !0), t.addEventListener('error', c, !0), (t.id = e), (t.src = e));
};
l > 0;
-
)
(l--, d(n.shift()));
}
@@ -3362,7 +3359,6 @@ var saveTextAs =
s = void 0 === a ? n : a >> 0,
u = 0 > s ? Math.max(n + s, 0) : Math.min(s, n);
u > i;
-
)
((t[i] = e), i++);
return t;
@@ -3472,7 +3468,6 @@ var zen = tmbObjs,
r = n.length,
o = (window.console = window.console || {});
r--;
-
)
((e = n[r]), o[e] || (o[e] = t));
})(),
diff --git a/lib/interactive/TMB_MOT/index.ts b/lib/interactive/TMB_MOT/index.ts
index 5ed9afd..c76eec4 100644
--- a/lib/interactive/TMB_MOT/index.ts
+++ b/lib/interactive/TMB_MOT/index.ts
@@ -22,8 +22,11 @@ const staticAssets = {
export default defineInstrument({
kind: 'INTERACTIVE',
- language: 'en',
- tags: ['TestMyBrain'],
+ language: ['en', 'fr'],
+ tags: {
+ en: ['TestMyBrain'],
+ fr: ['TestMyBrain']
+ },
internal: {
edition: 1,
name: 'TMB_MOT'
@@ -43,16 +46,27 @@ export default defineInstrument({
},
render,
html,
- staticAssets
+ staticAssets,
+ enableLanguageLock: true,
+ enableLanguageSelect: true
},
clientDetails: {
estimatedDuration: 1,
- instructions: ['Instructions will be presented on screen in the task.']
+ instructions: {
+ en: ['Instructions will be presented on screen in the task.'],
+ fr: ["Les instructions seront présentées à l'écran pendant la tâche."]
+ }
},
details: {
- description: 'An attention task that measures the ability to track multiple moving objects simultaneously.',
+ description: {
+ en: 'An attention task that measures the ability to track multiple moving objects simultaneously.',
+ fr: 'Une tâche attentionnelle qui mesure la capacité à suivre simultanément plusieurs objets en mouvement.'
+ },
license: 'LGPL-3.0',
- title: 'TMB Multiple Object Tracking'
+ title: {
+ en: 'TMB Multiple Object Tracking',
+ fr: 'TMB Suivi d’objets multiples'
+ }
},
measures: {},
validationSchema: z.any()
diff --git a/lib/interactive/TMB_MOT/render.js b/lib/interactive/TMB_MOT/render.js
index 4e4e811..732470d 100644
--- a/lib/interactive/TMB_MOT/render.js
+++ b/lib/interactive/TMB_MOT/render.js
@@ -1,7 +1,19 @@
// @ts-nocheck
/* eslint-disable */
+import { translator } from './translator.ts';
+
export function render(done) {
+ translator.init();
+
+ function tFormat(key, vars) {
+ var s = translator.t(key);
+ if (vars) {
+ for (var k in vars) s = s.replace(new RegExp('\\{' + k + '\\}', 'g'), vars[k]);
+ }
+ return s;
+ }
+
var circle = []; // Array of SVG circles objects
var happy = []; // array of happy targets
var sad = []; // array of sad targets
@@ -54,15 +66,17 @@ export function render(done) {
function beginNoPractice() {
showAlert(
"
';
// deal with practice errors
if (targetClicks < numTargets) {
@@ -415,12 +430,7 @@ export function render(done) {
// rewind the trials chain by one
frameSequence.unshift(frame);
- msg =
- "
Let's try again.
" +
- 'When the movement stops, ' +
- 'click the ' +
- numTargets +
- ' dots that flashed.
' +
- 'Next time, when the movement stops, ' +
- 'click the 2 dots that flashed.
' +
- 'The other dots have ' +
- 'red sad faces behind them. ' +
+ '
' +
+ translator.t('instructions.heading') +
+ '
' +
+ translator.t('instructions.practiceClickTwo') +
+ ' ' +
' ' +
- 'Try not to click on those.
',
- practice3: '
Good!
' + "Now we'll do the same thing with " + '3 flashing dots.
',
- targets3:
- '
Great!
' +
- "Now we'll do 6 more with 3 dots. " +
- 'Motion is slow at first, then gets faster. ' +
- 'This will be the first of 3 parts.
' +
- 'When you lose track of dots, just guess. ' +
- 'Your score will be the total number of ' +
- 'green smiles that you click.
',
- targets3_noPrac:
- 'The first part of the test has 3 flashing dots. ' +
- 'Motion is slow at first, then gets faster. ' +
- 'This will be the first of 3 parts.
' +
- 'When you lose track of dots, just guess. ' +
- 'Your score will be the total number of ' +
- 'green smiles that you click.
',
- targets4:
- ' Excellent!
' +
- 'You have finished the first part of this test. ' +
- '' +
- 'There are two parts left.
' +
- 'The next part has 4 flashing dots. ' +
- 'Motion is slow at first, then gets faster.
' +
- 'When you lose track of dots, just guess. ' +
- 'Every smile you click adds to your score!
',
- targets5:
- ' Outstanding!
' +
- 'Now there is only one part left!
' +
- 'The final part has 5 flashing dots! ' +
- 'Motion is slow at first, then gets faster.
' +
- 'When you lose track of dots, just guess. ' +
- 'Every smile you click adds to your score!
',
- emaTargets5:
- 'You will do this task ' +
- 'with 5 flashing dots! ' +
- 'Motion is slow at first, then gets faster.
' +
- 'When you lose track of dots, just guess. ' +
- 'Every smile you click adds to your score!
',
- noprac: 'Remember:
' + 'Click on the dots with the green ' + 'smiley faces behind them.
'
};
// set the random generator's seed
diff --git a/lib/interactive/TMB_MOT/snap.0.5.1.min.js b/lib/interactive/TMB_MOT/snap.0.5.1.min.js
index b246e3e..b892d9e 100644
--- a/lib/interactive/TMB_MOT/snap.0.5.1.min.js
+++ b/lib/interactive/TMB_MOT/snap.0.5.1.min.js
@@ -1440,7 +1440,6 @@
k = g.toTransformString(),
l = m(g) == m(this.matrix) ? m(b.transform) : k;
'svg' != e.type && (e = e.parent());
-
)
i.push(h(e));
for (d = i.length; d--; ) j.add(i[d]);
@@ -2134,7 +2133,6 @@
return (b.normalize && b.normalize(), b);
};
c.firstChild;
-
)
c.removeChild(c.firstChild);
for (var f = d(a); f.firstChild; ) c.appendChild(f.firstChild);
@@ -3411,7 +3409,6 @@
},
k = 0;
1e6 >= g && !k;
-
) {
for (var l = 0, n = d.length; n > l; l++) {
var o = j(l);
@@ -3781,7 +3778,6 @@
},
r = i.length;
r--;
-
)
!(function (b) {
((a[b] = f[b] =
diff --git a/lib/interactive/TMB_MOT/translator.ts b/lib/interactive/TMB_MOT/translator.ts
new file mode 100644
index 0000000..2ad9f4b
--- /dev/null
+++ b/lib/interactive/TMB_MOT/translator.ts
@@ -0,0 +1,114 @@
+import { Translator } from '/runtime/v1/@opendatacapture/runtime-core';
+
+export const translator = new Translator({
+ translations: {
+ optionalPractice: {
+ intro: {
+ en: 'You are about to take: TMB Multiple Object Tracking.
If you have taken this test before, please choose whether to:',
+ fr: 'Vous êtes sur le point de passer : TMB Suivi d’objets multiples.
Si vous avez déjà passé ce test, veuillez choisir :'
+ },
+ skip: {
+ en: 'Skip the practice trials',
+ fr: 'Sauter les essais d’entraînement'
+ },
+ retake: {
+ en: 'Re-take the practice trials',
+ fr: 'Refaire les essais d’entraînement'
+ }
+ },
+ buttons: {
+ clickContinue: {
+ en: 'Click here to continue',
+ fr: 'Cliquez ici pour continuer'
+ },
+ clickInstructions: {
+ en: 'Click here for instructions',
+ fr: 'Cliquez ici pour les instructions'
+ },
+ clickRetry: {
+ en: 'Click here to retry',
+ fr: 'Cliquez ici pour réessayer'
+ }
+ },
+ trial: {
+ score: {
+ en: 'Score',
+ fr: 'Score'
+ },
+ trialOf: {
+ en: '{n} of 6',
+ fr: '{n} sur 6'
+ },
+ youGot: {
+ en: 'You got {hits} of {total} dots correct.',
+ fr: 'Vous avez identifié correctement {hits} points sur {total}.'
+ },
+ tryAgain: {
+ en: 'Let’s try again.
When the movement stops, click the {n} dots that flashed.',
+ fr: 'Essayons à nouveau.
Lorsque le mouvement s’arrête, cliquez sur les {n} points qui ont clignoté.'
+ },
+ tookTooLong: {
+ en: 'You took too long to respond!
Remember: once the movement stops, click the dots that flashed.',
+ fr: 'Vous avez mis trop de temps à répondre !
Rappel : une fois le mouvement arrêté, cliquez sur les points qui ont clignoté.'
+ },
+ clickFlashedPractice: {
+ en: 'Click the {n} dots that flashed!',
+ fr: 'Cliquez sur les {n} points qui ont clignoté !'
+ },
+ clickDots: {
+ en: 'Click {n} dots',
+ fr: 'Cliquez sur {n} points'
+ }
+ },
+ instructions: {
+ title: {
+ en: 'Splitting Your Attention',
+ fr: 'Diviser votre attention'
+ },
+ heading: {
+ en: 'Instructions:',
+ fr: 'Instructions :'
+ },
+ keepTrack: {
+ en: 'Keep track of the dots that flash, they have green smiles behind them.',
+ fr: 'Suivez les points qui clignotent, ils ont un sourire vert derrière eux.'
+ },
+ practiceClickTwo: {
+ en: 'Next time, when the movement stops, click the 2 dots that flashed.
The other dots have red sad faces behind them.',
+ fr: 'La prochaine fois, lorsque le mouvement s’arrête, cliquez sur les 2 points qui ont clignoté.
Les autres points ont un visage triste rouge derrière eux.'
+ },
+ tryNotToClick: {
+ en: 'Try not to click on those.',
+ fr: 'Essayez de ne pas cliquer sur ceux-là.'
+ },
+ good3Dots: {
+ en: 'Good!
Now we’ll do the same thing with 3 flashing dots.',
+ fr: 'Bien !
Nous allons maintenant faire la même chose avec 3 points clignotants.'
+ },
+ targets3: {
+ en: 'Great!
Now we’ll do 6 more with 3 dots. Motion is slow at first, then gets faster. This will be the first of 3 parts.
When you lose track of dots, just guess. Your score will be the total number of green smiles that you click.',
+ fr: 'Super !
Nous allons maintenant en faire 6 autres avec 3 points. Le mouvement est lent au début, puis s’accélère. Ce sera la première des 3 parties.
Lorsque vous perdez les points de vue, devinez simplement. Votre score sera le nombre total de sourires verts sur lesquels vous cliquez.'
+ },
+ targets3NoPrac: {
+ en: 'The first part of the test has 3 flashing dots. Motion is slow at first, then gets faster. This will be the first of 3 parts.
When you lose track of dots, just guess. Your score will be the total number of green smiles that you click.',
+ fr: 'La première partie du test comporte 3 points clignotants. Le mouvement est lent au début, puis s’accélère. Ce sera la première des 3 parties.
Lorsque vous perdez les points de vue, devinez simplement. Votre score sera le nombre total de sourires verts sur lesquels vous cliquez.'
+ },
+ targets4: {
+ en: 'Excellent!
You have finished the first part of this test. There are two parts left.
The next part has 4 flashing dots. Motion is slow at first, then gets faster.
When you lose track of dots, just guess. Every smile you click adds to your score!',
+ fr: 'Excellent !
Vous avez terminé la première partie de ce test. Il reste deux parties.
La partie suivante comporte 4 points clignotants. Le mouvement est lent au début, puis s’accélère.
Lorsque vous perdez les points de vue, devinez simplement. Chaque sourire sur lequel vous cliquez augmente votre score !'
+ },
+ targets5: {
+ en: 'Outstanding!
Now there is only one part left!
The final part has 5 flashing dots! Motion is slow at first, then gets faster.
When you lose track of dots, just guess. Every smile you click adds to your score!',
+ fr: 'Remarquable !
Il ne reste plus qu’une partie !
La dernière partie comporte 5 points clignotants ! Le mouvement est lent au début, puis s’accélère.
Lorsque vous perdez les points de vue, devinez simplement. Chaque sourire sur lequel vous cliquez augmente votre score !'
+ },
+ emaTargets5: {
+ en: 'You will do this task with 5 flashing dots! Motion is slow at first, then gets faster.
When you lose track of dots, just guess. Every smile you click adds to your score!',
+ fr: 'Vous ferez cette tâche avec 5 points clignotants ! Le mouvement est lent au début, puis s’accélère.
Lorsque vous perdez les points de vue, devinez simplement. Chaque sourire sur lequel vous cliquez augmente votre score !'
+ },
+ noprac: {
+ en: 'Remember:
Click on the dots with the green smiley faces behind them.',
+ fr: 'Rappel :
Cliquez sur les points ayant un visage souriant vert derrière eux.'
+ }
+ }
+ }
+});