]> _ Git - fluidbook-toolbox-quiz.git/commitdiff
wip #6195 @0.5
authorVincent Vanwaelscappel <vincent@cubedesigners.com>
Wed, 16 Aug 2023 12:00:26 +0000 (14:00 +0200)
committerVincent Vanwaelscappel <vincent@cubedesigners.com>
Wed, 16 Aug 2023 12:00:26 +0000 (14:00 +0200)
32 files changed:
.idea/.gitignore [new file with mode: 0644]
.idea/misc.xml [new file with mode: 0644]
animations/NOK.json [new file with mode: 0644]
animations/OK.json [new file with mode: 0644]
js/quiz.animations.js [new file with mode: 0644]
js/quiz.js [new file with mode: 0644]
js/quiz.question.js [new file with mode: 0644]
js/quiz.resize.js [new file with mode: 0644]
js/quiz.score.js [new file with mode: 0644]
js/quiz.scorm.js [new file with mode: 0644]
style/001-global-variables.sass [new file with mode: 0644]
style/002-item-variables.sass [new file with mode: 0644]
style/003-reset.sass [new file with mode: 0644]
style/004-mixins.sass [new file with mode: 0644]
style/005-utilities.sass [new file with mode: 0644]
style/100-global.sass [new file with mode: 0644]
style/101-header-footer.sass [new file with mode: 0644]
style/102-intro.sass [new file with mode: 0644]
style/103-question-multiple.sass [new file with mode: 0644]
style/104-animations.sass [new file with mode: 0644]
style/105-outro.sass [new file with mode: 0644]
style/106-question-draganddrop.sass [new file with mode: 0644]
style/style.sass [new file with mode: 0644]
views/footer.blade.php [new file with mode: 0644]
views/header_question.blade.php [new file with mode: 0644]
views/header_title.blade.php [new file with mode: 0644]
views/index.blade.php [new file with mode: 0644]
views/screens/intro.blade.php [new file with mode: 0644]
views/screens/outro.blade.php [new file with mode: 0644]
views/screens/question_draganddrop.blade.php [new file with mode: 0644]
views/screens/question_multiple.blade.php [new file with mode: 0644]
views/sprite.blade.php [new file with mode: 0644]

diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644 (file)
index 0000000..13566b8
--- /dev/null
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644 (file)
index 0000000..ceefc72
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="AhkProjectSettings">
+    <option name="defaultAhkSdk" value="AutoHotkey" />
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" />
+</project>
\ No newline at end of file
diff --git a/animations/NOK.json b/animations/NOK.json
new file mode 100644 (file)
index 0000000..b006dd0
--- /dev/null
@@ -0,0 +1 @@
+{"v":"5.9.0","fr":60,"ip":0,"op":310,"w":500,"h":500,"nm":"WRONG_anim","ddd":0,"assets":[],"fonts":{"list":[{"origin":3,"fPath":"images/font_0","fClass":"","fFamily":"Source Sans Pro","fWeight":"","fStyle":"SemiBold","fName":"SourceSansPro-SemiBold","ascent":70.599365234375}]},"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Nul 1","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[0.626,0.626,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.155,0.155,0]},"t":20,"s":[85,85,100]},{"i":{"x":[0,0,0.667],"y":[1,1,1]},"o":{"x":[0.501,0.501,0.333],"y":[0.189,0.189,0]},"t":110,"s":[90,90,100]},{"t":170,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":296,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Calque de forme 1","parent":4,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[82.25,82.25,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-32.25,-32.312],[32,31.938],[32.25,-31.812],[-32,32.438]],"c":false},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0.623528992896,0.992156982422,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":12,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Contour 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Forme 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":40,"s":[0]},{"t":110,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Réduire les tracés 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[1],"y":[0]},"t":266,"s":[100]},{"t":296,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Réduire les tracés 2","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":40,"op":296,"st":40,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"VALIDATE_X Silhouettes","parent":4,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[82.25,82.25,0],"ix":2,"l":2},"a":{"a":0,"k":[35.605,35.605,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-26.87,-35.355],[35.355,26.87],[26.87,35.355],[-35.355,-26.87]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[35.605,35.606],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Groupe 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-35.355,26.87],[26.87,-35.355],[35.355,-26.87],[-26.871,35.355]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[35.605,35.605],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Groupe 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":40,"op":296,"st":40,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"VALIDATE_CIRCLEW Silhouettes","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[82.25,82.25,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,1]},"o":{"x":[0.576,0.576,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":20,"s":[100,100,100]},{"i":{"x":[0.973,0.973,0.667],"y":[1.001,1.001,1]},"o":{"x":[0.813,0.813,0.333],"y":[0,0,0]},"t":274,"s":[100,100,100]},{"t":296,"s":[0,0,100]}],"ix":6,"l":2,"x":"var $bm_rt;\nvar n, n, t, t, v, amp, freq, decay;\n$bm_rt = n = 0;\nif (numKeys > 0) {\n    $bm_rt = n = nearestKey(time).index;\n    if (key(n).time > time) {\n        n--;\n    }\n}\nif (n == 0) {\n    $bm_rt = t = 0;\n} else {\n    $bm_rt = t = $bm_sub(time, key(n).time);\n}\nif (n > 0 && t < 1) {\n    v = velocityAtTime($bm_sub(key(n).time, $bm_div(thisComp.frameDuration, 10)));\n    amp = 0.03;\n    freq = 3;\n    decay = 10;\n    $bm_rt = $bm_sum(value, $bm_div($bm_mul($bm_mul(v, amp), Math.sin($bm_mul($bm_mul($bm_mul(freq, t), 2), Math.PI))), Math.exp($bm_mul(decay, t))));\n} else {\n    $bm_rt = value;\n}"}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-45.287,0],[0,-45.287],[45.287,0],[0,45.287]],"o":[[45.287,0],[0,45.287],[-45.287,0],[0,-45.287]],"v":[[0,-82],[82,0],[0,82],[-82,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.815686334348,0.086274509804,0.486274539723,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[82.25,82.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Groupe 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":296,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"VALIDATE_CIRCLE2 Silhouettes","parent":4,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[82.25,82.25,0],"ix":2,"l":2},"a":{"a":0,"k":[90.25,90.25,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,1]},"o":{"x":[0.552,0.552,0.333],"y":[0,0,0]},"t":16,"s":[89,89,100]},{"t":28,"s":[100,100,100]}],"ix":6,"l":2,"x":"var $bm_rt;\nvar n, n, t, t, v, amp, freq, decay;\n$bm_rt = n = 0;\nif (numKeys > 0) {\n    $bm_rt = n = nearestKey(time).index;\n    if (key(n).time > time) {\n        n--;\n    }\n}\nif (n == 0) {\n    $bm_rt = t = 0;\n} else {\n    $bm_rt = t = $bm_sub(time, key(n).time);\n}\nif (n > 0 && t < 1) {\n    v = velocityAtTime($bm_sub(key(n).time, $bm_div(thisComp.frameDuration, 10)));\n    amp = 0.03;\n    freq = 3;\n    decay = 10;\n    $bm_rt = $bm_sum(value, $bm_div($bm_mul($bm_mul(v, amp), Math.sin($bm_mul($bm_mul($bm_mul(freq, t), 2), Math.PI))), Math.exp($bm_mul(decay, t))));\n} else {\n    $bm_rt = value;\n}"}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-49.706],[49.706,0],[0,49.706],[-49.706,0]],"o":[[0,49.706],[-49.706,0],[0,-49.706],[49.706,0]],"v":[[90,0],[0,90],[-90,0],[0,-90]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[90.25,90.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Groupe 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":16,"op":296,"st":-4,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"VALIDATE_CIRCLE2 Silhouettes 2","parent":5,"sr":1,"ks":{"o":{"a":0,"k":72,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":28,"s":[90.25,90.25,0],"to":[0,2.5,0],"ti":[0,-2.5,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"t":108,"s":[90.25,105.25,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":252,"s":[90.25,105.25,0],"to":[0,-2.5,0],"ti":[0,2.5,0]},{"t":292,"s":[90.25,90.25,0]}],"ix":2,"l":2},"a":{"a":0,"k":[90.25,90.25,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2,"x":"var $bm_rt;\nvar n, n, t, t, v, amp, freq, decay;\n$bm_rt = n = 0;\nif (numKeys > 0) {\n    $bm_rt = n = nearestKey(time).index;\n    if (key(n).time > time) {\n        n--;\n    }\n}\nif (n == 0) {\n    $bm_rt = t = 0;\n} else {\n    $bm_rt = t = $bm_sub(time, key(n).time);\n}\nif (n > 0 && t < 1) {\n    v = velocityAtTime($bm_sub(key(n).time, $bm_div(thisComp.frameDuration, 10)));\n    amp = 0.03;\n    freq = 3;\n    decay = 10;\n    $bm_rt = $bm_sum(value, $bm_div($bm_mul($bm_mul(v, amp), Math.sin($bm_mul($bm_mul($bm_mul(freq, t), 2), Math.PI))), Math.exp($bm_mul(decay, t))));\n} else {\n    $bm_rt = value;\n}"}},"ao":0,"ef":[{"ty":29,"nm":"Flou gaussien","np":5,"mn":"ADBE Gaussian Blur 2","ix":1,"en":1,"ef":[{"ty":0,"nm":"Flou","mn":"ADBE Gaussian Blur 2-0001","ix":1,"v":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":28,"s":[0]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":108,"s":[150]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[1],"y":[0]},"t":252,"s":[150]},{"t":292,"s":[0]}],"ix":1}},{"ty":7,"nm":"Dimensions de flou","mn":"ADBE Gaussian Blur 2-0002","ix":2,"v":{"a":0,"k":1,"ix":2}},{"ty":7,"nm":"Recopier les pixels du contour","mn":"ADBE Gaussian Blur 2-0003","ix":3,"v":{"a":0,"k":0,"ix":3}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-49.706],[49.706,0],[0,49.706],[-49.706,0]],"o":[[0,49.706],[-49.706,0],[0,-49.706],[49.706,0]],"v":[[90,0],[0,90],[-90,0],[0,-90]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.815686334348,0.086274509804,0.486274539723,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[90.25,90.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Groupe 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":16,"op":292,"st":-4,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"VALIDATE_CIRCLE3 Silhouettes 2","parent":9,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[181,181,0],"ix":2,"l":2},"a":{"a":0,"k":[181,181,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-98.583],[98.583,0],[0,98.583],[-98.583,0]],"o":[[0,98.583],[-98.583,0],[0,-98.583],[98.583,0]],"v":[[178.5,0],[0,178.5],[-178.5,0],[0,-178.5]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[181,181],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Groupe 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":20,"op":292,"st":20,"bm":0},{"ddd":0,"ind":8,"ty":5,"nm":"$text","parent":4,"tt":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":20,"s":[0]},{"t":40,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"s":true,"x":{"a":0,"k":83.338,"ix":3},"y":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":20,"s":[137.873]},{"t":80,"s":[207.41]}],"ix":4}},"a":{"a":0,"k":[0.5,-5.463,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"t":{"d":{"k":[{"s":{"s":25,"f":"SourceSansPro-SemiBold","t":"$text","ca":0,"j":2,"tr":20,"lh":30.0000019073486,"ls":0,"fc":[1,1,1]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":20,"op":292,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"VALIDATE_CIRCLE3 Silhouettes","parent":4,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[82.25,82.25,0],"ix":2,"l":2},"a":{"a":0,"k":[181,181,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0,0,0.667],"y":[1,1,1]},"o":{"x":[0.177,0.177,0.333],"y":[0.291,0.291,0]},"t":24,"s":[50,50,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":106,"s":[100,100,100]},{"i":{"x":[0.836,0.836,0.667],"y":[-0.528,-0.528,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":232,"s":[100,100,100]},{"t":292,"s":[50,50,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-98.583],[98.583,0],[0,98.583],[-98.583,0]],"o":[[0,98.583],[-98.583,0],[0,-98.583],[98.583,0]],"v":[[178.5,0],[0,178.5],[-178.5,0],[0,-178.5]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Contour 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[181,181],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Groupe 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":26,"op":292,"st":26,"bm":0}],"markers":[]}
diff --git a/animations/OK.json b/animations/OK.json
new file mode 100644 (file)
index 0000000..e4e2c07
--- /dev/null
@@ -0,0 +1 @@
+{"v":"5.9.0","fr":30,"ip":0,"op":160,"w":500,"h":500,"nm":"VALIDATE_anim","ddd":0,"assets":[],"fonts":{"list":[{"origin":3,"fPath":"images/font_0","fClass":"","fFamily":"Source Sans Pro","fWeight":"","fStyle":"SemiBold","fName":"SourceSansPro-SemiBold","ascent":70.599365234375}]},"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Nul 1","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[0.667,0.667,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0]},"t":10,"s":[85,85,100]},{"i":{"x":[0,0,0.667],"y":[1,1,1]},"o":{"x":[0.501,0.501,0.333],"y":[0.189,0.189,0]},"t":50,"s":[90,90,100]},{"t":80,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":148,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Calque de forme 1","parent":4,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[80.25,82.25,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-42,-10.25],[-8.75,23],[45.375,-31.25]],"c":false},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0.623528992896,0.992156982422,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":13,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Contour 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Forme 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":20,"s":[0]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":50,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[1],"y":[0]},"t":133,"s":[100]},{"t":148,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Réduire les tracés 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":20,"op":148,"st":20,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"VALIDATE_V Silhouettes","parent":4,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[82.211,81.147,0],"ix":2,"l":2},"a":{"a":0,"k":[46.212,32.777,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[37.477,-32.527],[-10.606,15.556],[-37.476,-11.314],[-45.962,-2.829],[-10.606,32.527],[45.962,-24.042]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[46.212,32.777],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Groupe 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":20,"op":148,"st":20,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"VALIDATE_CIRCLE1 Silhouettes","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[82.25,82.25,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,1]},"o":{"x":[0.576,0.576,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":10,"s":[100,100,100]},{"i":{"x":[0.973,0.973,0.667],"y":[1.001,1.001,1]},"o":{"x":[0.813,0.813,0.333],"y":[0,0,0]},"t":137,"s":[100,100,100]},{"t":148,"s":[0,0,100]}],"ix":6,"l":2,"x":"var $bm_rt;\nvar n, n, t, t, v, amp, freq, decay;\n$bm_rt = n = 0;\nif (numKeys > 0) {\n    $bm_rt = n = nearestKey(time).index;\n    if (key(n).time > time) {\n        n--;\n    }\n}\nif (n == 0) {\n    $bm_rt = t = 0;\n} else {\n    $bm_rt = t = $bm_sub(time, key(n).time);\n}\nif (n > 0 && t < 1) {\n    v = velocityAtTime($bm_sub(key(n).time, $bm_div(thisComp.frameDuration, 10)));\n    amp = 0.03;\n    freq = 3;\n    decay = 10;\n    $bm_rt = $bm_sum(value, $bm_div($bm_mul($bm_mul(v, amp), Math.sin($bm_mul($bm_mul($bm_mul(freq, t), 2), Math.PI))), Math.exp($bm_mul(decay, t))));\n} else {\n    $bm_rt = value;\n}"}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-45.287],[45.287,0],[0,45.287],[-45.287,0]],"o":[[0,45.287],[-45.287,0],[0,-45.287],[45.287,0]],"v":[[82,0],[0,82],[-82,0],[0,-82]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.086274509804,0.749019607843,0.749019607843,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[82.25,82.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Groupe 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":148,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"VALIDATE_CIRCLE2 Silhouettes","parent":4,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[82.25,82.25,0],"ix":2,"l":2},"a":{"a":0,"k":[90.25,90.25,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,1.189]},"o":{"x":[0.552,0.552,0.333],"y":[0,0,0]},"t":8,"s":[89,89,100]},{"t":14,"s":[100,100,100]}],"ix":6,"l":2,"x":"var $bm_rt;\nvar n, n, t, t, v, amp, freq, decay;\n$bm_rt = n = 0;\nif (numKeys > 0) {\n    $bm_rt = n = nearestKey(time).index;\n    if (key(n).time > time) {\n        n--;\n    }\n}\nif (n == 0) {\n    $bm_rt = t = 0;\n} else {\n    $bm_rt = t = $bm_sub(time, key(n).time);\n}\nif (n > 0 && t < 1) {\n    v = velocityAtTime($bm_sub(key(n).time, $bm_div(thisComp.frameDuration, 10)));\n    amp = 0.03;\n    freq = 3;\n    decay = 10;\n    $bm_rt = $bm_sum(value, $bm_div($bm_mul($bm_mul(v, amp), Math.sin($bm_mul($bm_mul($bm_mul(freq, t), 2), Math.PI))), Math.exp($bm_mul(decay, t))));\n} else {\n    $bm_rt = value;\n}"}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-49.706],[49.706,0],[0,49.706],[-49.706,0]],"o":[[0,49.706],[-49.706,0],[0,-49.706],[49.706,0]],"v":[[90,0],[0,90],[-90,0],[0,-90]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[90.25,90.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Groupe 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":8,"op":148,"st":-2,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"VALIDATE_CIRCLE2 Silhouettes 2","parent":5,"sr":1,"ks":{"o":{"a":0,"k":72,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":14,"s":[90.25,90.25,0],"to":[0,2.5,0],"ti":[0,-2.5,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"t":54,"s":[90.25,105.25,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":126,"s":[90.25,105.25,0],"to":[0,-2.5,0],"ti":[0,2.5,0]},{"t":146,"s":[90.25,90.25,0]}],"ix":2,"l":2},"a":{"a":0,"k":[90.25,90.25,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2,"x":"var $bm_rt;\nvar n, n, t, t, v, amp, freq, decay;\n$bm_rt = n = 0;\nif (numKeys > 0) {\n    $bm_rt = n = nearestKey(time).index;\n    if (key(n).time > time) {\n        n--;\n    }\n}\nif (n == 0) {\n    $bm_rt = t = 0;\n} else {\n    $bm_rt = t = $bm_sub(time, key(n).time);\n}\nif (n > 0 && t < 1) {\n    v = velocityAtTime($bm_sub(key(n).time, $bm_div(thisComp.frameDuration, 10)));\n    amp = 0.03;\n    freq = 3;\n    decay = 10;\n    $bm_rt = $bm_sum(value, $bm_div($bm_mul($bm_mul(v, amp), Math.sin($bm_mul($bm_mul($bm_mul(freq, t), 2), Math.PI))), Math.exp($bm_mul(decay, t))));\n} else {\n    $bm_rt = value;\n}"}},"ao":0,"ef":[{"ty":29,"nm":"Flou gaussien","np":5,"mn":"ADBE Gaussian Blur 2","ix":1,"en":1,"ef":[{"ty":0,"nm":"Flou","mn":"ADBE Gaussian Blur 2-0001","ix":1,"v":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":14,"s":[0]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":54,"s":[150]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[1],"y":[0]},"t":126,"s":[150]},{"t":146,"s":[0]}],"ix":1}},{"ty":7,"nm":"Dimensions de flou","mn":"ADBE Gaussian Blur 2-0002","ix":2,"v":{"a":0,"k":1,"ix":2}},{"ty":7,"nm":"Recopier les pixels du contour","mn":"ADBE Gaussian Blur 2-0003","ix":3,"v":{"a":0,"k":0,"ix":3}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-49.706],[49.706,0],[0,49.706],[-49.706,0]],"o":[[0,49.706],[-49.706,0],[0,-49.706],[49.706,0]],"v":[[90,0],[0,90],[-90,0],[0,-90]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.086274509804,0.749019607843,0.749019607843,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[90.25,90.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Groupe 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":8,"op":146,"st":-2,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"VALIDATE_CIRCLE3 Silhouettes 2","parent":9,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[181,181,0],"ix":2,"l":2},"a":{"a":0,"k":[181,181,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-98.583],[98.583,0],[0,98.583],[-98.583,0]],"o":[[0,98.583],[-98.583,0],[0,-98.583],[98.583,0]],"v":[[178.5,0],[0,178.5],[-178.5,0],[0,-178.5]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[181,181],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Groupe 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":10,"op":146,"st":10,"bm":0},{"ddd":0,"ind":8,"ty":5,"nm":"$text","parent":4,"tt":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[0]},{"t":20,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"s":true,"x":{"a":0,"k":83.338,"ix":3},"y":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":10,"s":[137.873]},{"t":40,"s":[207.41]}],"ix":4}},"a":{"a":0,"k":[0.5,-5.463,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"t":{"d":{"k":[{"s":{"s":25,"f":"SourceSansPro-SemiBold","t":"$text","ca":0,"j":2,"tr":20,"lh":30.0000019073486,"ls":0,"fc":[1,1,1]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":10,"op":146,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"VALIDATE_CIRCLE3 Silhouettes","parent":4,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[82.25,82.25,0],"ix":2,"l":2},"a":{"a":0,"k":[181,181,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0,0,0.667],"y":[1,1,1]},"o":{"x":[0.177,0.177,0.333],"y":[0.291,0.291,0]},"t":12,"s":[50,50,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":53,"s":[100,100,100]},{"i":{"x":[0.836,0.836,0.667],"y":[-0.528,-0.528,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":116,"s":[100,100,100]},{"t":146,"s":[50,50,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-98.583],[98.583,0],[0,98.583],[-98.583,0]],"o":[[0,98.583],[-98.583,0],[0,-98.583],[98.583,0]],"v":[[178.5,0],[0,178.5],[-178.5,0],[0,-178.5]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Contour 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[181,181],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Groupe 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":13,"op":146,"st":13,"bm":0}],"markers":[]}
diff --git a/js/quiz.animations.js b/js/quiz.animations.js
new file mode 100644 (file)
index 0000000..d43a719
--- /dev/null
@@ -0,0 +1,37 @@
+const lottie = require("lottie-web");
+const $ = require("cash-dom");
+
+
+function QuizAnimations(quiz) {
+    this.quiz = quiz;
+}
+
+QuizAnimations.prototype = {
+    // Load the animation "name" in container
+    load: function (name, container, replace) {
+        let json = this.quiz.data.animations[name];
+        if (json) {
+            for (const k in replace) {
+                json = json.replace(new RegExp(k, 'g'), replace[k]);
+            }
+            lottie.loadAnimation({
+                container: $(container).get(0),
+                renderer: 'svg',
+                loop: false,
+                autoplay: true,
+                animationData: JSON.parse(json),
+            });
+        }
+    },
+
+    triggeredBtn: function() {
+        /*$(document).on("mousedown", ".btn", function() {
+            gsap.to($(this), { scale: .9, duration: 0.3 });
+        }).on("mouseup", ".btn", function() {
+            gsap.to($(this), { scale: 1, duration: 0.3 });
+        })*/
+    }
+}
+
+
+module.exports = QuizAnimations;
diff --git a/js/quiz.js b/js/quiz.js
new file mode 100644 (file)
index 0000000..b99daff
--- /dev/null
@@ -0,0 +1,356 @@
+import $ from "cash-dom";
+import gsap from "gsap";
+import { MotionPathPlugin } from "gsap/MotionPathPlugin.js";
+import {CubeSCORM} from '/application/resources/scorm/scorm';
+import lottie from "lottie-web";
+import SplitType from 'split-type'
+import SimpleBar from 'simplebar'
+import 'simplebar/dist/simplebar.css'
+import Handlebars from "handlebars";
+
+import QuizResize from "./quiz.resize";
+import QuizAnimations from "./quiz.animations";
+import QuizScore from './quiz.score';
+import QuizScorm from './quiz.scorm';
+import QuizQuestion from './quiz.question';
+
+window.cubeSCORM = new CubeSCORM();
+window.$ = window.jQuery = $;
+
+window.key = require('keymaster-reloaded');
+
+import ResizeObserver from 'resize-observer-polyfill';
+window.ResizeObserver = ResizeObserver;
+
+function Quiz() {
+}
+
+Quiz.prototype = {
+    init: function () {
+        let $this = this;
+
+        // Initialisation des modules
+        this.animations = new QuizAnimations(this);
+        this.score=new QuizScore(this);
+        this.scorm=new QuizScorm(this);
+        this.resize = new QuizResize(this);
+        this.question = new QuizQuestion(this);
+
+        // Ici seront injectées dans this.data toutes les données du quiz et du thème pour qu'elles soient disponibles
+        // dans l'object à tout moment
+        this.data = data;
+        this.responses = []
+
+        console.log(this.data);
+        // ICI tout commence vraiment
+        console.log(this.data.theme)
+
+        this.timeoutAnimation = false
+
+        // commencer
+        $(document).on("click", "#start", function() {
+            $this.start()
+        })
+
+        //
+        $("#quiz").css("background-image","url("+this.data.theme.backgroundImage+")")
+
+        // La fonction resize est appelée à chaque fois qu'un resize de la fenêtre survient (et à l'init de l'app)
+        $(window).on('resize', function () {
+            $this.quizResize();
+        });
+        this.quizResize();
+
+        //animer le texte d'intro
+        let title = new SplitType("#welcome h2", { types: 'words, chars' })
+        let text = new SplitType("#welcome p", { types: 'words, chars' })
+        gsap.from(title.words, {
+            opacity: 0,
+            y: 20,
+            duration: 1,
+            stagger: 0.05,
+            onStart: () => {
+                $(title.elements).removeClass("none")
+            }
+        })
+        gsap.to(text.words, {
+            opacity: 1,
+            y: 0,
+            duration: 1,
+            ease: "power1.inOut",
+            stagger: {
+                amount: 0.2
+            },
+            onStart: () => {
+                $(text.elements).removeClass("none")
+            }
+        })
+
+        // Préparer les réponses du joueur dans l'objet this.responses
+        // à chaque fois que le formulaire change de valeur
+        $(document).on("change", ".active-screen form", function(e) {
+            $this.responses = []
+            $(this).find("input:checked").each(function() {
+                $this.responses.push(parseInt($(this).val()))
+            });
+        })
+
+        // Passer à la page suivante
+        // Valider les réponses
+        $(document).on("click", ".next .action", function () {
+            let responses = $this.responses
+            $this.next(responses);
+            $this.responses = []
+        })
+        key('space', function (e){
+            e.preventDefault()
+            $this.next();
+        })
+
+        // Réinitialiser les réponses
+        $(document).on("click", ".btn.reset", function() {
+            $this.resetForm()
+        })
+        key('r', function (e){
+            e.preventDefault()
+            $this.resetForm()
+        })
+
+        if(key.isPressed('R')) {
+            alert('r')
+        }
+
+        $(document).on("mousedown", ".btn", function() {
+            gsap.to($(this), { scale: .95, duration: .2, ease: "back.inOut" });
+        }).on("mouseup", ".btn", function() {
+            gsap.to($(this), { scale: 1, duration: .2 });
+        })
+
+        //
+        this.activeNav()
+    },
+
+    start: function() {
+        const $this = this
+        gsap.timeline().to("#welcome-screen", {
+            opacity: 0,
+            onComplete: function() {
+                let responses = $this.responses
+                $this.next(responses);
+                $("#welcome-screen").removeClass("next active-screen").addClass("none").next(".container-screen").removeClass("none").addClass("next active-screen")
+            }
+        })
+    },
+
+    updateIcons: function () {
+        $("[data-icon]").each(function () {
+            var iconId = 'quiz-' + $(this).data('icon');
+            // L'icône est déjà en place
+            if ($(this).children('svg.' + iconId).length) {
+                return;
+            }
+            // Si une autre icône est présente, on la supprime
+            $(this).children('svg.svg-icon').remove();
+            // Puis on ajoute l'icône
+            var icon = getSpriteIcon(iconId);
+            if ($(this).is('[data-icon-prepend]')) {
+                $(this).prepend(icon);
+            } else {
+                $(this).append(icon);
+            }
+        });
+    },
+
+    quizResize: function () {
+        this.updateIcons();
+        this.resize.resize();
+    },
+
+    next: function (responses) {
+        // on arrête l'animation si le joueur passe à la question suivante
+        this.stopAnimationValidation()
+
+        let status = quiz.score.questionStatus
+        let currentPosition = quiz.score.lastAnsweredQuestion + 1
+
+        const $el = $(".active-screen .btn.action")
+
+        quiz.score.updateScore()
+        // if form exist and responses are validated
+        // dont miss to add this second condition
+        if($(".active-screen form").length > 0) {
+            if(status.length > 0) {
+                if(status[this.question.currentPosition()].ok === "not answered") {
+                    this.validateResponse(responses);
+                    this.updateBtnValidation("validated")
+                    return false
+                }
+            }
+        }
+
+        $el.parents(".container-screen").addClass("none").removeClass("next active-screen").next(".container-screen").removeClass("none").addClass("next active-screen")
+        this.resetForm()
+        // on incrémente de 1 la position actuelle de la question (qui commence à l'index zero)
+        // pour récupérer le premier enfant de la nav
+        this.activeNav(  (parseInt(this.question.currentPosition())+1)  )
+        this.updateBtnValidation()
+        // si c'est la dernière question a été validée alors on affiche le résultat au prochain screen
+        if(this.question.last(currentPosition)) {
+            this.result()
+        }
+    },
+
+    // marque page automatique
+    // si le joueur recharge la page, le rediriger là où il en était
+    setDisplay: function() {
+        const   currentQuestion = quiz.score.lastAnsweredQuestion + 1,
+                questions = this.quiz.questions
+
+        if(questions.length > 0) {
+            if (quiz.score.lastAnsweredQuestion > -1 && questions.length <= currentQuestion) {
+                //
+            }
+        }
+    },
+
+    resetForm: () => {
+        $("form").find("input").prop("checked", false)
+    },
+
+    updateBtnValidation: function(status) {
+        let $btnAction = $(".footer-question .action"),
+            validationText = $btnAction.data("validation-text"),
+            continueText = $btnAction.data("continue-text")
+
+        $btnAction.find('.text').text(status === "validated" ? continueText : validationText)
+    },
+
+    validateResponse: function(responses) {
+        const form = $(".active-screen form")
+        const activeScreen = $(".active-screen")
+        const position = activeScreen.data("position")
+
+        if(form) {
+            if(form.length > 0) {
+                let validated = quiz.score.setAnswer(position,responses);
+                if(validated.ok === "ok") {
+                    this.animationValidation("OK")
+                }else {
+                    this.animationValidation("NOK")
+                }
+                this.resultAfterValidation(validated.status[position].answers)
+            }
+            return false
+        }
+    },
+
+    activeNav: function(position = 1) {
+        const questionStatus = quiz.score.questionStatus
+        const lastAnsweredQuestion = quiz.score.lastAnsweredQuestion
+        if($(".active-screen").find(".progress-item").length > 0) {
+            let $el = $(".progress-container .progress-item:nth-child(" + position + ")")
+
+            $(".progress-container .progress-item").removeClass("active")
+            $el.addClass("active")
+
+            let n = (lastAnsweredQuestion + 1)
+            let $_el = $(".progress-container .progress-item:nth-child(" + n + ")")
+
+            if (lastAnsweredQuestion > -1) {
+                if (questionStatus[lastAnsweredQuestion].ok === 'ok') {
+                    $_el.addClass("ok")
+                }
+                if (questionStatus[lastAnsweredQuestion].ok === 'nok') {
+                    $_el.addClass("nok")
+                }
+            }
+        }
+    },
+
+    animationValidation: function(status) {
+        let selector = $("#anim")
+        let text = status === "NOK" ? "Not quite" : "Perfect"
+        let $this = this
+        this.animations.load(status, selector, {'\\$text': text});
+        selector.addClass("active")
+        this.timeoutAnimation = setTimeout(function(e){
+            $this.stopAnimationValidation()
+        }, 10000)
+    },
+
+    stopAnimationValidation: function() {
+        $("#anim").removeClass("active").empty()
+        if(this.timeoutAnimation)
+            clearTimeout(this.timeoutAnimation)
+    },
+
+    resultAfterValidation: function(datas) {
+        for(let k in datas) {
+            let n = (parseInt(k) + 1)
+            let icon = getSpriteIcon("quiz-ok")
+            let $el = $(".active-screen .question-multiple .list-item:nth-of-type("+n+") label")
+            $el.addClass(datas[k])
+            if(datas[k] === "nok") {
+                icon = getSpriteIcon("quiz-wrong")
+            }
+            if(datas[k] !== "neutral") {
+                $el.find(".access").addClass(datas[k]).html(icon)
+            }
+        }
+    },
+
+    result: function() {
+        let maxScore = quiz.score.maxScore,
+            score = quiz.score.score
+
+        let status = quiz.score.questionStatus
+        let reviewList = this.question.getAll();
+
+        const counter = $("#progress-counter")
+        if(score < (maxScore / 2)) {
+            counter.addClass("nok")
+        }else if(score >= (maxScore / 2)) {
+            counter.addClass("ok")
+        }
+
+        reviewList = reviewList.map((c,i) => {
+            return {
+                'question': c['question'],
+                'answers': c['answers'].filter((c) => {
+                    return c['correct'] === 1
+                }),
+                'status': status[i].ok
+            }
+        })
+        let $ul = $("#answers-list")
+
+        $("[id^=score-]").text(score)
+        $("[id^=maxScore-]").text(maxScore)
+
+        //
+        // HANDLEBARS TEMPLATING
+        //
+        // on applique une incrementation de +1
+        // utilisé pour la numérotation des questions
+        Handlebars.registerHelper("inc", (value) => { return parseInt(value) + 1; });
+
+        // on envoie le html avec les nouvelles données
+        const source = $("#template-answers-review").html();
+        const template = Handlebars.compile(source);
+        const html = template({reviewList: reviewList});
+        $ul.html(html)
+
+        // mise en place de la scrollbar personnalisé
+        // https://github.com/Grsmto/simplebar/tree/master/packages/simplebar
+        const simpleBar = new SimpleBar($ul.get(0))
+    },
+
+    restart: function() {
+
+    }
+}
+
+$(function () {
+    window.quiz = new Quiz();
+    window.quiz.init();
+});
diff --git a/js/quiz.question.js b/js/quiz.question.js
new file mode 100644 (file)
index 0000000..f659d07
--- /dev/null
@@ -0,0 +1,37 @@
+var QuizQuestion = function(quiz) {
+    this.quiz = quiz;
+    this.init();
+}
+
+QuizQuestion.prototype = {
+    init: function(){
+
+    },
+
+    getAll: function() {
+      return this.quiz.data.questions
+    },
+
+    byPosition: function(pos) {
+        return this.quiz.data.questions[parseInt(pos)]
+    },
+
+    currentPosition: function() {
+        return $(document).find(".active-screen").data("position");
+    },
+
+    current: function() {
+        let currentPosition = this.currentPosition()
+        return this.byPosition(currentPosition)
+    },
+
+    last: function(position) {
+        return this.quiz.data.questions.length === parseInt(position)
+    },
+
+    getFormData: function(responses) {
+        //
+    },
+}
+
+module.exports = QuizQuestion;
diff --git a/js/quiz.resize.js b/js/quiz.resize.js
new file mode 100644 (file)
index 0000000..b68ab5a
--- /dev/null
@@ -0,0 +1,14 @@
+function QuizResize(quiz) {
+    this.quiz = quiz;
+}
+
+QuizResize.prototype = {
+    resize: function () {
+        this.ww = $(window).width();
+        this.hh = $(window).height();
+
+        // Exécuter ici toutes opérations qui doivent intervenir lorsque la fenêtre est redimensionnée par le système ou l'utilisateur
+    },
+}
+
+module.exports = QuizResize;
diff --git a/js/quiz.score.js b/js/quiz.score.js
new file mode 100644 (file)
index 0000000..b336788
--- /dev/null
@@ -0,0 +1,153 @@
+const $ = require("cash-dom");
+
+function QuizScore(quiz) {
+    this.quiz = quiz;
+    this.logQuestions = [];
+    // Le score global du quiz
+    this.score = 0;
+    this.maxScore = 0;
+    this.questionStatus = [];
+    this.answers = [];
+    this.lastAnsweredQuestion = -1;
+    this.init();
+}
+
+QuizScore.prototype = {
+    init: function () {
+
+    },
+
+    /**
+     *
+     * @param questionIndex integer
+     * @param answers array
+     * @returns {{ok, status: []}}
+     */
+    setAnswer: function (questionIndex, answers) {
+        this.lastAnsweredQuestion = questionIndex;
+        this.answers[questionIndex] = answers;
+        this.updateScore();
+        return {
+            ok: this.questionStatus[questionIndex].ok,
+            score: this.score,
+            maxScore: this.maxScore,
+            status: this.questionStatus
+        };
+    },
+
+    checkQuestion: function (questionIndex) {
+        let question = this.quiz.data.questions[questionIndex];
+
+        let a = [];
+        let ok = 'ok';
+        let count = question.count_for_score;
+        let log = {
+            'count': count,
+        };
+
+        let answersStatus = [];
+        let userAnswers = this.answers[questionIndex];
+        let min_score = 0;
+        let this_score = 0;
+        if (userAnswers === undefined || userAnswers === null) {
+            ok = 'not answered';
+        } else {
+            let $this = this;
+            if (question.type === 'multiple') {
+                // Le score de la question
+                min_score = this.getMinScore(question);
+                this_score = 0;
+                for (let answerIndex in question.answers) {
+                    answerIndex = parseInt(answerIndex);
+                    const answer = question.answers[answerIndex];
+
+                    let checkedByUser = userAnswers.indexOf(answerIndex) >= 0;
+                    if (parseInt(answer.correct) === 1) {
+                        if (checkedByUser) {
+                            // C'est une bonne réponse et elle a été cochée par l'utilisateur
+                            this_score += answer.score;
+                            answersStatus[answerIndex] = 'ok';
+                        } else {
+                            // C'est une bonne réponse, mais elle n'a pas été cochée par l'utilisateur
+                            answersStatus[answerIndex] = 'missed';
+                        }
+                    } else {
+                        if (checkedByUser) {
+                            // C'est une mauvaise réponse et elle a été cochée par l'utilisateur
+                            this_score -= answer.score;
+                            answersStatus[answerIndex] = 'nok';
+                        } else {
+                            // C'est une bonne réponse et elle n'a pas été cochée par l'utilisateur
+                            answersStatus[answerIndex] = 'neutral';
+                        }
+                    }
+                }
+                ok = this_score >= min_score ? 'ok' : 'nok';
+
+                log.answer = a;
+            } else {
+                log.answer = $(this).find('input,textarea,select').val();
+            }
+        }
+
+        if (!count) {
+            ok = 'ok';
+        }
+
+        this.questionStatus[questionIndex] = {
+            ok: ok,
+            answers: answersStatus,
+            // dbg_min_score: min_score,
+            // dbg_this_score: this_score
+        };
+
+        if (count) {
+            this.maxScore++;
+            if (ok == 'ok') {
+                this.score++;
+                log.score = 1;
+            } else {
+                log.score = 0;
+            }
+        } else {
+            log.score = 0;
+        }
+        this.logQuestions[questionIndex] = log;
+    },
+
+    getMinScore: function (question) {
+        // Le score minimal est le score que l'utilisateur doit atteindre sur une question pour que sa réponse soit considérée
+        let min_score = parseInt(question.min_score);
+        if (min_score === 0) {
+            min_score = 0;
+            for (const answerIndex in question.answers) {
+                const answer = question.answers[answerIndex];
+                if (answer.correct === 1) {
+                    min_score += answer.score;
+                }
+            }
+        }
+        return min_score;
+    },
+
+    updateScore: function () {
+        this.maxScore = 0;
+        this.score = 0;
+        this.logQuestions = [];
+
+        for (const qn in this.quiz.data.questions) {
+            this.checkQuestion(qn);
+        }
+
+        let state = {
+            q: this.lastAnsweredQuestion + 1, a: this.answers
+        };
+
+        if (cubeSCORM.SCORM) {
+            cubeSCORM.setSCORMLocation(state);
+        }
+    },
+};
+
+module.exports = QuizScore;
+
diff --git a/js/quiz.scorm.js b/js/quiz.scorm.js
new file mode 100644 (file)
index 0000000..b5e5570
--- /dev/null
@@ -0,0 +1,7 @@
+function QuizScorm(quiz) {
+    this.quiz = quiz;
+}
+
+QuizScorm.prototype = {};
+
+module.exports = QuizScorm;
diff --git a/style/001-global-variables.sass b/style/001-global-variables.sass
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/style/002-item-variables.sass b/style/002-item-variables.sass
new file mode 100644 (file)
index 0000000..9e5f8fc
--- /dev/null
@@ -0,0 +1 @@
+// Do not edit this file, quiz variables will be populated at compile time
diff --git a/style/003-reset.sass b/style/003-reset.sass
new file mode 100644 (file)
index 0000000..45897f9
--- /dev/null
@@ -0,0 +1,51 @@
+/* http://meyerweb.com/eric/tools/css/reset/
+   v2.0 | 20110126
+   License: none (public domain) */
+
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed,
+figure, figcaption, footer, header, hgroup,
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video, main
+    margin: 0
+    padding: 0
+    border: 0
+    font-size: 100%
+    font: inherit
+    vertical-align: baseline
+    box-sizing: border-box
+
+
+/* HTML5 display-role reset for older browsers */
+article, aside, details, figcaption, figure,
+footer, header, hgroup, menu, nav, section, main
+    display: block
+
+
+body
+    line-height: 1
+
+
+ol, ul
+    list-style: none
+
+
+blockquote, q
+    quotes: none
+
+blockquote:before, blockquote:after,
+q:before, q:after
+    content: ''
+    content: none
+
+table
+    border-collapse: collapse
+    border-spacing: 0
diff --git a/style/004-mixins.sass b/style/004-mixins.sass
new file mode 100644 (file)
index 0000000..bd8e37f
--- /dev/null
@@ -0,0 +1,49 @@
+@mixin above($min-width)
+    @media (min-width: $min-width)
+        @content
+
+
+@mixin below($max-width)
+    @media (max-width: $max-width)
+        @content
+
+
+@mixin breakpoint($breakpoint, $direction: min)
+    $breakpoint-values: map-get($breakpoints, $breakpoint)
+    $breakpoint: map-get($breakpoint-values, $direction)
+    @media (#{$direction}-width: $breakpoint)
+        @content
+
+
+@mixin opacity($opacity, $rule: background-color, $color: $texts-color)
+    #{$rule}: rgba($color,$opacity)
+
+
+@mixin flex-config($justify-content: false, $flex: false, $flex-direction: false, $align-items: false)
+    display: flex
+
+    @if $justify-content != false
+        justify-content: $justify-content
+
+    @if $flex != false
+        flex: $flex
+
+    @if $flex-direction != false
+        flex-direction: $flex-direction
+
+    @if $align-items != false
+        align-items: $align-items
+
+
+@mixin font-size($size)
+    font-size: #{$size}px
+    line-height: map-get($fonts-size,$size)
+
+
+@mixin padding-container()
+    padding: 16px
+    +breakpoint(md)
+        padding: 24px
+
+@mixin radius($size)
+    border-radius: $size
diff --git a/style/005-utilities.sass b/style/005-utilities.sass
new file mode 100644 (file)
index 0000000..adc845c
--- /dev/null
@@ -0,0 +1,12 @@
+.radius
+    border-radius: 16px
+
+.relative
+    position: relative
+
+.none
+    display: none !important
+
+\:root
+    --space-21-66: clamp(1.31rem, calc(0.29rem + 5.11vw), 4.13rem)
+
diff --git a/style/100-global.sass b/style/100-global.sass
new file mode 100644 (file)
index 0000000..763a60d
--- /dev/null
@@ -0,0 +1,86 @@
+@import 005-utilities
+
+body
+    background-color: $neutral-color
+    font-family: $font
+    color: $texts-color
+
+[data-icon] svg
+    height: 20px
+
+.container
+    +flex-config(center,false,false,center)
+    min-height: 100vh
+
+#quiz
+    width: 100%
+    max-width: 1200px
+    min-height: 680px
+    margin: 0 auto
+    padding: 24px 24px
+    position: relative
+
+.btn
+    padding: 0 12px
+    text-align: center
+    font-size: 20px
+    border: none
+    cursor: pointer
+    display: inline-block
+    height: 58px
+    +flex-config(center,false,false,center)
+    @extend .radius
+    +font-size(20)
+    &.primary
+        background: radial-gradient(at 16% 6px, rgb(255, 102, 186) -7%, #D0167C 74%)
+        box-shadow: 0 4px 6px rgba(0,0,0,.2)
+    &.secondary
+        +opacity(.16)
+        padding-left: 22px
+    &.reset
+        max-width: 144px
+    &.info
+        max-width: 177px
+
+.access
+    width: 34px
+    height: 34px
+    border-radius: 4px
+    +font-size(16)
+    +opacity(.16)
+    text-transform: uppercase
+    margin-left: 16px
+    +flex-config(center,false,false,center)
+    border: 0
+    &.space
+        width: 70px
+    &.infos
+        width: 40px
+    &.ok
+        +opacity(.24, background-color, $ok-color)
+
+    &.ok,
+    &.missed
+        svg
+            color: $ok-color
+    &.nok
+        +opacity(.24, background-color, $nok-color)
+        svg
+            color: $nok-color
+    &.ok,
+    &.nok,
+    &.missed
+        svg
+            width: 15px
+            height: 15px
+
+.screen
+    position: relative
+    z-index: 1
+    &-image
+        position: absolute
+        top: 0
+        left: 0
+        height: 100%
+        width: 100%
+        z-index: 0
diff --git a/style/101-header-footer.sass b/style/101-header-footer.sass
new file mode 100644 (file)
index 0000000..d4a269e
--- /dev/null
@@ -0,0 +1,57 @@
+header,
+footer
+    position: relative
+
+header
+    z-index: 1
+
+#title
+    height: 80px
+    +flex-config(space-between,false,row,center)
+    margin-top: -24px
+
+#logo
+    height: 40px
+    filter: brightness(10)
+
+.header-question
+    text-align: center
+    .abovetitle
+        +font-size(16)
+    .progress-container
+        margin: 6px 0 16px
+        +flex-config(center,false,false,center)
+    .progress-item
+        width: 16px
+        height: 4px
+        border-radius: 100px
+        +opacity(.16)
+        display: inline-flex
+        transition: background-color .3s
+        &:not(:last-of-type)
+            margin-right: 7px
+        &.active
+            background-color: $texts-color
+        &.ok
+            background-color: $ok-color
+        &.nok
+            background-color: $nok-color
+    h1
+        +font-size(24)
+
+.footer
+    position: absolute
+    bottom: 0
+    left: 0
+    width: 100%
+    z-index: 2
+    +flex-config(space-between,false,row,center)
+    +padding-container()
+
+    .btn.primary
+        width: 100%
+        max-width: 400px
+        position: absolute
+        left: 50%
+        bottom: 24px
+        transform: translateX(-50%)
diff --git a/style/102-intro.sass b/style/102-intro.sass
new file mode 100644 (file)
index 0000000..f6d3b32
--- /dev/null
@@ -0,0 +1,16 @@
+#welcome
+    max-width: 590px
+    margin: 0 auto
+    top: 160px
+    h2
+        margin: 0 0 12px
+        +font-size(20)
+        clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%)
+
+    p
+        +font-size(16)
+        clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%)
+
+        .word
+            opacity: 0
+            transform: translateY(100px)
diff --git a/style/103-question-multiple.sass b/style/103-question-multiple.sass
new file mode 100644 (file)
index 0000000..fed8e2e
--- /dev/null
@@ -0,0 +1,40 @@
+.screen.question-multiple
+    top: 93px
+    .list
+        display: grid
+        grid-template-columns: repeat(2, 1fr)
+        grid-gap: 16px
+        &-item
+            label
+                width: 100%
+                height: 58px
+                @extend .radius
+                +opacity(.80,background-color,$neutral-color)
+                +flex-config(space-between,false,false,center)
+                padding: 0 16px
+                cursor: pointer
+                border: 2px solid rgba($texts-color, .24)
+                position: relative
+                overflow: hidden
+                &:after
+                    content: ""
+                    width: 100%
+                    height: 100%
+                    position: absolute
+                    top: 0
+                    left: 0
+                    transition: background-color .1s ease-out
+                &.ok:after,
+                &.missed:after
+                    //
+                    +opacity(.24,background-color,$ok-color)
+                *
+                    z-index: 1
+
+            input:checked+label
+                border-color: $texts-color
+                transition: border-color .1s ease-out
+                &:after
+                    +opacity(.16)
+                &.nok:after
+                    background: transparent
diff --git a/style/104-animations.sass b/style/104-animations.sass
new file mode 100644 (file)
index 0000000..4ef9ee3
--- /dev/null
@@ -0,0 +1,22 @@
+#anim
+    position: absolute
+    top: 50%
+    left: 50%
+    transform: translate(-50%,-50%)
+    z-index: 1
+    width: 100%
+    height: 100%
+    +opacity(.4, background-color, $neutral-color)
+    backdrop-filter: blur(4px)
+    // règle ie > 9 à tester
+    // filter:progid:DXImageTransform.Microsoft.Blur(PixelRadius='3')
+    opacity: 0
+    visibility: hidden
+    transition: all 1s
+    svg
+        position: relative
+        z-index: 1
+    &.active
+        visibility: visible
+        opacity: 1
+        transition: all 1s
diff --git a/style/105-outro.sass b/style/105-outro.sass
new file mode 100644 (file)
index 0000000..0438c0e
--- /dev/null
@@ -0,0 +1,147 @@
+.score
+    height: 576px //680(hauteur de base) - 80(hauteur du header) - 24(padding inférieure)
+    +opacity(.48,background-color,$neutral-color)
+    border-radius: 40px
+    overflow: hidden
+    +flex-config(false,false,row,stretch)
+
+    .subtitle
+        +opacity(.8,color,$texts-color)
+
+    &-content
+        flex: 1
+        padding: 24px
+        position: relative
+        h1
+            +font-size(40)
+            margin-bottom: 9px
+        .subtitle
+            +font-size(16)
+
+    &-content-wrapper
+        +flex-config(false,false,false,center)
+        position: relative
+        top: var(--space-21-66)
+        left: var(--space-21-66)
+
+    &-counter
+        height: 0
+        padding-bottom: 31%
+        width: 31%
+        max-width: 210px
+        position: relative
+        +font-size(80)
+        margin-right: 60px
+
+        #progress-counter
+            width: 100%
+            height: 100%
+            position: absolute
+            top: 0
+            left: 0
+            border-radius: 100px
+            background: transparent
+            +flex-config(center,false,false,center)
+            &.nok *
+                color: $nok-color
+            &.ok *
+                color: $ok-color
+
+            svg
+                overflow: visible
+                width: calc(100% - 12px)
+                height: calc(100% - 12px)
+                transform: rotate(-90deg)
+                position: absolute
+                circle
+                    stroke-width: 12px
+                circle:not(#progress-circle)
+                    +opacity(.16,color,$texts-color)
+                circle#progress-circle
+                    transition: stroke-dashoffset 0.5s ease-in-out
+
+    &-answers-review
+        width: 36.11111%
+        background-color: $neutral-color
+        padding: 24px 24px 0
+        position: relative
+        h2
+            +font-size(24)
+            margin-bottom: 5px
+        .subtitle
+            +font-size(16)
+            margin-bottom: 22px
+
+        &:after
+            content: ""
+            width: 100%
+            height: 80px
+            position: absolute
+            bottom: 0
+            left: 0
+            background: linear-gradient(to bottom,transparent, rgba($neutral-color,.8))
+
+    #answers-list
+        height: 85%
+        padding-right: 24px
+        .item
+            padding-left: 20px
+            margin-bottom: 22px
+            position: relative
+            *
+                +font-size(14)
+            &:after
+                content: ""
+                width: 12px
+                height: 12px
+                position: absolute
+                left: 0
+                top: 4px
+                border-radius: 20px
+            &.ok
+                //
+                &:after
+                    background-color: $ok-color
+                .position
+                    color: $ok-color
+            &.nok
+                //
+                &:after
+                    background-color: $nok-color
+                .position
+                    color: $nok-color
+
+            .question
+                margin-bottom: 2px
+
+            .answer
+                +opacity(.8,color,$texts-color)
+
+
+    footer
+        position: absolute
+        width: calc(100% - 48px)
+        bottom: 24px
+        .restart-sentence
+            margin-bottom: 14px
+        .controls
+            +flex-config(space-between)
+
+
+    // SimpleBar personalisation
+    .simplebar-wrapper
+        height: 100%
+    .simplebar-track
+        +opacity(.08,background-color,$texts-color)
+        border-radius: 20px
+        &.simplebar-vertical
+            height: 93%
+            width: 5px
+            .simplebar-scrollbar::before
+                background-color: #77679f
+                opacity: 1 !important
+                width: 3px
+                top: 1px
+                bottom: 1px
+                left: 1px
+                right: 1px
diff --git a/style/106-question-draganddrop.sass b/style/106-question-draganddrop.sass
new file mode 100644 (file)
index 0000000..9d599e9
--- /dev/null
@@ -0,0 +1,94 @@
+.container-screen.question-draganddrop
+    .screen-image
+        width: auto
+        img
+            height: 100%
+        &.zone-1
+            .zone-content
+                left: 24px
+        &.zone-2
+            left: initial
+            right: 0
+            .zone-content
+                right: 24px
+        .zone-content
+            position: absolute
+            top: 50%
+            transform: translateY(-50%)
+            width: 100%
+            max-width: 180px
+            .text
+                margin-bottom: 21px
+
+        form
+            +opacity(.08,background-color,$texts-color)
+            +radius(16px)
+            padding: 8px
+            border: 1px dashed rgba($texts-color,.4)
+        .slot
+            width: 100%
+            height: 51px
+            border: 1px solid rgba($texts-color,.24)
+            +radius(8px)
+
+    .screen
+        +flex-config(center, false, false, center)
+        margin-top: 92px
+        .list
+            position: relative
+            width: 100%
+            max-width: 368px
+            height: 225px
+            margin: 0 16px
+            &-item
+                position: absolute
+                width: 100%
+                height: 100%
+                +radius(16px)
+                &:nth-child(1)
+                    background-color: $neutral-color
+                    z-index: 4
+                    border: 2px solid $texts-color
+                    padding: 20px
+                &:nth-child(2)
+                    opacity: .64
+                    +opacity(.8,background-color,$neutral-color)
+                    transform: scale(.9)
+                    z-index: 3
+                    top: 32px
+                &:nth-child(3)
+                    opacity: .4
+                    +opacity(.8,background-color,$neutral-color)
+                    transform: scale(.81)
+                    z-index: 2
+                    top: 61px
+                &:nth-child(4)
+                    opacity: .16
+                    +opacity(.8,background-color,$neutral-color)
+                    transform: scale(0.72)
+                    z-index: 1
+                    top: 91px
+                &:not(:nth-child(-n+4)) // on cache les items à partir du 5ème
+                    opacity: 0
+                    visibility: hidden
+
+
+    .controls
+        width: 124px
+        padding: 12px 0
+        +font-size(20)
+        +opacity(.16,background-color,$texts-color)
+        border-radius: 16px
+        text-align: center
+        &.left .access
+            transform: rotate(-90deg)
+        &.right .access
+            transform: rotate(90deg)
+        p
+            margin-bottom: 5px
+        .access
+            margin: 0 auto
+            span
+                display: flex
+        svg
+            color: $texts-color
diff --git a/style/style.sass b/style/style.sass
new file mode 100644 (file)
index 0000000..b3a649c
--- /dev/null
@@ -0,0 +1,12 @@
+@import 001-global-variables
+@import 002-item-variables
+@import 003-reset
+@import 004-mixins
+
+@import 100-global
+@import 101-header-footer
+@import 102-intro
+@import 103-question-multiple
+@import 104-animations
+@import 105-outro
+@import 106-question-draganddrop
diff --git a/views/footer.blade.php b/views/footer.blade.php
new file mode 100644 (file)
index 0000000..a4de04a
--- /dev/null
@@ -0,0 +1,21 @@
+<footer class="footer-question footer">
+    @isset($reset)
+        <a class="btn secondary reset">
+            Reset
+            <span class="access">R</span>
+        </a>
+    @endisset
+    <a class="btn primary action" data-validation-text="Validate answer" data-continue-text="Continue">
+        <span class="text">{{$text}}</span>
+        <span class="access space">space</span>
+        @isset($time)
+            <span data-icon="running-man"></span>
+        @endisset
+    </a>
+    @isset($info)
+        <a class="btn secondary none">
+            More infos
+            <span class="access infos">F1</span>
+        </a>
+    @endisset
+</footer>
diff --git a/views/header_question.blade.php b/views/header_question.blade.php
new file mode 100644 (file)
index 0000000..dda7f1f
--- /dev/null
@@ -0,0 +1,12 @@
+<header class="header-question">
+    <p class="abovetitle">{{ __('Question').' '.($position+1).'/'.$max }} </p>
+    <div class="progress-container">
+        @for($i = 0; $i < $max; $i++)
+            <span class="progress-item"></span>
+        @endfor
+    </div>
+    <h1 id="titleQuestion">{{$data['question']}}</h1>
+    @if($data['type'] === "draganddrop")
+        <h2 class="subtitle">Use arrow keys to move the cards to the corresponding zone</h2>
+    @endif
+</header>
diff --git a/views/header_title.blade.php b/views/header_title.blade.php
new file mode 100644 (file)
index 0000000..38bd053
--- /dev/null
@@ -0,0 +1,4 @@
+<header id="title">
+    <h1 id="quizTitle">{{$data->title}}</h1>
+    <img src="{{$data->theme->logo}}" id="logo"/>
+</header>
diff --git a/views/index.blade.php b/views/index.blade.php
new file mode 100644 (file)
index 0000000..a01d88a
--- /dev/null
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, shrink-to-fit=no">
+    <meta name="width" content="1024">
+    <meta name="height" content="768">
+    <title>{{$data->title}}</title>
+    <link type="text/css" rel="stylesheet" href="css/style.css">
+</head>
+<body>
+@include("quizv2.sprite")
+@php
+    $totalQuestion = sizeof($data->questions);
+    $alphabet = range('A', 'Z');
+@endphp
+<div class="container">
+    <div id="quiz">
+        @if($data->intro_enable)
+            @include('quizv2.screens.intro', ['data'=> $data])
+        @endif
+        @foreach($data->questions as $key => $question)
+            @include('quizv2.screens.question_'.$question['type'], ['theme' => $data->theme, 'data'=> $question, 'max' => $totalQuestion, 'position' => $key, 'alphabet' => $alphabet])
+        @endforeach
+        @include('quizv2.screens.outro', ['data'=> $data])
+        <div id="anim"></div>
+    </div>
+</div>
+<script src="js/quiz.js"></script>
+</body>
+</html>
diff --git a/views/screens/intro.blade.php b/views/screens/intro.blade.php
new file mode 100644 (file)
index 0000000..291f435
--- /dev/null
@@ -0,0 +1,16 @@
+@php
+    $absPath = \App\Models\Quiz::find($data->id)->getPreviewURL();
+@endphp
+<div class="container-screen active-screen next" id="welcome-screen">
+    @include('quizv2.header_title', ['data', $data])
+    <div class="screen" id="welcome">
+        <h2 class="none">{{$data->intro_title}}</h2>
+        <p class="none">{{$data->intro_text}}</p>
+    </div>
+    <div class="screen-image">
+        <img src="{{$data->theme->introImage}}" />
+    </div>
+    <footer class="footer">
+        <a id="start" class="btn primary">{{$data->intro_button}}</a>
+    </footer>
+</div>
diff --git a/views/screens/outro.blade.php b/views/screens/outro.blade.php
new file mode 100644 (file)
index 0000000..f2d6868
--- /dev/null
@@ -0,0 +1,59 @@
+<div class="container-screen none">
+    @include('quizv2.header_title', ['data', $data])
+    <div class="screen score" id="score">
+        <div class="score-content">
+            <div class="score-content-wrapper">
+                <div class="score-counter">
+                    <div id="progress-counter">
+                        <span id="score-counter">0</span><span>/</span><span id="maxScore-counter">0</span>
+                        <svg width="100%" height="100%" id="svg">
+                            <circle cx="50%" cy="50%" r="50%" fill="transparent" stroke="currentColor" />
+                            <circle id="progress-circle" cx="50%" cy="50%" r="50%" fill="none" stroke="currentColor" />
+                        </svg>
+                    </div>
+                </div>
+                <div class="score-text">
+                    <h1>Congratulation!</h1>
+                    <p class="subtitle">You have completed the quiz<br/> with <span id="score-text"></span>
+                        correct answers out of <span id="maxScore-text"></span></p>
+                </div>
+            </div>
+            <footer>
+                @if($data->restart_button)
+                    <div class="restart-sentence">Want to improve your score?</div>
+                @endif
+                <div class="controls">
+                    @if($data->restart_button)
+                        <a class="btn secondary reset">
+                            Restart
+                            <span class="access">R</span>
+                        </a>
+                    @endif
+                    <a class="btn primary action">
+                        Leave
+                        <span class="access space">space</span>
+                    </a>
+                </div>
+            </footer>
+        </div>
+        <div class="score-answers-review">
+            <h2>Answers review</h2>
+            <p class="subtitle">Review your answers before you go</p>
+            <ul id="answers-list">
+                @verbatim
+                <script id="template-answers-review" type="text/x-handlebars-template">
+                    {{#each reviewList}}
+                        <li class="item {{this.status}}">
+                            <p class="position">Question {{inc @index}}</p>
+                            <p class="question">{{this.question}}</p>
+                            {{#each this.answers}}
+                                <p class="answer">{{this.answer}}</p>
+                            {{/each}}
+                        </li>
+                    {{/each}}
+                </script>
+                @endverbatim
+            </ul>
+        </div>
+    </div>
+</div>
diff --git a/views/screens/question_draganddrop.blade.php b/views/screens/question_draganddrop.blade.php
new file mode 100644 (file)
index 0000000..2052723
--- /dev/null
@@ -0,0 +1,50 @@
+<div class="container-screen none question-draganddrop" data-position="{{$position}}">
+    <div class="screen-image zone-1">
+        <img src="{{$theme->draganddropArea1Image}}" />
+        <div class="zone-content">
+            <div class="text">
+                <h2>Zone 1</h2>
+                <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh</p>
+            </div>
+            <form>
+                @foreach($data['answers'] as $key => $answer)
+                    <div class="slot">
+                    </div>
+                @endforeach
+            </form>
+        </div>
+    </div>
+    @include('quizv2.header_question', ['data' => $data, 'max' => $max, 'position' => $position])
+    <div class="screen question-draganddrop">
+        <div class="controls left">
+            <p>Move left</p>
+            <button class="access"><span data-icon="arrow"></span></button>
+        </div>
+        <ul class="list">
+            @foreach($data['answers'] as $key => $answer)
+                <li class="list-item">
+                    {{$answer['answer']}}
+                </li>
+            @endforeach
+        </ul>
+        <div class="controls right">
+            <p>Move right</p>
+            <button class="access"><span data-icon="arrow"></span></button>
+        </div>
+    </div>
+    <div class="screen-image zone-2">
+        <img src="{{$theme->draganddropArea2Image}}" />
+        <div class="zone-content">
+            <div class="text">
+                <h2>Zone 1</h2>
+                <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh</p>
+            </div>
+            <form>
+                @foreach($data['answers'] as $key => $answer)
+                    <div class="slot"></div>
+                @endforeach
+            </form>
+        </div>
+    </div>
+    @include('quizv2.footer', ['data' => $data, 'reset' => true, 'text' => 'Validate answer', 'info' => true])
+</div>
diff --git a/views/screens/question_multiple.blade.php b/views/screens/question_multiple.blade.php
new file mode 100644 (file)
index 0000000..6357f48
--- /dev/null
@@ -0,0 +1,22 @@
+<div class="container-screen none" data-position="{{$position}}">
+    @include('quizv2.header_question', ['data' => $data, 'max' => $max, 'position' => $position])
+    <div class="screen question-multiple">
+        <form id="form-{{$position}}">
+            <ul class="list">
+                @foreach($data['answers'] as $key => $answer)
+                   <li class="list-item">
+                        <input type="{{ $data['type'] === "multiple" ? 'checkbox' : 'radio' }}" name="{{ $data['type'] === "multiple" ? 'answer-'.$position.$key : 'answer' }}" id="question-{{$position.$key}}" class="none" value="{{$key}}">
+                        <label for="question-{{$position.$key}}">
+                            <span class="relative">{{$answer['answer']}}</span>
+                            <span class="access">{{$alphabet[$key]}}</span>
+                        </label>
+                   </li>
+                @endforeach
+            </ul>
+        </form>
+    </div>
+    <div class="screen-image">
+        <img src="{{$theme->standardImage}}">
+    </div>
+    @include('quizv2.footer', ['data' => $data, 'reset' => true, 'text' => 'Validate answer', 'info' => true])
+</div>
diff --git a/views/sprite.blade.php b/views/sprite.blade.php
new file mode 100644 (file)
index 0000000..29cc129
--- /dev/null
@@ -0,0 +1,47 @@
+{{--
+
+Downloaded from https://toolbox.fluidbook.com/tool-sprite/9/download
+Edit here : https://toolbox.fluidbook.com/tool-sprite/9/edit
+
+--}}<div class="svg-sprite" style="height: 0;width: 0;position: absolute;" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><symbol id="quiz-running-man" viewBox="0 0 18.998 26.45"><path d="M11.910 0.077 C 11.449 0.165,10.908 0.495,10.585 0.884 C 10.393 1.115,10.161 1.569,10.097 1.836 C 10.034 2.099,10.042 2.848,10.109 3.103 C 10.211 3.485,10.394 3.804,10.691 4.116 C 11.031 4.473,11.246 4.617,11.629 4.744 C 12.235 4.945,12.657 4.943,13.205 4.738 C 13.892 4.481,14.424 3.920,14.654 3.211 C 14.797 2.772,14.770 1.962,14.598 1.533 C 14.322 0.843,13.683 0.272,13.008 0.111 C 12.713 0.040,12.188 0.024,11.910 0.077 M8.588 5.892 C 7.363 6.522,5.722 7.424,5.330 7.683 C 4.997 7.902,4.636 8.267,4.396 8.625 C 4.162 8.975,4.088 9.121,3.959 9.483 C 3.787 9.963,3.769 10.133,3.748 11.446 C 3.720 13.187,3.753 13.379,4.147 13.754 C 4.421 14.016,4.563 14.071,4.971 14.073 C 5.377 14.075,5.515 14.021,5.795 13.754 C 6.093 13.470,6.141 13.341,6.174 12.740 C 6.189 12.464,6.211 11.810,6.222 11.288 C 6.246 10.208,6.250 10.189,6.508 9.912 C 6.590 9.825,6.770 9.681,6.908 9.592 C 7.210 9.399,7.881 9.042,7.903 9.064 C 7.971 9.132,6.569 17.719,6.407 18.222 C 6.305 18.542,6.160 18.709,5.863 18.849 C 5.502 19.019,5.439 19.006,3.166 18.286 C 1.903 17.887,1.709 17.841,1.391 17.868 C 1.002 17.900,0.649 18.148,0.468 18.516 C 0.372 18.712,0.364 18.750,0.364 19.045 C 0.364 19.322,0.375 19.385,0.448 19.540 C 0.573 19.808,0.740 19.973,1.007 20.098 C 1.479 20.316,4.412 21.260,4.925 21.358 C 5.357 21.441,5.846 21.407,6.359 21.258 C 7.229 21.006,7.882 20.532,8.370 19.799 C 8.713 19.283,8.789 19.044,9.053 17.621 C 9.274 16.432,9.283 16.389,9.312 16.357 C 9.342 16.324,9.702 16.611,10.465 17.277 C 11.167 17.889,11.524 18.248,11.628 18.445 L 11.712 18.605 11.733 22.039 L 11.754 25.473 11.859 25.664 C 12.016 25.950,12.197 26.138,12.425 26.250 C 12.756 26.413,13.154 26.426,13.472 26.284 C 13.634 26.211,13.907 25.942,14.064 25.699 L 14.185 25.511 14.185 21.948 L 14.185 18.385 14.058 18.012 C 13.806 17.271,13.540 16.804,13.136 16.398 C 13.008 16.269,12.586 15.880,12.198 15.535 C 11.811 15.190,11.494 14.903,11.494 14.897 C 11.494 14.871,11.975 12.540,12.110 11.908 C 12.287 11.086,12.350 10.829,12.377 10.829 C 12.388 10.829,12.524 11.039,12.680 11.296 C 13.343 12.392,13.661 12.780,14.193 13.144 C 14.706 13.495,14.997 13.592,16.618 13.953 C 17.576 14.166,17.807 14.155,18.233 13.875 C 18.632 13.612,18.839 13.025,18.698 12.551 C 18.638 12.349,18.450 12.080,18.276 11.947 C 18.104 11.816,17.844 11.736,16.750 11.477 C 16.259 11.361,15.807 11.236,15.714 11.191 C 15.425 11.050,15.254 10.808,14.359 9.277 C 13.552 7.898,12.884 6.789,12.765 6.632 C 12.551 6.347,12.293 6.236,11.082 5.907 C 10.230 5.676,9.726 5.573,9.441 5.573 C 9.209 5.573,9.209 5.573,8.588 5.892 " stroke="none" fill-rule="evenodd" fill="currentColor"></path></symbol><symbol id="quiz-arrow" viewBox="0 0 14.253 17.6"><path d="M6.965 0.026 C 6.699 0.077,6.762 0.008,3.897 3.444 C 0.352 7.697,0.394 7.643,0.357 7.826 C 0.323 7.987,0.344 8.195,0.407 8.330 C 0.464 8.451,0.668 8.658,0.796 8.725 C 0.874 8.766,0.934 8.775,1.128 8.776 C 1.344 8.776,1.377 8.770,1.487 8.710 C 1.658 8.616,1.709 8.556,4.537 5.169 L 6.259 3.107 6.277 3.210 C 6.286 3.267,6.301 6.387,6.309 10.143 L 6.325 16.973 6.396 17.108 C 6.491 17.290,6.608 17.423,6.742 17.502 C 6.846 17.563,6.871 17.567,7.127 17.567 C 7.382 17.567,7.407 17.563,7.511 17.502 C 7.645 17.423,7.762 17.290,7.857 17.108 L 7.928 16.973 7.943 10.132 C 7.951 6.369,7.964 3.240,7.973 3.179 L 7.988 3.067 8.218 3.345 C 9.700 5.133,12.272 8.212,12.439 8.397 C 12.556 8.528,12.704 8.667,12.767 8.706 C 12.875 8.772,12.898 8.777,13.110 8.776 C 13.292 8.775,13.362 8.765,13.452 8.724 C 13.583 8.665,13.775 8.477,13.836 8.350 C 13.892 8.231,13.920 8.010,13.899 7.852 C 13.884 7.740,13.859 7.692,13.729 7.525 C 13.352 7.037,11.966 5.352,10.158 3.183 C 7.737 0.280,7.629 0.156,7.441 0.077 C 7.306 0.020,7.104 -0.002,6.965 0.026 " stroke="none" fill-rule="evenodd" fill="currentColor"></path></symbol><symbol id="quiz-wrong" viewBox="0 0 70.711 70.711"><path d="M4.184 4.243 L -0.058 8.486 13.376 21.921 L 26.811 35.356 13.405 48.762 L -0.000 62.168 4.243 66.409 L 8.486 70.651 21.891 57.246 L 35.297 43.841 48.732 57.276 L 62.166 70.711 66.409 66.468 L 70.652 62.226 57.217 48.791 L 43.782 35.355 57.247 21.891 L 70.711 8.426 66.468 4.184 L 62.225 -0.058 48.761 13.406 L 35.297 26.870 21.861 13.435 L 8.426 -0.000 4.184 4.243 " stroke="none" fill-rule="evenodd" fill="currentColor"></path></symbol><symbol id="quiz-ok" viewBox="0 0 91.924 65.054"><path d="M59.367 24.054 L 35.315 48.107 21.869 34.663 L 8.422 21.219 4.221 25.509 L 0.020 29.799 17.600 47.379 C 27.268 57.048,35.244 64.960,35.323 64.960 C 35.403 64.960,48.171 52.257,63.696 36.731 L 91.925 8.502 87.672 4.251 L 83.420 0.001 59.367 24.054 " stroke="none" fill-rule="evenodd" fill="currentColor"></path></symbol><symbol id="quiz-reset" viewBox="0 0 26 26.213"><path d="M12.198 0.265 C 10.722 0.335,9.095 0.689,7.731 1.235 C 7.400 1.369,6.773 1.656,6.339 1.874 C 5.905 2.092,5.537 2.258,5.521 2.242 C 5.506 2.227,5.527 2.046,5.567 1.841 C 5.608 1.635,5.643 1.334,5.646 1.171 C 5.650 0.910,5.635 0.853,5.525 0.693 C 5.337 0.423,5.027 0.261,4.694 0.260 C 4.546 0.260,4.377 0.279,4.317 0.301 C 4.114 0.379,3.864 0.648,3.775 0.884 C 3.679 1.141,2.889 4.296,2.817 4.712 C 2.732 5.198,2.932 5.596,3.356 5.789 C 3.585 5.893,6.156 6.545,7.020 6.718 C 7.603 6.835,7.759 6.819,8.026 6.615 C 8.398 6.333,8.537 5.865,8.366 5.479 C 8.166 5.025,8.000 4.940,6.642 4.596 C 6.446 4.546,6.234 4.486,6.170 4.462 C 6.057 4.418,6.056 4.417,6.137 4.328 C 6.246 4.207,6.821 3.870,7.491 3.535 C 9.386 2.587,11.307 2.184,13.542 2.268 C 14.365 2.299,14.944 2.382,15.708 2.578 C 17.694 3.088,19.328 4.030,20.822 5.525 C 22.374 7.079,23.450 9.179,23.832 11.402 C 23.948 12.077,23.991 13.357,23.927 14.200 C 23.774 16.206,23.004 18.190,21.711 19.910 C 21.310 20.444,20.179 21.574,19.638 21.981 C 17.963 23.243,15.894 24.030,13.839 24.186 C 11.101 24.394,8.329 23.537,6.153 21.810 C 5.691 21.443,4.837 20.590,4.449 20.107 C 3.008 18.315,2.220 16.252,2.037 13.794 C 2.010 13.441,1.960 13.051,1.926 12.927 C 1.812 12.522,1.449 12.263,0.996 12.263 C 0.693 12.263,0.528 12.333,0.291 12.560 C -0.005 12.844,-0.065 13.345,0.062 14.473 C 0.403 17.507,1.612 20.113,3.660 22.226 C 5.598 24.225,7.801 25.417,10.682 26.024 C 11.226 26.138,11.302 26.143,12.917 26.163 L 14.589 26.184 15.399 26.004 C 18.299 25.358,20.447 24.185,22.360 22.204 C 24.182 20.317,25.302 18.107,25.827 15.362 C 25.944 14.751,25.988 13.106,25.919 11.982 C 25.787 9.860,24.815 7.331,23.407 5.451 C 21.727 3.206,19.229 1.472,16.622 0.740 C 15.229 0.349,13.762 0.191,12.198 0.265 " stroke="none" fill-rule="evenodd" fill="currentColor"></path></symbol><symbol id="quiz-help" viewBox="0 0 26 26"><path d="M11.787 0.066 C 9.687 0.328,8.300 0.766,6.654 1.687 C 5.479 2.345,4.862 2.816,3.842 3.834 C 2.693 4.981,2.064 5.840,1.391 7.182 C -0.177 10.308,-0.421 13.826,0.699 17.176 C 1.646 20.010,3.713 22.577,6.286 24.113 C 9.849 26.241,14.009 26.573,17.871 25.039 C 21.036 23.782,23.716 21.112,25.018 17.918 C 25.362 17.077,25.762 15.670,25.868 14.928 C 25.940 14.431,25.970 12.565,25.920 11.756 C 25.781 9.523,24.708 6.858,23.157 4.897 C 22.746 4.376,21.509 3.158,20.995 2.768 C 19.231 1.427,17.212 0.539,15.166 0.202 C 14.225 0.047,12.494 -0.023,11.787 0.066 M13.595 2.081 C 14.836 2.132,15.395 2.228,16.402 2.560 C 17.183 2.819,18.331 3.372,19.002 3.813 C 21.464 5.434,23.178 7.950,23.769 10.812 C 23.908 11.487,23.959 12.534,23.915 13.802 C 23.880 14.778,23.766 15.406,23.446 16.380 C 22.817 18.289,21.863 19.741,20.262 21.224 C 18.795 22.583,16.594 23.603,14.489 23.899 C 13.816 23.993,11.801 23.972,11.241 23.864 C 9.588 23.546,8.153 22.974,6.879 22.125 C 5.127 20.958,3.579 19.037,2.795 17.059 C 2.353 15.943,2.148 15.037,2.074 13.874 C 1.967 12.168,2.133 10.812,2.624 9.403 C 3.022 8.260,3.688 7.049,4.417 6.143 C 4.813 5.650,5.855 4.628,6.309 4.287 C 7.709 3.235,9.292 2.528,10.964 2.208 C 11.902 2.029,12.098 2.019,13.595 2.081 M12.198 6.569 C 11.286 6.773,10.386 7.396,9.859 8.189 C 9.533 8.679,9.302 9.342,9.248 9.942 C 9.206 10.401,9.276 10.620,9.552 10.904 C 9.857 11.216,10.151 11.292,10.532 11.157 C 10.942 11.013,11.135 10.764,11.223 10.268 C 11.374 9.414,11.678 8.945,12.273 8.648 C 12.475 8.548,12.546 8.537,13.000 8.537 C 13.459 8.537,13.524 8.547,13.739 8.654 C 14.041 8.803,14.423 9.185,14.573 9.488 C 14.680 9.703,14.690 9.767,14.689 10.224 C 14.688 10.627,14.672 10.762,14.604 10.911 C 14.320 11.537,13.821 11.896,13.096 11.996 C 12.663 12.056,12.296 12.258,12.142 12.520 L 12.025 12.718 12.025 13.913 L 12.025 15.108 12.156 15.320 C 12.575 15.999,13.453 15.991,13.855 15.306 C 13.967 15.114,13.975 15.065,13.990 14.490 L 14.006 13.879 14.340 13.741 C 15.264 13.359,16.036 12.625,16.432 11.753 C 16.652 11.267,16.727 10.887,16.726 10.252 C 16.725 9.607,16.662 9.250,16.472 8.802 C 16.014 7.726,15.135 6.957,13.989 6.628 C 13.557 6.504,12.628 6.473,12.198 6.569 M12.665 17.679 C 12.214 17.748,11.713 18.284,11.661 18.752 C 11.584 19.447,11.823 19.927,12.383 20.202 C 12.641 20.329,12.712 20.345,13.021 20.342 C 13.586 20.338,13.976 20.096,14.221 19.599 C 14.402 19.231,14.416 18.828,14.259 18.470 C 14.127 18.169,13.731 17.799,13.471 17.733 C 13.211 17.667,12.884 17.645,12.665 17.679 " stroke="none" fill-rule="evenodd" fill="currentColor"></path></symbol><symbol id="quiz-hourglass" viewBox="0 0 22 26.004"><path d="M0.787 0.072 C 0.554 0.107,0.402 0.185,0.278 0.334 C -0.077 0.756,-0.079 1.249,0.274 1.641 C 0.537 1.934,0.709 1.990,1.403 2.009 L 1.980 2.025 1.982 2.837 C 1.984 3.930,2.036 4.986,2.103 5.298 C 2.218 5.832,2.527 6.580,2.815 7.023 C 3.070 7.417,3.381 7.756,6.125 10.639 L 7.734 12.329 6.751 13.360 C 3.193 17.095,3.051 17.251,2.710 17.801 C 2.415 18.278,2.141 19.046,2.050 19.653 C 2.027 19.812,1.999 20.779,1.985 21.945 L 1.962 23.962 1.375 23.985 C 0.981 24.000,0.746 24.026,0.660 24.063 C 0.314 24.211,0.061 24.527,0.014 24.869 C -0.037 25.239,0.224 25.693,0.595 25.878 L 0.760 25.960 11.005 25.960 L 21.249 25.960 21.396 25.883 C 22.020 25.554,22.169 24.845,21.725 24.317 C 21.673 24.255,21.540 24.160,21.430 24.106 C 21.246 24.016,21.181 24.006,20.660 23.989 C 20.305 23.977,20.082 23.954,20.066 23.929 C 20.052 23.907,20.029 22.963,20.014 21.832 C 19.984 19.600,19.979 19.541,19.759 18.868 C 19.619 18.442,19.261 17.716,19.056 17.445 C 18.969 17.330,18.727 17.049,18.518 16.822 C 18.200 16.476,15.511 13.635,14.550 12.631 L 14.269 12.337 14.478 12.117 C 14.593 11.997,15.414 11.131,16.302 10.193 C 19.151 7.185,19.114 7.228,19.450 6.545 C 19.670 6.099,19.804 5.719,19.892 5.293 C 19.966 4.932,20.018 3.949,20.019 2.874 L 20.020 2.025 20.598 2.009 C 21.280 1.990,21.455 1.935,21.718 1.653 C 22.082 1.264,22.077 0.739,21.703 0.314 C 21.454 0.030,22.495 0.056,11.147 0.050 C 5.550 0.047,0.889 0.057,0.787 0.072 M18.002 2.594 C 18.001 3.494,17.938 4.884,17.890 5.082 C 17.826 5.348,17.597 5.818,17.409 6.068 C 17.238 6.296,16.875 6.685,14.465 9.222 C 12.926 10.842,12.306 11.508,12.092 11.771 C 11.935 11.965,11.866 12.216,11.902 12.463 C 11.952 12.805,11.927 12.776,13.950 14.905 C 17.646 18.795,17.628 18.774,17.833 19.393 C 17.933 19.696,17.934 19.714,17.968 21.079 C 17.986 21.838,18.002 22.801,18.002 23.219 L 18.003 23.980 11.000 23.980 L 3.997 23.980 3.998 23.073 C 4.001 21.718,4.062 19.731,4.107 19.545 C 4.169 19.290,4.428 18.801,4.643 18.531 C 4.843 18.280,5.561 17.513,7.639 15.332 C 9.199 13.695,9.803 13.038,9.966 12.801 C 10.092 12.618,10.101 12.586,10.099 12.343 C 10.097 12.153,10.076 12.041,10.020 11.935 C 9.908 11.719,9.925 11.737,7.036 8.690 C 5.956 7.551,4.963 6.497,4.828 6.349 C 4.447 5.931,4.152 5.371,4.072 4.918 C 4.052 4.805,4.025 4.105,4.011 3.364 L 3.985 2.017 10.994 2.017 L 18.003 2.017 18.002 2.594 M10.648 13.790 C 10.492 13.835,10.206 14.094,10.112 14.277 C 10.039 14.417,10.034 14.485,10.032 15.218 L 10.030 16.007 10.130 16.178 C 10.496 16.802,11.358 16.860,11.793 16.289 C 11.969 16.059,12.004 15.828,11.979 15.062 C 11.955 14.318,11.931 14.237,11.668 14.006 C 11.414 13.782,10.987 13.691,10.648 13.790 M10.721 17.515 C 10.679 17.524,10.514 17.635,10.355 17.762 C 10.004 18.043,6.415 21.651,6.191 21.948 C 6.032 22.159,6.032 22.160,6.034 22.463 C 6.037 22.732,6.049 22.786,6.146 22.942 C 6.206 23.040,6.340 23.177,6.449 23.254 C 6.863 23.543,7.239 23.516,7.645 23.170 C 7.766 23.067,8.570 22.290,9.432 21.443 L 11.000 19.904 12.568 21.443 C 14.365 23.208,14.513 23.342,14.718 23.398 C 14.943 23.459,15.304 23.413,15.497 23.300 C 15.689 23.188,15.892 22.923,15.953 22.705 C 16.011 22.496,15.974 22.212,15.863 22.022 C 15.759 21.845,12.814 18.851,12.031 18.126 C 11.741 17.858,11.435 17.605,11.351 17.564 C 11.205 17.494,10.936 17.473,10.721 17.515 " stroke="none" fill-rule="evenodd" fill="currentColor"></path></symbol></svg></div>
+<script>
+    function getSpriteIcon(icon, attrs, dimensions) {
+        var a = [];
+        var iconSymbol = $('svg symbol[id="' + icon + '"]');
+        if (iconSymbol.length > 1) {
+            $('svg symbol[id="' + icon + '"]:not(:last)').remove();
+            iconSymbol = $('svg symbol[id="' + icon + '"]');
+        }
+
+        if (iconSymbol.length == 0) {
+            return ''; // Bail out because symbol doesn't exist
+        }
+
+        if (attrs == undefined) {
+            attrs = {};
+        }
+        if (attrs.viewBox == null) {
+            attrs.viewBox = iconSymbol.get(0).attributes.viewBox.value;
+        }
+        if (dimensions === true) {
+            var vb = attrs.viewBox.split(' ');
+            attrs.x = vb[0];
+            attrs.y = vb[1];
+            attrs.width = vb[2];
+            attrs.height = vb[3];
+        }
+        if (attrs.class == null) {
+            attrs.class = icon;
+        } else {
+            attrs.class += ' ' + icon;
+        }
+
+        attrs.class += ' nav-icon svg-icon'; // Common class for all icons
+
+        $.each(attrs, function (k, v) {
+            a.push(k + '="' + v + '"');
+        });
+        return '<svg ' + a.join(' ') + ' aria-hidden="true"><use xlink:href="#' + icon + '" /></svg>';
+    }
+
+</script>