changeset 3127:a8455b0766cd

Merge branch 'hot_fix' into vnext
author Nicholas Jillings <nicholas.jillings@mail.bcu.ac.uk>
date Wed, 28 Nov 2018 13:51:51 +0000
parents aa4503f8c630 (diff) cb227441a102 (current diff)
children 5419fc9cbb15
files interfaces/ordinal.js python/score_parser.py
diffstat 41 files changed, 1878 insertions(+), 1251 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.brackets.json	Wed Nov 28 13:51:51 2018 +0000
@@ -0,0 +1,12 @@
+{
+    "brackets-minifier.on-save-project": false,
+    "brackets-minifier.js-project-minify": true,
+    "brackets-minifier.css-project-minify": true,
+    "brackets-minifier.js-custom-path": "",
+    "brackets-minifier.css-custom-path": "",
+    "brackets-minifier.project-exclude": "",
+    "brackets-minifier.concat-js-filename": "",
+    "brackets-minifier.concat-css-filename": "",
+    "brackets-minifier.uglifyjs-options": "{}",
+    "brackets-minifier.cleancss-options": "{}"
+}
\ No newline at end of file
--- a/.gitignore	Wed Nov 28 13:50:22 2018 +0000
+++ b/.gitignore	Wed Nov 28 13:51:51 2018 +0000
@@ -11,3 +11,6 @@
 *.DS_STORE
 *.swp
 *.swo
+saves/ratings/*
+saves/timelines/*
+saves/timelines_movement/*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/css/bootstrap.min.css	Wed Nov 28 13:51:51 2018 +0000
@@ -0,0 +1,6 @@
+/*!
+ * Bootstrap v3.3.7 (http://getbootstrap.com)
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}
+/*# sourceMappingURL=bootstrap.min.css.map */
\ No newline at end of file
--- a/css/core.css	Wed Nov 28 13:50:22 2018 +0000
+++ b/css/core.css	Wed Nov 28 13:51:51 2018 +0000
@@ -199,6 +199,7 @@
 div.master-volume-holder-inline {
     width: 100%;
     padding: 5px;
+    float: left;
 }
 div.master-volume-holder-float {
     position: absolute;
@@ -239,7 +240,7 @@
     height: auto;
 }
 div.calibration-slider {
-    width: 50px;
+    width: 44px;
     margin: 2px;
     text-align: center;
     align-content: center;
@@ -252,7 +253,15 @@
     /* WebKit */
     width: 8px;
     padding: 0 5px;
-    height: 290px;
+    height: 200px;
+}
+button.calibration-button {
+    height: 25px;
+    border-radius: 5px;
+    border: #444;
+    border-width: 1px;
+    border-style: solid;
+    background-color: white;
 }
 
 /*  Comment Boxes */
--- a/index.html	Wed Nov 28 13:50:22 2018 +0000
+++ b/index.html	Wed Nov 28 13:51:51 2018 +0000
@@ -24,7 +24,7 @@
 
 <body>
     <div id='topLevelBody'>
-        <h1><a target="_blank" href="https://github.com/BrechtDeMan/WebAudioEvaluationTool">Web Audio Evaluation Toolbox (v1.2.2)</a></h1>
+        <h1><a target="_blank" href="https://github.com/BrechtDeMan/WebAudioEvaluationTool">Web Audio Evaluation Toolbox (v1.2.3)</a></h1>
         <h2>Start menu </h2>
         <ul>
             <li><a href="test.html?url=tests/examples/AB_example.xml" target="_blank">AB interface test example</a></li>
@@ -54,7 +54,7 @@
         <button id="popup-previous" class="popupButton">Back</button>
     </div>
     <div class="testHalt" style="visibility: hidden"></div>
-    <div id="footer"><a target="_blank" href="https://github.com/BrechtDeMan/WebAudioEvaluationTool">Web Audio Evaluation Toolbox (v1.2.2)</a></div>
+    <div id="footer"><a target="_blank" href="https://github.com/BrechtDeMan/WebAudioEvaluationTool">Web Audio Evaluation Toolbox (v1.2.3)</a></div>
 </body>
 
 </html>
--- a/interfaces/AB.css	Wed Nov 28 13:50:22 2018 +0000
+++ b/interfaces/AB.css	Wed Nov 28 13:51:51 2018 +0000
@@ -24,6 +24,10 @@
     height: 40px;
     font-size: 1.2em;
 }
+div#submit-holder {
+    width: 100%;
+    text-align: center;
+}
 div.interface-buttons {
     height: 40px;
 }
--- a/interfaces/AB.js	Wed Nov 28 13:50:22 2018 +0000
+++ b/interfaces/AB.js	Wed Nov 28 13:51:51 2018 +0000
@@ -75,13 +75,14 @@
     var boxes = document.createElement('div');
     boxes.id = "box-holders";
 
+    var submitHolder = document.createElement("div");
+    submitHolder.id = "submit-holder";
     var submit = document.createElement('button');
     submit.id = "submit";
     submit.onclick = buttonSubmitClick;
     submit.className = "big-button";
-    submit.textContent = "submit";
-    submit.style.position = "relative";
-    submit.style.left = (window.innerWidth - 250) / 2 + 'px';
+    submit.textContent = "Submit";
+    submitHolder.appendChild(submit);
 
     feedbackHolder.appendChild(boxes);
 
@@ -95,7 +96,7 @@
     testContent.appendChild(interfaceButtons);
     testContent.appendChild(outsideRef);
     testContent.appendChild(feedbackHolder);
-    testContent.appendChild(submit);
+    testContent.appendChild(submitHolder);
     testContent.appendChild(comments);
     interfaceContext.insertPoint.appendChild(testContent);
 
@@ -395,10 +396,13 @@
 function buttonSubmitClick() {
     var checks = testState.currentStateMap.interfaces[0].options,
         canContinue = true;
-    
+
     if (interfaceContext.checkFragmentMinPlays() === false) {
-    return;
-}
+        return;
+    }
+    if (interfaceContext.checkCommentQuestions() === false) {
+        return;
+    }
 
     for (var i = 0; i < checks.length; i++) {
         if (checks[i].type == 'check') {
--- a/interfaces/ABX.css	Wed Nov 28 13:50:22 2018 +0000
+++ b/interfaces/ABX.css	Wed Nov 28 13:51:51 2018 +0000
@@ -20,9 +20,12 @@
     height: 40px;
     font-size: 1.2em;
 }
+div#submit-holder {
+    width: 100%;
+    text-align: center;
+}
 div#box-holders {
     width: 100%;
-    text-align: center;
 }
 div#playback-holder {
     float: none;
--- a/interfaces/ABX.js	Wed Nov 28 13:50:22 2018 +0000
+++ b/interfaces/ABX.js	Wed Nov 28 13:51:51 2018 +0000
@@ -77,15 +77,15 @@
     var boxes = document.createElement('div');
     boxes.align = "center";
     boxes.id = "box-holders";
-    boxes.style.float = "left";
 
+    var submitHolder = document.createElement("div");
+    submitHolder.id = "submit-holder";
     var submit = document.createElement('button');
     submit.id = "submit";
     submit.onclick = buttonSubmitClick;
     submit.className = "big-button";
     submit.textContent = "submit";
-    submit.style.position = "relative";
-    submit.style.left = (window.innerWidth - 250) / 2 + 'px';
+    submitHolder.appendChild(submit);
 
     feedbackHolder.appendChild(boxes);
 
@@ -98,7 +98,7 @@
     testContent.appendChild(pagetitle);
     testContent.appendChild(interfaceButtons);
     testContent.appendChild(feedbackHolder);
-    testContent.appendChild(submit);
+    testContent.appendChild(submitHolder);
     testContent.appendChild(comments);
     interfaceContext.insertPoint.appendChild(testContent);
 
@@ -424,9 +424,6 @@
         boxW = numObj * 312;
         diff = window.innerWidth - boxW;
     }
-    document.getElementById('box-holders').style.marginLeft = diff / 2 + 'px';
-    document.getElementById('box-holders').style.marginRight = diff / 2 + 'px';
-    document.getElementById('box-holders').style.width = boxW + 'px';
 }
 
 function buttonSubmitClick() {
@@ -436,6 +433,9 @@
     if (interfaceContext.checkFragmentMinPlays() === false) {
         return;
     }
+    if (interfaceContext.checkCommentQuestions() === false) {
+        return;
+    }
 
     for (var i = 0; i < checks.length; i++) {
         var checkState = true;
--- a/interfaces/ape.css	Wed Nov 28 13:50:22 2018 +0000
+++ b/interfaces/ape.css	Wed Nov 28 13:51:51 2018 +0000
@@ -26,7 +26,6 @@
 }
 div.slider {
     /* Specify any structure for the slider holder interface */
-    background-color: #eee;
     height: 150px;
     margin: 5px 50px;
     -moz-user-select: -moz-none;
@@ -61,6 +60,12 @@
     -webkit-user-select: none;
     border: 1px solid black;
 }
+canvas.tick-canvas {
+    z-index: -1;
+    position: absolute;
+    height: 150px;
+    background-color: #eee;
+}
 div#outside-reference-holder {
     display: flex;
     align-content: center;
--- a/interfaces/ape.js	Wed Nov 28 13:50:22 2018 +0000
+++ b/interfaces/ape.js	Wed Nov 28 13:51:51 2018 +0000
@@ -4,7 +4,7 @@
  */
 
 /*globals window,interfaceContext, document, audioEngineContext, console, $, Interface, testState, storage, specification */
-/*globals metricTracker */
+/*globals metricTracker, module, randomiseOrder */
 // Once this is loaded and parsed, begin execution
 loadInterface();
 
@@ -21,136 +21,15 @@
     testContent.id = 'testContent';
 
     // Bindings for interfaceContext
-    interfaceContext.checkAllPlayed = function () {
-        var hasBeenPlayed = audioEngineContext.checkAllPlayed();
-        if (hasBeenPlayed.length > 0) // if a fragment has not been played yet
-        {
-            var str = "";
-            if (hasBeenPlayed.length > 1) {
-                for (var i = 0; i < hasBeenPlayed.length; i++) {
-                    var ao_id = audioEngineContext.audioObjects[hasBeenPlayed[i]].interfaceDOM.getPresentedId();
-                    str = str + ao_id; // start from 1
-                    if (i < hasBeenPlayed.length - 2) {
-                        str += ", ";
-                    } else if (i == hasBeenPlayed.length - 2) {
-                        str += " or ";
-                    }
-                }
-                str = 'You have not played fragments ' + str + ' yet. Please listen, rate and comment all samples before submitting.';
-            } else {
-                str = 'You have not played fragment ' + (audioEngineContext.audioObjects[hasBeenPlayed[0]].interfaceDOM.getPresentedId()) + ' yet. Please listen, rate and comment all samples before submitting.';
-            }
-            this.storeErrorNode(str);
-            interfaceContext.lightbox.post("Message", str);
-            return false;
-        }
-        return true;
-    };
 
     interfaceContext.checkAllMoved = function () {
-        var state = true;
-        var str = 'You have not moved the following sliders. ';
-        for (var i = 0; i < this.interfaceSliders.length; i++) {
-            var interfaceTID = [];
-            for (var j = 0; j < this.interfaceSliders[i].metrics.length; j++) {
-                var ao_id = this.interfaceSliders[i].sliders[j].getAttribute("trackIndex");
-                if (this.interfaceSliders[i].metrics[j].wasMoved === false && audioEngineContext.audioObjects[ao_id].interfaceDOM.canMove()) {
-                    state = false;
-                    interfaceTID.push(j);
-                }
-            }
-            if (interfaceTID.length !== 0) {
-                var interfaceName = this.interfaceSliders[i].interfaceObject.title;
-                if (interfaceName === undefined) {
-                    str += 'On axis ' + String(i + 1) + ' you must move ';
-                } else {
-                    str += 'On axis "' + interfaceName + '" you must move ';
-                }
-                if (interfaceTID.length == 1) {
-                    str += 'slider ' + (audioEngineContext.audioObjects[interfaceTID[0]].interfaceDOM.getPresentedId()) + '. '; // start from 1
-                } else {
-                    str += 'sliders ';
-                    for (var k = 0; k < interfaceTID.length - 1; k++) {
-                        str += (audioEngineContext.audioObjects[interfaceTID[k]].interfaceDOM.getPresentedId()) + ', '; // start from 1
-                    }
-                    str += (audioEngineContext.audioObjects[interfaceTID[interfaceTID.length - 1]].interfaceDOM.getPresentedId()) + '. ';
-                }
-            }
-        }
-        if (state !== true) {
-            this.storeErrorNode(str);
-            interfaceContext.lightbox.post("Message", str);
-            console.log(str);
-        }
-        return state;
+        return module.checkAllMoved();
     };
 
     interfaceContext.checkScaleRange = function () {
-        var audioObjs = audioEngineContext.audioObjects;
-        var audioHolder = testState.stateMap[testState.stateIndex];
-        var interfaceObject = this.interfaceSliders[0].interfaceObject;
-        var state = true;
-        var str = '';
-        this.interfaceSliders.forEach(function (sliderHolder, i) {
-            var scales = (function () {
-                var scaleRange = interfaceObject.options.find(function (a) {
-                    return a.name == "scalerange";
-                });
-                return {
-                    min: scaleRange.min,
-                    max: scaleRange.max
-                };
-            })();
-            var range = sliderHolder.sliders.reduce(function (a, b) {
-                var v = convSliderPosToRate(b) * 100.0;
-                return {
-                    min: Math.min(a.min, v),
-                    max: Math.max(a.max, v)
-                };
-            }, {
-                min: 100,
-                max: 0
-            });
-            if (range.min >= scales.min || range.max <= scales.max) {
-                state = false;
-                str += 'On axis "' + sliderHolder.interfaceObject.title + '" you have not used the full width of the scale. ';
-            }
-        });
-        if (state !== true) {
-            this.storeErrorNode(str);
-            interfaceContext.lightbox.post("Message", str);
-            console.log(str);
-        }
-        return state;
+        return module.checkScaleRange();
     };
 
-    Interface.prototype.objectSelected = null;
-    Interface.prototype.objectMoved = false;
-    Interface.prototype.selectObject = function (object) {
-        if (this.objectSelected === null) {
-            this.objectSelected = object;
-            this.objectMoved = false;
-        }
-    };
-    Interface.prototype.moveObject = function () {
-        if (this.objectMoved === false) {
-            this.objectMoved = true;
-        }
-    };
-    Interface.prototype.releaseObject = function () {
-        this.objectSelected = null;
-        this.objectMoved = false;
-    };
-    Interface.prototype.getSelectedObject = function () {
-        return this.objectSelected;
-    };
-    Interface.prototype.hasSelectedObjectMoved = function () {
-        return this.objectMoved;
-    };
-
-    // Bindings for slider interfaces
-    Interface.prototype.interfaceSliders = [];
-
     // Bindings for audioObjects
 
     // Create the top div for the Title element
@@ -220,12 +99,13 @@
     interfaceContext.insertPoint.appendChild(testContent);
 
     // Load the full interface
+    window.module = new ape();
     testState.initialise();
     testState.advanceState();
-
 }
 
 function loadTest(audioHolderObject) {
+    module.clear();
     var width = window.innerWidth;
     var height = window.innerHeight;
     var id = audioHolderObject.id;
@@ -246,15 +126,10 @@
         document.getElementById("test-title").textContent = audioHolderObject.title;
     }
 
-
     // Delete outside reference
     document.getElementById("outside-reference-holder").innerHTML = "";
 
     var interfaceObj = interfaceContext.getCombinedInterfaces(audioHolderObject);
-    interfaceObj.forEach(function (interfaceObjectInstance) {
-        // Create the div box to center align
-        interfaceContext.interfaceSliders.push(new interfaceSliderHolder(interfaceObjectInstance, audioHolderObject));
-    });
     interfaceObj.forEach(function (interface) {
         interface.options.forEach(function (option) {
             if (option.type == "show") {
@@ -298,113 +173,7 @@
 
     var loopPlayback = audioHolderObject.loop;
 
-    var currentTestHolder = document.createElement('audioHolder');
-    currentTestHolder.id = audioHolderObject.id;
-    currentTestHolder.repeatCount = audioHolderObject.repeatCount;
-
-    // Find all the audioElements from the audioHolder
-    $(audioHolderObject.audioElements).each(function (index, element) {
-        // Find URL of track
-        // In this jQuery loop, variable 'this' holds the current audioElement.
-        var audioObject = audioEngineContext.newTrack(element);
-        // Check if an outside reference
-        if (element.type == 'outside-reference') {
-            // Construct outside reference;
-            var orNode = new outsideReferenceDOM(audioObject, index, document.getElementById("outside-reference-holder"));
-            audioObject.bindInterface(orNode);
-        } else {
-            // Create a slider per track
-            var sliderNode = new sliderObject(audioObject, interfaceObj, index);
-            audioObject.bindInterface(sliderNode);
-            interfaceContext.commentBoxes.createCommentBox(audioObject);
-        }
-    });
-
-    // Initialse the interfaceSlider object metrics
-
-    $('.track-slider').mousedown(function (event) {
-        interfaceContext.selectObject($(this)[0]);
-    });
-    $('.track-slider').on('touchstart', null, function (event) {
-        interfaceContext.selectObject($(this)[0]);
-    });
-
-    $('.track-slider').mousemove(function (event) {
-        event.preventDefault();
-    });
-
-    $('.slider').mousemove(function (event) {
-        event.preventDefault();
-        var obj = interfaceContext.getSelectedObject();
-        if (obj === null) {
-            return;
-        }
-        var move = event.clientX - 6;
-        var w = $(event.currentTarget).width();
-        move = Math.max(50, move);
-        move = Math.min(w + 50, move);
-        $(obj).css("left", move + "px");
-        interfaceContext.moveObject();
-    });
-
-    $('.slider').on('touchmove', null, function (event) {
-        event.preventDefault();
-        var obj = interfaceContext.getSelectedObject();
-        if (obj === null) {
-            return;
-        }
-        var move = event.originalEvent.targetTouches[0].clientX - 6;
-        var w = $(event.currentTarget).width();
-        move = Math.max(50, move);
-        move = Math.min(w + 50, move);
-        $(obj).css("left", move + "px");
-        interfaceContext.moveObject();
-    });
-
-    $(document).mouseup(function (event) {
-        event.preventDefault();
-        var obj = interfaceContext.getSelectedObject();
-        if (obj === null) {
-            return;
-        }
-        var interfaceID = obj.parentElement.getAttribute("interfaceid");
-        var trackID = obj.getAttribute("trackindex");
-        var id;
-        if (interfaceContext.hasSelectedObjectMoved() === true) {
-            var l = $(obj).css("left");
-            id = obj.getAttribute('trackIndex');
-            var time = audioEngineContext.timer.getTestTime();
-            var rate = convSliderPosToRate(obj);
-            audioEngineContext.audioObjects[id].metric.moved(time, rate);
-            interfaceContext.interfaceSliders[interfaceID].metrics[trackID].moved(time, rate);
-            console.log("slider " + id + " moved to " + rate + ' (' + time + ')');
-            obj.setAttribute("slider-value", convSliderPosToRate(obj));
-        } else {
-            id = Number(obj.attributes.trackIndex.value);
-            //audioEngineContext.metric.sliderPlayed(id);
-            audioEngineContext.play(id);
-        }
-        interfaceContext.releaseObject();
-    });
-
-    $('.slider').on('touchend', null, function (event) {
-        var obj = interfaceContext.getSelectedObject();
-        if (obj === null) {
-            return;
-        }
-        var interfaceID = obj.parentElement.getAttribute("interfaceid");
-        var trackID = obj.getAttribute("trackindex");
-        if (interfaceContext.hasSelectedObjectMoved() === true) {
-            var l = $(obj).css("left");
-            var id = obj.getAttribute('trackIndex');
-            var time = audioEngineContext.timer.getTestTime();
-            var rate = convSliderPosToRate(obj);
-            audioEngineContext.audioObjects[id].metric.moved(time, rate);
-            interfaceContext.interfaceSliders[interfaceID].metrics[trackID].moved(time, rate);
-            console.log("slider " + id + " moved to " + rate + ' (' + time + ')');
-        }
-        interfaceContext.releaseObject();
-    });
+    module.initialisePage(audioHolderObject);
 
     var interfaceList = audioHolderObject.interfaces.concat(specification.interfaces);
     for (var k = 0; k < interfaceList.length; k++) {
@@ -445,238 +214,561 @@
     });
 
     //testWaitIndicator();
+    module.resize();
 }
 
-function interfaceSliderHolder(interfaceObject, page) {
-    this.sliders = [];
-    this.metrics = [];
-    this.id = document.getElementsByClassName("sliderCanvasDiv").length;
-    this.name = interfaceObject.name;
-    this.interfaceObject = interfaceObject;
-    this.sliderDOM = document.createElement('div');
-    this.sliderDOM.className = 'sliderCanvasDiv';
-    this.sliderDOM.id = 'sliderCanvasHolder-' + this.id;
-    this.imageHolder = (function () {
-        var imageController = {};
-        imageController.root = document.createElement("div");
-        imageController.root.className = "imageController";
-        imageController.img = document.createElement("img");
-        imageController.root.appendChild(imageController.img);
-        imageController.setImage = function (src) {
-            imageController.img.src = "";
-            if (typeof src !== "string" || src.length === undefined) {
+function ape() {
+    var axis = [];
+    var DOMRoot = document.getElementById("slider-holder");
+    var AOIs = [];
+    var page;
+
+    function audioObjectInterface(audioObject, parent) {
+        // The audioObject communicates with this object
+        var playing = false;
+        var sliders = [];
+        this.enable = function () {
+            sliders.forEach(function (s) {
+                s.enable();
+            });
+        };
+
+        this.updateLoading = function (p) {
+            sliders.forEach(function (s) {
+                s.updateLoading(p);
+            });
+        };
+
+        this.startPlayback = function () {
+            playing = true;
+            sliders.forEach(function (s) {
+                s.playing();
+            });
+        };
+
+        this.stopPlayback = function () {
+            playing = false;
+            sliders.forEach(function (s) {
+                s.stopped();
+            });
+        };
+
+        this.getValue = function () {
+            return sliders[0].value;
+        };
+
+        this.getPresentedId = function () {
+            return sliders[0].label;
+        };
+
+        this.canMove = function () {
+            return true;
+        };
+
+        this.exportXMLDOM = function (audioObject) {
+            var elements = [];
+            sliders.forEach(function (s) {
+                elements.push(s.exportXMLDOM());
+            });
+            return elements;
+        };
+
+        this.error = function () {
+            sliders.forEach(function (s) {
+                s.error();
+            });
+        };
+
+        this.addSlider = function (s) {
+            sliders.push(s);
+        };
+
+        this.clicked = function (event) {
+            if (!playing) {
+                audioEngineContext.play(audioObject.id);
+            } else {
+                audioEngineContext.stop();
+            }
+            playing = !playing;
+        };
+
+        this.pageXMLSave = function (store) {
+            var inject = audioObject.storeDOM.getElementsByTagName("metric")[0];
+            sliders.forEach(function (s) {
+                s.pageXMLSave(inject);
+            });
+        };
+
+    }
+
+    function axisObject(interfaceObject, parent) {
+
+        function sliderInterface(AOI, axisInterface) {
+            var trackObj = document.createElement('div');
+            var labelHolder = document.createElement("span");
+            var label = "";
+            var metric = new metricTracker(this);
+            var value = Math.random();
+            trackObj.align = "center";
+            trackObj.className = 'track-slider track-slider-disabled';
+            trackObj.appendChild(labelHolder);
+            axisInterface.sliderRail.appendChild(trackObj);
+            metric.initialise(this.value);
+            this.setLabel = function (s) {
+                label = s;
+            };
+            this.resize = function (event) {
+                var width = $(axisInterface.sliderRail).width();
+                var w = Number(value * width);
+                trackObj.style.left = String(w) + "px";
+            };
+            this.playing = function () {
+                trackObj.classList.add("track-slider-playing");
+            };
+            this.stopped = function () {
+                trackObj.classList.remove("track-slider-playing");
+            };
+            this.enable = function () {
+                trackObj.addEventListener("mousedown", this);
+                trackObj.addEventListener("mouseup", this);
+                trackObj.classList.remove("track-slider-disabled");
+                labelHolder.textContent = label;
+            };
+            this.updateLoading = function (progress) {
+                labelHolder.textContent = progress + "%";
+            };
+            this.exportXMLDOM = function () {
+                var node = storage.document.createElement('value');
+                node.setAttribute("interface-name", axisInterface.name);
+                node.textContent = this.value;
+                return node;
+            };
+            this.error = function () {
+                trackObj.classList.add("error-colour");
+                trackObj.removeEventListener("mousedown");
+                trackObj.removeEventListener("mouseup");
+            };
+            var timing;
+            this.handleEvent = function (e) {
+                // This is only for the mousedown / touchdown
+                if (e.preventDefault) {
+                    e.preventDefault();
+                }
+                if (e.type == "mousedown") {
+                    axisInterface.mousedown(this);
+                } else if (e.type == "mouseup" || e.type == "touchend" || e.type == "touchcancel") {
+                    axisInterface.mouseup(this);
+                    metric.moved(audioEngineContext.timer.getTestTime(), this.value);
+                    console.log("Slider " + label + " on axis " + axisInterface.name + " moved to " + this.value);
+                }
+            };
+            this.clicked = function (e) {
+                AOI.clicked();
+            };
+            this.pageXMLSave = function (inject) {
+                var nodes = metric.exportXMLDOM(inject);
+                nodes.forEach(function (elem) {
+                    var name = elem.getAttribute("name");
+                    if (name == "elementTracker" || name == "elementTrackerFull" || name == "elementInitialPosition" || name == "elementFlagMoved") {
+                        elem.setAttribute("interface-name", axisInterface.name);
+                    } else {
+                        inject.removeChild(elem);
+                    }
+                });
+            };
+            this.hasMoved = function () {
+                return metric.wasMoved;
+            };
+            Object.defineProperties(this, {
+                "DOM": {
+                    "value": trackObj
+                },
+                "value": {
+                    "get": function () {
+                        return value;
+                    },
+                    "set": function (v) {
+                        if (v >= 0 && v <= 1) {
+                            value = v;
+                        }
+                        this.resize();
+                        return value;
+                    }
+                },
+                "label": {
+                    "get": function () {
+                        return label;
+                    },
+                    "set": function () {}
+                },
+                "metric": {
+                    "value": metric
+                }
+            });
+        }
+
+        function drawTick(position) {
+            var context = tickCanvas.getContext("2d"),
+                w = tickCanvas.width,
+                h = tickCanvas.height;
+            context.beginPath();
+            context.setLineDash([1, 2]);
+            context.moveTo(position * w, 0);
+            context.lineTo(position * w, h);
+            context.closePath();
+            context.stroke();
+        }
+
+        function clearTicks() {
+            var c = tickCanvas.getContext("2d"),
+                w = tickCanvas.width,
+                h = tickCanvas.height;
+            c.clearRect(0, 0, w, h);
+        }
+
+        function createScaleMarkers(interfaceObject, root, w) {
+            var ticks = interfaceObject.options.findIndex(function (a) {
+                return (a.type == "show" && a.name == "ticks");
+            });
+            ticks = (ticks >= 0);
+            clearTicks();
+            interfaceObject.scales.forEach(function (scaleObj) {
+                var position = Number(scaleObj.position) * 0.01;
+                var pixelPosition = (position * w) + 50;
+                var scaleDOM = document.createElement('span');
+                scaleDOM.className = "ape-marker-text";
+                scaleDOM.textContent = scaleObj.text;
+                scaleDOM.setAttribute('value', position);
+                root.appendChild(scaleDOM);
+                scaleDOM.style.left = Math.floor((pixelPosition - ($(scaleDOM).width() / 2))) + 'px';
+                if (ticks) {
+                    drawTick(position);
+                }
+            }, this);
+        }
+        var sliders = [];
+        var UI = {
+            selected: undefined,
+            startTime: undefined
+        };
+        this.name = interfaceObject.name;
+        var DOMRoot = document.createElement("div");
+        parent.getDOMRoot().appendChild(DOMRoot);
+        DOMRoot.className = "sliderCanvasDiv";
+        DOMRoot.id = "sliderCanvasHolder-" + this.name;
+
+        var axisTitle = document.createElement("div");
+        axisTitle.className = "pageTitle";
+        axisTitle.align = "center";
+        var titleSpan = document.createElement('span');
+        titleSpan.id = "pageTitle-" + this.name;
+        if (interfaceObject.title !== undefined && typeof interfaceObject.title == "string") {
+            titleSpan.textContent = interfaceObject.title;
+        } else {
+            titleSpan.textContent = "Axis " + String(this.id + 1);
+        }
+        axisTitle.appendChild(titleSpan);
+        DOMRoot.appendChild(axisTitle);
+
+        var imageHolder = (function () {
+            var imageController = {};
+            imageController.root = document.createElement("div");
+            imageController.root.className = "imageController";
+            imageController.img = document.createElement("img");
+            imageController.root.appendChild(imageController.img);
+            imageController.setImage = function (src) {
+                imageController.img.src = "";
+                if (typeof src !== "string" || src.length === undefined) {
+                    return;
+                }
+                imageController.img.src = src;
+            };
+            return imageController;
+        })();
+        if (interfaceObject.image !== undefined || page.audioElements.some(function (a) {
+                return a.image !== undefined;
+            })) {
+            DOMRoot.appendChild(imageHolder.root);
+            imageHolder.setImage(interfaceObject.image);
+        }
+
+        // Now create the slider box to hold the fragment sliders
+        var sliderRail = document.createElement("div");
+        sliderRail.id = "sliderrail-" + this.name;
+        sliderRail.className = "slider";
+        sliderRail.align = "left";
+        DOMRoot.appendChild(sliderRail);
+
+        // Canvas for the markers
+        var tickCanvas = document.createElement("canvas");
+        tickCanvas.id = "ticks-" + this.name;
+        tickCanvas.className = "tick-canvas";
+        tickCanvas.height = 150;
+        tickCanvas.width = $(sliderRail).width() - 100;
+        tickCanvas.style.width = ($(sliderRail).width() - 100) + "px";
+        sliderRail.appendChild(tickCanvas);
+
+        // Create the div to hold any scale objects
+        var scale = document.createElement("div");
+        scale.className = "sliderScale";
+        scale.id = "slider-scale-holder-" + this.name;
+        scale.slign = "left";
+        DOMRoot.appendChild(scale);
+        createScaleMarkers(interfaceObject, scale, $(sliderRail).width());
+
+        this.resize = function (event) {
+            var w = $(sliderRail).width();
+            var marginsize = 50;
+            sliders.forEach(function (s) {
+                s.resize();
+            });
+            scale.innerHTML = "";
+            tickCanvas.width = $(sliderRail).width();
+            tickCanvas.style.width = tickCanvas.width + "px";
+            createScaleMarkers(interfaceObject, scale, $(sliderRail).width());
+        };
+        this.playing = function (id) {
+            var node = audioEngineContext.audioObjects.find(function (a) {
+                return a.id == id;
+            });
+            if (node === undefined) {
+                this.imageHolder.setImage(interfaceObject.image || "");
                 return;
             }
-            imageController.img.src = src;
+            var imgurl = node.specification.image || interfaceObject.image || "";
+            this.imageHolder.setImage(imgurl);
         };
-        return imageController;
-    })();
+        this.stopped = function () {
+            var imgurl = interfaceObject.image || "";
+            this.imageHolder.setImage(imgurl);
+        };
+        this.addSlider = function (aoi) {
+            var node = new sliderInterface(aoi, this);
+            sliders.push(node);
+            return node;
+        };
+        this.mousedown = function (sliderUI) {
+            UI.selected = sliderUI;
+            UI.startTime = new Date();
+        };
+        this.mouseup = function (event) {
+            var delta = new Date() - UI.startTime;
+            if (delta < 200) {
+                UI.selected.clicked();
+            } else if (event.type == "touchend" || event.type == "touchcancel") {
+                UI.selected.handleEvent(event);
+            }
+            UI.selected = undefined;
+            UI.startTime = undefined;
+        };
+        this.handleEvent = function (event) {
+            // TODO: Functionalise and scope
+            function getTargetSlider(target) {
+                return sliders.find(function (a) {
+                    return a.DOM == target;
+                });
+            }
+            var time = audioEngineContext.timer.getTestTime();
+            var move, w;
+            if (event.preventDefault) {
+                event.preventDefault();
+            }
+            if (event.type == "touchstart") {
+                var selected = getTargetSlider(event.target);
+                if (typeof selected != "object") {
+                    return;
+                }
+                UI.startTime = new Date();
+                UI.selected = selected;
+            }
+            if (UI.selected === undefined) {
+                return;
+            }
+            if (event.type == "mousemove") {
+                move = event.clientX - 6;
+                w = $(sliderRail).width();
+                move = Math.max(50, move);
+                move = Math.min(w, move);
+                UI.selected.value = (move / w);
+            } else if (event.type == "touchmove") {
+                if (UI.selected == getTargetSlider(event.target)) {
+                    if (event.targetTouches) {
+                        move = event.targetTouches[0].clientX - 6;
+                    } else if (event.originalEvent.targetTouches) {
+                        move = event.originalEvent.targetTouches[0].clientX - 6;
+                    } else {
+                        return;
+                    }
+                    w = $(event.currentTarget).width();
+                    move = Math.max(50, move);
+                    move = Math.min(w, move);
+                    UI.selected.value = (move / w);
+                }
+            } else if (event.type == "touchend" || event.type == "touchcancel") {
+                if (UI.selected == getTargetSlider(event.target)) {
+                    this.mouseup(event);
+                }
+            }
+        };
+        this.checkAllMoved = function () {
+            var notMoved = sliders.filter(function (s) {
+                return !s.hasMoved();
+            });
+            if (notMoved.length !== 0) {
+                var ls = [];
+                notMoved.forEach(function (s) {
+                    ls.push(s.label);
+                });
+                var str = "On axis \"" + interfaceObject.title + "\", ";
+                if (ls.length == 1) {
+                    str += "slider " + ls[0];
+                } else {
+                    str += "sliders " + [ls.slice(0, ls.length - 1).join(", ")].concat(ls[ls.length - 1]).join(" and ");
+                }
+                str += ".";
+                return str;
+            } else {
+                return "";
+            }
+        };
+        this.checkScaleRange = function () {
+            var scaleRange = interfaceObject.options.find(function (a) {
+                return a.name == "scalerange";
+            });
+            if (scaleRange === undefined) {
+                return "";
+            }
+            var scales = {
+                min: scaleRange.min,
+                max: scaleRange.max
+            };
+            var maxSlider = sliders.reduce(function (a, b) {
+                return Math.max(a, b.value);
+            }, 0);
+            var minSlider = sliders.reduce(function (a, b) {
+                return Math.min(a, b.value);
+            }, 100);
+            if (minSlider >= scales.min || maxSlider <= scales.max) {
+                return "On axis \"" + interfaceObject.title + "\", you have not used the required width of the scales";
+            }
+            return "";
+        };
+        sliderRail.addEventListener("mousemove", this);
+        sliderRail.addEventListener("touchstart", this);
+        sliderRail.addEventListener("touchmove", this);
+        sliderRail.addEventListener("touchend", this);
+        sliderRail.addEventListener("touchcancel", this);
+        Object.defineProperties(this, {
+            "sliderRail": {
+                "value": sliderRail
+            }
+        });
+    }
+    this.getDOMRoot = function () {
+        return DOMRoot;
+    };
+    this.getPage = function () {
+        return page;
+    };
+    this.clear = function () {
+        page = undefined;
+        axis = [];
+        AOIs = [];
+        DOMRoot.innerHTML = "";
+    };
+    this.initialisePage = function (page_init) {
+        this.clear();
+        page = page_init;
+        var randomiseAxisOrder;
+        if (page.randomiseAxisOrder !== undefined) {
+            randomiseAxisOrder = page.randomiseAxisOrder;
+        } else {
+            randomiseAxisOrder = page.parent.randomiseAxisOrder;
+        }
+        var commentBoxes = false;
+        // Create each of the interface axis
+        if (randomiseAxisOrder) {
+            page.interfaces = randomiseOrder(page.interfaces);
+        }
+        var interfaceObj = interfaceContext.getCombinedInterfaces(page);
+        interfaceObj.forEach(function (i) {
+            var node = new axisObject(i, this);
+            axis.push(node);
+            i.options.forEach(function (o) {
+                if (o.type == "show" && o.name == "comments") {
+                    commentBoxes = true;
+                }
+            });
+        }, this);
 
-    var pagetitle = document.createElement('div');
-    pagetitle.className = "pageTitle";
-    pagetitle.align = "center";
-    var titleSpan = document.createElement('span');
-    titleSpan.id = "pageTitle-" + this.id;
-    if (interfaceObject.title !== undefined && typeof interfaceObject.title == "string") {
-        titleSpan.textContent = interfaceObject.title;
-    } else {
-        titleSpan.textContent = "Axis " + String(this.id + 1);
-    }
-    pagetitle.appendChild(titleSpan);
-    this.sliderDOM.appendChild(pagetitle);
-
-    if (interfaceObject.image !== undefined || page.audioElements.some(function (a) {
-            return a.image !== undefined;
-        })) {
-        this.sliderDOM.appendChild(this.imageHolder.root);
-        this.imageHolder.setImage(interfaceObject.image);
-    }
-    // Create the slider box to hold the slider elements
-    this.canvas = document.createElement('div');
-    if (this.name !== undefined)
-        this.canvas.id = 'slider-' + this.name;
-    else
-        this.canvas.id = 'slider-' + this.id;
-    this.canvas.setAttribute("interfaceid", this.id);
-    this.canvas.className = 'slider';
-    this.canvas.align = "left";
-    this.canvas.addEventListener('dragover', function (event) {
-        event.preventDefault();
-        event.dataTransfer.effectAllowed = 'none';
-        event.dataTransfer.dropEffect = 'copy';
-        return false;
-    }, false);
-    this.sliderDOM.appendChild(this.canvas);
-
-    // Create the div to hold any scale objects
-    this.scale = document.createElement('div');
-    this.scale.className = 'sliderScale';
-    this.scale.id = 'sliderScaleHolder-' + this.id;
-    this.scale.align = 'left';
-    this.sliderDOM.appendChild(this.scale);
-    var positionScale = this.canvas.style.width.substr(0, this.canvas.style.width.length - 2);
-    var offset = 50;
-    var dest = document.getElementById("slider-holder").appendChild(this.sliderDOM);
-    interfaceObject.scales.forEach(function (scaleObj) {
-        var position = Number(scaleObj.position) * 0.01;
-        var pixelPosition = (position * $(this.canvas).width()) + offset;
-        var scaleDOM = document.createElement('span');
-        scaleDOM.className = "ape-marker-text";
-        scaleDOM.textContent = scaleObj.text;
-        scaleDOM.setAttribute('value', position);
-        this.scale.appendChild(scaleDOM);
-        scaleDOM.style.left = Math.floor((pixelPosition - ($(scaleDOM).width() / 2))) + 'px';
-    }, this);
-
-    this.createSliderObject = function (audioObject, label) {
-        var trackObj = document.createElement('div');
-        trackObj.align = "center";
-        trackObj.className = 'track-slider track-slider-disabled track-slider-' + audioObject.id;
-        trackObj.id = 'track-slider-' + this.id + '-' + audioObject.id;
-        trackObj.setAttribute('trackIndex', audioObject.id);
-        if (this.name !== undefined) {
-            trackObj.setAttribute('interface-name', this.name);
-        } else {
-            trackObj.setAttribute('interface-name', this.id);
+        // Create the audioObject interface objects for each aO.
+        page.audioElements.forEach(function (element, index) {
+            var audioObject = audioEngineContext.newTrack(element);
+            if (element.type == 'outside-reference') {
+                // Construct outside reference;
+                var orNode = new outsideReferenceDOM(audioObject, index, document.getElementById("outside-reference-holder"));
+                audioObject.bindInterface(orNode);
+            } else {
+                var aoi = new audioObjectInterface(audioObject, this);
+                AOIs.push(aoi);
+                var label = interfaceContext.getLabel(page.label, index, page.labelStart);
+                axis.forEach(function (a) {
+                    var node = a.addSlider(aoi);
+                    node.setLabel(label);
+                    aoi.addSlider(node);
+                });
+                audioObject.bindInterface(aoi);
+                if (commentBoxes) {
+                    interfaceContext.commentBoxes.createCommentBox(audioObject);
+                }
+            }
+        });
+    };
+    this.checkAllMoved = function () {
+        var str = "You have not moved the following sliders. ";
+        var cont = true;
+        axis.forEach(function (a) {
+            var msg = a.checkAllMoved();
+            if (msg.length > 0) {
+                cont = false;
+                str += msg;
+            }
+        });
+        if (!cont) {
+            interfaceContext.lightbox.post("Error", str);
+            interfaceContext.storeErrorNode(str);
+            console.log(str);
         }
-        var offset = 50;
-        // Distribute it randomnly
-        var w = window.innerWidth - (offset + 8) * 2;
-        w = Math.random() * w;
-        w = Math.floor(w + (offset + 8));
-        trackObj.style.left = w + 'px';
-        this.canvas.appendChild(trackObj);
-        this.sliders.push(trackObj);
-        this.metrics.push(new metricTracker(this));
-        var labelHolder = document.createElement("span");
-        labelHolder.textContent = label;
-        trackObj.appendChild(labelHolder);
-        var rate = convSliderPosToRate(trackObj);
-        this.metrics[this.metrics.length - 1].initialise(rate);
-        trackObj.setAttribute("slider-value", rate);
-        return trackObj;
+        return cont;
     };
-
-    this.resize = function (event) {
-        var sliderDiv = this.canvas;
-        var sliderScaleDiv = this.scale;
-        var width = $(sliderDiv).width();
-        var marginsize = 50;
-        // Move sliders into new position
-        this.sliders.forEach(function (slider, index) {
-            var pix = Number(slider.getAttribute("slider-value")) * width;
-            slider.style.left = (pix + marginsize) + 'px';
+    this.checkScaleRange = function () {
+        var str = "";
+        var cont = true;
+        axis.forEach(function (a) {
+            var msg = a.checkScaleRange();
+            if (msg.length > 0) {
+                cont = false;
+                str += msg;
+            }
         });
-
-        // Move scale labels
-        for (var index = 0; index < this.scale.children.length; index++) {
-            var scaleObj = this.scale.children[index];
-            var position = Number(scaleObj.attributes.value.value);
-            var pixelPosition = (position * width) + marginsize;
-            scaleObj.style.left = Math.floor((pixelPosition - ($(scaleObj).width() / 2))) + 'px';
+        if (!cont) {
+            interfaceContext.lightbox.post("Error", str);
+            interfaceContext.storeErrorNode(str);
+            console.log(str);
         }
+        return cont;
     };
-
-    this.playing = function (id) {
-        var node = audioEngineContext.audioObjects.find(function (a) {
-            return a.id == id;
-        });
-        if (node === undefined) {
-            this.imageHolder.setImage(interfaceObject.image || "");
-            return;
-        }
-        var imgurl = node.specification.image || interfaceObject.image || "";
-        this.imageHolder.setImage(imgurl);
-    };
-}
-
-function sliderObject(audioObject, interfaceObjects, index) {
-    // Create a new slider object;
-    this.parent = audioObject;
-    this.trackSliderObjects = [];
-    this.label = interfaceContext.getLabel(audioObject.specification.parent.label, index, audioObject.specification.parent.labelStart);
-    this.playing = false;
-    for (var i = 0; i < interfaceContext.interfaceSliders.length; i++) {
-        var trackObj = interfaceContext.interfaceSliders[i].createSliderObject(audioObject, this.label);
-        this.trackSliderObjects.push(trackObj);
-    }
-
-    // Onclick, switch playback to that track
-
-    this.enable = function () {
-        if (this.parent.state == 1) {
-            $(this.trackSliderObjects).each(function (i, trackObj) {
-                $(trackObj).removeClass('track-slider-disabled');
+    this.pageXMLSave = function (store, pageSpecification) {
+        if (axis.length > 1) {
+            AOIs.forEach(function (ao) {
+                ao.pageXMLSave(store);
             });
         }
     };
-    this.updateLoading = function (progress) {
-        if (progress != 100) {
-            progress = String(progress);
-            progress = progress.split('.')[0];
-            this.trackSliderObjects[0].children[0].textContent = progress + '%';
-        } else {
-            this.trackSliderObjects[0].children[0].textContent = this.label;
-        }
-    };
-    this.startPlayback = function () {
-        $('.track-slider').removeClass('track-slider-playing');
-        var name = ".track-slider-" + this.parent.id;
-        $(name).addClass('track-slider-playing');
-        interfaceContext.commentBoxes.highlightById(audioObject.id);
-        $('.outside-reference').removeClass('track-slider-playing');
-        this.playing = true;
-
-        if (this.parent.specification.parent.playOne || specification.playOne) {
-            $('.track-slider').addClass('track-slider-disabled');
-            $('.outside-reference').addClass('track-slider-disabled');
-        }
-        interfaceContext.interfaceSliders.forEach(function (ts) {
-            ts.playing(this.parent.id);
-        }, this);
-    };
-    this.stopPlayback = function () {
-        if (this.playing) {
-            this.playing = false;
-            var name = ".track-slider-" + this.parent.id;
-            $(name).removeClass('track-slider-playing');
-            $('.track-slider').removeClass('track-slider-disabled');
-            $('.outside-reference').removeClass('track-slider-disabled');
-            var box = interfaceContext.commentBoxes.boxes.find(function (a) {
-                return a.id === audioObject.id;
-            });
-            if (box) {
-                box.highlight(false);
-            }
-        }
-    };
-    this.exportXMLDOM = function (audioObject) {
-        // Called by the audioObject holding this element. Must be present
-        var obj = [];
-        $(this.trackSliderObjects).each(function (i, trackObj) {
-            var node = storage.document.createElement('value');
-            if (trackObj.getAttribute("interface-name") !== "null") {
-                node.setAttribute("interface-name", trackObj.getAttribute("interface-name"));
-            }
-            node.textContent = convSliderPosToRate(trackObj);
-            obj.push(node);
+    this.resize = function (event) {
+        axis.forEach(function (a) {
+            a.resize(event);
         });
-
-        return obj;
-    };
-    this.getValue = function () {
-        return convSliderPosToRate(this.trackSliderObjects[0]);
-    };
-    this.getPresentedId = function () {
-        return this.label;
-    };
-    this.canMove = function () {
-        return true;
-    };
-    this.error = function () {
-        // audioObject has an error!!
-        this.playback.textContent = "Error";
-        $(this.playback).addClass("error-colour");
     };
 }
 
@@ -753,6 +845,9 @@
     if (interfaceContext.checkFragmentMinPlays() === false) {
         return;
     }
+    if (interfaceContext.checkCommentQuestions() === false) {
+        return;
+    }
 
     for (var i = 0; i < checks.length; i++) {
         var checkState = true;
@@ -820,9 +915,7 @@
     // MANDATORY FUNCTION
 
     // Resize the slider objects
-    for (var i = 0; i < interfaceContext.interfaceSliders.length; i++) {
-        interfaceContext.interfaceSliders[i].resize(event);
-    }
+    window.module.resize(event);
 }
 
 function pageXMLSave(store, pageSpecification) {
@@ -833,32 +926,5 @@
     // pageSpecification is the current page node configuration
     // To create new XML nodes, use storage.document.createElement();
 
-    if (interfaceContext.interfaceSliders.length == 1) {
-        // If there is only one axis, there only needs to be one metric return
-        return;
-    }
-    var audioelements = store.getElementsByTagName("audioelement");
-    for (var i = 0; i < audioelements.length; i++) {
-        // Have to append the metric specific nodes
-        if (pageSpecification.outsideReference === undefined || pageSpecification.outsideReference.id != audioelements[i].id) {
-            var inject = audioelements[i].getElementsByTagName("metric");
-            if (inject.length === 0) {
-                inject = storage.document.createElement("metric");
-            } else {
-                inject = inject[0];
-            }
-            for (var k = 0; k < interfaceContext.interfaceSliders.length; k++) {
-                var mrnodes = interfaceContext.interfaceSliders[k].metrics[i].exportXMLDOM(inject);
-                for (var j = 0; j < mrnodes.length; j++) {
-                    var name = mrnodes[j].getAttribute("name");
-                    if (name == "elementTracker" || name == "elementTrackerFull" || name == "elementInitialPosition" || name == "elementFlagMoved") {
-                        if (interfaceContext.interfaceSliders[k].name !== null) {
-                            mrnodes[j].setAttribute("interface-name", interfaceContext.interfaceSliders[k].name);
-                        }
-                        mrnodes[j].setAttribute("interface-id", k);
-                    }
-                }
-            }
-        }
-    }
+    module.pageXMLSave(store, pageSpecification);
 }
--- a/interfaces/discrete.css	Wed Nov 28 13:50:22 2018 +0000
+++ b/interfaces/discrete.css	Wed Nov 28 13:51:51 2018 +0000
@@ -20,79 +20,47 @@
     min-width: 20px;
     background-color: #ddd
 }
-div#slider-holder {
-    height: inherit;
-    position: absolute;
-    left: 0px;
-    z-index: 3;
-    margin-top: 25px;
+div#slider-box {
+    width: 75%;
+    height: auto;
+    margin: auto;
+    padding-bottom: 20px;
 }
-div#scale-holder {
-    position: absolute;
-    left: 0px;
-    z-index: 2;
+div#slider-grid {
+    display: grid;
+    grid-template-columns: 1fr;
+    grid-row-gap: 10px;
 }
 div#scale-text-holder {
-    position: relative;
-    float: left;
+    display: grid;
+    grid-template-rows: 1fr;
+    min-height: 25px;
+    text-align: center;
+}
+div.discrete-row {
+    display: grid;
+    grid-template-rows: 1fr;
+    padding: 10px;
+    border: 1px solid black;
+    height: 50px;
+    line-height: 50px;
+}
+button.discrete-button {
+    width: 100px;
+}
+div.discrete-label {
+    width: 100px;
+    text-align: center;
 }
 div.scale-text {
-    position: absolute;
-    font-size: 1.2em;
-}
-canvas#scale-canvas {
-    position: relative;
-    float: left;
-}
-div.track-slider {
-    float: left;
-    height: 30px;
-    border: solid;
-    border-width: 1px;
-    border-color: black;
-    padding: 2px;
-    margin-left: 94px;
-    margin-bottom: 30px;
-}
-div.track-slider-range {
-    float: left;
-    height: 100%;
-    margin: 0px 50px;
     position: relative;
 }
-div.track-slider-title {
-    float: left;
-    padding-top: 5px;
-    width: 100px;
+div.scale-text > span {
+    position: absolute;
+    bottom: 0;
+    width: 100%;
+    left: 0;
 }
-button.track-slider-button {
-    float: left;
-    width: 100px;
-    height: 30px;
+div.discrete-row-playing {
+    background-color: rgba(255, 201, 201, 0.5);
 }
-input.track-radio {
-    position: absolute;
-    margin: 9px 0px;
-}
-div#outside-reference-holder {
-    display: flex;
-    align-content: center;
-    justify-content: center;
-    margin-bottom: 5px;
-}
-button.outside-reference {
-    position: inherit;
-    margin: 0px 5px;
-}
-div.track-slider-playing {
-    background-color: #FFDDDD;
-}
-div#page-count {
-    float: left;
-    margin: 0px 5px;
-}
-div#master-volume-holder {
-    position: absolute;
-    top: 10px;
-    left: 120px;
-}
--- a/interfaces/discrete.js	Wed Nov 28 13:50:22 2018 +0000
+++ b/interfaces/discrete.js	Wed Nov 28 13:51:51 2018 +0000
@@ -1,4 +1,8 @@
-/* globals interfaceContext, document, window, $, specification, audioEngineContext, console, window, testState, storage */
+/**
+ * WAET Blank Template
+ * Use this to start building your custom interface
+ */
+/*globals window, interfaceContext, testState, Interface, audioEngineContext, console, document, specification, $, storage*/
 // Once this is loaded and parsed, begin execution
 loadInterface();
 
@@ -56,44 +60,41 @@
             console.log('Stopped at ' + time); // DEBUG/SAFETY
         }
     };
-
-    // Create outside reference holder
-    var outsideRef = document.createElement("div");
-    outsideRef.id = "outside-reference-holder";
-
     // Create Submit (save) button
     var submit = document.createElement("button");
     submit.innerHTML = 'Next';
     submit.onclick = buttonSubmitClick;
     submit.id = 'submit-button';
     submit.style.float = 'left';
+
+    // Create the sort button
+    var sort = document.createElement("button");
+    sort.id = "sort-fragments";
+    sort.textContent = "Sort";
+    sort.style.display = "inline-block";
+    sort.style.visibility = "hidden";
+    sort.onclick = buttonSortFragmentClick;
+
     // Append the interface buttons into the interfaceButtons object.
     interfaceButtons.appendChild(playback);
     interfaceButtons.appendChild(submit);
+    interfaceButtons.appendChild(sort);
 
-    // Create a slider box
-    var sliderBox = document.createElement('div');
-    sliderBox.style.width = "100%";
-    sliderBox.style.height = window.innerHeight - 200 + 12 + 'px';
-    sliderBox.style.marginBottom = '10px';
-    sliderBox.id = 'slider';
-    var scaleHolder = document.createElement('div');
-    scaleHolder.id = "scale-holder";
-    scaleHolder.style.marginLeft = "107px";
-    sliderBox.appendChild(scaleHolder);
+
+    // Create outside reference holder
+    var outsideRef = document.createElement("div");
+    outsideRef.id = "outside-reference-holder";
+
+    // Create a holder for the slider rows
+    var sliderBox = document.createElement("div");
+    sliderBox.id = 'slider-box';
+    var sliderGrid = document.createElement("div");
+    sliderGrid.id = "slider-grid";
+    sliderBox.appendChild(sliderGrid);
     var scaleText = document.createElement('div');
     scaleText.id = "scale-text-holder";
-    scaleText.style.height = "25px";
-    scaleText.style.width = "100%";
-    scaleHolder.appendChild(scaleText);
-    var scaleCanvas = document.createElement('canvas');
-    scaleCanvas.id = "scale-canvas";
-    scaleCanvas.style.marginLeft = "150px";
-    scaleHolder.appendChild(scaleCanvas);
-    var sliderObjectHolder = document.createElement('div');
-    sliderObjectHolder.id = 'slider-holder';
-    sliderObjectHolder.align = "center";
-    sliderBox.appendChild(sliderObjectHolder);
+    sliderGrid.appendChild(scaleText);
+
 
     // Global parent for the comment boxes on the page
     var feedbackHolder = document.createElement('div');
@@ -118,11 +119,16 @@
 
 function loadTest(page) {
     // Called each time a new test page is to be build. The page specification node is the only item passed in
-    var id = page.id;
 
     var feedbackHolder = document.getElementById('feedbackHolder');
+    var sliderBox = document.getElementById('slider-box');
+    var sliderGrid = document.getElementById("slider-grid");
+    var scaleTextHolder = document.getElementById("scale-text-holder");
+    var interfaceObj = interfaceContext.getCombinedInterfaces(page);
+    var commentBoxPrefix = "Comment on track";
+    var loopPlayback = page.loop;
     feedbackHolder.innerHTML = "";
-    var interfaceObj = interfaceContext.getCombinedInterfaces(page);
+
     if (interfaceObj.length > 1) {
         console.log("WARNING - This interface only supports one <interface> node per page. Using first interface node");
     }
@@ -132,7 +138,7 @@
     if (typeof page.title == "string" && page.title.length > 0) {
         document.getElementById("test-title").textContent = page.title;
     }
-
+    // Set the axis title
     if (interfaceObj.title !== null) {
         document.getElementById("pageTitle").textContent = interfaceObj.title;
     }
@@ -147,15 +153,67 @@
     // Delete outside reference
     document.getElementById("outside-reference-holder").innerHTML = "";
 
-    var sliderBox = document.getElementById('slider-holder');
-    sliderBox.innerHTML = "";
-
-    var commentBoxPrefix = "Comment on track";
+    // Get the comment box prefix
     if (interfaceObj.commentBoxPrefix !== undefined) {
         commentBoxPrefix = interfaceObj.commentBoxPrefix;
     }
-    var loopPlayback = page.loop;
 
+    // Populate the comment questions
+    $(page.commentQuestions).each(function (index, element) {
+        var node = interfaceContext.createCommentQuestion(element);
+        feedbackHolder.appendChild(node.holder);
+    });
+
+    // Configure the grid
+    var numRows = page.audioElements.filter(function (a) {
+        return (a.type !== "outside-reference");
+    }).length;
+    var numColumns = page.interfaces[0].scales.length;
+    sliderGrid.style.gridTemplateRows = "50px repeat(" + numRows + ", 72px)";
+    scaleTextHolder.style.gridTemplateColumns = "100px repeat(" + numColumns + ", 1fr) 100px";
+    page.interfaces[0].scales.sort(function (a, b) {
+        if (a.position > b.position) {
+            return 1;
+        } else if (a.position < b.position) {
+            return -1;
+        }
+        return 0;
+    }).forEach(function (a, i) {
+        var h = document.createElement("div");
+        var text = document.createElement("span");
+        h.className = "scale-text";
+        h.style.gridColumn = String(i + 2) + "/" + String(i + 3);
+        text.textContent = a.text;
+        h.appendChild(text);
+        scaleTextHolder.appendChild(h);
+    });
+
+    // Find all the audioElements from the audioHolder
+    var index = 0;
+    var labelType = page.label;
+    if (labelType == "default") {
+        labelType = "number";
+    }
+    $(page.audioElements).each(function (pageIndex, element) {
+        // Find URL of track
+        // In this jQuery loop, variable 'this' holds the current audioElement.
+
+        var audioObject = audioEngineContext.newTrack(element);
+        if (element.type == 'outside-reference') {
+            // Construct outside reference;
+            var orNode = new interfaceContext.outsideReferenceDOM(audioObject, index, document.getElementById("outside-reference-holder"));
+            audioObject.bindInterface(orNode);
+        } else {
+            // Create a slider per track
+            var label = interfaceContext.getLabel(labelType, index, page.labelStart);
+            var sliderObj = new discreteObject(audioObject, label);
+            sliderGrid.appendChild(sliderObj.DOMRoot);
+            audioObject.bindInterface(sliderObj);
+            interfaceContext.commentBoxes.createCommentBox(audioObject);
+            index += 1;
+        }
+
+    });
     interfaceObj.options.forEach(function (option) {
         if (option.type == "show") {
             switch (option.name) {
@@ -187,204 +245,109 @@
                 case "comments":
                     interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder, true);
                     break;
+                case "fragmentSort":
+                    var button = document.getElementById('sort-fragments');
+                    button.style.visibility = "visible";
+                    break;
             }
         }
     });
-
-    // Find all the audioElements from the audioHolder
-    var index = 0;
-    var interfaceScales = page.interfaces[0].scales;
-    var labelType = page.label;
-    if (labelType == "default") {
-        labelType = "number";
-    }
-    $(page.audioElements).each(function (pageIndex, element) {
-        // Find URL of track
-        // In this jQuery loop, variable 'this' holds the current audioElement.
-
-        var audioObject = audioEngineContext.newTrack(element);
-        if (element.type == 'outside-reference') {
-            // Construct outside reference;
-            var orNode = new interfaceContext.outsideReferenceDOM(audioObject, index, document.getElementById("outside-reference-holder"));
-            audioObject.bindInterface(orNode);
-        } else {
-            // Create a slider per track
-            var label = interfaceContext.getLabel(labelType, index, page.labelStart);
-            var sliderObj = new discreteObject(audioObject, label, interfaceScales);
-            sliderBox.appendChild(sliderObj.holder);
-            audioObject.bindInterface(sliderObj);
-            interfaceContext.commentBoxes.createCommentBox(audioObject);
-            index += 1;
-        }
-
-    });
-
-    $(page.commentQuestions).each(function (index, element) {
-        var node = interfaceContext.createCommentQuestion(element);
-        feedbackHolder.appendChild(node.holder);
-    });
-
     // Auto-align
     resizeWindow(null);
 }
 
-function discreteObject(audioObject, label, interfaceScales) {
+function discreteObject(audioObject, label) {
     // An example node, you can make this however you want for each audioElement.
     // However, every audioObject (audioEngineContext.audioObject) MUST have an interface object with the following
     // You attach them by calling audioObject.bindInterface( )
-    if (interfaceScales === null || interfaceScales.length === 0) {
-        console.log("WARNING: The discrete radio's are built depending on the number of scale points specified! Ensure you have some specified. Defaulting to 5 for now!");
-        var numOptions = 5;
-    }
-    this.parent = audioObject;
+    var playing = false;
 
-    this.holder = document.createElement('div');
-    this.title = document.createElement('div');
-    this.discreteHolder = document.createElement('div');
-    this.discretes = [];
-    this.play = document.createElement('button');
-
-    this.holder.className = 'track-slider';
-    this.holder.style.width = window.innerWidth - 200 + 'px';
-    this.holder.appendChild(this.title);
-    this.holder.appendChild(this.discreteHolder);
-    this.holder.appendChild(this.play);
-    this.holder.setAttribute('trackIndex', audioObject.id);
-    this.title.textContent = label;
-    this.title.className = 'track-slider-title';
-
-    this.discreteHolder.className = "track-slider-range";
-    this.discreteHolder.style.width = window.innerWidth - 500 + 'px';
-    this.radioClicked = function (event) {
-        var time = audioEngineContext.timer.getTestTime();
-        if (audioEngineContext.status === 0) {
-            event.currentTarget.checked = false;
-            return;
+    function buttonClicked(event) {
+        if (!playing) {
+            audioEngineContext.play(audioObject.id);
+        } else {
+            audioEngineContext.stop();
         }
-        var id = this.parent.id;
-        var position = this.getValue();
-        this.parent.metric.moved(time, position);
-        console.log('slider ' + id + ' moved to ' + position + ' (' + time + ')');
-
-    };
-    this.handleEvent = function (event) {
-        if (event.currentTarget.getAttribute("name") === this.parent.specification.id) {
-            this.radioClicked(event);
-        }
-    };
-    for (var i = 0; i < interfaceScales.length; i++) {
-        var node = document.createElement('input');
-        node.setAttribute('type', 'radio');
-        node.className = 'track-radio';
-        node.disabled = true;
-        node.setAttribute('position', interfaceScales[i].position);
-        node.setAttribute('name', audioObject.specification.id);
-        node.setAttribute('id', audioObject.specification.id + '-' + String(i));
-        this.discretes.push(node);
-        this.discreteHolder.appendChild(node);
-        node.addEventListener("click", this);
     }
 
-    this.play.className = 'track-slider-button';
-    this.play.textContent = "Loading...";
-    this.play.value = audioObject.id;
-    this.play.disabled = true;
-    this.play.setAttribute("playstate", "ready");
-    this.play.onclick = function (event) {
-        var id = Number(event.currentTarget.value);
-        //audioEngineContext.metric.sliderPlayed(id);
-        if (event.currentTarget.getAttribute("playstate") == "ready")
-            audioEngineContext.play(id);
-        else if (event.currentTarget.getAttribute("playstate") == "playing")
-            audioEngineContext.stop();
-    };
-    this.resize = function (event) {
-        this.holder.style.width = window.innerWidth - 200 + 'px';
-        this.discreteHolder.style.width = window.innerWidth - 500 + 'px';
-        //text.style.left = (posPix+150-($(text).width()/2)) +'px';
-        for (var i = 0; i < this.discretes.length; i++) {
-            var width = $(this.discreteHolder).width() - 20;
-            var node = this.discretes[i];
-            var nodeW = $(node).width();
-            var position = node.getAttribute('position');
-            var posPix = Math.round(width * (position / 100.0));
-            node.style.left = (posPix + 10 - (nodeW / 2)) + 'px';
+    function radioSelected(event) {
+        var time = audioEngineContext.timer.getTestTime();
+        audioObject.metric.moved(time, event.currentTarget.value);
+        console.log("slider " + audioObject.id + " moved to " + event.currentTarget.value + "(" + time + ")");
+    }
+
+    var root = document.createElement("div"),
+        labelHolder = document.createElement("div"),
+        button = document.createElement("button");
+    root.className = "discrete-row";
+    labelHolder.className = "discrete-label";
+    button.className = "discrete-button";
+    root.appendChild(labelHolder);
+
+    var labelSpan = document.createElement("span");
+    labelHolder.appendChild(labelSpan);
+    labelSpan.textContent = label;
+    button.textContent = "Listen";
+    button.disabled = "true";
+    button.addEventListener("click", this);
+
+    var numScales = audioObject.specification.parent.interfaces[0].scales.length;
+    root.style.gridTemplateColumns = "100px repeat(" + numScales + ", 1fr) 100px";
+    for (var n = 0; n < numScales; n++) {
+        var input = document.createElement("input");
+        input.type = "radio";
+        input.disabled = "true";
+        input.value = n / (numScales - 1);
+        input.addEventListener("click", this);
+        input.name = audioObject.specification.id;
+        root.appendChild(input);
+    }
+    root.appendChild(button);
+    this.handleEvent = function (event) {
+        if (event.currentTarget === button) {
+            buttonClicked(event);
+        } else if (event.currentTarget.type === "radio") {
+            radioSelected(event);
         }
     };
     this.enable = function () {
         // This is used to tell the interface object that playback of this node is ready
-        this.play.disabled = false;
-        this.play.textContent = "Play";
-        $(this.slider).removeClass('track-slider-disabled');
-        this.discretes.forEach(function (elem) {
-            elem.disabled = false;
-        });
+        button.disabled = "";
+        var a = root.querySelectorAll("input[type=\"radio\"]");
+        for (var n = 0; n < a.length; n++) {
+            a[n].disabled = false;
+        }
+        button.textContent = "Listen";
     };
     this.updateLoading = function (progress) {
         // progress is a value from 0 to 100 indicating the current download state of media files
-        if (progress != 100) {
-            progress = String(progress);
-            progress = progress.split('.')[0];
-            this.play.textContent = progress + '%';
-        } else {
-            this.play.textContent = "Play";
-        }
+        button.textContent = progress + "%";
     };
-
     this.startPlayback = function () {
-        // Called by audioObject when playback begins
-        this.play.setAttribute("playstate", "playing");
-        $(".track-slider").removeClass('track-slider-playing');
-        $(this.holder).addClass('track-slider-playing');
-        var outsideReference = document.getElementById('outside-reference');
-        this.play.textContent = "Listening";
-        if (outsideReference !== null) {
-            $(outsideReference).removeClass('track-slider-playing');
-        }
-        if (this.parent.specification.parent.playOne || specification.playOne) {
-            $('.track-slider-button').text = "Wait";
-            $('.track-slider-button').attr("disabled", "true");
-        }
-        interfaceContext.commentBoxes.highlightById(audioObject.id);
-        if (audioObject.specification.image !== undefined) {
-            interfaceContext.imageHolder.setImage(audioObject.specification.image);
-        }
+        // Called when playback has begun
+        playing = true;
+        $(root).addClass("discrete-row-playing");
+        button.textContent = "Stop";
     };
     this.stopPlayback = function () {
-        // Called by audioObject when playback stops
-        if (this.play.getAttribute("playstate") == "playing") {
-            this.play.setAttribute("playstate", "ready");
-            $(this.holder).removeClass('track-slider-playing');
-            $('.track-slider-button').text = "Play";
-            this.play.textContent = "Play";
-            $('.track-slider-button').removeAttr("disabled");
-            var box = interfaceContext.commentBoxes.boxes.find(function (a) {
-                return a.id === audioObject.id;
-            });
-            if (box) {
-                box.highlight(false);
-            }
-            if (audioObject.specification.parent.interfaces[0].image !== undefined) {
-                interfaceContext.imageHolder.setImage(audioObject.specification.parent.interfaces[0].image);
-            } else {
-                interfaceContext.imageHolder.setImage("");
+        // Called when playback has stopped. This gets called even if playback never started!
+        playing = false;
+        $(root).removeClass("discrete-row-playing");
+        button.textContent = "Listen";
+    };
+    this.getValue = function () {
+        // Return the current value of the object. If there is no value, return 0
+        var a = root.querySelectorAll("input[type=\"radio\"]");
+        for (var n = 0; n < a.length; n++) {
+            if (a[n].checked) {
+                return Number(a[n].value);
             }
         }
-    };
-
-    this.getValue = function () {
-        // Return the current value of the object. If there is no value, return -1
-        var checkedElement = this.discretes.find(function (elem) {
-            return elem.checked;
-        });
-        if (checkedElement === undefined) {
-            return -1;
-        }
-        return checkedElement.getAttribute("position") / 100.0;
+        return -1;
     };
     this.getPresentedId = function () {
         // Return the presented ID of the object. For instance, the APE has sliders starting from 0. Whilst AB has alphabetical scale
-        return this.title.textContent;
+        return label;
     };
     this.canMove = function () {
         // Return either true or false if the interface object can be moved. AB / Reference cannot, whilst sliders can and therefore have a continuous scale.
@@ -399,75 +362,36 @@
         var node = storage.document.createElement('value');
         node.textContent = this.getValue();
         return node;
+
     };
     this.error = function () {
-        // audioObject has an error!!
-        this.playback.textContent = "Error";
-        $(this.playback).addClass("error-colour");
+        // If there is an error with the audioObject, this will be called to indicate a failure
     };
+    Object.defineProperties(this, {
+        "DOMRoot": {
+            "value": root
+        }
+    });
 }
 
 function resizeWindow(event) {
     // Called on every window resize event, use this to scale your page properly
-    var numObj = document.getElementsByClassName('track-slider').length;
-    var totalHeight = (numObj * 66) - 30;
-    document.getElementById('scale-holder').style.width = window.innerWidth - 220 + 'px';
-    // Cheers edge for making me delete a canvas every resize.
-    var canvas = document.getElementById('scale-canvas');
-    var new_canvas = document.createElement("canvas");
-    new_canvas.id = 'scale-canvas';
-    new_canvas.style.marginLeft = "150px";
-    canvas.parentElement.appendChild(new_canvas);
-    canvas.parentElement.removeChild(canvas);
-    new_canvas.width = window.innerWidth - 520;
-    new_canvas.height = totalHeight;
-    for (var i in audioEngineContext.audioObjects) {
-        if (audioEngineContext.audioObjects[i].specification.type != 'outside-reference') {
-            audioEngineContext.audioObjects[i].interfaceDOM.resize(event);
-        }
-    }
-    document.getElementById('slider-holder').style.height = totalHeight + 'px';
-    document.getElementById('slider').style.height = totalHeight + 70 + 'px';
-    drawScale();
 }
 
-function drawScale() {
-    var interfaceObj = testState.currentStateMap.interfaces[0];
-    var scales = testState.currentStateMap.interfaces[0].scales;
-    scales = scales.sort(function (a, b) {
-        return a.position - b.position;
+function buttonSortFragmentClick() {
+    var sortIndex = interfaceContext.sortFragmentsByScore();
+    var sliderBox = document.getElementById("slider-holder");
+    var nodes = audioEngineContext.audioObjects.filter(function (ao) {
+        return ao.specification.type !== "outside-reference";
     });
-    var canvas = document.getElementById('scale-canvas');
-    var ctx = canvas.getContext("2d");
-    var height = canvas.height;
-    var width = canvas.width;
-    var textHolder = document.getElementById('scale-text-holder');
-    textHolder.innerHTML = "";
-    ctx.fillStyle = "#000000";
-    ctx.setLineDash([1, 4]);
-    scales.forEach(function (scale) {
-        var posPercent = scale.position / 100.0;
-        var posPix = Math.round(width * posPercent);
-        if (posPix <= 0) {
-            posPix = 1;
-        }
-        if (posPix >= width) {
-            posPix = width - 1;
-        }
-        ctx.moveTo(posPix, 0);
-        ctx.lineTo(posPix, height);
-        ctx.stroke();
-
-        var text = document.createElement('div');
-        text.align = "center";
-        var textC = document.createElement('span');
-        textC.textContent = scale.text;
-        text.appendChild(textC);
-        text.className = "scale-text";
-        textHolder.appendChild(text);
-        text.style.width = $(text.children[0]).width() + 'px';
-        text.style.left = (posPix + 150 - ($(text).width() / 2)) + 'px';
+    var i;
+    nodes.forEach(function (ao) {
+        sliderBox.removeChild(ao.interfaceDOM.holder);
     });
+    for (i = 0; i < nodes.length; i++) {
+        var j = sortIndex[i];
+        sliderBox.appendChild(nodes[j].interfaceDOM.holder);
+    }
 }
 
 function buttonSubmitClick() // TODO: Only when all songs have been played!
@@ -485,9 +409,12 @@
     if (interfaceContext.checkFragmentMinPlays() === false) {
         return;
     }
+    if (interfaceContext.checkCommentQuestions() === false) {
+        return;
+    }
 
     for (var i = 0; i < checks.length; i++) {
-        var checkState;
+        var checkState = true;
         if (checks[i].type == 'check') {
             switch (checks[i].name) {
                 case 'fragmentPlayed':
@@ -510,16 +437,15 @@
                 case 'scalerange':
                     // Check the scale has been used effectively
                     checkState = interfaceContext.checkScaleRange(checks[i].errorMessage);
+
                     break;
                 default:
                     console.log("WARNING - Check option " + checks[i].check + " is not supported on this interface");
                     break;
             }
-            if (checkState === false) {
-                canContinue = false;
-            }
         }
-        if (!canContinue) {
+        if (checkState === false) {
+            canContinue = false;
             break;
         }
     }
--- a/interfaces/horizontal-sliders.js	Wed Nov 28 13:50:22 2018 +0000
+++ b/interfaces/horizontal-sliders.js	Wed Nov 28 13:51:51 2018 +0000
@@ -62,9 +62,20 @@
     submit.onclick = buttonSubmitClick;
     submit.id = 'submit-button';
     submit.style.float = 'left';
+
+    // Create the sort button
+    var sort = document.createElement("button");
+    sort.id = "sort-fragments";
+    sort.textContent = "Sort";
+    sort.style.display = "inline-block";
+    sort.style.visibility = "hidden";
+    sort.onclick = buttonSortFragmentClick;
+
     // Append the interface buttons into the interfaceButtons object.
     interfaceButtons.appendChild(playback);
     interfaceButtons.appendChild(submit);
+    interfaceButtons.appendChild(sort);
+
 
     // Create outside reference holder
     var outsideRef = document.createElement("div");
@@ -226,6 +237,10 @@
                 case "comments":
                     interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder, true);
                     break;
+                case "fragmentSort":
+                    var button = document.getElementById('sort-fragments');
+                    button.style.visibility = "visible";
+                    break;
             }
         }
     });
@@ -383,6 +398,14 @@
 function drawScale() {
     var interfaceObj = testState.currentStateMap.interfaces[0];
     var scales = testState.currentStateMap.interfaces[0].scales;
+    var ticks = specification.interfaces.options.concat(interfaceObj.options).find(function (a) {
+        return (a.type == "show" && a.name == "ticks");
+    });
+    if (ticks !== undefined) {
+        ticks = true;
+    } else {
+        ticks = false;
+    }
     scales = scales.sort(function (a, b) {
         return a.position - b.position;
     });
@@ -403,9 +426,11 @@
         if (posPix >= width) {
             posPix = width - 1;
         }
-        ctx.moveTo(posPix, 0);
-        ctx.lineTo(posPix, height);
-        ctx.stroke();
+        if (ticks) {
+            ctx.moveTo(posPix, 0);
+            ctx.lineTo(posPix, height);
+            ctx.stroke();
+        }
 
         var text = document.createElement('div');
         text.align = "center";
@@ -419,6 +444,22 @@
     });
 }
 
+function buttonSortFragmentClick() {
+    var sortIndex = interfaceContext.sortFragmentsByScore();
+    var sliderBox = document.getElementById("slider-holder");
+    var nodes = audioEngineContext.audioObjects.filter(function (ao) {
+        return ao.specification.type !== "outside-reference";
+    });
+    var i;
+    nodes.forEach(function (ao) {
+        sliderBox.removeChild(ao.interfaceDOM.holder);
+    });
+    for (i = 0; i < nodes.length; i++) {
+        var j = sortIndex[i];
+        sliderBox.appendChild(nodes[j].interfaceDOM.holder);
+    }
+}
+
 function buttonSubmitClick() // TODO: Only when all songs have been played!
 {
     var checks = testState.currentStateMap.interfaces[0].options,
@@ -434,6 +475,9 @@
     if (interfaceContext.checkFragmentMinPlays() === false) {
         return;
     }
+    if (interfaceContext.checkCommentQuestions() === false) {
+        return;
+    }
 
     for (var i = 0; i < checks.length; i++) {
         var checkState = true;
--- a/interfaces/mushra.css	Wed Nov 28 13:50:22 2018 +0000
+++ b/interfaces/mushra.css	Wed Nov 28 13:51:51 2018 +0000
@@ -39,6 +39,8 @@
 }
 div.scale-text {
     position: absolute;
+    text-align: right;
+    min-width: 100px;
 }
 canvas#scale-canvas {
     position: relative;
--- a/interfaces/mushra.js	Wed Nov 28 13:50:22 2018 +0000
+++ b/interfaces/mushra.js	Wed Nov 28 13:51:51 2018 +0000
@@ -67,9 +67,20 @@
     submit.onclick = buttonSubmitClick;
     submit.id = 'submit-button';
     submit.style.display = 'inline-block';
+
+    // Create the sort button
+    var sort = document.createElement("button");
+    sort.id = "sort-fragments";
+    sort.textContent = "Sort";
+    sort.style.display = "inline-block";
+    sort.style.visibility = "hidden";
+    sort.onclick = buttonSortFragmentClick;
+
     // Append the interface buttons into the interfaceButtons object.
     interfaceButtons.appendChild(playback);
     interfaceButtons.appendChild(submit);
+    interfaceButtons.appendChild(sort);
+
 
     // Create outside reference holder
     var outsideRef = document.createElement("div");
@@ -206,6 +217,8 @@
 
 
     var interfaceOptions = interfaceObj.options;
+    var sortButton = document.getElementById("sort-fragments");
+    sortButton.style.visibility = "hidden";
     interfaceOptions.forEach(function (option) {
         if (option.type == "show") {
             switch (option.name) {
@@ -239,31 +252,8 @@
                     interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder, true);
                     break;
                 case "fragmentSort":
-                    var button = document.getElementById('sort');
-                    if (button === null) {
-                        button = document.createElement("button");
-                        button.id = 'sort';
-                        button.textContent = "Sort";
-                        button.style.display = 'inline-block';
-                        var container = document.getElementById("interface-buttons");
-                        var neighbour = container.lastElementChild;
-                        container.appendChild(button);
-                        button.onclick = function () {
-                            var sortIndex = interfaceContext.sortFragmentsByScore();
-                            var sliderBox = document.getElementById("slider-holder");
-                            var nodes = audioEngineContext.audioObjects.filter(function (ao) {
-                                return ao.specification.type !== "outside-reference";
-                            });
-                            var i;
-                            nodes.forEach(function (ao) {
-                                sliderBox.removeChild(ao.interfaceDOM.holder);
-                            });
-                            for (i = 0; i < nodes.length; i++) {
-                                var j = sortIndex[i];
-                                sliderBox.appendChild(nodes[j].interfaceDOM.holder);
-                            }
-                        };
-                    }
+                    var button = document.getElementById('sort-fragments');
+                    button.style.visibility = "visible";
                     break;
             }
         }
@@ -480,6 +470,14 @@
 function drawScale() {
     var interfaceObj = testState.currentStateMap.interfaces[0];
     var scales = testState.currentStateMap.interfaces[0].scales;
+    var ticks = specification.interfaces.options.concat(interfaceObj.options).find(function (a) {
+        return (a.type == "show" && a.name == "ticks");
+    });
+    if (ticks !== undefined) {
+        ticks = true;
+    } else {
+        ticks = false;
+    }
     scales = scales.sort(function (a, b) {
         return a.position - b.position;
     });
@@ -495,11 +493,13 @@
     scales.forEach(function (scale) {
         var posPercent = scale.position / 100.0;
         var posPix = (1 - posPercent) * (draw_heights[1] - draw_heights[0]) + draw_heights[0];
-        ctx.fillStyle = "#000000";
-        ctx.setLineDash([1, 2]);
-        ctx.moveTo(0, posPix);
-        ctx.lineTo(width, posPix);
-        ctx.stroke();
+        if (ticks) {
+            ctx.fillStyle = "#000000";
+            ctx.setLineDash([1, 2]);
+            ctx.moveTo(0, posPix);
+            ctx.lineTo(width, posPix);
+            ctx.stroke();
+        }
         var text = document.createElement('div');
         text.align = "right";
         var textC = document.createElement('span');
@@ -508,11 +508,26 @@
         text.className = "scale-text";
         textHolder.appendChild(text);
         text.style.top = (posPix - 9) + 'px';
-        text.style.left = 100 - ($(text).width() + 3) + 'px';
         lastHeight = posPix;
     });
 }
 
+function buttonSortFragmentClick() {
+    var sortIndex = interfaceContext.sortFragmentsByScore();
+    var sliderBox = document.getElementById("slider-holder");
+    var nodes = audioEngineContext.audioObjects.filter(function (ao) {
+        return ao.specification.type !== "outside-reference";
+    });
+    var i;
+    nodes.forEach(function (ao) {
+        sliderBox.removeChild(ao.interfaceDOM.holder);
+    });
+    for (i = 0; i < nodes.length; i++) {
+        var j = sortIndex[i];
+        sliderBox.appendChild(nodes[j].interfaceDOM.holder);
+    }
+}
+
 function buttonSubmitClick() // TODO: Only when all songs have been played!
 {
     var checks = testState.currentStateMap.interfaces[0].options,
@@ -528,6 +543,9 @@
     if (interfaceContext.checkFragmentMinPlays() === false) {
         return;
     }
+    if (interfaceContext.checkCommentQuestions() === false) {
+        return;
+    }
 
     for (var i = 0; i < checks.length; i++) {
         var checkState = true;
--- a/interfaces/timeline.js	Wed Nov 28 13:50:22 2018 +0000
+++ b/interfaces/timeline.js	Wed Nov 28 13:51:51 2018 +0000
@@ -505,6 +505,9 @@
     if (interfaceContext.checkFragmentMinPlays() === false) {
         return;
     }
+    if (interfaceContext.checkCommentQuestions() === false) {
+        return;
+    }
     for (var i = 0; i < checks.length; i++) {
         var checkState = true;
         if (checks[i].type == 'check') {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/js/bootstrap.min.js	Wed Nov 28 13:51:51 2018 +0000
@@ -0,0 +1,7 @@
+/*!
+ * Bootstrap v3.3.7 (http://getbootstrap.com)
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under the MIT license
+ */
+if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>3)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){if(a(b.target).is(this))return b.handleObj.handler.apply(this,arguments)}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.7",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a("#"===f?[]:f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.7",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c).prop(c,!0)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c).prop(c,!1))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target).closest(".btn");b.call(d,"toggle"),a(c.target).is('input[type="radio"], input[type="checkbox"]')||(c.preventDefault(),d.is("input,button")?d.trigger("focus"):d.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(!(a>this.$items.length-1||a<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){if(!this.sliding)return this.slide("next")},c.prototype.prev=function(){if(!this.sliding)return this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.7",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.7",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",c).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",".dropdown-menu",g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){d.$element.one("mouseup.dismiss.bs.modal",function(b){a(b.target).is(d.$element)&&(d.ignoreBackdropClick=!0)})}),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in"),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$dialog.one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){document===a.target||this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a(document.createElement("div")).addClass("modal-backdrop "+e).appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.adjustDialog()},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth<a,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"",this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.inState=null,this.init("tooltip",a,b)};c.VERSION="3.3.7",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);if(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),!c.isInStateTrue())return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-m<o.top?"bottom":"right"==h&&k.right+l>o.width?"left":"left"==h&&k.left-l<o.left?"right":h,f.removeClass(n).addClass(h)}var p=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(p,h);var q=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",q).emulateTransitionEnd(c.TRANSITION_DURATION):q()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top+=g,b.left+=h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element&&e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=a(this.$tip),g=a.Event("hide.bs."+this.type);if(this.$element.trigger(g),!g.isDefaultPrevented())return f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=window.SVGElement&&c instanceof window.SVGElement,g=d?{top:0,left:0}:f?null:b.offset(),h={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},i=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,h,i,g)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null,a.$element=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.7",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.7",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(void 0===e[a+1]||b<e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){
+this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.7",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.7",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return e<c&&"top";if("bottom"==this.affixed)return null!=c?!(e+this.unpin<=f.top)&&"bottom":!(e+g<=a-d)&&"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&e<=c?"top":null!=d&&i+j>=a-d&&"bottom"},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);
\ No newline at end of file
--- a/js/core.js	Wed Nov 28 13:50:22 2018 +0000
+++ b/js/core.js	Wed Nov 28 13:51:51 2018 +0000
@@ -1,6 +1,6 @@
 /**
  * core.js
- * 
+ *
  * Main script to run, calls all other core functions and manages loading/store to backend.
  * Also contains all global variables.
  */
@@ -44,6 +44,17 @@
     return el.firstChild.href;
 }
 
+function insertParam(s, key, value)
+{
+    key = encodeURI(key); value = encodeURI(value);
+    if (s.split("?").length == 1) {
+        s = s + ">";
+    } else {
+        s = s + "&";
+    }
+    return s+key+"="+value;
+}
+
 // Firefox does not have an XMLDocument.prototype.getElementsByName
 // and there is no searchAll style command, this custom function will
 // search all children recusrively for the name. Used for XSD where all
@@ -146,11 +157,12 @@
     // Create the specification object
     specification = new Specification();
 
+    // Create the storage object
+    storage = new Storage();
+
     // Create the interface object
     interfaceContext = new Interface(specification);
 
-    // Create the storage object
-    storage = new Storage();
     // Define window callbacks for interface
     window.onresize = function (event) {
         interfaceContext.resizeWindow(event);
@@ -174,6 +186,9 @@
                 case "returnURL":
                     gReturnURL = value;
                     break;
+                case "testKey":
+                    storage.sessionLinked = value;
+                    break;
                 case "saveFilenamePrefix":
                     storage.filenamePrefix = value;
                     break;
@@ -417,7 +432,7 @@
         storage.SessionKey.finish().then(function (resolved) {
             var converter = new showdown.Converter();
             if (typeof specification.returnURL == "string" && specification.returnURL.length > 0) {
-                window.location = specification.returnURL;
+                window.location = insertParam(specification.returnURL, "testKey", storage.SessionKey.key);
             } else {
                 popup.popupContent.innerHTML = converter.makeHtml(specification.exitText);
             }
@@ -1145,8 +1160,7 @@
 
     this.proceedClicked = function () {
         // Each time the popup button is clicked!
-        if (testState.stateIndex === 0 && specification.calibration) {
-            interfaceContext.calibrationModuleObject.collect();
+        if (testState.stateIndex === -1 && specification.calibration) {
             advanceState();
             return;
         }
@@ -1362,14 +1376,18 @@
                 this.advanceState();
             }
         } else if (this.stateIndex == -1) {
-            this.stateIndex++;
-            if (specification.calibration) {
+            if (interfaceContext.calibrationTests.checkFrequencies) {
                 popup.showPopup();
-                popup.popupTitle.textContent = "Calibration. Set the levels so all tones are of equal amplitude. Move your mouse over the sliders to hear the tones. The red slider is the reference tone";
-                interfaceContext.calibrationModuleObject = new interfaceContext.calibrationModule();
-                interfaceContext.calibrationModuleObject.build(popup.popupResponse);
+                popup.popupTitle.textContent = "Set the levels so all tones are of equal amplitude. Move your mouse over the sliders to hear the tones. The red slider is the reference tone";
+                interfaceContext.calibrationTests.performFrequencyCheck(popup.popupResponse);
+                popup.hidePreviousButton();
+            } else if (interfaceContext.calibrationTests.checkChannels) {
+                popup.showPopup();
+                popup.popupTitle.textContent = "Click play to start the audio, the click the button corresponding to where the sound appears to be coming from.";
+                interfaceContext.calibrationTests.performChannelCheck(popup.popupResponse);
                 popup.hidePreviousButton();
             } else {
+                this.stateIndex++;
                 this.advanceState();
             }
         } else if (this.stateIndex == this.stateMap.length) {
@@ -2221,10 +2239,19 @@
     };
 
     this.moved = function (time, position) {
+        var last;
         if (time > 0) {
             this.wasMoved = true;
         }
-        this.movementTracker[this.movementTracker.length] = [time, position];
+        // Get the last entry
+        if (this.movementTracker.length > 0) {
+            last = this.movementTracker[this.movementTracker.length - 1];
+        } else {
+            last = -1;
+        }
+        if (position != last[1]) {
+            this.movementTracker[this.movementTracker.length] = [time, position];
+        }
     };
 
     this.startListening = function (time) {
@@ -2425,6 +2452,9 @@
                 function trackCommentFocus() {
                     return document.activeElement.className.indexOf("trackComment") >= 0;
                 }
+                if (testState.currentStatePosition != "test") {
+                    return;
+                }
                 if (trackCommentFocus()) {
                     return;
                 }
@@ -2436,7 +2466,6 @@
                 } else {
                     keypress.call(this, e.key);
                 }
-                console.log(e);
             }
         };
         document.addEventListener("keydown", keyboardInterfaceController, false);
@@ -2488,7 +2517,7 @@
     this.returnDateNode = function () {
         // Create an XML Node for the Date and Time a test was conducted
         // Structure is
-        // <datetime> 
+        // <datetime>
         //	<date year="##" month="##" day="##">DD/MM/YY</date>
         //	<time hour="##" minute="##" sec="##">HH:MM:SS</time>
         // </datetime>
@@ -2721,6 +2750,12 @@
             this.textArea.style.width = boxwidth - 6 + "px";
         };
         this.resize();
+        this.check = function () {
+            if (this.specification.mandatory && this.textArea.value.length === 0) {
+                return false;
+            }
+            return true;
+        };
     };
 
     this.radioBox = function (commentQuestion) {
@@ -2795,6 +2830,15 @@
             }
             this.holder.style.width = boxwidth + "px";
         };
+        this.check = function () {
+            var anyChecked = this.options.some(function (a) {
+                return a.checked;
+            });
+            if (this.specification.mandatory && anyChecked === false) {
+                return false;
+            }
+            return true;
+        };
         this.resize();
     };
 
@@ -2861,6 +2905,15 @@
             }
             this.holder.style.width = boxwidth + "px";
         };
+        this.check = function () {
+            var anyChecked = this.options.some(function (a) {
+                return a.checked;
+            });
+            if (this.specification.mandatory && anyChecked === false) {
+                return false;
+            }
+            return true;
+        };
         this.resize();
     };
 
@@ -2918,6 +2971,9 @@
             this.holder.style.width = boxwidth + "px";
             this.slider.style.width = boxwidth - 24 + "px";
         };
+        this.check = function () {
+            return true;
+        };
         this.resize();
     };
 
@@ -2940,6 +2996,19 @@
         this.commentQuestions = [];
     };
 
+    this.checkCommentQuestions = function () {
+        var errored = this.commentQuestions.reduce(function (a, cq) {
+            if (cq.check() === false) {
+                a.push(cq);
+            }
+            return a;
+        }, []);
+        if (errored.length === 0) {
+            return true;
+        }
+        interfaceContext.lightbox.post("Message", "Not all the mandatory comment boxes below have been filled.");
+    };
+
     this.outsideReferenceDOM = function (audioObject, index, inject) {
         this.parent = audioObject;
         this.outsideReferenceHolder = document.createElement('button');
@@ -3171,93 +3240,200 @@
         return imageController;
     })();
 
-    this.calibrationModuleObject = null;
-    this.calibrationModule = function () {
-        // This creates an on-page calibration module
-        this.storeDOM = storage.document.createElement("calibration");
-        storage.root.appendChild(this.storeDOM);
-        // The calibration is a fixed state module
-        this.calibrationNodes = [];
-        this.holder = null;
-        this.build = function (inject) {
-            var f0 = 62.5;
-            this.holder = document.createElement("div");
-            this.holder.className = "calibration-holder";
-            this.calibrationNodes = [];
-            while (f0 < 20000) {
-                /* jshint loopfunc: true */
-                var obj = {
-                    root: document.createElement("div"),
-                    input: document.createElement("input"),
-                    oscillator: audioContext.createOscillator(),
-                    gain: audioContext.createGain(),
-                    f: f0,
-                    parent: this,
-                    handleEvent: function (event) {
-                        switch (event.type) {
-                            case "mouseenter":
-                                this.oscillator.start(0);
-                                break;
-                            case "mouseleave":
-                                this.oscillator.stop(0);
-                                this.oscillator = audioContext.createOscillator();
-                                this.oscillator.connect(this.gain);
-                                this.oscillator.frequency.value = this.f;
-                                break;
-                            case "mousemove":
-                                var value = Math.pow(10, this.input.value / 20);
-                                if (this.f == 1000) {
-                                    audioEngineContext.outputGain.gain.value = value;
-                                    interfaceContext.volume.slider.value = this.input.value;
-                                } else {
-                                    this.gain.gain.value = value;
+    this.calibrationTests = (function () {
+        function readonly(t) {
+            throw ("Cannot set read-only variable");
+        }
+
+        function getStorageRoot() {
+            var storageRoot = storage.root.querySelector("calibration");
+            if (storageRoot === undefined) {
+                storageRoot = storage.document.createElement("calibration");
+                storage.root.appendChild(storageRoot);
+            }
+            return storageRoot;
+        }
+        var calibrationObject,
+            _checkedFrequency = false,
+            _checkedChannels = false;
+
+        // Define the checkFrequencies test!
+        var checkFrequencyUnit = function (htmlRoot, storageRoot) {
+
+            function createFrequencyElement(frequency) {
+                return (function (frequency) {
+                    var hold = document.createElement("div");
+                    hold.className = "calibration-slider";
+                    var range = document.createElement("input");
+                    range.type = "range";
+                    range.min = "-24";
+                    range.max = "24";
+                    range.step = "0.5";
+                    range.setAttribute("orient", "vertical");
+                    range.value = (Math.random() - 0.5) * 24;
+                    range.setAttribute("frequency", frequency);
+                    hold.appendChild(range);
+                    htmlRoot.appendChild(hold);
+
+                    var gain = audioContext.createGain();
+                    gain.connect(outputGain);
+                    gain.gain.value = Math.pow(10, Number(range.value) / 20.0);
+                    var osc;
+
+                    var store = storage.document.createElement("response");
+                    store.setAttribute("frequency", frequency);
+                    storageHook.appendChild(store);
+                    var interface = {};
+                    Object.defineProperties(interface, {
+                        "handleEvent": {
+                            "value": function (e) {
+                                if (e.type == "mouseenter") {
+                                    osc = audioContext.createOscillator();
+                                    osc.frequency.value = frequency;
+                                    osc.connect(gain);
+                                    osc.start();
+                                    console.log("start " + frequency);
+                                } else if (e.type == "mouseleave") {
+                                    console.log("stop " + frequency);
+                                    osc.stop();
+                                    osc = undefined;
                                 }
-                                break;
+                                store.textContent = e.currentTarget.value;
+                                gain.gain.value = Math.pow(10, Number(e.currentTarget.value) / 20.0);
+                            }
                         }
-                    },
-                    disconnect: function () {
-                        this.gain.disconnect();
+                    });
+                    range.addEventListener("mousemove", interface);
+                    range.addEventListener("mouseenter", interface);
+                    range.addEventListener("mouseleave", interface);
+                    return interface;
+                })(frequency);
+            }
+            var htmlHook = document.createElement("div");
+            htmlRoot.appendChild(htmlHook);
+            var storageHook = storage.document.createElement("frequency");
+            storageRoot.appendChild(storageHook);
+            var frequencies = [100, 200, 400, 800, 1200, 1600, 2000, 4000, 8000, 12000];
+            var outputGain = audioContext.createGain();
+            outputGain.gain.value = 0.25;
+            outputGain.connect(audioContext.destination);
+            this.sliders = frequencies.map(createFrequencyElement);
+        };
+
+        var checkChannelsUnit = function (htmlRoot, storageRoot) {
+
+            function onclick(ev) {
+                var storageHook = storage.document.querySelector("calibration").querySelector("channels");
+                storageHook.setAttribute("selected", ev.currentTarget.value);
+                storageHook.setAttribute("selectedText", ev.currentTarget.textContent);
+                osc.stop();
+                gainL = undefined;
+                gainR = undefined;
+                cmerge = undefined;
+                popup.proceedClicked();
+            }
+            var osc = audioContext.createOscillator();
+            var gainL = audioContext.createGain();
+            var gainR = audioContext.createGain();
+            gainL.channelCount = 1;
+            gainR.channelCount = 1;
+            var cmerge = audioContext.createChannelMerger(2);
+            osc.connect(gainL, 0, 0);
+            osc.connect(gainR, 0, 0);
+            gainL.connect(cmerge, 0, 0);
+            gainR.connect(cmerge, 0, 1);
+            cmerge.connect(audioContext.destination);
+            var play = document.createElement("button");
+            play.textContent = "Play Audio";
+            play.onclick = function () {
+                osc.start();
+                play.disabled = true;
+            };
+            play.className = "calibration-button";
+            htmlRoot.appendChild(play);
+            var choiceHolder = document.createElement("div");
+            var leftButton = document.createElement("button");
+            leftButton.textContent = "Left";
+            leftButton.value = "-1";
+            leftButton.className = "calibration-button";
+            var centerButton = document.createElement("button");
+            centerButton.textContent = "Middle";
+            centerButton.value = "0";
+            centerButton.className = "calibration-button";
+            var rightButton = document.createElement("button");
+            rightButton.textContent = "Right";
+            rightButton.value = "1";
+            rightButton.className = "calibration-button";
+            choiceHolder.appendChild(leftButton);
+            choiceHolder.appendChild(centerButton);
+            choiceHolder.appendChild(rightButton);
+            htmlRoot.appendChild(choiceHolder);
+            leftButton.addEventListener("click", onclick);
+            centerButton.addEventListener("click", onclick);
+            rightButton.addEventListener("click", onclick);
+
+            var storageHook = storage.document.createElement("channels");
+            storageRoot.appendChild(storageHook);
+
+            var pan;
+            if (Math.random() > 0.5) {
+                pan = 1;
+                gainL.gain.value = 0.0;
+                gainR.gain.value = 0.25;
+                storageHook.setAttribute("presented", pan);
+                storageHook.setAttribute("presentedText", "Right");
+            } else {
+                pan = -1;
+                gainL.gain.value = 0.25;
+                gainR.gain.value = 0.0;
+                storageHook.setAttribute("presented", pan);
+                storageHook.setAttribute("presentedText", "Left");
+            }
+        };
+
+        var interface = {};
+        Object.defineProperties(interface, {
+            "calibrationObject": {
+                "get": function () {
+                    return calibrationObject;
+                },
+                "set": readonly
+            },
+            "checkFrequencies": {
+                "get": function () {
+                    if (specification.calibration.checkFrequencies && _checkedFrequency === false) {
+                        return true;
                     }
-                };
-                obj.root.className = "calibration-slider";
-                obj.root.appendChild(obj.input);
-                obj.oscillator.connect(obj.gain);
-                obj.gain.connect(audioEngineContext.outputGain);
-                obj.gain.gain.value = Math.random() * 2;
-                obj.input.value = obj.gain.gain.value;
-                obj.input.setAttribute('orient', 'vertical');
-                obj.input.type = "range";
-                obj.input.min = -12;
-                obj.input.max = 0;
-                obj.input.step = 0.25;
-                if (f0 != 1000) {
-                    obj.input.value = (Math.random() * 12) - 6;
-                } else {
-                    obj.input.value = 0;
-                    obj.root.style.backgroundColor = "rgb(255,125,125)";
+                    return false;
+                },
+                "set": readonly
+            },
+            "checkChannels": {
+                "get": function () {
+                    if (specification.calibration.checkChannels && _checkedChannels === false) {
+                        return true;
+                    }
+                    return false;
+                },
+                "set": readonly
+            },
+            "performFrequencyCheck": {
+                "value": function (htmlRoot) {
+                    htmlRoot.innerHTML = "";
+                    calibrationObject = new checkFrequencyUnit(htmlRoot, getStorageRoot());
+                    _checkedFrequency = true;
                 }
-                obj.input.addEventListener("mousemove", obj);
-                obj.input.addEventListener("mouseenter", obj);
-                obj.input.addEventListener("mouseleave", obj);
-                obj.gain.gain.value = Math.pow(10, obj.input.value / 20);
-                obj.oscillator.frequency.value = f0;
-                this.calibrationNodes.push(obj);
-                this.holder.appendChild(obj.root);
-                f0 *= 2;
+            },
+            "performChannelCheck": {
+                "value": function (htmlRoot) {
+                    htmlRoot.innerHTML = "";
+                    calibrationObject = new checkChannelsUnit(htmlRoot, getStorageRoot());
+                    _checkedChannels = true;
+                }
             }
-            inject.appendChild(this.holder);
-        };
-        this.collect = function () {
-            this.calibrationNodes.forEach(function (obj) {
-                var node = storage.document.createElement("calibrationresult");
-                node.setAttribute("frequency", obj.f);
-                node.setAttribute("range-min", obj.input.min);
-                node.setAttribute("range-max", obj.input.max);
-                node.setAttribute("gain-lin", obj.gain.gain.value);
-                this.storeDOM.appendChild(node);
-            }, this);
-        };
-    };
+        });
+        return interface;
+    })();
 
 
     // Global Checkers
@@ -3626,6 +3802,7 @@
     this.document = null;
     this.root = null;
     this.state = 0;
+    var linkedID = undefined;
     var pFilenamePrefix = "save";
 
     this.initialise = function (existingStore) {
@@ -3651,6 +3828,9 @@
         if (specification.postTest !== undefined) {
             this.globalPostTest = new this.surveyNode(this, this.root, specification.postTest);
         }
+        if (linkedID) {
+            this.root.setAttribute("linked", linkedID);
+        }
     };
 
     this.SessionKey = (function (parent) {
@@ -3658,13 +3838,17 @@
         if (window.returnURL !== undefined) {
             returnURL = String(window.returnURL);
         }
+        
+        var chainCount = 0;
+        var chainPosition = chainCount;
 
         function postUpdate() {
-            // Return a new promise.
-            var hold = document.createElement("div");
-            var clone = parent.root.cloneNode(true);
-            hold.appendChild(clone);
             return new Promise(function (resolve, reject) {
+                // Return a new promise.
+                chainPosition+=1;
+                var hold = document.createElement("div");
+                var clone = parent.root.cloneNode(true);
+                hold.appendChild(clone);
                 // Do the usual XHR stuff
                 console.log("Requested save...");
                 var req = new XMLHttpRequest();
@@ -3698,7 +3882,12 @@
                 };
 
                 // Make the request
-                req.send([hold.innerHTML]);
+                if (chainCount > chainPosition) {
+                    // We have items downstream that will upload for us
+                    resolve(true);
+                } else {
+                    req.send([hold.innerHTML]);
+                }
             });
         }
 
@@ -3779,9 +3968,10 @@
             },
             "update": {
                 "value": function () {
-                    if (this.key === null || requestChains === undefined) {
-                        throw ("Cannot save as key == null");
+                    if (requestChains === undefined) {
+                        throw ("Initiate key exchange first");
                     }
+                    chainCount += 1;
                     this.parent.root.setAttribute("state", "update");
                     requestChains = requestChains.then(postUpdate);
                 }
@@ -3794,6 +3984,7 @@
                     this.parent.finish();
                     return requestChains.then(postUpdate()).then(function () {
                         console.log("OK");
+                        return true;
                     }, function () {
                         createProjectSave("local");
                     });
@@ -4048,6 +4239,20 @@
                 pFilenamePrefix = value;
                 return value;
             }
+        },
+        "sessionLinked": {
+            'get': function () {
+                return linkedID;
+            },
+            'set': function(s) {
+                if (typeof s == "string") {
+                    linkedID = s;
+                    if (this.root) {
+                        this.root.setAttribute("linked", s);
+                    }
+                }
+                return linkedID;
+            }
         }
     });
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/js/min/core.min.js	Wed Nov 28 13:51:51 2018 +0000
@@ -0,0 +1,1 @@
+function escapeHTML(e){return e.split("&").join("&amp;").split("<").join("&lt;").split('"').join("&quot;")}function qualifyURL(e){var t=document.createElement("div");return t.innerHTML='<a href="'+escapeHTML(e)+'">x</a>',t.firstChild.href}function loadProjectSpec(e){var t=new XMLHttpRequest;t.open("GET","xml/test-schema.xsd",!0),t.onload=function(){specification.processSchema(t.response);var i=new XMLHttpRequest;i.open("GET",e,!0),i.onload=function(){loadProjectSpecCallback(i.response)},i.onerror=function(){document.getElementsByTagName("body")[0].innerHTML=null;var e=document.createElement("h3");e.textContent="FATAL ERROR";var t=document.createElement("p");t.textContent="There was an error when loading your XML file. Please check your path in the URL. After the path to this page, there should be '?url=path/to/your/file.xml'. Check the spelling of your filename as well. If you are still having issues, check the log of the python server or your webserver distribution for 404 codes for your file.",document.getElementsByTagName("body")[0].appendChild(e),document.getElementsByTagName("body")[0].appendChild(t)},i.send()},t.send()}function loadProjectSpecCallback(e){var t,i,n=(new DOMParser).parseFromString(e,"text/xml"),o=n.getElementsByTagName("parsererror");if(o.length>=1)return t=document.createElement("h3"),t.textContent="FATAL ERROR",i=document.createElement("span"),i.textContent="The XML parser returned the following errors when decoding your XML file",document.getElementsByTagName("body")[0].innerHTML=null,document.getElementsByTagName("body")[0].appendChild(t),document.getElementsByTagName("body")[0].appendChild(i),void document.getElementsByTagName("body")[0].appendChild(o[0]);if(void 0===n||void 0===n.firstChild)return t=document.createElement("h3"),t.textContent="FATAL ERROR",i=document.createElement("span"),i.textContent="The project XML was not decoded properly, try refreshing your browser and clearing caches. If the problem persists, contact the test creator.",document.getElementsByTagName("body")[0].innerHTML=null,document.getElementsByTagName("body")[0].appendChild(t),void document.getElementsByTagName("body")[0].appendChild(i);if("waet"==n.firstChild.nodeName){var s={xml:e,schema:specification.getSchemaString(),arguments:["--noout","--schema","test-schema.xsd","document.xml"]};projectXML=n;var r=validateXML(s);if(console.log(r),"document.xml validates\n"!=r){document.getElementsByTagName("body")[0].innerHTML=null,(t=document.createElement("h3")).textContent="FATAL ERROR",(i=document.createElement("h4")).textContent="The XML validator returned the following errors when decoding your XML file",document.getElementsByTagName("body")[0].appendChild(t),document.getElementsByTagName("body")[0].appendChild(i),r=r.split("\n");for(var a in r)document.getElementsByTagName("body")[0].appendChild(document.createElement("br")),(i=document.createElement("span")).textContent=r[a],document.getElementsByTagName("body")[0].appendChild(i);return}specification.decode(projectXML),storage.initialise()}else if("waetresult"==n.firstChild.nodeName){(projectXML=document.implementation.createDocument(null,"waet")).firstChild.appendChild(n.getElementsByTagName("waet")[0].getElementsByTagName("setup")[0].cloneNode(!0));for(var c,l=n.firstChild.firstChild;null!==l;){if("survey"==l.nodeName)if("complete"==l.getAttribute("state"))for(var u=l.getAttribute("location"),h=projectXML.getElementsByTagName("setup")[0].getElementsByTagName("survey")[0];null!==h;){if("pre"==u||"before"==u){if("pre"==h.getAttribute("location")||"before"==h.getAttribute("location")){projectXML.getElementsByTagName("setup")[0].removeChild(h);break}}else if("post"==h.getAttribute("location")||"after"==h.getAttribute("location")){projectXML.getElementsByTagName("setup")[0].removeChild(h);break}h=h.nextElementSibling}else c=l,l=l.previousElementSibling,n.firstChild.removeChild(c);else"page"==l.nodeName&&"empty"==l.getAttribute("state")&&(projectXML.firstChild.appendChild(n.getElementById(l.getAttribute("ref")).cloneNode(!0)),c=l,l=l.previousElementSibling,n.firstChild.removeChild(c));l=l.nextElementSibling}specification.decode(projectXML),storage.initialise(n)}if(isFinite(specification.sampleRate)&&Number(specification.sampleRate)!=audioContext.sampleRate){var p="Sample rates do not match! Requested "+Number(specification.sampleRate)+", got "+audioContext.sampleRate+". Please set the sample rate to match before completing this test.";interfaceContext.lightbox.post("Error",p)}else{var d=new XMLHttpRequest;d.open("GET","interfaces/interfaces.json"),d.onerror=function(e){throw e},d.onload=function(){if(200!==d.status)throw new Error(d.status);var e=specification.interface,t=document.getElementsByTagName("head")[0],i=JSON.parse(d.responseText).interfaces.find(function(t){return t.name==e});if(!i)throw"Cannot load desired interface";i.scripts.forEach(function(e){var i=document.createElement("script");i.setAttribute("type","text/javascript"),i.setAttribute("src",e),t.appendChild(i)}),i.css.forEach(function(e){var i=document.createElement("link");i.setAttribute("rel","stylesheet"),i.setAttribute("type","text/css"),i.setAttribute("href",e),t.appendChild(i)})},d.send(),void 0!==gReturnURL&&(console.log("returnURL Overide from "+specification.returnURL+" to "+gReturnURL),specification.returnURL=gReturnURL),void 0!==gSaveFilenamePrefix&&(specification.saveFilenamePrefix=gSaveFilenamePrefix),audioEngineContext=new AudioEngine(specification)}}function createProjectSave(e){window.onbeforeunload=null;var t=storage.finish(),i=document.createElement("div");i.appendChild(t);var n=[i.innerHTML];if("local"==e){var o=new Blob(n,{type:"application/xml"}),s=window.URL.createObjectURL(o),r=document.createElement("a");r.hidden="",r.href=s,r.download="save.xml",r.textContent="Save File",popup.showPopup(),popup.popupContent.innerHTML="<span>Please save the file below to give to your test supervisor</span><br>",popup.popupContent.appendChild(r)}else{"string"==typeof specification.projectReturn&&"http"==specification.projectReturn.substr(0,4)&&specification.projectReturn,storage.SessionKey.finish().then(function(e){"string"==typeof specification.returnURL&&specification.returnURL.length>0?window.location=specification.returnURL:popup.popupContent.textContent=specification.exitText},function(e){console.log("Save: Error! "+e.textContent),createProjectSave("local")}),popup.showPopup(),popup.popupContent.innerHTML=null,popup.popupContent.textContent="Submitting. Please Wait","function"==typeof popup.hideNextButton&&popup.hideNextButton(),"function"==typeof popup.hidePreviousButton&&popup.hidePreviousButton()}}function errorSessionDump(e){popup.showPopup(),popup.popupContent.innerHTML=null;var t=document.createElement("error"),i=document.createElement("div");"object"==typeof e?(t.appendChild(e),popup.popupContent.appendChild(e)):(t.textContent=e,popup.popupContent.innerHTML="ERROR : "+e);var n=interfaceXMLSave();n.appendChild(t),i.appendChild(n);var o=[i.innerHTML],s=new Blob(o,{type:"application/xml"}),r=window.URL.createObjectURL(s),a=document.createElement("a");a.hidden="",a.href=r,a.download="save.xml",a.textContent="Save File",popup.popupContent.appendChild(a)}function interfaceXMLSave(){return storage.finish()}function linearToDecibel(e){return 20*Math.log10(e)}function decibelToLinear(e){return Math.pow(10,e/20)}function secondsToSamples(e,t){return Math.round(e*t)}function samplesToSeconds(e,t){return e/t}function randomString(e){for(var t="",i=0;i<e;i+=2){t+=Math.floor(1295*Math.random()).toString(36)}return t}function randomiseOrder(e){for(var t=e.length,i=[],n=0;n<t;++n)i.push(n);for(var o=i.slice(0),s=[],r=[],a=0;a<t;a++){var c=Math.random();c=Math.floor(c*e.length),s.push(e.splice(c,1)[0]),r.push(i.splice(c,1)[0])}return console.log(o.toString()),console.log(r.toString()),s}function randomSubArray(e,t){t>e.length&&(t=e.length);for(var i=[];t>0;){var n=Math.floor(Math.random()*e.length);i.push(e.splice(n,1)[0]),t--}return i}function interfacePopup(){function e(e,r){function a(e){var t=this.popupOptions.findIndex(function(t,i,n){return t.specification.id==e},this);this.currentIndex=t-1}var c;if("question"===e.specification.type)c=t;else if("checkbox"===e.specification.type)c=i;else if("radio"===e.specification.type)c=n;else if("number"===e.specification.type)c=o;else{if("slider"!==e.specification.type)return;c=s}for(var l=0;l<e.specification.conditions.length;l++){var u,h=e.specification.conditions[l];if(null!==(u=c(h,r)?h.jumpToOnPass:h.jumpToOnFail)){a.call(this,u);break}}}function t(e,t){switch(e.check){case"equals":if(t==e.value)return!0;break;case"greaterThan":case"lessThan":console.log("Survey Element of type 'question' cannot interpret greaterThan/lessThan conditions. IGNORING");break;case"contains":if(t.includes(e.value))return!0}return!1}function i(e,t){switch(e.check){case"contains":for(var i=0;i<t.length;i++){var n=t[i];if(n.name===e.value&&n.checked)return!0}break;case"equals":case"greaterThan":case"lessThan":console.log("Survey Element of type 'checkbox' cannot interpret equals/greaterThan/lessThan conditions. IGNORING");break;default:console.log("Unknown condition. IGNORING")}return!1}function n(e,t){switch(e.check){case"equals":if(t===e.value)return!0;break;case"contains":case"greaterThan":case"lessThan":console.log("Survey Element of type 'radio' cannot interpret contains/greaterThan/lessThan conditions. IGNORING");break;default:console.log("Unknown condition. IGNORING")}return!1}function o(e,t){var i=i;switch(i.check){case"greaterThan":if(t>Number(i.value))return!0;break;case"lessThan":if(t<Number(i.value))return!0;break;case"equals":if(t==i.value)return!0;break;case"contains":console.log("Survey Element of type 'number' cannot interpret \"contains\" conditions. IGNORING");break;default:console.log("Unknown condition. IGNORING")}return!1}function s(e,t){switch(e.check){case"contains":console.log("Survey Element of type 'number' cannot interpret contains conditions. IGNORING");break;case"greaterThan":if(t>Number(e.value))return!0;break;case"lessThan":if(t<Number(e.value))return!0;break;case"equals":if(t==e.value)return!0;break;default:console.log("Unknown condition. IGNORING")}return!1}this.popup=null,this.popupContent=null,this.popupTitle=null,this.popupResponse=null,this.buttonProceed=null,this.buttonPrevious=null,this.popupOptions=null,this.currentIndex=null,this.node=null,this.store=null;var r;$(window).keypress(function(e){13==e.keyCode&&"visible"==popup.popup.style.visibility&&!1===interfaceContext.lightbox.isVisible()&&(console.log(e),popup.buttonProceed.onclick(),e.preventDefault())}),this.createPopup=function(){document.getElementById("topLevelBody");this.popup=document.getElementById("popupHolder"),this.popup.style.left=window.innerWidth/2-250+"px",this.popup.style.top=window.innerHeight/2-125+"px",this.popupContent=document.getElementById("popupContent"),this.popupTitle=document.getElementById("popupTitleHolder"),this.popupResponse=document.getElementById("popupResponse"),this.buttonProceed=document.getElementById("popup-proceed"),this.buttonProceed.onclick=function(){popup.proceedClicked()},this.buttonPrevious=document.getElementById("popup-previous"),this.buttonPrevious.onclick=function(){popup.previousClick()},this.hidePopup(),this.popup.style.visibility="hidden"},this.showPopup=function(){null===this.popup&&this.createPopup(),this.popup.style.visibility="visible";document.getElementsByClassName("testHalt")[0].style.visibility="visible",this.popupResponse.style.left="0%"},this.hidePopup=function(){if(this.popup){this.popup.style.visibility="hidden";document.getElementsByClassName("testHalt")[0].style.visibility="hidden",this.buttonPrevious.style.visibility="inherit"}},this.postNode=function(){var e=this.popupOptions[this.currentIndex],t=new showdown.Converter,i=new DOMParser;r=new Date,this.popupResponse.innerHTML="",this.popupTitle.innerHTML="";var n=e.specification.statement.split("\n");n.forEach(function(e,t,i){i[t]=e.trim()}),e.specification.statement=n.join("\n");for(var o=i.parseFromString(t.makeHtml(e.specification.statement),"text/html").querySelector("body").children;o.length>0;)this.popupTitle.appendChild(o[0]);"question"==e.specification.type?function(e){var t=document.createElement("textarea");switch(e.specification.boxsize){case"small":t.cols="20",t.rows="1";break;case"normal":t.cols="30",t.rows="2";break;case"large":t.cols="40",t.rows="5";break;case"huge":t.cols="50",t.rows="10"}void 0===e.response?e.response="":t.value=e.response,this.popupResponse.appendChild(t),t.focus(),this.popupResponse.style.textAlign="center",this.popupResponse.style.left="0%"}.call(this,e):"checkbox"==e.specification.type?function(e){null===e.response&&(e.response=[]);var t=document.createElement("table");t.className="popup-option-list",t.border="0";var i=[];e.specification.options.forEach(function(t,n){var o=document.createElement("tr");i.push(o);var s=document.createElement("td");o.appendChild(s);var r=document.createElement("input");r.id=t.name,r.type="checkbox",s.appendChild(r),s=document.createElement("td"),o.appendChild(s);var a=document.createElement("span");a.textContent=t.text,s.appendChild(a),(o=document.createElement("div")).setAttribute("name","option"),o.className="popup-option-checbox";var c;e.response.length>0&&(c=e.response.find(function(e){return e.name==t.name})),void 0!==c?!0===c.checked&&(r.checked="true"):e.response.push({name:t.name,text:t.text,checked:!1})}),e.specification.randomise&&(i=randomiseOrder(i)),i.forEach(function(e){t.appendChild(e)}),this.popupResponse.appendChild(t)}.call(this,e):"radio"==e.specification.type?function(e){null===e.response&&(e.response={name:"",text:""});var t=document.createElement("table");t.className="popup-option-list",t.border="0";var i=[];e.specification.options.forEach(function(t,n){var o=document.createElement("tr");i.push(o);var s=document.createElement("td");o.appendChild(s);var r=document.createElement("input");r.id=t.name,r.type="radio",r.name=e.specification.id,s.appendChild(r),s=document.createElement("td"),o.appendChild(s);var a=document.createElement("span");a.textContent=t.text,s.appendChild(a),(o=document.createElement("div")).setAttribute("name","option"),o.className="popup-option-checkbox",e.response.name===t.name&&(r.checked=!0)}),e.specification.randomise&&(i=randomiseOrder(i)),i.forEach(function(e){t.appendChild(e)}),this.popupResponse.appendChild(t)}.call(this,e):"number"==e.specification.type?function(e){var t=document.createElement("input");t.type="textarea",null!==e.specification.min&&(t.min=e.specification.min),null!==e.specification.max&&(t.max=e.specification.max),null!==e.specification.step&&(t.step=e.specification.step),void 0!==e.response&&(t.value=e.response),this.popupResponse.appendChild(t),this.popupResponse.style.textAlign="center",this.popupResponse.style.left="0%"}.call(this,e):"video"==e.specification.type?function(e){var t=document.createElement("video");t.src=e.specification.url,this.popupResponse.appendChild(t)}.call(this,e):"youtube"==e.specification.type?function(e){var t=document.createElement("iframe");t.className="youtube",t.src=e.specification.url,this.popupResponse.appendChild(t)}.call(this,e):"slider"==e.specification.type&&function(e){var t=document.createElement("div"),i=document.createElement("input");i.type="range",i.style.width="90%",null!==e.specification.min&&(i.min=e.specification.min),null!==e.specification.max&&(i.max=e.specification.max),void 0!==e.response&&(i.value=e.response),t.className="survey-slider-text-holder";var n=document.createElement("span"),o=document.createElement("span");n.textContent=e.specification.leftText,o.textContent=e.specification.rightText,t.appendChild(n),t.appendChild(o),this.popupResponse.appendChild(i),this.popupResponse.appendChild(t),this.popupResponse.style.textAlign="center"}.call(this,e),this.currentIndex+1==this.popupOptions.length?"pre"==this.node.location?this.buttonProceed.textContent="Start":this.buttonProceed.textContent="Submit":this.buttonProceed.textContent="Next",this.currentIndex>0?this.buttonPrevious.style.visibility="visible":this.buttonPrevious.style.visibility="hidden"},this.initState=function(e,t){e.options.length>0?(this.popupOptions=[],this.node=e,this.store=t,e.options.forEach(function(e){this.popupOptions.push({specification:e,response:null})},this),this.currentIndex=0,this.showPopup(),this.postNode()):advanceState()},this.proceedClicked=function(){if(0===testState.stateIndex&&specification.calibration)return interfaceContext.calibrationModuleObject.collect(),void advanceState();var t=this.popupOptions[this.currentIndex],i=!0,n=(new Date-r)/1e3;n<t.specification.minWait?interfaceContext.lightbox.post("Error","Not enough time has elapsed, please wait "+(t.specification.minWait-n).toFixed(0)+" seconds"):(t.elapsedTime=n,"question"==t.specification.type?i=function(t){var i=this.popupResponse.getElementsByTagName("textarea")[0];return!0===t.specification.mandatory&&0===i.value.length?(interfaceContext.lightbox.post("Error","This question is mandatory"),!1):(console.log("Question: "+t.specification.statement),console.log("Question Response: "+i.value),t.response=i.value,e.call(this,t,i.value),!0)}.call(this,t):"checkbox"==t.specification.type?i=function(t){console.log("Checkbox: "+t.specification.statement);var i,n=this.popupResponse.getElementsByTagName("input"),o=0;for(i=0;i<t.specification.options.length;i++)n[i].checked&&o++;if(void 0!==t.specification.min)if(void 0===t.specification.max){if(o<t.specification.min){var s="You must select at least "+t.specification.min+" option";return t.specification.min>1&&(s+="s"),void interfaceContext.lightbox.post("Error",s)}}else if(o<t.specification.min||o>t.specification.max)return t.specification.min==t.specification.max?interfaceContext.lightbox.post("Error","You must only select "+t.specification.min):interfaceContext.lightbox.post("Error","You must select between "+t.specification.min+" and "+t.specification.max),!1;for(i=0;i<t.specification.options.length;i++)t.response.forEach(function(e){var t=this.popupResponse.querySelector("#"+e.name);e.checked=t.checked}),console.log(t.specification.options[i].name+": "+n[i].checked);return e.call(this,t,t.response),!0}.call(this,t):"radio"==t.specification.type?i=function(t){var i=this.popupResponse;console.log("Radio: "+t.specification.statement),t.response=null;for(var n,o=0,s=i.getElementsByTagName("input");void 0===n;){if(o==s.length){if(!0===t.specification.mandatory)return interfaceContext.lightbox.post("Error","Please select one option"),!1;break}!0===s[o].checked&&(n=s[o]),o++}var r=t.specification.options.find(function(e){return n.id==e.name});if(void 0===r)throw interfaceContext.lightbox.post("Error","A configuration error has occured, the test cannot be continued"),"ERROR - Cannot find option";return t.response=r,e.call(this,t,t.response.name),!0}.call(this,t):"number"==t.specification.type?i=function(t){var i=this.popupContent.getElementsByTagName("input")[0];if(!0===t.specification.mandatory&&0===i.value.length)return interfaceContext.lightbox.post("Error","This question is mandatory. Please enter a number"),!1;var n=Number(i.value);return isNaN(n)?(interfaceContext.lightbox.post("Error","Please enter a valid number"),!1):n<t.specification.min&&null!==t.specification.min?(interfaceContext.lightbox.post("Error","Number is below the minimum value of "+t.specification.min),!1):n>t.specification.max&&null!==t.specification.max?(interfaceContext.lightbox.post("Error","Number is above the maximum value of "+t.specification.max),!1):(t.response=i.value,e.call(this,t,t.response),!0)}.call(this,t):"slider"==t.specification.type&&(i=function(t){var i=this.popupContent.getElementsByTagName("input")[0];return t.response=i.value,e.call(this,t,t.response),!0}.call(this,t)),!1!==i&&(this.currentIndex++,this.currentIndex<this.popupOptions.length?this.postNode():(this.popupTitle.innerHTML="",this.popupResponse.innerHTML="",this.hidePopup(),this.popupOptions.forEach(function(e){this.store.postResult(e)},this),this.store.complete(),advanceState())))},this.previousClick=function(){this.currentIndex>0&&(this.currentIndex--,this.postNode())},this.resize=function(e){if(null!==this.popup){this.popup.style.left=window.innerWidth/2-250+"px",this.popup.style.top=window.innerHeight/2-125+"px";var t=document.getElementsByClassName("testHalt")[0];t.style.width=window.innerWidth,t.style.height=window.innerHeight}},this.hideNextButton=function(){this.buttonProceed.style.visibility="hidden"},this.hidePreviousButton=function(){this.buttonPrevious.style.visibility="hidden"},this.showNextButton=function(){this.buttonProceed.style.visibility="visible"},this.showPreviousButton=function(){this.buttonPrevious.style.visibility="visible"}}function advanceState(){testState.advanceState()}function stateMachine(){function e(e,t){var i=[];return e.forEach(function(t,n){t.alwaysInclude&&i.push(e.splice(n,1)[0])}),i.concat(randomSubArray(e,t-i.length))}this.stateMap=[],this.preTestSurvey=null,this.postTestSurvey=null,this.stateIndex=null,this.currentStateMap=null,this.currentStatePosition=null,this.currentStore=null,this.initialise=function(){var t=[];specification.pages.forEach(function(e){(null!==e.position||e.alwaysInclude)&&(e.alwaysInclude=!0),t.push(e)}),specification.numPages>0&&(specification.randomiseOrder=!0,t=e(t,specification.numPages));var i=[];t.forEach(function(e){if(void 0!==e.position){i.push(e);var n=t.indexOf(e);t.splice(n,1)}}),specification.randomiseOrder&&(t=randomiseOrder(t)),i.forEach(function(e){t.splice(e.position,0,e)}),t.forEach(function(t,i){t.presentedId=i,this.stateMap.push(t);t.audioElements;!function(t){var i=[],n=[],o=[];t.audioElements.forEach(function(e){e.label.length>0||void 0!==e.postion?i.push(e):"outside-reference"===e.type?n.push(e):o.push(e)}),(t.poolSize>0||t.randomiseOrder)&&(t.randomiseOrder=!0,0===t.poolSize&&(t.poolSize=t.audioElements.length),t.poolSize-=i.length,o=e(o,t.poolSize)),t.randomiseOrder&&(o=randomiseOrder(o)),i=i.concat(o),t.audioElements=i.concat(n),t.audioElements.forEach(function(e,t){e.position=t})}(t),storage.createTestPageStore(t),audioEngineContext.loadPageData(t)},this),null!==specification.preTest&&(this.preTestSurvey=specification.preTest),null!==specification.postTest&&(this.postTestSurvey=specification.postTest),this.stateMap.length>0?(null!==this.stateIndex&&console.log("NOTE - State already initialise"),this.stateIndex=-2,console.log("Starting test...")):console.log("FATAL - StateMap not correctly constructed. EMPTY_STATE_MAP")},this.advanceState=function(){if(null===this.stateIndex&&this.initialise(),this.stateIndex>-2&&storage.update(),-2==this.stateIndex)this.stateIndex++,void 0!==this.preTestSurvey?popup.initState(this.preTestSurvey,storage.globalPreTest):this.advanceState();else if(-1==this.stateIndex)this.stateIndex++,specification.calibration?(popup.showPopup(),popup.popupTitle.textContent="Calibration. Set the levels so all tones are of equal amplitude. Move your mouse over the sliders to hear the tones. The red slider is the reference tone",interfaceContext.calibrationModuleObject=new interfaceContext.calibrationModule,interfaceContext.calibrationModuleObject.build(popup.popupResponse),popup.hidePreviousButton()):this.advanceState();else if(this.stateIndex==this.stateMap.length)console.log("Ending test ..."),this.stateIndex++,void 0===this.postTestSurvey?this.advanceState():popup.initState(this.postTestSurvey,storage.globalPostTest);else if(this.stateIndex>this.stateMap.length)createProjectSave(specification.projectReturn);else{if(popup.hidePopup(),null===this.currentStateMap)return this.currentStateMap=this.stateMap[this.stateIndex],this.currentStore=storage.testPages[this.stateIndex],void 0!==this.currentStateMap.preTest?(this.currentStatePosition="pre",popup.initState(this.currentStateMap.preTest,storage.testPages[this.stateIndex].preTest)):this.currentStatePosition="test",void interfaceContext.newPage(this.currentStateMap,storage.testPages[this.stateIndex]);switch(this.currentStatePosition){case"pre":this.currentStatePosition="test";break;case"test":if(this.currentStatePosition="post",this.testPageCompleted(),void 0===this.currentStateMap.postTest)return void this.advanceState();popup.initState(this.currentStateMap.postTest,storage.testPages[this.stateIndex].postTest);break;case"post":this.stateIndex++,this.currentStateMap=null,this.advanceState()}}},this.testPageCompleted=function(){var e=storage.testPages[this.stateIndex],t=e.XMLDOM.getElementsByTagName("metric")[0];if(audioEngineContext.metric.enableTestTimer){var i=e.parent.document.createElement("metricresult");i.id="testTime",i.textContent=audioEngineContext.timer.testDuration,t.appendChild(i)}audioEngineContext.audioObjects;audioEngineContext.audioObjects.forEach(function(e){e.exportXMLDOM()}),interfaceContext.commentQuestions.forEach(function(t){t.exportXMLDOM(e)}),pageXMLSave(e.XMLDOM,this.currentStateMap),e.complete()},this.getCurrentTestPage=function(){return this.stateIndex>=0&&this.stateIndex<this.stateMap.length?this.currentStateMap:null},this.getCurrentTestPageStore=function(){return this.stateIndex>=0&&this.stateIndex<this.stateMap.length?this.currentStore:null}}function AudioEngine(e){this.outputGain=audioContext.createGain(),this.fooGain=audioContext.createGain(),this.fooGain.gain.value=0,this.status=0,this.outputGain.connect(audioContext.destination),this.fooGain.connect(audioContext.destination),this.timer=new timer,this.metric=new sessionMetrics(this,e),this.loopPlayback=!1,this.synchPlayback=!1,this.pageSpecification=null,this.pageStore=null;var t=audioContext.createBuffer(1,audioContext.sampleRate,audioContext.sampleRate);this.nullBufferSource=audioContext.createBufferSource(),this.nullBufferSource.buffer=t,this.nullBufferSource.loop=!0,this.nullBufferSource.start(0),this.audioObjects=[],this.buffers=[],this.bufferObj=function(){var e=[];this.buffer=null,this.users=[],this.progress=0,this.status=0,this.ready=function(){this.status>=2&&(this.status=3);for(var e=0;e<this.users.length;e++)this.users[e].state=1,null!==this.users[e].interfaceDOM&&this.users[e].bufferLoaded(this)},this.setUrls=function(t){var i,n=audioContext.sampleRate,o=[];for(i=0;i<t.length;i++)t[i].sampleRate==n&&o.push(t.splice(i,1)[0]);o=o.concat(t),e=o},this.hasUrl=function(t){var i,n=e.length;for(i=0;i<n;i++)if(e[i].url==t)return!0;return!1},this.getMedia=function(){function t(e){return new Promise(function(t,i){var n=new XMLHttpRequest;n.open("GET",e,!0),n.responseType="arraybuffer",n.onload=function(){200==n.status&&t(n.response)},n.onerror=function(){i(new Error(n.statusText))},n.addEventListener("progress",function(e){if(e.lengthComputable){this.progress=e.loaded/e.total;for(var t=0;t<this.users.length;t++)null!==this.users[t].interfaceDOM&&"function"==typeof this.users[t].interfaceDOM.updateLoading&&this.users[t].interfaceDOM.updateLoading(100*this.progress)}}.bind(o)),n.send()})}function i(){if(!(++s>=e.length))return t(e[s].url).then(n.bind(this)).catch(i.bind(this));!function(){this.status=-1;for(var t=0;t<this.users.length;t++)this.users[t].state=-1,null!==this.users[t].interfaceDOM&&this.users[t].bufferLoaded(this);interfaceContext.lightbox.post("Error","Could not load resource "+e[s].url)}()}function n(e){var t=this;return audioContext.decodeAudioData(e,function(e){return t.buffer=e,t.status=2,calculateLoudness(t,"I"),!0},function(i){var n=new WAVE;if(0===n.open(e)){t.buffer=audioContext.createBuffer(n.num_channels,n.num_samples,n.sample_rate);for(var o=0;o<n.num_channels;o++)for(var s=t.buffer.getChannelData(o),r=0;r<n.num_samples;r++)s[r]=n.decoded_data[o][r]}return void 0!==t.buffer?(t.status=2,calculateLoudness(t,"I"),!0):(n=void 0,!1)})}var o=this,s=0;this.progress=0,this.status=1,s=0,t(e[0].url).then(n.bind(o)).catch(i.bind(o))},this.registerAudioObject=function(e){this.users.forEach(function(t){if(e.id==t.id)return 0}),this.users.push(e),3!=this.status&&-1!=this.status||e.bufferLoaded(this)},this.copyBuffer=function(e,t){void 0===e&&(e=0),void 0===t&&(t=0);var i,n=secondsToSamples(e,this.buffer.sampleRate),o=secondsToSamples(t,this.buffer.sampleRate),s=this.buffer.length+n+o,r=audioContext.createBuffer(this.buffer.numberOfChannels,s,this.buffer.sampleRate);if(0===n&&"function"==typeof r.copyToChannel)for(i=0;i<this.buffer.numberOfChannels;i++)r.copyToChannel(this.buffer.getChannelData(i),i);else for(i=0;i<this.buffer.numberOfChannels;i++)for(var a=this.buffer.getChannelData(i),c=r.getChannelData(i),l=0;l<a.length;l++)c[l+n]=a[l];return r.lufs=this.buffer.lufs,r.playbackGain=this.buffer.playbackGain,r},this.cropBuffer=function(e,t){for(var i=Math.floor(e*this.buffer.sampleRate),n=Math.floor(t*this.buffer.sampleRate),o=n-i,s=audioContext.createBuffer(this.buffer.numberOfChannels,o,this.buffer.sampleRate),r=0;r<this.buffer.numberOfChannels;r++){var a=this.buffer.getChannelData(r),c=a.subarray(i,n);if("function"==typeof s.copyToChannel)s.copyToChannel(c,r);else for(var l=s.getChannelData(r),u=0;u<o;u++)l[u]=a[u+i]}return s}},this.loadPageData=function(e){e.audioElements.forEach(function(t){var i=e.hostURL+t.url,n=this.buffers.find(function(e){return e.hasUrl(i)});if(void 0===n){n=new this.bufferObj;var o=[{url:i,sampleRate:t.sampleRate}];t.alternatives.forEach(function(e){o.push({url:e.url,sampleRate:e.sampleRate})}),n.setUrls(o),n.getMedia(),this.buffers.push(n)}},this)},this.play=function(t){if("number"!=typeof t||t<0||t>this.audioObjects.length)throw"FATAL - Passed id was undefined - AudioEngineContext.play(id)";var i=this.audioObjects[t].specification.maxNumberPlays||this.audioObjects[t].specification.parent.maxNumberPlays||e.maxNumberPlays;if(void 0!==i&&this.audioObjects[t].numberOfPlays>=i)interfaceContext.lightbox.post("Error","Cannot play this fragment more than "+i+" times");else if(1===this.status){if(this.timer.startTest(),interfaceContext.playhead.setTimePerPixel(this.audioObjects[t]),this.synchPlayback)(function(t){var i=audioContext.currentTime+.1;e.crossFade,this.audioObjects.forEach(function(e){e.setupPlayback(),e.bufferStart(i),e.id===t?e.listenStart(i):e.listenStop(i)})}).call(this,t);else{if(!1===this.bufferReady(t))return void console.log("Cannot play. Buffer not ready");(function(t){var i=audioContext.currentTime+.1,n=i+e.crossFade;this.audioObjects.forEach(function(e){e.id===t?(e.setupPlayback(),e.bufferStart(i),e.listenStart(i)):(e.listenStop(i),e.bufferStop(n))})}).call(this,t)}interfaceContext.playhead.start()}},this.stop=function(){if(1==this.status){var e=audioContext.currentTime+.1;this.audioObjects.forEach(function(t){t.listenStop(e),t.bufferStop(e)}),interfaceContext.playhead.stop()}},this.newTrack=function(e){var t=this.audioObjects.length;this.audioObjects[t]=new audioObject(t);var i=testState.currentStateMap.hostURL+e.url,n=this.buffers.find(function(e){return e.hasUrl(i)});void 0===n&&(console.log("[WARN]: Buffer was not loaded in pre-test! "+i),n=new this.bufferObj,this.buffers.push(n),n.getMedia(i)),this.audioObjects[t].specification=e,this.audioObjects[t].url=i;for(var o=this.pageStore.XMLDOM.getElementsByTagName("audioelement"),s=0;s<o.length;s++)if(o[s].getAttribute("ref")==e.id){this.audioObjects[t].storeDOM=o[s];break}return n.registerAudioObject(this.audioObjects[t]),this.audioObjects[t]},this.newTestPage=function(e,t){this.pageStore=t,this.pageSpecification=e,this.status=0,this.audioObjectsReady=!1,this.metric.reset(),this.buffers.forEach(function(e){e.users=[]}),this.audioObjects=[],this.timer=new timer,this.loopPlayback=e.loop,this.synchPlayback=e.synchronous,interfaceContext.keyboardInterface.resetKeyBindings()},this.checkAllPlayed=function(){for(var e=[],t=0;t<this.audioObjects.length;t++)!1===this.audioObjects[t].metric.wasListenedTo&&e.push(this.audioObjects[t].id);return e},this.checkAllReady=function(){for(var e=!0,t=0;t<this.audioObjects.length;t++)0===this.audioObjects[t].state&&(console.log("WAIT -- audioObject "+t+" not ready yet!"),e=!1);return e},this.setSynchronousLoop=function(){for(var e=0,t=0;t<this.audioObjects.length;t++)e<this.audioObjects[t].buffer.buffer.duration&&(e=this.audioObjects[t].buffer.buffer.duration,t);this.audioObjects.forEach(function(t){t.buffer.buffer.duration!==e&&(t.buffer.buffer=t.buffer.copyBuffer(0,e-t.buffer.buffer.duration))})},this.bufferReady=function(e){return!!this.checkAllReady()&&(this.synchPlayback&&this.setSynchronousLoop(),this.status=1,!0)}}function audioObject(e){var t=0;this.specification=void 0,this.id=e,this.state=0,this.url=null,this.metric=new metricTracker(this),this.storeDOM=null,this.playing=!1,this.interfaceDOM=null,this.commentDOM=null,this.bufferNode=void 0,this.outputGain=audioContext.createGain(),this.outputGain.gain.value=0,this.onplayGain=1,this.outputGain.connect(audioEngineContext.outputGain),audioEngineContext.nullBufferSource.connect(this.outputGain),this.buffer=void 0,this.bufferLoaded=function(t){if(-1==t.status)return this.state=-1,null!==this.interfaceDOM&&this.interfaceDOM.error(),void(this.buffer=t);this.buffer=t;var i=this.specification.preSilence||this.specification.parent.preSilence||specification.preSilence||0,n=this.specification.postSilence||this.specification.parent.postSilence||specification.postSilence||0,o=this.specification.startTime,s=this.specification.stopTime,r=new t.constructor;r.buffer=t.cropBuffer(o||0,s||t.buffer.duration),0===i&&0===n||(r.buffer=r.copyBuffer(i,n)),r.buffer.lufs=t.buffer.lufs,this.buffer=r;var a=this.specification.loudness||this.specification.parent.loudness||specification.loudness;"number"==typeof a&&isFinite(a)?this.buffer.buffer.playbackGain=decibelToLinear(a-this.buffer.buffer.lufs):this.buffer.buffer.playbackGain=1,null!==this.interfaceDOM&&this.interfaceDOM.enable(),this.onplayGain=decibelToLinear(this.specification.gain)*(this.buffer.buffer.playbackGain||1),this.storeDOM.setAttribute("playGain",linearToDecibel(this.onplayGain)),this.state=1,audioEngineContext.bufferReady(e)},this.bindInterface=function(e){if(this.interfaceDOM=e,this.metric.initialise(e.getValue()),1==this.state)this.interfaceDOM.enable();else if(-1==this.state)return void this.interfaceDOM.error();var t=e.getPresentedId();this.storeDOM.setAttribute("presentedId",t),1==t.length&&interfaceContext.keyboardInterface.registerKeyBinding(t,this)},this.listenStart=function(e){!1===this.playing&&(t++,this.outputGain.gain.linearRampToValueAtTime(this.onplayGain,e),this.metric.startListening(audioEngineContext.timer.getTestTime()),this.bufferNode.playbackStartTime=audioEngineContext.timer.getTestTime(),this.interfaceDOM.startPlayback(),this.playing=!0)},this.listenStop=function(e){!0===this.playing&&(this.outputGain.gain.linearRampToValueAtTime(0,e),this.metric.stopListening(audioEngineContext.timer.getTestTime(),this.getCurrentPosition())),this.interfaceDOM.stopPlayback(),this.playing=!1},this.setupPlayback=function(){void 0===this.bufferNode&&void 0!==this.buffer.buffer&&(this.bufferNode=audioContext.createBufferSource(),this.bufferNode.owner=this,this.bufferNode.connect(this.outputGain),this.bufferNode.buffer=this.buffer.buffer,audioEngineContext.loopPlayback&&(this.bufferNode.loopStart=this.specification.startTime||0,this.bufferNode.loopEnd=this.specification.stopTime-this.specification.startTime||this.buffer.buffer.duration,this.bufferNode.loop=!0),this.bufferNode.onended=function(e){null!==e.currentTarget&&(e.currentTarget.owner.bufferStop(audioContext.currentTime+.1),e.currentTarget.owner.listenStop(audioContext.currentTime+.1))},this.bufferNode.state=0)},this.bufferStart=function(e){this.outputGain.gain.cancelScheduledValues(audioContext.currentTime),this.bufferNode&&0===this.bufferNode.state&&(this.bufferNode.state=1,!0===this.bufferNode.loop?this.bufferNode.start(e):this.bufferNode.start(e,this.specification.startTime||0,this.specification.stopTime-this.specification.startTime||this.buffer.buffer.duration))},this.bufferStop=function(e){this.outputGain.gain.cancelScheduledValues(audioContext.currentTime),void 0!==this.bufferNode&&this.bufferNode.state>0&&(this.bufferNode.stop(e),this.bufferNode=void 0),this.outputGain.gain.linearRampToValueAtTime(0,e),this.interfaceDOM.stopPlayback()},this.getCurrentPosition=function(){var e=audioEngineContext.timer.getTestTime();if(void 0!==this.bufferNode){var t=(e-this.bufferNode.playbackStartTime)%this.buffer.buffer.duration;return isNaN(t)?0:t}return 0},this.exportXMLDOM=function(){var e=storage.document.createElement("file");if(e.setAttribute("sampleRate",this.buffer.buffer.sampleRate),e.setAttribute("channels",this.buffer.buffer.numberOfChannels),e.setAttribute("sampleCount",this.buffer.buffer.length),e.setAttribute("duration",this.buffer.buffer.duration),this.storeDOM.appendChild(e),"outside-reference"!=this.specification.type){var t=this.interfaceDOM.exportXMLDOM(this);if(null!==t)if(void 0===t.length)this.storeDOM.appendChild(t);else for(var i=0;i<t.length;i++)this.storeDOM.appendChild(t[i]);null!==this.commentDOM&&this.storeDOM.appendChild(this.commentDOM.exportXMLDOM(this))}this.metric.exportXMLDOM(this.storeDOM.getElementsByTagName("metric")[0])},Object.defineProperties(this,{numberOfPlays:{get:function(){return t},set:function(){return t}}})}function timer(){this.testStarted=!1,this.testStartTime=0,this.testDuration=0,this.minimumTestTime=0,this.startTest=function(){!1===this.testStarted&&(this.testStartTime=audioContext.currentTime,this.testStarted=!0,this.updateTestTime(),audioEngineContext.metric.initialiseTest())},this.stopTest=function(){this.testStarted?(this.testDuration=this.getTestTime(),this.testStarted=!1):console.log("ERR: Test tried to end before beginning")},this.updateTestTime=function(){this.testStarted&&(this.testDuration=audioContext.currentTime-this.testStartTime)},this.getTestTime=function(){return this.updateTestTime(),this.testDuration}}function sessionMetrics(e,t){this.engine=e,this.lastClicked=-1,this.data=-1,this.reset=function(){this.lastClicked=-1,this.data=-1},this.enableElementInitialPosition=!1,this.enableElementListenTracker=!1,this.enableElementTimer=!1,this.enableElementTracker=!1,this.enableFlagListenedTo=!1,this.enableFlagMoved=!1,this.enableTestTimer=!1;for(var i=0;i<t.metrics.enabled.length;i++){switch(t.metrics.enabled[i]){case"testTimer":this.enableTestTimer=!0;break;case"elementTimer":this.enableElementTimer=!0;break;case"elementTracker":this.enableElementTracker=!0;break;case"elementListenTracker":this.enableElementListenTracker=!0;break;case"elementInitialPosition":this.enableElementInitialPosition=!0;break;case"elementFlagListenedTo":this.enableFlagListenedTo=!0;break;case"elementFlagMoved":this.enableFlagMoved=!0;break;case"elementFlagComments":this.enableFlagComments=!0}}this.initialiseTest=function(){}}function metricTracker(e){this.listenedTimer=0,this.listenStart=0,this.listenHold=!1,this.initialPosition=-1,this.movementTracker=[],this.listenTracker=[],this.wasListenedTo=!1,this.wasMoved=!1,this.hasComments=!1,this.parent=e,this.initialise=function(e){-1==this.initialPosition&&(this.initialPosition=e,this.moved(0,e))},this.moved=function(e,t){e>0&&(this.wasMoved=!0),t!=(this.movementTracker.length>0?this.movementTracker[this.movementTracker.length-1]:-1)[1]&&(this.movementTracker[this.movementTracker.length]=[e,t])},this.startListening=function(e){if(!1===this.listenHold){this.wasListenedTo=!0,this.listenStart=e,this.listenHold=!0;var t=document.createElement("event"),i=document.createElement("testTime");i.setAttribute("start",e);var n=document.createElement("bufferTime");n.setAttribute("start",this.parent.getCurrentPosition()),t.appendChild(i),t.appendChild(n),this.listenTracker.push(t),console.log("slider "+this.parent.id+" played ("+e+")")}},this.stopListening=function(e,t){if(!0===this.listenHold){var i=e-this.listenStart;this.listenedTimer+=i,this.listenStart=0,this.listenHold=!1;var n=this.listenTracker[this.listenTracker.length-1],o=n.getElementsByTagName("testTime")[0],s=n.getElementsByTagName("bufferTime")[0];o.setAttribute("stop",e),void 0===t?s.setAttribute("stop",this.parent.getCurrentPosition()):s.setAttribute("stop",t),console.log("slider "+this.parent.id+" played for ("+i+")")}},this.exportXMLDOM=function(e){var t=[];return audioEngineContext.metric.enableElementTimer&&t.push(function(e){var t=storage.document.createElement("metricresult");return t.setAttribute("name","enableElementTimer"),t.textContent=this.listenedTimer,e.appendChild(t),t}.call(this,e)),audioEngineContext.metric.enableElementTracker&&t.push(function(e){var t=storage.document.createElement("metricresult");t.setAttribute("name","elementTrackerFull");for(var i=0;i<this.movementTracker.length;i++){var n=storage.document.createElement("movement");n.setAttribute("time",this.movementTracker[i][0]),n.setAttribute("value",this.movementTracker[i][1]),t.appendChild(n)}return e.appendChild(t),t}.call(this,e)),audioEngineContext.metric.enableElementListenTracker&&t.push(function(e){var t=storage.document.createElement("metricresult");t.setAttribute("name","elementListenTracker");for(var i=0;i<this.listenTracker.length;i++)t.appendChild(this.listenTracker[i]);return e.appendChild(t),t}.call(this,e)),audioEngineContext.metric.enableElementInitialPosition&&t.push(function(e){var t=storage.document.createElement("metricresult");return t.setAttribute("name","elementInitialPosition"),t.textContent=this.initialPosition,e.appendChild(t),t}.call(this,e)),audioEngineContext.metric.enableFlagListenedTo&&t.push(function(e){var t=storage.document.createElement("metricresult");return t.setAttribute("name","elementFlagListenedTo"),t.textContent=this.wasListenedTo,e.appendChild(t),t}.call(this,e)),audioEngineContext.metric.enableFlagMoved&&t.push(function(e){var t=storage.document.createElement("metricresult");return t.setAttribute("name","elementFlagMoved"),t.textContent=this.wasMoved,e.appendChild(t),t}.call(this,e)),audioEngineContext.metric.enableFlagComments&&t.push(function(e){var t=storage.document.createElement("metricresult");return t.setAttribute("name","elementFlagComments"),null===this.parent.commentDOM?t.textContent="false":0===this.parent.commentDOM.textContent.length?t.textContent="false":t.textContet="true",e.appendChild(t),t}.call(this,e)),t}}function Interface(e){this.specification=e,this.insertPoint=document.getElementById("topLevelBody"),this.newPage=function(e,t){audioEngineContext.newTestPage(e,t),interfaceContext.commentBoxes.deleteCommentBoxes(),interfaceContext.deleteCommentQuestions(),loadTest(e,t)},this.keyboardInterface=function(){var e={keys:[],registerKeyBinding:function(e,t){if("string"!=typeof e||1!=e.length)throw"Key must be a singular character";if(this.keys.findIndex(function(t){return t.key==e})>=0)throw"Key "+e+" already bounded!";return this.keys.push({key:e,audioObject:t}),!0},deregisterKeyBinding:function(e){var t=this.keys.findIndex(function(t){return t.key==e});if(-1==t)throw"Key "+e+" not bounded!";return this.keys.splice(t,1),!0},resetKeyBindings:function(){this.keys=[]},handleEvent:function(e){" "===e.key?audioEngineContext.audioObjects.some(function(e){return e.playing})&&document.activeElement.className.indexOf("trackComment")>=0==!1&&(e.preventDefault(),audioEngineContext.stop()):function(e){var t=this.keys.findIndex(function(t){return t.key==e});t>=0&&audioEngineContext.play(this.keys[t].audioObject.id)}.call(this,e.key),console.log(e)}};return document.addEventListener("keydown",e,!1),e}(),this.interfaceObjects=[],this.interfaceObject=function(){},this.resizeWindow=function(e){popup.resize(e),this.volume.resize(),this.lightbox.resize(),this.commentBoxes.boxes.forEach(function(e){e.resize()}),this.commentQuestions.forEach(function(e){e.resize()});try{resizeWindow(e)}catch(e){console.log("Warning - Interface does not have Resize option"),console.log(e)}},this.returnNavigator=function(){var e=storage.document.createElement("navigator"),t=storage.document.createElement("platform");t.textContent=navigator.platform;var i=storage.document.createElement("vendor");i.textContent=navigator.vendor;var n=storage.document.createElement("uagent");n.textContent=navigator.userAgent;var o=storage.document.createElement("window");return o.setAttribute("innerWidth",window.innerWidth),o.setAttribute("innerHeight",window.innerHeight),e.appendChild(t),e.appendChild(i),e.appendChild(n),e.appendChild(o),e},this.returnDateNode=function(){var e=new Date,t=storage.document.createElement("datetime"),i=storage.document.createElement("date"),n=storage.document.createElement("time");return i.setAttribute("year",e.getFullYear()),i.setAttribute("month",e.getMonth()+1),i.setAttribute("day",e.getDate()),n.setAttribute("hour",e.getHours()),n.setAttribute("minute",e.getMinutes()),n.setAttribute("secs",e.getSeconds()),t.appendChild(i),t.appendChild(n),t},this.lightbox={parent:this,root:document.createElement("div"),content:document.createElement("div"),accept:document.createElement("button"),blanker:document.createElement("div"),post:function(e,t){switch(e){case"Error":this.content.className="lightbox-error";break;case"Warning":this.content.className="lightbox-warning";break;default:this.content.className="lightbox-message"}var i=document.createElement("p");i.textContent=t,this.content.appendChild(i),this.show()},show:function(){this.root.style.visibility="visible",this.blanker.style.visibility="visible",this.accept.focus()},clear:function(){this.root.style.visibility="",this.blanker.style.visibility="",this.content.textContent=""},handleEvent:function(e){e.currentTarget==this.accept&&this.clear()},resize:function(e){this.root.style.left=window.innerWidth/2-250+"px"},isVisible:function(){return"visible"==this.root.style.visibility}},this.lightbox.root.appendChild(this.lightbox.content),this.lightbox.root.appendChild(this.lightbox.accept),this.lightbox.root.className="popupHolder",this.lightbox.root.id="lightbox-root",this.lightbox.accept.className="popupButton",this.lightbox.accept.style.bottom="10px",this.lightbox.accept.textContent="OK",this.lightbox.accept.style.left="237.5px",this.lightbox.accept.addEventListener("click",this.lightbox),this.lightbox.blanker.className="testHalt",this.lightbox.blanker.id="lightbox-blanker",document.getElementsByTagName("body")[0].appendChild(this.lightbox.root),document.getElementsByTagName("body")[0].appendChild(this.lightbox.blanker),this.commentBoxes=function(){var e={};return e.boxes=[],e.injectPoint=null,e.elementCommentBox=function(e){e.specification;this.audioObject=e,this.id=e.id;var t=e.specification.parent;this.trackComment=document.createElement("div"),this.trackComment.className="comment-div",this.trackComment.id="comment-div-"+e.id,this.trackString=document.createElement("span"),this.trackString.innerHTML=t.commentBoxPrefix+" "+e.interfaceDOM.getPresentedId(),this.trackCommentBox=document.createElement("textarea"),this.trackCommentBox.rows="4",this.trackCommentBox.cols="100",this.trackCommentBox.name="trackComment"+e.id,this.trackCommentBox.className="trackComment";var i=document.createElement("br");this.trackComment.appendChild(this.trackString),this.trackComment.appendChild(i),this.trackComment.appendChild(this.trackCommentBox),this.exportXMLDOM=function(){var e=document.createElement("comment"),t=document.createElement("question");t.textContent=this.trackString.textContent;var i=document.createElement("response");return i.textContent=this.trackCommentBox.value,console.log("Comment frag-"+this.id+": "+i.textContent),e.appendChild(t),e.appendChild(i),e},this.resize=function(){var e=(window.innerWidth-100)/2;e>=600?e=600:e<400&&(e=400),this.trackComment.style.width=e+"px",this.trackCommentBox.style.width=e-6+"px"},this.resize(),this.highlight=function(e){!0===e?$(this.trackComment).addClass("comment-box-playing"):$(this.trackComment).removeClass("comment-box-playing")}},e.createCommentBox=function(e){var t=new this.elementCommentBox(e);return this.boxes.push(t),e.commentDOM=t,t},e.sortCommentBoxes=function(){this.boxes.sort(function(e,t){return e.id-t.id})},e.showCommentBoxes=function(e,t){this.injectPoint=e,t&&this.sortCommentBoxes(),this.boxes.forEach(function(t){e.appendChild(t.trackComment)})},e.deleteCommentBoxes=function(){null!==this.injectPoint&&(this.boxes.forEach(function(e){this.injectPoint.removeChild(e.trackComment)},this),this.injectPoint=null),this.boxes=[]},e.highlightById=function(e){(void 0===e||"number"!=typeof e||e>=this.boxes.length)&&(console.log("Error - Invalid id"),e=-1),this.boxes.forEach(function(t){t.id===e?t.highlight(!0):t.highlight(!1)})},e}(),this.commentQuestions=[],this.commentBox=function(e){this.specification=e,this.holder=document.createElement("div"),this.holder.className="comment-div",this.string=document.createElement("span"),this.string.innerHTML=e.statement,this.textArea=document.createElement("textarea"),this.textArea.rows="4",this.textArea.cols="100",this.textArea.className="trackComment";var t=document.createElement("br");this.holder.appendChild(this.string),this.holder.appendChild(t),this.holder.appendChild(this.textArea),this.exportXMLDOM=function(e){var t=e.parent.document.createElement("comment");t.id=this.specification.id,t.setAttribute("type",this.specification.type),console.log("Question: "+this.string.textContent),console.log("Response: "+t.textContent);var i=e.parent.document.createElement("question");i.textContent=this.string.textContent;var n=e.parent.document.createElement("response");return n.textContent=this.textArea.value,t.appendChild(i),t.appendChild(n),e.XMLDOM.appendChild(t),t},this.resize=function(){var e=(window.innerWidth-100)/2;e>=600?e=600:e<400&&(e=400),this.holder.style.width=e+"px",this.textArea.style.width=e-6+"px"},this.resize(),this.check=function(){return!this.specification.mandatory||0!==this.textArea.value.length}},this.radioBox=function(e){this.specification=e,this.holder=document.createElement("div"),this.holder.className="comment-div",this.string=document.createElement("span"),this.string.innerHTML=e.statement,this.holder.appendChild(this.string),this.options=[],this.inputs=document.createElement("div"),this.inputs.className="comment-checkbox-inputs-holder";for(var t=e.options.length,i=0;i<t;i++){var n=document.createElement("div");n.className="comment-checkbox-inputs-flex";var o=document.createElement("span");o.textContent=e.options[i].text,o.className="comment-radio-span",n.appendChild(o);var s=document.createElement("input");s.type="radio",s.name=e.id,s.setAttribute("setvalue",e.options[i].name),s.className="comment-radio",n.appendChild(s),this.inputs.appendChild(n),this.options.push(s)}this.holder.appendChild(this.inputs),this.exportXMLDOM=function(e){var t=e.parent.document.createElement("comment");t.id=this.specification.id,t.setAttribute("type",this.specification.type);var i=document.createElement("question");i.textContent=this.string.textContent;for(var n=document.createElement("response"),o=0;!1===this.options[o].checked&&!(++o>=this.options.length););return o>=this.options.length?n.textContent="null":(n.textContent=this.options[o].getAttribute("setvalue"),n.setAttribute("number",o)),console.log("Comment: "+i.textContent),console.log("Response: "+n.textContent),t.appendChild(i),t.appendChild(n),e.XMLDOM.appendChild(t),t},this.resize=function(){var e=(window.innerWidth-100)/2;e>=600?e=600:e<400&&(e=400),this.holder.style.width=e+"px"},this.check=function(){var e=this.options.some(function(e){return e.checked});return!this.specification.mandatory||!1!==e},this.resize()},this.checkboxBox=function(e){this.specification=e,this.holder=document.createElement("div"),this.holder.className="comment-div",this.string=document.createElement("span"),this.string.innerHTML=e.statement,this.holder.appendChild(this.string),this.options=[],this.inputs=document.createElement("div"),this.inputs.className="comment-checkbox-inputs-holder";for(var t=e.options.length,i=0;i<t;i++){var n=document.createElement("div");n.className="comment-checkbox-inputs-flex";var o=document.createElement("span");o.textContent=e.options[i].text,o.className="comment-radio-span",n.appendChild(o);var s=document.createElement("input");s.type="checkbox",s.name=e.id,s.setAttribute("setvalue",e.options[i].name),s.className="comment-radio",n.appendChild(s),this.inputs.appendChild(n),this.options.push(s)}this.holder.appendChild(this.inputs),this.exportXMLDOM=function(e){var t=e.parent.document.createElement("comment");t.id=this.specification.id,t.setAttribute("type",this.specification.type);var i=document.createElement("question");i.textContent=this.string.textContent,t.appendChild(i),console.log("Comment: "+i.textContent);for(var n=0;n<this.options.length;n++){var o=document.createElement("response");o.textContent=this.options[n].checked,o.setAttribute("name",this.options[n].getAttribute("setvalue")),t.appendChild(o),console.log("Response "+o.getAttribute("name")+": "+o.textContent)}return e.XMLDOM.appendChild(t),t},this.resize=function(){var e=(window.innerWidth-100)/2;e>=600?e=600:e<400&&(e=400),this.holder.style.width=e+"px"},this.check=function(){var e=this.options.some(function(e){return e.checked});return!this.specification.mandatory||!1!==e},this.resize()},this.sliderBox=function(e){this.specification=e,this.holder=document.createElement("div"),this.holder.className="comment-div",this.string=document.createElement("span"),this.string.innerHTML=e.statement,this.slider=document.createElement("input"),this.slider.type="range",this.slider.min=e.min,this.slider.max=e.max,this.slider.step=e.step,this.slider.value=e.value;var t=document.createElement("br"),i=document.createElement("div");i.className="comment-slider-text-holder",this.leftText=document.createElement("span"),this.leftText.textContent=e.leftText,this.rightText=document.createElement("span"),this.rightText.textContent=e.rightText,i.appendChild(this.leftText),i.appendChild(this.rightText),this.holder.appendChild(this.string),this.holder.appendChild(t),this.holder.appendChild(this.slider),this.holder.appendChild(i),this.exportXMLDOM=function(e){var t=e.parent.document.createElement("comment");t.id=this.specification.id,t.setAttribute("type",this.specification.type),console.log("Question: "+this.string.textContent),console.log("Response: "+this.slider.value);var i=e.parent.document.createElement("question");i.textContent=this.string.textContent;var n=e.parent.document.createElement("response");return n.textContent=this.slider.value,t.appendChild(i),t.appendChild(n),e.XMLDOM.appendChild(t),t},this.resize=function(){var e=(window.innerWidth-100)/2;e>=600?e=600:e<400&&(e=400),this.holder.style.width=e+"px",this.slider.style.width=e-24+"px"},this.check=function(){return!0},this.resize()},this.createCommentQuestion=function(e){var t;return"question"==e.type?t=new this.commentBox(e):"radio"==e.type?t=new this.radioBox(e):"checkbox"==e.type?t=new this.checkboxBox(e):"slider"==e.type&&(t=new this.sliderBox(e)),this.commentQuestions.push(t),t},this.deleteCommentQuestions=function(){this.commentQuestions=[]},this.checkCommentQuestions=function(){if(0===this.commentQuestions.reduce(function(e,t){return!1===t.check()&&e.push(t),e},[]).length)return!0;interfaceContext.lightbox.post("Message","Not all the mandatory comment boxes below have been filled.")},this.outsideReferenceDOM=function(e,t,i){this.parent=e,this.outsideReferenceHolder=document.createElement("button"),this.outsideReferenceHolder.className="outside-reference",this.outsideReferenceHolder.setAttribute("track-id",t),this.outsideReferenceHolder.textContent=this.parent.specification.label||"Reference",this.outsideReferenceHolder.disabled=!0,this.handleEvent=function(e){audioEngineContext.play(this.parent.id)},this.outsideReferenceHolder.addEventListener("click",this),i.appendChild(this.outsideReferenceHolder),this.enable=function(){1==this.parent.state&&(this.outsideReferenceHolder.disabled=!1)},this.updateLoading=function(e){100!=e?(e=(e=String(e)).split(".")[0],this.outsideReferenceHolder.textContent=e+"%"):this.outsideReferenceHolder.textContent=this.parent.specification.label||"Reference"},this.startPlayback=function(){$(".track-slider").removeClass("track-slider-playing"),$(".comment-div").removeClass("comment-box-playing"),this.outsideReferenceHolder.style.backgroundColor="#FDD"},this.stopPlayback=function(){this.outsideReferenceHolder.style.backgroundColor=""},this.exportXMLDOM=function(e){return null},this.getValue=function(){return 0},this.getPresentedId=function(){return this.parent.specification.label||"Reference"},this.canMove=function(){return!1},this.error=function(){this.outsideReferenceHolder.textContent="Error",this.outsideReferenceHolder.style.backgroundColor="#F00"}},this.playhead=function(){var e={};e.object=document.createElement("div"),e.object.className="playhead",e.object.align="left";var t=document.createElement("div");return t.style.width="50px",e.curTimeSpan=document.createElement("span"),e.curTimeSpan.textContent="00:00",t.appendChild(e.curTimeSpan),e.object.appendChild(t),e.scrubberTrack=document.createElement("div"),e.scrubberTrack.className="playhead-scrub-track",e.scrubberHead=document.createElement("div"),e.scrubberHead.id="playhead-scrubber",e.scrubberTrack.appendChild(e.scrubberHead),e.object.appendChild(e.scrubberTrack),e.timePerPixel=0,e.maxTime=0,e.playbackObject=void 0,e.setTimePerPixel=function(e){this.playbackObject=e,this.maxTime=e.buffer.buffer.duration;this.timePerPixel=this.maxTime/490,this.maxTime<60?this.curTimeSpan.textContent="0.00":this.curTimeSpan.textContent="00:00"},e.update=function(){if(this.timePerPixel>0){var e=this.playbackObject.getCurrentPosition();if(e>0&&e<this.maxTime){var t=Math.floor(e/this.timePerPixel);if(this.scrubberHead.style.left=t+"px",this.maxTime>60){var i=e%60,n=Math.floor((e-i)/60);i=(i=i.toString()).substr(0,2),n=n.toString(),this.curTimeSpan.textContent=n+":"+i}else e=e.toString(),this.curTimeSpan.textContent=e.substr(0,4)}else this.scrubberHead.style.left="0px",this.maxTime<60?this.curTimeSpan.textContent="0.00":this.curTimeSpan.textContent="00:00"}void 0!==this.playbackObject&&void 0===this.interval&&window.requestAnimationFrame(this.update.bind(this))},e.interval=void 0,e.start=function(){void 0!==this.playbackObject&&void 0===this.interval&&window.requestAnimationFrame(this.update.bind(this))},e.stop=function(){this.timePerPixel=0},e}(),this.volume=function(){var e={};e.valueLin=1,e.valueDB=0,e.root=document.createElement("div"),e.root.id="master-volume-root",e.object=document.createElement("div"),e.object.className="master-volume-holder-float",e.object.appendChild(e.root),e.slider=document.createElement("input"),e.slider.id="master-volume-control",e.slider.type="range",e.valueText=document.createElement("span"),e.valueText.id="master-volume-feedback",e.valueText.textContent="0dB",e.slider.min=-60,e.slider.max=12,e.slider.value=0,e.slider.step=1,e.handleEvent=function(e){"mousemove"!=e.type&&"mouseup"!=e.type||(this.valueDB=Number(this.slider.value),this.valueLin=decibelToLinear(this.valueDB),this.valueText.textContent=this.valueDB+"dB",audioEngineContext.outputGain.gain.value=this.valueLin),"mouseup"==e.type&&this.onmouseup(),this.slider.value=this.valueDB,e.stopPropagation&&e.stopPropagation()},e.onmouseup=function(){var e=testState.currentStore.XMLDOM.getElementsByTagName("metric")[0].getAllElementsByName("volumeTracker");0===e.length?((e=storage.document.createElement("metricresult")).setAttribute("name","volumeTracker"),testState.currentStore.XMLDOM.getElementsByTagName("metric")[0].appendChild(e)):e=e[0];var t=storage.document.createElement("movement");t.setAttribute("test-time",audioEngineContext.timer.getTestTime()),t.setAttribute("volume",this.valueDB),t.setAttribute("format","dBFS"),e.appendChild(t)},e.slider.addEventListener("mousemove",e),e.root.addEventListener("mouseup",e);var t=document.createElement("div");return t.innerHTML="<span>Master Volume Control</span>",t.style.fontSize="0.75em",t.style.width="100%",t.align="center",e.root.appendChild(t),e.root.appendChild(e.slider),e.root.appendChild(e.valueText),e.resize=function(e){window.innerWidth<1e3?this.object.className="master-volume-holder-inline":this.object.className="master-volume-holder-float"},e}(),this.imageHolder=function(){var e={};return e.root=document.createElement("div"),e.root.id="imageController",e.img=document.createElement("img"),e.root.appendChild(e.img),e.setImage=function(t){e.img.src="","string"==typeof t&&void 0!==t.length&&(e.img.src=t)},e}(),this.calibrationModuleObject=null,this.calibrationModule=function(){this.storeDOM=storage.document.createElement("calibration"),storage.root.appendChild(this.storeDOM),this.calibrationNodes=[],this.holder=null,this.build=function(e){var t=62.5;for(this.holder=document.createElement("div"),this.holder.className="calibration-holder",this.calibrationNodes=[];t<2e4;){var i={root:document.createElement("div"),input:document.createElement("input"),oscillator:audioContext.createOscillator(),gain:audioContext.createGain(),f:t,parent:this,handleEvent:function(e){switch(e.type){case"mouseenter":this.oscillator.start(0);break;case"mouseleave":this.oscillator.stop(0),this.oscillator=audioContext.createOscillator(),this.oscillator.connect(this.gain),this.oscillator.frequency.value=this.f;break;case"mousemove":var t=Math.pow(10,this.input.value/20);1e3==this.f?(audioEngineContext.outputGain.gain.value=t,interfaceContext.volume.slider.value=this.input.value):this.gain.gain.value=t}},disconnect:function(){this.gain.disconnect()}};i.root.className="calibration-slider",i.root.appendChild(i.input),i.oscillator.connect(i.gain),i.gain.connect(audioEngineContext.outputGain),i.gain.gain.value=2*Math.random(),i.input.value=i.gain.gain.value,i.input.setAttribute("orient","vertical"),i.input.type="range",i.input.min=-12,i.input.max=0,i.input.step=.25,1e3!=t?i.input.value=12*Math.random()-6:(i.input.value=0,i.root.style.backgroundColor="rgb(255,125,125)"),i.input.addEventListener("mousemove",i),i.input.addEventListener("mouseenter",i),i.input.addEventListener("mouseleave",i),i.gain.gain.value=Math.pow(10,i.input.value/20),i.oscillator.frequency.value=t,this.calibrationNodes.push(i),this.holder.appendChild(i.root),t*=2}e.appendChild(this.holder)},this.collect=function(){this.calibrationNodes.forEach(function(e){var t=storage.document.createElement("calibrationresult");t.setAttribute("frequency",e.f),t.setAttribute("range-min",e.input.min),t.setAttribute("range-max",e.input.max),t.setAttribute("gain-lin",e.gain.gain.value),this.storeDOM.appendChild(t)},this)}},this.checkHiddenAnchor=function(e){return!audioEngineContext.audioObjects.filter(function(e){return"anchor"===e.specification.type}).some(function(e){return e.interfaceDOM.getValue()>e.specification.marker/100&&e.specification.marker>0})||(console.log("Anchor node not below marker value"),e?interfaceContext.lightbox.post("Message",e):interfaceContext.lightbox.post("Message","Please keep listening"),this.storeErrorNode("Anchor node not below marker value"),!1)},this.checkHiddenReference=function(e){return!audioEngineContext.audioObjects.filter(function(e){return"reference"===e.specification.type}).some(function(e){return e.interfaceDOM.getValue()<e.specification.marker/100&&e.specification.marker>0})||(console.log("Reference node not below marker value"),e?interfaceContext.lightbox.post("Message",e):interfaceContext.lightbox.post("Message","Please keep listening"),this.storeErrorNode("Reference node not below marker value"),!1)},this.checkFragmentsFullyPlayed=function(e){if(audioEngineContext.loopPlayback)return console.log("WARNING - Looped source: Cannot check fragments are fully played"),!0;var t,i=!0,n=[];for(t=0;t<audioEngineContext.audioObjects.length;t++){for(var o=audioEngineContext.audioObjects[t],s=o.buffer.buffer.duration,r=o.metric,a=!1,c=0;c<r.listenTracker.length;c++){var l=r.listenTracker[c].getElementsByTagName("testtime"),u=Number(l[0].getAttribute("start"));if(Number(l[0].getAttribute("stop"))-u>=s){a=!0;break}}!1===a&&(i=!1,console.log("Continue listening to track-"+o.interfaceDOM.getPresentedId()),n.push(o.interfaceDOM.getPresentedId()))}if(!1===i){var h="You have not completely listened to fragments ";for(t=0;t<n.length;t++)h+=n[t],t!=n.length-1&&(h+=", ");return h+=". Please keep listening",console.log(h),this.storeErrorNode(h),e&&(h=e),interfaceContext.lightbox.post("Error",h),!1}return!0},this.checkAllMoved=function(e){var t="You have not moved ",i=[];if(audioEngineContext.audioObjects.forEach(function(e){!1===e.metric.wasMoved&&!0===e.interfaceDOM.canMove()&&i.push(e.interfaceDOM.getPresentedId())},this),0===i.length)return!0;if(1==i.length)t+="track "+i[0];else{t+="tracks ";for(var n=0;n<i.length-1;n++)t+=i[n]+", ";t+="and "+i[n]}return t+=".",console.log(t),this.storeErrorNode(t),e&&(t=e),interfaceContext.lightbox.post("Error",t),!1},this.checkAllPlayed=function(e){var t="You have not played ",i=[];if(audioEngineContext.audioObjects.forEach(function(e){!1===e.metric.wasListenedTo&&i.push(e.interfaceDOM.getPresentedId())},this),0===i.length)return!0;if(1==i.length)t+="track "+i[0];else{t+="tracks ";for(var n=0;n<i.length-1;n++)t+=i[n]+", ";t+="and "+i[n]}return t+=".",console.log(t),this.storeErrorNode(t),e&&(t=e),interfaceContext.lightbox.post("Error",t),!1},this.checkAllCommented=function(e){var t,i="You have not commented on all the fragments.",n=this.commentBoxes.boxes,o=n.length;for(t=0;t<o;t++)if(""===n[t].trackCommentBox.value)return console.log(i),this.storeErrorNode(i),e&&(i=e),interfaceContext.lightbox.post("Error",i),!1;return!0},this.checkScaleRange=function(e){var t=testState.getCurrentTestPage().interfaces,i=!0,n="Please keep listening. ";if(void 0===t)return!0;t=t[0];var o=function(){var e=t.options.find(function(e){return"scalerange"==e.name});return{min:e.min,max:e.max}}(),s=audioEngineContext.audioObjects.reduce(function(e,t){var i=100*t.interfaceDOM.getValue();return{min:Math.min(e.min,i),max:Math.max(e.max,i)}},{min:100,max:0});return s.min>o.min?(n+="At least one fragment must be below the "+o.min+" mark.",i=!1):s.max<o.max&&(n+="At least one fragment must be above the "+o.max+" mark.",i=!1),!1===i&&(console.log(n),this.storeErrorNode(n),e&&(n=e),interfaceContext.lightbox.post("Error",n)),i},this.checkFragmentMinPlays=function(){var e=audioEngineContext.audioObjects.filter(function(e){var t=e.specification.minNumberPlays||e.specification.parent.minNumberPlays||specification.minNumberPlays;return!(void 0===t||e.numberOfPlays>=t)});if(0===e.length)return!0;var t=[];e.forEach(function(e){t.push(e.interfaceDOM.getPresentedId())});var i="You have not played fragments "+t.join(", ")+" enough. Please keep listening";return interfaceContext.lightbox.post("Message",i),this.storeErrorNode(i),!1},this.sortFragmentsByScore=function(){for(var e=audioEngineContext.audioObjects.filter(function(e){return"outside-reference"!==e.specification.type}),t=[],i=0;t.push(i++)<e.length;);return t.sort(function(t,i){var n=e[t].interfaceDOM.getValue(),o=e[i].interfaceDOM.getValue();return n>o?1:n<o?-1:0},e[0].interfaceDOM.getValue())},this.storeErrorNode=function(e){var t=audioEngineContext.timer.getTestTime(),i=storage.document.createElement("error");i.setAttribute("time",t),i.textContent=e,testState.currentStore.XMLDOM.appendChild(i)},this.getLabel=function(e,t,i){function n(e,t,i){if("none"==e)return"";switch(e){case"letter":return String.fromCharCode((t+i)%26+97);case"capital":return String.fromCharCode((t+i)%26+65);case"samediff":return 0===t?"Same":1==t?"Difference":"";case"number":return String(t+i);default:return""}}switch("string"==typeof i&&0!==i.length||(i=String.fromCharCode(0)),e){case"letter":((i=i.charCodeAt(0))<97||i>122)&&(i=97),i-=97;break;case"capital":((i=i.charCodeAt(0))<65||i>90)&&(i=65),i-=65;break;case"number":i=Number(i),isFinite(i)||(i=1);break;default:i=0}if("number"==typeof t)return n(e,t,i);if(t.length&&t.length>0){var o,s=[],r=t.length;for(o=0;o<r;o++)s[o]=n(e,t[o],i);return s}throw"Invalid arguments"},this.getCombinedInterfaces=function(e){var t=specification.interfaces,i=e.interfaces;return i.forEach(function(e){var i=[];t.options.forEach(function(t){e.options.find(function(e){return e.name==t.name&&e.type==t.type})||i.push(t)}),e.options=e.options.concat(i),!e.scales&&t.scales&&(e.scales=t.scales)}),i}}function Storage(){this.globalPreTest=null,this.globalPostTest=null,this.testPages=[],this.document=null,this.root=null,this.state=0;var e="save";this.initialise=function(e){if(void 0===e){this.SessionKey.requestKey(),this.document=document.implementation.createDocument(null,"waetresult",null),this.root=this.document.childNodes[0];var t=specification.projectXML;t.setAttribute("file-name",specification.url),t.setAttribute("url",qualifyURL(specification.url)),this.root.appendChild(t),this.root.appendChild(interfaceContext.returnDateNode()),this.root.appendChild(interfaceContext.returnNavigator())}else this.document=e,this.root=e.firstChild,this.SessionKey.key=this.root.getAttribute("key");void 0!==specification.preTest&&(this.globalPreTest=new this.surveyNode(this,this.root,specification.preTest)),void 0!==specification.postTest&&(this.globalPostTest=new this.surveyNode(this,this.root,specification.postTest))},this.SessionKey=function(e){function t(){var t=document.createElement("div"),n=e.root.cloneNode(!0);return t.appendChild(n),new Promise(function(n,s){console.log("Requested save...");var r=new XMLHttpRequest;r.open("POST",i+"php/save.php?key="+o+"&saveFilenamePrefix="+e.filenamePrefix),r.setRequestHeader("Content-Type","text/xml"),r.onload=function(){if(this.status>=300)console.log("WARNING - Could not update at this time");else{var e=(new DOMParser).parseFromString(r.responseText,"application/xml").getElementsByTagName("response")[0];if("OK"==e.getAttribute("state")){var t=e.getElementsByTagName("file")[0];console.log("Intermediate save: OK, written "+t.getAttribute("bytes")+"B"),n(!0)}else{var i=e.getElementsByTagName("message");console.log("Intermediate save: Error! "+i.textContent),s("Intermediate save: Error! "+i.textContent)}}},r.onerror=function(){s(Error("Network Error"))},r.send([t.innerHTML])})}var i="";void 0!==window.returnURL&&(i=String(window.returnURL));var n=null,o=null,s={};return Object.defineProperties(s,{key:{get:function(){return o},set:function(e){throw"Cannot set read-only property"}},request:{value:new XMLHttpRequest},parent:{value:e},requestKey:{value:function(){n=new Promise(function(t,n){var o=new XMLHttpRequest;o.open("GET",i+"php/requestKey.php?saveFilenamePrefix="+e.filenamePrefix,!0),o.onload=function(){200==o.status?t(o.response):n(Error(o.statusText))},o.onerror=function(){n(Error("Network Error"))},o.send()}).then(function(t){function i(){throw o=null,"An unspecified error occured, no server key could be generated"}var n=(new DOMParser).parseFromString(t,"text/xml");if(0===t.length&&i(),n.getElementsByTagName("state").length>0){if("OK"==n.getElementsByTagName("state")[0].textContent)return o=n.getAllElementsByTagName("key")[0].textContent,e.root.setAttribute("key",o),e.root.setAttribute("state","empty"),!0;if("ERROR"==n.getElementsByTagName("state")[0].textContent)return o=null,console.error('Could not generate server key. Server responded with error message: "'+n.getElementsByTagName("message")[0].textContent+'"'),!1}else i();return!0})}},update:{value:function(){if(null===this.key||void 0===n)throw"Cannot save as key == null";this.parent.root.setAttribute("state","update"),n=n.then(t)}},finish:{value:function(){if(null===this.key||void 0===n)throw"Cannot save as key == null";return this.parent.finish(),n.then(t()).then(function(){console.log("OK")},function(){createProjectSave("local")})}}}),s}(this),this.createTestPageStore=function(e){var t=new this.pageNode(this,e);return this.testPages.push(t),this.testPages[this.testPages.length-1]},this.surveyNode=function(e,t,i){this.specification=i,this.parent=e,this.state="empty",this.XMLDOM=this.parent.document.createElement("survey"),this.XMLDOM.setAttribute("location",this.specification.location),this.XMLDOM.setAttribute("state",this.state),this.specification.options.forEach(function(e){if("statement"!=e.type){var t=this.parent.document.createElement("surveyresult");t.setAttribute("ref",e.id),t.setAttribute("type",e.type),this.XMLDOM.appendChild(t)}},this),t.appendChild(this.XMLDOM),this.postResult=function(e){function t(e,t){var i=e.createElement("response");return i.setAttribute("name",t.name),i.setAttribute("checked",t.checked),i}if("statement"!=e.specification.type){for(var i=this.XMLDOM.firstChild;null!==i&&i.getAttribute("ref")!=e.specification.id;)i=i.nextElementSibling;switch(i.setAttribute("duration",e.elapsedTime),e.specification.type){case"number":case"question":case"slider":i.appendChild(function(e,t){var i=e.createElement("response");return i.textContent=t,i}(this.parent.document,e.response));break;case"radio":i.appendChild(function(e,t){var i=e.createElement("response");return null!==t.response&&(i.setAttribute("name",t.response.name),i.textContent=t.response.text),i}(this.parent.document,e));break;case"checkbox":if(void 0===e.response){i.appendChild(this.parent.document.createElement("response"));break}for(var n=0;n<e.response.length;n++)i.appendChild(t(this.parent.document,e.response[n]))}}},this.complete=function(){this.state="complete",this.XMLDOM.setAttribute("state",this.state)}},this.pageNode=function(e,t){this.specification=t,this.parent=e,this.state="empty",this.XMLDOM=this.parent.document.createElement("page"),this.XMLDOM.setAttribute("ref",t.id),this.XMLDOM.setAttribute("presentedId",t.presentedId),this.XMLDOM.setAttribute("state",this.state),void 0!==t.preTest&&(this.preTest=new this.parent.surveyNode(this.parent,this.XMLDOM,this.specification.preTest)),void 0!==t.postTest&&(this.postTest=new this.parent.surveyNode(this.parent,this.XMLDOM,this.specification.postTest));var i=this.parent.document.createElement("metric");this.XMLDOM.appendChild(i),this.specification.audioElements.forEach(function(e){var t=this.parent.document.createElement("audioelement");t.setAttribute("ref",e.id),void 0!==e.name&&t.setAttribute("name",e.name),t.setAttribute("type",e.type),t.setAttribute("url",e.url),t.setAttribute("fqurl",qualifyURL(e.url)),t.setAttribute("gain",e.gain),"anchor"!=e.type&&"reference"!=e.type||e.marker>0&&t.setAttribute("marker",e.marker);var i=this.parent.document.createElement("metric");t.appendChild(i),this.XMLDOM.appendChild(t)},this),this.parent.root.appendChild(this.XMLDOM),this.complete=function(){this.state="complete",this.XMLDOM.setAttribute("state","complete")}},this.update=function(){this.SessionKey.update()},this.finish=function(){return this.state=1,this.root.setAttribute("state","complete"),this.root},Object.defineProperties(this,{filenamePrefix:{get:function(){return e},set:function(t){return"string"!=typeof t&&(t=String(t)),e=t,t}}})}var audioContext,projectXML,schemaXSD,specification,interfaceContext,storage,popup,testState,audioEngineContext,gReturnURL,gSaveFilenamePrefix,currentTrackOrder=[];AudioBufferSourceNode.prototype.owner=void 0,AudioBufferSourceNode.prototype.playbackStartTime=void 0,AudioBuffer.prototype.playbackGain=void 0,AudioBuffer.prototype.lufs=void 0,XMLDocument.prototype.getAllElementsByName=function(e){e=String(e);return this.documentElement.getAllElementsByName(e)},Element.prototype.getAllElementsByName=function(e){e=String(e);for(var t=[],i=this.firstElementChild;null!==i;)i.getAttribute("name")==e&&t.push(i),i.childElementCount>0&&(t=t.concat(i.getAllElementsByName(e))),i=i.nextElementSibling;return t},XMLDocument.prototype.getAllElementsByTagName=function(e){e=String(e);return this.documentElement.getAllElementsByTagName(e)},Element.prototype.getAllElementsByTagName=function(e){e=String(e);for(var t=[],i=this.firstElementChild;null!==i;)i.nodeName==e&&t.push(i),i.childElementCount>0&&(t=t.concat(i.getAllElementsByTagName(e))),i=i.nextElementSibling;return t},"function"!=typeof XMLDocument.prototype.getElementsByName&&(XMLDocument.prototype.getElementsByName=function(e){e=String(e);for(var t=this.documentElement.firstElementChild,i=[];null!==t;)t.getAttribute("name")==e&&i.push(t),t=t.nextElementSibling;return i});var window_depedancy_callback,check_dependancies=function(){return"function"==typeof jQuery&&("function"==typeof Specification&&("function"==typeof calculateLoudness&&("function"==typeof WAVE&&"function"==typeof validateXML)))},onload=function(){var e=window.AudioContext||window.webkitAudioContext;if(audioContext=new e,testState=new stateMachine,popup=new interfacePopup,specification=new Specification,interfaceContext=new Interface(specification),storage=new Storage,window.onresize=function(e){interfaceContext.resizeWindow(e)},0!==window.location.search.length){var t,i=window.location.search.split("?")[1].split("&");for(var n in i){i[n]=i[n].split("=");var o=i[n][0],s=decodeURIComponent(i[n][1]);switch(o){case"url":t=s,specification.url=t;break;case"returnURL":gReturnURL=s;break;case"saveFilenamePrefix":storage.filenamePrefix=s}}loadProjectSpec(t),window.onbeforeunload=function(){return"Please only leave this page once you have completed the tests. Are you sure you have completed all testing?"}}interfaceContext.lightbox.resize()};window_depedancy_callback=window.setInterval(function(){check_dependancies()?(window.clearInterval(window_depedancy_callback),onload()):document.getElementById("topLevelBody").innerHTML="<h1>Loading Resources</h1>"},100);
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/js/min/jquery-2.1.4.min.js	Wed Nov 28 13:51:51 2018 +0000
@@ -0,0 +1,1 @@
+!function(e,t){"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){function n(e){var t="length"in e&&e.length,n=V.type(e);return"function"!==n&&!V.isWindow(e)&&(!(1!==e.nodeType||!t)||("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e))}function r(e,t,n){if(V.isFunction(t))return V.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return V.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(te.test(t))return V.filter(t,e,n);t=V.filter(t,e)}return V.grep(e,function(e){return I.call(t,e)>=0!==n})}function i(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}function o(){U.removeEventListener("DOMContentLoaded",o,!1),e.removeEventListener("load",o,!1),V.ready()}function s(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=V.expando+s.uid++}function a(e,t,n){var r;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(de,"-$1").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===n||"false"!==n&&("null"===n?null:+n+""===n?+n:pe.test(n)?V.parseJSON(n):n)}catch(e){}fe.set(e,t,n)}else n=void 0;return n}function u(){return!0}function l(){return!1}function c(){try{return U.activeElement}catch(e){}}function f(e,t){return V.nodeName(e,"table")&&V.nodeName(11!==t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function p(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function d(e){var t=je.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function h(e,t){for(var n=0,r=e.length;n<r;n++)ce.set(e[n],"globalEval",!t||ce.get(t[n],"globalEval"))}function g(e,t){var n,r,i,o,s,a,u,l;if(1===t.nodeType){if(ce.hasData(e)&&(o=ce.access(e),s=ce.set(t,o),l=o.events)){delete s.handle,s.events={};for(i in l)for(n=0,r=l[i].length;n<r;n++)V.event.add(t,i,l[i][n])}fe.hasData(e)&&(a=fe.access(e),u=V.extend({},a),fe.set(t,u))}}function m(e,t){var n=e.getElementsByTagName?e.getElementsByTagName(t||"*"):e.querySelectorAll?e.querySelectorAll(t||"*"):[];return void 0===t||t&&V.nodeName(e,t)?V.merge([e],n):n}function v(e,t){var n=t.nodeName.toLowerCase();"input"===n&&ve.test(e.type)?t.checked=e.checked:"input"!==n&&"textarea"!==n||(t.defaultValue=e.defaultValue)}function y(t,n){var r,i=V(n.createElement(t)).appendTo(n.body),o=e.getDefaultComputedStyle&&(r=e.getDefaultComputedStyle(i[0]))?r.display:V.css(i[0],"display");return i.detach(),o}function x(e){var t=U,n=He[e];return n||("none"!==(n=y(e,t))&&n||((t=(qe=(qe||V("<iframe frameborder='0' width='0' height='0'/>")).appendTo(t.documentElement))[0].contentDocument).write(),t.close(),n=y(e,t),qe.detach()),He[e]=n),n}function b(e,t,n){var r,i,o,s,a=e.style;return(n=n||Pe(e))&&(s=n.getPropertyValue(t)||n[t]),n&&(""!==s||V.contains(e.ownerDocument,e)||(s=V.style(e,t)),Fe.test(s)&&Oe.test(t)&&(r=a.width,i=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=s,s=n.width,a.width=r,a.minWidth=i,a.maxWidth=o)),void 0!==s?s+"":s}function w(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}function T(e,t){if(t in e)return t;for(var n=t[0].toUpperCase()+t.slice(1),r=t,i=Be.length;i--;)if((t=Be[i]+n)in e)return t;return r}function C(e,t,n){var r=Me.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function N(e,t,n,r,i){for(var o=n===(r?"border":"content")?4:"width"===t?1:0,s=0;o<4;o+=2)"margin"===n&&(s+=V.css(e,n+ge[o],!0,i)),r?("content"===n&&(s-=V.css(e,"padding"+ge[o],!0,i)),"margin"!==n&&(s-=V.css(e,"border"+ge[o]+"Width",!0,i))):(s+=V.css(e,"padding"+ge[o],!0,i),"padding"!==n&&(s+=V.css(e,"border"+ge[o]+"Width",!0,i)));return s}function k(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Pe(e),s="border-box"===V.css(e,"boxSizing",!1,o);if(i<=0||null==i){if(((i=b(e,t,o))<0||null==i)&&(i=e.style[t]),Fe.test(i))return i;r=s&&(X.boxSizingReliable()||i===e.style[t]),i=parseFloat(i)||0}return i+N(e,t,n||(s?"border":"content"),r,o)+"px"}function E(e,t){for(var n,r,i,o=[],s=0,a=e.length;s<a;s++)(r=e[s]).style&&(o[s]=ce.get(r,"olddisplay"),n=r.style.display,t?(o[s]||"none"!==n||(r.style.display=""),""===r.style.display&&me(r)&&(o[s]=ce.access(r,"olddisplay",x(r.nodeName)))):(i=me(r),"none"===n&&i||ce.set(r,"olddisplay",i?n:V.css(r,"display"))));for(s=0;s<a;s++)(r=e[s]).style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[s]||"":"none"));return e}function S(e,t,n,r,i){return new S.prototype.init(e,t,n,r,i)}function D(){return setTimeout(function(){_e=void 0}),_e=V.now()}function j(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=ge[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function A(e,t,n){for(var r,i=(Ge[t]||[]).concat(Ge["*"]),o=0,s=i.length;o<s;o++)if(r=i[o].call(n,t,e))return r}function L(e,t,n){var r,i,o=0,s=Ye.length,a=V.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;for(var t=_e||D(),n=Math.max(0,l.startTime+l.duration-t),r=1-(n/l.duration||0),o=0,s=l.tweens.length;o<s;o++)l.tweens[o].run(r);return a.notifyWith(e,[l,r,n]),r<1&&s?n:(a.resolveWith(e,[l]),!1)},l=a.promise({elem:e,props:V.extend({},t),opts:V.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:_e||D(),duration:n.duration,tweens:[],createTween:function(t,n){var r=V.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;n<r;n++)l.tweens[n].run(1);return t?a.resolveWith(e,[l,t]):a.rejectWith(e,[l,t]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,s;for(n in e)if(r=V.camelCase(n),i=t[r],o=e[n],V.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(s=V.cssHooks[r])&&"expand"in s){o=s.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}(c,l.opts.specialEasing);o<s;o++)if(r=Ye[o].call(l,e,c,l.opts))return r;return V.map(c,A,l),V.isFunction(l.opts.start)&&l.opts.start.call(e,l),V.fx.timer(V.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function q(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(se)||[];if(V.isFunction(n))for(;r=o[i++];)"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function H(e,t,n,r){function i(a){var u;return o[a]=!0,V.each(e[a]||[],function(e,a){var l=a(t,n,r);return"string"!=typeof l||s||o[l]?s?!(u=l):void 0:(t.dataTypes.unshift(l),i(l),!1)}),u}var o={},s=e===ct;return i(t.dataTypes[0])||!o["*"]&&i("*")}function O(e,t){var n,r,i=V.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&V.extend(!0,e,r),e}function F(e,t,n,r){var i;if(V.isArray(t))V.each(t,function(t,i){n||gt.test(e)?r(e,i):F(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==V.type(t))r(e,t);else for(i in t)F(e+"["+i+"]",t[i],n,r)}function P(e){return V.isWindow(e)?e:9===e.nodeType&&e.defaultView}var R=[],M=R.slice,W=R.concat,$=R.push,I=R.indexOf,B={},_=B.toString,z=B.hasOwnProperty,X={},U=e.document,V=function(e,t){return new V.fn.init(e,t)},Y=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,G=/^-ms-/,Q=/-([\da-z])/gi,J=function(e,t){return t.toUpperCase()};V.fn=V.prototype={jquery:"2.1.4",constructor:V,selector:"",length:0,toArray:function(){return M.call(this)},get:function(e){return null!=e?e<0?this[e+this.length]:this[e]:M.call(this)},pushStack:function(e){var t=V.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return V.each(this,e,t)},map:function(e){return this.pushStack(V.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(M.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:$,sort:R.sort,splice:R.splice},V.extend=V.fn.extend=function(){var e,t,n,r,i,o,s=arguments[0]||{},a=1,u=arguments.length,l=!1;for("boolean"==typeof s&&(l=s,s=arguments[a]||{},a++),"object"==typeof s||V.isFunction(s)||(s={}),a===u&&(s=this,a--);a<u;a++)if(null!=(e=arguments[a]))for(t in e)n=s[t],s!==(r=e[t])&&(l&&r&&(V.isPlainObject(r)||(i=V.isArray(r)))?(i?(i=!1,o=n&&V.isArray(n)?n:[]):o=n&&V.isPlainObject(n)?n:{},s[t]=V.extend(l,o,r)):void 0!==r&&(s[t]=r));return s},V.extend({expando:"jQuery"+("2.1.4"+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isFunction:function(e){return"function"===V.type(e)},isArray:Array.isArray,isWindow:function(e){return null!=e&&e===e.window},isNumeric:function(e){return!V.isArray(e)&&e-parseFloat(e)+1>=0},isPlainObject:function(e){return"object"===V.type(e)&&!e.nodeType&&!V.isWindow(e)&&!(e.constructor&&!z.call(e.constructor.prototype,"isPrototypeOf"))},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?B[_.call(e)]||"object":typeof e},globalEval:function(e){var t,n=eval;(e=V.trim(e))&&(1===e.indexOf("use strict")?((t=U.createElement("script")).text=e,U.head.appendChild(t).parentNode.removeChild(t)):n(e))},camelCase:function(e){return e.replace(G,"ms-").replace(Q,J)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,r){var i=0,o=e.length,s=n(e);if(r){if(s)for(;i<o&&!1!==t.apply(e[i],r);i++);else for(i in e)if(!1===t.apply(e[i],r))break}else if(s)for(;i<o&&!1!==t.call(e[i],i,e[i]);i++);else for(i in e)if(!1===t.call(e[i],i,e[i]))break;return e},trim:function(e){return null==e?"":(e+"").replace(Y,"")},makeArray:function(e,t){var r=t||[];return null!=e&&(n(Object(e))?V.merge(r,"string"==typeof e?[e]:e):$.call(r,e)),r},inArray:function(e,t,n){return null==t?-1:I.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,s=!n;i<o;i++)!t(e[i],i)!==s&&r.push(e[i]);return r},map:function(e,t,r){var i,o=0,s=e.length,a=[];if(n(e))for(;o<s;o++)null!=(i=t(e[o],o,r))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,r))&&a.push(i);return W.apply([],a)},guid:1,proxy:function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),V.isFunction(e))return r=M.call(arguments,2),i=function(){return e.apply(t||this,r.concat(M.call(arguments)))},i.guid=e.guid=e.guid||V.guid++,i},now:Date.now,support:X}),V.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){B["[object "+t+"]"]=t.toLowerCase()});var K=function(e){function t(e,t,n,r){var i,o,s,a,u,l,f,d,h,g;if((t?t.ownerDocument||t:M)!==A&&j(t),t=t||A,n=n||[],a=t.nodeType,"string"!=typeof e||!e||1!==a&&9!==a&&11!==a)return n;if(!r&&q){if(11!==a&&(i=me.exec(e)))if(s=i[1]){if(9===a){if(!(o=t.getElementById(s))||!o.parentNode)return n;if(o.id===s)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(s))&&P(t,o)&&o.id===s)return n.push(o),n}else{if(i[2])return Q.apply(n,t.getElementsByTagName(e)),n;if((s=i[3])&&x.getElementsByClassName)return Q.apply(n,t.getElementsByClassName(s)),n}if(x.qsa&&(!H||!H.test(e))){if(d=f=R,h=t,g=1!==a&&e,1===a&&"object"!==t.nodeName.toLowerCase()){for(l=C(e),(f=t.getAttribute("id"))?d=f.replace(ye,"\\$&"):t.setAttribute("id",d),d="[id='"+d+"'] ",u=l.length;u--;)l[u]=d+p(l[u]);h=ve.test(e)&&c(t.parentNode)||t,g=l.join(",")}if(g)try{return Q.apply(n,h.querySelectorAll(g)),n}catch(e){}finally{f||t.removeAttribute("id")}}}return k(e.replace(se,"$1"),t,n,r)}function n(){function e(n,r){return t.push(n+" ")>b.cacheLength&&delete e[t.shift()],e[n+" "]=r}var t=[];return e}function r(e){return e[R]=!0,e}function i(e){var t=A.createElement("div");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function o(e,t){for(var n=e.split("|"),r=e.length;r--;)b.attrHandle[n[r]]=t}function s(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||X)-(~e.sourceIndex||X);if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function a(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function u(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function l(e){return r(function(t){return t=+t,r(function(n,r){for(var i,o=e([],n.length,t),s=o.length;s--;)n[i=o[s]]&&(n[i]=!(r[i]=n[i]))})})}function c(e){return e&&void 0!==e.getElementsByTagName&&e}function f(){}function p(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function d(e,t,n){var r=t.dir,i=n&&"parentNode"===r,o=$++;return t.first?function(t,n,o){for(;t=t[r];)if(1===t.nodeType||i)return e(t,n,o)}:function(t,n,s){var a,u,l=[W,o];if(s){for(;t=t[r];)if((1===t.nodeType||i)&&e(t,n,s))return!0}else for(;t=t[r];)if(1===t.nodeType||i){if(u=t[R]||(t[R]={}),(a=u[r])&&a[0]===W&&a[1]===o)return l[2]=a[2];if(u[r]=l,l[2]=e(t,n,s))return!0}}}function h(e){return e.length>1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function g(e,t,n,r,i){for(var o,s=[],a=0,u=e.length,l=null!=t;a<u;a++)(o=e[a])&&(n&&!n(o,r,i)||(s.push(o),l&&t.push(a)));return s}function m(e,n,i,o,s,a){return o&&!o[R]&&(o=m(o)),s&&!s[R]&&(s=m(s,a)),r(function(r,a,u,l){var c,f,p,d=[],h=[],m=a.length,v=r||function(e,n,r){for(var i=0,o=n.length;i<o;i++)t(e,n[i],r);return r}(n||"*",u.nodeType?[u]:u,[]),y=!e||!r&&n?v:g(v,d,e,u,l),x=i?s||(r?e:m||o)?[]:a:y;if(i&&i(y,x,u,l),o)for(c=g(x,h),o(c,[],u,l),f=c.length;f--;)(p=c[f])&&(x[h[f]]=!(y[h[f]]=p));if(r){if(s||e){if(s){for(c=[],f=x.length;f--;)(p=x[f])&&c.push(y[f]=p);s(null,x=[],c,l)}for(f=x.length;f--;)(p=x[f])&&(c=s?K(r,p):d[f])>-1&&(r[c]=!(a[c]=p))}}else x=g(x===a?x.splice(m,x.length):x),s?s(null,a,x,l):Q.apply(a,x)})}function v(e){for(var t,n,r,i=e.length,o=b.relative[e[0].type],s=o||b.relative[" "],a=o?1:0,u=d(function(e){return e===t},s,!0),l=d(function(e){return K(t,e)>-1},s,!0),c=[function(e,n,r){var i=!o&&(r||n!==E)||((t=n).nodeType?u(e,n,r):l(e,n,r));return t=null,i}];a<i;a++)if(n=b.relative[e[a].type])c=[d(h(c),n)];else{if((n=b.filter[e[a].type].apply(null,e[a].matches))[R]){for(r=++a;r<i&&!b.relative[e[r].type];r++);return m(a>1&&h(c),a>1&&p(e.slice(0,a-1).concat({value:" "===e[a-2].type?"*":""})).replace(se,"$1"),n,a<r&&v(e.slice(a,r)),r<i&&v(e=e.slice(r)),r<i&&p(e))}c.push(n)}return h(c)}var y,x,b,w,T,C,N,k,E,S,D,j,A,L,q,H,O,F,P,R="sizzle"+1*new Date,M=e.document,W=0,$=0,I=n(),B=n(),_=n(),z=function(e,t){return e===t&&(D=!0),0},X=1<<31,U={}.hasOwnProperty,V=[],Y=V.pop,G=V.push,Q=V.push,J=V.slice,K=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},Z="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",ee="[\\x20\\t\\r\\n\\f]",te="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",ne=te.replace("w","w#"),re="\\["+ee+"*("+te+")(?:"+ee+"*([*^$|!~]?=)"+ee+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+ne+"))|)"+ee+"*\\]",ie=":("+te+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+re+")*)|.*)\\)|)",oe=new RegExp(ee+"+","g"),se=new RegExp("^"+ee+"+|((?:^|[^\\\\])(?:\\\\.)*)"+ee+"+$","g"),ae=new RegExp("^"+ee+"*,"+ee+"*"),ue=new RegExp("^"+ee+"*([>+~]|"+ee+")"+ee+"*"),le=new RegExp("="+ee+"*([^\\]'\"]*?)"+ee+"*\\]","g"),ce=new RegExp(ie),fe=new RegExp("^"+ne+"$"),pe={ID:new RegExp("^#("+te+")"),CLASS:new RegExp("^\\.("+te+")"),TAG:new RegExp("^("+te.replace("w","w*")+")"),ATTR:new RegExp("^"+re),PSEUDO:new RegExp("^"+ie),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ee+"*(even|odd|(([+-]|)(\\d*)n|)"+ee+"*(?:([+-]|)"+ee+"*(\\d+)|))"+ee+"*\\)|)","i"),bool:new RegExp("^(?:"+Z+")$","i"),needsContext:new RegExp("^"+ee+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ee+"*((?:-\\d)?\\d*)"+ee+"*\\)|)(?=[^-]|$)","i")},de=/^(?:input|select|textarea|button)$/i,he=/^h\d$/i,ge=/^[^{]+\{\s*\[native \w/,me=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ve=/[+~]/,ye=/'|\\/g,xe=new RegExp("\\\\([\\da-f]{1,6}"+ee+"?|("+ee+")|.)","ig"),be=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},we=function(){j()};try{Q.apply(V=J.call(M.childNodes),M.childNodes),V[M.childNodes.length].nodeType}catch(e){Q={apply:V.length?function(e,t){G.apply(e,J.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}x=t.support={},T=t.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},j=t.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:M;return r!==A&&9===r.nodeType&&r.documentElement?(A=r,L=r.documentElement,(n=r.defaultView)&&n!==n.top&&(n.addEventListener?n.addEventListener("unload",we,!1):n.attachEvent&&n.attachEvent("onunload",we)),q=!T(r),x.attributes=i(function(e){return e.className="i",!e.getAttribute("className")}),x.getElementsByTagName=i(function(e){return e.appendChild(r.createComment("")),!e.getElementsByTagName("*").length}),x.getElementsByClassName=ge.test(r.getElementsByClassName),x.getById=i(function(e){return L.appendChild(e).id=R,!r.getElementsByName||!r.getElementsByName(R).length}),x.getById?(b.find.ID=function(e,t){if(void 0!==t.getElementById&&q){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},b.filter.ID=function(e){var t=e.replace(xe,be);return function(e){return e.getAttribute("id")===t}}):(delete b.find.ID,b.filter.ID=function(e){var t=e.replace(xe,be);return function(e){var n=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}}),b.find.TAG=x.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):x.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=x.getElementsByClassName&&function(e,t){if(q)return t.getElementsByClassName(e)},O=[],H=[],(x.qsa=ge.test(r.querySelectorAll))&&(i(function(e){L.appendChild(e).innerHTML="<a id='"+R+"'></a><select id='"+R+"-\f]' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&H.push("[*^$]="+ee+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||H.push("\\["+ee+"*(?:value|"+Z+")"),e.querySelectorAll("[id~="+R+"-]").length||H.push("~="),e.querySelectorAll(":checked").length||H.push(":checked"),e.querySelectorAll("a#"+R+"+*").length||H.push(".#.+[+~]")}),i(function(e){var t=r.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&H.push("name"+ee+"*[*^$|!~]?="),e.querySelectorAll(":enabled").length||H.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),H.push(",.*:")})),(x.matchesSelector=ge.test(F=L.matches||L.webkitMatchesSelector||L.mozMatchesSelector||L.oMatchesSelector||L.msMatchesSelector))&&i(function(e){x.disconnectedMatch=F.call(e,"div"),F.call(e,"[s!='']:x"),O.push("!=",ie)}),H=H.length&&new RegExp(H.join("|")),O=O.length&&new RegExp(O.join("|")),t=ge.test(L.compareDocumentPosition),P=t||ge.test(L.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},z=t?function(e,t){if(e===t)return D=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!x.sortDetached&&t.compareDocumentPosition(e)===n?e===r||e.ownerDocument===M&&P(M,e)?-1:t===r||t.ownerDocument===M&&P(M,t)?1:S?K(S,e)-K(S,t):0:4&n?-1:1)}:function(e,t){if(e===t)return D=!0,0;var n,i=0,o=e.parentNode,a=t.parentNode,u=[e],l=[t];if(!o||!a)return e===r?-1:t===r?1:o?-1:a?1:S?K(S,e)-K(S,t):0;if(o===a)return s(e,t);for(n=e;n=n.parentNode;)u.unshift(n);for(n=t;n=n.parentNode;)l.unshift(n);for(;u[i]===l[i];)i++;return i?s(u[i],l[i]):u[i]===M?-1:l[i]===M?1:0},r):A},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==A&&j(e),n=n.replace(le,"='$1']"),x.matchesSelector&&q&&(!O||!O.test(n))&&(!H||!H.test(n)))try{var r=F.call(e,n);if(r||x.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return t(n,A,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==A&&j(e),P(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==A&&j(e);var n=b.attrHandle[t.toLowerCase()],r=n&&U.call(b.attrHandle,t.toLowerCase())?n(e,t,!q):void 0;return void 0!==r?r:x.attributes||!q?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},t.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},t.uniqueSort=function(e){var t,n=[],r=0,i=0;if(D=!x.detectDuplicates,S=!x.sortStable&&e.slice(0),e.sort(z),D){for(;t=e[i++];)t===e[i]&&(r=n.push(i));for(;r--;)e.splice(n[r],1)}return S=null,e},w=t.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=w(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r++];)n+=w(t);return n},(b=t.selectors={cacheLength:50,createPseudo:r,match:pe,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(xe,be),e[3]=(e[3]||e[4]||e[5]||"").replace(xe,be),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return pe.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&ce.test(n)&&(t=C(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(xe,be).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=I[e+" "];return t||(t=new RegExp("(^|"+ee+")"+e+"("+ee+"|$)"))&&I(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,n,r){return function(i){var o=t.attr(i,e);return null==o?"!="===n:!n||(o+="","="===n?o===r:"!="===n?o!==r:"^="===n?r&&0===o.indexOf(r):"*="===n?r&&o.indexOf(r)>-1:"$="===n?r&&o.slice(-r.length)===r:"~="===n?(" "+o.replace(oe," ")+" ").indexOf(r)>-1:"|="===n&&(o===r||o.slice(0,r.length+1)===r+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),s="last"!==e.slice(-4),a="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,d,h,g=o!==s?"nextSibling":"previousSibling",m=t.parentNode,v=a&&t.nodeName.toLowerCase(),y=!u&&!a;if(m){if(o){for(;g;){for(f=t;f=f[g];)if(a?f.nodeName.toLowerCase()===v:1===f.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[s?m.firstChild:m.lastChild],s&&y){for(d=(l=(c=m[R]||(m[R]={}))[e]||[])[0]===W&&l[1],p=l[0]===W&&l[2],f=d&&m.childNodes[d];f=++d&&f&&f[g]||(p=d=0)||h.pop();)if(1===f.nodeType&&++p&&f===t){c[e]=[W,d,p];break}}else if(y&&(l=(t[R]||(t[R]={}))[e])&&l[0]===W)p=l[1];else for(;(f=++d&&f&&f[g]||(p=d=0)||h.pop())&&((a?f.nodeName.toLowerCase()!==v:1!==f.nodeType)||!++p||(y&&((f[R]||(f[R]={}))[e]=[W,p]),f!==t)););return(p-=i)===r||p%r==0&&p/r>=0}}},PSEUDO:function(e,n){var i,o=b.pseudos[e]||b.setFilters[e.toLowerCase()]||t.error("unsupported pseudo: "+e);return o[R]?o(n):o.length>1?(i=[e,e,"",n],b.setFilters.hasOwnProperty(e.toLowerCase())?r(function(e,t){for(var r,i=o(e,n),s=i.length;s--;)e[r=K(e,i[s])]=!(t[r]=i[s])}):function(e){return o(e,0,i)}):o}},pseudos:{not:r(function(e){var t=[],n=[],i=N(e.replace(se,"$1"));return i[R]?r(function(e,t,n,r){for(var o,s=i(e,null,r,[]),a=e.length;a--;)(o=s[a])&&(e[a]=!(t[a]=o))}):function(e,r,o){return t[0]=e,i(t,null,o,n),t[0]=null,!n.pop()}}),has:r(function(e){return function(n){return t(e,n).length>0}}),contains:r(function(e){return e=e.replace(xe,be),function(t){return(t.textContent||t.innerText||w(t)).indexOf(e)>-1}}),lang:r(function(e){return fe.test(e||"")||t.error("unsupported lang: "+e),e=e.replace(xe,be).toLowerCase(),function(t){var n;do{if(n=q?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===L},focus:function(e){return e===A.activeElement&&(!A.hasFocus||A.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return!1===e.disabled},disabled:function(e){return!0===e.disabled},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return he.test(e.nodeName)},input:function(e){return de.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:l(function(){return[0]}),last:l(function(e,t){return[t-1]}),eq:l(function(e,t,n){return[n<0?n+t:n]}),even:l(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:l(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:l(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:l(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq;for(y in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[y]=a(y);for(y in{submit:!0,reset:!0})b.pseudos[y]=u(y);return f.prototype=b.filters=b.pseudos,b.setFilters=new f,C=t.tokenize=function(e,n){var r,i,o,s,a,u,l,c=B[e+" "];if(c)return n?0:c.slice(0);for(a=e,u=[],l=b.preFilter;a;){r&&!(i=ae.exec(a))||(i&&(a=a.slice(i[0].length)||a),u.push(o=[])),r=!1,(i=ue.exec(a))&&(r=i.shift(),o.push({value:r,type:i[0].replace(se," ")}),a=a.slice(r.length));for(s in b.filter)!(i=pe[s].exec(a))||l[s]&&!(i=l[s](i))||(r=i.shift(),o.push({value:r,type:s,matches:i}),a=a.slice(r.length));if(!r)break}return n?a.length:a?t.error(e):B(e,u).slice(0)},N=t.compile=function(e,n){var i,o=[],s=[],a=_[e+" "];if(!a){for(n||(n=C(e)),i=n.length;i--;)(a=v(n[i]))[R]?o.push(a):s.push(a);(a=_(e,function(e,n){var i=n.length>0,o=e.length>0,s=function(r,s,a,u,l){var c,f,p,d=0,h="0",m=r&&[],v=[],y=E,x=r||o&&b.find.TAG("*",l),w=W+=null==y?1:Math.random()||.1,T=x.length;for(l&&(E=s!==A&&s);h!==T&&null!=(c=x[h]);h++){if(o&&c){for(f=0;p=e[f++];)if(p(c,s,a)){u.push(c);break}l&&(W=w)}i&&((c=!p&&c)&&d--,r&&m.push(c))}if(d+=h,i&&h!==d){for(f=0;p=n[f++];)p(m,v,s,a);if(r){if(d>0)for(;h--;)m[h]||v[h]||(v[h]=Y.call(u));v=g(v)}Q.apply(u,v),l&&!r&&v.length>0&&d+n.length>1&&t.uniqueSort(u)}return l&&(W=w,E=y),m};return i?r(s):s}(s,o))).selector=e}return a},k=t.select=function(e,t,n,r){var i,o,s,a,u,l="function"==typeof e&&e,f=!r&&C(e=l.selector||e);if(n=n||[],1===f.length){if((o=f[0]=f[0].slice(0)).length>2&&"ID"===(s=o[0]).type&&x.getById&&9===t.nodeType&&q&&b.relative[o[1].type]){if(!(t=(b.find.ID(s.matches[0].replace(xe,be),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}for(i=pe.needsContext.test(e)?0:o.length;i--&&(s=o[i],!b.relative[a=s.type]);)if((u=b.find[a])&&(r=u(s.matches[0].replace(xe,be),ve.test(o[0].type)&&c(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&p(o)))return Q.apply(n,r),n;break}}return(l||N(e,f))(r,t,!q,n,ve.test(e)&&c(t.parentNode)||t),n},x.sortStable=R.split("").sort(z).join("")===R,x.detectDuplicates=!!D,j(),x.sortDetached=i(function(e){return 1&e.compareDocumentPosition(A.createElement("div"))}),i(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||o("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),x.attributes&&i(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||o("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),i(function(e){return null==e.getAttribute("disabled")})||o(Z,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),t}(e);V.find=K,V.expr=K.selectors,V.expr[":"]=V.expr.pseudos,V.unique=K.uniqueSort,V.text=K.getText,V.isXMLDoc=K.isXML,V.contains=K.contains;var Z=V.expr.match.needsContext,ee=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,te=/^.[^:#\[\.,]*$/;V.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?V.find.matchesSelector(r,e)?[r]:[]:V.find.matches(e,V.grep(t,function(e){return 1===e.nodeType}))},V.fn.extend({find:function(e){var t,n=this.length,r=[],i=this;if("string"!=typeof e)return this.pushStack(V(e).filter(function(){for(t=0;t<n;t++)if(V.contains(i[t],this))return!0}));for(t=0;t<n;t++)V.find(e,i[t],r);return r=this.pushStack(n>1?V.unique(r):r),r.selector=this.selector?this.selector+" "+e:e,r},filter:function(e){return this.pushStack(r(this,e||[],!1))},not:function(e){return this.pushStack(r(this,e||[],!0))},is:function(e){return!!r(this,"string"==typeof e&&Z.test(e)?V(e):e||[],!1).length}});var ne,re=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/;(V.fn.init=function(e,t){var n,r;if(!e)return this;if("string"==typeof e){if(!(n="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:re.exec(e))||!n[1]&&t)return!t||t.jquery?(t||ne).find(e):this.constructor(t).find(e);if(n[1]){if(t=t instanceof V?t[0]:t,V.merge(this,V.parseHTML(n[1],t&&t.nodeType?t.ownerDocument||t:U,!0)),ee.test(n[1])&&V.isPlainObject(t))for(n in t)V.isFunction(this[n])?this[n](t[n]):this.attr(n,t[n]);return this}return(r=U.getElementById(n[2]))&&r.parentNode&&(this.length=1,this[0]=r),this.context=U,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):V.isFunction(e)?void 0!==ne.ready?ne.ready(e):e(V):(void 0!==e.selector&&(this.selector=e.selector,this.context=e.context),V.makeArray(e,this))}).prototype=V.fn,ne=V(U);var ie=/^(?:parents|prev(?:Until|All))/,oe={children:!0,contents:!0,next:!0,prev:!0};V.extend({dir:function(e,t,n){for(var r=[],i=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&V(e).is(n))break;r.push(e)}return r},sibling:function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}}),V.fn.extend({has:function(e){var t=V(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(V.contains(this,t[e]))return!0})},closest:function(e,t){for(var n,r=0,i=this.length,o=[],s=Z.test(e)||"string"!=typeof e?V(e,t||this.context):0;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(s?s.index(n)>-1:1===n.nodeType&&V.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?V.unique(o):o)},index:function(e){return e?"string"==typeof e?I.call(V(e),this[0]):I.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(V.unique(V.merge(this.get(),V(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),V.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return V.dir(e,"parentNode")},parentsUntil:function(e,t,n){return V.dir(e,"parentNode",n)},next:function(e){return i(e,"nextSibling")},prev:function(e){return i(e,"previousSibling")},nextAll:function(e){return V.dir(e,"nextSibling")},prevAll:function(e){return V.dir(e,"previousSibling")},nextUntil:function(e,t,n){return V.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return V.dir(e,"previousSibling",n)},siblings:function(e){return V.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return V.sibling(e.firstChild)},contents:function(e){return e.contentDocument||V.merge([],e.childNodes)}},function(e,t){V.fn[e]=function(n,r){var i=V.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=V.filter(r,i)),this.length>1&&(oe[e]||V.unique(i),ie.test(e)&&i.reverse()),this.pushStack(i)}});var se=/\S+/g,ae={};V.Callbacks=function(e){var t,n,r,i,o,s,a=[],u=!(e="string"==typeof e?ae[e]||function(e){var t=ae[e]={};return V.each(e.match(se)||[],function(e,n){t[n]=!0}),t}(e):V.extend({},e)).once&&[],l=function(f){for(t=e.memory&&f,n=!0,s=i||0,i=0,o=a.length,r=!0;a&&s<o;s++)if(!1===a[s].apply(f[0],f[1])&&e.stopOnFalse){t=!1;break}r=!1,a&&(u?u.length&&l(u.shift()):t?a=[]:c.disable())},c={add:function(){if(a){var n=a.length;!function t(n){V.each(n,function(n,r){var i=V.type(r);"function"===i?e.unique&&c.has(r)||a.push(r):r&&r.length&&"string"!==i&&t(r)})}(arguments),r?o=a.length:t&&(i=n,l(t))}return this},remove:function(){return a&&V.each(arguments,function(e,t){for(var n;(n=V.inArray(t,a,n))>-1;)a.splice(n,1),r&&(n<=o&&o--,n<=s&&s--)}),this},has:function(e){return e?V.inArray(e,a)>-1:!(!a||!a.length)},empty:function(){return a=[],o=0,this},disable:function(){return a=u=t=void 0,this},disabled:function(){return!a},lock:function(){return u=void 0,t||c.disable(),this},locked:function(){return!u},fireWith:function(e,t){return!a||n&&!u||(t=[e,(t=t||[]).slice?t.slice():t],r?u.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!n}};return c},V.extend({Deferred:function(e){var t=[["resolve","done",V.Callbacks("once memory"),"resolved"],["reject","fail",V.Callbacks("once memory"),"rejected"],["notify","progress",V.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return V.Deferred(function(n){V.each(t,function(t,o){var s=V.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&V.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[o[0]+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?V.extend(e,r):r}},i={};return r.pipe=r.then,V.each(t,function(e,o){var s=o[2],a=o[3];r[o[1]]=s.add,a&&s.add(function(){n=a},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=s.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t,n,r,i=0,o=M.call(arguments),s=o.length,a=1!==s||e&&V.isFunction(e.promise)?s:0,u=1===a?e:V.Deferred(),l=function(e,n,r){return function(i){n[e]=this,r[e]=arguments.length>1?M.call(arguments):i,r===t?u.notifyWith(n,r):--a||u.resolveWith(n,r)}};if(s>1)for(t=new Array(s),n=new Array(s),r=new Array(s);i<s;i++)o[i]&&V.isFunction(o[i].promise)?o[i].promise().done(l(i,r,o)).fail(u.reject).progress(l(i,n,t)):--a;return a||u.resolveWith(r,o),u.promise()}});var ue;V.fn.ready=function(e){return V.ready.promise().done(e),this},V.extend({isReady:!1,readyWait:1,holdReady:function(e){e?V.readyWait++:V.ready(!0)},ready:function(e){(!0===e?--V.readyWait:V.isReady)||(V.isReady=!0,!0!==e&&--V.readyWait>0||(ue.resolveWith(U,[V]),V.fn.triggerHandler&&(V(U).triggerHandler("ready"),V(U).off("ready"))))}}),V.ready.promise=function(t){return ue||(ue=V.Deferred(),"complete"===U.readyState?setTimeout(V.ready):(U.addEventListener("DOMContentLoaded",o,!1),e.addEventListener("load",o,!1))),ue.promise(t)},V.ready.promise();var le=V.access=function(e,t,n,r,i,o,s){var a=0,u=e.length,l=null==n;if("object"===V.type(n)){i=!0;for(a in n)V.access(e,t,a,n[a],!0,o,s)}else if(void 0!==r&&(i=!0,V.isFunction(r)||(s=!0),l&&(s?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(V(e),n)})),t))for(;a<u;a++)t(e[a],n,s?r:r.call(e[a],a,t(e[a],n)));return i?e:l?t.call(e):u?t(e[0],n):o};V.acceptData=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType},s.uid=1,s.accepts=V.acceptData,s.prototype={key:function(e){if(!s.accepts(e))return 0;var t={},n=e[this.expando];if(!n){n=s.uid++;try{t[this.expando]={value:n},Object.defineProperties(e,t)}catch(r){t[this.expando]=n,V.extend(e,t)}}return this.cache[n]||(this.cache[n]={}),n},set:function(e,t,n){var r,i=this.key(e),o=this.cache[i];if("string"==typeof t)o[t]=n;else if(V.isEmptyObject(o))V.extend(this.cache[i],t);else for(r in t)o[r]=t[r];return o},get:function(e,t){var n=this.cache[this.key(e)];return void 0===t?n:n[t]},access:function(e,t,n){var r;return void 0===t||t&&"string"==typeof t&&void 0===n?void 0!==(r=this.get(e,t))?r:this.get(e,V.camelCase(t)):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r,i,o=this.key(e),s=this.cache[o];if(void 0===t)this.cache[o]={};else{V.isArray(t)?r=t.concat(t.map(V.camelCase)):(i=V.camelCase(t),r=t in s?[t,i]:(r=i)in s?[r]:r.match(se)||[]),n=r.length;for(;n--;)delete s[r[n]]}},hasData:function(e){return!V.isEmptyObject(this.cache[e[this.expando]]||{})},discard:function(e){e[this.expando]&&delete this.cache[e[this.expando]]}};var ce=new s,fe=new s,pe=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,de=/([A-Z])/g;V.extend({hasData:function(e){return fe.hasData(e)||ce.hasData(e)},data:function(e,t,n){return fe.access(e,t,n)},removeData:function(e,t){fe.remove(e,t)},_data:function(e,t,n){return ce.access(e,t,n)},_removeData:function(e,t){ce.remove(e,t)}}),V.fn.extend({data:function(e,t){var n,r,i,o=this[0],s=o&&o.attributes;if(void 0===e){if(this.length&&(i=fe.get(o),1===o.nodeType&&!ce.get(o,"hasDataAttrs"))){for(n=s.length;n--;)s[n]&&0===(r=s[n].name).indexOf("data-")&&(r=V.camelCase(r.slice(5)),a(o,r,i[r]));ce.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof e?this.each(function(){fe.set(this,e)}):le(this,function(t){var n,r=V.camelCase(e);if(o&&void 0===t){if(void 0!==(n=fe.get(o,e)))return n;if(void 0!==(n=fe.get(o,r)))return n;if(void 0!==(n=a(o,r,void 0)))return n}else this.each(function(){var n=fe.get(this,r);fe.set(this,r,t),-1!==e.indexOf("-")&&void 0!==n&&fe.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){fe.remove(this,e)})}}),V.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=ce.get(e,t),n&&(!r||V.isArray(n)?r=ce.access(e,t,V.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=V.queue(e,t),r=n.length,i=n.shift(),o=V._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){V.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return ce.get(e,n)||ce.access(e,n,{empty:V.Callbacks("once memory").add(function(){ce.remove(e,[t+"queue",n])})})}}),V.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length<n?V.queue(this[0],e):void 0===t?this:this.each(function(){var n=V.queue(this,e,t);V._queueHooks(this,e),"fx"===e&&"inprogress"!==n[0]&&V.dequeue(this,e)})},dequeue:function(e){return this.each(function(){V.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=V.Deferred(),o=this,s=this.length,a=function(){--r||i.resolveWith(o,[o])};for("string"!=typeof e&&(t=e,e=void 0),e=e||"fx";s--;)(n=ce.get(o[s],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(a));return a(),i.promise(t)}});var he=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ge=["Top","Right","Bottom","Left"],me=function(e,t){return e=t||e,"none"===V.css(e,"display")||!V.contains(e.ownerDocument,e)},ve=/^(?:checkbox|radio)$/i;!function(){var e=U.createDocumentFragment().appendChild(U.createElement("div")),t=U.createElement("input");t.setAttribute("type","radio"),t.setAttribute("checked","checked"),t.setAttribute("name","t"),e.appendChild(t),X.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,e.innerHTML="<textarea>x</textarea>",X.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue}();var ye="undefined";X.focusinBubbles="onfocusin"in e;var xe=/^key/,be=/^(?:mouse|pointer|contextmenu)|click/,we=/^(?:focusinfocus|focusoutblur)$/,Te=/^([^.]*)(?:\.(.+)|)$/;V.event={global:{},add:function(e,t,n,r,i){var o,s,a,u,l,c,f,p,d,h,g,m=ce.get(e);if(m)for(n.handler&&(n=(o=n).handler,i=o.selector),n.guid||(n.guid=V.guid++),(u=m.events)||(u=m.events={}),(s=m.handle)||(s=m.handle=function(t){return typeof V!==ye&&V.event.triggered!==t.type?V.event.dispatch.apply(e,arguments):void 0}),l=(t=(t||"").match(se)||[""]).length;l--;)d=g=(a=Te.exec(t[l])||[])[1],h=(a[2]||"").split(".").sort(),d&&(f=V.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=V.event.special[d]||{},c=V.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&V.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,s)||e.addEventListener&&e.addEventListener(d,s,!1)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),V.event.global[d]=!0)},remove:function(e,t,n,r,i){var o,s,a,u,l,c,f,p,d,h,g,m=ce.hasData(e)&&ce.get(e);if(m&&(u=m.events)){for(l=(t=(t||"").match(se)||[""]).length;l--;)if(a=Te.exec(t[l])||[],d=g=a[1],h=(a[2]||"").split(".").sort(),d){for(f=V.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],a=a[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=o=p.length;o--;)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||a&&!a.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));s&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,m.handle)||V.removeEvent(e,d,m.handle),delete u[d])}else for(d in u)V.event.remove(e,d+t[l],n,r,!0);V.isEmptyObject(u)&&(delete m.handle,ce.remove(e,"events"))}},trigger:function(t,n,r,i){var o,s,a,u,l,c,f,p=[r||U],d=z.call(t,"type")?t.type:t,h=z.call(t,"namespace")?t.namespace.split("."):[];if(s=a=r=r||U,3!==r.nodeType&&8!==r.nodeType&&!we.test(d+V.event.triggered)&&(d.indexOf(".")>=0&&(d=(h=d.split(".")).shift(),h.sort()),l=d.indexOf(":")<0&&"on"+d,t=t[V.expando]?t:new V.Event(d,"object"==typeof t&&t),t.isTrigger=i?2:3,t.namespace=h.join("."),t.namespace_re=t.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=r),n=null==n?[t]:V.makeArray(n,[t]),f=V.event.special[d]||{},i||!f.trigger||!1!==f.trigger.apply(r,n))){if(!i&&!f.noBubble&&!V.isWindow(r)){for(u=f.delegateType||d,we.test(u+d)||(s=s.parentNode);s;s=s.parentNode)p.push(s),a=s;a===(r.ownerDocument||U)&&p.push(a.defaultView||a.parentWindow||e)}for(o=0;(s=p[o++])&&!t.isPropagationStopped();)t.type=o>1?u:f.bindType||d,(c=(ce.get(s,"events")||{})[t.type]&&ce.get(s,"handle"))&&c.apply(s,n),(c=l&&s[l])&&c.apply&&V.acceptData(s)&&(t.result=c.apply(s,n),!1===t.result&&t.preventDefault());return t.type=d,i||t.isDefaultPrevented()||f._default&&!1!==f._default.apply(p.pop(),n)||!V.acceptData(r)||l&&V.isFunction(r[d])&&!V.isWindow(r)&&((a=r[l])&&(r[l]=null),V.event.triggered=d,r[d](),V.event.triggered=void 0,a&&(r[l]=a)),t.result}},dispatch:function(e){e=V.event.fix(e);var t,n,r,i,o,s=[],a=M.call(arguments),u=(ce.get(this,"events")||{})[e.type]||[],l=V.event.special[e.type]||{};if(a[0]=e,e.delegateTarget=this,!l.preDispatch||!1!==l.preDispatch.call(this,e)){for(s=V.event.handlers.call(this,e,u),t=0;(i=s[t++])&&!e.isPropagationStopped();)for(e.currentTarget=i.elem,n=0;(o=i.handlers[n++])&&!e.isImmediatePropagationStopped();)e.namespace_re&&!e.namespace_re.test(o.namespace)||(e.handleObj=o,e.data=o.data,void 0!==(r=((V.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,a))&&!1===(e.result=r)&&(e.preventDefault(),e.stopPropagation()));return l.postDispatch&&l.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,r,i,o,s=[],a=t.delegateCount,u=e.target;if(a&&u.nodeType&&(!e.button||"click"!==e.type))for(;u!==this;u=u.parentNode||this)if(!0!==u.disabled||"click"!==e.type){for(r=[],n=0;n<a;n++)void 0===r[i=(o=t[n]).selector+" "]&&(r[i]=o.needsContext?V(i,this).index(u)>=0:V.find(i,this,null,[u]).length),r[i]&&r.push(o);r.length&&s.push({elem:u,handlers:r})}return a<t.length&&s.push({elem:this,handlers:t.slice(a)}),s},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,t){var n,r,i,o=t.button;return null==e.pageX&&null!=t.clientX&&(r=(n=e.target.ownerDocument||U).documentElement,i=n.body,e.pageX=t.clientX+(r&&r.scrollLeft||i&&i.scrollLeft||0)-(r&&r.clientLeft||i&&i.clientLeft||0),e.pageY=t.clientY+(r&&r.scrollTop||i&&i.scrollTop||0)-(r&&r.clientTop||i&&i.clientTop||0)),e.which||void 0===o||(e.which=1&o?1:2&o?3:4&o?2:0),e}},fix:function(e){if(e[V.expando])return e;var t,n,r,i=e.type,o=e,s=this.fixHooks[i];for(s||(this.fixHooks[i]=s=be.test(i)?this.mouseHooks:xe.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new V.Event(o),t=r.length;t--;)e[n=r[t]]=o[n];return e.target||(e.target=U),3===e.target.nodeType&&(e.target=e.target.parentNode),s.filter?s.filter(e,o):e},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==c()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===c()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&V.nodeName(this,"input"))return this.click(),!1},_default:function(e){return V.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=V.extend(new V.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?V.event.trigger(i,null,t):V.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},V.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)},V.Event=function(e,t){if(!(this instanceof V.Event))return new V.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?u:l):this.type=e,t&&V.extend(this,t),this.timeStamp=e&&e.timeStamp||V.now(),this[V.expando]=!0},V.Event.prototype={isDefaultPrevented:l,isPropagationStopped:l,isImmediatePropagationStopped:l,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=u,e&&e.preventDefault&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=u,e&&e.stopPropagation&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=u,e&&e.stopImmediatePropagation&&e.stopImmediatePropagation(),this.stopPropagation()}},V.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,t){V.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=e.relatedTarget,i=e.handleObj;return r&&(r===this||V.contains(this,r))||(e.type=i.origType,n=i.handler.apply(this,arguments),e.type=t),n}}}),X.focusinBubbles||V.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){V.event.simulate(t,e.target,V.event.fix(e),!0)};V.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=ce.access(r,t);i||r.addEventListener(e,n,!0),ce.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=ce.access(r,t)-1;i?ce.access(r,t,i):(r.removeEventListener(e,n,!0),ce.remove(r,t))}}}),V.fn.extend({on:function(e,t,n,r,i){var o,s;if("object"==typeof e){"string"!=typeof t&&(n=n||t,t=void 0);for(s in e)this.on(s,t,n,e[s],i);return this}if(null==n&&null==r?(r=t,n=t=void 0):null==r&&("string"==typeof t?(r=n,n=void 0):(r=n,n=t,t=void 0)),!1===r)r=l;else if(!r)return this;return 1===i&&(o=r,(r=function(e){return V().off(e),o.apply(this,arguments)}).guid=o.guid||(o.guid=V.guid++)),this.each(function(){V.event.add(this,e,r,n,t)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,V(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=l),this.each(function(){V.event.remove(this,e,n,t)})},trigger:function(e,t){return this.each(function(){V.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return V.event.trigger(e,t,n,!0)}});var Ce=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,Ne=/<([\w:]+)/,ke=/<|&#?\w+;/,Ee=/<(?:script|style|link)/i,Se=/checked\s*(?:[^=]|=\s*.checked.)/i,De=/^$|\/(?:java|ecma)script/i,je=/^true\/(.*)/,Ae=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,Le={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};Le.optgroup=Le.option,Le.tbody=Le.tfoot=Le.colgroup=Le.caption=Le.thead,Le.th=Le.td,V.extend({clone:function(e,t,n){var r,i,o,s,a=e.cloneNode(!0),u=V.contains(e.ownerDocument,e);if(!(X.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||V.isXMLDoc(e)))for(s=m(a),r=0,i=(o=m(e)).length;r<i;r++)v(o[r],s[r]);if(t)if(n)for(o=o||m(e),s=s||m(a),r=0,i=o.length;r<i;r++)g(o[r],s[r]);else g(e,a);return(s=m(a,"script")).length>0&&h(s,!u&&m(e,"script")),a},buildFragment:function(e,t,n,r){for(var i,o,s,a,u,l,c=t.createDocumentFragment(),f=[],p=0,d=e.length;p<d;p++)if((i=e[p])||0===i)if("object"===V.type(i))V.merge(f,i.nodeType?[i]:i);else if(ke.test(i)){for(o=o||c.appendChild(t.createElement("div")),s=(Ne.exec(i)||["",""])[1].toLowerCase(),a=Le[s]||Le._default,o.innerHTML=a[1]+i.replace(Ce,"<$1></$2>")+a[2],l=a[0];l--;)o=o.lastChild;V.merge(f,o.childNodes),(o=c.firstChild).textContent=""}else f.push(t.createTextNode(i));for(c.textContent="",p=0;i=f[p++];)if((!r||-1===V.inArray(i,r))&&(u=V.contains(i.ownerDocument,i),o=m(c.appendChild(i),"script"),u&&h(o),n))for(l=0;i=o[l++];)De.test(i.type||"")&&n.push(i);return c},cleanData:function(e){for(var t,n,r,i,o=V.event.special,s=0;void 0!==(n=e[s]);s++){if(V.acceptData(n)&&(i=n[ce.expando])&&(t=ce.cache[i])){if(t.events)for(r in t.events)o[r]?V.event.remove(n,r):V.removeEvent(n,r,t.handle);ce.cache[i]&&delete ce.cache[i]}delete fe.cache[n[fe.expando]]}}}),V.fn.extend({text:function(e){return le(this,function(e){return void 0===e?V.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){f(this,e).appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=f(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){for(var n,r=e?V.filter(e,this):this,i=0;null!=(n=r[i]);i++)t||1!==n.nodeType||V.cleanData(m(n)),n.parentNode&&(t&&V.contains(n.ownerDocument,n)&&h(m(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(V.cleanData(m(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return V.clone(this,e,t)})},html:function(e){return le(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ee.test(e)&&!Le[(Ne.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(Ce,"<$1></$2>");try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(V.cleanData(m(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=arguments[0];return this.domManip(arguments,function(t){e=this.parentNode,V.cleanData(m(this)),e&&e.replaceChild(t,this)}),e&&(e.length||e.nodeType)?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t){e=W.apply([],e);var n,r,i,o,s,a,u=0,l=this.length,c=this,f=l-1,h=e[0],g=V.isFunction(h);if(g||l>1&&"string"==typeof h&&!X.checkClone&&Se.test(h))return this.each(function(n){var r=c.eq(n);g&&(e[0]=h.call(this,n,r.html())),r.domManip(e,t)});if(l&&(n=V.buildFragment(e,this[0].ownerDocument,!1,this),r=n.firstChild,1===n.childNodes.length&&(n=r),r)){for(o=(i=V.map(m(n,"script"),p)).length;u<l;u++)s=n,u!==f&&(s=V.clone(s,!0,!0),o&&V.merge(i,m(s,"script"))),t.call(this[u],s,u);if(o)for(a=i[i.length-1].ownerDocument,V.map(i,d),u=0;u<o;u++)s=i[u],De.test(s.type||"")&&!ce.access(s,"globalEval")&&V.contains(a,s)&&(s.src?V._evalUrl&&V._evalUrl(s.src):V.globalEval(s.textContent.replace(Ae,"")))}return this}}),V.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){V.fn[e]=function(e){for(var n,r=[],i=V(e),o=i.length-1,s=0;s<=o;s++)n=s===o?this:this.clone(!0),V(i[s])[t](n),$.apply(r,n.get());return this.pushStack(r)}});var qe,He={},Oe=/^margin/,Fe=new RegExp("^("+he+")(?!px)[a-z%]+$","i"),Pe=function(t){return t.ownerDocument.defaultView.opener?t.ownerDocument.defaultView.getComputedStyle(t,null):e.getComputedStyle(t,null)};!function(){function t(){s.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",s.innerHTML="",i.appendChild(o);var t=e.getComputedStyle(s,null);n="1%"!==t.top,r="4px"===t.width,i.removeChild(o)}var n,r,i=U.documentElement,o=U.createElement("div"),s=U.createElement("div");s.style&&(s.style.backgroundClip="content-box",s.cloneNode(!0).style.backgroundClip="",X.clearCloneStyle="content-box"===s.style.backgroundClip,o.style.cssText="border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;position:absolute",o.appendChild(s),e.getComputedStyle&&V.extend(X,{pixelPosition:function(){return t(),n},boxSizingReliable:function(){return null==r&&t(),r},reliableMarginRight:function(){var t,n=s.appendChild(U.createElement("div"));return n.style.cssText=s.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",n.style.marginRight=n.style.width="0",s.style.width="1px",i.appendChild(o),t=!parseFloat(e.getComputedStyle(n,null).marginRight),i.removeChild(o),s.removeChild(n),t}}))}(),V.swap=function(e,t,n,r){var i,o,s={};for(o in t)s[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=s[o];return i};var Re=/^(none|table(?!-c[ea]).+)/,Me=new RegExp("^("+he+")(.*)$","i"),We=new RegExp("^([+-])=("+he+")","i"),$e={position:"absolute",visibility:"hidden",display:"block"},Ie={letterSpacing:"0",fontWeight:"400"},Be=["Webkit","O","Moz","ms"];V.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=b(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{float:"cssFloat"},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,s,a=V.camelCase(t),u=e.style;if(t=V.cssProps[a]||(V.cssProps[a]=T(u,a)),s=V.cssHooks[t]||V.cssHooks[a],void 0===n)return s&&"get"in s&&void 0!==(i=s.get(e,!1,r))?i:u[t];"string"==(o=typeof n)&&(i=We.exec(n))&&(n=(i[1]+1)*i[2]+parseFloat(V.css(e,t)),o="number"),null!=n&&n==n&&("number"!==o||V.cssNumber[a]||(n+="px"),X.clearCloneStyle||""!==n||0!==t.indexOf("background")||(u[t]="inherit"),s&&"set"in s&&void 0===(n=s.set(e,n,r))||(u[t]=n))}},css:function(e,t,n,r){var i,o,s,a=V.camelCase(t);return t=V.cssProps[a]||(V.cssProps[a]=T(e.style,a)),(s=V.cssHooks[t]||V.cssHooks[a])&&"get"in s&&(i=s.get(e,!0,n)),void 0===i&&(i=b(e,t,r)),"normal"===i&&t in Ie&&(i=Ie[t]),""===n||n?(o=parseFloat(i),!0===n||V.isNumeric(o)?o||0:i):i}}),V.each(["height","width"],function(e,t){V.cssHooks[t]={get:function(e,n,r){if(n)return Re.test(V.css(e,"display"))&&0===e.offsetWidth?V.swap(e,$e,function(){return k(e,t,r)}):k(e,t,r)},set:function(e,n,r){var i=r&&Pe(e);return C(0,n,r?N(e,t,r,"border-box"===V.css(e,"boxSizing",!1,i),i):0)}}}),V.cssHooks.marginRight=w(X.reliableMarginRight,function(e,t){if(t)return V.swap(e,{display:"inline-block"},b,[e,"marginRight"])}),V.each({margin:"",padding:"",border:"Width"},function(e,t){V.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+ge[r]+t]=o[r]||o[r-2]||o[0];return i}},Oe.test(e)||(V.cssHooks[e+t].set=C)}),V.fn.extend({css:function(e,t){return le(this,function(e,t,n){var r,i,o={},s=0;if(V.isArray(t)){for(r=Pe(e),i=t.length;s<i;s++)o[t[s]]=V.css(e,t[s],!1,r);return o}return void 0!==n?V.style(e,t,n):V.css(e,t)},e,t,arguments.length>1)},show:function(){return E(this,!0)},hide:function(){return E(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){me(this)?V(this).show():V(this).hide()})}}),V.Tween=S,(S.prototype={constructor:S,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(V.cssNumber[n]?"":"px")},cur:function(){var e=S.propHooks[this.prop];return e&&e.get?e.get(this):S.propHooks._default.get(this)},run:function(e){var t,n=S.propHooks[this.prop];return this.options.duration?this.pos=t=V.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):S.propHooks._default.set(this),this}}).init.prototype=S.prototype,(S.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=V.css(e.elem,e.prop,""))&&"auto"!==t?t:0:e.elem[e.prop]},set:function(e){V.fx.step[e.prop]?V.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[V.cssProps[e.prop]]||V.cssHooks[e.prop])?V.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}}).scrollTop=S.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},V.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},V.fx=S.prototype.init,V.fx.step={};var _e,ze,Xe=/^(?:toggle|show|hide)$/,Ue=new RegExp("^(?:([+-])=|)("+he+")([a-z%]*)$","i"),Ve=/queueHooks$/,Ye=[function(e,t,n){var r,i,o,s,a,u,l,c=this,f={},p=e.style,d=e.nodeType&&me(e),h=ce.get(e,"fxshow");n.queue||(null==(a=V._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,u=a.empty.fire,a.empty.fire=function(){a.unqueued||u()}),a.unqueued++,c.always(function(){c.always(function(){a.unqueued--,V.queue(e,"fx").length||a.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],"inline"===("none"===(l=V.css(e,"display"))?ce.get(e,"olddisplay")||x(e.nodeName):l)&&"none"===V.css(e,"float")&&(p.display="inline-block")),n.overflow&&(p.overflow="hidden",c.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],Xe.exec(i)){if(delete t[r],o=o||"toggle"===i,i===(d?"hide":"show")){if("show"!==i||!h||void 0===h[r])continue;d=!0}f[r]=h&&h[r]||V.style(e,r)}else l=void 0;if(V.isEmptyObject(f))"inline"===("none"===l?x(e.nodeName):l)&&(p.display=l);else{h?"hidden"in h&&(d=h.hidden):h=ce.access(e,"fxshow",{}),o&&(h.hidden=!d),d?V(e).show():c.done(function(){V(e).hide()}),c.done(function(){var t;ce.remove(e,"fxshow");for(t in f)V.style(e,t,f[t])});for(r in f)s=A(d?h[r]:0,r,c),r in h||(h[r]=s.start,d&&(s.end=s.start,s.start="width"===r||"height"===r?1:0))}}],Ge={"*":[function(e,t){var n=this.createTween(e,t),r=n.cur(),i=Ue.exec(t),o=i&&i[3]||(V.cssNumber[e]?"":"px"),s=(V.cssNumber[e]||"px"!==o&&+r)&&Ue.exec(V.css(n.elem,e)),a=1,u=20;if(s&&s[3]!==o){o=o||s[3],i=i||[],s=+r||1;do{s/=a=a||".5",V.style(n.elem,e,s+o)}while(a!==(a=n.cur()/r)&&1!==a&&--u)}return i&&(s=n.start=+s||+r||0,n.unit=o,n.end=i[1]?s+(i[1]+1)*i[2]:+i[2]),n}]};V.Animation=V.extend(L,{tweener:function(e,t){V.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");for(var n,r=0,i=e.length;r<i;r++)n=e[r],Ge[n]=Ge[n]||[],Ge[n].unshift(t)},prefilter:function(e,t){t?Ye.unshift(e):Ye.push(e)}}),V.speed=function(e,t,n){var r=e&&"object"==typeof e?V.extend({},e):{complete:n||!n&&t||V.isFunction(e)&&e,duration:e,easing:n&&t||t&&!V.isFunction(t)&&t};return r.duration=V.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in V.fx.speeds?V.fx.speeds[r.duration]:V.fx.speeds._default,null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){V.isFunction(r.old)&&r.old.call(this),r.queue&&V.dequeue(this,r.queue)},r},V.fn.extend({fadeTo:function(e,t,n,r){return this.filter(me).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=V.isEmptyObject(e),o=V.speed(t,n,r),s=function(){var t=L(this,V.extend({},e),o);(i||ce.get(this,"finish"))&&t.stop(!0)};return s.finish=s,i||!1===o.queue?this.each(s):this.queue(o.queue,s)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return"string"!=typeof e&&(n=t,t=e,e=void 0),t&&!1!==e&&this.queue(e||"fx",[]),this.each(function(){var t=!0,i=null!=e&&e+"queueHooks",o=V.timers,s=ce.get(this);if(i)s[i]&&s[i].stop&&r(s[i]);else for(i in s)s[i]&&s[i].stop&&Ve.test(i)&&r(s[i]);for(i=o.length;i--;)o[i].elem!==this||null!=e&&o[i].queue!==e||(o[i].anim.stop(n),t=!1,o.splice(i,1));!t&&n||V.dequeue(this,e)})},finish:function(e){return!1!==e&&(e=e||"fx"),this.each(function(){var t,n=ce.get(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=V.timers,s=r?r.length:0;for(n.finish=!0,V.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;t<s;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}}),V.each(["toggle","show","hide"],function(e,t){var n=V.fn[t];V.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(j(t,!0),e,r,i)}}),V.each({slideDown:j("show"),slideUp:j("hide"),slideToggle:j("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){V.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),V.timers=[],V.fx.tick=function(){var e,t=0,n=V.timers;for(_e=V.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||V.fx.stop(),_e=void 0},V.fx.timer=function(e){V.timers.push(e),e()?V.fx.start():V.timers.pop()},V.fx.interval=13,V.fx.start=function(){ze||(ze=setInterval(V.fx.tick,V.fx.interval))},V.fx.stop=function(){clearInterval(ze),ze=null},V.fx.speeds={slow:600,fast:200,_default:400},V.fn.delay=function(e,t){return e=V.fx?V.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},function(){var e=U.createElement("input"),t=U.createElement("select"),n=t.appendChild(U.createElement("option"));e.type="checkbox",X.checkOn=""!==e.value,X.optSelected=n.selected,t.disabled=!0,X.optDisabled=!n.disabled,(e=U.createElement("input")).value="t",e.type="radio",X.radioValue="t"===e.value}();var Qe,Je=V.expr.attrHandle;V.fn.extend({attr:function(e,t){return le(this,V.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){V.removeAttr(this,e)})}}),V.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(e&&3!==o&&8!==o&&2!==o)return typeof e.getAttribute===ye?V.prop(e,t,n):(1===o&&V.isXMLDoc(e)||(t=t.toLowerCase(),r=V.attrHooks[t]||(V.expr.match.bool.test(t)?Qe:void 0)),void 0===n?r&&"get"in r&&null!==(i=r.get(e,t))?i:null==(i=V.find.attr(e,t))?void 0:i:null!==n?r&&"set"in r&&void 0!==(i=r.set(e,n,t))?i:(e.setAttribute(t,n+""),n):void V.removeAttr(e,t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(se);if(o&&1===e.nodeType)for(;n=o[i++];)r=V.propFix[n]||n,V.expr.match.bool.test(n)&&(e[r]=!1),e.removeAttribute(n)},attrHooks:{type:{set:function(e,t){if(!X.radioValue&&"radio"===t&&V.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}}}),Qe={set:function(e,t,n){return!1===t?V.removeAttr(e,n):e.setAttribute(n,n),n}},V.each(V.expr.match.bool.source.match(/\w+/g),function(e,t){var n=Je[t]||V.find.attr;Je[t]=function(e,t,r){var i,o;return r||(o=Je[t],Je[t]=i,i=null!=n(e,t,r)?t.toLowerCase():null,Je[t]=o),i}});var Ke=/^(?:input|select|textarea|button)$/i;V.fn.extend({prop:function(e,t){return le(this,V.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[V.propFix[e]||e]})}}),V.extend({propFix:{for:"htmlFor",class:"className"},prop:function(e,t,n){var r,i,o=e.nodeType;if(e&&3!==o&&8!==o&&2!==o)return(1!==o||!V.isXMLDoc(e))&&(t=V.propFix[t]||t,i=V.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){return e.hasAttribute("tabindex")||Ke.test(e.nodeName)||e.href?e.tabIndex:-1}}}}),X.optSelected||(V.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null}}),V.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){V.propFix[this.toLowerCase()]=this});var Ze=/[\t\r\n\f]/g;V.fn.extend({addClass:function(e){var t,n,r,i,o,s,a="string"==typeof e&&e,u=0,l=this.length;if(V.isFunction(e))return this.each(function(t){V(this).addClass(e.call(this,t,this.className))});if(a)for(t=(e||"").match(se)||[];u<l;u++)if(n=this[u],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(Ze," "):" ")){for(o=0;i=t[o++];)r.indexOf(" "+i+" ")<0&&(r+=i+" ");s=V.trim(r),n.className!==s&&(n.className=s)}return this},removeClass:function(e){var t,n,r,i,o,s,a=0===arguments.length||"string"==typeof e&&e,u=0,l=this.length;if(V.isFunction(e))return this.each(function(t){V(this).removeClass(e.call(this,t,this.className))});if(a)for(t=(e||"").match(se)||[];u<l;u++)if(n=this[u],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(Ze," "):"")){for(o=0;i=t[o++];)for(;r.indexOf(" "+i+" ")>=0;)r=r.replace(" "+i+" "," ");s=e?V.trim(r):"",n.className!==s&&(n.className=s)}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):V.isFunction(e)?this.each(function(n){V(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n)for(var t,r=0,i=V(this),o=e.match(se)||[];t=o[r++];)i.hasClass(t)?i.removeClass(t):i.addClass(t);else n!==ye&&"boolean"!==n||(this.className&&ce.set(this,"__className__",this.className),this.className=this.className||!1===e?"":ce.get(this,"__className__")||"")})},hasClass:function(e){for(var t=" "+e+" ",n=0,r=this.length;n<r;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(Ze," ").indexOf(t)>=0)return!0;return!1}});var et=/\r/g;V.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=V.isFunction(e),this.each(function(n){var i;1===this.nodeType&&(null==(i=r?e.call(this,n,V(this).val()):e)?i="":"number"==typeof i?i+="":V.isArray(i)&&(i=V.map(i,function(e){return null==e?"":e+""})),(t=V.valHooks[this.type]||V.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))});if(i)return(t=V.valHooks[i.type]||V.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:"string"==typeof(n=i.value)?n.replace(et,""):null==n?"":n}}}),V.extend({valHooks:{option:{get:function(e){var t=V.find.attr(e,"value");return null!=t?t:V.trim(V.text(e))}},select:{get:function(e){for(var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||i<0,s=o?null:[],a=o?i+1:r.length,u=i<0?a:o?i:0;u<a;u++)if(((n=r[u]).selected||u===i)&&(X.optDisabled?!n.disabled:null===n.getAttribute("disabled"))&&(!n.parentNode.disabled||!V.nodeName(n.parentNode,"optgroup"))){if(t=V(n).val(),o)return t;s.push(t)}return s},set:function(e,t){for(var n,r,i=e.options,o=V.makeArray(t),s=i.length;s--;)((r=i[s]).selected=V.inArray(r.value,o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),V.each(["radio","checkbox"],function(){V.valHooks[this]={set:function(e,t){if(V.isArray(t))return e.checked=V.inArray(V(e).val(),t)>=0}},X.checkOn||(V.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),V.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){V.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),V.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}});var tt=V.now(),nt=/\?/;V.parseJSON=function(e){return JSON.parse(e+"")},V.parseXML=function(e){var t,n;if(!e||"string"!=typeof e)return null;try{n=new DOMParser,t=n.parseFromString(e,"text/xml")}catch(e){t=void 0}return t&&!t.getElementsByTagName("parsererror").length||V.error("Invalid XML: "+e),t};var rt=/#.*$/,it=/([?&])_=[^&]*/,ot=/^(.*?):[ \t]*([^\r\n]*)$/gm,st=/^(?:GET|HEAD)$/,at=/^\/\//,ut=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,lt={},ct={},ft="*/".concat("*"),pt=e.location.href,dt=ut.exec(pt.toLowerCase())||[];V.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:pt,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(dt[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":ft,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":V.parseJSON,"text xml":V.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?O(O(e,V.ajaxSettings),t):O(V.ajaxSettings,e)},ajaxPrefilter:q(lt),ajaxTransport:q(ct),ajax:function(e,t){function n(e,t,n,s){var u,c,v,y,b,T=t;2!==x&&(x=2,a&&clearTimeout(a),r=void 0,o=s||"",w.readyState=e>0?4:0,u=e>=200&&e<300||304===e,n&&(y=function(e,t,n){for(var r,i,o,s,a=e.contents,u=e.dataTypes;"*"===u[0];)u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in a)if(a[i]&&a[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}s||(s=i)}o=o||s}if(o)return o!==u[0]&&u.unshift(o),n[o]}(f,w,n)),y=function(e,t,n,r){var i,o,s,a,u,l={},c=e.dataTypes.slice();if(c[1])for(s in e.converters)l[s.toLowerCase()]=e.converters[s];for(o=c.shift();o;)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(s=l[u+" "+o]||l["* "+o]))for(i in l)if((a=i.split(" "))[1]===o&&(s=l[u+" "+a[0]]||l["* "+a[0]])){!0===s?s=l[i]:!0!==l[i]&&(o=a[0],c.unshift(a[1]));break}if(!0!==s)if(s&&e.throws)t=s(t);else try{t=s(t)}catch(e){return{state:"parsererror",error:s?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}(f,y,w,u),u?(f.ifModified&&((b=w.getResponseHeader("Last-Modified"))&&(V.lastModified[i]=b),(b=w.getResponseHeader("etag"))&&(V.etag[i]=b)),204===e||"HEAD"===f.type?T="nocontent":304===e?T="notmodified":(T=y.state,c=y.data,u=!(v=y.error))):(v=T,!e&&T||(T="error",e<0&&(e=0))),w.status=e,w.statusText=(t||T)+"",u?h.resolveWith(p,[c,T,w]):h.rejectWith(p,[w,T,v]),w.statusCode(m),m=void 0,l&&d.trigger(u?"ajaxSuccess":"ajaxError",[w,f,u?c:v]),g.fireWith(p,[w,T]),l&&(d.trigger("ajaxComplete",[w,f]),--V.active||V.event.trigger("ajaxStop")))}"object"==typeof e&&(t=e,e=void 0),t=t||{};var r,i,o,s,a,u,l,c,f=V.ajaxSetup({},t),p=f.context||f,d=f.context&&(p.nodeType||p.jquery)?V(p):V.event,h=V.Deferred(),g=V.Callbacks("once memory"),m=f.statusCode||{},v={},y={},x=0,b="canceled",w={readyState:0,getResponseHeader:function(e){var t;if(2===x){if(!s)for(s={};t=ot.exec(o);)s[t[1].toLowerCase()]=t[2];t=s[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===x?o:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return x||(e=y[n]=y[n]||e,v[e]=t),this},overrideMimeType:function(e){return x||(f.mimeType=e),this},statusCode:function(e){var t;if(e)if(x<2)for(t in e)m[t]=[m[t],e[t]];else w.always(e[w.status]);return this},abort:function(e){var t=e||b;return r&&r.abort(t),n(0,t),this}};if(h.promise(w).complete=g.add,w.success=w.done,w.error=w.fail,f.url=((e||f.url||pt)+"").replace(rt,"").replace(at,dt[1]+"//"),f.type=t.method||t.type||f.method||f.type,f.dataTypes=V.trim(f.dataType||"*").toLowerCase().match(se)||[""],null==f.crossDomain&&(u=ut.exec(f.url.toLowerCase()),f.crossDomain=!(!u||u[1]===dt[1]&&u[2]===dt[2]&&(u[3]||("http:"===u[1]?"80":"443"))===(dt[3]||("http:"===dt[1]?"80":"443")))),f.data&&f.processData&&"string"!=typeof f.data&&(f.data=V.param(f.data,f.traditional)),H(lt,f,t,w),2===x)return w;(l=V.event&&f.global)&&0==V.active++&&V.event.trigger("ajaxStart"),f.type=f.type.toUpperCase(),f.hasContent=!st.test(f.type),i=f.url,f.hasContent||(f.data&&(i=f.url+=(nt.test(i)?"&":"?")+f.data,delete f.data),!1===f.cache&&(f.url=it.test(i)?i.replace(it,"$1_="+tt++):i+(nt.test(i)?"&":"?")+"_="+tt++)),f.ifModified&&(V.lastModified[i]&&w.setRequestHeader("If-Modified-Since",V.lastModified[i]),V.etag[i]&&w.setRequestHeader("If-None-Match",V.etag[i])),(f.data&&f.hasContent&&!1!==f.contentType||t.contentType)&&w.setRequestHeader("Content-Type",f.contentType),w.setRequestHeader("Accept",f.dataTypes[0]&&f.accepts[f.dataTypes[0]]?f.accepts[f.dataTypes[0]]+("*"!==f.dataTypes[0]?", "+ft+"; q=0.01":""):f.accepts["*"]);for(c in f.headers)w.setRequestHeader(c,f.headers[c]);if(f.beforeSend&&(!1===f.beforeSend.call(p,w,f)||2===x))return w.abort();b="abort";for(c in{success:1,error:1,complete:1})w[c](f[c]);if(r=H(ct,f,t,w)){w.readyState=1,l&&d.trigger("ajaxSend",[w,f]),f.async&&f.timeout>0&&(a=setTimeout(function(){w.abort("timeout")},f.timeout));try{x=1,r.send(v,n)}catch(e){if(!(x<2))throw e;n(-1,e)}}else n(-1,"No Transport");return w},getJSON:function(e,t,n){return V.get(e,t,n,"json")},getScript:function(e,t){return V.get(e,void 0,t,"script")}}),V.each(["get","post"],function(e,t){V[t]=function(e,n,r,i){return V.isFunction(n)&&(i=i||r,r=n,n=void 0),V.ajax({url:e,type:t,dataType:i,data:n,success:r})}}),V._evalUrl=function(e){return V.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,throws:!0})},V.fn.extend({wrapAll:function(e){var t;return V.isFunction(e)?this.each(function(t){V(this).wrapAll(e.call(this,t))}):(this[0]&&(t=V(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e}).append(this)),this)},wrapInner:function(e){return V.isFunction(e)?this.each(function(t){V(this).wrapInner(e.call(this,t))}):this.each(function(){var t=V(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=V.isFunction(e);return this.each(function(n){V(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){V.nodeName(this,"body")||V(this).replaceWith(this.childNodes)}).end()}}),V.expr.filters.hidden=function(e){return e.offsetWidth<=0&&e.offsetHeight<=0},V.expr.filters.visible=function(e){return!V.expr.filters.hidden(e)};var ht=/%20/g,gt=/\[\]$/,mt=/\r?\n/g,vt=/^(?:submit|button|image|reset|file)$/i,yt=/^(?:input|select|textarea|keygen)/i;V.param=function(e,t){var n,r=[],i=function(e,t){t=V.isFunction(t)?t():null==t?"":t,r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(void 0===t&&(t=V.ajaxSettings&&V.ajaxSettings.traditional),V.isArray(e)||e.jquery&&!V.isPlainObject(e))V.each(e,function(){i(this.name,this.value)});else for(n in e)F(n,e[n],t,i);return r.join("&").replace(ht,"+")},V.fn.extend({serialize:function(){return V.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=V.prop(this,"elements");return e?V.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!V(this).is(":disabled")&&yt.test(this.nodeName)&&!vt.test(e)&&(this.checked||!ve.test(e))}).map(function(e,t){var n=V(this).val();return null==n?null:V.isArray(n)?V.map(n,function(e){return{name:t.name,value:e.replace(mt,"\r\n")}}):{name:t.name,value:n.replace(mt,"\r\n")}}).get()}}),V.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(e){}};var xt=0,bt={},wt={0:200,1223:204},Tt=V.ajaxSettings.xhr();e.attachEvent&&e.attachEvent("onunload",function(){for(var e in bt)bt[e]()}),X.cors=!!Tt&&"withCredentials"in Tt,X.ajax=Tt=!!Tt,V.ajaxTransport(function(e){var t;if(X.cors||Tt&&!e.crossDomain)return{send:function(n,r){var i,o=e.xhr(),s=++xt;if(o.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(i in e.xhrFields)o[i]=e.xhrFields[i];e.mimeType&&o.overrideMimeType&&o.overrideMimeType(e.mimeType),e.crossDomain||n["X-Requested-With"]||(n["X-Requested-With"]="XMLHttpRequest");for(i in n)o.setRequestHeader(i,n[i]);t=function(e){return function(){t&&(delete bt[s],t=o.onload=o.onerror=null,"abort"===e?o.abort():"error"===e?r(o.status,o.statusText):r(wt[o.status]||o.status,o.statusText,"string"==typeof o.responseText?{text:o.responseText}:void 0,o.getAllResponseHeaders()))}},o.onload=t(),o.onerror=t("error"),t=bt[s]=t("abort");try{o.send(e.hasContent&&e.data||null)}catch(e){if(t)throw e}},abort:function(){t&&t()}}}),V.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return V.globalEval(e),e}}}),V.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),V.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(r,i){t=V("<script>").prop({async:!0,charset:e.scriptCharset,src:e.url}).on("load error",n=function(e){t.remove(),n=null,e&&i("error"===e.type?404:200,e.type)}),U.head.appendChild(t[0])},abort:function(){n&&n()}}}});var Ct=[],Nt=/(=)\?(?=&|$)|\?\?/;V.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Ct.pop()||V.expando+"_"+tt++;return this[e]=!0,e}}),V.ajaxPrefilter("json jsonp",function(t,n,r){var i,o,s,a=!1!==t.jsonp&&(Nt.test(t.url)?"url":"string"==typeof t.data&&!(t.contentType||"").indexOf("application/x-www-form-urlencoded")&&Nt.test(t.data)&&"data");if(a||"jsonp"===t.dataTypes[0])return i=t.jsonpCallback=V.isFunction(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,a?t[a]=t[a].replace(Nt,"$1"+i):!1!==t.jsonp&&(t.url+=(nt.test(t.url)?"&":"?")+t.jsonp+"="+i),t.converters["script json"]=function(){return s||V.error(i+" was not called"),s[0]},t.dataTypes[0]="json",o=e[i],e[i]=function(){s=arguments},r.always(function(){e[i]=o,t[i]&&(t.jsonpCallback=n.jsonpCallback,Ct.push(i)),s&&V.isFunction(o)&&o(s[0]),s=o=void 0}),"script"}),V.parseHTML=function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||U;var r=ee.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=V.buildFragment([e],t,i),i&&i.length&&V(i).remove(),V.merge([],r.childNodes))};var kt=V.fn.load;V.fn.load=function(e,t,n){if("string"!=typeof e&&kt)return kt.apply(this,arguments);var r,i,o,s=this,a=e.indexOf(" ");return a>=0&&(r=V.trim(e.slice(a)),e=e.slice(0,a)),V.isFunction(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),s.length>0&&V.ajax({url:e,type:i,dataType:"html",data:t}).done(function(e){o=arguments,s.html(r?V("<div>").append(V.parseHTML(e)).find(r):e)}).complete(n&&function(e,t){s.each(n,o||[e.responseText,t,e])}),this},V.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){V.fn[t]=function(e){return this.on(t,e)}}),V.expr.filters.animated=function(e){return V.grep(V.timers,function(t){return e===t.elem}).length};var Et=e.document.documentElement;V.offset={setOffset:function(e,t,n){var r,i,o,s,a,u,l=V.css(e,"position"),c=V(e),f={};"static"===l&&(e.style.position="relative"),a=c.offset(),o=V.css(e,"top"),u=V.css(e,"left"),("absolute"===l||"fixed"===l)&&(o+u).indexOf("auto")>-1?(s=(r=c.position()).top,i=r.left):(s=parseFloat(o)||0,i=parseFloat(u)||0),V.isFunction(t)&&(t=t.call(e,n,a)),null!=t.top&&(f.top=t.top-a.top+s),null!=t.left&&(f.left=t.left-a.left+i),"using"in t?t.using.call(e,f):c.css(f)}},V.fn.extend({offset:function(e){if(arguments.length)return void 0===e?this:this.each(function(t){V.offset.setOffset(this,e,t)});var t,n,r=this[0],i={top:0,left:0},o=r&&r.ownerDocument;if(o)return t=o.documentElement,V.contains(t,r)?(typeof r.getBoundingClientRect!==ye&&(i=r.getBoundingClientRect()),n=P(o),{top:i.top+n.pageYOffset-t.clientTop,left:i.left+n.pageXOffset-t.clientLeft}):i},position:function(){if(this[0]){var e,t,n=this[0],r={top:0,left:0};return"fixed"===V.css(n,"position")?t=n.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),V.nodeName(e[0],"html")||(r=e.offset()),r.top+=V.css(e[0],"borderTopWidth",!0),r.left+=V.css(e[0],"borderLeftWidth",!0)),{top:t.top-r.top-V.css(n,"marginTop",!0),left:t.left-r.left-V.css(n,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent||Et;e&&!V.nodeName(e,"html")&&"static"===V.css(e,"position");)e=e.offsetParent;return e||Et})}}),V.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,n){var r="pageYOffset"===n;V.fn[t]=function(i){return le(this,function(t,i,o){var s=P(t);if(void 0===o)return s?s[n]:t[i];s?s.scrollTo(r?e.pageXOffset:o,r?o:e.pageYOffset):t[i]=o},t,i,arguments.length,null)}}),V.each(["top","left"],function(e,t){V.cssHooks[t]=w(X.pixelPosition,function(e,n){if(n)return n=b(e,t),Fe.test(n)?V(e).position()[t]+"px":n})}),V.each({Height:"height",Width:"width"},function(e,t){V.each({padding:"inner"+e,content:t,"":"outer"+e},function(n,r){V.fn[r]=function(r,i){var o=arguments.length&&(n||"boolean"!=typeof r),s=n||(!0===r||!0===i?"margin":"border");return le(this,function(t,n,r){var i;return V.isWindow(t)?t.document.documentElement["client"+e]:9===t.nodeType?(i=t.documentElement,Math.max(t.body["scroll"+e],i["scroll"+e],t.body["offset"+e],i["offset"+e],i["client"+e])):void 0===r?V.css(t,n,s):V.style(t,n,r,s)},t,o?r:void 0,o,null)}})}),V.fn.size=function(){return this.length},V.fn.andSelf=V.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return V});var St=e.jQuery,Dt=e.$;return V.noConflict=function(t){return e.$===V&&(e.$=Dt),t&&e.jQuery===V&&(e.jQuery=St),V},typeof t===ye&&(e.jQuery=e.$=V),V});
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/js/min/loader.min.js	Wed Nov 28 13:51:51 2018 +0000
@@ -0,0 +1,1 @@
+window.onload=function(){if(void 0===window.AudioContext&&void 0===window.webkitAudioContext){var e=document.getElementsByTagName("body")[0];e.innerHTML="<h1>Sorry! Your browser is not supported :(</h1><p>Your browser does not support the HTML5 Web Audio API. Please use one of the following supported browsers instead.<p>";var t=document.createElement("table");t.border="0",t.innerHTML="<tr><td>Chrome</td><td>v10 or newer</td></tr>",t.innerHTML+="<tr><td>Firefox</td><td>v25 or newer</td></tr><tr><td>Safari (OSX)</td><td> v6 or newer, OSX only</td></tr>",t.innerHTML+="<tr><td>Safari (iOS)</td><td>iOS 6.1 or newer</td></tr>",t.innerHTML+="<tr><td>Edge</td><td>12 or newer</td></tr>",e.appendChild(t)}else for(var r=document.getElementsByTagName("head")[0],d=["js/specification.js","js/core.js","js/loudness.js","js/xmllint.js","js/WAVE.js"],o=0;o<d.length;o++){var n=d[o],i=document.createElement("script");i.type="text/javascript",i.async=!1,i.defer=!0,i.src=n,r.appendChild(i)}};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/js/min/loudness.min.js	Wed Nov 28 13:51:51 2018 +0000
@@ -0,0 +1,1 @@
+function calculateLoudness(e,a,r,n){if("iPad"!=navigator.platform&&"iPhone"!=navigator.platform||e.ready(),void 0===e)return 0;void 0===a&&(a="I"),void 0===r&&(r=-23),void 0===n&&(n=new OfflineAudioContext(audioContext.destination.channelCount,Math.max(.4,e.buffer.duration)*audioContext.sampleRate,audioContext.sampleRate));var t=n.createBiquadFilter();t.type="highshelf",t.gain.value=4,t.frequency.value=1500;var o=n.createBiquadFilter();o.type="highpass",o.Q.value=.5,o.frequency.value=38;var l=n.createBufferSource();l.buffer=e.buffer,l.connect(t),t.connect(o),o.connect(n.destination),n.oncomplete=function(r){switch("object"==typeof r.renderedBuffer&&(r=r.renderedBuffer),a){case"I":var n=calculateMeanSquared(r,.4,.75),t=calculateLoudnessFromBlocks(n),o=loudnessOfBlocks(loudnessGate(t,n,loudnessOfBlocks(loudnessGate(t,n,-70))-10));e.buffer.lufs=o}e.ready()},l.start(0),n.startRendering()}function calculateMeanSquared(e,a,r){var n=Math.floor(e.sampleRate*a),t=Math.floor(n*(1-r)),o=Math.floor((e.length-n)/t);o=Math.max(o,1);for(var l=Array(e.numberOfChannels),u=0;u<e.numberOfChannels;u++){l[u]=new Float32Array(o);for(var f=e.getChannelData(u),i=0;i<o;i++){l[u][i]=0;for(var s=0;s<n;s++){var c=i*t+s;if(c>=e.length)break;var d=f[c];l[u][i]+=d*d}l[u][i]/=n}}return l}function calculateLoudnessFromBlocks(e){for(var a=e[0].length,r=e.length,n=Array(a),t=0;t<a;t++){for(var o=0,l=0;l<r;l++){var u=1;u>=3&&(u=1.41),o+=e[l][t]*u}n[t]=10*Math.log10(o)-.691}return n}function loudnessGate(e,a,r){var n,t,o=a[0].length,l=a.length,u=Array(l);for(t=0;t<l;t++)u[t]=[];for(n=0;n<o;n++)if(e[n]>r)for(t=0;t<l;t++)u[t].push(a[t][n]);return u}function loudnessOfBlocks(e){for(var a=e[0].length,r=e.length,n=0,t=0;t<a;t++){for(var o=0,l=0;l<r;l++){var u=1;u>=3&&(u=1.41),o+=e[l][t]*u}n+=o/=a}return n=10*Math.log10(n)-.691}var interval_cal_loudness_event=null;if(void 0===OfflineAudioContext)var OfflineAudioContext=webkitOfflineAudioContext;
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/js/min/specification.min.js	Wed Nov 28 13:51:51 2018 +0000
@@ -0,0 +1,1 @@
+function Specification(){function t(t){this.location=void 0,this.options=[],this.parent=void 0,this.showBackButton=!0,this.specification=t,this.addOption=function(){var t=new this.OptionNode(this.specification);return this.options.push(t),t},this.OptionNode=function(t){this.type=void 0,this.schema=void 0,this.id=void 0,this.name=void 0,this.mandatory=void 0,this.statement=void 0,this.boxsize=void 0,this.options=[],this.min=void 0,this.max=void 0,this.minWait=void 0,this.step=void 0,this.conditions=[],this.decode=function(t,e){this.schema=s.querySelector("[name="+e.nodeName+"]");var i,n=this.schema.querySelectorAll("attribute");for(i in n){if(!0===isNaN(Number(i)))break;var r=n[i].getAttribute("name")||n[i].getAttribute("ref"),o=e.getAttribute(r);null!==(o=a(o,n[i]))&&(this[r]=o)}if("surveyentry"==e.nodeName){if(console.log("NOTE - Use of <surveyelement> is now deprecated. Whilst these will still work, newer nodes and tighter error checking will not be enforced"),console.log("Please use the newer, type specifc nodes"),!this.type)throw"Type not specified"}else this.type=e.nodeName.split("survey")[1];if(this.statement=e.getElementsByTagName("statement")[0].textContent,"checkbox"==this.type||"radio"==this.type){var h=e.getElementsByTagName("option");if(null===h.length)console.log("Malformed"+e.nodeName+"entry"),this.statement="Malformed"+e.nodeName+"entry",this.type="statement";else for(this.options=[],i=0;i<h.length;i++)this.options.push({name:h[i].getAttribute("name"),text:h[i].textContent})}else if("slider"==this.type){this.leftText="",this.rightText="";var l=e.getElementsByTagName("minText"),m=e.getElementsByTagName("maxText");l.length>0&&(this.leftText=l[0].textContent),m.length>0&&(this.rightText=m[0].textContent)}var c=e.getElementsByTagName("conditional");for(i=0;i<c.length;i++){var d=c[i],u={check:d.getAttribute("check"),value:d.getAttribute("value"),jumpToOnPass:d.getAttribute("jumpToOnPass"),jumpToOnFail:d.getAttribute("jumpToOnFail")};this.conditions.push(u)}},this.exportXML=function(t){var e=t.createElement("survey"+this.type),i=t.createElement("statement");switch(i.textContent=this.statement,e.appendChild(i),e.id=this.id,void 0!==this.name&&e.setAttribute("name",this.name),void 0!==this.mandatory&&e.setAttribute("mandatory",this.mandatory),e.id=this.id,void 0!==this.name&&e.setAttribute("name",this.name),this.type){case"checkbox":void 0!==this.min?e.setAttribute("min",this.min):e.setAttribute("min","0"),void 0!==this.max?e.setAttribute("max",this.max):e.setAttribute("max","undefined");case"radio":for(var s=0;s<this.options.length;s++){var n=this.options[s],a=t.createElement("option");a.setAttribute("name",n.name),a.textContent=n.text,e.appendChild(a)}break;case"number":void 0!==this.min&&e.setAttribute("min",this.min),void 0!==this.max&&e.setAttribute("max",this.max);break;case"question":void 0!==this.boxsize&&e.setAttribute("boxsize",this.boxsize),void 0!==this.mandatory&&e.setAttribute("mandatory",this.mandatory);break;case"video":void 0!==this.mandatory&&e.setAttribute("mandatory",this.mandatory);case"youtube":void 0!==this.url&&e.setAttribute("url",this.url);break;case"slider":if(e.setAttribute("min",this.min),e.setAttribute("max",this.max),this.leftText){var r=t.createElement("minText");r.textContent=this.leftText,e.appendChild(r)}if(this.rightText){var o=t.createElement("maxText");o.textContent=this.rightText,e.appendChild(o)}}return this.conditions.forEach(function(i){var s=t.createElement("conditional");s.setAttribute("check",i.check),s.setAttribute("value",i.value),s.setAttribute("jumpToOnPass",i.jumpToOnPass),s.setAttribute("jumpToOnFail",i.jumpToOnFail),e.appendChild(s)}),e}},this.decode=function(t,e){this.schema=s.querySelector("[name=survey]"),this.parent=t,this.location=e.getAttribute("location"),"before"==this.location?this.location="pre":"after"==this.location&&(this.location="post"),this.showBackButton=e.getAttribute("showBackButton"),"false"==this.showBackButton?this.showBackButton=!1:this.showBackButton=!0;for(var i=e.firstElementChild;i;){var n=new this.OptionNode(this.specification);n.decode(t,i),this.options.push(n),i=i.nextElementSibling}0===this.options.length&&(console.log("Empty survey node"),console.log(this))},this.encode=function(t){var e=t.createElement("survey");e.setAttribute("location",this.location),e.setAttribute("showBackButton",this.showBackButton);for(var i=0;i<this.options.length;i++)e.appendChild(this.options[i].exportXML(t));return e}}function e(t){this.title=void 0,this.name=void 0,this.image=void 0,this.options=[],this.scales=[],this.schema=void 0,this.decode=function(t,e){this.schema=s.querySelectorAll("[name=interface]")[1],this.name=e.getAttribute("name");var i=e.getElementsByTagName("title");1==i.length&&(this.title=i[0].textContent);var n,r,o=e.getElementsByTagName("interfaceoption"),h=this.schema.querySelector("[name=interfaceoption]").querySelectorAll("attribute");for(n=0;n<o.length;n++){var l=o[n],m={};for(r=0;r<h.length;r++){var c=h[r].getAttribute("name")||h[r].getAttribute("ref"),d=l.getAttribute(c);null!==(d=a(d,h[r]))&&(m[c]=d)}"check"==m.type&&l.firstElementChild&&(m.errorMessage=l.firstElementChild.textContent),this.options.push(m)}var u=e.getElementsByTagName("image");1==u.length&&(this.image=u[0].getAttribute("src"));var p=e.getElementsByTagName("scales");if(1==p.length){var g=(p=p[0]).querySelectorAll("scalelabel");for(n=0;n<g.length;n++)this.scales.push({text:g[n].textContent,position:Number(g[n].getAttribute("position"))})}},this.encode=function(t){var e=t.createElement("interface");if("string"==typeof this.name&&this.name.length>0&&e.setAttribute("name",this.name),"string"==typeof this.title){var i=t.createElement("title");i.textContent=this.title,e.appendChild(i)}if(this.options.forEach(function(i){var s=t.createElement("interfaceoption");if(s.setAttribute("type",i.type),s.setAttribute("name",i.name),"check"==i.type&&void 0!==i.errorMessage){var n=t.createElement("errormessage");n.textContent=i.errorMessage,s.appendChild(n)}e.appendChild(s)}),"string"==typeof this.image&&0!==this.image.length){var s=t.createElement("image");s.setAttribute("src",this.image),e.appendChild(s)}if(0!==this.scales.length){var n=t.createElement("scales");this.scales.forEach(function(e){var i=t.createElement("scalelabel");i.setAttribute("position",e.position),i.textContent=e.text,n.appendChild(i)}),e.appendChild(n)}return e}}function i(i){function n(t){this.id=void 0,this.name=void 0,this.type=void 0,this.statement=void 0,this.mandatory=void 0,this.schema=s.querySelector("[name=commentquestion]"),this.decode=function(t,e){switch(this.id=e.id,this.name=e.getAttribute("name"),this.mandatory="true"==e.getAttribute("mandatory"),null===this.name&&(this.name=void 0),e.nodeName){case"commentradio":this.type="radio",this.options=[];break;case"commentcheckbox":this.type="checkbox",this.options=[];break;case"commentslider":this.type="slider",this.min=void 0,this.max=void 0,this.step=void 0;break;case"commentquestion":this.type="question";break;default:throw"Unknown comment type "+e.nodeName}if(this.statement=e.getElementsByTagName("statement")[0].textContent,"radio"==this.type||"checkbox"==this.type)for(var i=e.getElementsByTagName("option"),s=0;s<i.length;s++){var n=i[s];this.options.push({name:n.getAttribute("name"),text:n.textContent})}"slider"==this.type&&(this.min=Number(e.getAttribute("min")),this.max=Number(e.getAttribute("max")),this.step=Number(e.getAttribute("step")),void 0===this.step&&(this.step=1),this.value=Number(e.getAttribute("value")),void 0===this.value&&(this.value=this.min),this.leftText=e.getElementsByTagName("minText"),this.leftText&&this.leftText.length>0?this.leftText=this.leftText[0].textContent:this.leftText="",this.rightText=e.getElementsByTagName("maxText"),this.rightText&&this.rightText.length>0?this.rightText=this.rightText[0].textContent:this.rightText="")},this.encode=function(t){var e;switch(this.type){case"radio":e=t.createElement("commentradio");break;case"checkbox":e=t.createElement("commentcheckbox");break;case"slider":e=t.createElement("commentslider");break;case"question":e=t.createElement("commentquestion");break;default:throw"Unknown type "+this.type}e.id=this.id,e.setAttribute("mandatory",this.mandatory),e.setAttribute("type",this.type),void 0!==this.name&&e.setAttribute("name",this.name);var i=t.createElement("statement");if(i.textContent=this.statement,e.appendChild(i),"radio"!=this.type&&"checkbox"!=this.type||this.options.forEach(function(i){var s=t.createElement("option");s.setAttribute("name",i.name),s.textContent=i.text,e.appendChild(s)}),"slider"==this.type){if(e.setAttribute("min",this.min),e.setAttribute("max",this.max),1!==this.step&&e.setAttribute("step",this.step),this.value!==this.min&&e.setAttribute("value",this.value),this.leftText.length>0){var s=t.createElement("minText");s.textContent=this.leftText,e.appendChild(s)}if(this.rightText.length>0){var n=t.createElement("maxText");n.textContent=this.rightText,e.appendChild(n)}}return e}}function r(t){this.url=void 0,this.id=void 0,this.name=void 0,this.parent=void 0,this.type=void 0,this.marker=void 0,this.enforce=!1,this.gain=0,this.label=void 0,this.startTime=void 0,this.stopTime=void 0,this.sampleRate=void 0,this.image=void 0,this.minNumberPlays=void 0,this.maxNumberPlays=void 0,this.alternatives=[],this.schema=s.querySelector("[name=audioelement]"),this.parent=void 0,this.decode=function(t,e){this.parent=t;for(var i=this.schema.querySelectorAll("attribute"),s=0;s<i.length;s++){var n=i[s].getAttribute("name")||i[s].getAttribute("ref"),r=e.getAttribute(n);null!==(r=a(r,i[s]))&&(this[n]=r)}for(var o=e.firstElementChild;o;)"alternative"==o.nodeName&&this.alternatives.push({url:o.getAttribute("url"),sampleRate:o.getAttribute("sampleRate")}),o=o.nextElementSibling},this.encode=function(t){for(var e=t.createElement("audioelement"),i=this.schema.querySelectorAll("attribute"),s=0;s<i.length;s++){var n=i[s].getAttribute("name");null===n&&(n=i[s].getAttribute("ref")),void 0===this[n]&&"required"!=i[s].getAttribute("use")||e.setAttribute(n,this[n])}return this.alternatives.forEach(function(i){var s=t.createElement("alternative");s.setAttribute("url",i.url),s.setAttribute("sampleRate",i.sampleRate),e.appendChild(s)}),e}}this.presentedId=void 0,this.id=void 0,this.title=void 0,this.hostURL=void 0,this.randomiseOrder=void 0,this.loop=void 0,this.outsideReference=void 0,this.loudness=void 0,this.label=void 0,this.labelStart=void 0,this.preTest=new t(i),this.postTest=new t(i),this.preTest.location="pre",this.postTest.location="post",this.interfaces=[],this.playOne=void 0,this.restrictMovement=void 0,this.position=void 0,this.commentBoxPrefix="Comment on track",this.minNumberPlays=void 0,this.maxNumberPlays=void 0,this.randomiseAxisOrder=void 0,this.audioElements=[],this.commentQuestions=[],this.schema=s.querySelector("[name=page]"),this.specification=i,this.parent=void 0,this.addInterface=function(){var t=new e(i);return this.interfaces.push(t),t},this.addCommentQuestion=function(){var t=new n(i);return this.commentQuestions.push(t),t},this.addAudioElement=function(){var t=new r(i);return this.audioElements.push(t),t},this.decode=function(t,i){this.parent=t;var s,o,h=this.schema.querySelectorAll("attribute");for(s=0;s<h.length;s++){var l=h[s].getAttribute("name")||h[s].getAttribute("ref"),m=i.getAttribute(l);null!==(m=a(m,h[s]))&&(this[l]=m)}var c=i.getElementsByTagName("title");0!==c.length&&c[0].parentElement==i&&(this.title=c[0].textContent);var d=i.getElementsByTagName("commentboxprefix");0!==d.length&&d[0].parentElement==i&&(this.commentBoxPrefix=d[0].textContent);var u=i.getElementsByTagName("interface");for(s=0;s<u.length;s++)(o=new e(this.specification)).decode(this,u[s],t.schema.querySelectorAll("[name=interface]")[1]),this.interfaces.push(o);var p=i.getElementsByTagName("survey"),g=t.schema.querySelector("[name=survey]");for(s=0;s<p.length;s++){var v=p[s].getAttribute("location");"pre"==v||"before"==v?0!==this.preTest.options.length?this.errors.push("Already a pre/before test survey defined! Ignoring second!!"):this.preTest.decode(t,p[s],g):"post"!=v&&"after"!=v||(0!==this.postTest.options.length?this.errors.push("Already a post/after test survey defined! Ignoring second!!"):this.postTest.decode(t,p[s],g))}var f=i.getElementsByTagName("audioelement");for(s=0;s<f.length;s++){var b=new r(this.specification);b.decode(this,f[s]),this.audioElements.push(b)}var x=i.getElementsByTagName("commentquestions");if(0!==x.length)for(var y=(x=x[0]).firstElementChild;y;)(o=new n(this.specification)).decode(t,y),this.commentQuestions.push(o),y=y.nextElementSibling},this.encode=function(t){var e,i=t.createElement("page"),s=this.schema.querySelectorAll("attribute");for(e=0;e<s.length;e++){var n=s[e].getAttribute("name");null===n&&(n=s[e].getAttribute("ref")),void 0===this[n]&&"required"!=s[e].getAttribute("use")||i.setAttribute(n,this[n])}var a=t.createElement("commentboxprefix");for(a.textContent=this.commentBoxPrefix,i.appendChild(a),e=0;e<this.interfaces.length;e++)i.appendChild(this.interfaces[e].encode(t));for(e=0;e<this.audioElements.length;e++)i.appendChild(this.audioElements[e].encode(t));if(this.commentQuestions.length>0){var r=t.createElement("commentquestions");for(e=0;e<this.commentQuestions.length;e++)r.appendChild(this.commentQuestions[e].encode(t));i.appendChild(r)}return i.appendChild(this.preTest.encode(t)),i.appendChild(this.postTest.encode(t)),i}}var s,n;this.interface=void 0,this.projectReturn=void 0,this.returnURL=void 0,this.randomiseOrder=void 0,this.poolSize=void 0,this.loudness=void 0,this.sampleRate=void 0,this.calibration=void 0,this.crossFade=void 0,this.preSilence=void 0,this.postSilence=void 0,this.playOne=void 0,this.minNumberPlays=void 0,this.maxNumberPlays=void 0,this.randomiseAxisOrder=void 0,this.metrics=new function(){this.enabled=[],this.decode=function(t,e){var i=e.getElementsByTagName("metricenable");for(var s in i){if(!0===isNaN(Number(s)))break;this.enabled.push(i[s].textContent)}},this.encode=function(t){var e=t.createElement("metric");for(var i in this.enabled){if(!0===isNaN(Number(i)))break;var s=t.createElement("metricenable");s.textContent=this.enabled[i],e.appendChild(s)}return e}},this.preTest=new t(this),this.postTest=new t(this),this.preTest.location="pre",this.postTest.location="post",this.pages=[],this.interfaces=new e(this),this.errors=[],this.exitText="Thank you.",this.createNewPage=function(){var t=new i(this);return this.pages.push(t),t};var a=function(t,e){null===e.getAttribute("name")&&void 0!==e.getAttribute("ref")&&(e=s.querySelector("[name="+e.getAttribute("ref")+"]"));var i=e.getAttribute("default");null===t&&(t=i);var n=e.getAttribute("type");if("string"==typeof n)n=n.substr(3);else{var a=e.querySelectorAll("restriction,enumeration");n=a.length>0&&"string"==typeof(n=a[0].getAttribute("base"))?n.substr(3):"string"}if(null===t)return t;switch(n){case"boolean":t="true"==t;break;case"negativeInteger":case"positiveInteger":case"nonNegativeInteger":case"nonPositiveInteger":case"integer":case"decimal":case"short":t=Number(t);break;default:t=String(t)}return t};this.processSchema=function(t){if(void 0===s){n=t;var e=new DOMParser;s=e.parseFromString(n,"text/xml"),Object.defineProperties(this,{schema:{value:s},schemaString:{value:n}})}},this.getSchema=function(){return s},this.getSchemaString=function(){return n},this.decode=function(t){s=this.schema,this.errors=[],this.projectXML=t.childNodes[0];var e,n=t.getElementsByTagName("setup")[0],r=s.querySelector("[name=setup]").querySelectorAll("attribute");for(e=0;e<r.length;e++){var o=r[e].getAttribute("name")||r[e].getAttribute("ref"),h=n.getAttribute(o);null!==(h=a(h,r[e]))&&(this[o]=h)}var l=n.getElementsByTagName("exitText");1==l.length&&(this.exitText=l[0].textContent),this.metrics.decode(this,n.getElementsByTagName("metric")[0]);var m=n.getElementsByTagName("survey");for(e=0;e<m.length;e++){switch(m[e].getAttribute("location")){case"pre":case"before":this.preTest.decode(this,m[e]);break;case"post":case"after":this.postTest.decode(this,m[e])}}var c=n.getElementsByTagName("interface");c.length>1&&this.errors.push("Only one <interface> node in the <setup> node allowed! Others except first ingnored!"),0!==c.length&&(c=c[0],this.interfaces.decode(this,c,this.schema.querySelectorAll("[name=interface]")[1]));var d=t.getElementsByTagName("page"),u=this.schema.querySelector("[name=page]");for(e=0;e<d.length;e++){var p=new i(this);p.decode(this,d[e],u),this.pages.push(p);for(var g=0;g<p.repeatCount;g++){var v=new i(this);v.decode(this,d[e],u),v.id+="-repeat-"+g,this.pages.push(v)}}},this.encode=function(){var t=document.implementation.createDocument(null,"waet"),e=t.firstChild;e.setAttribute("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance"),e.setAttribute("xsi:noNamespaceSchemaLocation","test-schema.xsd");for(var i=t.createElement("setup"),n=s.querySelector("[name=setup]").querySelectorAll("attribute"),a=0;a<n.length;a++){var r=n[a].getAttribute("name");null===r&&(r=n[a].getAttribute("ref")),void 0===this[r]&&"required"!=n[a].getAttribute("use")||i.setAttribute(r,this[r])}if(e.appendChild(i),null!==this.exitText){var o=t.createElement("exitText");o.textContent=this.exitText,i.appendChild(o)}return i.appendChild(this.preTest.encode(t)),i.appendChild(this.postTest.encode(t)),i.appendChild(this.metrics.encode(t)),i.appendChild(this.interfaces.encode(t)),this.pages.forEach(function(i){e.appendChild(i.encode(t))}),t}}
\ No newline at end of file
--- a/js/specification.js	Wed Nov 28 13:50:22 2018 +0000
+++ b/js/specification.js	Wed Nov 28 13:51:51 2018 +0000
@@ -12,13 +12,13 @@
     this.poolSize = undefined;
     this.loudness = undefined;
     this.sampleRate = undefined;
-    this.calibration = undefined;
     this.crossFade = undefined;
     this.preSilence = undefined;
     this.postSilence = undefined;
     this.playOne = undefined;
     this.minNumberPlays = undefined;
     this.maxNumberPlays = undefined;
+    this.randomiseAxisOrder = undefined;
 
     // nodes
     this.metrics = new metricNode();
@@ -130,7 +130,9 @@
             if (projectAttr !== null) {
                 this[attributeName] = projectAttr;
             }
-
+        }
+        if (projectXML.getElementsByTagName('calibration').length > 0) {
+            this.calibration.decode(this, projectXML.getElementsByTagName('calibration')[0]);
         }
 
         var exitTextNode = setupNode.getElementsByTagName('exitText');
@@ -208,6 +210,7 @@
             exitTextNode.textContent = this.exitText;
             setup.appendChild(exitTextNode);
         }
+        setup.appendChild(this.calibration.encode(RootDocument));
         setup.appendChild(this.preTest.encode(RootDocument));
         setup.appendChild(this.postTest.encode(RootDocument));
         setup.appendChild(this.metrics.encode(RootDocument));
@@ -218,10 +221,88 @@
         return RootDocument;
     };
 
+    this.calibration = (function () {
+        var frequencies = false,
+            levels = false,
+            channels = false,
+            schema = undefined;
+        var Calibration = {};
+        Object.defineProperties(Calibration, {
+            "parent": {
+                "value": this
+            },
+            "schema": {
+                "get": function () {
+                    return schema;
+                },
+                "set": function (t) {
+                    if (schema === undefined) {
+                        schema = t;
+                    } else {
+                        throw ("Cannot set readonly");
+                    }
+                }
+            },
+            "checkFrequencies": {
+                "get": function () {
+                    return frequencies;
+                },
+                "set": function (t) {
+                    frequencies = (t === true);
+                }
+            },
+            "checkLevels": {
+                "get": function () {
+                    return levels;
+                },
+                "set": function (t) {
+                    levels = (t === true);
+                }
+            },
+            "checkChannels": {
+                "get": function () {
+                    return channels;
+                },
+                "set": function (t) {
+                    channels = (t === true);
+                }
+            },
+            "encode": {
+                "value": function (doc) {
+                    var node = doc.createElement("calibration");
+                    node.setAttribute("checkFrequencies", frequencies);
+                    node.setAttribute("checkLevels", levels);
+                    node.setAttribute("checkChannels", channels);
+                    return node;
+                }
+            },
+            "decode": {
+                "value": function (parent, xml) {
+                    this.schema = schemaRoot.querySelector("[name=calibration]");
+                    var attributeMap = this.schema.querySelectorAll('attribute'),
+                        i;
+                    for (i in attributeMap) {
+                        if (isNaN(Number(i)) === true) {
+                            break;
+                        }
+                        var attributeName = attributeMap[i].getAttribute('name') || attributeMap[i].getAttribute('ref');
+                        var projectAttr = xml.getAttribute(attributeName);
+                        projectAttr = processAttribute(projectAttr, attributeMap[i]);
+                        if (projectAttr !== null) {
+                            this[attributeName] = projectAttr;
+                        }
+                    }
+                }
+            }
+        });
+        return Calibration;
+    })();
+
     function surveyNode(specification) {
         this.location = undefined;
         this.options = [];
         this.parent = undefined;
+        this.showBackButton = true;
         this.specification = specification;
 
         this.addOption = function () {
@@ -409,6 +490,12 @@
             } else if (this.location == 'after') {
                 this.location = 'post';
             }
+            this.showBackButton = xml.getAttribute("showBackButton");
+            if (this.showBackButton == "false") {
+                this.showBackButton = false;
+            } else {
+                this.showBackButton = true;
+            }
             var child = xml.firstElementChild;
             while (child) {
                 var node = new this.OptionNode(this.specification);
@@ -424,6 +511,7 @@
         this.encode = function (doc) {
             var node = doc.createElement('survey');
             node.setAttribute('location', this.location);
+            node.setAttribute('showBackButton', this.showBackButton);
             for (var i = 0; i < this.options.length; i++) {
                 node.appendChild(this.options[i].exportXML(doc));
             }
@@ -572,6 +660,7 @@
         this.commentBoxPrefix = "Comment on track";
         this.minNumberPlays = undefined;
         this.maxNumberPlays = undefined;
+        this.randomiseAxisOrder = undefined;
         this.audioElements = [];
         this.commentQuestions = [];
         this.schema = schemaRoot.querySelector("[name=page]");
@@ -696,8 +785,12 @@
                 AHNode.appendChild(this.audioElements[i].encode(root));
             }
             // Create <CommentQuestion>
-            for (i = 0; i < this.commentQuestions.length; i++) {
-                AHNode.appendChild(this.commentQuestions[i].encode(root));
+            if (this.commentQuestions.length > 0) {
+                var node = root.createElement("commentquestions");
+                for (i = 0; i < this.commentQuestions.length; i++) {
+                    node.appendChild(this.commentQuestions[i].encode(root));
+                }
+                AHNode.appendChild(node);
             }
 
             AHNode.appendChild(this.preTest.encode(root));
@@ -710,10 +803,12 @@
             this.name = undefined;
             this.type = undefined;
             this.statement = undefined;
+            this.mandatory = undefined;
             this.schema = schemaRoot.querySelector('[name=commentquestion]');
             this.decode = function (parent, xml) {
                 this.id = xml.id;
                 this.name = xml.getAttribute('name');
+                this.mandatory = xml.getAttribute("mandatory") == "true";
                 if (this.name === null) {
                     this.name = undefined;
                 }
@@ -794,6 +889,7 @@
                         throw ("Unknown type " + this.type);
                 }
                 node.id = this.id;
+                node.setAttribute("mandatory", this.mandatory);
                 node.setAttribute("type", this.type);
                 if (this.name !== undefined) {
                     node.setAttribute("name", this.name);
--- a/php/pseudo.php	Wed Nov 28 13:50:22 2018 +0000
+++ b/php/pseudo.php	Wed Nov 28 13:51:51 2018 +0000
@@ -1,24 +1,37 @@
 <?php
-    header('Access-Control-Allow-Origin: *');
-	header("Content-type: text/xml");
-    header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
-    header("Cache-Control: post-check=0, pre-check=0", false);
-    header("Pragma: no-cache");
-    $files = glob('../saves/' . '*.xml');
-    $numsaves = 0;
-    if ( $files !== false )
-    {
-        $numsaves = count( $files );
-    }
+header('Access-Control-Allow-Origin: *');
+header("Content-type: text/xml");
+header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
+header("Cache-Control: post-check=0, pre-check=0", false);
+header("Pragma: no-cache");
 
-    $files = glob('../tests/' . '*.xml');
-    $numtests = 0;
-    if ( $numtests !== false )
-    {
-        $numtests = count( $files );
-    }
+if (isset($_GET["prefix"]) == FALSE) {
+    $prefix = "";
+} else {
+    $prefix = $_GET["prefix"];
+}
 
-    $testID = ($numsaves % $numtests);
+if (isset($_GET["dir"]) == FALSE) {
+    $dir = "";
+} else {
+    $dir = $_GET["dir"];
+}
 
-	readfile($files[$testID]);
+$files = glob('../saves/' . $prefix . '*.xml');
+$numsaves = 0;
+if ( $files !== false )
+{
+    $numsaves = count( $files );
+}
+
+$files = glob('../tests/' . $dir . '*.xml');
+$numtests = 0;
+
+if ( $numtests !== false )
+{
+    $numtests = count( $files );
+}
+
+$testID = ($numsaves % $numtests);
+readfile($files[$testID]);
 ?>
--- a/php/requestKey.php	Wed Nov 28 13:50:22 2018 +0000
+++ b/php/requestKey.php	Wed Nov 28 13:51:51 2018 +0000
@@ -11,6 +11,10 @@
     return $randomString;
 }
 
+if (!file_exists("../saves")) {
+    mkdir("../saves");
+}
+
 // Request a new session key from the server
 header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
 header("Cache-Control: post-check=0, pre-check=0", false);
--- a/php/save.php	Wed Nov 28 13:50:22 2018 +0000
+++ b/php/save.php	Wed Nov 28 13:51:51 2018 +0000
@@ -33,7 +33,17 @@
 }
 $postText = file_get_contents('php://input');
 $file_key = $_GET['key'];
-$filename = '../saves/'.$saveFilenamePrefix.$file_key.".xml";
+
+$update = false;
+if (isset($_GET["update"])) {
+    $update = $_GET["update"] == "update";
+}
+
+if ($update) {
+    $filename = '../saves/update-'.$saveFilenamePrefix.$file_key.".xml";
+} else {
+    $filename = '../saves/'.$saveFilenamePrefix.$file_key.".xml";
+}
 
 if (!file_exists($filename)) {
     die('<response state="error"><message>Could not find save</message></response>');
@@ -132,4 +142,8 @@
 // Return XML confirmation data
 $xml = '<response state="OK"><message>OK</message><file bytes="'.$wbytes.'">"'.$filename.'"</file></response>';
 echo $xml;
+
+if (!$update) {
+    unlink('../saves/update-'.$saveFilenamePrefix.$file_key.".xml");
+}
 ?>
--- a/python/generate_report.py	Wed Nov 28 13:50:22 2018 +0000
+++ b/python/generate_report.py	Wed Nov 28 13:51:51 2018 +0000
@@ -232,17 +232,18 @@
             
             # number of comments (interesting if comments not mandatory)
             for audioelement in audioelements:
-                response = audioelement.find("./comment/response")
-                was_played = audioelement.find("./metric/metricresult/[@name='elementFlagListenedTo']")
-                was_moved = audioelement.find("./metric/metricresult/[@name='elementFlagMoved']")
-                if response is not None and response.text is not None and len(response.text) > 1: 
-                    number_of_comments += 1
-                else: 
-                    number_of_missing_comments += 1
-                if was_played is not None and was_played.text == 'false': 
-                    not_played.append(audioelement.get('name'))
-                if was_moved is not None and was_moved.text == 'false': 
-                    not_moved.append(audioelement.get('name'))
+                if audioelement.get("type") != "outside-reference":
+                    response = audioelement.find("./comment/response")
+                    was_played = audioelement.find("./metric/metricresult/[@name='elementFlagListenedTo']")
+                    was_moved = audioelement.find("./metric/metricresult/[@name='elementFlagMoved']")
+                    if response is not None and response.text is not None and len(response.text) > 1: 
+                        number_of_comments += 1
+                    else: 
+                        number_of_missing_comments += 1
+                    if was_played is not None and was_played.text == 'false': 
+                        not_played.append(audioelement.get('name'))
+                    if was_moved is not None and was_moved.text == 'false': 
+                        not_moved.append(audioelement.get('name'))
             
             # update global counters
             total_empty_comments += number_of_missing_comments
--- a/python/pythonServer.py	Wed Nov 28 13:50:22 2018 +0000
+++ b/python/pythonServer.py	Wed Nov 28 13:51:51 2018 +0000
@@ -13,6 +13,7 @@
 import copy
 import string
 import random
+import errno
 
 if sys.version_info[0] == 2:
     # Version 2.x
@@ -28,6 +29,12 @@
 scriptdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # script directory
 os.chdir(scriptdir) # does this work?
 
+try:
+    os.makedirs("../saves")
+except OSError as e:
+    if e.errno != errno.EEXIST:
+        raise
+
 PSEUDO_PATH = '../tests/'
 pseudo_files = []
 pseudo_index = 0
@@ -147,12 +154,15 @@
     global curSaveIndex
     options = self.path.rsplit('?')
     options = options[1].rsplit('&')
+    update = False
     for option in options:
         optionPair = option.rsplit('=')
         if optionPair[0] == "key":
             key = optionPair[1]
         elif optionPair[0] == "saveFilenamePrefix":
             prefix = optionPair[1]
+        elif optionPair[0] == "state":
+            update = optionPair[1] == "update"
     if key == None:
         self.send_response(404)
         return
@@ -162,6 +172,8 @@
     postVars = self.rfile.read(varLen)
     print("Saving file key "+key)
     filename = prefix+'-'+key+'.xml'
+    if update:
+        filename = "update-"+filename
     file = open('../saves/'+filename,'wb')
     file.write(postVars)
     file.close()
@@ -182,6 +194,9 @@
         self.wfile.write(bytes(reply, "utf-8"))
     curSaveIndex += 1
     curFileName = 'test-'+str(curSaveIndex)+'.xml'
+    if update == False:
+        if(os.path.isfile("../saves/update-"+filename)):
+            os.remove("../saves/update-"+filename)
     
 def testSave(self):
     self.send_response(200)
@@ -210,7 +225,6 @@
         self.wfile.write(message)
     elif sys.version_info[0] == 3:
         self.wfile.write(bytes(message, "utf-8"))
-    
 
 def poolXML(s):
     pool = ET.parse('../tests/pool.xml')
--- a/python/score_plot.py	Wed Nov 28 13:50:22 2018 +0000
+++ b/python/score_plot.py	Wed Nov 28 13:51:51 2018 +0000
@@ -20,6 +20,7 @@
 # initialise plot types (false by default) and options
 enable_boxplot    = False     # show box plot
 enable_confidence = False     # show confidence interval
+enable_combined   = False     # show combined plots
 confidence        = 0.90      # confidence value (for confidence interval plot)
 enable_individual = False     # show all individual ratings
 show_individual   = []        # show specific individuals (empty: show all individuals found)
@@ -69,7 +70,8 @@
             #TODO add confidence value input
         elif arg == 'ind' or arg == 'individual' or arg == '-i':
             enable_individual = True     # show all individual ratings
-            
+        elif arg == 'comb' or arg == 'combined' or arg == '-m':
+            enable_combined   = True     # show combined plot with error bars  
         # PLOT OPTIONS
         elif arg == 'leg' or arg == 'legend' or arg == '-l':
             if not enable_individual: 
@@ -91,7 +93,8 @@
              rating_folder = arg
 
 # at least one plot type should be selected: box plot by default
-if not enable_boxplot and not enable_confidence and not enable_individual:
+if not enable_boxplot and not enable_confidence and not enable_individual and not enable_combined:
+    print("Default to enable boxplot")
     enable_boxplot = True
 
 # check if folder_name exists
@@ -113,6 +116,7 @@
 
 
 # CODE
+combined = {}
 
 # get every csv file in folder
 for file in os.listdir(rating_folder):
@@ -209,25 +213,44 @@
                                        numpoints=1 # remove extra marker
                                        )
                     increment += 1 # increase counter
+        if enable_combined:
+            print(page_name)
+            combined[page_name] = {"labels": headerrow, "r": ratings}
 
-        # TITLE, AXIS LABELS AND LIMITS
-        plt.title(page_name)
-        plt.xlabel('Fragment')
-        plt.xlim(0, len(headerrow)+1) # only show relevant region, leave space left & right)
-        plt.xticks(range(1, len(headerrow)+1), headerrow, rotation=90) # show fragment names
-        plt.ylabel('Rating')
-        plt.ylim(0,1)
-        
-        
-
-        # SHOW PLOT
-        #plt.show()
-        #exit()
+        if enable_boxplot or enable_confidence or enable_individual:
+            # TITLE, AXIS LABELS AND LIMITS
+            plt.title(page_name)
+            plt.xlabel('Fragment')
+            plt.xlim(0, len(headerrow)+1) # only show relevant region, leave space left & right)
+            plt.xticks(range(1, len(headerrow)+1), headerrow, rotation=90) # show fragment names
+            plt.ylabel('Rating')
+            plt.ylim(0,1)
+            # SHOW PLOT
+            #plt.show()
+            #exit()
     
-        # SAVE PLOT
-        # automatically 
-        plot_type = ("-box" if enable_boxplot else "") + \
+            # SAVE PLOT
+            # automatically 
+            plot_type = ("-box" if enable_boxplot else "") + \
                     ("-conf" if enable_confidence else "") + \
                     ("-ind" if enable_individual else "")
-        plt.savefig(rating_folder+page_name+plot_type+".pdf", bbox_inches='tight')
-        plt.close()
+            plt.savefig(rating_folder+page_name+plot_type+".pdf", bbox_inches='tight')
+            plt.close()
+
+if enable_combined:
+    plt.figure()
+    pages = combined.keys()
+    numcombined = len(pages)
+    spacing = 1.0/float(numcombined+2)
+    for i in range(0,numcombined):
+        page_name = pages[i]
+        N = len(combined[page_name]['labels'])
+        mean = np.percentile(combined[page_name]['r'], 50, 0)
+        p25 = np.percentile(combined[page_name]['r'], 25, 0)
+        p75 = np.percentile(combined[page_name]['r'], 75, 0)
+        yerr = [mean-p25, p75-mean]
+        print(yerr)
+        plt.errorbar(np.arange(0,N)+(spacing*(i+1)), combined[page_name]['r'].mean(0), yerr=yerr, fmt='x', elinewidth=0.5)
+    ax = plt.gca()
+    ax.grid(which='major', axis='x', linewidth=2, color='k')
+    plt.show()
--- a/test.html	Wed Nov 28 13:50:22 2018 +0000
+++ b/test.html	Wed Nov 28 13:51:51 2018 +0000
@@ -14,12 +14,14 @@
     <meta name="author" content="" />
 
     <!-- Load up the default core JS and CSS files-->
+    <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
     <link rel='stylesheet' type='text/css' href='css/core.css'>
     <!-- Use jQuery hosted from Google CDN -->
     <!--<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>-->
     <script type="text/javascript" src="js/showdown.min.js"></script>
     <script type="text/javascript" src="js/jquery-2.1.4.js"></script>
     <script type="text/javascript" src="js/loader.js"></script>
+    <script type="text/javascript" src="js/bootstrap.min.js"></script>
 </head>
 
 <body>
@@ -37,7 +39,7 @@
         <button id="popup-previous" class="popupButton">Back</button>
     </div>
     <div class="testHalt" style="visibility: hidden"></div>
-    <div id="footer"><a target="_blank" href="https://github.com/BrechtDeMan/WebAudioEvaluationTool">Web Audio Evaluation Toolbox (v1.2.2)</a></div>
+    <div id="footer"><a target="_blank" href="https://github.com/BrechtDeMan/WebAudioEvaluationTool">Web Audio Evaluation Toolbox (v1.2.3)</a></div>
 </body>
 
 </html>
--- a/test_create.html	Wed Nov 28 13:50:22 2018 +0000
+++ b/test_create.html	Wed Nov 28 13:51:51 2018 +0000
@@ -19,7 +19,7 @@
     <div class="container">
         <div id="pageRoot">
             <h1>Web Audio Evaluation Tool</h1>
-            <h3>Test Creator <span class="label label-primary">v1.2.2</span></h3>
+            <h3>Test Creator <span class="label label-primary">v1.2.3</span></h3>
         </div>
         <button type="button" class="btn btn-info" ng-click="validate()">Validate</button>
         <button type="button" class="btn btn-success" ng-click="exportXML()" ng-disabled="validated == false">Export XML</button>
@@ -74,10 +74,6 @@
                     <span>Fixed Sampling Rate: </span>
                     <input type="number" ng-model="specification.sampleRate" min="0" placeholder="{{placeholder('sampleRate')}}" />
                 </div>
-                <div class="attribute" data-container="body" data-toggle="popover" data-placement="bottom" data-trigger="hover" data-content="Show a 'method of adjustment' audio calibration before testing.">
-                    <span>Pre-Test audio calibration: </span>
-                    <input type="checkbox" ng-model="specification.calibration" />
-                </div>
                 <div class="attribute" data-container="body" data-toggle="popover" data-placement="bottom" data-trigger="hover" data-content="Default cross-fade time when switching between elements. Can be over-ridden on each page">
                     <span>Global Cross-fade time: </span>
                     <input type="number" ng-model="specification.crossFade" min="0" step="0.1" placeholder="{{placeholder('crossFade')}}" />
@@ -107,6 +103,23 @@
                 <h2>Test Completed Message</h2>
                 <textarea ng-model="specification.exitText" data-container="body" data-toggle="popover" data-placement="bottom" data-trigger="hover" data-content="Once the test is completed, you can show a message to the user. Markdown syntax is supported for formatting."></textarea>
             </div>
+            <div class="node">
+                <h2>Pre-Test Calibrations</h2>
+                <div class="attributes">
+                    <div class="attribute" data-container="body" data-toggle="popover" data-placement="bottom" data-trigger="hover" data-content="Perform a frequency listening response">
+                        <span>Check Frequency Response</span>
+                        <input type="checkbox" value="testTimer" ng-model="specification.calibration.checkFrequencies" />
+                    </div>
+                    <div class="attribute" data-container="body" data-toggle="popover" data-placement="bottom" data-trigger="hover" data-content="Set the output levels">
+                        <span>Check Levels</span>
+                        <input type="checkbox" value="testTimer" ng-model="specification.calibration.checkLevels" />
+                    </div>
+                    <div class="attribute" data-container="body" data-toggle="popover" data-placement="bottom" data-trigger="hover" data-content="Check L/R configuration">
+                        <span>Check Channels</span>
+                        <input type="checkbox" value="testTimer" ng-model="specification.calibration.checkChannels" />
+                    </div>
+                </div>
+            </div>
             <div id="metricsNode" class="node">
                 <h3>Session Metrics</h3>
                 <div class="attributes">
@@ -142,6 +155,12 @@
             </div>
             <div id="globalpresurvey" class="node" ng-controller="survey" ng-init="survey = specification.preTest">
                 <h2>Pre Test Survey</h2>
+                <div class="attributes">
+                    <div class="attribute" data-container="body" data-toggle="popover" data-placement="bottom" data-trigger="hover" data-content="Allow users to go both back and forward in the test">
+                        <span>Show back button: </span>
+                        <input type="checkbox" ng-model="survey.showBackButton" />
+                    </div>
+                </div>
                 <button type="button" class="btn btn-success" ng-click="addSurveyEntry()">Add Entry</button>
                 <div class="node surveyentry" ng-repeat="opt in survey.options" ng-controller="surveyOption">
                     <h3>Survey Entry</h3>
@@ -273,6 +292,12 @@
             </div>
             <div id="globalpostsurvey" class="node" ng-controller="survey" ng-init="survey = specification.postTest">
                 <h2>Post Test Survey</h2>
+                <div class="attributes">
+                    <div class="attribute" data-container="body" data-toggle="popover" data-placement="bottom" data-trigger="hover" data-content="Allow users to go both back and forward in the test">
+                        <span>Show back button: </span>
+                        <input type="checkbox" ng-model="survey.showBackButton" />
+                    </div>
+                </div>
                 <button type="button" class="btn btn-success" ng-click="addSurveyEntry()">Add Entry</button>
                 <div class="node surveyentry" ng-repeat="opt in survey.options" ng-controller="surveyOption">
                     <h3>Survey Entry</h3>
@@ -446,6 +471,10 @@
                             <span>Show Fragment Comments: </span>
                             <input type="checkbox" ng-click="enableInterfaceOption($event)" />
                         </div>
+                        <div class="attribute" name="ticks" type="show" data-container="body" data-toggle="popover" data-placement="bottom" data-trigger="hover" data-content="Show tick marks for each scale label">
+                            <span>Show Scale Ticks: </span>
+                            <input type="checkbox" ng-click="enableInterfaceOption($event)" />
+                        </div>
                     </div>
                 </div>
             </div>
@@ -453,7 +482,7 @@
         <div style="text-align: center;">
             <button type="button" class="btn btn-success" ng-click="addPage()">Add Page</button>
         </div>
-        <div class="node pageNode" ng-controller="page" ng-repeat="page in specification.pages">
+        <div class="node pageNode" ng-controller="page" ng-repeat="page in specification.pages" dropzone>
             <h2>Page</h2>
             <button type="button" class="btn btn-danger" ng-click="removePage(page)">Remove Page</button>
             <div class="attributes">
@@ -550,6 +579,12 @@
             </div>
             <div class="node" ng-controller="survey" ng-init="survey = page.preTest">
                 <h2>Pre Page Survey</h2>
+                <div class="attributes">
+                    <div class="attribute" data-container="body" data-toggle="popover" data-placement="bottom" data-trigger="hover" data-content="Allow users to go both back and forward in the test">
+                        <span>Show back button: </span>
+                        <input type="checkbox" ng-model="survey.showBackButton" />
+                    </div>
+                </div>
                 <button type="button" class="btn btn-success" ng-click="addSurveyEntry()">Add Entry</button>
                 <div class="node surveyentry" ng-repeat="opt in survey.options" ng-controller="surveyOption">
                     <h3>Survey Entry</h3>
@@ -681,6 +716,12 @@
             </div>
             <div class="node" ng-controller="survey" ng-init="survey = page.postTest">
                 <h2>Post Page Survey</h2>
+                <div class="attributes">
+                    <div class="attribute" data-container="body" data-toggle="popover" data-placement="bottom" data-trigger="hover" data-content="Allow users to go both back and forward in the test">
+                        <span>Show back button: </span>
+                        <input type="checkbox" ng-model="survey.showBackButton" />
+                    </div>
+                </div>
                 <button type="button" class="btn btn-success" ng-click="addSurveyEntry()">Add Entry</button>
                 <div class="node surveyentry" ng-repeat="opt in survey.options" ng-controller="surveyOption">
                     <h3>Survey Entry</h3>
@@ -856,6 +897,10 @@
                             <span>Show Fragment Comments: </span>
                             <input type="checkbox" ng-click="enableInterfaceOption($event)" />
                         </div>
+                        <div class="attribute" name="ticks" type="show" data-container="body" data-toggle="popover" data-placement="bottom" data-trigger="hover" data-content="Show tick marks for each scale label">
+                            <span>Show Scale Ticks: </span>
+                            <input type="checkbox" ng-click="enableInterfaceOption($event)" />
+                        </div>
                     </div>
                 </div>
                 <div class="node">
@@ -909,6 +954,15 @@
                     <button type="button" class="btn btn-danger" ng-click="removeCommentQuestion(cq)">Remove Comment Question</button>
                     <div class="attributes">
                         <div class="attribute">
+                            <span>Type:</span>
+                            <select ng-model="cq.type">
+                                <option value="question">Question</option>
+                                <option value="checkbox">Checkbox</option>
+                                <option value="radio">Radio</option>
+                                <option value="slider">Slider</option>
+                            </select>
+                        </div>
+                        <div class="attribute">
                             <span>Unique ID:</span>
                             <input type="text" ng-model="cq.id" required/>
                         </div>
@@ -916,6 +970,10 @@
                             <span>Common Name:</span>
                             <input type="text" ng-model="cq.name" />
                         </div>
+                        <div class="attribute">
+                            <span>Mandatory:</span>
+                            <input type="checkbox" ng-model="cq.mandatory" />
+                        </div>
                         <div class="attribute" ng-show="cq.type == 'slider'">
                             <span>Minimum:</span>
                             <input type="number" ng-model="cq.min" />
@@ -1044,46 +1102,69 @@
             </div>
         </div>
     </div>
-    <div id="popupHolder" ng-show="popupVisible">
-        <div ng-controller="introduction" class="popup" ng-show="popupVisible">
-            <div class="popupTitle" ng-switch="state">
-                <span ng-switch-when="0">Test Creator <span class="label label-primary">v1.2.2</span></span>
-                <span ng-switch-when="1">Create New Test</span>
-            </div>
-            <div class="popupContent container-fluid" ng-switch="state">
-                <div ng-switch-when="0">
-                    <h3>Please wait while assets load...</h3>
+    <div class="modal fade bs-example-modal-lg" id="popupHolder" tabindex="-1" role="dialog" ng-controller="introduction">
+        <div class="modal-dialog modal-lg" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <h3>Test Creator</h3>
+                    <h3 class="label label-primary">v1.2.3</h3>
                 </div>
-                <div ng-switch-when="1">
-                    <div>
-                        <span>Welcome to the WAET test creator tool. This will allow you to create a new test from scratch to suit your testing needs. If you wish to update a test file, please drag and drop the XML document into the area below for processing, otherwise press 'Next' to start a new test. This tool generates files for the WAET 1.2.2 version.</span>
+                <div class="modal-body" ng-switch="state">
+                    <div ng-switch-when="0">
+                        <div>
+                            <h3>Please wait while assets load...</h3>
+                        </div>
                     </div>
-                    <div>
-                        <input type="file" id="files" ng-model="files" onchange="handleFiles(event)" />
+                    <div ng-switch-when="1">
+                        <div>
+                            <span>Welcome to the WAET test creator tool. This will allow you to create a new test from scratch to suit your testing needs. If you wish to update a test file, please drag and drop the XML document into the area below for processing, otherwise press 'Next' to start a new test. This tool generates files for the WAET 1.2.3 version.</span>
+                        </div>
+                        <div>
+                            <input type="file" id="files" ng-model="files" onchange="handleFiles(event)" />
+                        </div>
+                    </div>
+                    <div ng-switch-when="2">
+                        <div>
+                            <span>Please select the interface you would like to use below. Selecting an interface will give a brief description of the interface type.</span>
+                        </div>
+                        <div class="row">
+                            <div class="col-md-6">
+                                <div class="new-test" ng-repeat="i in testSpecifications.interfaces" ng-mouseover="mouseover(i.name)" ng-click="select(i.name)">
+                                    <label style="cursor:pointer">
+                                        <input type="radio" name="new-test" value="{{i.name}}" id="i.name" style="cursor:pointer" /> {{i.name}}
+                                    </label>
+                                </div>
+                            </div>
+                            <div class="col-md-6">
+                                <span>{{description}}</span>
+                            </div>
+                        </div>
+                    </div>
+                    <div ng-switch-when="3" dropzone>
+                        <div>
+                            <h4>Audio Files</h4>
+                            <p>{{selected}} is a pairwise test with only two fragments per page. To make it easy to add a lot of fragments (and therefore pages) you can automatically drop your fragments onto here, set a name for each and we will populate your page elements for you!</p>
+                        </div>
+                        <table class="table table-bordered">
+                            <tr>
+                                <td>Filename</td>
+                                <td>Name</td>
+                            </tr>
+                            <tr ng-repeat="elem in audioFragments">
+                                <td>{{elem.fname}}</td>
+                                <td>
+                                    <input type="text" ng-model="elem.name" required />
+                                </td>
+                            </tr>
+                        </table>
                     </div>
                 </div>
-                <div ng-switch-when="2">
-                    <div>
-                        <span>Please select the interface you would like to use below. Selecting an interface will give a brief description of the interface type.</span>
-                    </div>
-                    <div class="row">
-                        <div class="col-md-6" style="overflow-y: scroll;height: 333px;">
-                            <div class="new-test" ng-repeat="i in testSpecifications.interfaces" ng-mouseover="mouseover(i.name)" ng-click="select(i.name)">
-                                <label style="cursor:pointer">
-                                    <input type="radio" name="new-test" value="{{i.name}}" id="i.name" style="cursor:pointer" /> {{i.name}}
-                                </label>
-                            </div>
-                        </div>
-                        <div class="col-md-6">
-                            <span>{{description}}</span>
-                        </div>
-                    </div>
+                <div class="modal-footer">
+                    <button id="popupBack" type="button" class="btn btn-default" ng-show="state>0" ng-click="back()">Back</button>
+                    <button id="popupNext" type="button" class="btn btn-warning" ng-show="state>1" ng-click="skip()">Skip</button>
+                    <button id="popupNext" type="button" class="btn btn-default" ng-click="next()">Next</button>
                 </div>
             </div>
-            <div class="popupButtons">
-                <button id="popupBack" type="button" class="btn btn-default" ng-show="state>0" ng-click="back()">Back</button>
-                <button id="popupNext" type="button" class="btn btn-default" ng-click="next()">Next</button>
-            </div>
         </div>
     </div>
     <div id="screenblank" ng-show="popupVisible"></div>
--- a/test_create/style.css	Wed Nov 28 13:50:22 2018 +0000
+++ b/test_create/style.css	Wed Nov 28 13:51:51 2018 +0000
@@ -8,12 +8,6 @@
     background-color: rgba(0, 0, 0, 0.75);
 }
 #popupHolder {
-    text-align: center;
-    width: 100%;
-    height: 100%;
-    position: fixed;
-    top: 0px;
-    z-index: 2;
 }
 .popup {
     position: relative;
--- a/test_create/test_core.js	Wed Nov 28 13:50:22 2018 +0000
+++ b/test_create/test_core.js	Wed Nov 28 13:51:51 2018 +0000
@@ -31,11 +31,48 @@
 
 var AngularInterface = angular.module("creator", []);
 
+AngularInterface.directive("dropzone", function () {
+    return {
+        restrict: "A",
+        link: function (scope, elem) {
+            elem.bind('dragover', function (evt) {
+                evt.stopPropagation();
+                evt.preventDefault();
+            });
+            elem.bind('dragend', function (evt) {
+                console.log(evt);
+                evt.stopPropagation();
+                evt.preventDefault();
+            });
+            elem.bind('drop', function (event) {
+                var evt = event.originalEvent;
+                console.log(evt);
+                evt.stopPropagation();
+                evt.preventDefault();
+
+                var files = evt.dataTransfer.files;
+                for (var i = 0, f; f = files[i]; i++) {
+                    var reader = new FileReader();
+                    reader.readAsArrayBuffer(f);
+
+                    reader.onload = (function (theFile) {
+                        return function (e) {
+                            scope.ondrop(theFile.name);
+                            scope.$apply();
+                        };
+                    })(f);
+                }
+            });
+        }
+    }
+});
+
 var specification = new Specification();
 
 window.onload = function () {
     // Get the test interface specifications
     toggleDropdowns();
+    $("#popupHolder").modal("show");
 };
 
 function toggleDropdowns() {
@@ -51,7 +88,6 @@
 }
 
 AngularInterface.controller("view", ['$scope', '$element', '$window', function ($s, $e, $w) {
-    $s.popupVisible = true;
     $s.testSpecifications = {};
 
     (function () {
@@ -75,12 +111,6 @@
         });
     })();
 
-    $s.showPopup = function () {
-        $s.popupVisible = true;
-    };
-    $s.hidePopup = function () {
-        $s.popupVisible = false;
-    };
     $s.globalSchema = undefined;
     get("xml/test-schema.xsd").then(function (text) {
         specification.processSchema(text);
@@ -178,13 +208,39 @@
 AngularInterface.controller("introduction", ['$scope', '$element', '$window', function ($s, $e, $w) {
     $s.state = 0;
     $s.selected = undefined;
+    $s.close = function () {
+        $($e[0]).modal('hide');
+    }
     $s.next = function () {
+        if (($s.state === 1 && $s.file) || $s.state === 2) {
+            $s.initialise($s.selected);
+            if ($s.selected != "AB" && $s.selected != "ABX") {
+                $s.close();
+            }
+        } else if ($s.state === 3 && $s.audioFragments.length > 0) {
+            // Populate the audio pages by creating a pairwise set of pairs
+            $s.populatePages((function (a) {
+                var b = [];
+                a.forEach(function (e1, i1, a) {
+                    a.forEach(function (e2, i2) {
+                        var entry = [e1, e2];
+                        if (i1 > i2) {
+                            b.push(entry);
+                        }
+                    });
+                });
+                return b;
+            })($s.audioFragments));
+            $s.close();
+        } else if ($s.state > 3) {
+            $s.close();
+        }
         $s.state++;
-        if ($s.state > 2 || $s.file) {
-            $s.hidePopup();
-            $s.initialise($s.selected);
-        }
+        console.log("Modal state " + $s.state);
     };
+    $s.skip = function () {
+        $s.close();
+    }
     $s.back = function () {
         $s.state--;
     };
@@ -221,9 +277,9 @@
         }
     };
     $s.select = function (name) {
-            $s.selected = name;
-        }
-        // Get the test interface specifications
+        $s.selected = name;
+    };
+    // Get the test interface specifications
     $s.file = undefined;
     $s.description = "";
 
@@ -241,6 +297,28 @@
         };
         r.readAsText($s.file);
     };
+
+    $s.audioFragments = [];
+    $s.ondrop = function (filename) {
+        $s.audioFragments.push({
+            fname: filename,
+            name: "fragment-" + String($s.audioFragments.length)
+        });
+    };
+
+    $s.populatePages = function (structures) {
+        structures.forEach(function (p, i) {
+            var page = $w.specification.createNewPage();
+            page.id = "page-" + String(i);
+            p.forEach(function (a) {
+                var fragment = page.addAudioElement();
+                fragment.name = a.name;
+                fragment.id = a.name + "-p" + String(i);
+                fragment.url = a.fname;
+            });
+            page.addInterface();
+        });
+    }
 }]);
 
 AngularInterface.controller("setup", ['$scope', '$element', '$window', function ($s, $e, $w) {
@@ -502,6 +580,10 @@
     $s.addAudioElement = function () {
         $s.page.addAudioElement();
     };
+    $s.ondrop = function (filename) {
+        var fragment = $s.page.addAudioElement();
+        fragment.url = filename;
+    };
     $s.removeAudioElement = function (element) {
         var index = $s.page.audioElements.findIndex(function (a) {
             return a == element;
--- a/tests/examples/AB_example.xml	Wed Nov 28 13:50:22 2018 +0000
+++ b/tests/examples/AB_example.xml	Wed Nov 28 13:51:51 2018 +0000
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
     <waet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test-schema.xsd">
-        <setup interface="AB" projectReturn="save.php" randomiseOrder="false" poolSize="2" loudness="-23" playOne="true">
+        <setup interface="AB" projectReturn="save.php" returnURL="http://localhost:8000/test.html?url=tests/examples/AB_example.xml" randomiseOrder="false" poolSize="2" loudness="-23" playOne="true">
             <survey location="before">
                 <surveyquestion id="sessionId" mandatory="true">
                     <statement>Please enter your name.</statement>
@@ -45,10 +45,6 @@
                 <metricenable>elementListenTracker</metricenable>
             </metric>
             <interface>
-                <interfaceoption type="check" name="fragmentMoved" />
-                <interfaceoption type="check" name="scalerange" min="25" max="75">
-                    <errormessage>Test Error Message</errormessage>
-                </interfaceoption>
                 <interfaceoption type="show" name='playhead' />
                 <interfaceoption type="show" name="page-count" />
                 <interfaceoption type="show" name='volume' />
--- a/tests/examples/APE_example.xml	Wed Nov 28 13:50:22 2018 +0000
+++ b/tests/examples/APE_example.xml	Wed Nov 28 13:51:51 2018 +0000
@@ -1,145 +1,146 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
-<waet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test-schema.xsd">
-    <setup interface="APE" projectReturn="save.php" randomiseOrder='true' poolSize="2" loudness="-23" calibration="true">
-        <survey location="before">
-            <surveyquestion id="sessionId" mandatory="true">
-                <statement>Please enter your name.</statement>
-                <conditional check="equals" value="John" jumpToOnPass="test-intro" jumpToOnFail="checkboxtest" />
-            </surveyquestion>
-            <surveycheckbox id="checkboxtest" mandatory="true" min="2" max="4" randomise="true">
-                <statement>Please select with which activities you have any experience (example checkbox question)</statement>
-                <option name="musician">Playing a musical instrument</option>
-                <option name="soundengineer">Recording or mixing audio</option>
-                <option name="developer">Developing audio software</option>
-                <option name="hwdesigner">Designing or building audio hardware</option>
-                <option name="researcher">Research in the field of audio</option>
-            </surveycheckbox>
-            <surveyquestion id="instrument" mandatory="false">
-                <statement>What instrument did you play?</statement>
-            </surveyquestion>
-            <surveystatement id="test-intro">
-                <statement>This is an example of an 'APE'-style test, with two pages, using the test stimuli in 'example_eval/'.</statement>
-            </surveystatement>
-        </survey>
-        <survey location="after">
-            <surveyquestion id="location" mandatory="true" boxsize="large">
-                <statement>Please enter your location. (example mandatory text question)</statement>
-            </surveyquestion>
-            <surveynumber id="age" min="0">
-                <statement>Please enter your age (example non-mandatory number question)</statement>
-            </surveynumber>
-            <surveyradio id="rating">
-                <statement>Please rate this interface (example radio button question)</statement>
-                <option name="bad">Bad</option>
-                <option name="poor">Poor</option>
-                <option name="good">Good</option>
-                <option name="great">Great</option>
-            </surveyradio>
-            <surveystatement id="thankyou">
-                <statement>Thank you for taking this listening test. Please click 'Submit' and your results will appear in the 'saves/' folder.</statement>
-            </surveystatement>
-        </survey>
-        <metric>
-            <metricenable>testTimer</metricenable>
-            <metricenable>elementTimer</metricenable>
-            <metricenable>elementInitialPosition</metricenable>
-            <metricenable>elementTracker</metricenable>
-            <metricenable>elementFlagListenedTo</metricenable>
-            <metricenable>elementFlagMoved</metricenable>
-            <metricenable>elementListenTracker</metricenable>
-        </metric>
-        <interface>
-            <interfaceoption type="check" name="fragmentMoved" />
-            <interfaceoption type="check" name="fragmentPlayed" />
-            <interfaceoption type="check" name="scalerange" min="25" max="75" />
-            <interfaceoption type="show" name='playhead' />
-            <interfaceoption type="show" name="page-count" />
-            <interfaceoption type="show" name="comments" />
-        </interface>
-    </setup>
-    <page id='test-0' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='true' synchronous="true" loudness="-12">
-        <commentboxprefix>Comment on fragment</commentboxprefix>
-        <interface name="preference">
-            <title>Preference</title>
-            <scales>
-                <scalelabel position="0">Min</scalelabel>
-                <scalelabel position="100">Max</scalelabel>
-                <scalelabel position="50">Middle</scalelabel>
-                <scalelabel position="20">20</scalelabel>
-            </scales>
-        </interface>
-        <interface name="depth">
-            <title>Depth</title>
-            <scales>
-                <scalelabel position="0">Low</scalelabel>
-                <scalelabel position="100">High</scalelabel>
-                <scalelabel position="50">Middle</scalelabel>
-                <scalelabel position="50">Middle</scalelabel>
-            </scales>
-        </interface>
-        <audioelement url="0.wav" id="track-0" type="anchor" />
-        <audioelement url="1.wav" id="track-1" />
-        <audioelement url="2.wav" id="track-2" />
-        <audioelement url="3.wav" id="track-3" />
-        <audioelement url="4.wav" id="track-4" />
-        <survey location="before">
-            <surveyentry type="statement" id="test-0-intro">
-                <statement>Example of an 'APE' style interface with hidden anchor 'zero' (which needs to be below 20%), looping of the samples, randomisation of marker labels, mandatory moving of every sample, and a forced scale usage of at least 25%-75%.</statement>
-            </surveyentry>
-        </survey>
-        <survey location="after">
-            <surveyentry type="question" id="genre-0" mandatory="true">
-                <statement>Please enter the genre.</statement>
-            </surveyentry>
-        </survey>
-    </page>
-    <page id='test-1' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='false' synchronous="true" label="letter">
-        <commentboxprefix>Comment on fragment</commentboxprefix>
-        <interface name="preference">
-            <title>Example Test Question</title>
-            <scales>
-                <scalelabel position="0">Min</scalelabel>
-                <scalelabel position="100">Max</scalelabel>
-                <scalelabel position="50">Middle</scalelabel>
-                <scalelabel position="20">20</scalelabel>
-            </scales>
-        </interface>
-        <audioelement url="0.wav" gain="-6" id="track-5" type="anchor" marker="20" />
-        <audioelement url="1.wav" gain="0.0" id="track-6" type="reference" marker="80" />
-        <audioelement url="2.wav" gain="0.0" id="track-7" />
-        <audioelement url="3.wav" gain="0.0" id="track-8" />
-        <audioelement url="4.wav" gain="0.0" id="track-9" />
-        <audioelement url="5.wav" gain="0.0" id="track-10" />
-        <audioelement url="6.wav" gain="0.0" id="track-11" type="outside-reference" />
-        <commentquestions>
-            <commentquestion id='mixingExperience'>
-                <statement>What is your general experience with numbers?</statement>
-            </commentquestion>
-            <commentradio id="preference">
-                <statement>Please enter your overall preference</statement>
-                <option name="worst">Very Bad</option>
-                <option name="bad"></option>
-                <option name="OK">OK</option>
-                <option name="Good"></option>
-                <option name="Great">Great</option>
-            </commentradio>
-            <commentcheckbox id="character" type="checkbox">
-                <statement>Please describe the overall character</statement>
-                <option name="funky">Funky</option>
-                <option name="mellow">Mellow</option>
-                <option name="laidback">Laid back</option>
-                <option name="heavy">Heavy</option>
-            </commentcheckbox>
-        </commentquestions>
-        <survey location="before">
-            <surveyentry type="statement" id="test-1-intro">
-                <statement>Example of an 'APE' style interface with hidden anchor 'zero' (which needs to be below 20%), looping of the samples, randomisation of marker labels, mandatory moving of every sample, and a forced scale usage of at least 25%-75%.</statement>
-            </surveyentry>
-        </survey>
-        <survey location="after">
-            <surveyentry type="question" id="genre-1" mandatory="true">
-                <statement>Please enter the genre.</statement>
-            </surveyentry>
-        </survey>
-    </page>
-</waet>
+    <waet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test-schema.xsd">
+        <setup interface="APE" projectReturn="save.php" randomiseOrder='true' poolSize="2" loudness="-23">
+            <calibration checkFrequencies="true" checkLevels="true" checkChannels="true" />
+            <survey location="before">
+                <surveyquestion id="sessionId" mandatory="true">
+                    <statement>Please enter your name.</statement>
+                    <conditional check="equals" value="John" jumpToOnPass="test-intro" jumpToOnFail="checkboxtest" />
+                </surveyquestion>
+                <surveycheckbox id="checkboxtest" mandatory="true" min="2" max="4" randomise="true">
+                    <statement>Please select with which activities you have any experience (example checkbox question)</statement>
+                    <option name="musician">Playing a musical instrument</option>
+                    <option name="soundengineer">Recording or mixing audio</option>
+                    <option name="developer">Developing audio software</option>
+                    <option name="hwdesigner">Designing or building audio hardware</option>
+                    <option name="researcher">Research in the field of audio</option>
+                </surveycheckbox>
+                <surveyquestion id="instrument" mandatory="false">
+                    <statement>What instrument did you play?</statement>
+                </surveyquestion>
+                <surveystatement id="test-intro">
+                    <statement>This is an example of an 'APE'-style test, with two pages, using the test stimuli in 'example_eval/'.</statement>
+                </surveystatement>
+            </survey>
+            <survey location="after">
+                <surveyquestion id="location" mandatory="true" boxsize="large">
+                    <statement>Please enter your location. (example mandatory text question)</statement>
+                </surveyquestion>
+                <surveynumber id="age" min="0">
+                    <statement>Please enter your age (example non-mandatory number question)</statement>
+                </surveynumber>
+                <surveyradio id="rating">
+                    <statement>Please rate this interface (example radio button question)</statement>
+                    <option name="bad">Bad</option>
+                    <option name="poor">Poor</option>
+                    <option name="good">Good</option>
+                    <option name="great">Great</option>
+                </surveyradio>
+                <surveystatement id="thankyou">
+                    <statement>Thank you for taking this listening test. Please click 'submit' and your results will appear in the 'saves/' folder.</statement>
+                </surveystatement>
+            </survey>
+            <metric>
+                <metricenable>testTimer</metricenable>
+                <metricenable>elementTimer</metricenable>
+                <metricenable>elementInitialPosition</metricenable>
+                <metricenable>elementTracker</metricenable>
+                <metricenable>elementFlagListenedTo</metricenable>
+                <metricenable>elementFlagMoved</metricenable>
+                <metricenable>elementListenTracker</metricenable>
+            </metric>
+            <interface>
+                <interfaceoption type="check" name="fragmentMoved" />
+                <interfaceoption type="check" name="fragmentPlayed" />
+                <interfaceoption type="check" name="scalerange" min="25" max="75" />
+                <interfaceoption type="show" name='playhead' />
+                <interfaceoption type="show" name="page-count" />
+                <interfaceoption type="show" name="comments" />
+            </interface>
+        </setup>
+        <page id='test-0' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='true' synchronous="true" loudness="-12">
+            <commentboxprefix>Comment on fragment</commentboxprefix>
+            <interface name="preference">
+                <title>Preference</title>
+                <scales>
+                    <scalelabel position="0">Min</scalelabel>
+                    <scalelabel position="100">Max</scalelabel>
+                    <scalelabel position="50">Middle</scalelabel>
+                    <scalelabel position="20">20</scalelabel>
+                </scales>
+            </interface>
+            <interface name="depth">
+                <title>Depth</title>
+                <scales>
+                    <scalelabel position="0">Low</scalelabel>
+                    <scalelabel position="100">High</scalelabel>
+                    <scalelabel position="50">Middle</scalelabel>
+                    <scalelabel position="50">Middle</scalelabel>
+                </scales>
+            </interface>
+            <audioelement url="0.wav" id="track-0" type="anchor" />
+            <audioelement url="1.wav" id="track-1" />
+            <audioelement url="2.wav" id="track-2" />
+            <audioelement url="3.wav" id="track-3" />
+            <audioelement url="4.wav" id="track-4" />
+            <survey location="before">
+                <surveyentry type="statement" id="test-0-intro">
+                    <statement>Example of an 'APE' style interface with hidden anchor 'zero' (which needs to be below 20%), looping of the samples, randomisation of marker labels, mandatory moving of every sample, and a forced scale usage of at least 25%-75%.</statement>
+                </surveyentry>
+            </survey>
+            <survey location="after">
+                <surveyentry type="question" id="genre-0" mandatory="true">
+                    <statement>Please enter the genre.</statement>
+                </surveyentry>
+            </survey>
+        </page>
+        <page id='test-1' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='false' synchronous="true" label="letter">
+            <commentboxprefix>Comment on fragment</commentboxprefix>
+            <interface name="preference">
+                <title>Example Test Question</title>
+                <scales>
+                    <scalelabel position="0">Min</scalelabel>
+                    <scalelabel position="100">Max</scalelabel>
+                    <scalelabel position="50">Middle</scalelabel>
+                    <scalelabel position="20">20</scalelabel>
+                </scales>
+            </interface>
+            <audioelement url="0.wav" gain="-6" id="track-5" type="anchor" marker="20" />
+            <audioelement url="1.wav" gain="0.0" id="track-6" type="reference" marker="80" />
+            <audioelement url="2.wav" gain="0.0" id="track-7" />
+            <audioelement url="3.wav" gain="0.0" id="track-8" />
+            <audioelement url="4.wav" gain="0.0" id="track-9" />
+            <audioelement url="5.wav" gain="0.0" id="track-10" />
+            <audioelement url="6.wav" gain="0.0" id="track-11" type="outside-reference" />
+            <commentquestions>
+                <commentquestion id='mixingExperience'>
+                    <statement>What is your general experience with numbers?</statement>
+                </commentquestion>
+                <commentradio id="preference">
+                    <statement>Please enter your overall preference</statement>
+                    <option name="worst">Very Bad</option>
+                    <option name="bad"></option>
+                    <option name="OK">OK</option>
+                    <option name="Good"></option>
+                    <option name="Great">Great</option>
+                </commentradio>
+                <commentcheckbox id="character">
+                    <statement>Please describe the overall character</statement>
+                    <option name="funky">Funky</option>
+                    <option name="mellow">Mellow</option>
+                    <option name="laidback">Laid back</option>
+                    <option name="heavy">Heavy</option>
+                </commentcheckbox>
+            </commentquestions>
+            <survey location="before">
+                <surveyentry type="statement" id="test-1-intro">
+                    <statement>Example of an 'APE' style interface with hidden anchor 'zero' (which needs to be below 20%), looping of the samples, randomisation of marker labels, mandatory moving of every sample, and a forced scale usage of at least 25%-75%.</statement>
+                </surveyentry>
+            </survey>
+            <survey location="after">
+                <surveyentry type="question" id="genre-1" mandatory="true">
+                    <statement>Please enter the genre.</statement>
+                </surveyentry>
+            </survey>
+        </page>
+    </waet>
--- a/tests/examples/horizontal_example.xml	Wed Nov 28 13:50:22 2018 +0000
+++ b/tests/examples/horizontal_example.xml	Wed Nov 28 13:51:51 2018 +0000
@@ -17,6 +17,7 @@
             <interfaceoption type="show" name="page-count" />
             <interfaceoption type="show" name="volume" />
             <interfaceoption type="show" name="comments" />
+            <interfaceoption type="show" name="ticks" />
         </interface>
     </setup>
     <page id='test-0' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='true' loudness="-12">
--- a/tests/examples/mushra_example.xml	Wed Nov 28 13:50:22 2018 +0000
+++ b/tests/examples/mushra_example.xml	Wed Nov 28 13:51:51 2018 +0000
@@ -112,24 +112,24 @@
         <audioelement url="5.wav" gain="0.0" id="track-10" />
         <audioelement url="1.wav" gain="0.0" id="track-11" type="outside-reference" />
         <commentquestions>
-            <commentquestion id='mixingExperience' type="question">
+            <commentquestion id='mixingExperience'>
                 <statement>What is your general experience with numbers?</statement>
             </commentquestion>
-            <commentquestion id="preference" type="radio">
+            <commentradio id="preference">
                 <statement>Please enter your overall preference</statement>
                 <option name="worst">Very Bad</option>
                 <option name="bad"></option>
                 <option name="OK">OK</option>
                 <option name="Good"></option>
                 <option name="Great">Great</option>
-            </commentquestion>
-            <commentquestion id="character" type="checkbox">
+            </commentradio>
+            <commentcheckbox id="character">
                 <statement>Please describe the overall character</statement>
                 <option name="funky">Funky</option>
                 <option name="mellow">Mellow</option>
                 <option name="laidback">Laid back</option>
                 <option name="heavy">Heavy</option>
-            </commentquestion>
+            </commentcheckbox>
         </commentquestions>
         <survey location="before">
             <surveyentry type="statement" id="test-1-intro">
--- a/tests/examples/radio_example.xml	Wed Nov 28 13:50:22 2018 +0000
+++ b/tests/examples/radio_example.xml	Wed Nov 28 13:51:51 2018 +0000
@@ -29,9 +29,9 @@
                 <scalelabel position="100">(5) Inaudible</scalelabel>
             </scales>
         </interface>
-        <audioelement url="0.wav" id="track-1" alwaysInclude="true" />
-        <audioelement url="1.wav" id="track-2" />
-        <audioelement url="3.wav" id="track-4" />
-        <audioelement url="3.wav" id="track-5" />
+        <audioelement url="0.wav" id="track-0" alwaysInclude="true" />
+        <audioelement url="1.wav" id="track-1" />
+        <audioelement url="2.wav" id="track-2" />
+        <audioelement url="3.wav" id="track-3" />
     </page>
 </waet>
--- a/xml/test-schema.xsd	Wed Nov 28 13:50:22 2018 +0000
+++ b/xml/test-schema.xsd	Wed Nov 28 13:51:51 2018 +0000
@@ -48,6 +48,7 @@
             <xs:complexType>
                 <xs:sequence>
                     <xs:element name="exitText" type="xs:string" minOccurs="0" maxOccurs="1" />
+                    <xs:element ref="calibration" minOccurs="0" maxOccurs="1" />
                     <xs:element ref="survey" minOccurs="0" maxOccurs="2" />
                     <xs:element ref="metric" maxOccurs="1" />
                     <xs:element ref="interface" maxOccurs="1" />
@@ -59,7 +60,6 @@
                 <xs:attribute ref="poolSize" />
                 <xs:attribute name="loudness" type="xs:nonPositiveInteger" use="optional" />
                 <xs:attribute name="sampleRate" type="xs:positiveInteger" use="optional" />
-                <xs:attribute name="calibration" type="xs:boolean" default="false" />
                 <xs:attribute name="crossFade" default="0.0">
                     <xs:simpleType>
                         <xs:restriction base="xs:decimal">
@@ -67,6 +67,7 @@
                         </xs:restriction>
                     </xs:simpleType>
                 </xs:attribute>
+                <xs:attribute name="randomiseAxisOrder" type="xs:boolean" default="false" />
                 <xs:attribute ref="preSilence" />
                 <xs:attribute ref="postSilence" />
                 <xs:attribute ref="playOne" />
@@ -75,6 +76,14 @@
             </xs:complexType>
         </xs:element>
 
+        <xs:element name="calibration">
+            <xs:complexType>
+                <xs:attribute name="checkFrequencies" type="xs:boolean" default="false" />
+                <xs:attribute name="checkLevels" type="xs:boolean" default="false" />
+                <xs:attribute name="checkChannels" type="xs:boolean" default="false" />
+            </xs:complexType>
+        </xs:element>
+
         <xs:element name="page">
             <xs:complexType>
                 <xs:sequence>
@@ -105,6 +114,7 @@
                     </xs:simpleType>
                 </xs:attribute>
                 <xs:attribute name="labelStart" type="xs:string" use="optional" default="" />
+                <xs:attribute name="randomiseAxisOrder" type="xs:boolean" use="optional" />
                 <xs:attribute ref="poolSize" />
                 <xs:attribute ref="alwaysInclude" />
                 <xs:attribute name="position" use="optional" type="xs:nonNegativeInteger" />
@@ -277,6 +287,7 @@
                 </xs:sequence>
                 <xs:attribute ref="id" use="optional" />
                 <xs:attribute ref="name" use="optional" />
+                <xs:attribute ref="mandatory" use="optional" />
             </xs:complexType>
         </xs:element>
 
@@ -296,6 +307,7 @@
                 </xs:sequence>
                 <xs:attribute ref="id" use="optional" />
                 <xs:attribute ref="name" use="optional" />
+                <xs:attribute ref="mandatory" use="optional" />
             </xs:complexType>
         </xs:element>
 
@@ -306,6 +318,7 @@
                 </xs:sequence>
                 <xs:attribute ref="id" use="optional" />
                 <xs:attribute ref="name" use="optional" />
+                <xs:attribute ref="mandatory" use="optional" />
             </xs:complexType>
         </xs:element>
 
@@ -322,6 +335,7 @@
                 <xs:attribute name="max" type="xs:decimal" use="required" />
                 <xs:attribute name="step" type="xs:decimal" use="optional" default="1" />
                 <xs:attribute name="value" type="xs:decimal" use="optional" />
+                <xs:attribute ref="mandatory" use="optional" />
             </xs:complexType>
         </xs:element>
 
@@ -547,6 +561,7 @@
                         </xs:restriction>
                     </xs:simpleType>
                 </xs:attribute>
+                <xs:attribute name="showBackButton" type="xs:boolean" default="true" />
             </xs:complexType>
         </xs:element>